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