github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/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|TOPFRAME,$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 noerr 411 BL libc_errno(SB) 412 MOVW (R0), R0 // errno 413 RSB.CS $0, R0 // caller expects negative errno 414 noerr: 415 MOVW R9, R13 416 RET 417 418 TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0 419 MOVW R13, R9 420 SUB $8, R13 421 BIC $0x7, R13 // align for ELF ABI 422 MOVW 4(R0), R1 // arg 2 cmd 423 MOVW 8(R0), R2 // arg 3 arg (vararg, on stack) 424 MOVW R2, 0(R13) 425 MOVW 0(R0), R0 // arg 1 fd 426 BL libc_fcntl(SB) 427 MOVW R9, R13 428 RET 429 430 TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0 431 MOVW R13, R9 432 BIC $0x7, R13 // align for ELF ABI 433 MOVW 4(R0), R1 // arg 2 new 434 MOVW 8(R0), R2 // arg 3 old 435 MOVW 0(R0), R0 // arg 1 sig 436 BL libc_sigaction(SB) 437 CMP $-1, R0 438 BNE 3(PC) 439 MOVW $0, R8 // crash on failure 440 MOVW R8, (R8) 441 MOVW R9, R13 442 RET 443 444 TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0 445 MOVW R13, R9 446 BIC $0x7, R13 // align for ELF ABI 447 MOVW 4(R0), R1 // arg 2 new 448 MOVW 8(R0), R2 // arg 3 old 449 MOVW 0(R0), R0 // arg 1 how 450 BL libc_pthread_sigmask(SB) 451 CMP $-1, R0 452 BNE 3(PC) 453 MOVW $0, R8 // crash on failure 454 MOVW R8, (R8) 455 MOVW R9, R13 456 RET 457 458 TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0 459 MOVW R13, R9 460 BIC $0x7, R13 // align for ELF ABI 461 MOVW 4(R0), R1 // arg 2 old 462 MOVW 0(R0), R0 // arg 1 new 463 BL libc_sigaltstack(SB) 464 CMP $-1, R0 465 BNE 3(PC) 466 MOVW $0, R8 // crash on failure 467 MOVW R8, (R8) 468 MOVW R9, R13 469 RET 470 471 // syscall calls a function in libc on behalf of the syscall package. 472 // syscall takes a pointer to a struct like: 473 // struct { 474 // fn uintptr 475 // a1 uintptr 476 // a2 uintptr 477 // a3 uintptr 478 // r1 uintptr 479 // r2 uintptr 480 // err uintptr 481 // } 482 // syscall must be called on the g0 stack with the 483 // C calling convention (use libcCall). 484 // 485 // syscall expects a 32-bit result and tests for 32-bit -1 486 // to decide there was an error. 487 TEXT runtime·syscall(SB),NOSPLIT,$0 488 MOVW R13, R9 489 BIC $0x7, R13 // align for ELF ABI 490 491 MOVW R0, R8 492 493 MOVW (0*4)(R8), R7 // fn 494 MOVW (1*4)(R8), R0 // a1 495 MOVW (2*4)(R8), R1 // a2 496 MOVW (3*4)(R8), R2 // a3 497 498 BL (R7) 499 500 MOVW R0, (4*4)(R8) // r1 501 MOVW R1, (5*4)(R8) // r2 502 503 // Standard libc functions return -1 on error and set errno. 504 CMP $-1, R0 505 BNE ok 506 507 // Get error code from libc. 508 BL libc_errno(SB) 509 MOVW (R0), R1 510 MOVW R1, (6*4)(R8) // err 511 512 ok: 513 MOVW $0, R0 // no error (it's ignored anyway) 514 MOVW R9, R13 515 RET 516 517 // syscallX calls a function in libc on behalf of the syscall package. 518 // syscallX takes a pointer to a struct like: 519 // struct { 520 // fn uintptr 521 // a1 uintptr 522 // a2 uintptr 523 // a3 uintptr 524 // r1 uintptr 525 // r2 uintptr 526 // err uintptr 527 // } 528 // syscallX must be called on the g0 stack with the 529 // C calling convention (use libcCall). 530 // 531 // syscallX is like syscall but expects a 64-bit result 532 // and tests for 64-bit -1 to decide there was an error. 533 TEXT runtime·syscallX(SB),NOSPLIT,$0 534 MOVW R13, R9 535 BIC $0x7, R13 // align for ELF ABI 536 537 MOVW R0, R8 538 539 MOVW (0*4)(R8), R7 // fn 540 MOVW (1*4)(R8), R0 // a1 541 MOVW (2*4)(R8), R1 // a2 542 MOVW (3*4)(R8), R2 // a3 543 544 BL (R7) 545 546 MOVW R0, (4*4)(R8) // r1 547 MOVW R1, (5*4)(R8) // r2 548 549 // Standard libc functions return -1 on error and set errno. 550 CMP $-1, R0 551 BNE ok 552 CMP $-1, R1 553 BNE ok 554 555 // Get error code from libc. 556 BL libc_errno(SB) 557 MOVW (R0), R1 558 MOVW R1, (6*4)(R8) // err 559 560 ok: 561 MOVW $0, R0 // no error (it's ignored anyway) 562 MOVW R9, R13 563 RET 564 565 // syscall6 calls a function in libc on behalf of the syscall package. 566 // syscall6 takes a pointer to a struct like: 567 // struct { 568 // fn uintptr 569 // a1 uintptr 570 // a2 uintptr 571 // a3 uintptr 572 // a4 uintptr 573 // a5 uintptr 574 // a6 uintptr 575 // r1 uintptr 576 // r2 uintptr 577 // err uintptr 578 // } 579 // syscall6 must be called on the g0 stack with the 580 // C calling convention (use libcCall). 581 // 582 // syscall6 expects a 32-bit result and tests for 32-bit -1 583 // to decide there was an error. 584 TEXT runtime·syscall6(SB),NOSPLIT,$0 585 MOVW R13, R9 586 SUB $8, R13 587 BIC $0x7, R13 // align for ELF ABI 588 589 MOVW R0, R8 590 591 MOVW (0*4)(R8), R7 // fn 592 MOVW (1*4)(R8), R0 // a1 593 MOVW (2*4)(R8), R1 // a2 594 MOVW (3*4)(R8), R2 // a3 595 MOVW (4*4)(R8), R3 // a4 596 MOVW (5*4)(R8), R4 // a5 597 MOVW R4, 0(R13) 598 MOVW (6*4)(R8), R5 // a6 599 MOVW R5, 4(R13) 600 601 BL (R7) 602 603 MOVW R0, (7*4)(R8) // r1 604 MOVW R1, (8*4)(R8) // r2 605 606 // Standard libc functions return -1 on error and set errno. 607 CMP $-1, R0 608 BNE ok 609 610 // Get error code from libc. 611 BL libc_errno(SB) 612 MOVW (R0), R1 613 MOVW R1, (9*4)(R8) // err 614 615 ok: 616 MOVW $0, R0 // no error (it's ignored anyway) 617 MOVW R9, R13 618 RET 619 620 // syscall6X calls a function in libc on behalf of the syscall package. 621 // syscall6X takes a pointer to a struct like: 622 // struct { 623 // fn uintptr 624 // a1 uintptr 625 // a2 uintptr 626 // a3 uintptr 627 // a4 uintptr 628 // a5 uintptr 629 // a6 uintptr 630 // r1 uintptr 631 // r2 uintptr 632 // err uintptr 633 // } 634 // syscall6X must be called on the g0 stack with the 635 // C calling convention (use libcCall). 636 // 637 // syscall6X is like syscall6 but expects a 64-bit result 638 // and tests for 64-bit -1 to decide there was an error. 639 TEXT runtime·syscall6X(SB),NOSPLIT,$0 640 MOVW R13, R9 641 SUB $8, R13 642 BIC $0x7, R13 // align for ELF ABI 643 644 MOVW R0, R8 645 646 MOVW (0*4)(R8), R7 // fn 647 MOVW (1*4)(R8), R0 // a1 648 MOVW (2*4)(R8), R1 // a2 649 MOVW (3*4)(R8), R2 // a3 650 MOVW (4*4)(R8), R3 // a4 651 MOVW (5*4)(R8), R4 // a5 652 MOVW R4, 0(R13) 653 MOVW (6*4)(R8), R5 // a6 654 MOVW R5, 4(R13) 655 656 BL (R7) 657 658 MOVW R0, (7*4)(R8) // r1 659 MOVW R1, (8*4)(R8) // r2 660 661 // Standard libc functions return -1 on error and set errno. 662 CMP $-1, R0 663 BNE ok 664 CMP $-1, R1 665 BNE ok 666 667 // Get error code from libc. 668 BL libc_errno(SB) 669 MOVW (R0), R1 670 MOVW R1, (9*4)(R8) // err 671 672 ok: 673 MOVW $0, R0 // no error (it's ignored anyway) 674 MOVW R9, R13 675 RET 676 677 // syscall10 calls a function in libc on behalf of the syscall package. 678 // syscall10 takes a pointer to a struct like: 679 // struct { 680 // fn uintptr 681 // a1 uintptr 682 // a2 uintptr 683 // a3 uintptr 684 // a4 uintptr 685 // a5 uintptr 686 // a6 uintptr 687 // a7 uintptr 688 // a8 uintptr 689 // a9 uintptr 690 // a10 uintptr 691 // r1 uintptr 692 // r2 uintptr 693 // err uintptr 694 // } 695 // syscall10 must be called on the g0 stack with the 696 // C calling convention (use libcCall). 697 TEXT runtime·syscall10(SB),NOSPLIT,$0 698 MOVW R13, R9 699 SUB $24, R13 700 BIC $0x7, R13 // align for ELF ABI 701 702 MOVW R0, R8 703 704 MOVW (0*4)(R8), R7 // fn 705 MOVW (1*4)(R8), R0 // a1 706 MOVW (2*4)(R8), R1 // a2 707 MOVW (3*4)(R8), R2 // a3 708 MOVW (4*4)(R8), R3 // a4 709 MOVW (5*4)(R8), R4 // a5 710 MOVW R4, 0(R13) 711 MOVW (6*4)(R8), R5 // a6 712 MOVW R5, 4(R13) 713 MOVW (7*4)(R8), R6 // a7 714 MOVW R6, 8(R13) 715 MOVW (8*4)(R8), R4 // a8 716 MOVW R4, 12(R13) 717 MOVW (9*4)(R8), R5 // a9 718 MOVW R5, 16(R13) 719 MOVW (10*4)(R8), R6 // a10 720 MOVW R6, 20(R13) 721 722 BL (R7) 723 724 MOVW R0, (11*4)(R8) // r1 725 MOVW R1, (12*4)(R8) // r2 726 727 // Standard libc functions return -1 on error and set errno. 728 CMP $-1, R0 729 BNE ok 730 731 // Get error code from libc. 732 BL libc_errno(SB) 733 MOVW (R0), R1 734 MOVW R1, (13*4)(R8) // err 735 736 ok: 737 MOVW $0, R0 // no error (it's ignored anyway) 738 MOVW R9, R13 739 RET 740 741 // syscall10X calls a function in libc on behalf of the syscall package. 742 // syscall10X takes a pointer to a struct like: 743 // struct { 744 // fn uintptr 745 // a1 uintptr 746 // a2 uintptr 747 // a3 uintptr 748 // a4 uintptr 749 // a5 uintptr 750 // a6 uintptr 751 // a7 uintptr 752 // a8 uintptr 753 // a9 uintptr 754 // a10 uintptr 755 // r1 uintptr 756 // r2 uintptr 757 // err uintptr 758 // } 759 // syscall10X must be called on the g0 stack with the 760 // C calling convention (use libcCall). 761 // 762 // syscall10X is like syscall10 but expects a 64-bit result 763 // and tests for 64-bit -1 to decide there was an error. 764 TEXT runtime·syscall10X(SB),NOSPLIT,$0 765 MOVW R13, R9 766 SUB $24, R13 767 BIC $0x7, R13 // align for ELF ABI 768 769 MOVW R0, R8 770 771 MOVW (0*4)(R8), R7 // fn 772 MOVW (1*4)(R8), R0 // a1 773 MOVW (2*4)(R8), R1 // a2 774 MOVW (3*4)(R8), R2 // a3 775 MOVW (4*4)(R8), R3 // a4 776 MOVW (5*4)(R8), R4 // a5 777 MOVW R4, 0(R13) 778 MOVW (6*4)(R8), R5 // a6 779 MOVW R5, 4(R13) 780 MOVW (7*4)(R8), R6 // a7 781 MOVW R6, 8(R13) 782 MOVW (8*4)(R8), R4 // a8 783 MOVW R4, 12(R13) 784 MOVW (9*4)(R8), R5 // a9 785 MOVW R5, 16(R13) 786 MOVW (10*4)(R8), R6 // a10 787 MOVW R6, 20(R13) 788 789 BL (R7) 790 791 MOVW R0, (11*4)(R8) // r1 792 MOVW R1, (12*4)(R8) // r2 793 794 // Standard libc functions return -1 on error and set errno. 795 CMP $-1, R0 796 BNE ok 797 CMP $-1, R1 798 BNE ok 799 800 // Get error code from libc. 801 BL libc_errno(SB) 802 MOVW (R0), R1 803 MOVW R1, (13*4)(R8) // err 804 805 ok: 806 MOVW $0, R0 // no error (it's ignored anyway) 807 MOVW R9, R13 808 RET