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