| ... | @@ -272,13 +272,27 @@ fn _start() callconv(.Naked) noreturn { | ... | @@ -272,13 +272,27 @@ fn _start() callconv(.Naked) noreturn { |
| 272 | \\ bstrins.d $sp, $zero, 3, 0 | 272 | \\ bstrins.d $sp, $zero, 3, 0 |
| 273 | \\ b %[posixCallMainAndExit] | 273 | \\ b %[posixCallMainAndExit] |
| 274 | , | 274 | , |
| | 275 | // zig fmt: off |
| 275 | .riscv32, .riscv64 => | 276 | .riscv32, .riscv64 => |
| | 277 | // The self-hosted riscv64 backend is not able to assemble this yet. |
| | 278 | if (builtin.zig_backend != .stage2_riscv64) |
| | 279 | // The RISC-V ELF ABI assumes that `gp` is set to the value of `__global_pointer$` at |
| | 280 | // startup in order for GP relaxation to work, even in static builds. |
| | 281 | \\ .weak __global_pointer$ |
| | 282 | \\ .hidden __global_pointer$ |
| | 283 | \\ .option push |
| | 284 | \\ .option norelax |
| | 285 | \\ lla gp, __global_pointer$ |
| | 286 | \\ .option pop |
| | 287 | else "" |
| | 288 | ++ |
| 276 | \\ li s0, 0 | 289 | \\ li s0, 0 |
| 277 | \\ li ra, 0 | 290 | \\ li ra, 0 |
| 278 | \\ mv a0, sp | 291 | \\ mv a0, sp |
| 279 | \\ andi sp, sp, -16 | 292 | \\ andi sp, sp, -16 |
| 280 | \\ tail %[posixCallMainAndExit]@plt | 293 | \\ tail %[posixCallMainAndExit]@plt |
| 281 | , | 294 | , |
| | 295 | // zig fmt: off |
| 282 | .m68k => | 296 | .m68k => |
| 283 | // Note that the - 8 is needed because pc in the jsr instruction points into the middle | 297 | // Note that the - 8 is needed because pc in the jsr instruction points into the middle |
| 284 | // of the jsr instruction. (The lea is 6 bytes, the jsr is 4 bytes.) | 298 | // of the jsr instruction. (The lea is 6 bytes, the jsr is 4 bytes.) |
| ... | @@ -293,6 +307,7 @@ fn _start() callconv(.Naked) noreturn { | ... | @@ -293,6 +307,7 @@ fn _start() callconv(.Naked) noreturn { |
| 293 | \\ .gpword . | 307 | \\ .gpword . |
| 294 | \\ .gpword %[posixCallMainAndExit] | 308 | \\ .gpword %[posixCallMainAndExit] |
| 295 | \\ 1: | 309 | \\ 1: |
| | 310 | // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64. |
| 296 | \\ lw $gp, 0($ra) | 311 | \\ lw $gp, 0($ra) |
| 297 | \\ subu $gp, $ra, $gp | 312 | \\ subu $gp, $ra, $gp |
| 298 | \\ lw $25, 4($ra) | 313 | \\ lw $25, 4($ra) |
| ... | @@ -314,8 +329,6 @@ fn _start() callconv(.Naked) noreturn { | ... | @@ -314,8 +329,6 @@ fn _start() callconv(.Naked) noreturn { |
| 314 | \\ .gpdword %[posixCallMainAndExit] | 329 | \\ .gpdword %[posixCallMainAndExit] |
| 315 | \\ 1: | 330 | \\ 1: |
| 316 | // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64. | 331 | // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64. |
| 317 | // We need to set it up in order for dynamically-linked / position-independent code to | | |
| 318 | // work. | | |
| 319 | \\ ld $gp, 0($ra) | 332 | \\ ld $gp, 0($ra) |
| 320 | \\ dsubu $gp, $ra, $gp | 333 | \\ dsubu $gp, $ra, $gp |
| 321 | \\ ld $25, 8($ra) | 334 | \\ ld $25, 8($ra) |