| ... | ... | @@ -479,7 +479,6 @@ fn clone() callconv(.Naked) void { |
| 479 | 479 | \\ syscall |
| 480 | 480 | ); |
| 481 | 481 | }, |
| 482 | | |
| 483 | 482 | .powerpc64, .powerpc64le => { |
| 484 | 483 | asm volatile ( |
| 485 | 484 | \\ # store non-volatile regs r30, r31 on stack in order to put our |
| ... | ... | @@ -528,7 +527,51 @@ fn clone() callconv(.Naked) void { |
| 528 | 527 | \\ blr |
| 529 | 528 | ); |
| 530 | 529 | }, |
| 530 | .sparcv9 => { |
| 531 | // Implementation by @LemonBoy (https://github.com/LemonBoy) |
| 532 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 533 | // i0, i1, i2, i3, i4, i5, sp |
| 531 | 534 | |
| 535 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| 536 | // g1 o0, o1, o2, o3, o4 |
| 537 | asm volatile ( |
| 538 | \\ save %%sp, -192, %%sp |
| 539 | \\ # Save the func pointer and the arg pointer |
| 540 | \\ mov %%i0, %%g2 |
| 541 | \\ mov %%i3, %%g3 |
| 542 | \\ # Shuffle the arguments |
| 543 | \\ mov 217, %%g1 |
| 544 | \\ mov %%i2, %%o0 |
| 545 | \\ sub %%i1, 2047, %%o1 |
| 546 | \\ mov %%i4, %%o2 |
| 547 | \\ mov %%i5, %%o3 |
| 548 | \\ ldx [%%fp + 192 - 2*8 + 2047], %%o4 |
| 549 | \\ t 0x6d |
| 550 | \\ bcs,pn %%xcc, 2f |
| 551 | \\ nop |
| 552 | \\ # sparc64 returns the child pid in o0 and a flag telling |
| 553 | \\ # whether the process is the child in o1 |
| 554 | \\ brnz %%o1, 1f |
| 555 | \\ nop |
| 556 | \\ # This is the parent process, return the child pid |
| 557 | \\ mov %%o0, %%i0 |
| 558 | \\ ret |
| 559 | \\ restore |
| 560 | \\1: |
| 561 | \\ # This is the child process |
| 562 | \\ mov %%g0, %%fp |
| 563 | \\ call %%g2 |
| 564 | \\ mov %%g3, %%o0 |
| 565 | \\ # Exit |
| 566 | \\ mov 1, %%g1 |
| 567 | \\ t 0x6d |
| 568 | \\2: |
| 569 | \\ # The syscall failed |
| 570 | \\ sub %%g0, %%o0, %%i0 |
| 571 | \\ ret |
| 572 | \\ restore |
| 573 | ); |
| 574 | }, |
| 532 | 575 | else => @compileError("Implement clone() for this arch."), |
| 533 | 576 | } |
| 534 | 577 | } |