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