Note · budding
A Rust target for big-endian MIPS III n32
- Stage
- budding
- Links
- 1 out, 1 in
Rust has no built-in target for what an SGI Indy needs: MIPS III instructions, big-endian, the n32 ABI. IRIX 7 defines its own.
The target file says the architecture is mips64, the ABI is n32, the CPU is mips3, the byte order is big, and pointers are 32 bits wide. That combination is the point of n32: 64-bit registers and arithmetic with 32-bit pointers. It adds +soft-float and +noabicalls for the kernel and links with rust-lld. Because no prebuilt standard library exists for a custom target, everything is built with -Z build-std on a pinned nightly compiler.
Two things I did not expect.
LLVM will not build MIPS III with the o32 ABI. In LLVM, choosing o32 means a 32-bit MIPS, so MIPS II at best. An IRIX system has to run o32 programs, and on this processor they are MIPS III capable, so the compatibility layer has to accept o32 binaries it could not itself have been compiled as. The kernel sidesteps the problem by being n32 throughout.
The GCC backend was not the way in. The plan for a while was to compile Rust through GCC, by way of rustc_codegen_gcc and libgccjit, since GCC already has the IRIX target. That build path was never completed, and the decision in the end was to use LLVM alone. GCC stays in the project as the C toolchain for IRIX itself.
One assembly detail belongs here too. Under n32, registers $8 to $11 are the fifth to eighth argument registers, and the names $t0 to $t3 move up to $12 to $15. Hand-written assembly carried over from o32 documentation silently uses the wrong registers.
Projects
- IRIX 7 A Rust operating system for the SGI Indy, meant to run IRIX 6.5 applications unchanged.
Projects
- IRIX 7 A Rust operating system for the SGI Indy, meant to run IRIX 6.5 applications unchanged.