github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/runtime/sys_openbsd_arm.s (about) 1 // Copyright 2009 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 ARM, OpenBSD 6 // /usr/src/sys/kern/syscalls.master for syscall numbers. 7 // 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 #define CLOCK_REALTIME $0 14 #define CLOCK_MONOTONIC $3 15 16 // With OpenBSD 6.7 onwards, an armv7 syscall returns two instructions 17 // after the SWI instruction, to allow for a speculative execution 18 // barrier to be placed after the SWI without impacting performance. 19 // For now use hardware no-ops as this works with both older and newer 20 // kernels. After OpenBSD 6.8 is released this should be changed to 21 // speculation barriers. 22 #define NOOP MOVW R0, R0 23 #define INVOKE_SYSCALL \ 24 SWI $0; \ 25 NOOP; \ 26 NOOP 27 28 // mstart_stub is the first function executed on a new thread started by pthread_create. 29 // It just does some low-level setup and then calls mstart. 30 // Note: called with the C calling convention. 31 TEXT runtime·mstart_stub(SB),NOSPLIT,$0 32 // R0 points to the m. 33 // We are already on m's g0 stack. 34 35 // Save callee-save registers. 36 MOVM.DB.W [R4-R11], (R13) 37 38 MOVW m_g0(R0), g 39 BL runtime·save_g(SB) 40 41 BL runtime·mstart(SB) 42 43 // Restore callee-save registers. 44 MOVM.IA.W (R13), [R4-R11] 45 46 // Go is all done with this OS thread. 47 // Tell pthread everything is ok (we never join with this thread, so 48 // the value here doesn't really matter). 49 MOVW $0, R0 50 RET 51 52 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16 53 MOVW sig+4(FP), R0 54 MOVW info+8(FP), R1 55 MOVW ctx+12(FP), R2 56 MOVW fn+0(FP), R3 57 MOVW R13, R9 58 SUB $24, R13 59 BIC $0x7, R13 // alignment for ELF ABI 60 BL (R3) 61 MOVW R9, R13 62 RET 63 64 TEXT runtime·sigtramp(SB),NOSPLIT,$0 65 // Reserve space for callee-save registers and arguments. 66 MOVM.DB.W [R4-R11], (R13) 67 SUB $16, R13 68 69 // If called from an external code context, g will not be set. 70 // Save R0, since runtime·load_g will clobber it. 71 MOVW R0, 4(R13) // signum 72 BL runtime·load_g(SB) 73 74 MOVW R1, 8(R13) 75 MOVW R2, 12(R13) 76 BL runtime·sigtrampgo(SB) 77 78 // Restore callee-save registers. 79 ADD $16, R13 80 MOVM.IA.W (R13), [R4-R11] 81 82 RET 83 84 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0 85 B runtime·armPublicationBarrier(SB) 86 87 // TODO(jsing): OpenBSD only supports GOARM=7 machines... this 88 // should not be needed, however the linker still allows GOARM=5 89 // on this platform. 90 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0 91 MOVM.WP [R1, R2, R3, R12], (R13) 92 MOVW $330, R12 // sys___get_tcb 93 INVOKE_SYSCALL 94 MOVM.IAW (R13), [R1, R2, R3, R12] 95 RET 96 97 // These trampolines help convert from Go calling convention to C calling convention. 98 // They should be called with asmcgocall - note that while asmcgocall does 99 // stack alignment, creation of a frame undoes it again. 100 // A pointer to the arguments is passed in R0. 101 // A single int32 result is returned in R0. 102 // (For more results, make an args/results structure.) 103 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 104 MOVW R13, R9 105 BIC $0x7, R13 // align for ELF ABI 106 MOVW 0(R0), R0 // arg 1 attr 107 CALL libc_pthread_attr_init(SB) 108 MOVW R9, R13 109 RET 110 111 TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0 112 MOVW R13, R9 113 BIC $0x7, R13 // align for ELF ABI 114 MOVW 0(R0), R0 // arg 1 attr 115 CALL libc_pthread_attr_destroy(SB) 116 MOVW R9, R13 117 RET 118 119 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 120 MOVW R13, R9 121 BIC $0x7, R13 // align for ELF ABI 122 MOVW 4(R0), R1 // arg 2 size 123 MOVW 0(R0), R0 // arg 1 attr 124 CALL libc_pthread_attr_getstacksize(SB) 125 MOVW R9, R13 126 RET 127 128 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 129 MOVW R13, R9 130 BIC $0x7, R13 // align for ELF ABI 131 MOVW 4(R0), R1 // arg 2 state 132 MOVW 0(R0), R0 // arg 1 attr 133 CALL libc_pthread_attr_setdetachstate(SB) 134 MOVW R9, R13 135 RET 136 137 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0 138 MOVW R13, R9 139 SUB $16, R13 140 BIC $0x7, R13 // align for ELF ABI 141 MOVW 0(R0), R1 // arg 2 attr 142 MOVW 4(R0), R2 // arg 3 start 143 MOVW 8(R0), R3 // arg 4 arg 144 MOVW R13, R0 // arg 1 &threadid (discarded) 145 CALL libc_pthread_create(SB) 146 MOVW R9, R13 147 RET 148 149 TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0 150 MOVW R13, R9 151 BIC $0x7, R13 // align for ELF ABI 152 MOVW 4(R0), R1 // arg 2 - signal 153 MOVW $0, R2 // arg 3 - tcb 154 MOVW 0(R0), R0 // arg 1 - tid 155 CALL libc_thrkill(SB) 156 MOVW R9, R13 157 RET 158 159 TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0 160 MOVW R13, R9 161 SUB $16, R13 162 BIC $0x7, R13 // align for ELF ABI 163 MOVW 4(R0), R1 // arg 2 - clock_id 164 MOVW 8(R0), R2 // arg 3 - abstime 165 MOVW 12(R0), R3 // arg 4 - lock 166 MOVW 16(R0), R4 // arg 5 - abort (on stack) 167 MOVW R4, 0(R13) 168 MOVW 0(R0), R0 // arg 1 - id 169 CALL libc_thrsleep(SB) 170 MOVW R9, R13 171 RET 172 173 TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0 174 MOVW R13, R9 175 BIC $0x7, R13 // align for ELF ABI 176 MOVW 4(R0), R1 // arg 2 - count 177 MOVW 0(R0), R0 // arg 1 - id 178 CALL libc_thrwakeup(SB) 179 MOVW R9, R13 180 RET 181 182 TEXT runtime·exit_trampoline(SB),NOSPLIT,$0 183 MOVW R13, R9 184 BIC $0x7, R13 // align for ELF ABI 185 MOVW 0(R0), R0 // arg 1 exit status 186 BL libc_exit(SB) 187 MOVW $0, R8 // crash on failure 188 MOVW R8, (R8) 189 MOVW R9, R13 190 RET 191 192 TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0 193 MOVW R13, R9 194 MOVW R0, R8 195 BIC $0x7, R13 // align for ELF ABI 196 BL libc_getthrid(SB) 197 MOVW R0, 0(R8) 198 MOVW R9, R13 199 RET 200 201 TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0 202 MOVW R13, R9 203 BIC $0x7, R13 // align for ELF ABI 204 MOVW R0, R4 205 BL libc_getpid(SB) // arg 1 pid 206 MOVW R4, R1 // arg 2 signal 207 BL libc_kill(SB) 208 MOVW R9, R13 209 RET 210 211 TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0 212 MOVW R13, R9 213 BIC $0x7, R13 // align for ELF ABI 214 BL libc_sched_yield(SB) 215 MOVW R9, R13 216 RET 217 218 TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0 219 MOVW R13, R9 220 SUB $16, R13 221 BIC $0x7, R13 // align for ELF ABI 222 MOVW R0, R8 223 MOVW 4(R0), R1 // arg 2 len 224 MOVW 8(R0), R2 // arg 3 prot 225 MOVW 12(R0), R3 // arg 4 flags 226 MOVW 16(R0), R4 // arg 5 fid (on stack) 227 MOVW R4, 0(R13) 228 MOVW $0, R5 // pad (on stack) 229 MOVW R5, 4(R13) 230 MOVW 20(R0), R6 // arg 6 offset (on stack) 231 MOVW R6, 8(R13) // low 32 bits 232 MOVW $0, R7 233 MOVW R7, 12(R13) // high 32 bits 234 MOVW 0(R0), R0 // arg 1 addr 235 BL libc_mmap(SB) 236 MOVW $0, R1 237 CMP $-1, R0 238 BNE ok 239 BL libc_errno(SB) 240 MOVW (R0), R1 // errno 241 MOVW $0, R0 242 ok: 243 MOVW R0, 24(R8) 244 MOVW R1, 28(R8) 245 MOVW R9, R13 246 RET 247 248 TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0 249 MOVW R13, R9 250 BIC $0x7, R13 // align for ELF ABI 251 MOVW 4(R0), R1 // arg 2 len 252 MOVW 0(R0), R0 // arg 1 addr 253 BL libc_munmap(SB) 254 CMP $-1, R0 255 BNE 3(PC) 256 MOVW $0, R8 // crash on failure 257 MOVW R8, (R8) 258 MOVW R9, R13 259 RET 260 261 TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0 262 MOVW R13, R9 263 BIC $0x7, R13 // align for ELF ABI 264 MOVW 4(R0), R1 // arg 2 len 265 MOVW 8(R0), R2 // arg 3 advice 266 MOVW 0(R0), R0 // arg 1 addr 267 BL libc_madvise(SB) 268 // ignore failure - maybe pages are locked 269 MOVW R9, R13 270 RET 271 272 TEXT runtime·open_trampoline(SB),NOSPLIT,$0 273 MOVW R13, R9 274 SUB $8, R13 275 BIC $0x7, R13 // align for ELF ABI 276 MOVW 4(R0), R1 // arg 2 - flags 277 MOVW 8(R0), R2 // arg 3 - mode (vararg, on stack) 278 MOVW R2, 0(R13) 279 MOVW 0(R0), R0 // arg 1 - path 280 MOVW R13, R4 281 BIC $0x7, R13 // align for ELF ABI 282 BL libc_open(SB) 283 MOVW R9, R13 284 RET 285 286 TEXT runtime·close_trampoline(SB),NOSPLIT,$0 287 MOVW R13, R9 288 BIC $0x7, R13 // align for ELF ABI 289 MOVW 0(R0), R0 // arg 1 - fd 290 BL libc_close(SB) 291 MOVW R9, R13 292 RET 293 294 TEXT runtime·read_trampoline(SB),NOSPLIT,$0 295 MOVW R13, R9 296 BIC $0x7, R13 // align for ELF ABI 297 MOVW 4(R0), R1 // arg 2 - buf 298 MOVW 8(R0), R2 // arg 3 - count 299 MOVW 0(R0), R0 // arg 1 - fd 300 BL libc_read(SB) 301 CMP $-1, R0 302 BNE noerr 303 BL libc_errno(SB) 304 MOVW (R0), R0 // errno 305 RSB.CS $0, R0 // caller expects negative errno 306 noerr: 307 MOVW R9, R13 308 RET 309 310 TEXT runtime·write_trampoline(SB),NOSPLIT,$0 311 MOVW R13, R9 312 BIC $0x7, R13 // align for ELF ABI 313 MOVW 4(R0), R1 // arg 2 buf 314 MOVW 8(R0), R2 // arg 3 count 315 MOVW 0(R0), R0 // arg 1 fd 316 BL libc_write(SB) 317 CMP $-1, R0 318 BNE noerr 319 BL libc_errno(SB) 320 MOVW (R0), R0 // errno 321 RSB.CS $0, R0 // caller expects negative errno 322 noerr: 323 MOVW R9, R13 324 RET 325 326 TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0 327 MOVW R13, R9 328 BIC $0x7, R13 // align for ELF ABI 329 MOVW 4(R0), R1 // arg 2 flags 330 MOVW 0(R0), R0 // arg 1 filedes 331 BL libc_pipe2(SB) 332 CMP $-1, R0 333 BNE 3(PC) 334 BL libc_errno(SB) 335 MOVW (R0), R0 // errno 336 RSB.CS $0, R0 // caller expects negative errno 337 MOVW R9, R13 338 RET 339 340 TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0 341 MOVW R13, R9 342 BIC $0x7, R13 // align for ELF ABI 343 MOVW 4(R0), R1 // arg 2 new 344 MOVW 8(R0), R2 // arg 3 old 345 MOVW 0(R0), R0 // arg 1 which 346 BL libc_setitimer(SB) 347 MOVW R9, R13 348 RET 349 350 TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0 351 MOVW R13, R9 352 BIC $0x7, R13 // align for ELF ABI 353 MOVW 0(R0), R0 // arg 1 usec 354 BL libc_usleep(SB) 355 MOVW R9, R13 356 RET 357 358 TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0 359 MOVW R13, R9 360 SUB $8, R13 361 BIC $0x7, R13 // align for ELF ABI 362 MOVW 4(R0), R1 // arg 2 miblen 363 MOVW 8(R0), R2 // arg 3 out 364 MOVW 12(R0), R3 // arg 4 size 365 MOVW 16(R0), R4 // arg 5 dst (on stack) 366 MOVW R4, 0(R13) 367 MOVW 20(R0), R5 // arg 6 ndst (on stack) 368 MOVW R5, 4(R13) 369 MOVW 0(R0), R0 // arg 1 mib 370 BL libc_sysctl(SB) 371 MOVW R9, R13 372 RET 373 374 TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0 375 MOVW R13, R9 376 BIC $0x7, R13 // align for ELF ABI 377 BL libc_kqueue(SB) 378 MOVW R9, R13 379 RET 380 381 TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0 382 MOVW R13, R9 383 SUB $8, R13 384 BIC $0x7, R13 // align for ELF ABI 385 MOVW 4(R0), R1 // arg 2 keventt 386 MOVW 8(R0), R2 // arg 3 nch 387 MOVW 12(R0), R3 // arg 4 ev 388 MOVW 16(R0), R4 // arg 5 nev (on stack) 389 MOVW R4, 0(R13) 390 MOVW 20(R0), R5 // arg 6 ts (on stack) 391 MOVW R5, 4(R13) 392 MOVW 0(R0), R0 // arg 1 kq 393 BL libc_kevent(SB) 394 CMP $-1, R0 395 BNE ok 396 BL libc_errno(SB) 397 MOVW (R0), R0 // errno 398 RSB.CS $0, R0 // caller expects negative errno 399 ok: 400 MOVW R9, R13 401 RET 402 403 TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0 404 MOVW R13, R9 405 BIC $0x7, R13 // align for ELF ABI 406 MOVW 4(R0), R1 // arg 2 tp 407 MOVW 0(R0), R0 // arg 1 clock_id 408 BL libc_clock_gettime(SB) 409 CMP $-1, R0 410 BNE 3(PC) 411 MOVW $0, R8 // crash on failure 412 MOVW R8, (R8) 413 MOVW R9, R13 414 RET 415 416 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 417 MOVW R13, R9 418 SUB $8, R13 419 BIC $0x7, R13 // align for ELF ABI 420 MOVW 4(R0), R1 // arg 2 cmd 421 MOVW 8(R0), R2 // arg 3 arg (vararg, on stack) 422 MOVW R2, 0(R13) 423 MOVW 0(R0), R0 // arg 1 fd 424 BL libc_fcntl(SB) 425 MOVW R9, R13 426 RET 427 428 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 429 MOVW R13, R9 430 BIC $0x7, R13 // align for ELF ABI 431 MOVW 4(R0), R1 // arg 2 new 432 MOVW 8(R0), R2 // arg 3 old 433 MOVW 0(R0), R0 // arg 1 sig 434 BL libc_sigaction(SB) 435 CMP $-1, R0 436 BNE 3(PC) 437 MOVW $0, R8 // crash on failure 438 MOVW R8, (R8) 439 MOVW R9, R13 440 RET 441 442 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 443 MOVW R13, R9 444 BIC $0x7, R13 // align for ELF ABI 445 MOVW 4(R0), R1 // arg 2 new 446 MOVW 8(R0), R2 // arg 3 old 447 MOVW 0(R0), R0 // arg 1 how 448 BL libc_pthread_sigmask(SB) 449 CMP $-1, R0 450 BNE 3(PC) 451 MOVW $0, R8 // crash on failure 452 MOVW R8, (R8) 453 MOVW R9, R13 454 RET 455 456 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 457 MOVW R13, R9 458 BIC $0x7, R13 // align for ELF ABI 459 MOVW 4(R0), R1 // arg 2 old 460 MOVW 0(R0), R0 // arg 1 new 461 BL libc_sigaltstack(SB) 462 CMP $-1, R0 463 BNE 3(PC) 464 MOVW $0, R8 // crash on failure 465 MOVW R8, (R8) 466 MOVW R9, R13 467 RET 468 469 // syscall calls a function in libc on behalf of the syscall package. 470 // syscall takes a pointer to a struct like: 471 // struct { 472 // fn uintptr 473 // a1 uintptr 474 // a2 uintptr 475 // a3 uintptr 476 // r1 uintptr 477 // r2 uintptr 478 // err uintptr 479 // } 480 // syscall must be called on the g0 stack with the 481 // C calling convention (use libcCall). 482 // 483 // syscall expects a 32-bit result and tests for 32-bit -1 484 // to decide there was an error. 485 TEXT runtime·syscall(SB),NOSPLIT,$0 486 MOVW R13, R9 487 BIC $0x7, R13 // align for ELF ABI 488 489 MOVW R0, R8 490 491 MOVW (0*4)(R8), R7 // fn 492 MOVW (1*4)(R8), R0 // a1 493 MOVW (2*4)(R8), R1 // a2 494 MOVW (3*4)(R8), R2 // a3 495 496 BL (R7) 497 498 MOVW R0, (4*4)(R8) // r1 499 MOVW R1, (5*4)(R8) // r2 500 501 // Standard libc functions return -1 on error and set errno. 502 CMP $-1, R0 503 BNE ok 504 505 // Get error code from libc. 506 BL libc_errno(SB) 507 MOVW (R0), R1 508 MOVW R1, (6*4)(R8) // err 509 510 ok: 511 MOVW $0, R0 // no error (it's ignored anyway) 512 MOVW R9, R13 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 // 529 // syscallX is like syscall but expects a 64-bit result 530 // and tests for 64-bit -1 to decide there was an error. 531 TEXT runtime·syscallX(SB),NOSPLIT,$0 532 MOVW R13, R9 533 BIC $0x7, R13 // align for ELF ABI 534 535 MOVW R0, R8 536 537 MOVW (0*4)(R8), R7 // fn 538 MOVW (1*4)(R8), R0 // a1 539 MOVW (2*4)(R8), R1 // a2 540 MOVW (3*4)(R8), R2 // a3 541 542 BL (R7) 543 544 MOVW R0, (4*4)(R8) // r1 545 MOVW R1, (5*4)(R8) // r2 546 547 // Standard libc functions return -1 on error and set errno. 548 CMP $-1, R0 549 BNE ok 550 CMP $-1, R1 551 BNE ok 552 553 // Get error code from libc. 554 BL libc_errno(SB) 555 MOVW (R0), R1 556 MOVW R1, (6*4)(R8) // err 557 558 ok: 559 MOVW $0, R0 // no error (it's ignored anyway) 560 MOVW R9, R13 561 RET 562 563 // syscall6 calls a function in libc on behalf of the syscall package. 564 // syscall6 takes a pointer to a struct like: 565 // struct { 566 // fn uintptr 567 // a1 uintptr 568 // a2 uintptr 569 // a3 uintptr 570 // a4 uintptr 571 // a5 uintptr 572 // a6 uintptr 573 // r1 uintptr 574 // r2 uintptr 575 // err uintptr 576 // } 577 // syscall6 must be called on the g0 stack with the 578 // C calling convention (use libcCall). 579 // 580 // syscall6 expects a 32-bit result and tests for 32-bit -1 581 // to decide there was an error. 582 TEXT runtime·syscall6(SB),NOSPLIT,$0 583 MOVW R13, R9 584 SUB $8, R13 585 BIC $0x7, R13 // align for ELF ABI 586 587 MOVW R0, R8 588 589 MOVW (0*4)(R8), R7 // fn 590 MOVW (1*4)(R8), R0 // a1 591 MOVW (2*4)(R8), R1 // a2 592 MOVW (3*4)(R8), R2 // a3 593 MOVW (4*4)(R8), R3 // a4 594 MOVW (5*4)(R8), R4 // a5 595 MOVW R4, 0(R13) 596 MOVW (6*4)(R8), R5 // a6 597 MOVW R5, 4(R13) 598 599 BL (R7) 600 601 MOVW R0, (7*4)(R8) // r1 602 MOVW R1, (8*4)(R8) // r2 603 604 // Standard libc functions return -1 on error and set errno. 605 CMP $-1, R0 606 BNE ok 607 608 // Get error code from libc. 609 BL libc_errno(SB) 610 MOVW (R0), R1 611 MOVW R1, (9*4)(R8) // err 612 613 ok: 614 MOVW $0, R0 // no error (it's ignored anyway) 615 MOVW R9, R13 616 RET 617 618 // syscall6X calls a function in libc on behalf of the syscall package. 619 // syscall6X takes a pointer to a struct like: 620 // struct { 621 // fn uintptr 622 // a1 uintptr 623 // a2 uintptr 624 // a3 uintptr 625 // a4 uintptr 626 // a5 uintptr 627 // a6 uintptr 628 // r1 uintptr 629 // r2 uintptr 630 // err uintptr 631 // } 632 // syscall6X must be called on the g0 stack with the 633 // C calling convention (use libcCall). 634 // 635 // syscall6X is like syscall6 but expects a 64-bit result 636 // and tests for 64-bit -1 to decide there was an error. 637 TEXT runtime·syscall6X(SB),NOSPLIT,$0 638 MOVW R13, R9 639 SUB $8, R13 640 BIC $0x7, R13 // align for ELF ABI 641 642 MOVW R0, R8 643 644 MOVW (0*4)(R8), R7 // fn 645 MOVW (1*4)(R8), R0 // a1 646 MOVW (2*4)(R8), R1 // a2 647 MOVW (3*4)(R8), R2 // a3 648 MOVW (4*4)(R8), R3 // a4 649 MOVW (5*4)(R8), R4 // a5 650 MOVW R4, 0(R13) 651 MOVW (6*4)(R8), R5 // a6 652 MOVW R5, 4(R13) 653 654 BL (R7) 655 656 MOVW R0, (7*4)(R8) // r1 657 MOVW R1, (8*4)(R8) // r2 658 659 // Standard libc functions return -1 on error and set errno. 660 CMP $-1, R0 661 BNE ok 662 CMP $-1, R1 663 BNE ok 664 665 // Get error code from libc. 666 BL libc_errno(SB) 667 MOVW (R0), R1 668 MOVW R1, (9*4)(R8) // err 669 670 ok: 671 MOVW $0, R0 // no error (it's ignored anyway) 672 MOVW R9, R13 673 RET 674 675 // syscall10 calls a function in libc on behalf of the syscall package. 676 // syscall10 takes a pointer to a struct like: 677 // struct { 678 // fn uintptr 679 // a1 uintptr 680 // a2 uintptr 681 // a3 uintptr 682 // a4 uintptr 683 // a5 uintptr 684 // a6 uintptr 685 // a7 uintptr 686 // a8 uintptr 687 // a9 uintptr 688 // a10 uintptr 689 // r1 uintptr 690 // r2 uintptr 691 // err uintptr 692 // } 693 // syscall10 must be called on the g0 stack with the 694 // C calling convention (use libcCall). 695 TEXT runtime·syscall10(SB),NOSPLIT,$0 696 MOVW R13, R9 697 SUB $24, R13 698 BIC $0x7, R13 // align for ELF ABI 699 700 MOVW R0, R8 701 702 MOVW (0*4)(R8), R7 // fn 703 MOVW (1*4)(R8), R0 // a1 704 MOVW (2*4)(R8), R1 // a2 705 MOVW (3*4)(R8), R2 // a3 706 MOVW (4*4)(R8), R3 // a4 707 MOVW (5*4)(R8), R4 // a5 708 MOVW R4, 0(R13) 709 MOVW (6*4)(R8), R5 // a6 710 MOVW R5, 4(R13) 711 MOVW (7*4)(R8), R6 // a7 712 MOVW R6, 8(R13) 713 MOVW (8*4)(R8), R4 // a8 714 MOVW R4, 12(R13) 715 MOVW (9*4)(R8), R5 // a9 716 MOVW R5, 16(R13) 717 MOVW (10*4)(R8), R6 // a10 718 MOVW R6, 20(R13) 719 720 BL (R7) 721 722 MOVW R0, (11*4)(R8) // r1 723 MOVW R1, (12*4)(R8) // r2 724 725 // Standard libc functions return -1 on error and set errno. 726 CMP $-1, R0 727 BNE ok 728 729 // Get error code from libc. 730 BL libc_errno(SB) 731 MOVW (R0), R1 732 MOVW R1, (13*4)(R8) // err 733 734 ok: 735 MOVW $0, R0 // no error (it's ignored anyway) 736 MOVW R9, R13 737 RET 738 739 // syscall10X calls a function in libc on behalf of the syscall package. 740 // syscall10X takes a pointer to a struct like: 741 // struct { 742 // fn uintptr 743 // a1 uintptr 744 // a2 uintptr 745 // a3 uintptr 746 // a4 uintptr 747 // a5 uintptr 748 // a6 uintptr 749 // a7 uintptr 750 // a8 uintptr 751 // a9 uintptr 752 // a10 uintptr 753 // r1 uintptr 754 // r2 uintptr 755 // err uintptr 756 // } 757 // syscall10X must be called on the g0 stack with the 758 // C calling convention (use libcCall). 759 // 760 // syscall10X is like syscall10 but expects a 64-bit result 761 // and tests for 64-bit -1 to decide there was an error. 762 TEXT runtime·syscall10X(SB),NOSPLIT,$0 763 MOVW R13, R9 764 SUB $24, R13 765 BIC $0x7, R13 // align for ELF ABI 766 767 MOVW R0, R8 768 769 MOVW (0*4)(R8), R7 // fn 770 MOVW (1*4)(R8), R0 // a1 771 MOVW (2*4)(R8), R1 // a2 772 MOVW (3*4)(R8), R2 // a3 773 MOVW (4*4)(R8), R3 // a4 774 MOVW (5*4)(R8), R4 // a5 775 MOVW R4, 0(R13) 776 MOVW (6*4)(R8), R5 // a6 777 MOVW R5, 4(R13) 778 MOVW (7*4)(R8), R6 // a7 779 MOVW R6, 8(R13) 780 MOVW (8*4)(R8), R4 // a8 781 MOVW R4, 12(R13) 782 MOVW (9*4)(R8), R5 // a9 783 MOVW R5, 16(R13) 784 MOVW (10*4)(R8), R6 // a10 785 MOVW R6, 20(R13) 786 787 BL (R7) 788 789 MOVW R0, (11*4)(R8) // r1 790 MOVW R1, (12*4)(R8) // r2 791 792 // Standard libc functions return -1 on error and set errno. 793 CMP $-1, R0 794 BNE ok 795 CMP $-1, R1 796 BNE ok 797 798 // Get error code from libc. 799 BL libc_errno(SB) 800 MOVW (R0), R1 801 MOVW R1, (13*4)(R8) // err 802 803 ok: 804 MOVW $0, R0 // no error (it's ignored anyway) 805 MOVW R9, R13 806 RET