diff options
| author | Alex Rønne Petersen <alex@alexrp.com> | 2025-10-18 01:56:20 +0200 |
|---|---|---|
| committer | Alex Rønne Petersen <alex@alexrp.com> | 2025-10-18 11:16:31 +0200 |
| commit | b8d776928a0b0092830ee632b1c57c8bcf9391ea (patch) | |
| tree | 5f30b527977d152cad713f19018c69c7a71124c5 /lib/std/start.zig | |
| parent | f3da54f53c1db1484b00657de18e3677358549cd (diff) | |
| download | zig-b8d776928a0b0092830ee632b1c57c8bcf9391ea.tar.gz zig-b8d776928a0b0092830ee632b1c57c8bcf9391ea.zip | |
std: make all MIPS inline asm safe for MIPS I
MIPS I has load hazards so we need to insert nops in a few places. This is not a
problem for MIPS II and later.
While doing this, I also touched up all the inline asm to use ABI register
aliases and a consistent formatting convention. Also fixed a few places that
didn't properly check if the syscall return value should be negated.
Diffstat (limited to 'lib/std/start.zig')
| -rw-r--r-- | lib/std/start.zig | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/lib/std/start.zig b/lib/std/start.zig index 60ddae43ac..da880e7803 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -325,24 +325,26 @@ fn _start() callconv(.naked) noreturn { \\ jsr (%%pc, %%a0) , .mips, .mipsel => - \\ move $fp, $0 + \\ move $fp, $zero \\ bal 1f \\ .gpword . \\ .gpword %[posixCallMainAndExit] - \\ 1: + \\1: // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64. \\ lw $gp, 0($ra) + \\ nop \\ subu $gp, $ra, $gp - \\ lw $25, 4($ra) - \\ addu $25, $25, $gp - \\ move $ra, $0 + \\ lw $t9, 4($ra) + \\ nop + \\ addu $t9, $t9, $gp + \\ move $ra, $zero \\ move $a0, $sp \\ and $sp, -8 \\ subu $sp, $sp, 16 - \\ jalr $25 + \\ jalr $t9 , .mips64, .mips64el => - \\ move $fp, $0 + \\ move $fp, $zero // This is needed because early MIPS versions don't support misaligned loads. Without // this directive, the hidden `nop` inserted to fill the delay slot after `bal` would // cause the two doublewords to be aligned to 4 bytes instead of 8. @@ -350,17 +352,17 @@ fn _start() callconv(.naked) noreturn { \\ bal 1f \\ .gpdword . \\ .gpdword %[posixCallMainAndExit] - \\ 1: + \\1: // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64. \\ ld $gp, 0($ra) \\ dsubu $gp, $ra, $gp - \\ ld $25, 8($ra) - \\ daddu $25, $25, $gp - \\ move $ra, $0 + \\ ld $t9, 8($ra) + \\ daddu $t9, $t9, $gp + \\ move $ra, $zero \\ move $a0, $sp \\ and $sp, -16 \\ dsubu $sp, $sp, 16 - \\ jalr $25 + \\ jalr $t9 , .powerpc, .powerpcle => // Set up the initial stack frame, and clear the back chain pointer. |
