github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/sys_openbsd_ppc64.s (about) 1 // Copyright 2023 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 // System calls and other sys.stuff for ppc64, OpenBSD 6 // System calls are implemented in libc/libpthread, this file 7 // contains trampolines that convert from Go to C calling convention. 8 // Some direct system call implementations currently remain. 9 // 10 11 #include "go_asm.h" 12 #include "go_tls.h" 13 #include "textflag.h" 14 15 #define CLOCK_REALTIME $0 16 #define CLOCK_MONOTONIC $3 17 18 // mstart_stub is the first function executed on a new thread started by pthread_create. 19 // It just does some low-level setup and then calls mstart. 20 // Note: called with the C calling convention. 21 TEXT runtime·mstart_stub(SB),NOSPLIT,$32 22 // R3 points to the m. 23 // We are already on m's g0 stack. 24 25 // Go relies on R0 being $0. 26 XOR R0, R0 27 28 // TODO(jsing): Save callee-save registers (R14-R31, F14-F31, V20-V31). 29 30 MOVD m_g0(R3), g 31 BL runtime·save_g(SB) 32 33 BL runtime·mstart(SB) 34 35 // TODO(jsing): Restore callee-save registers (R14-R31, F14-F31, V20-V31). 36 37 // Go is all done with this OS thread. 38 // Tell pthread everything is ok (we never join with this thread, so 39 // the value here doesn't really matter). 40 MOVD $0, R3 41 42 RET 43 44 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 45 MOVW sig+8(FP), R3 46 MOVD info+16(FP), R4 47 MOVD ctx+24(FP), R5 48 MOVD fn+0(FP), R12 49 MOVD R12, CTR 50 CALL (CTR) // Alignment for ELF ABI? 51 RET 52 53 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$16 54 // Go relies on R0 being $0 and we may have been executing non-Go code. 55 XOR R0, R0 56 57 // TODO(jsing): Save callee-save registers (R2, R14-R31, F14-F31). 58 // in the case of signal forwarding. 59 // Please refer to https://golang.org/issue/31827 . 60 61 // If called from an external code context, g will not be set. 62 BL runtime·load_g(SB) 63 64 BL runtime·sigtrampgo<ABIInternal>(SB) 65 66 // TODO(jsing): Restore callee-save registers. 67 68 RET 69 70 // These trampolines help convert from Go calling convention to C calling convention. 71 // They should be called with asmcgocall. 72 // A pointer to the arguments is passed in R3. 73 // A single int32 result is returned in R3. 74 // (For more results, make an args/results structure.) 75 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$32 76 MOVD 0(R3), R3 // arg 1 - attr 77 CALL libc_pthread_attr_init(SB) 78 RET 79 80 TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$32 81 MOVD 0(R3), R3 // arg 1 - attr 82 CALL libc_pthread_attr_destroy(SB) 83 RET 84 85 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$32 86 MOVD 8(R3), R4 // arg 2 - size 87 MOVD 0(R3), R3 // arg 1 - attr 88 CALL libc_pthread_attr_getstacksize(SB) 89 RET 90 91 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$32 92 MOVD 8(R3), R4 // arg 2 - state 93 MOVD 0(R3), R3 // arg 1 - attr 94 CALL libc_pthread_attr_setdetachstate(SB) 95 RET 96 97 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$32 98 MOVD 0(R3), R4 // arg 2 - attr 99 MOVD 8(R3), R5 // arg 3 - start 100 MOVD 16(R3), R6 // arg 4 - arg 101 102 MOVD R1, R15 103 SUB $64, R1 104 RLDCR $0, R1, $~15, R1 105 MOVD R1, R3 // arg 1 - &threadid (discard) 106 CALL libc_pthread_create(SB) 107 MOVD R15, R1 108 109 RET 110 111 TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$32 112 MOVD 8(R3), R4 // arg 2 - signal (int64) 113 MOVD $0, R5 // arg 3 - tcb 114 MOVW 0(R3), R3 // arg 1 - tid 115 CALL libc_thrkill(SB) 116 RET 117 118 TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$32 119 MOVW 8(R3), R4 // arg 2 - clock_id 120 MOVD 16(R3), R5 // arg 3 - abstime 121 MOVD 24(R3), R6 // arg 4 - lock 122 MOVD 32(R3), R7 // arg 5 - abort 123 MOVD 0(R3), R3 // arg 1 - id 124 CALL libc_thrsleep(SB) 125 RET 126 127 TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$32 128 MOVW 8(R3), R4 // arg 2 - count 129 MOVD 0(R3), R3 // arg 1 - id 130 CALL libc_thrwakeup(SB) 131 RET 132 133 TEXT runtime·exit_trampoline(SB),NOSPLIT,$32 134 MOVW 0(R3), R3 // arg 1 - status 135 CALL libc_exit(SB) 136 MOVD $0, R3 // crash on failure 137 MOVD R3, (R3) 138 RET 139 140 TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$32 141 MOVD R3, R14 // pointer to args 142 CALL libc_getthrid(SB) 143 MOVW R3, 0(R14) // return value 144 RET 145 146 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$32 147 MOVD R3, R14 // pointer to args 148 CALL libc_getpid(SB) // arg 1 - pid 149 MOVW 0(R14), R4 // arg 2 - signal 150 CALL libc_kill(SB) 151 RET 152 153 TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$32 154 CALL libc_sched_yield(SB) 155 RET 156 157 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$32 158 MOVD R3, R14 // pointer to args 159 MOVD 0(R14), R3 // arg 1 - addr 160 MOVD 8(R14), R4 // arg 2 - len 161 MOVW 16(R14), R5 // arg 3 - prot 162 MOVW 20(R14), R6 // arg 4 - flags 163 MOVW 24(R14), R7 // arg 5 - fid 164 MOVW 28(R14), R8 // arg 6 - offset 165 CALL libc_mmap(SB) 166 MOVD $0, R4 167 CMP R3, $-1 168 BNE noerr 169 CALL libc_errno(SB) 170 MOVW (R3), R4 // errno 171 MOVD $0, R3 172 noerr: 173 MOVD R3, 32(R14) 174 MOVD R4, 40(R14) 175 RET 176 177 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$32 178 MOVD 8(R3), R4 // arg 2 - len 179 MOVD 0(R3), R3 // arg 1 - addr 180 CALL libc_munmap(SB) 181 CMP R3, $-1 182 BNE 3(PC) 183 MOVD $0, R3 // crash on failure 184 MOVD R3, (R3) 185 RET 186 187 TEXT runtime·madvise_trampoline(SB),NOSPLIT,$32 188 MOVD 8(R3), R4 // arg 2 - len 189 MOVW 16(R3), R5 // arg 3 - advice 190 MOVD 0(R3), R3 // arg 1 - addr 191 CALL libc_madvise(SB) 192 // ignore failure - maybe pages are locked 193 RET 194 195 TEXT runtime·open_trampoline(SB),NOSPLIT,$32 196 MOVW 8(R3), R4 // arg 2 - flags 197 MOVW 12(R3), R5 // arg 3 - mode 198 MOVD 0(R3), R3 // arg 1 - path 199 MOVD $0, R6 // varargs 200 CALL libc_open(SB) 201 RET 202 203 TEXT runtime·close_trampoline(SB),NOSPLIT,$32 204 MOVW 0(R3), R3 // arg 1 - fd 205 CALL libc_close(SB) 206 RET 207 208 TEXT runtime·read_trampoline(SB),NOSPLIT,$32 209 MOVD 8(R3), R4 // arg 2 - buf 210 MOVW 16(R3), R5 // arg 3 - count 211 MOVW 0(R3), R3 // arg 1 - fd (int32) 212 CALL libc_read(SB) 213 CMP R3, $-1 214 BNE noerr 215 CALL libc_errno(SB) 216 MOVW (R3), R3 // errno 217 NEG R3, R3 // caller expects negative errno value 218 noerr: 219 RET 220 221 TEXT runtime·write_trampoline(SB),NOSPLIT,$32 222 MOVD 8(R3), R4 // arg 2 - buf 223 MOVW 16(R3), R5 // arg 3 - count 224 MOVD 0(R3), R3 // arg 1 - fd (uintptr) 225 CALL libc_write(SB) 226 CMP R3, $-1 227 BNE noerr 228 CALL libc_errno(SB) 229 MOVW (R3), R3 // errno 230 NEG R3, R3 // caller expects negative errno value 231 noerr: 232 RET 233 234 TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$32 235 MOVW 8(R3), R4 // arg 2 - flags 236 MOVD 0(R3), R3 // arg 1 - filedes 237 CALL libc_pipe2(SB) 238 CMP R3, $-1 239 BNE noerr 240 CALL libc_errno(SB) 241 MOVW (R3), R3 // errno 242 NEG R3, R3 // caller expects negative errno value 243 noerr: 244 RET 245 246 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$32 247 MOVD 8(R3), R4 // arg 2 - new 248 MOVD 16(R3), R5 // arg 3 - old 249 MOVW 0(R3), R3 // arg 1 - which 250 CALL libc_setitimer(SB) 251 RET 252 253 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$32 254 MOVW 0(R3), R3 // arg 1 - usec 255 CALL libc_usleep(SB) 256 RET 257 258 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$32 259 MOVW 8(R3), R4 // arg 2 - miblen 260 MOVD 16(R3), R5 // arg 3 - out 261 MOVD 24(R3), R6 // arg 4 - size 262 MOVD 32(R3), R7 // arg 5 - dst 263 MOVD 40(R3), R8 // arg 6 - ndst 264 MOVD 0(R3), R3 // arg 1 - mib 265 CALL libc_sysctl(SB) 266 RET 267 268 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$32 269 CALL libc_kqueue(SB) 270 RET 271 272 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$32 273 MOVD 8(R3), R4 // arg 2 - keventt 274 MOVW 16(R3), R5 // arg 3 - nch 275 MOVD 24(R3), R6 // arg 4 - ev 276 MOVW 32(R3), R7 // arg 5 - nev 277 MOVD 40(R3), R8 // arg 6 - ts 278 MOVW 0(R3), R3 // arg 1 - kq 279 CALL libc_kevent(SB) 280 CMP R3, $-1 281 BNE noerr 282 CALL libc_errno(SB) 283 MOVW (R3), R3 // errno 284 NEG R3, R3 // caller expects negative errno value 285 noerr: 286 RET 287 288 TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$32 289 MOVD 8(R3), R4 // arg 2 - tp 290 MOVW 0(R3), R3 // arg 1 - clock_id 291 CALL libc_clock_gettime(SB) 292 CMP R3, $-1 293 BNE noerr 294 CALL libc_errno(SB) 295 MOVW (R3), R3 // errno 296 NEG R3, R3 // caller expects negative errno value 297 noerr: 298 RET 299 300 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$32 301 MOVD R3, R14 // pointer to args 302 MOVW 0(R14), R3 // arg 1 - fd 303 MOVW 4(R14), R4 // arg 2 - cmd 304 MOVW 8(R14), R5 // arg 3 - arg 305 MOVD $0, R6 // vararg 306 CALL libc_fcntl(SB) 307 MOVD $0, R4 308 CMP R3, $-1 309 BNE noerr 310 CALL libc_errno(SB) 311 MOVW (R3), R4 // errno 312 MOVW $-1, R3 313 noerr: 314 MOVW R3, 12(R14) 315 MOVW R4, 16(R14) 316 RET 317 318 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$32 319 MOVD 8(R3), R4 // arg 2 - new 320 MOVD 16(R3), R5 // arg 3 - old 321 MOVW 0(R3), R3 // arg 1 - sig 322 CALL libc_sigaction(SB) 323 CMP R3, $-1 324 BNE 3(PC) 325 MOVD $0, R3 // crash on syscall failure 326 MOVD R3, (R3) 327 RET 328 329 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$32 330 MOVD 8(R3), R4 // arg 2 - new 331 MOVD 16(R3), R5 // arg 3 - old 332 MOVW 0(R3), R3 // arg 1 - how 333 CALL libc_pthread_sigmask(SB) 334 CMP R3, $-1 335 BNE 3(PC) 336 MOVD $0, R3 // crash on syscall failure 337 MOVD R3, (R3) 338 RET 339 340 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$32 341 MOVD 8(R3), R4 // arg 2 - old 342 MOVD 0(R3), R3 // arg 1 - new 343 CALL libc_sigaltstack(SB) 344 CMP R3, $-1 345 BNE 3(PC) 346 MOVD $0, R3 // crash on syscall failure 347 MOVD R3, (R3) 348 RET 349 350 TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$32 351 MOVD R3, R14 // pointer to args 352 CALL libc_getthrid(SB) 353 MOVW R3, 0(R14) // return value 354 RET 355 356 // syscall calls a function in libc on behalf of the syscall package. 357 // syscall takes a pointer to a struct like: 358 // struct { 359 // fn uintptr 360 // a1 uintptr 361 // a2 uintptr 362 // a3 uintptr 363 // r1 uintptr 364 // r2 uintptr 365 // err uintptr 366 // } 367 // syscall must be called on the g0 stack with the 368 // C calling convention (use libcCall). 369 // 370 // syscall expects a 32-bit result and tests for 32-bit -1 371 // to decide there was an error. 372 TEXT runtime·syscall(SB),NOSPLIT,$32 373 MOVD R3, R14 // pointer to args 374 375 MOVD (0*8)(R14), R12 // fn 376 MOVD (1*8)(R14), R3 // a1 377 MOVD (2*8)(R14), R4 // a2 378 MOVD (3*8)(R14), R5 // a3 379 MOVD $0, R6 // vararg 380 381 MOVD R12, CTR 382 CALL (CTR) 383 384 MOVD R3, (4*8)(R14) // r1 385 MOVD R4, (5*8)(R14) // r2 386 387 // Standard libc functions return -1 on error 388 // and set errno. 389 CMPW R3, $-1 390 BNE ok 391 392 // Get error code from libc. 393 CALL libc_errno(SB) 394 MOVW (R3), R3 395 MOVD R3, (6*8)(R14) // err 396 397 ok: 398 RET 399 400 // syscallX calls a function in libc on behalf of the syscall package. 401 // syscallX takes a pointer to a struct like: 402 // struct { 403 // fn uintptr 404 // a1 uintptr 405 // a2 uintptr 406 // a3 uintptr 407 // r1 uintptr 408 // r2 uintptr 409 // err uintptr 410 // } 411 // syscallX must be called on the g0 stack with the 412 // C calling convention (use libcCall). 413 // 414 // syscallX is like syscall but expects a 64-bit result 415 // and tests for 64-bit -1 to decide there was an error. 416 TEXT runtime·syscallX(SB),NOSPLIT,$32 417 MOVD R3, R14 // pointer to args 418 419 MOVD (0*8)(R14), R12 // fn 420 MOVD (1*8)(R14), R3 // a1 421 MOVD (2*8)(R14), R4 // a2 422 MOVD (3*8)(R14), R5 // a3 423 MOVD $0, R6 // vararg 424 425 MOVD R12, CTR 426 CALL (CTR) 427 428 MOVD R3, (4*8)(R14) // r1 429 MOVD R4, (5*8)(R14) // r2 430 431 // Standard libc functions return -1 on error 432 // and set errno. 433 CMP R3, $-1 434 BNE ok 435 436 // Get error code from libc. 437 CALL libc_errno(SB) 438 MOVW (R3), R3 439 MOVD R3, (6*8)(R14) // err 440 441 ok: 442 RET 443 444 // syscall6 calls a function in libc on behalf of the syscall package. 445 // syscall6 takes a pointer to a struct like: 446 // struct { 447 // fn uintptr 448 // a1 uintptr 449 // a2 uintptr 450 // a3 uintptr 451 // a4 uintptr 452 // a5 uintptr 453 // a6 uintptr 454 // r1 uintptr 455 // r2 uintptr 456 // err uintptr 457 // } 458 // syscall6 must be called on the g0 stack with the 459 // C calling convention (use libcCall). 460 // 461 // syscall6 expects a 32-bit result and tests for 32-bit -1 462 // to decide there was an error. 463 TEXT runtime·syscall6(SB),NOSPLIT,$32 464 MOVD R3, R14 // pointer to args 465 466 MOVD (0*8)(R14), R12 // fn 467 MOVD (1*8)(R14), R3 // a1 468 MOVD (2*8)(R14), R4 // a2 469 MOVD (3*8)(R14), R5 // a3 470 MOVD (4*8)(R14), R6 // a4 471 MOVD (5*8)(R14), R7 // a5 472 MOVD (6*8)(R14), R8 // a6 473 MOVD $0, R9 // vararg 474 475 MOVD R12, CTR 476 CALL (CTR) 477 478 MOVD R3, (7*8)(R14) // r1 479 MOVD R4, (8*8)(R14) // r2 480 481 // Standard libc functions return -1 on error 482 // and set errno. 483 CMPW R3, $-1 484 BNE ok 485 486 // Get error code from libc. 487 CALL libc_errno(SB) 488 MOVW (R3), R3 489 MOVD R3, (9*8)(R14) // err 490 491 ok: 492 RET 493 494 // syscall6X calls a function in libc on behalf of the syscall package. 495 // syscall6X takes a pointer to a struct like: 496 // struct { 497 // fn uintptr 498 // a1 uintptr 499 // a2 uintptr 500 // a3 uintptr 501 // a4 uintptr 502 // a5 uintptr 503 // a6 uintptr 504 // r1 uintptr 505 // r2 uintptr 506 // err uintptr 507 // } 508 // syscall6X must be called on the g0 stack with the 509 // C calling convention (use libcCall). 510 // 511 // syscall6X is like syscall6 but expects a 64-bit result 512 // and tests for 64-bit -1 to decide there was an error. 513 TEXT runtime·syscall6X(SB),NOSPLIT,$32 514 MOVD R3, R14 // pointer to args 515 516 MOVD (0*8)(R14), R12 // fn 517 MOVD (1*8)(R14), R3 // a1 518 MOVD (2*8)(R14), R4 // a2 519 MOVD (3*8)(R14), R5 // a3 520 MOVD (4*8)(R14), R6 // a4 521 MOVD (5*8)(R14), R7 // a5 522 MOVD (6*8)(R14), R8 // a6 523 MOVD $0, R9 // vararg 524 525 MOVD R12, CTR 526 CALL (CTR) 527 528 MOVD R3, (7*8)(R14) // r1 529 MOVD R4, (8*8)(R14) // r2 530 531 // Standard libc functions return -1 on error 532 // and set errno. 533 CMP R3, $-1 534 BNE ok 535 536 // Get error code from libc. 537 CALL libc_errno(SB) 538 MOVW (R3), R3 539 MOVD R3, (9*8)(R14) // err 540 541 ok: 542 RET 543 544 // syscall10 calls a function in libc on behalf of the syscall package. 545 // syscall10 takes a pointer to a struct like: 546 // struct { 547 // fn uintptr 548 // a1 uintptr 549 // a2 uintptr 550 // a3 uintptr 551 // a4 uintptr 552 // a5 uintptr 553 // a6 uintptr 554 // a7 uintptr 555 // a8 uintptr 556 // a9 uintptr 557 // a10 uintptr 558 // r1 uintptr 559 // r2 uintptr 560 // err uintptr 561 // } 562 // syscall10 must be called on the g0 stack with the 563 // C calling convention (use libcCall). Note that this is 564 // really syscall8 as a maximum of eight parameters can be 565 // passed via registers (and current usage does not exceed 566 // this). 567 TEXT runtime·syscall10(SB),NOSPLIT,$32 568 MOVD R3, R14 // pointer to args 569 570 MOVD (0*8)(R14), R12 // fn 571 MOVD (1*8)(R14), R3 // a1 572 MOVD (2*8)(R14), R4 // a2 573 MOVD (3*8)(R14), R5 // a3 574 MOVD (4*8)(R14), R6 // a4 575 MOVD (5*8)(R14), R7 // a5 576 MOVD (6*8)(R14), R8 // a6 577 MOVD (7*8)(R14), R9 // a7 578 MOVD (8*8)(R14), R10 // a8 579 580 MOVD R12, CTR 581 CALL (CTR) 582 583 MOVD R3, (11*8)(R14) // r1 584 MOVD R4, (12*8)(R14) // r2 585 586 // Standard libc functions return -1 on error 587 // and set errno. 588 CMPW R3, $-1 589 BNE ok 590 591 // Get error code from libc. 592 CALL libc_errno(SB) 593 MOVW (R3), R3 594 MOVD R3, (13*8)(R14) // err 595 596 ok: 597 RET 598 599 // syscall10X calls a function in libc on behalf of the syscall package. 600 // syscall10X takes a pointer to a struct like: 601 // struct { 602 // fn uintptr 603 // a1 uintptr 604 // a2 uintptr 605 // a3 uintptr 606 // a4 uintptr 607 // a5 uintptr 608 // a6 uintptr 609 // a7 uintptr 610 // a8 uintptr 611 // a9 uintptr 612 // a10 uintptr 613 // r1 uintptr 614 // r2 uintptr 615 // err uintptr 616 // } 617 // syscall10X must be called on the g0 stack with the 618 // C calling convention (use libcCall). Note that this is 619 // really syscall8X as a maximum of eight parameters can be 620 // passed via registers (and current usage does not exceed 621 // this). 622 // 623 // syscall10X is like syscall10 but expects a 64-bit result 624 // and tests for 64-bit -1 to decide there was an error. 625 TEXT runtime·syscall10X(SB),NOSPLIT,$32 626 MOVD R3, R14 // pointer to args 627 628 MOVD (0*8)(R14), R12 // fn 629 MOVD (1*8)(R14), R3 // a1 630 MOVD (2*8)(R14), R4 // a2 631 MOVD (3*8)(R14), R5 // a3 632 MOVD (4*8)(R14), R6 // a4 633 MOVD (5*8)(R14), R7 // a5 634 MOVD (6*8)(R14), R8 // a6 635 MOVD (7*8)(R14), R9 // a7 636 MOVD (8*8)(R14), R10 // a8 637 638 MOVD R12, CTR 639 CALL (CTR) 640 641 MOVD R3, (11*8)(R14) // r1 642 MOVD R4, (12*8)(R14) // r2 643 644 // Standard libc functions return -1 on error 645 // and set errno. 646 CMP R3, $-1 647 BNE ok 648 649 // Get error code from libc. 650 CALL libc_errno(SB) 651 MOVW (R3), R3 652 MOVD R3, (13*8)(R14) // err 653 654 ok: 655 RET