github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/runtime/sys_linux_ppc64x.s (about) 1 // Copyright 2014 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build linux && (ppc64 || ppc64le) 6 // +build linux 7 // +build ppc64 ppc64le 8 9 // 10 // System calls and other sys.stuff for ppc64, Linux 11 // 12 13 #include "go_asm.h" 14 #include "go_tls.h" 15 #include "textflag.h" 16 #include "asm_ppc64x.h" 17 18 #define SYS_exit 1 19 #define SYS_read 3 20 #define SYS_write 4 21 #define SYS_open 5 22 #define SYS_close 6 23 #define SYS_getpid 20 24 #define SYS_kill 37 25 #define SYS_pipe 42 26 #define SYS_brk 45 27 #define SYS_fcntl 55 28 #define SYS_mmap 90 29 #define SYS_munmap 91 30 #define SYS_setitimer 104 31 #define SYS_clone 120 32 #define SYS_sched_yield 158 33 #define SYS_nanosleep 162 34 #define SYS_rt_sigreturn 172 35 #define SYS_rt_sigaction 173 36 #define SYS_rt_sigprocmask 174 37 #define SYS_sigaltstack 185 38 #define SYS_madvise 205 39 #define SYS_mincore 206 40 #define SYS_gettid 207 41 #define SYS_futex 221 42 #define SYS_sched_getaffinity 223 43 #define SYS_exit_group 234 44 #define SYS_epoll_create 236 45 #define SYS_epoll_ctl 237 46 #define SYS_epoll_wait 238 47 #define SYS_clock_gettime 246 48 #define SYS_tgkill 250 49 #define SYS_epoll_create1 315 50 #define SYS_pipe2 317 51 52 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4 53 MOVW code+0(FP), R3 54 SYSCALL $SYS_exit_group 55 RET 56 57 // func exitThread(wait *uint32) 58 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8 59 MOVD wait+0(FP), R1 60 // We're done using the stack. 61 MOVW $0, R2 62 SYNC 63 MOVW R2, (R1) 64 MOVW $0, R3 // exit code 65 SYSCALL $SYS_exit 66 JMP 0(PC) 67 68 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20 69 MOVD name+0(FP), R3 70 MOVW mode+8(FP), R4 71 MOVW perm+12(FP), R5 72 SYSCALL $SYS_open 73 BVC 2(PC) 74 MOVW $-1, R3 75 MOVW R3, ret+16(FP) 76 RET 77 78 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12 79 MOVW fd+0(FP), R3 80 SYSCALL $SYS_close 81 BVC 2(PC) 82 MOVW $-1, R3 83 MOVW R3, ret+8(FP) 84 RET 85 86 TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28 87 MOVD fd+0(FP), R3 88 MOVD p+8(FP), R4 89 MOVW n+16(FP), R5 90 SYSCALL $SYS_write 91 BVC 2(PC) 92 NEG R3 // caller expects negative errno 93 MOVW R3, ret+24(FP) 94 RET 95 96 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28 97 MOVW fd+0(FP), R3 98 MOVD p+8(FP), R4 99 MOVW n+16(FP), R5 100 SYSCALL $SYS_read 101 BVC 2(PC) 102 NEG R3 // caller expects negative errno 103 MOVW R3, ret+24(FP) 104 RET 105 106 // func pipe() (r, w int32, errno int32) 107 TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12 108 ADD $FIXED_FRAME, R1, R3 109 SYSCALL $SYS_pipe 110 MOVW R3, errno+8(FP) 111 RET 112 113 // func pipe2(flags int32) (r, w int32, errno int32) 114 TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20 115 ADD $FIXED_FRAME+8, R1, R3 116 MOVW flags+0(FP), R4 117 SYSCALL $SYS_pipe2 118 MOVW R3, errno+16(FP) 119 RET 120 121 TEXT runtime·usleep(SB),NOSPLIT,$16-4 122 MOVW usec+0(FP), R3 123 MOVD R3, R5 124 MOVW $1000000, R4 125 DIVD R4, R3 126 MOVD R3, 8(R1) 127 MOVW $1000, R4 128 MULLD R3, R4 129 SUB R4, R5 130 MOVD R5, 16(R1) 131 132 // nanosleep(&ts, 0) 133 ADD $8, R1, R3 134 MOVW $0, R4 135 SYSCALL $SYS_nanosleep 136 RET 137 138 TEXT runtime·gettid(SB),NOSPLIT,$0-4 139 SYSCALL $SYS_gettid 140 MOVW R3, ret+0(FP) 141 RET 142 143 TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0 144 SYSCALL $SYS_getpid 145 MOVW R3, R14 146 SYSCALL $SYS_gettid 147 MOVW R3, R4 // arg 2 tid 148 MOVW R14, R3 // arg 1 pid 149 MOVW sig+0(FP), R5 // arg 3 150 SYSCALL $SYS_tgkill 151 RET 152 153 TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0 154 SYSCALL $SYS_getpid 155 MOVW R3, R3 // arg 1 pid 156 MOVW sig+0(FP), R4 // arg 2 157 SYSCALL $SYS_kill 158 RET 159 160 TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8 161 SYSCALL $SYS_getpid 162 MOVD R3, ret+0(FP) 163 RET 164 165 TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24 166 MOVD tgid+0(FP), R3 167 MOVD tid+8(FP), R4 168 MOVD sig+16(FP), R5 169 SYSCALL $SYS_tgkill 170 RET 171 172 TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24 173 MOVW mode+0(FP), R3 174 MOVD new+8(FP), R4 175 MOVD old+16(FP), R5 176 SYSCALL $SYS_setitimer 177 RET 178 179 TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28 180 MOVD addr+0(FP), R3 181 MOVD n+8(FP), R4 182 MOVD dst+16(FP), R5 183 SYSCALL $SYS_mincore 184 NEG R3 // caller expects negative errno 185 MOVW R3, ret+24(FP) 186 RET 187 188 // func walltime() (sec int64, nsec int32) 189 TEXT runtime·walltime(SB),NOSPLIT,$16-12 190 MOVD R1, R15 // R15 is unchanged by C code 191 MOVD g_m(g), R21 // R21 = m 192 193 MOVD $0, R3 // CLOCK_REALTIME 194 195 MOVD runtime·vdsoClockgettimeSym(SB), R12 // Check for VDSO availability 196 CMP R12, R0 197 BEQ fallback 198 199 // Set vdsoPC and vdsoSP for SIGPROF traceback. 200 // Save the old values on stack and restore them on exit, 201 // so this function is reentrant. 202 MOVD m_vdsoPC(R21), R4 203 MOVD m_vdsoSP(R21), R5 204 MOVD R4, 32(R1) 205 MOVD R5, 40(R1) 206 207 MOVD LR, R14 208 MOVD $ret-FIXED_FRAME(FP), R5 // caller's SP 209 MOVD R14, m_vdsoPC(R21) 210 MOVD R5, m_vdsoSP(R21) 211 212 MOVD m_curg(R21), R6 213 CMP g, R6 214 BNE noswitch 215 216 MOVD m_g0(R21), R7 217 MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack 218 219 noswitch: 220 SUB $16, R1 // Space for results 221 RLDICR $0, R1, $59, R1 // Align for C code 222 MOVD R12, CTR 223 MOVD R1, R4 224 225 // Store g on gsignal's stack, so if we receive a signal 226 // during VDSO code we can find the g. 227 // If we don't have a signal stack, we won't receive signal, 228 // so don't bother saving g. 229 // When using cgo, we already saved g on TLS, also don't save 230 // g here. 231 // Also don't save g if we are already on the signal stack. 232 // We won't get a nested signal. 233 MOVBZ runtime·iscgo(SB), R22 234 CMP R22, $0 235 BNE nosaveg 236 MOVD m_gsignal(R21), R22 // g.m.gsignal 237 CMP R22, $0 238 BEQ nosaveg 239 240 CMP g, R22 241 BEQ nosaveg 242 MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo 243 MOVD g, (R22) 244 245 BL (CTR) // Call from VDSO 246 247 MOVD $0, (R22) // clear g slot, R22 is unchanged by C code 248 249 JMP finish 250 251 nosaveg: 252 BL (CTR) // Call from VDSO 253 254 finish: 255 MOVD $0, R0 // Restore R0 256 MOVD 0(R1), R3 // sec 257 MOVD 8(R1), R5 // nsec 258 MOVD R15, R1 // Restore SP 259 260 // Restore vdsoPC, vdsoSP 261 // We don't worry about being signaled between the two stores. 262 // If we are not in a signal handler, we'll restore vdsoSP to 0, 263 // and no one will care about vdsoPC. If we are in a signal handler, 264 // we cannot receive another signal. 265 MOVD 40(R1), R6 266 MOVD R6, m_vdsoSP(R21) 267 MOVD 32(R1), R6 268 MOVD R6, m_vdsoPC(R21) 269 270 return: 271 MOVD R3, sec+0(FP) 272 MOVW R5, nsec+8(FP) 273 RET 274 275 // Syscall fallback 276 fallback: 277 ADD $32, R1, R4 278 SYSCALL $SYS_clock_gettime 279 MOVD 32(R1), R3 280 MOVD 40(R1), R5 281 JMP return 282 283 TEXT runtime·nanotime1(SB),NOSPLIT,$16-8 284 MOVD $1, R3 // CLOCK_MONOTONIC 285 286 MOVD R1, R15 // R15 is unchanged by C code 287 MOVD g_m(g), R21 // R21 = m 288 289 MOVD runtime·vdsoClockgettimeSym(SB), R12 // Check for VDSO availability 290 CMP R12, R0 291 BEQ fallback 292 293 // Set vdsoPC and vdsoSP for SIGPROF traceback. 294 // Save the old values on stack and restore them on exit, 295 // so this function is reentrant. 296 MOVD m_vdsoPC(R21), R4 297 MOVD m_vdsoSP(R21), R5 298 MOVD R4, 32(R1) 299 MOVD R5, 40(R1) 300 301 MOVD LR, R14 // R14 is unchanged by C code 302 MOVD $ret-FIXED_FRAME(FP), R5 // caller's SP 303 MOVD R14, m_vdsoPC(R21) 304 MOVD R5, m_vdsoSP(R21) 305 306 MOVD m_curg(R21), R6 307 CMP g, R6 308 BNE noswitch 309 310 MOVD m_g0(R21), R7 311 MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack 312 313 noswitch: 314 SUB $16, R1 // Space for results 315 RLDICR $0, R1, $59, R1 // Align for C code 316 MOVD R12, CTR 317 MOVD R1, R4 318 319 // Store g on gsignal's stack, so if we receive a signal 320 // during VDSO code we can find the g. 321 // If we don't have a signal stack, we won't receive signal, 322 // so don't bother saving g. 323 // When using cgo, we already saved g on TLS, also don't save 324 // g here. 325 // Also don't save g if we are already on the signal stack. 326 // We won't get a nested signal. 327 MOVBZ runtime·iscgo(SB), R22 328 CMP R22, $0 329 BNE nosaveg 330 MOVD m_gsignal(R21), R22 // g.m.gsignal 331 CMP R22, $0 332 BEQ nosaveg 333 334 CMP g, R22 335 BEQ nosaveg 336 MOVD (g_stack+stack_lo)(R22), R22 // g.m.gsignal.stack.lo 337 MOVD g, (R22) 338 339 BL (CTR) // Call from VDSO 340 341 MOVD $0, (R22) // clear g slot, R22 is unchanged by C code 342 343 JMP finish 344 345 nosaveg: 346 BL (CTR) // Call from VDSO 347 348 finish: 349 MOVD $0, R0 // Restore R0 350 MOVD 0(R1), R3 // sec 351 MOVD 8(R1), R5 // nsec 352 MOVD R15, R1 // Restore SP 353 354 // Restore vdsoPC, vdsoSP 355 // We don't worry about being signaled between the two stores. 356 // If we are not in a signal handler, we'll restore vdsoSP to 0, 357 // and no one will care about vdsoPC. If we are in a signal handler, 358 // we cannot receive another signal. 359 MOVD 40(R1), R6 360 MOVD R6, m_vdsoSP(R21) 361 MOVD 32(R1), R6 362 MOVD R6, m_vdsoPC(R21) 363 364 return: 365 // sec is in R3, nsec in R5 366 // return nsec in R3 367 MOVD $1000000000, R4 368 MULLD R4, R3 369 ADD R5, R3 370 MOVD R3, ret+0(FP) 371 RET 372 373 // Syscall fallback 374 fallback: 375 ADD $32, R1, R4 376 SYSCALL $SYS_clock_gettime 377 MOVD 32(R1), R3 378 MOVD 40(R1), R5 379 JMP return 380 381 TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28 382 MOVW how+0(FP), R3 383 MOVD new+8(FP), R4 384 MOVD old+16(FP), R5 385 MOVW size+24(FP), R6 386 SYSCALL $SYS_rt_sigprocmask 387 BVC 2(PC) 388 MOVD R0, 0xf0(R0) // crash 389 RET 390 391 TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36 392 MOVD sig+0(FP), R3 393 MOVD new+8(FP), R4 394 MOVD old+16(FP), R5 395 MOVD size+24(FP), R6 396 SYSCALL $SYS_rt_sigaction 397 BVC 2(PC) 398 NEG R3 // caller expects negative errno 399 MOVW R3, ret+32(FP) 400 RET 401 402 #ifdef GOARCH_ppc64le 403 // Call the function stored in _cgo_sigaction using the GCC calling convention. 404 TEXT runtime·callCgoSigaction(SB),NOSPLIT,$0 405 MOVD sig+0(FP), R3 406 MOVD new+8(FP), R4 407 MOVD old+16(FP), R5 408 MOVD _cgo_sigaction(SB), R12 409 MOVD R12, CTR // R12 should contain the function address 410 MOVD R1, R15 // Save R1 411 MOVD R2, 24(R1) // Save R2 412 SUB $48, R1 // reserve 32 (frame) + 16 bytes for sp-8 where fp may be saved. 413 RLDICR $0, R1, $59, R1 // Align to 16 bytes for C code 414 BL (CTR) 415 XOR R0, R0, R0 // Clear R0 as Go expects 416 MOVD R15, R1 // Restore R1 417 MOVD 24(R1), R2 // Restore R2 418 MOVW R3, ret+24(FP) // Return result 419 RET 420 #endif 421 422 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 423 MOVW sig+8(FP), R3 424 MOVD info+16(FP), R4 425 MOVD ctx+24(FP), R5 426 MOVD fn+0(FP), R12 427 MOVD R12, CTR 428 BL (CTR) 429 MOVD 24(R1), R2 430 RET 431 432 TEXT runtime·sigreturn(SB),NOSPLIT,$0-0 433 RET 434 435 #ifdef GOARCH_ppc64le 436 // ppc64le doesn't need function descriptors 437 // Save callee-save registers in the case of signal forwarding. 438 // Same as on ARM64 https://golang.org/issue/31827 . 439 TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0 440 #else 441 // function descriptor for the real sigtramp 442 TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0 443 DWORD $sigtramp<>(SB) 444 DWORD $0 445 DWORD $0 446 TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0 447 #endif 448 // Start with standard C stack frame layout and linkage. 449 MOVD LR, R0 450 MOVD R0, 16(R1) // Save LR in caller's frame. 451 MOVW CR, R0 // Save CR in caller's frame 452 MOVD R0, 8(R1) 453 // The stack must be acquired here and not 454 // in the automatic way based on stack size 455 // since that sequence clobbers R31 before it 456 // gets saved. 457 // We are being ultra safe here in saving the 458 // Vregs. The case where they might need to 459 // be saved is very unlikely. 460 MOVDU R1, -544(R1) 461 MOVD R14, 64(R1) 462 MOVD R15, 72(R1) 463 MOVD R16, 80(R1) 464 MOVD R17, 88(R1) 465 MOVD R18, 96(R1) 466 MOVD R19, 104(R1) 467 MOVD R20, 112(R1) 468 MOVD R21, 120(R1) 469 MOVD R22, 128(R1) 470 MOVD R23, 136(R1) 471 MOVD R24, 144(R1) 472 MOVD R25, 152(R1) 473 MOVD R26, 160(R1) 474 MOVD R27, 168(R1) 475 MOVD R28, 176(R1) 476 MOVD R29, 184(R1) 477 MOVD g, 192(R1) // R30 478 MOVD R31, 200(R1) 479 FMOVD F14, 208(R1) 480 FMOVD F15, 216(R1) 481 FMOVD F16, 224(R1) 482 FMOVD F17, 232(R1) 483 FMOVD F18, 240(R1) 484 FMOVD F19, 248(R1) 485 FMOVD F20, 256(R1) 486 FMOVD F21, 264(R1) 487 FMOVD F22, 272(R1) 488 FMOVD F23, 280(R1) 489 FMOVD F24, 288(R1) 490 FMOVD F25, 296(R1) 491 FMOVD F26, 304(R1) 492 FMOVD F27, 312(R1) 493 FMOVD F28, 320(R1) 494 FMOVD F29, 328(R1) 495 FMOVD F30, 336(R1) 496 FMOVD F31, 344(R1) 497 // Save V regs 498 // STXVD2X and LXVD2X used since 499 // we aren't sure of alignment. 500 // Endianness doesn't matter 501 // if we are just loading and 502 // storing values. 503 MOVD $352, R7 // V20 504 STXVD2X VS52, (R7)(R1) 505 ADD $16, R7 // V21 368 506 STXVD2X VS53, (R7)(R1) 507 ADD $16, R7 // V22 384 508 STXVD2X VS54, (R7)(R1) 509 ADD $16, R7 // V23 400 510 STXVD2X VS55, (R7)(R1) 511 ADD $16, R7 // V24 416 512 STXVD2X VS56, (R7)(R1) 513 ADD $16, R7 // V25 432 514 STXVD2X VS57, (R7)(R1) 515 ADD $16, R7 // V26 448 516 STXVD2X VS58, (R7)(R1) 517 ADD $16, R7 // V27 464 518 STXVD2X VS59, (R7)(R1) 519 ADD $16, R7 // V28 480 520 STXVD2X VS60, (R7)(R1) 521 ADD $16, R7 // V29 496 522 STXVD2X VS61, (R7)(R1) 523 ADD $16, R7 // V30 512 524 STXVD2X VS62, (R7)(R1) 525 ADD $16, R7 // V31 528 526 STXVD2X VS63, (R7)(R1) 527 528 // initialize essential registers (just in case) 529 BL runtime·reginit(SB) 530 531 // this might be called in external code context, 532 // where g is not set. 533 MOVBZ runtime·iscgo(SB), R6 534 CMP R6, $0 535 BEQ 2(PC) 536 BL runtime·load_g(SB) 537 538 MOVW R3, FIXED_FRAME+0(R1) 539 MOVD R4, FIXED_FRAME+8(R1) 540 MOVD R5, FIXED_FRAME+16(R1) 541 MOVD $runtime·sigtrampgo(SB), R12 542 MOVD R12, CTR 543 BL (CTR) 544 MOVD 24(R1), R2 // Should this be here? Where is it saved? 545 // Starts at 64; FIXED_FRAME is 32 546 MOVD 64(R1), R14 547 MOVD 72(R1), R15 548 MOVD 80(R1), R16 549 MOVD 88(R1), R17 550 MOVD 96(R1), R18 551 MOVD 104(R1), R19 552 MOVD 112(R1), R20 553 MOVD 120(R1), R21 554 MOVD 128(R1), R22 555 MOVD 136(R1), R23 556 MOVD 144(R1), R24 557 MOVD 152(R1), R25 558 MOVD 160(R1), R26 559 MOVD 168(R1), R27 560 MOVD 176(R1), R28 561 MOVD 184(R1), R29 562 MOVD 192(R1), g // R30 563 MOVD 200(R1), R31 564 FMOVD 208(R1), F14 565 FMOVD 216(R1), F15 566 FMOVD 224(R1), F16 567 FMOVD 232(R1), F17 568 FMOVD 240(R1), F18 569 FMOVD 248(R1), F19 570 FMOVD 256(R1), F20 571 FMOVD 264(R1), F21 572 FMOVD 272(R1), F22 573 FMOVD 280(R1), F23 574 FMOVD 288(R1), F24 575 FMOVD 292(R1), F25 576 FMOVD 300(R1), F26 577 FMOVD 308(R1), F27 578 FMOVD 316(R1), F28 579 FMOVD 328(R1), F29 580 FMOVD 336(R1), F30 581 FMOVD 344(R1), F31 582 MOVD $352, R7 583 LXVD2X (R7)(R1), VS52 584 ADD $16, R7 // 368 V21 585 LXVD2X (R7)(R1), VS53 586 ADD $16, R7 // 384 V22 587 LXVD2X (R7)(R1), VS54 588 ADD $16, R7 // 400 V23 589 LXVD2X (R7)(R1), VS55 590 ADD $16, R7 // 416 V24 591 LXVD2X (R7)(R1), VS56 592 ADD $16, R7 // 432 V25 593 LXVD2X (R7)(R1), VS57 594 ADD $16, R7 // 448 V26 595 LXVD2X (R7)(R1), VS58 596 ADD $16, R8 // 464 V27 597 LXVD2X (R7)(R1), VS59 598 ADD $16, R7 // 480 V28 599 LXVD2X (R7)(R1), VS60 600 ADD $16, R7 // 496 V29 601 LXVD2X (R7)(R1), VS61 602 ADD $16, R7 // 512 V30 603 LXVD2X (R7)(R1), VS62 604 ADD $16, R7 // 528 V31 605 LXVD2X (R7)(R1), VS63 606 ADD $544, R1 607 MOVD 8(R1), R0 608 MOVFL R0, $0xff 609 MOVD 16(R1), R0 610 MOVD R0, LR 611 612 RET 613 614 #ifdef GOARCH_ppc64le 615 // ppc64le doesn't need function descriptors 616 TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0 617 // The stack unwinder, presumably written in C, may not be able to 618 // handle Go frame correctly. So, this function is NOFRAME, and we 619 // save/restore LR manually. 620 MOVD LR, R10 621 622 // We're coming from C code, initialize essential registers. 623 CALL runtime·reginit(SB) 624 625 // If no traceback function, do usual sigtramp. 626 MOVD runtime·cgoTraceback(SB), R6 627 CMP $0, R6 628 BEQ sigtramp 629 630 // If no traceback support function, which means that 631 // runtime/cgo was not linked in, do usual sigtramp. 632 MOVD _cgo_callers(SB), R6 633 CMP $0, R6 634 BEQ sigtramp 635 636 // Set up g register. 637 CALL runtime·load_g(SB) 638 639 // Figure out if we are currently in a cgo call. 640 // If not, just do usual sigtramp. 641 // compared to ARM64 and others. 642 CMP $0, g 643 BEQ sigtrampnog // g == nil 644 MOVD g_m(g), R6 645 CMP $0, R6 646 BEQ sigtramp // g.m == nil 647 MOVW m_ncgo(R6), R7 648 CMPW $0, R7 649 BEQ sigtramp // g.m.ncgo = 0 650 MOVD m_curg(R6), R7 651 CMP $0, R7 652 BEQ sigtramp // g.m.curg == nil 653 MOVD g_syscallsp(R7), R7 654 CMP $0, R7 655 BEQ sigtramp // g.m.curg.syscallsp == 0 656 MOVD m_cgoCallers(R6), R7 // R7 is the fifth arg in C calling convention. 657 CMP $0, R7 658 BEQ sigtramp // g.m.cgoCallers == nil 659 MOVW m_cgoCallersUse(R6), R8 660 CMPW $0, R8 661 BNE sigtramp // g.m.cgoCallersUse != 0 662 663 // Jump to a function in runtime/cgo. 664 // That function, written in C, will call the user's traceback 665 // function with proper unwind info, and will then call back here. 666 // The first three arguments, and the fifth, are already in registers. 667 // Set the two remaining arguments now. 668 MOVD runtime·cgoTraceback(SB), R6 669 MOVD $runtime·sigtramp(SB), R8 670 MOVD _cgo_callers(SB), R12 671 MOVD R12, CTR 672 MOVD R10, LR // restore LR 673 JMP (CTR) 674 675 sigtramp: 676 MOVD R10, LR // restore LR 677 JMP runtime·sigtramp(SB) 678 679 sigtrampnog: 680 // Signal arrived on a non-Go thread. If this is SIGPROF, get a 681 // stack trace. 682 CMPW R3, $27 // 27 == SIGPROF 683 BNE sigtramp 684 685 // Lock sigprofCallersUse (cas from 0 to 1). 686 MOVW $1, R7 687 MOVD $runtime·sigprofCallersUse(SB), R8 688 SYNC 689 LWAR (R8), R6 690 CMPW $0, R6 691 BNE sigtramp 692 STWCCC R7, (R8) 693 BNE -4(PC) 694 ISYNC 695 696 // Jump to the traceback function in runtime/cgo. 697 // It will call back to sigprofNonGo, which will ignore the 698 // arguments passed in registers. 699 // First three arguments to traceback function are in registers already. 700 MOVD runtime·cgoTraceback(SB), R6 701 MOVD $runtime·sigprofCallers(SB), R7 702 MOVD $runtime·sigprofNonGoWrapper<>(SB), R8 703 MOVD _cgo_callers(SB), R12 704 MOVD R12, CTR 705 MOVD R10, LR // restore LR 706 JMP (CTR) 707 #else 708 // function descriptor for the real sigtramp 709 TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0 710 DWORD $cgoSigtramp<>(SB) 711 DWORD $0 712 DWORD $0 713 TEXT cgoSigtramp<>(SB),NOSPLIT,$0 714 JMP sigtramp<>(SB) 715 #endif 716 717 TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0 718 // We're coming from C code, set up essential register, then call sigprofNonGo. 719 CALL runtime·reginit(SB) 720 CALL runtime·sigprofNonGo(SB) 721 RET 722 723 TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0 724 MOVD addr+0(FP), R3 725 MOVD n+8(FP), R4 726 MOVW prot+16(FP), R5 727 MOVW flags+20(FP), R6 728 MOVW fd+24(FP), R7 729 MOVW off+28(FP), R8 730 731 SYSCALL $SYS_mmap 732 BVC ok 733 MOVD $0, p+32(FP) 734 MOVD R3, err+40(FP) 735 RET 736 ok: 737 MOVD R3, p+32(FP) 738 MOVD $0, err+40(FP) 739 RET 740 741 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0 742 MOVD addr+0(FP), R3 743 MOVD n+8(FP), R4 744 SYSCALL $SYS_munmap 745 BVC 2(PC) 746 MOVD R0, 0xf0(R0) 747 RET 748 749 TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0 750 MOVD addr+0(FP), R3 751 MOVD n+8(FP), R4 752 MOVW flags+16(FP), R5 753 SYSCALL $SYS_madvise 754 MOVW R3, ret+24(FP) 755 RET 756 757 // int64 futex(int32 *uaddr, int32 op, int32 val, 758 // struct timespec *timeout, int32 *uaddr2, int32 val2); 759 TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0 760 MOVD addr+0(FP), R3 761 MOVW op+8(FP), R4 762 MOVW val+12(FP), R5 763 MOVD ts+16(FP), R6 764 MOVD addr2+24(FP), R7 765 MOVW val3+32(FP), R8 766 SYSCALL $SYS_futex 767 BVC 2(PC) 768 NEG R3 // caller expects negative errno 769 MOVW R3, ret+40(FP) 770 RET 771 772 // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 773 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0 774 MOVW flags+0(FP), R3 775 MOVD stk+8(FP), R4 776 777 // Copy mp, gp, fn off parent stack for use by child. 778 // Careful: Linux system call clobbers ???. 779 MOVD mp+16(FP), R7 780 MOVD gp+24(FP), R8 781 MOVD fn+32(FP), R12 782 783 MOVD R7, -8(R4) 784 MOVD R8, -16(R4) 785 MOVD R12, -24(R4) 786 MOVD $1234, R7 787 MOVD R7, -32(R4) 788 789 SYSCALL $SYS_clone 790 BVC 2(PC) 791 NEG R3 // caller expects negative errno 792 793 // In parent, return. 794 CMP R3, $0 795 BEQ 3(PC) 796 MOVW R3, ret+40(FP) 797 RET 798 799 // In child, on new stack. 800 // initialize essential registers 801 BL runtime·reginit(SB) 802 MOVD -32(R1), R7 803 CMP R7, $1234 804 BEQ 2(PC) 805 MOVD R0, 0(R0) 806 807 // Initialize m->procid to Linux tid 808 SYSCALL $SYS_gettid 809 810 MOVD -24(R1), R12 // fn 811 MOVD -16(R1), R8 // g 812 MOVD -8(R1), R7 // m 813 814 CMP R7, $0 815 BEQ nog 816 CMP R8, $0 817 BEQ nog 818 819 MOVD R3, m_procid(R7) 820 821 // TODO: setup TLS. 822 823 // In child, set up new stack 824 MOVD R7, g_m(R8) 825 MOVD R8, g 826 //CALL runtime·stackcheck(SB) 827 828 nog: 829 // Call fn 830 MOVD R12, CTR 831 BL (CTR) 832 833 // It shouldn't return. If it does, exit that thread. 834 MOVW $111, R3 835 SYSCALL $SYS_exit 836 BR -2(PC) // keep exiting 837 838 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0 839 MOVD new+0(FP), R3 840 MOVD old+8(FP), R4 841 SYSCALL $SYS_sigaltstack 842 BVC 2(PC) 843 MOVD R0, 0xf0(R0) // crash 844 RET 845 846 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0 847 SYSCALL $SYS_sched_yield 848 RET 849 850 TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0 851 MOVD pid+0(FP), R3 852 MOVD len+8(FP), R4 853 MOVD buf+16(FP), R5 854 SYSCALL $SYS_sched_getaffinity 855 BVC 2(PC) 856 NEG R3 // caller expects negative errno 857 MOVW R3, ret+24(FP) 858 RET 859 860 // int32 runtime·epollcreate(int32 size); 861 TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0 862 MOVW size+0(FP), R3 863 SYSCALL $SYS_epoll_create 864 BVC 2(PC) 865 NEG R3 // caller expects negative errno 866 MOVW R3, ret+8(FP) 867 RET 868 869 // int32 runtime·epollcreate1(int32 flags); 870 TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0 871 MOVW flags+0(FP), R3 872 SYSCALL $SYS_epoll_create1 873 BVC 2(PC) 874 NEG R3 // caller expects negative errno 875 MOVW R3, ret+8(FP) 876 RET 877 878 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 879 TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0 880 MOVW epfd+0(FP), R3 881 MOVW op+4(FP), R4 882 MOVW fd+8(FP), R5 883 MOVD ev+16(FP), R6 884 SYSCALL $SYS_epoll_ctl 885 NEG R3 // caller expects negative errno 886 MOVW R3, ret+24(FP) 887 RET 888 889 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 890 TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0 891 MOVW epfd+0(FP), R3 892 MOVD ev+8(FP), R4 893 MOVW nev+16(FP), R5 894 MOVW timeout+20(FP), R6 895 SYSCALL $SYS_epoll_wait 896 BVC 2(PC) 897 NEG R3 // caller expects negative errno 898 MOVW R3, ret+24(FP) 899 RET 900 901 // void runtime·closeonexec(int32 fd); 902 TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0 903 MOVW fd+0(FP), R3 // fd 904 MOVD $2, R4 // F_SETFD 905 MOVD $1, R5 // FD_CLOEXEC 906 SYSCALL $SYS_fcntl 907 RET 908 909 // func runtime·setNonblock(int32 fd) 910 TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4 911 MOVW fd+0(FP), R3 // fd 912 MOVD $3, R4 // F_GETFL 913 MOVD $0, R5 914 SYSCALL $SYS_fcntl 915 OR $0x800, R3, R5 // O_NONBLOCK 916 MOVW fd+0(FP), R3 // fd 917 MOVD $4, R4 // F_SETFL 918 SYSCALL $SYS_fcntl 919 RET 920 921 // func sbrk0() uintptr 922 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0 923 // Implemented as brk(NULL). 924 MOVD $0, R3 925 SYSCALL $SYS_brk 926 MOVD R3, ret+0(FP) 927 RET 928 929 TEXT runtime·access(SB),$0-20 930 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go 931 MOVW R0, ret+16(FP) // for vet 932 RET 933 934 TEXT runtime·connect(SB),$0-28 935 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go 936 MOVW R0, ret+24(FP) // for vet 937 RET 938 939 TEXT runtime·socket(SB),$0-20 940 MOVD R0, 0(R0) // unimplemented, only needed for android; declared in stubs_linux.go 941 MOVW R0, ret+16(FP) // for vet 942 RET