github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/sys_darwin_arm64.s (about) 1 // Copyright 2015 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, Darwin 6 // System calls are implemented in libSystem, this file contains 7 // trampolines that convert from Go to C calling convention. 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 #include "cgo/abi_arm64.h" 13 14 #define CLOCK_REALTIME 0 15 16 TEXT notok<>(SB),NOSPLIT,$0 17 MOVD $0, R8 18 MOVD R8, (R8) 19 B 0(PC) 20 21 TEXT runtime·open_trampoline(SB),NOSPLIT,$0 22 SUB $16, RSP 23 MOVW 8(R0), R1 // arg 2 flags 24 MOVW 12(R0), R2 // arg 3 mode 25 MOVW R2, (RSP) // arg 3 is variadic, pass on stack 26 MOVD 0(R0), R0 // arg 1 pathname 27 BL libc_open(SB) 28 ADD $16, RSP 29 RET 30 31 TEXT runtime·close_trampoline(SB),NOSPLIT,$0 32 MOVW 0(R0), R0 // arg 1 fd 33 BL libc_close(SB) 34 RET 35 36 TEXT runtime·write_trampoline(SB),NOSPLIT,$0 37 MOVD 8(R0), R1 // arg 2 buf 38 MOVW 16(R0), R2 // arg 3 count 39 MOVW 0(R0), R0 // arg 1 fd 40 BL libc_write(SB) 41 MOVD $-1, R1 42 CMP R0, R1 43 BNE noerr 44 BL libc_error(SB) 45 MOVW (R0), R0 46 NEG R0, R0 // caller expects negative errno value 47 noerr: 48 RET 49 50 TEXT runtime·read_trampoline(SB),NOSPLIT,$0 51 MOVD 8(R0), R1 // arg 2 buf 52 MOVW 16(R0), R2 // arg 3 count 53 MOVW 0(R0), R0 // arg 1 fd 54 BL libc_read(SB) 55 MOVD $-1, R1 56 CMP R0, R1 57 BNE noerr 58 BL libc_error(SB) 59 MOVW (R0), R0 60 NEG R0, R0 // caller expects negative errno value 61 noerr: 62 RET 63 64 TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0 65 BL libc_pipe(SB) // pointer already in R0 66 CMP $0, R0 67 BEQ 3(PC) 68 BL libc_error(SB) // return negative errno value 69 NEG R0, R0 70 RET 71 72 TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0 73 MOVW 0(R0), R0 74 BL libc_exit(SB) 75 MOVD $1234, R0 76 MOVD $1002, R1 77 MOVD R0, (R1) // fail hard 78 79 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 80 MOVD 0(R0), R19 // signal 81 BL libc_getpid(SB) 82 // arg 1 pid already in R0 from getpid 83 MOVD R19, R1 // arg 2 signal 84 BL libc_kill(SB) 85 RET 86 87 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 88 MOVD R0, R19 89 MOVD 0(R19), R0 // arg 1 addr 90 MOVD 8(R19), R1 // arg 2 len 91 MOVW 16(R19), R2 // arg 3 prot 92 MOVW 20(R19), R3 // arg 4 flags 93 MOVW 24(R19), R4 // arg 5 fd 94 MOVW 28(R19), R5 // arg 6 off 95 BL libc_mmap(SB) 96 MOVD $0, R1 97 MOVD $-1, R2 98 CMP R0, R2 99 BNE ok 100 BL libc_error(SB) 101 MOVW (R0), R1 102 MOVD $0, R0 103 ok: 104 MOVD R0, 32(R19) // ret 1 p 105 MOVD R1, 40(R19) // ret 2 err 106 RET 107 108 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 109 MOVD 8(R0), R1 // arg 2 len 110 MOVD 0(R0), R0 // arg 1 addr 111 BL libc_munmap(SB) 112 CMP $0, R0 113 BEQ 2(PC) 114 BL notok<>(SB) 115 RET 116 117 TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0 118 MOVD 8(R0), R1 // arg 2 len 119 MOVW 16(R0), R2 // arg 3 advice 120 MOVD 0(R0), R0 // arg 1 addr 121 BL libc_madvise(SB) 122 RET 123 124 TEXT runtime·mlock_trampoline(SB),NOSPLIT,$0 125 MOVD 8(R0), R1 // arg 2 len 126 MOVD 0(R0), R0 // arg 1 addr 127 BL libc_mlock(SB) 128 RET 129 130 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0 131 MOVD 8(R0), R1 // arg 2 new 132 MOVD 16(R0), R2 // arg 3 old 133 MOVW 0(R0), R0 // arg 1 which 134 BL libc_setitimer(SB) 135 RET 136 137 TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0 138 MOVD R0, R1 // arg 2 timespec 139 MOVW $CLOCK_REALTIME, R0 // arg 1 clock_id 140 BL libc_clock_gettime(SB) 141 RET 142 143 GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size) 144 145 TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40 146 MOVD R0, R19 147 BL libc_mach_absolute_time(SB) 148 MOVD R0, 0(R19) 149 MOVW timebase<>+machTimebaseInfo_numer(SB), R20 150 MOVD $timebase<>+machTimebaseInfo_denom(SB), R21 151 LDARW (R21), R21 // atomic read 152 CMP $0, R21 153 BNE initialized 154 155 SUB $(machTimebaseInfo__size+15)/16*16, RSP 156 MOVD RSP, R0 157 BL libc_mach_timebase_info(SB) 158 MOVW machTimebaseInfo_numer(RSP), R20 159 MOVW machTimebaseInfo_denom(RSP), R21 160 ADD $(machTimebaseInfo__size+15)/16*16, RSP 161 162 MOVW R20, timebase<>+machTimebaseInfo_numer(SB) 163 MOVD $timebase<>+machTimebaseInfo_denom(SB), R22 164 STLRW R21, (R22) // atomic write 165 166 initialized: 167 MOVW R20, 8(R19) 168 MOVW R21, 12(R19) 169 RET 170 171 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 172 MOVW sig+8(FP), R0 173 MOVD info+16(FP), R1 174 MOVD ctx+24(FP), R2 175 MOVD fn+0(FP), R11 176 BL (R11) 177 RET 178 179 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$176 180 // Save callee-save registers in the case of signal forwarding. 181 // Please refer to https://golang.org/issue/31827 . 182 SAVE_R19_TO_R28(8*4) 183 SAVE_F8_TO_F15(8*14) 184 185 // Save arguments. 186 MOVW R0, (8*1)(RSP) // sig 187 MOVD R1, (8*2)(RSP) // info 188 MOVD R2, (8*3)(RSP) // ctx 189 190 // this might be called in external code context, 191 // where g is not set. 192 BL runtime·load_g(SB) 193 194 #ifdef GOOS_ios 195 MOVD RSP, R6 196 CMP $0, g 197 BEQ nog 198 // iOS always use the main stack to run the signal handler. 199 // We need to switch to gsignal ourselves. 200 MOVD g_m(g), R11 201 MOVD m_gsignal(R11), R5 202 MOVD (g_stack+stack_hi)(R5), R6 203 204 nog: 205 // Restore arguments. 206 MOVW (8*1)(RSP), R0 207 MOVD (8*2)(RSP), R1 208 MOVD (8*3)(RSP), R2 209 210 // Reserve space for args and the stack pointer on the 211 // gsignal stack. 212 SUB $48, R6 213 // Save stack pointer. 214 MOVD RSP, R4 215 MOVD R4, (8*4)(R6) 216 // Switch to gsignal stack. 217 MOVD R6, RSP 218 219 // Save arguments. 220 MOVW R0, (8*1)(RSP) 221 MOVD R1, (8*2)(RSP) 222 MOVD R2, (8*3)(RSP) 223 #endif 224 225 // Call sigtrampgo. 226 MOVD $runtime·sigtrampgo(SB), R11 227 BL (R11) 228 229 #ifdef GOOS_ios 230 // Switch to old stack. 231 MOVD (8*4)(RSP), R5 232 MOVD R5, RSP 233 #endif 234 235 // Restore callee-save registers. 236 RESTORE_R19_TO_R28(8*4) 237 RESTORE_F8_TO_F15(8*14) 238 239 RET 240 241 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 242 JMP runtime·sigtramp(SB) 243 244 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 245 MOVD 8(R0), R1 // arg 2 new 246 MOVD 16(R0), R2 // arg 3 old 247 MOVW 0(R0), R0 // arg 1 how 248 BL libc_pthread_sigmask(SB) 249 CMP $0, R0 250 BEQ 2(PC) 251 BL notok<>(SB) 252 RET 253 254 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 255 MOVD 8(R0), R1 // arg 2 new 256 MOVD 16(R0), R2 // arg 3 old 257 MOVW 0(R0), R0 // arg 1 how 258 BL libc_sigaction(SB) 259 CMP $0, R0 260 BEQ 2(PC) 261 BL notok<>(SB) 262 RET 263 264 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 265 MOVW 0(R0), R0 // arg 1 usec 266 BL libc_usleep(SB) 267 RET 268 269 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0 270 MOVW 8(R0), R1 // arg 2 miblen 271 MOVD 16(R0), R2 // arg 3 oldp 272 MOVD 24(R0), R3 // arg 4 oldlenp 273 MOVD 32(R0), R4 // arg 5 newp 274 MOVD 40(R0), R5 // arg 6 newlen 275 MOVD 0(R0), R0 // arg 1 mib 276 BL libc_sysctl(SB) 277 RET 278 279 TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0 280 MOVD 8(R0), R1 // arg 2 oldp 281 MOVD 16(R0), R2 // arg 3 oldlenp 282 MOVD 24(R0), R3 // arg 4 newp 283 MOVD 32(R0), R4 // arg 5 newlen 284 MOVD 0(R0), R0 // arg 1 name 285 BL libc_sysctlbyname(SB) 286 RET 287 288 289 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 290 BL libc_kqueue(SB) 291 RET 292 293 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0 294 MOVD 8(R0), R1 // arg 2 keventt 295 MOVW 16(R0), R2 // arg 3 nch 296 MOVD 24(R0), R3 // arg 4 ev 297 MOVW 32(R0), R4 // arg 5 nev 298 MOVD 40(R0), R5 // arg 6 ts 299 MOVW 0(R0), R0 // arg 1 kq 300 BL libc_kevent(SB) 301 MOVD $-1, R2 302 CMP R0, R2 303 BNE ok 304 BL libc_error(SB) 305 MOVW (R0), R0 // errno 306 NEG R0, R0 // caller wants it as a negative error code 307 ok: 308 RET 309 310 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 311 SUB $16, RSP 312 MOVW 4(R0), R1 // arg 2 cmd 313 MOVW 8(R0), R2 // arg 3 arg 314 MOVW R2, (RSP) // arg 3 is variadic, pass on stack 315 MOVW 0(R0), R0 // arg 1 fd 316 BL libc_fcntl(SB) 317 ADD $16, RSP 318 RET 319 320 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 321 #ifdef GOOS_ios 322 // sigaltstack on iOS is not supported and will always 323 // run the signal handler on the main stack, so our sigtramp has 324 // to do the stack switch ourselves. 325 MOVW $43, R0 326 BL libc_exit(SB) 327 #else 328 MOVD 8(R0), R1 // arg 2 old 329 MOVD 0(R0), R0 // arg 1 new 330 CALL libc_sigaltstack(SB) 331 CBZ R0, 2(PC) 332 BL notok<>(SB) 333 #endif 334 RET 335 336 // Thread related functions 337 338 // mstart_stub is the first function executed on a new thread started by pthread_create. 339 // It just does some low-level setup and then calls mstart. 340 // Note: called with the C calling convention. 341 TEXT runtime·mstart_stub(SB),NOSPLIT,$160 342 // R0 points to the m. 343 // We are already on m's g0 stack. 344 345 // Save callee-save registers. 346 SAVE_R19_TO_R28(8) 347 SAVE_F8_TO_F15(88) 348 349 MOVD m_g0(R0), g 350 BL ·save_g(SB) 351 352 BL runtime·mstart(SB) 353 354 // Restore callee-save registers. 355 RESTORE_R19_TO_R28(8) 356 RESTORE_F8_TO_F15(88) 357 358 // Go is all done with this OS thread. 359 // Tell pthread everything is ok (we never join with this thread, so 360 // the value here doesn't really matter). 361 MOVD $0, R0 362 363 RET 364 365 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 366 MOVD 0(R0), R0 // arg 1 attr 367 BL libc_pthread_attr_init(SB) 368 RET 369 370 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 371 MOVD 8(R0), R1 // arg 2 size 372 MOVD 0(R0), R0 // arg 1 attr 373 BL libc_pthread_attr_getstacksize(SB) 374 RET 375 376 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 377 MOVD 8(R0), R1 // arg 2 state 378 MOVD 0(R0), R0 // arg 1 attr 379 BL libc_pthread_attr_setdetachstate(SB) 380 RET 381 382 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0 383 SUB $16, RSP 384 MOVD 0(R0), R1 // arg 2 state 385 MOVD 8(R0), R2 // arg 3 start 386 MOVD 16(R0), R3 // arg 4 arg 387 MOVD RSP, R0 // arg 1 &threadid (which we throw away) 388 BL libc_pthread_create(SB) 389 ADD $16, RSP 390 RET 391 392 TEXT runtime·raise_trampoline(SB),NOSPLIT,$0 393 MOVW 0(R0), R0 // arg 1 sig 394 BL libc_raise(SB) 395 RET 396 397 TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0 398 MOVD 8(R0), R1 // arg 2 attr 399 MOVD 0(R0), R0 // arg 1 mutex 400 BL libc_pthread_mutex_init(SB) 401 RET 402 403 TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0 404 MOVD 0(R0), R0 // arg 1 mutex 405 BL libc_pthread_mutex_lock(SB) 406 RET 407 408 TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0 409 MOVD 0(R0), R0 // arg 1 mutex 410 BL libc_pthread_mutex_unlock(SB) 411 RET 412 413 TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0 414 MOVD 8(R0), R1 // arg 2 attr 415 MOVD 0(R0), R0 // arg 1 cond 416 BL libc_pthread_cond_init(SB) 417 RET 418 419 TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0 420 MOVD 8(R0), R1 // arg 2 mutex 421 MOVD 0(R0), R0 // arg 1 cond 422 BL libc_pthread_cond_wait(SB) 423 RET 424 425 TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0 426 MOVD 8(R0), R1 // arg 2 mutex 427 MOVD 16(R0), R2 // arg 3 timeout 428 MOVD 0(R0), R0 // arg 1 cond 429 BL libc_pthread_cond_timedwait_relative_np(SB) 430 RET 431 432 TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0 433 MOVD 0(R0), R0 // arg 1 cond 434 BL libc_pthread_cond_signal(SB) 435 RET 436 437 TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0 438 MOVD R0, R19 // R19 is callee-save 439 BL libc_pthread_self(SB) 440 MOVD R0, 0(R19) // return value 441 RET 442 443 TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0 444 MOVD 8(R0), R1 // arg 2 sig 445 MOVD 0(R0), R0 // arg 1 thread 446 BL libc_pthread_kill(SB) 447 RET 448 449 TEXT runtime·pthread_key_create_trampoline(SB),NOSPLIT,$0 450 MOVD 8(R0), R1 // arg 2 destructor 451 MOVD 0(R0), R0 // arg 1 *key 452 BL libc_pthread_key_create(SB) 453 RET 454 455 TEXT runtime·pthread_setspecific_trampoline(SB),NOSPLIT,$0 456 MOVD 8(R0), R1 // arg 2 value 457 MOVD 0(R0), R0 // arg 1 key 458 BL libc_pthread_setspecific(SB) 459 RET 460 461 TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0 462 MOVD $0, R0 // arg 1 val 463 BL libc_notify_is_valid_token(SB) 464 BL libc_xpc_date_create_from_current(SB) 465 RET 466 467 // syscall calls a function in libc on behalf of the syscall package. 468 // syscall takes a pointer to a struct like: 469 // struct { 470 // fn uintptr 471 // a1 uintptr 472 // a2 uintptr 473 // a3 uintptr 474 // r1 uintptr 475 // r2 uintptr 476 // err uintptr 477 // } 478 // syscall must be called on the g0 stack with the 479 // C calling convention (use libcCall). 480 TEXT runtime·syscall(SB),NOSPLIT,$0 481 SUB $16, RSP // push structure pointer 482 MOVD R0, 8(RSP) 483 484 MOVD 0(R0), R12 // fn 485 MOVD 16(R0), R1 // a2 486 MOVD 24(R0), R2 // a3 487 MOVD 8(R0), R0 // a1 488 489 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. 490 // (Because ios decided not to adhere to the standard arm64 calling convention, sigh...) 491 // The only libSystem calls we support that are vararg are open, fcntl, and ioctl, 492 // which are all of the form fn(x, y, ...). So we just need to put the 3rd arg 493 // on the stack as well. 494 // If we ever have other vararg libSystem calls, we might need to handle more cases. 495 MOVD R2, (RSP) 496 497 BL (R12) 498 499 MOVD 8(RSP), R2 // pop structure pointer 500 ADD $16, RSP 501 MOVD R0, 32(R2) // save r1 502 MOVD R1, 40(R2) // save r2 503 CMPW $-1, R0 504 BNE ok 505 SUB $16, RSP // push structure pointer 506 MOVD R2, 8(RSP) 507 BL libc_error(SB) 508 MOVW (R0), R0 509 MOVD 8(RSP), R2 // pop structure pointer 510 ADD $16, RSP 511 MOVD R0, 48(R2) // save err 512 ok: 513 RET 514 515 // syscallX calls a function in libc on behalf of the syscall package. 516 // syscallX takes a pointer to a struct like: 517 // struct { 518 // fn uintptr 519 // a1 uintptr 520 // a2 uintptr 521 // a3 uintptr 522 // r1 uintptr 523 // r2 uintptr 524 // err uintptr 525 // } 526 // syscallX must be called on the g0 stack with the 527 // C calling convention (use libcCall). 528 TEXT runtime·syscallX(SB),NOSPLIT,$0 529 SUB $16, RSP // push structure pointer 530 MOVD R0, (RSP) 531 532 MOVD 0(R0), R12 // fn 533 MOVD 16(R0), R1 // a2 534 MOVD 24(R0), R2 // a3 535 MOVD 8(R0), R0 // a1 536 BL (R12) 537 538 MOVD (RSP), R2 // pop structure pointer 539 ADD $16, RSP 540 MOVD R0, 32(R2) // save r1 541 MOVD R1, 40(R2) // save r2 542 CMP $-1, R0 543 BNE ok 544 SUB $16, RSP // push structure pointer 545 MOVD R2, (RSP) 546 BL libc_error(SB) 547 MOVW (R0), R0 548 MOVD (RSP), R2 // pop structure pointer 549 ADD $16, RSP 550 MOVD R0, 48(R2) // save err 551 ok: 552 RET 553 554 // syscallPtr is like syscallX except that the libc function reports an 555 // error by returning NULL and setting errno. 556 TEXT runtime·syscallPtr(SB),NOSPLIT,$0 557 SUB $16, RSP // push structure pointer 558 MOVD R0, (RSP) 559 560 MOVD 0(R0), R12 // fn 561 MOVD 16(R0), R1 // a2 562 MOVD 24(R0), R2 // a3 563 MOVD 8(R0), R0 // a1 564 BL (R12) 565 566 MOVD (RSP), R2 // pop structure pointer 567 ADD $16, RSP 568 MOVD R0, 32(R2) // save r1 569 MOVD R1, 40(R2) // save r2 570 CMP $0, R0 571 BNE ok 572 SUB $16, RSP // push structure pointer 573 MOVD R2, (RSP) 574 BL libc_error(SB) 575 MOVW (R0), R0 576 MOVD (RSP), R2 // pop structure pointer 577 ADD $16, RSP 578 MOVD R0, 48(R2) // save err 579 ok: 580 RET 581 582 // syscall6 calls a function in libc on behalf of the syscall package. 583 // syscall6 takes a pointer to a struct like: 584 // struct { 585 // fn uintptr 586 // a1 uintptr 587 // a2 uintptr 588 // a3 uintptr 589 // a4 uintptr 590 // a5 uintptr 591 // a6 uintptr 592 // r1 uintptr 593 // r2 uintptr 594 // err uintptr 595 // } 596 // syscall6 must be called on the g0 stack with the 597 // C calling convention (use libcCall). 598 TEXT runtime·syscall6(SB),NOSPLIT,$0 599 SUB $16, RSP // push structure pointer 600 MOVD R0, 8(RSP) 601 602 MOVD 0(R0), R12 // fn 603 MOVD 16(R0), R1 // a2 604 MOVD 24(R0), R2 // a3 605 MOVD 32(R0), R3 // a4 606 MOVD 40(R0), R4 // a5 607 MOVD 48(R0), R5 // a6 608 MOVD 8(R0), R0 // a1 609 610 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. 611 // See syscall above. The only function this applies to is openat, for which the 4th 612 // arg must be on the stack. 613 MOVD R3, (RSP) 614 615 BL (R12) 616 617 MOVD 8(RSP), R2 // pop structure pointer 618 ADD $16, RSP 619 MOVD R0, 56(R2) // save r1 620 MOVD R1, 64(R2) // save r2 621 CMPW $-1, R0 622 BNE ok 623 SUB $16, RSP // push structure pointer 624 MOVD R2, 8(RSP) 625 BL libc_error(SB) 626 MOVW (R0), R0 627 MOVD 8(RSP), R2 // pop structure pointer 628 ADD $16, RSP 629 MOVD R0, 72(R2) // save err 630 ok: 631 RET 632 633 // syscall6X calls a function in libc on behalf of the syscall package. 634 // syscall6X takes a pointer to a struct like: 635 // struct { 636 // fn uintptr 637 // a1 uintptr 638 // a2 uintptr 639 // a3 uintptr 640 // a4 uintptr 641 // a5 uintptr 642 // a6 uintptr 643 // r1 uintptr 644 // r2 uintptr 645 // err uintptr 646 // } 647 // syscall6X must be called on the g0 stack with the 648 // C calling convention (use libcCall). 649 TEXT runtime·syscall6X(SB),NOSPLIT,$0 650 SUB $16, RSP // push structure pointer 651 MOVD R0, (RSP) 652 653 MOVD 0(R0), R12 // fn 654 MOVD 16(R0), R1 // a2 655 MOVD 24(R0), R2 // a3 656 MOVD 32(R0), R3 // a4 657 MOVD 40(R0), R4 // a5 658 MOVD 48(R0), R5 // a6 659 MOVD 8(R0), R0 // a1 660 BL (R12) 661 662 MOVD (RSP), R2 // pop structure pointer 663 ADD $16, RSP 664 MOVD R0, 56(R2) // save r1 665 MOVD R1, 64(R2) // save r2 666 CMP $-1, R0 667 BNE ok 668 SUB $16, RSP // push structure pointer 669 MOVD R2, (RSP) 670 BL libc_error(SB) 671 MOVW (R0), R0 672 MOVD (RSP), R2 // pop structure pointer 673 ADD $16, RSP 674 MOVD R0, 72(R2) // save err 675 ok: 676 RET 677 678 // syscall9 calls a function in libc on behalf of the syscall package. 679 // syscall9 takes a pointer to a struct like: 680 // struct { 681 // fn uintptr 682 // a1 uintptr 683 // a2 uintptr 684 // a3 uintptr 685 // a4 uintptr 686 // a5 uintptr 687 // a6 uintptr 688 // a7 uintptr 689 // a8 uintptr 690 // a9 uintptr 691 // r1 uintptr 692 // r2 uintptr 693 // err uintptr 694 // } 695 // syscall9 must be called on the g0 stack with the 696 // C calling convention (use libcCall). 697 TEXT runtime·syscall9(SB),NOSPLIT,$0 698 SUB $16, RSP // push structure pointer 699 MOVD R0, 8(RSP) 700 701 MOVD 0(R0), R12 // fn 702 MOVD 16(R0), R1 // a2 703 MOVD 24(R0), R2 // a3 704 MOVD 32(R0), R3 // a4 705 MOVD 40(R0), R4 // a5 706 MOVD 48(R0), R5 // a6 707 MOVD 56(R0), R6 // a7 708 MOVD 64(R0), R7 // a8 709 MOVD 72(R0), R8 // a9 710 MOVD 8(R0), R0 // a1 711 712 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. 713 // See syscall above. The only function this applies to is openat, for which the 4th 714 // arg must be on the stack. 715 MOVD R3, (RSP) 716 717 BL (R12) 718 719 MOVD 8(RSP), R2 // pop structure pointer 720 ADD $16, RSP 721 MOVD R0, 80(R2) // save r1 722 MOVD R1, 88(R2) // save r2 723 CMPW $-1, R0 724 BNE ok 725 SUB $16, RSP // push structure pointer 726 MOVD R2, 8(RSP) 727 BL libc_error(SB) 728 MOVW (R0), R0 729 MOVD 8(RSP), R2 // pop structure pointer 730 ADD $16, RSP 731 MOVD R0, 96(R2) // save err 732 ok: 733 RET 734 735 // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors, 736 // takes 5 uintptrs and 1 float64, and only returns one value, 737 // for use with standard C ABI functions. 738 TEXT runtime·syscall_x509(SB),NOSPLIT,$0 739 SUB $16, RSP // push structure pointer 740 MOVD R0, (RSP) 741 742 MOVD 0(R0), R12 // fn 743 MOVD 16(R0), R1 // a2 744 MOVD 24(R0), R2 // a3 745 MOVD 32(R0), R3 // a4 746 MOVD 40(R0), R4 // a5 747 FMOVD 48(R0), F0 // f1 748 MOVD 8(R0), R0 // a1 749 BL (R12) 750 751 MOVD (RSP), R2 // pop structure pointer 752 ADD $16, RSP 753 MOVD R0, 56(R2) // save r1 754 RET