Nintendo 64 development used several C/C++ toolchains, including SGI IDO, Kyoto Microcomputer’s exeGCC, SN Systems’ GNU-based tools and Metrowerks CodeWarrior. Their versions, vendor changes and assemblers can produce different machine code from the same source. Nintendo’s own development documentation lists both IDO and exeGCC options 1.
This guide brings together documented production toolchains, preserved builds and modern matching implementations. It also covers later iQue compilers and experimental comparison profiles, with their status stated separately. A compiler that can target the N64 is not automatically a compiler known to have built a commercial N64 game. This is a catalogue of the evidenced families and variants below, not a claim that every private studio build has survived.
Compiler Families at a Glance
The main choices differ in more than their version numbers. Follow the family sections for the evidence and practical consequences:
| Family or variant | Historical or matching role | Main distinction |
|---|---|---|
| SGI IDO 5.3 | Historical N64 development; early-game matching | SGI compiler pipeline, separate from GCC |
| SGI IDO 7.1 | Historical N64 development; later-game matching | Different SGI release; cannot substitute for 5.3 when matching |
| Metrowerks CodeWarrior | Documented N64 C/C++ development product | Integrated development tools; N64 version is distinct from other CodeWarrior targets |
| KMC exeGCC / GCC 2.7.2 | Historical development and matching | KMC-targeted GNU toolchain; modern matching builds reproduce its output |
| SN64 GCC 2.7.2 | Preserved SN builds 0001, 0004 and 0006 | SN-specific compiler builds and ASN64 assembly |
| SN64 GCC 2.8.1 | Production-game matching evidence | Later SN compiler; paired assembler matters |
| SN64 2.7.2-970404 reconstruction | Modern reconstruction | Recreated compiler plus compatibility assembly; distinct from preserved executables |
| Paper Mario GCC 2.8.1 | Modern matching implementation for Paper Mario | Patched compiler and paired GNU binutils |
| GCC 2.8.1 + ASN64 2.56 | Modern comparison pairing | Tests GCC generation with original SN assembly; not a separate proven historical release |
| EGCS 1.1.2 / GCC 2.91.66 | Later iQue rebuilds | Separate GNU branch and toolchain; not an SN64 alias |
| Other SGI and later GNU versions | Comparison or homebrew | Capability alone does not establish retail N64 use |
The tables describe families rather than assigning one compiler to every game from a particular publisher. A single executable can combine game code, boot code and libraries built with different tools 2 3.
Glossary
These terms explain the differences discussed below:
- IDO - IRIS Development Option, SGI’s development toolchain for IRIX.
- GCC - GNU Compiler Collection; historical packages may call it the GNU C Compiler.
- ABI - Application Binary Interface. Defines conventions such as parameter passing, register use and data layout.
- ISA - Instruction Set Architecture. A processor’s available instructions, distinct from its calling convention.
- Assembler - Converts assembly into object code. Macro expansion and instruction scheduling can affect the bytes.
- ELF / ECOFF / PsyQ object - Object-file formats used along different toolchain paths. Matching tools may convert a historical format into ELF for linking.
- EGCS - Experimental GNU Compiler System, a GNU compiler development branch. EGCS 1.1.2 identifies itself with the GCC version 2.91.66.
- BSS - Storage reserved for uninitialized or zero-initialized objects, normally without storing their zero bytes in the executable file.
- DWARF / STABS - Debug-information formats used to describe source lines, functions and types to a debugger.
- RSP - Reality Signal Processor. Its microcode is separate from the main CPU’s C/C++ compilation.
SGI IDO 5.3 and 7.1
IDO is SGI’s compiler family, rather than a vendor build of GCC. Nintendo’s manual lists IDO 5.3 and IDO 7.1 for SGI workstations running different IRIX releases. The workstation’s operating-system version and the compiler’s version are separate labels 1.
The PARTNER-N64 comparison lists exeGCC on both host families and IDO on SGI. Source: Introduction to Nintendo 64, PDF page 112. Select the scan to enlarge.
IDO 5.3 and 7.1 should be treated as separate matching candidates. decompdecomp describes 5.3 as an early-game starting point and 7.1 as a later first-party starting point. These are search hints, not a rule that identifies a game’s toolchain from its release year. Ocarina of Time’s build system is a useful concrete example of retaining different compiler settings for different parts and editions 3 4.
How IDO Runs on Modern Computers
The ido-static-recomp project converts selected IRIX toolchain programs into programs for modern hosts. It supports both 5.3 and 7.1, including the C frontend, optimizer and code generator. This preserves a historical compilation pipeline rather than asking a current compiler to approximate its output 5.
Running an original IRIX executable through an emulator is another route. The host execution method should be recorded separately from the target compiler version: a statically recompiled IDO 5.3 is still intended to reproduce IDO 5.3 output 4 5.
IDO Matching Characteristics
The decompdecomp IDO guide documents useful observations. Unconditional branches within functions often use b, encoded as beq $zero, $zero. Expression structure, first assignments and temporary lifetimes can influence register allocation. Floating-point constants and argument home slots also provide clues 4.
These are tendencies, not fingerprints that uniquely identify a version. A b instruction can also come from handwritten assembly. A compiler family guess still needs compilation evidence.
The guide uses -O2 -mips2 as a common starting point, with other optimization and instruction-set choices needed for some files. Its source-layout observations are deliberately narrower: one IDO 5.3 comparison changed output after whitespace was collapsed, but the mechanism was not established. Preserve working source layout and test formatting changes under fixed inputs rather than treating all whitespace as harmless 4.
KMC exeGCC and GCC 2.7.2
Kyoto Microcomputer, usually shortened to KMC, supplied exeGCC for the PARTNER-N64 environment. exeGCC is the product/toolchain name; “KMC GCC” usually identifies its GNU compiler lineage in decompilation projects. They are not two unrelated historical compiler families. A modern KMC-compatible build is a further distinction: it aims to reproduce the older compiler’s output on a different host 1 6 7.
Nintendo documents SGI-hosted and PC-hosted exeGCC packages. PARTNER-N64 names a development system; it is not an alternative name for SN Systems’ compiler. The manual’s KMC branding and compiler table help keep those products separate 1.
What Was Included in exeGCC?
The exeGCC(N64) User’s Guide describes a complete PC development package. Its directory tree includes the gcc driver, cpp preprocessor, cc1 compiler, GNU assembler/linker and utilities, mild ROM packer, sgi2gas conversion tool, libkmc.a, startup code and an extender loader 7.
Thus, the gcc command is one component of exeGCC. The product also supplies host execution, library and ROM-building facilities. The guide’s contemporary edition describes C support and explicitly excludes C++ and Objective-C at that time; the language capabilities of generic GCC should not be assumed to describe every shipped exeGCC package 7.
Documented KMC N64 Versions
The preserved package’s VERSION.TXT documents three PC releases. These dates and changes come from KMC’s release history, rather than from a game-release-date estimate 8:
| exeGCC PC release | Vendor date | Documented changes |
|---|---|---|
| 1.0 | 1 January 1997 | Initial shipping release |
| 1.1 | 5 July 1997 | Win32 operation for Windows 95/NT and greater virtual-memory access; reduced debug-information size; avoids stack/protection failures on complex optimized functions; adds ROM-packer and make improvements |
| 1.2 | 26 September 1997 | Adds stronger debug-information shrinking and the mild lba command; using the shrinking feature requires PARTNER-N64/WIN 1.07 |
The vendor describes debug information falling to roughly two-thirds in 1.1, and the added 1.2 shrinking facility reducing existing debug information to about one-tenth. Those are vendor-reported debug-data reductions, not measurements of executable instruction size or game performance. The release notes do not establish that all three releases generate identical machine code, or document a new optimizer version for each release 8.
The preserved 1.2 distribution contains GCC 2.7.2: its driver has the banner format gcc version %s release 1.2, with 2.7.2 version strings; cc1 also contains 2.7.2. Its assembler carries a 2.6 version string, and the linker identifies itself as 2.6. These are separate component and package versions 9.
These labels should be recorded independently:
| Version label | What it identifies | What it does not establish |
|---|---|---|
| exeGCC 1.0 / 1.1 / 1.2 | KMC’s PC package releases | A GNU GCC 1.x backend |
| GCC 2.7.2 | Compiler version found in the preserved 1.2 package | The full exeGCC package release or exact assembler behavior |
| GNU binutils 2.6 | Assembler/linker lineage in that package | GCC version 2.6 |
| PARTNER-N64/WIN 1.07 | Debugger required for the 1.2 shrinking feature | A compiler release called GCC 1.07 |
| OS/Library 2.0i | Nintendo SDK/library release | An exeGCC or GCC backend version |
| Matching compiler v0.1 | A modern decompals release tag | Historical exeGCC 0.1 or GNU GCC 0.1 |
Nintendo’s PC OS/Library 2.0i release notes independently refer to exeGCC 1.2’s compression facilities and revised makefiles. This supports the package-version distinction 10.
The exeGCC guide also contains a verbose-command example showing GCC 2.7.0 for Hitachi SH, with SH include paths. That reused example is not evidence of an N64/MIPS exeGCC 2.7.0 release. Likewise, later exeGCC products for other processors do not automatically belong in an N64 version list. The three PC releases above are the documented history in the inspected package, not a claim to have found every private or SGI-hosted build 7 8.
Original KMC Tools Versus Modern Matching Builds
“KMC GCC” can refer to an original KMC executable, or to a source-built compatibility toolchain. The distinction matters even when both display GCC 2.7.2:
| Implementation | What runs | Reproduction boundary |
|---|---|---|
| Original exeGCC package | KMC’s shipped programs and supporting host runtime | Captures a particular historical package; its old host environment still needs support |
| Original binaries through a wrapper | A loader such as kmc-gcc-wrapper runs the original compiler binaries | Rehosts original tools; does not replace the compiler with current GCC |
| Modern KMC-compatible GCC | decompals/mips-gcc-2.7.2, paired with matching binutils | Source-built toolchain tailored to reproduce KMC output; version text alone is not proof of equivalence |
The matching repository starts from GCC 2.7.2. Its changes disable particular small-data section selections, select GNU assembler output by default, and change the local-label prefix to match KMC. It also includes modern-host fixes and driver support for passing assembler-related options. These are concrete compatibility changes, not a wholesale upgrade to a newer GNU compiler 11.
The small-data changes can affect where constants and objects are placed; assembler settings and labels can affect assembly or scheduling. Consequently, substituting stock GCC 2.7.2 or a different assembler is not guaranteed to preserve binary output. Conversely, a host wrapper or debug-information change does not inherently mean that every function’s instructions change 11.
In decompdecomp, gcc-2.7.2-kmc pins decompals GCC release v0.1 with binutils 2.6 release v0.3. These are modern distribution tags around historical compiler versions. This profile is a matching build, rather than an untouched copy of exeGCC 1.2 12.
Matching Settings and Package Behavior
The KMC matching guide starts with -O2 -mips3 -G0. GCC commonly uses j for an unconditional jump inside a function, where IDO often uses b. Declaration order, lifetimes and expression ordering can change registers and stack slots 13.
The original exeGCC guide documents GCCSW for default compiler options and N64ALIGN for data alignment. Its PC setup uses MIPS III with 32-bit general/floating-point register settings. Capturing only the displayed GCC version therefore misses environment-dependent parts of the build recipe 7.
Debug options deserve attention too. In the documented matching workflow, -g or -g3 can affect instruction placement because debug labels interact with assembler scheduling. That is separate from exeGCC 1.2’s debug-information shrinking facility. A complete recipe records the original or reconstructed tool build, assembler, flags and environment 13 8.
Which Version Changes Can Reach the Game Binary?
The documented exeGCC releases change several parts of the toolchain, but the release number is not a list of new CPU-code optimizations. The vendor notes support the following distinctions 8:
| Transition | What changed | What that means when comparing binaries |
|---|---|---|
| 1.0 to 1.1 | Win32 execution, memory access and robustness while compiling large optimized functions | These address the host compiler’s execution. Avoiding a compiler stack/protection failure does not establish a changed instruction pattern in successfully compiled functions |
| 1.0 to 1.1 | Smaller debug information; mild delta-transfer alignment and diagnostic options; make path handling |
Debug objects, development builds or ROM packaging can differ. A warning-option change need not alter a successful build’s payload; a packing/alignment change can affect layout without changing the C optimizer |
| 1.1 to 1.2 | Additional debug-information shrinking and a new mild command |
Debug data or packer capabilities can identify a newer environment when independently corroborated. These changes do not establish a general .text opcode difference |
The sources audited here provide no validated instruction fingerprint that separates exeGCC PC 1.0, 1.1 and 1.2. The inspected 1.2 package contains GCC 2.7.2; the evidence recorded here does not establish the backend versions in 1.0 or 1.1. Do not invent a mapping such as “exeGCC 1.0 means GCC 2.7.0” 8 9.
Likewise, decompals’ modern compatibility commits describe changes to that reconstruction. They do not prove that an original KMC release changed at the same points. A difference between stock GCC 2.7.2 and a KMC-compatible build is a different question from a difference between two historical exeGCC packages 11.
Patterns That Suggest a Different KMC Build or Setting
A pattern is useful when it narrows the next experiment. Its strength depends on which artifact survives: build logs and object files retain evidence that a stripped cartridge ROM normally loses. The following are diagnostic suggestions derived from the documented settings and compatibility changes, not newly measured release fingerprints 13 7 8 11:
| Observed pattern | Investigate first | What it can establish |
|---|---|---|
| An original build log records the compiler banner and component paths | Package contents, driver/backend versions and executable hashes | Strong evidence for the tools invoked by that build. A GNU version alone does not identify the exeGCC package or assembler |
| Debug information uses an independently identified shrinking facility | Release notes, debugger requirements and retained uncompressed output | Corroborating evidence for the debug-tool environment. Small debug sections alone do not prove 1.2: flags, stripping and source size also affect them |
| Only branch/return delay slots or NOP placement disagree | Assembler build, reorder settings and -g/-g3; compare the compiler’s assembly before assembly |
Suggests a scheduling difference. If both compilers emit identical assembly but objects differ, the divergence is downstream of C code generation |
Global references use $gp-relative loads where another build uses high/low address construction |
-G threshold, small-data sections, global-pointer setup and assembler relaxation |
Suggests a small-data/addressing policy difference; it is not an exeGCC 1.0/1.1/1.2 signature |
Constants or small objects appear in .sdata in one output and .rodata/.data in another |
Exact matching-build commit and section-selection settings | The modern KMC compatibility source changes particular small-data selections. This can distinguish those source revisions under triggering inputs, not identify an original package automatically |
| Addresses differ while the surrounding operations agree | Linker script, libraries, common-symbol alignment, N64ALIGN and ROM packing |
Suggests placement or relocation differences. A changed address operand alone is weak evidence for a different optimizer |
| Function frames, saved registers or arithmetic ordering differ across many functions | Optimization level, prototypes, source types, ABI/register settings, then compiler build | Makes a different code generator worth testing after context/settings are controlled. One register mismatch is insufficient |
| Only local-label spelling or symbol-table organization differs in assembly/objects | Assembler dialect and modern compatibility/driver changes | May identify a tool-path difference. Labels generally disappear from stripped ROMs, and a renamed label need not change instructions |
A region uses j while another favors b, with other structural differences |
A different compiler family, library or separately built module | A family-level clue, including possible GCC/IDO mixing; it does not distinguish KMC package releases |
For example, lw $v0,offset($gp) versus a lui plus address-relative load is a useful clue about data addressing. The first question is whether the same object became eligible for small-data access, not whether the game used a later exeGCC release. Compare relocation types and sections in objects when available; in a ROM, compare resolved addresses and the surrounding global-pointer setup 7 11.
The original guide’s N64ALIGN option is another potential false version clue. Stronger alignment can move globals and change address operands under the same compiler version. Similarly, a smaller debug file can come from compression without any reduction in executable instructions 7 8.
Confirming a Suspected Version Difference
A useful version claim should survive a controlled comparison:
- Identify the candidate precisely - Record exeGCC package, backend, assembler and linker identities separately. For modern builds, include the release tag or source commit and executable hashes.
- Freeze the build context - Keep source, headers, symbol addresses, libraries, linker script and environment fixed. Check
GCCSW,N64ALIGN, optimization, debug, register-width and small-data settings before changing versions. - Locate the first divergence - Compare compiler-generated assembly, then object code/relocations, then linked code and runtime data, then ROM packing. This separates a compiler decision from an assembler or layout change.
- Require more than a tiny match - Compare several nontrivial functions with calls, global accesses and floating point in the same module. Keep library and engine results separate.
- State the level of certainty - “Matches KMC-compatible GCC 2.7.2 with these flags” is justified by reproduced bytes. “Built with exeGCC PC 1.2” additionally needs evidence identifying that historical package; a match alone need not uniquely identify it.
Without retained build evidence or controlled comparisons of the original releases, the strongest conclusion may be a KMC-family or compiler-profile identification. The Paper Mario patch experiments illustrate why this distinction matters: assembler scheduling and alignment can change linked instructions, while other tool changes alter only object metadata. Those experiments are not measurements of differences between KMC releases 14.
SN Systems SN64 GCC
SN Systems supplied a PC development system with GNU-based C/C++ compilation, its ASN64 assembler and PSYLINK linker. The SN64 manual describes CCN64 as a driver that invokes the compilation, assembly and linking stages. A driver’s version is not necessarily the GCC backend’s version 15.
The SN64 SDK article covers the wider package. For compiler matching, the important identity is the combination of frontend, compiler build, assembler and flags.
Preserved SN64 Builds
The inspected decompdecomp registry distinguishes these original compiler profiles. Its integration notes explain the assembler pairings and preservation sources 2 12:
| Compiler | Profile ID | Assembly path and important difference |
|---|---|---|
| GCC 2.7.2 build 0001 | sn-n64-272-0001 |
Original compiler with ASN64 2.56; the integration borrows the pinned 2.8.1 preprocessor |
| GCC 2.7.2 build 0004 | sn-n64-272-0004 |
Preserved compiler and its own assembler; also uses the pinned 2.8.1 preprocessor |
| GCC 2.7.2 build 0006 | sn-n64-272-0006 |
Preserved compiler, preprocessor and paired assembler |
| GCC 2.8.1 | sn-n64-281 |
Preserved compiler with its preprocessor and ASN64 2.78 |
The borrowed preprocessors are properties of these modern integrations. They should not be described as the exact contents of the original 0001 or 0004 distribution.
SN64 2.8.1 assembly cannot simply be fed to the older ASN64 2.56: the integration documents rejected %hi/%lo expressions. Build 0001 also rejects the -mcpu=VR4300 option used by the 2.8.1 default profile. An unsupported option can reveal a wrong compiler assumption before any matching begins 2.
For modern matching, decompdecomp runs the preserved programs through wibo, converts their PsyQ objects to ELF, then links and compares bytes. Object conversion is part of the reproduction path, not evidence that the historical compiler produced ELF 2.
Games That Demonstrate the Differences
The Excitebike 64 matching project documents SN64 GCC 2.8.1 for game code and 2.7.2 builds 0006 and 0001 for its boot loader. Its libultra and libgcc use KMC-compatible GCC 2.7.2 with binutils 2.6. This is a concrete example of several compiler profiles within one game’s build 16.
The Turok 2 project reports matching engine and VM-module code with SN64 GCC 2.8.1, including -O2 -mno-fix4300, and a byte-exact ROM rebuild. That supports this game’s configuration; it does not establish a universal SN64 flag set 17.
Reconstructed SN64 GCC 2.7.2-970404
The SN64-gcc project recreates a version of the SN64 GCC toolchain. decompdecomp exposes its 2.7.2-970404 reconstruction separately as sn-n64-272-970404. It uses native compiler programs, a modern-asn64 compatibility wrapper and GNU assembly tools 2 18.
This is useful when investigating SN-style generation without executing the original Windows compiler. It is not an alias for preserved build 0001, 0004 or 0006. Its default profile includes -fno-exceptions because the reconstruction enables exceptions by default. Reproduction still has to be established for the functions and data being matched 2.
Metrowerks CodeWarrior for Nintendo 64
CodeWarrior was also offered for N64 development. Metrowerks’ CodeWarrior’s Architectural Advantage, finalized in September 2000, lists Nintendo64 MIPS as a C/C++ target hosted on Windows 95/98/NT. Its architecture combines a project manager, editor, compiler, linker and debugger through target-specific tools 19.
This is a separate product family to investigate alongside IDO and the GNU variants. A CodeWarrior version for GameCube, PlayStation or another MIPS target is not an interchangeable N64 compiler. The product name identifies the environment; exact compiler plugins, libraries and options still need to be established for a matching project.
The inspected N64 profile list does not include CodeWarrior. The sources used here establish the N64 product’s availability, but do not identify a particular retail game’s matching compiler build or justify CodeWarrior-specific instruction fingerprints. Those remain gaps rather than reasons to omit the product from the historical catalogue 12 19.
Paper Mario GCC 2.8.1
The Paper Mario team’s GCC fork is a community-maintained GCC 2.8.1 toolchain with N64 target support, language extensions, host fixes and debugging changes. Its companion binutils fork supplies a modified assembler and related tools. Sharing the version string 2.8.1 with SN64 does not make these pipelines interchangeable 20.
There is no single binary change applied to every function. Some patches change instructions or data placement when their conditions are met. Others enable source that the unpatched compiler rejects, or change only debug information and object-file metadata. The patch inventory below describes source-level mechanisms; the measured examples then test selected effects. No whole-game A/B rebuild is claimed.
The audited revisions are GCC d97824f and binutils fb13863. The GCC repository’s initial 1,217 files match GNU’s GCC 2.8.1 release archive. The subsequent patches are modern matching/build changes; their presence does not prove that Nintendo’s original compiler contained the same source edits 21.
What Counts as a Binary Difference?
A compiler comparison needs to distinguish the executable payload from its container:
- Instructions and runtime data - Changes to
.text, constants, initialized data, addresses or padding can change the ROM and its execution. Equivalent C behavior can still produce different instruction bytes. - Debug information and object metadata -
.debug_*, STABS records, symbol tables and ELF headers can differ while the extracted executable payload remains identical. These differences reach the ROM only if the build packages them or they affect linking/layout. - Build acceptance - A new target or language feature can make compilation possible. If the unpatched build rejects the input, there is no unpatched binary to compare.
For a controlled comparison, hold the source, headers, compiler host, flags, assembler and linker settings fixed, and change only the patch under investigation. Plain GCC 2.8.1 does not provide this fork’s mips-nintendo-nu64 target, so comparing an unpatched generic MIPS build also requires making target defaults equivalent 22.
Compiler Patches and Their Output Effects
The compiler changes have different triggers. The expected effects below follow from the implementation; the addu/subu case also has an explicit maintainer report:
| Patch | Without the change | With the change and effect on output |
|---|---|---|
| N64 target configuration | The mips-nintendo-nu64 target is unavailable |
Adds VR4300/MIPS III defaults, Nintendo macros and 32-bit integer/long/pointer definitions. Passing -mips3 through its driver also selects 32-bit general/floating-point registers. Defaults and macros can change instructions, declarations and data; this is not a fixed byte substitution 22. |
naked functions |
This MIPS backend does not implement the attribute; ordinary functions receive compiler-managed entry/exit code | For a function marked __attribute__((naked)), skips prologue/epilogue expansion and disallows the automatic return-instruction path. Stack adjustment, register-save/restore and return instructions that would otherwise be generated can disappear. The author must supply the required assembly. Unmarked functions do not take these new early exits 23. |
| Named sections | This backend lacks the added named-section output hook | Emits .section NAME for section attributes. The linker can place that function/data elsewhere, changing addresses, relocations and padding. Moving an item does not inherently rewrite its arithmetic, but address-dependent instructions can change 24. |
| Negative-constant optimizer fix | The maintainers report host GCC 6 versus GCC 9 producing different MIPS addu/subu choices around 0x80000000 |
Changes one condition in common-subexpression elimination to preserve the intended matching output across those host builds. This can change actual .text instruction bytes in affected expressions; it is not merely a debug-record correction 25. |
| Japanese-text preprocessing | No added N64-specific encoding/line-ending handling | N64GCC_KANJI selects optional SJIS/EUC handling and octal escaping of multibyte text. N64GCC_CUTCR=ON normalizes CRLF and removes trailing DOS EOF. These can change accepted input, preprocessing and resulting string/data bytes where the original handling differed; neither option applies a universal instruction rewrite 26. |
| Anonymous structs/unions | The parser does not construct these unnamed members in the same way | Enables direct access to their nested fields. A follow-up removes the field-search optimization that breaks this for structures with more than 15 members. This expands accepted source; it does not inherently add a runtime wrapper or an extra pointer indirection 27. |
| 64-bit/macOS host support | Old assumptions about host-side floating-point storage and legacy build interfaces can prevent correct builds | Separately copies the low/high halves of compiler-internal floating constants and adds host/build compatibility. The intent is to run the old compiler correctly on modern hosts, not change the N64’s pointer width. Output equality still needs checking 28. |
| Debug output fixes | Some debug labels, abbreviation tables and line records are unsuitable for the paired assembler or debugger | Renames DWARF labels, terminates the abbreviation table, corrects line-table size accounting and makes STABS line references function-relative. These directly change debug records/labels. Their interaction with assembler scheduling is covered below 29. |
The negative-constant fix changes the guard from -INTVAL(const_arg1) >= 0 to (-INTVAL(const_arg1) >> 0x1f) >= 0. The maintainer’s explanation identifies the resulting addu/subu discrepancy. It does not establish that every function changes, or provide a universal byte delta for the game 25.
The MIPS instruction-description file, config/mips/mips.md, is unchanged from the repository’s GCC 2.8.1 baseline. The large-looking mips.c diff mostly changes whitespace; ignoring whitespace leaves 44 added lines implementing the naked checks. That narrow backend change should not be mistaken for a wholesale replacement of GCC’s instruction selector 21 23.
Binutils Patches and Their Output Effects
The paired assembler can change the final machine code even when the compiler emits the same assembly. The binutils fork starts from GNU binutils 2.9.1 and adds the following behavior:
| Patch | Without the change | With the change and effect on output |
|---|---|---|
| N64 assembly compatibility | Different target defaults, instruction eligibility and directive/register parsing | Adds the Nintendo target, symbolic register parsing, N64-specific handling of MIPS instruction levels and .set behavior. Some inputs become accepted; expanded instructions and object flags can differ. This is not evidence of new instructions in the N64 CPU 30. |
| Debug-label delay-slot handling | A label blocks the assembler from moving the previous instruction into a branch’s delay slot | Labels with the special ._D_ prefix are excluded from that barrier check; real labels still block the swap. When other safety checks allow it, instruction order and delay-slot filling can change. The maintainers added this so debugging could retain Paper Mario’s matching opcodes 31. |
| Global-pointer relaxation control | Eligible references may be relaxed to use $gp |
Adds .set nogpopt to suppress that optimization and .set gpopt to restore it. Affected load/address sequences can differ in their instructions and size, which can also affect delay-slot opportunities and later addresses. Merely installing the patch does not disable relaxation everywhere 32. |
| Binary inclusion and common-data alignment | No added .incbin directive or N64ALIGN policy |
.incbin inserts the selected file bytes directly. With N64ALIGN=ON, common symbols receive at least 8-byte alignment at sizes of 16 bytes or more, and 16-byte alignment at 1,024 bytes or more. This can move BSS symbols and change address references without adding initialized bytes for the BSS itself 30. |
| ELF symbols and file layout | Different symbol classification/counting and load-segment file-offset adjustment | Changes local/global symbol bookkeeping and the symbol table’s sh_info; skips a load-segment offset-adjustment block in the NU64 configuration. ELF bytes/file offsets can differ independently of the extracted ROM payload 30 33. |
| Debugger metadata | Older debug-section/symbol handling | Adds .MIPS.abiflags for the relevant debug mode, changes STABS/ECOFF handling, drops selected local-label symbols and forces final MIPS ELF flags to 0x60001101. These are object/debug metadata changes, not a request for the CPU to execute a different instruction set 34. |
The debug-label fix crosses the usual code/debug boundary. A label emits no CPU instruction, but the unpatched assembler treats it as a scheduling barrier. Removing that barrier can move a real instruction into a delay slot and change .text. In contrast, repairing a debug-table terminator can change the ELF without changing any instruction. These effects must be checked separately 29 31.
What This Means for Matching
For the same ordinary C with no added attributes or encoding options, the fork does not automatically insert a new code sequence. Important differences can still come from target defaults, the optimizer’s negative-constant fix and the assembler’s scheduling/relaxation behavior. Source using new extensions may have no successful unpatched counterpart at all.
A whole-file ELF comparison will also detect debug and metadata changes. To establish a game-code difference, compare linked instructions, runtime data and symbol placement, then the final ROM. The sources above identify concrete mechanisms and reported cases; this article does not claim a measured count of changed Paper Mario functions or bytes.
Measured Binary Comparisons
Small controlled examples demonstrate which differences reach executable bytes. Seven example pairs were built on Apple Silicon macOS 27.0.1 using Apple Clang 21.0.0 to build the historical tools. The GCC and binutils source revisions are pinned above. GNU MIPS binutils 2.47.20260726 linked every pair at 0x80000400 with the same linker script 14.
Here, “reverted” means selected patch behavior was removed from the Paper Mario fork. The N64 target and modern-host fixes stayed in both builds. This avoids comparing different target configurations or an original GCC release that cannot build the same target on this host. The downloadable reversion files identify every source edit.
The comparisons isolate these behaviors:
- Compiler entry/exit - Restore ordinary prologue/epilogue and return eligibility, while retaining
nakedattribute recognition so both compilers accept identical C. This is a behavior ablation, not pristine GCC ignoring an unsupported attribute. - Assembler scheduling and alignment - Restore the debug-label scheduling barrier and remove the
N64ALIGNblock. The scheduling test has no common data; the alignment test has no debug label, so each exercises one of those changes. - Object/debug metadata - Reverse binutils commit
2e31907in a separate assembler build. - Negative-constant optimization - Restore the pre-PR-18 condition in a separate compiler build.
Both compiler variants use -G0 -mips3 -mgp32 -mfp32 -O2. Assembly uses -EB -mips3 -G0, with -g2 added for the metadata test. N64ALIGN=ON is identical on both sides. Compiler-generated assembly and the linker input object use fixed temporary filenames to avoid filename-only debug/symbol differences. Every pair uses the same final linker and script 14.
The table compares the extracted, linked .text bytes. Lengths include section padding; differing bytes means differing byte positions, not differing instructions:
| Example | Reverted / patched .text length | Differing bytes | Measured result |
|---|---|---|---|
| Ordinary C arithmetic | 16 / 16 bytes | 0 | Instructions, object file and linked ELF are identical |
| Naked assembly entry | 16 / 16 bytes | 3 | Function size falls from 16 to 8 bytes; an extra compiler-generated return disappears, but section padding keeps .text at 16 bytes |
| Special debug label before return | 16 / 16 bytes | 6 | addiu moves into the return’s delay slot |
| Real label before return | 16 / 16 bytes | 0 | The real-label barrier still prevents that swap |
| Common-symbol alignment | 32 / 32 bytes | 2 | Both referenced BSS addresses move by 12 bytes; two address operands change |
| Object/debug metadata | 16 / 16 bytes | 0 | Objects differ: 887 bytes reverted, 675 patched. Linked instructions remain identical |
Two uses of 0x80000000U |
32 / 32 bytes | 0 | Both emit the same subu sequence on this host; this does not reproduce the GCC 6 versus GCC 9 case |
Every compile/assemble/link sequence was repeated. Object, linked ELF and extracted .text hashes were stable across repeats. Full SHA-256 hashes, source files, exact reversions, symbol listings and disassemblies are in the experiment download. The machine-readable results record tool versions and flags. These are synthetic examples; no game code or ROM was used 14.
Naked Functions Can Shrink Without Shrinking the Section
The test C supplies its own return sequence:
void __attribute__((naked)) naked_entry(void) {
__asm__ volatile (".set noreorder\n\tjr $31\n\tnop\n\t.set reorder");
}
With ordinary entry/exit behavior restored, the compiler adds another return after the inline assembly. The measured function bodies contain these big-endian instruction words:
| Output | Function words | Function size |
|---|---|---|
| Ordinary entry/exit behavior restored | 03e00008 00000000 03e00008 00000000 |
16 bytes |
| Patched naked behavior | 03e00008 00000000 |
8 bytes |
03e00008 is jr $ra; 00000000 is nop. The patched section fills the remaining eight bytes with zero padding, so only three byte positions differ in the complete 16-byte .text section. The source intentionally supplies assembly for the whole entry; this is not evidence that arbitrary C is safe inside a naked function 14.
A Debug Label Changes Real Instruction Order
The assembly example places ._D_LM1 between an arithmetic instruction and a return:
addiu $2,$4,1
._D_LM1:
jr $31
nop
The first two linked instruction words change as follows:
| Output | Words at 0x80000400 and 0x80000404 | Execution order |
|---|---|---|
| Debug-label barrier restored | 24820001 03e00008 |
addiu $v0,$a0,1, then jr $ra; the delay slot is a NOP |
| Patched assembler | 03e00008 24820001 |
jr $ra, with addiu $v0,$a0,1 in its delay slot |
A MIPS delay-slot instruction executes before control transfers. The patch changes the placement of the arithmetic operation without changing this example’s intended result. Replacing the special label with real_label makes the two assemblers produce identical bytes. This control confirms that the observed change is specific to the debug-label exception 31 14.
Alignment Changes Linked Address Operands
The alignment example declares 32-byte and 1,024-byte common symbols, both requesting four-byte alignment. Its linker script deliberately starts BSS allocation after a one-byte reservation so stronger alignment has a visible effect. This is a constructed layout, not a recovered Paper Mario layout.
With N64ALIGN=ON on both sides, the symbols and references change as follows:
| Symbol or instruction | Alignment block removed | Patched assembler |
|---|---|---|
large address |
0x80000424 |
0x80000430 |
small address |
0x80000824 |
0x80000830 |
addiu $v0,$v0,%lo(small) |
24420824 |
24420830 |
addiu $v1,$v1,%lo(large) |
24630424 |
24630430 |
Both addresses move by 0x0c. Only the last byte of each shown instruction changes, giving two differing .text bytes. The BSS space is not stored as initialized ROM data; its placement still affects instructions that refer to it 30 14.
A Different Object File Can Contain Identical Code
The metadata test reverses the GDB compatibility commit while retaining the other assembler changes. A two-instruction function assembled with -g2 produces these objects:
| Property | Metadata commit reverted | Patched assembler |
|---|---|---|
| Object size | 887 bytes | 675 bytes |
| ELF flags | 0x10000001 |
0x60001101 |
| Relevant section | .mdebug, 240 bytes |
.MIPS.abiflags, 24 bytes |
Linked .text SHA-256 |
2235882e0b98070fdcac3cc7d809aa3e768019c7fe2d6a6c0cf08009d32dfde7 |
Same hash |
The linker script discards those metadata sections. The resulting instruction bytes are identical, while the complete linked ELFs still differ. An ELF checksum alone would therefore overstate the change to the executable payload. The header flags do not turn this two-instruction example into different CPU code 34 14.
The Negative-Constant Test Did Not Reproduce the Reported Difference
The compiler probe uses the same large constant twice:
unsigned int constant_reuse(unsigned int x, unsigned int y) {
unsigned int a = x + 0x80000000U;
unsigned int b = y + 0x80000000U;
return a ^ b;
}
Both the patched compiler and the version with only the CSE condition reverted emit identical objects and linked code. Both use subu for these operations. This is a negative result for this source and Apple Clang 21 host build, not a refutation of the maintainer’s GCC 6/GCC 9 report. Reproducing that reported host-dependent difference requires those host compiler conditions and a triggering input 25 14.
The reproduction script builds the pinned tools, applies the supplied reversions and reruns all examples in an empty directory. It targets the macOS host configuration used here. The archive includes the sources and reversion files it needs; no installed game project or compiler is modified 14.
Compiler Profiles in decompdecomp
In decompdecomp, gcc-2.8.1-pm uses the paired GNU toolchain. A separate profile, gcc-2.8.1-pm-sn-as, takes the PM compiler’s assembly and processes it with original SN ASN64 2.56 before object conversion. This tests a different assembler path with the same compiler family 2 12.
The hybrid profile can help reproduce scheduling and macro encodings. Its existence does not prove that a studio shipped this exact compiler/assembler pairing. A matching implementation is evidence about reproducible output; identifying an original distribution needs additional historical evidence.
EGCS and the iQue Releases
EGCS belongs in an N64 compiler reference because later iQue releases rebuilt N64 software with it. The Ocarina of Time Makefile explicitly selects EGCS for some iQue files and libraries while retaining other compiler paths. An iQue build should therefore be investigated separately from an original cartridge revision 3.
decompdecomp distinguishes a modern matching build, gcc-egcs-2.91.66, from gcc-egcs-1.1.2-4, an original Linux EGCS release. The former is paired with EGCS-era binutils; the latter needs its original 32-bit host runtime. Their related version names do not establish identical output for every input 2 35.
The matching profile defaults include -mno-abicalls -fno-pic for ordinary executable code. These affect how code addresses functions and data. They belong in the recorded configuration alongside optimization and register-width settings 12 35.
Other SGI Versions and Modern N64 Compilers
An inventory of tools capable of generating N64-compatible instructions is larger than the list of toolchains evidenced in production games. decompdecomp makes the distinction explicit with these additional profiles 2 4:
| Profile | What it adds | Evidence boundary |
|---|---|---|
ido-5.3-cxx |
IDO 5.3’s separate C++ frontend | C++ comparison path; not interchangeable with its C frontend |
ido-4.1 |
Earlier SGI compiler; ECOFF conversion | Experimental comparison; retail N64 use not established here |
ido-5.2 |
Another earlier SGI release | Experimental comparison; retail N64 use not established here |
ido-6.0 |
Intermediate SGI release | Experimental comparison; retail N64 use not established here |
mipspro-7.4.4 |
Later SGI compiler | Experimental comparison; retail N64 use unconfirmed |
gcc-4.4.0-n64 |
Later MIPS64 ELF compiler configured for the N64 ABI | Experimental later compiler; not a retail-era identification |
The integration notes state that real execution of the additional SGI packs remained pending license acceptance in that validation. A picker entry should not be reported as a successfully tested compiler solely because it is registered 2.
For new homebrew, libdragon provides an open-source N64 development environment with a modern GCC cross-toolchain. Its toolchain build script configures a mips64-elf target. This serves a different purpose from reproducing the output of a 1990s compiler 36.
Likewise, the old-gcc collection offers many historical MIPS compiler builds. Availability of GCC 2.8.0, 2.95.x or another version is useful for experiments, but does not by itself identify an N64 game that used it 37.
RSP Compilers Are a Separate Category
The RSP runs microcode alongside the main CPU. A compiler for that processor does not replace IDO or GCC for the game’s main C/C++ program.
RSPL is a modern high-level language and transpiler that emits RSP MIPS assembly. It exposes vector lanes through swizzle syntax and produces overlays usable by libdragon. It is relevant to new microcode development, rather than evidence of a historical cartridge’s main-CPU compiler 38.
What Actually Changes the Machine Code?
Compiler identity is only one part of the recipe. The following settings explain common mismatches in the documented IDO, KMC, SN64 and EGCS workflows 2 4 12 13 35:
| Setting | Difference to investigate |
|---|---|
| Compiler version and vendor patches | Optimization passes, instruction selection and register allocation |
| Optimization level | Inlining, loop structure, common expressions and scheduling |
ISA selection, such as -mips2 or -mips3 |
Which instructions may be emitted; not the same as pointer size |
| ABI and register widths | Calling conventions, structure returns, integer and floating-point register use |
Small-data settings, such as -G0 |
Whether eligible data uses small-data addressing |
| PIC and ABI-call settings | Global-pointer setup and function/data access sequences |
| Floating-point options | Register mode, conversions and possibly data representation, such as short doubles |
| CPU workaround flags | Instruction sequences or scheduling intended for processor hazards |
| Assembler version and options | Pseudo-instruction expansion, delay slots and object relocations |
| Headers, macros and prototypes | Argument conversions, structure offsets and visible expression structure |
| Debug settings and source layout | Can affect historical output; compare under controlled inputs |
The N64’s 64-bit CPU does not imply that every game used 64-bit pointers or a 64-bit calling convention. ISA level, register-width options and the ABI must be recorded independently. Even an assembly alias can hide a difference: the SN integration documents addu and daddu both appearing as move in a display while encoding different instructions 2 12.
There is no supported universal ranking of these compilers by speed or code size in the sources used here. Such a comparison needs the same workload, equivalent semantics, explicit settings and measurements on the target hardware. The best compiler for matching is the one that reproduces the target bytes.
Identifying a Game’s Compiler
A useful identification combines historical evidence with reproduction. These checks narrow the search without mistaking a visual resemblance for proof:
- Start with the exact release - A cartridge revision, a later regional conversion and an iQue rebuild can have different toolchains.
- Read an existing matching project’s configuration - Record compiler builds, assemblers and file-specific flags, not just the top-level default.
- Use instruction patterns as clues - IDO’s frequent
bversus GCC’s frequentjcan suggest a family. They cannot establish a compiler version. - Compare several nontrivial functions - Include calls, global data, branches and floating point. Tiny arithmetic functions may match multiple compilers.
- Separate game and library evidence - Boot code, libultra and an engine may need different profiles.
- Verify linked bytes and data - Function matching needs addresses and relocations resolved. A complete ROM rebuild is a separate, stronger integration check.
The decompdecomp compiler notes provide a useful caution: a 32-function probe found two new SN64 2.8.1 matches among candidates developed under KMC. That justified narrow compiler overrides, rather than identifying the whole game as SN64. Some controls also matched more than one compiler 2.
For an applied walkthrough, the AI-assisted tutorial covers importing a ROM, checking compiler evidence and testing recovered C:
Running Historical Compilers Today
Host support is a practical consideration, separate from code-generation identity. The following summarizes the inspected decompdecomp-rr integration as of 13 November 2026; it is not a claim that every downloadable release of the app includes the same profiles 2 12:
| Toolchain path | Modern execution approach | Limit to keep in mind |
|---|---|---|
| IDO 5.3 / 7.1 C | Static recompilation for modern hosts | Preserve the exact compiler release and flags |
| KMC-compatible, PM and reconstructed EGCS builds | Linux packs; Intel macOS packs use Rosetta on Apple Silicon | A different host build needs output verification |
| Original SN64 builds | wibo, ASN64 and PsyQ-to-ELF conversion; Windows path uses WSL | Original tools and assembler pairings remain significant |
| Reconstructed SN64 970404 | Native source build on macOS; pinned Linux build | Compatibility implementation, not an original SN executable |
| Additional SGI profiles | Bundled IRIX emulation on Linux; WSL or an optional Linux VM on other hosts | Experimental; integration notes distinguish configuration from execution validation |
| Original EGCS and GCC 4.4 | Linux executables with pinned runtime libraries | VM/container checks do not establish physical-host coverage everywhere |
Imported community projects may retain their own build scripts instead of using these built-in profiles. Preserve that configuration when reproducing an existing decompilation. Main-CPU compilers also do not replace the separate RSP microcode toolchain 3.
For wider context, see the C/C++ compiler toolchain reference, the Nintendo 64 SDK article and the SN64 SDK article.
References
-
Nintendo, Introduction to Nintendo 64, Chapter 6, PDF pp. 112-115, PARTNER-N64 host/compiler comparison and exeGCC installation. ↩ ↩2 ↩3 ↩4
-
RetroReversing/decompdecomp, SN64 compiler integration. Cross-checked against the local decompdecomp-rr checkout on 13 November 2026; distinguishes original tools, reconstructed profiles and validation limits. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14
-
zeldaret, Ocarina of Time Makefile, compiler selection, iQue-specific EGCS objects, library settings and microcode assembly. ↩ ↩2 ↩3 ↩4
-
RetroReversing/decompdecomp, IDO matching guide, matching observations and experimental SGI comparison profiles. ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
decompals, ido-static-recomp, supported 5.3/7.1 toolchain programs and modern-host builds. ↩ ↩2
-
decompals, mips-gcc-2.7.2, GCC build tailored to KMC output. ↩
-
Nintendo/KMC, exeGCC(N64) User’s Guide, NUS-06-0160-001A, released 31 December 1997, printed pp. 11-15 and 20. Package structure, host/runtime distinction, C-only edition, environment settings and the Hitachi SH verbose-output example. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
KMC,
kmc/gcc/MIPSE/VERSION.TXT, preserved in the kmc-gcc-wrapper release archive, assetkmc-gcc-wrapper-ubuntu-latest.tar.gz. Vendor release entries dated 1 January, 5 July and 26 September 1997. Dates and changes were read from the archive, not inferred from its upload date. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 -
Original KMC
GCC.OUT,CC1.OUT,AS.OUTandLD.OUTin that archive; inspection record with archive/component SHA-256 hashes. Version/banner strings inspected without executing the original binaries; these observations do not establish byte-identical output between releases. ↩ ↩2 -
Nintendo, N64 OS/Library 2.0i for the PC release notes, setup scripts and exeGCC 1.2 compression/makefile compatibility. ↩
-
decompals/mips-gcc-2.7.2, small-data changes, GNU assembler default, KMC label prefix, ABI-option forwarding and symbol-table option forwarding. These changes are present at the inspected
v0.1tag. ↩ ↩2 ↩3 ↩4 ↩5 -
RetroReversing/decompdecomp, toolchain registry and N64 platform definition. Local checkout inspected on 13 November 2026 for profile identities, flags, dependencies and host paths. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
RetroReversing/decompdecomp, KMC GCC matching guide, jump patterns, register allocation and debug-sensitive assembly. ↩ ↩2 ↩3 ↩4
-
RetroReversing, Paper Mario patch experiment bundle, results and SHA-256 hashes, and reproduction script. Seven controlled example pairs compiled/assembled and linked on 13 November 2026; all 14 build paths repeated with stable hashes. Reversions retain the common N64 target and modern-host support. No full-game A/B rebuild or runtime execution is claimed. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10
-
SN Systems, PC Development System for the Nintendo 64, Chapter 13, PDF pp. 244-246, CCN64 driver and processing stages. ↩
-
chasmlol, Excitebike 64 README, Toolchain, SN64 game/boot compiler builds and KMC library tools. Project-reported configuration; this article does not independently rebuild the ROM. ↩
-
mgrz18, Turok 2 decompilation, project-reported SN64 identification and byte-exact rebuild. ↩
-
decompals, SN64-gcc, reconstruction containing the 2.7.2-970404 tree. ↩
-
Metrowerks, CodeWarrior’s Architectural Advantage, finalized 13 September 2000, Table 1, printed p. 11, Nintendo64 MIPS target and Windows hosts. ↩ ↩2
-
Paper Mario Reverse-Engineering Team, gcc-papermario and binutils-papermario, matching compiler and assembler forks. ↩
-
Paper Mario GCC, initial GCC 2.8.1 import, compared with the GNU GCC 2.8.1 release archive. All 1,217 imported files were byte-identical in this audit. Subsequent changes inspected through revision
d97824ffc7517675646960442b3f512a473e4404. ↩ ↩2 -
Paper Mario GCC, pinned N64 target configuration and configure script, target definitions, driver specifications and NU64 preprocessing mode. ↩ ↩2
-
Paper Mario GCC, original N64/naked patch, attribute validation/merging, prologue/epilogue early returns and return-instruction eligibility. ↩ ↩2
-
Paper Mario GCC, named-section output hook. ↩
-
Paper Mario GCC, PR #18, host GCC version differences and the negative-constant test in
cse.c. ↩ ↩2 ↩3 -
Paper Mario GCC, pinned preprocessor source,
kanjienv_check,iskanji1,safe_writeandnu64cutcr. ↩ -
Paper Mario GCC, anonymous struct/union parser support and large-structure lookup fix. ↩
-
Paper Mario GCC, 64-bit host support and pinned host configuration/build instructions. ↩
-
Paper Mario GCC, DWARF label changes, abbreviation terminator, line-table accounting and STABS changes. ↩ ↩2
-
Paper Mario binutils, initial PM changes, Nintendo assembly behavior, register parsing,
.incbin,N64ALIGNand ELF file-layout changes. Final source audited throughfb13863bb812ac34417916e0b8a6e16f5ca6badb. ↩ ↩2 ↩3 ↩4 -
Paper Mario binutils, PR #6, recognizing debug labels during delay-slot arrangement. ↩ ↩2 ↩3
-
Paper Mario binutils, global-pointer relaxation control,
.set gpopt,.set nogpoptandnopic_need_relax. ↩ -
Paper Mario binutils, symbol-table fix, local symbol count and MIPS symbol classification. ↩
-
Paper Mario binutils, GDB compatibility changes, ABI flags, debug sections and symbol filtering. ↩ ↩2
-
RetroReversing/decompdecomp, additional GNU compiler guide, PM and EGCS distinctions and host limitations. ↩ ↩2 ↩3
-
libdragon, project documentation and GCC toolchain build script. ↩
-
decompals, old-gcc, available historical compiler versions and big-endian target option. ↩
-
HailToDodongo, RSPL, RSP language, assembly output and libdragon overlay support. ↩