| ... | ... | @@ -386,6 +386,11 @@ fn clone() callconv(.Naked) void { |
| 386 | 386 | ); |
| 387 | 387 | }, |
| 388 | 388 | .arm => { |
| 389 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 390 | // r0, r1, r2, r3, +0, +4, +8 |
| 391 | |
| 392 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| 393 | // r7 r0, r1, r2, r3, r4 |
| 389 | 394 | asm volatile ( |
| 390 | 395 | \\ stmfd sp!,{r4,r5,r6,r7} |
| 391 | 396 | \\ mov r7,#120 |
| ... | ... | @@ -445,6 +450,11 @@ fn clone() callconv(.Naked) void { |
| 445 | 450 | ); |
| 446 | 451 | }, |
| 447 | 452 | .mips, .mipsel => { |
| 453 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 454 | // 3, 4, 5, 6, 7, 8, 9 |
| 455 | |
| 456 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| 457 | // 2 4, 5, 6, 7, 8 |
| 448 | 458 | asm volatile ( |
| 449 | 459 | \\ # Save function pointer and argument pointer on new thread stack |
| 450 | 460 | \\ and $5, $5, -8 |
| ... | ... | @@ -465,12 +475,14 @@ fn clone() callconv(.Naked) void { |
| 465 | 475 | \\ addu $sp, $sp, 16 |
| 466 | 476 | \\ jr $ra |
| 467 | 477 | \\ subu $2, $0, $2 |
| 468 | | \\1: beq $2, $0, 1f |
| 478 | \\1: |
| 479 | \\ beq $2, $0, 1f |
| 469 | 480 | \\ nop |
| 470 | 481 | \\ addu $sp, $sp, 16 |
| 471 | 482 | \\ jr $ra |
| 472 | 483 | \\ nop |
| 473 | | \\1: lw $25, 0($sp) |
| 484 | \\1: |
| 485 | \\ lw $25, 0($sp) |
| 474 | 486 | \\ lw $4, 4($sp) |
| 475 | 487 | \\ jalr $25 |
| 476 | 488 | \\ nop |
| ... | ... | @@ -480,51 +492,48 @@ fn clone() callconv(.Naked) void { |
| 480 | 492 | ); |
| 481 | 493 | }, |
| 482 | 494 | .powerpc64, .powerpc64le => { |
| 495 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 496 | // 3, 4, 5, 6, 7, 8, 9 |
| 497 | |
| 498 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| 499 | // 0 3, 4, 5, 6, 7 |
| 483 | 500 | asm volatile ( |
| 484 | | \\ # store non-volatile regs r30, r31 on stack in order to put our |
| 485 | | \\ # start func and its arg there |
| 486 | | \\ stwu 30, -16(1) |
| 487 | | \\ stw 31, 4(1) |
| 488 | | \\ # save r3 (func) into r30, and r6(arg) into r31 |
| 489 | | \\ mr 30, 3 |
| 490 | | \\ mr 31, 6 |
| 491 | 501 | \\ # create initial stack frame for new thread |
| 492 | | \\ clrrwi 4, 4, 4 |
| 493 | | \\ li 0, 0 |
| 494 | | \\ stwu 0, -16(4) |
| 495 | | \\ #move c into first arg |
| 496 | | \\ mr 3, 5 |
| 497 | | \\ mr 5, 7 |
| 498 | | \\ mr 6, 8 |
| 499 | | \\ mr 7, 9 |
| 500 | | \\ # move syscall number into r0 |
| 501 | | \\ li 0, 120 |
| 502 | \\ clrrdi 4, 4, 4 |
| 503 | \\ li 0, 0 |
| 504 | \\ stdu 0,-32(4) |
| 505 | \\ |
| 506 | \\ # save fn and arg to child stack |
| 507 | \\ std 3, 8(4) |
| 508 | \\ std 6, 16(4) |
| 509 | \\ |
| 510 | \\ # shuffle args into correct registers and call SYS_clone |
| 511 | \\ mr 3, 5 |
| 512 | \\ #mr 4, 4 |
| 513 | \\ mr 5, 7 |
| 514 | \\ mr 6, 8 |
| 515 | \\ mr 7, 9 |
| 516 | \\ li 0, 120 # SYS_clone = 120 |
| 502 | 517 | \\ sc |
| 503 | | \\ # check for syscall error |
| 504 | | \\ bns+ 1f # jump to label 1 if no summary overflow. |
| 505 | | \\ #else |
| 506 | | \\ neg 3, 3 #negate the result (errno) |
| 518 | \\ |
| 519 | \\ # if error, negate return (errno) |
| 520 | \\ bns+ 1f |
| 521 | \\ neg 3, 3 |
| 522 | \\ |
| 507 | 523 | \\1: |
| 508 | | \\ # compare sc result with 0 |
| 524 | \\ # if we're the parent, return |
| 509 | 525 | \\ cmpwi cr7, 3, 0 |
| 510 | | \\ # if not 0, jump to end |
| 511 | | \\ bne cr7, 2f |
| 512 | | \\ #else: we're the child |
| 513 | | \\ #call funcptr: move arg (d) into r3 |
| 514 | | \\ mr 3, 31 |
| 515 | | \\ #move r30 (funcptr) into CTR reg |
| 516 | | \\ mtctr 30 |
| 517 | | \\ # call CTR reg |
| 526 | \\ bnelr cr7 |
| 527 | \\ |
| 528 | \\ # we're the child. call fn(arg) |
| 529 | \\ ld 3, 16(1) |
| 530 | \\ ld 12, 8(1) |
| 531 | \\ mtctr 12 |
| 518 | 532 | \\ bctrl |
| 519 | | \\ # mov SYS_exit into r0 (the exit param is already in r3) |
| 520 | | \\ li 0, 1 |
| 533 | \\ |
| 534 | \\ # call SYS_exit. exit code is already in r3 from fn return value |
| 535 | \\ li 0, 1 # SYS_exit = 1 |
| 521 | 536 | \\ sc |
| 522 | | \\2: |
| 523 | | \\ # restore stack |
| 524 | | \\ lwz 30, 0(1) |
| 525 | | \\ lwz 31, 4(1) |
| 526 | | \\ addi 1, 1, 16 |
| 527 | | \\ blr |
| 528 | 537 | ); |
| 529 | 538 | }, |
| 530 | 539 | .sparcv9 => { |