github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/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 // +build linux 6 // +build ppc64 ppc64le 7 8 // 9 // System calls and other sys.stuff for ppc64, Linux 10 // 11 12 #include "go_asm.h" 13 #include "go_tls.h" 14 #include "textflag.h" 15 #include "asm_ppc64x.h" 16 17 #define SYS_exit 1 18 #define SYS_read 3 19 #define SYS_write 4 20 #define SYS_open 5 21 #define SYS_close 6 22 #define SYS_getpid 20 23 #define SYS_kill 37 24 #define SYS_brk 45 25 #define SYS_fcntl 55 26 #define SYS_mmap 90 27 #define SYS_munmap 91 28 #define SYS_setitimer 104 29 #define SYS_clone 120 30 #define SYS_sched_yield 158 31 #define SYS_nanosleep 162 32 #define SYS_rt_sigreturn 172 33 #define SYS_rt_sigaction 173 34 #define SYS_rt_sigprocmask 174 35 #define SYS_sigaltstack 185 36 #define SYS_madvise 205 37 #define SYS_mincore 206 38 #define SYS_gettid 207 39 #define SYS_futex 221 40 #define SYS_sched_getaffinity 223 41 #define SYS_exit_group 234 42 #define SYS_epoll_create 236 43 #define SYS_epoll_ctl 237 44 #define SYS_epoll_wait 238 45 #define SYS_clock_gettime 246 46 #define SYS_tgkill 250 47 #define SYS_epoll_create1 315 48 49 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4 50 MOVW code+0(FP), R3 51 SYSCALL $SYS_exit_group 52 RET 53 54 // func exitThread(wait *uint32) 55 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8 56 MOVD wait+0(FP), R1 57 // We're done using the stack. 58 MOVW $0, R2 59 SYNC 60 MOVW R2, (R1) 61 MOVW $0, R3 // exit code 62 SYSCALL $SYS_exit 63 JMP 0(PC) 64 65 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20 66 MOVD name+0(FP), R3 67 MOVW mode+8(FP), R4 68 MOVW perm+12(FP), R5 69 SYSCALL $SYS_open 70 BVC 2(PC) 71 MOVW $-1, R3 72 MOVW R3, ret+16(FP) 73 RET 74 75 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12 76 MOVW fd+0(FP), R3 77 SYSCALL $SYS_close 78 BVC 2(PC) 79 MOVW $-1, R3 80 MOVW R3, ret+8(FP) 81 RET 82 83 TEXT runtime·write(SB),NOSPLIT|NOFRAME,$0-28 84 MOVD fd+0(FP), R3 85 MOVD p+8(FP), R4 86 MOVW n+16(FP), R5 87 SYSCALL $SYS_write 88 BVC 2(PC) 89 MOVW $-1, R3 90 MOVW R3, ret+24(FP) 91 RET 92 93 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28 94 MOVW fd+0(FP), R3 95 MOVD p+8(FP), R4 96 MOVW n+16(FP), R5 97 SYSCALL $SYS_read 98 BVC 2(PC) 99 MOVW $-1, R3 100 MOVW R3, ret+24(FP) 101 RET 102 103 TEXT runtime·usleep(SB),NOSPLIT,$16-4 104 MOVW usec+0(FP), R3 105 MOVD R3, R5 106 MOVW $1000000, R4 107 DIVD R4, R3 108 MOVD R3, 8(R1) 109 MOVW $1000, R4 110 MULLD R3, R4 111 SUB R4, R5 112 MOVD R5, 16(R1) 113 114 // nanosleep(&ts, 0) 115 ADD $8, R1, R3 116 MOVW $0, R4 117 SYSCALL $SYS_nanosleep 118 RET 119 120 TEXT runtime·gettid(SB),NOSPLIT,$0-4 121 SYSCALL $SYS_gettid 122 MOVW R3, ret+0(FP) 123 RET 124 125 TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0 126 SYSCALL $SYS_getpid 127 MOVW R3, R14 128 SYSCALL $SYS_gettid 129 MOVW R3, R4 // arg 2 tid 130 MOVW R14, R3 // arg 1 pid 131 MOVW sig+0(FP), R5 // arg 3 132 SYSCALL $SYS_tgkill 133 RET 134 135 TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0 136 SYSCALL $SYS_getpid 137 MOVW R3, R3 // arg 1 pid 138 MOVW sig+0(FP), R4 // arg 2 139 SYSCALL $SYS_kill 140 RET 141 142 TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24 143 MOVW mode+0(FP), R3 144 MOVD new+8(FP), R4 145 MOVD old+16(FP), R5 146 SYSCALL $SYS_setitimer 147 RET 148 149 TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28 150 MOVD addr+0(FP), R3 151 MOVD n+8(FP), R4 152 MOVD dst+16(FP), R5 153 SYSCALL $SYS_mincore 154 NEG R3 // caller expects negative errno 155 MOVW R3, ret+24(FP) 156 RET 157 158 // func walltime() (sec int64, nsec int32) 159 TEXT runtime·walltime(SB),NOSPLIT,$16 160 MOVD R1, R15 // R15 is unchanged by C code 161 MOVD g_m(g), R21 // R21 = m 162 163 MOVD $0, R3 // CLOCK_REALTIME 164 165 MOVD runtime·vdsoClockgettimeSym(SB), R12 // Check for VDSO availability 166 CMP R12, R0 167 BEQ fallback 168 169 // Set vdsoPC and vdsoSP for SIGPROF traceback. 170 MOVD LR, R14 171 MOVD R14, m_vdsoPC(R21) 172 MOVD R15, m_vdsoSP(R21) 173 174 MOVD m_curg(R21), R6 175 CMP g, R6 176 BNE noswitch 177 178 MOVD m_g0(R21), R7 179 MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack 180 181 noswitch: 182 SUB $16, R1 // Space for results 183 RLDICR $0, R1, $59, R1 // Align for C code 184 MOVD R12, CTR 185 MOVD R1, R4 186 BL (CTR) // Call from VDSO 187 MOVD $0, R0 // Restore R0 188 MOVD R0, m_vdsoSP(R21) // Clear vdsoSP 189 MOVD 0(R1), R3 // sec 190 MOVD 8(R1), R5 // nsec 191 MOVD R15, R1 // Restore SP 192 193 finish: 194 MOVD R3, sec+0(FP) 195 MOVW R5, nsec+8(FP) 196 RET 197 198 // Syscall fallback 199 fallback: 200 ADD $32, R1, R4 201 SYSCALL $SYS_clock_gettime 202 MOVD 32(R1), R3 203 MOVD 40(R1), R5 204 JMP finish 205 206 TEXT runtime·nanotime(SB),NOSPLIT,$16 207 MOVD $1, R3 // CLOCK_MONOTONIC 208 209 MOVD R1, R15 // R15 is unchanged by C code 210 MOVD g_m(g), R21 // R21 = m 211 212 MOVD runtime·vdsoClockgettimeSym(SB), R12 // Check for VDSO availability 213 CMP R12, R0 214 BEQ fallback 215 216 // Set vdsoPC and vdsoSP for SIGPROF traceback. 217 MOVD LR, R14 // R14 is unchanged by C code 218 MOVD R14, m_vdsoPC(R21) 219 MOVD R15, m_vdsoSP(R21) 220 221 MOVD m_curg(R21), R6 222 CMP g, R6 223 BNE noswitch 224 225 MOVD m_g0(R21), R7 226 MOVD (g_sched+gobuf_sp)(R7), R1 // Set SP to g0 stack 227 228 noswitch: 229 SUB $16, R1 // Space for results 230 RLDICR $0, R1, $59, R1 // Align for C code 231 MOVD R12, CTR 232 MOVD R1, R4 233 BL (CTR) // Call from VDSO 234 MOVD $0, R0 // Restore R0 235 MOVD $0, m_vdsoSP(R21) // Clear vdsoSP 236 MOVD 0(R1), R3 // sec 237 MOVD 8(R1), R5 // nsec 238 MOVD R15, R1 // Restore SP 239 240 finish: 241 // sec is in R3, nsec in R5 242 // return nsec in R3 243 MOVD $1000000000, R4 244 MULLD R4, R3 245 ADD R5, R3 246 MOVD R3, ret+0(FP) 247 RET 248 249 // Syscall fallback 250 fallback: 251 ADD $32, R1, R4 252 SYSCALL $SYS_clock_gettime 253 MOVD 32(R1), R3 254 MOVD 48(R1), R5 255 JMP finish 256 257 TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28 258 MOVW how+0(FP), R3 259 MOVD new+8(FP), R4 260 MOVD old+16(FP), R5 261 MOVW size+24(FP), R6 262 SYSCALL $SYS_rt_sigprocmask 263 BVC 2(PC) 264 MOVD R0, 0xf0(R0) // crash 265 RET 266 267 TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36 268 MOVD sig+0(FP), R3 269 MOVD new+8(FP), R4 270 MOVD old+16(FP), R5 271 MOVD size+24(FP), R6 272 SYSCALL $SYS_rt_sigaction 273 BVC 2(PC) 274 NEG R3 // caller expects negative errno 275 MOVW R3, ret+32(FP) 276 RET 277 278 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 279 MOVW sig+8(FP), R3 280 MOVD info+16(FP), R4 281 MOVD ctx+24(FP), R5 282 MOVD fn+0(FP), R12 283 MOVD R12, CTR 284 BL (CTR) 285 MOVD 24(R1), R2 286 RET 287 288 #ifdef GOARCH_ppc64le 289 // ppc64le doesn't need function descriptors 290 TEXT runtime·sigtramp(SB),NOSPLIT,$64 291 #else 292 // function descriptor for the real sigtramp 293 TEXT runtime·sigtramp(SB),NOSPLIT|NOFRAME,$0 294 DWORD $runtime·_sigtramp(SB) 295 DWORD $0 296 DWORD $0 297 TEXT runtime·_sigtramp(SB),NOSPLIT,$64 298 #endif 299 // initialize essential registers (just in case) 300 BL runtime·reginit(SB) 301 302 // this might be called in external code context, 303 // where g is not set. 304 MOVBZ runtime·iscgo(SB), R6 305 CMP R6, $0 306 BEQ 2(PC) 307 BL runtime·load_g(SB) 308 309 MOVW R3, FIXED_FRAME+0(R1) 310 MOVD R4, FIXED_FRAME+8(R1) 311 MOVD R5, FIXED_FRAME+16(R1) 312 MOVD $runtime·sigtrampgo(SB), R12 313 MOVD R12, CTR 314 BL (CTR) 315 MOVD 24(R1), R2 316 RET 317 318 #ifdef GOARCH_ppc64le 319 // ppc64le doesn't need function descriptors 320 TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0 321 // The stack unwinder, presumably written in C, may not be able to 322 // handle Go frame correctly. So, this function is NOFRAME, and we 323 // save/restore LR manually. 324 MOVD LR, R10 325 326 // We're coming from C code, initialize essential registers. 327 CALL runtime·reginit(SB) 328 329 // If no traceback function, do usual sigtramp. 330 MOVD runtime·cgoTraceback(SB), R6 331 CMP $0, R6 332 BEQ sigtramp 333 334 // If no traceback support function, which means that 335 // runtime/cgo was not linked in, do usual sigtramp. 336 MOVD _cgo_callers(SB), R6 337 CMP $0, R6 338 BEQ sigtramp 339 340 // Set up g register. 341 CALL runtime·load_g(SB) 342 343 // Figure out if we are currently in a cgo call. 344 // If not, just do usual sigtramp. 345 CMP $0, g 346 BEQ sigtrampnog // g == nil 347 MOVD g_m(g), R6 348 CMP $0, R6 349 BEQ sigtramp // g.m == nil 350 MOVW m_ncgo(R6), R7 351 CMPW $0, R7 352 BEQ sigtramp // g.m.ncgo = 0 353 MOVD m_curg(R6), R7 354 CMP $0, R7 355 BEQ sigtramp // g.m.curg == nil 356 MOVD g_syscallsp(R7), R7 357 CMP $0, R7 358 BEQ sigtramp // g.m.curg.syscallsp == 0 359 MOVD m_cgoCallers(R6), R7 // R7 is the fifth arg in C calling convention. 360 CMP $0, R7 361 BEQ sigtramp // g.m.cgoCallers == nil 362 MOVW m_cgoCallersUse(R6), R8 363 CMPW $0, R8 364 BNE sigtramp // g.m.cgoCallersUse != 0 365 366 // Jump to a function in runtime/cgo. 367 // That function, written in C, will call the user's traceback 368 // function with proper unwind info, and will then call back here. 369 // The first three arguments, and the fifth, are already in registers. 370 // Set the two remaining arguments now. 371 MOVD runtime·cgoTraceback(SB), R6 372 MOVD $runtime·sigtramp(SB), R8 373 MOVD _cgo_callers(SB), R12 374 MOVD R12, CTR 375 MOVD R10, LR // restore LR 376 JMP (CTR) 377 378 sigtramp: 379 MOVD R10, LR // restore LR 380 JMP runtime·sigtramp(SB) 381 382 sigtrampnog: 383 // Signal arrived on a non-Go thread. If this is SIGPROF, get a 384 // stack trace. 385 CMPW R3, $27 // 27 == SIGPROF 386 BNE sigtramp 387 388 // Lock sigprofCallersUse (cas from 0 to 1). 389 MOVW $1, R7 390 MOVD $runtime·sigprofCallersUse(SB), R8 391 SYNC 392 LWAR (R8), R6 393 CMPW $0, R6 394 BNE sigtramp 395 STWCCC R7, (R8) 396 BNE -4(PC) 397 ISYNC 398 399 // Jump to the traceback function in runtime/cgo. 400 // It will call back to sigprofNonGo, which will ignore the 401 // arguments passed in registers. 402 // First three arguments to traceback function are in registers already. 403 MOVD runtime·cgoTraceback(SB), R6 404 MOVD $runtime·sigprofCallers(SB), R7 405 MOVD $runtime·sigprofNonGoWrapper<>(SB), R8 406 MOVD _cgo_callers(SB), R12 407 MOVD R12, CTR 408 MOVD R10, LR // restore LR 409 JMP (CTR) 410 #else 411 // function descriptor for the real sigtramp 412 TEXT runtime·cgoSigtramp(SB),NOSPLIT|NOFRAME,$0 413 DWORD $runtime·_cgoSigtramp(SB) 414 DWORD $0 415 DWORD $0 416 TEXT runtime·_cgoSigtramp(SB),NOSPLIT,$0 417 JMP runtime·sigtramp(SB) 418 #endif 419 420 TEXT runtime·sigprofNonGoWrapper<>(SB),NOSPLIT,$0 421 // We're coming from C code, set up essential register, then call sigprofNonGo. 422 CALL runtime·reginit(SB) 423 CALL runtime·sigprofNonGo(SB) 424 RET 425 426 TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0 427 MOVD addr+0(FP), R3 428 MOVD n+8(FP), R4 429 MOVW prot+16(FP), R5 430 MOVW flags+20(FP), R6 431 MOVW fd+24(FP), R7 432 MOVW off+28(FP), R8 433 434 SYSCALL $SYS_mmap 435 BVC ok 436 MOVD $0, p+32(FP) 437 MOVD R3, err+40(FP) 438 RET 439 ok: 440 MOVD R3, p+32(FP) 441 MOVD $0, err+40(FP) 442 RET 443 444 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0 445 MOVD addr+0(FP), R3 446 MOVD n+8(FP), R4 447 SYSCALL $SYS_munmap 448 BVC 2(PC) 449 MOVD R0, 0xf0(R0) 450 RET 451 452 TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0 453 MOVD addr+0(FP), R3 454 MOVD n+8(FP), R4 455 MOVW flags+16(FP), R5 456 SYSCALL $SYS_madvise 457 MOVW R3, ret+24(FP) 458 RET 459 460 // int64 futex(int32 *uaddr, int32 op, int32 val, 461 // struct timespec *timeout, int32 *uaddr2, int32 val2); 462 TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0 463 MOVD addr+0(FP), R3 464 MOVW op+8(FP), R4 465 MOVW val+12(FP), R5 466 MOVD ts+16(FP), R6 467 MOVD addr2+24(FP), R7 468 MOVW val3+32(FP), R8 469 SYSCALL $SYS_futex 470 BVC 2(PC) 471 NEG R3 // caller expects negative errno 472 MOVW R3, ret+40(FP) 473 RET 474 475 // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 476 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0 477 MOVW flags+0(FP), R3 478 MOVD stk+8(FP), R4 479 480 // Copy mp, gp, fn off parent stack for use by child. 481 // Careful: Linux system call clobbers ???. 482 MOVD mp+16(FP), R7 483 MOVD gp+24(FP), R8 484 MOVD fn+32(FP), R12 485 486 MOVD R7, -8(R4) 487 MOVD R8, -16(R4) 488 MOVD R12, -24(R4) 489 MOVD $1234, R7 490 MOVD R7, -32(R4) 491 492 SYSCALL $SYS_clone 493 BVC 2(PC) 494 NEG R3 // caller expects negative errno 495 496 // In parent, return. 497 CMP R3, $0 498 BEQ 3(PC) 499 MOVW R3, ret+40(FP) 500 RET 501 502 // In child, on new stack. 503 // initialize essential registers 504 BL runtime·reginit(SB) 505 MOVD -32(R1), R7 506 CMP R7, $1234 507 BEQ 2(PC) 508 MOVD R0, 0(R0) 509 510 // Initialize m->procid to Linux tid 511 SYSCALL $SYS_gettid 512 513 MOVD -24(R1), R12 // fn 514 MOVD -16(R1), R8 // g 515 MOVD -8(R1), R7 // m 516 517 CMP R7, $0 518 BEQ nog 519 CMP R8, $0 520 BEQ nog 521 522 MOVD R3, m_procid(R7) 523 524 // TODO: setup TLS. 525 526 // In child, set up new stack 527 MOVD R7, g_m(R8) 528 MOVD R8, g 529 //CALL runtime·stackcheck(SB) 530 531 nog: 532 // Call fn 533 MOVD R12, CTR 534 BL (CTR) 535 536 // It shouldn't return. If it does, exit that thread. 537 MOVW $111, R3 538 SYSCALL $SYS_exit 539 BR -2(PC) // keep exiting 540 541 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0 542 MOVD new+0(FP), R3 543 MOVD old+8(FP), R4 544 SYSCALL $SYS_sigaltstack 545 BVC 2(PC) 546 MOVD R0, 0xf0(R0) // crash 547 RET 548 549 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0 550 SYSCALL $SYS_sched_yield 551 RET 552 553 TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0 554 MOVD pid+0(FP), R3 555 MOVD len+8(FP), R4 556 MOVD buf+16(FP), R5 557 SYSCALL $SYS_sched_getaffinity 558 BVC 2(PC) 559 NEG R3 // caller expects negative errno 560 MOVW R3, ret+24(FP) 561 RET 562 563 // int32 runtime·epollcreate(int32 size); 564 TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0 565 MOVW size+0(FP), R3 566 SYSCALL $SYS_epoll_create 567 BVC 2(PC) 568 NEG R3 // caller expects negative errno 569 MOVW R3, ret+8(FP) 570 RET 571 572 // int32 runtime·epollcreate1(int32 flags); 573 TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0 574 MOVW flags+0(FP), R3 575 SYSCALL $SYS_epoll_create1 576 BVC 2(PC) 577 NEG R3 // caller expects negative errno 578 MOVW R3, ret+8(FP) 579 RET 580 581 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 582 TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0 583 MOVW epfd+0(FP), R3 584 MOVW op+4(FP), R4 585 MOVW fd+8(FP), R5 586 MOVD ev+16(FP), R6 587 SYSCALL $SYS_epoll_ctl 588 NEG R3 // caller expects negative errno 589 MOVW R3, ret+24(FP) 590 RET 591 592 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 593 TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0 594 MOVW epfd+0(FP), R3 595 MOVD ev+8(FP), R4 596 MOVW nev+16(FP), R5 597 MOVW timeout+20(FP), R6 598 SYSCALL $SYS_epoll_wait 599 BVC 2(PC) 600 NEG R3 // caller expects negative errno 601 MOVW R3, ret+24(FP) 602 RET 603 604 // void runtime·closeonexec(int32 fd); 605 TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0 606 MOVW fd+0(FP), R3 // fd 607 MOVD $2, R4 // F_SETFD 608 MOVD $1, R5 // FD_CLOEXEC 609 SYSCALL $SYS_fcntl 610 RET 611 612 // func sbrk0() uintptr 613 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0 614 // Implemented as brk(NULL). 615 MOVD $0, R3 616 SYSCALL $SYS_brk 617 MOVD R3, ret+0(FP) 618 RET