github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/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 // syscall calls a function in libc on behalf of the syscall package. 462 // syscall takes a pointer to a struct like: 463 // struct { 464 // fn uintptr 465 // a1 uintptr 466 // a2 uintptr 467 // a3 uintptr 468 // r1 uintptr 469 // r2 uintptr 470 // err uintptr 471 // } 472 // syscall must be called on the g0 stack with the 473 // C calling convention (use libcCall). 474 TEXT runtime·syscall(SB),NOSPLIT,$0 475 SUB $16, RSP // push structure pointer 476 MOVD R0, 8(RSP) 477 478 MOVD 0(R0), R12 // fn 479 MOVD 16(R0), R1 // a2 480 MOVD 24(R0), R2 // a3 481 MOVD 8(R0), R0 // a1 482 483 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. 484 // (Because ios decided not to adhere to the standard arm64 calling convention, sigh...) 485 // The only libSystem calls we support that are vararg are open, fcntl, and ioctl, 486 // which are all of the form fn(x, y, ...). So we just need to put the 3rd arg 487 // on the stack as well. 488 // If we ever have other vararg libSystem calls, we might need to handle more cases. 489 MOVD R2, (RSP) 490 491 BL (R12) 492 493 MOVD 8(RSP), R2 // pop structure pointer 494 ADD $16, RSP 495 MOVD R0, 32(R2) // save r1 496 MOVD R1, 40(R2) // save r2 497 CMPW $-1, R0 498 BNE ok 499 SUB $16, RSP // push structure pointer 500 MOVD R2, 8(RSP) 501 BL libc_error(SB) 502 MOVW (R0), R0 503 MOVD 8(RSP), R2 // pop structure pointer 504 ADD $16, RSP 505 MOVD R0, 48(R2) // save err 506 ok: 507 RET 508 509 // syscallX calls a function in libc on behalf of the syscall package. 510 // syscallX takes a pointer to a struct like: 511 // struct { 512 // fn uintptr 513 // a1 uintptr 514 // a2 uintptr 515 // a3 uintptr 516 // r1 uintptr 517 // r2 uintptr 518 // err uintptr 519 // } 520 // syscallX must be called on the g0 stack with the 521 // C calling convention (use libcCall). 522 TEXT runtime·syscallX(SB),NOSPLIT,$0 523 SUB $16, RSP // push structure pointer 524 MOVD R0, (RSP) 525 526 MOVD 0(R0), R12 // fn 527 MOVD 16(R0), R1 // a2 528 MOVD 24(R0), R2 // a3 529 MOVD 8(R0), R0 // a1 530 BL (R12) 531 532 MOVD (RSP), R2 // pop structure pointer 533 ADD $16, RSP 534 MOVD R0, 32(R2) // save r1 535 MOVD R1, 40(R2) // save r2 536 CMP $-1, R0 537 BNE ok 538 SUB $16, RSP // push structure pointer 539 MOVD R2, (RSP) 540 BL libc_error(SB) 541 MOVW (R0), R0 542 MOVD (RSP), R2 // pop structure pointer 543 ADD $16, RSP 544 MOVD R0, 48(R2) // save err 545 ok: 546 RET 547 548 // syscallPtr is like syscallX except that the libc function reports an 549 // error by returning NULL and setting errno. 550 TEXT runtime·syscallPtr(SB),NOSPLIT,$0 551 SUB $16, RSP // push structure pointer 552 MOVD R0, (RSP) 553 554 MOVD 0(R0), R12 // fn 555 MOVD 16(R0), R1 // a2 556 MOVD 24(R0), R2 // a3 557 MOVD 8(R0), R0 // a1 558 BL (R12) 559 560 MOVD (RSP), R2 // pop structure pointer 561 ADD $16, RSP 562 MOVD R0, 32(R2) // save r1 563 MOVD R1, 40(R2) // save r2 564 CMP $0, R0 565 BNE ok 566 SUB $16, RSP // push structure pointer 567 MOVD R2, (RSP) 568 BL libc_error(SB) 569 MOVW (R0), R0 570 MOVD (RSP), R2 // pop structure pointer 571 ADD $16, RSP 572 MOVD R0, 48(R2) // save err 573 ok: 574 RET 575 576 // syscall6 calls a function in libc on behalf of the syscall package. 577 // syscall6 takes a pointer to a struct like: 578 // struct { 579 // fn uintptr 580 // a1 uintptr 581 // a2 uintptr 582 // a3 uintptr 583 // a4 uintptr 584 // a5 uintptr 585 // a6 uintptr 586 // r1 uintptr 587 // r2 uintptr 588 // err uintptr 589 // } 590 // syscall6 must be called on the g0 stack with the 591 // C calling convention (use libcCall). 592 TEXT runtime·syscall6(SB),NOSPLIT,$0 593 SUB $16, RSP // push structure pointer 594 MOVD R0, 8(RSP) 595 596 MOVD 0(R0), R12 // fn 597 MOVD 16(R0), R1 // a2 598 MOVD 24(R0), R2 // a3 599 MOVD 32(R0), R3 // a4 600 MOVD 40(R0), R4 // a5 601 MOVD 48(R0), R5 // a6 602 MOVD 8(R0), R0 // a1 603 604 // If fn is declared as vararg, we have to pass the vararg arguments on the stack. 605 // See syscall above. The only function this applies to is openat, for which the 4th 606 // arg must be on the stack. 607 MOVD R3, (RSP) 608 609 BL (R12) 610 611 MOVD 8(RSP), R2 // pop structure pointer 612 ADD $16, RSP 613 MOVD R0, 56(R2) // save r1 614 MOVD R1, 64(R2) // save r2 615 CMPW $-1, R0 616 BNE ok 617 SUB $16, RSP // push structure pointer 618 MOVD R2, 8(RSP) 619 BL libc_error(SB) 620 MOVW (R0), R0 621 MOVD 8(RSP), R2 // pop structure pointer 622 ADD $16, RSP 623 MOVD R0, 72(R2) // save err 624 ok: 625 RET 626 627 // syscall6X calls a function in libc on behalf of the syscall package. 628 // syscall6X takes a pointer to a struct like: 629 // struct { 630 // fn uintptr 631 // a1 uintptr 632 // a2 uintptr 633 // a3 uintptr 634 // a4 uintptr 635 // a5 uintptr 636 // a6 uintptr 637 // r1 uintptr 638 // r2 uintptr 639 // err uintptr 640 // } 641 // syscall6X must be called on the g0 stack with the 642 // C calling convention (use libcCall). 643 TEXT runtime·syscall6X(SB),NOSPLIT,$0 644 SUB $16, RSP // push structure pointer 645 MOVD R0, (RSP) 646 647 MOVD 0(R0), R12 // fn 648 MOVD 16(R0), R1 // a2 649 MOVD 24(R0), R2 // a3 650 MOVD 32(R0), R3 // a4 651 MOVD 40(R0), R4 // a5 652 MOVD 48(R0), R5 // a6 653 MOVD 8(R0), R0 // a1 654 BL (R12) 655 656 MOVD (RSP), R2 // pop structure pointer 657 ADD $16, RSP 658 MOVD R0, 56(R2) // save r1 659 MOVD R1, 64(R2) // save r2 660 CMP $-1, R0 661 BNE ok 662 SUB $16, RSP // push structure pointer 663 MOVD R2, (RSP) 664 BL libc_error(SB) 665 MOVW (R0), R0 666 MOVD (RSP), R2 // pop structure pointer 667 ADD $16, RSP 668 MOVD R0, 72(R2) // save err 669 ok: 670 RET 671 672 // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors, 673 // takes 5 uintptrs and 1 float64, and only returns one value, 674 // for use with standard C ABI functions. 675 TEXT runtime·syscall_x509(SB),NOSPLIT,$0 676 SUB $16, RSP // push structure pointer 677 MOVD R0, (RSP) 678 679 MOVD 0(R0), R12 // fn 680 MOVD 16(R0), R1 // a2 681 MOVD 24(R0), R2 // a3 682 MOVD 32(R0), R3 // a4 683 MOVD 40(R0), R4 // a5 684 FMOVD 48(R0), F0 // f1 685 MOVD 8(R0), R0 // a1 686 BL (R12) 687 688 MOVD (RSP), R2 // pop structure pointer 689 ADD $16, RSP 690 MOVD R0, 56(R2) // save r1 691 RET