diff options
| author | Alex Rønne Petersen <alex@alexrp.com> | 2024-07-25 19:06:38 +0200 |
|---|---|---|
| committer | Alex Rønne Petersen <alex@alexrp.com> | 2024-07-29 10:05:25 +0200 |
| commit | e33af8e9021199696e413057b57fb86e750a9de0 (patch) | |
| tree | 264476aa162eabd04ba072586c5fee40c88b19c3 /lib/std/start.zig | |
| parent | 77fc3b88fbdf805e0c2c1fc2647513cee56813a4 (diff) | |
| download | zig-e33af8e9021199696e413057b57fb86e750a9de0.tar.gz zig-e33af8e9021199696e413057b57fb86e750a9de0.zip | |
start: Perform the posixCallMainAndExit() call with jalr on mips.
It's actually important for the ABI that r25 (t9) contains the address of the
called function, so that this standard prologue sequence works:
lui $2, %hi(_gp_disp)
addiu $2, $2, %lo(_gp_disp)
addu $gp, $2, $t9
(This is a bit similar to the ToC situation on powerpc that was fixed in
7bc78967b400322a0fc5651f37a1b0428c37fb9d.)
Diffstat (limited to 'lib/std/start.zig')
| -rw-r--r-- | lib/std/start.zig | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/lib/std/start.zig b/lib/std/start.zig index 78845904d6..fcc7fcd100 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -329,31 +329,43 @@ fn _start() callconv(.Naked) noreturn { \\ jsr (%%pc, %%a0) , .mips, .mipsel => + \\ move $fp, $0 \\ bal 1f \\ .gpword . + \\ .gpword %[posixCallMainAndExit] \\ 1: \\ lw $gp, 0($ra) \\ subu $gp, $ra, $gp - \\ move $fp, $0 + \\ lw $25, 4($ra) + \\ addu $25, $25, $gp \\ move $ra, $0 \\ move $a0, $sp \\ and $sp, -8 - \\ j %[posixCallMainAndExit] + \\ subu $sp, $sp, 16 + \\ jalr $25 , .mips64, .mips64el => + \\ move $fp, $0 + // 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. + \\ .balign 8 \\ bal 1f \\ .gpdword . + \\ .gpdword %[posixCallMainAndExit] \\ 1: // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64. // We need to set it up in order for dynamically-linked / position-independent code to // work. \\ ld $gp, 0($ra) \\ dsubu $gp, $ra, $gp - \\ move $fp, $0 + \\ ld $25, 8($ra) + \\ daddu $25, $25, $gp \\ move $ra, $0 \\ move $a0, $sp \\ and $sp, -16 - \\ j %[posixCallMainAndExit] + \\ dsubu $sp, $sp, 16 + \\ jalr $25 , .powerpc, .powerpcle => // Set up the initial stack frame, and clear the back chain pointer. |
