mirror of
https://github.com/zeldaret/oot.git
synced 2025-04-08 23:56:26 +00:00
Write about IDO and EGCS in compilers.md (#2432)
* Write about IDO and EGCS in compilers.md * Fix typo * Fix another typo * Apply suggestions from code review Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> --------- Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com>
This commit is contained in:
parent
284ecb114e
commit
11b7bf2914
4 changed files with 66 additions and 3 deletions
63
docs/compilers.md
Normal file
63
docs/compilers.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
# Compilers
|
||||
|
||||
Ocarina of Time was written mostly in C, compiled to MIPS machine code. For the
|
||||
N64 and GameCube versions, all code was compiled with the IDO compiler. For the
|
||||
iQue Player versions, some of the code (namely libultra, and some game files
|
||||
such as those related to Chinese text) was compiled with the EGCS compiler instead.
|
||||
|
||||
## IDO
|
||||
|
||||
Ocarina of Time was originally developed on
|
||||
[Silicon Graphics "Indy"](https://en.wikipedia.org/wiki/SGI_Indy) workstations,
|
||||
and IDO (IRIS Development Option) was the C compiler toolchain that shipped with
|
||||
these. Two different versions of IDO were used for Ocarina of Time: IDO 5.3 was
|
||||
used for some libraries (namely libultra, libleo, and the JPEG library) while
|
||||
IDO 7.1 was used for the other libraries and all of the "main" game code.
|
||||
|
||||
These Silicon Graphics workstations ran the MIPS-based IRIX operating system, so
|
||||
the original compiler binaries can't run on modern systems. Originally this
|
||||
project used [qemu-irix](https://github.com/n64decomp/qemu-irix) (now
|
||||
unmaintained) to run emulate IRIX on modern systems, but nowadays we use the
|
||||
more lightweight
|
||||
[ido-static-recomp](https://github.com/decompals/ido-static-recomp) instead.
|
||||
|
||||
## EGCS
|
||||
|
||||
[EGCS (Experimental/Enhanced GNU Compiler System)](https://en.wikipedia.org/wiki/GNU_Compiler_Collection#EGCS_fork)
|
||||
was a fork of the GCC compiler. The Linux-based iQue SDK included a patched
|
||||
version of EGCS release 1.1.2. The original compiler can still run on modern Linux
|
||||
systems, but we use a
|
||||
[modified version](https://github.com/decompals/mips-gcc-egcs-2.91.66)
|
||||
that includes Mac support and a few other minor improvements (such as anonymous
|
||||
struct/union support).
|
||||
|
||||
This version of the EGCS compiler has a bug where code that indexes into an array member can
|
||||
fail to compile if the array member is at a large (>= 0x8000) offset in a struct. For
|
||||
example, when run on the source code
|
||||
|
||||
```c
|
||||
struct Foo {
|
||||
char a[0x8000];
|
||||
int b[1];
|
||||
};
|
||||
|
||||
int test(struct Foo* foo, int i) {
|
||||
return foo->b[i];
|
||||
}
|
||||
```
|
||||
|
||||
the compiler errors with
|
||||
|
||||
```
|
||||
Compiler error: src.c: In function `test':
|
||||
src.c:8: internal error--unrecognizable insn:
|
||||
(insn 20 18 22 (set (reg:SI 85)
|
||||
(plus:SI (reg:SI 81)
|
||||
(const_int 32768))) -1 (nil)
|
||||
(nil))
|
||||
../../gcc/toplev.c:1367: Internal compiler error in function fatal_insn
|
||||
```
|
||||
|
||||
In some recompiled files, the game developers had to modify the code to work
|
||||
around this bug, for example by storing a pointer to the array in a temporary
|
||||
variable before indexing into it.
|
|
@ -2570,7 +2570,7 @@ void Actor_Draw(PlayState* play, Actor* actor) {
|
|||
gSPSegment(POLY_OPA_DISP++, 0x06, play->objectCtx.slots[actor->objectSlot].segment);
|
||||
gSPSegment(POLY_XLU_DISP++, 0x06, play->objectCtx.slots[actor->objectSlot].segment);
|
||||
#else
|
||||
// Workaround for EGCS bug
|
||||
// Workaround for EGCS internal compiler error (see docs/compilers.md)
|
||||
slots = play->objectCtx.slots;
|
||||
gSPSegment(POLY_OPA_DISP++, 0x06, slots[actor->objectSlot].segment);
|
||||
gSPSegment(POLY_XLU_DISP++, 0x06, slots[actor->objectSlot].segment);
|
||||
|
|
|
@ -119,7 +119,7 @@ void Font_LoadOrderedFont(Font* font) {
|
|||
|
||||
PRINTF("msg_data=%x, msg_data0=%x jj=%x\n", font->msgOffset, font->msgLength, len);
|
||||
|
||||
// Workaround for EGCS bug
|
||||
// Workaround for EGCS internal compiler error (see docs/compilers.md)
|
||||
msgBufWide = font->msgBufWide;
|
||||
fontBufIndex = 0;
|
||||
for (codePointIndex = 0; msgBufWide[codePointIndex] != MESSAGE_WIDE_END; codePointIndex++) {
|
||||
|
|
|
@ -853,7 +853,7 @@ void Sram_InitSave(FileSelectState* fileSelect, SramContext* sramCtx) {
|
|||
#if !PLATFORM_IQUE
|
||||
gSaveContext.save.info.playerData.playerName[offset] = fileSelect->fileNames[fileSelect->buttonIndex][offset];
|
||||
#else
|
||||
// Workaround for EGCS bug
|
||||
// Workaround for EGCS internal compiler error (see docs/compilers.md)
|
||||
u8* fileName = fileSelect->fileNames[fileSelect->buttonIndex];
|
||||
|
||||
gSaveContext.save.info.playerData.playerName[offset] = fileName[offset];
|
||||
|
|
Loading…
Add table
Reference in a new issue