github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/runtime/sys_openbsd_arm64.s (about) 1 // Copyright 2019 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, OpenBSD 6 // System calls are implemented in libc/libpthread, this file 7 // contains trampolines that convert from Go to C calling convention. 8 // Some direct system call implementations currently remain. 9 // 10 11 #include "go_asm.h" 12 #include "go_tls.h" 13 #include "textflag.h" 14 15 #define CLOCK_REALTIME $0 16 #define CLOCK_MONOTONIC $3 17 18 // With OpenBSD 6.7 onwards, an arm64 syscall returns two instructions 19 // after the SVC instruction, to allow for a speculative execution 20 // barrier to be placed after the SVC without impacting performance. 21 // For now use hardware no-ops as this works with both older and newer 22 // kernels. After OpenBSD 6.8 is released this should be changed to 23 // speculation barriers. 24 #define INVOKE_SYSCALL \ 25 SVC; \ 26 NOOP; \ 27 NOOP 28 29 // mstart_stub is the first function executed on a new thread started by pthread_create. 30 // It just does some low-level setup and then calls mstart. 31 // Note: called with the C calling convention. 32 TEXT runtime·mstart_stub(SB),NOSPLIT,$160 33 // R0 points to the m. 34 // We are already on m's g0 stack. 35 36 // Save callee-save registers. 37 MOVD R19, 8(RSP) 38 MOVD R20, 16(RSP) 39 MOVD R21, 24(RSP) 40 MOVD R22, 32(RSP) 41 MOVD R23, 40(RSP) 42 MOVD R24, 48(RSP) 43 MOVD R25, 56(RSP) 44 MOVD R26, 64(RSP) 45 MOVD R27, 72(RSP) 46 MOVD g, 80(RSP) 47 MOVD R29, 88(RSP) 48 FMOVD F8, 96(RSP) 49 FMOVD F9, 104(RSP) 50 FMOVD F10, 112(RSP) 51 FMOVD F11, 120(RSP) 52 FMOVD F12, 128(RSP) 53 FMOVD F13, 136(RSP) 54 FMOVD F14, 144(RSP) 55 FMOVD F15, 152(RSP) 56 57 MOVD m_g0(R0), g 58 BL runtime·save_g(SB) 59 60 BL runtime·mstart(SB) 61 62 // Restore callee-save registers. 63 MOVD 8(RSP), R19 64 MOVD 16(RSP), R20 65 MOVD 24(RSP), R21 66 MOVD 32(RSP), R22 67 MOVD 40(RSP), R23 68 MOVD 48(RSP), R24 69 MOVD 56(RSP), R25 70 MOVD 64(RSP), R26 71 MOVD 72(RSP), R27 72 MOVD 80(RSP), g 73 MOVD 88(RSP), R29 74 FMOVD 96(RSP), F8 75 FMOVD 104(RSP), F9 76 FMOVD 112(RSP), F10 77 FMOVD 120(RSP), F11 78 FMOVD 128(RSP), F12 79 FMOVD 136(RSP), F13 80 FMOVD 144(RSP), F14 81 FMOVD 152(RSP), F15 82 83 // Go is all done with this OS thread. 84 // Tell pthread everything is ok (we never join with this thread, so 85 // the value here doesn't really matter). 86 MOVD $0, R0 87 88 RET 89 90 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 91 MOVW sig+8(FP), R0 92 MOVD info+16(FP), R1 93 MOVD ctx+24(FP), R2 94 MOVD fn+0(FP), R11 95 BL (R11) // Alignment for ELF ABI? 96 RET 97 98 TEXT runtime·sigtramp(SB),NOSPLIT,$192 99 // Save callee-save registers in the case of signal forwarding. 100 // Please refer to https://golang.org/issue/31827 . 101 MOVD R19, 8*4(RSP) 102 MOVD R20, 8*5(RSP) 103 MOVD R21, 8*6(RSP) 104 MOVD R22, 8*7(RSP) 105 MOVD R23, 8*8(RSP) 106 MOVD R24, 8*9(RSP) 107 MOVD R25, 8*10(RSP) 108 MOVD R26, 8*11(RSP) 109 MOVD R27, 8*12(RSP) 110 MOVD g, 8*13(RSP) 111 MOVD R29, 8*14(RSP) 112 FMOVD F8, 8*15(RSP) 113 FMOVD F9, 8*16(RSP) 114 FMOVD F10, 8*17(RSP) 115 FMOVD F11, 8*18(RSP) 116 FMOVD F12, 8*19(RSP) 117 FMOVD F13, 8*20(RSP) 118 FMOVD F14, 8*21(RSP) 119 FMOVD F15, 8*22(RSP) 120 121 // If called from an external code context, g will not be set. 122 // Save R0, since runtime·load_g will clobber it. 123 MOVW R0, 8(RSP) // signum 124 BL runtime·load_g(SB) 125 126 MOVD R1, 16(RSP) 127 MOVD R2, 24(RSP) 128 BL runtime·sigtrampgo(SB) 129 130 // Restore callee-save registers. 131 MOVD 8*4(RSP), R19 132 MOVD 8*5(RSP), R20 133 MOVD 8*6(RSP), R21 134 MOVD 8*7(RSP), R22 135 MOVD 8*8(RSP), R23 136 MOVD 8*9(RSP), R24 137 MOVD 8*10(RSP), R25 138 MOVD 8*11(RSP), R26 139 MOVD 8*12(RSP), R27 140 MOVD 8*13(RSP), g 141 MOVD 8*14(RSP), R29 142 FMOVD 8*15(RSP), F8 143 FMOVD 8*16(RSP), F9 144 FMOVD 8*17(RSP), F10 145 FMOVD 8*18(RSP), F11 146 FMOVD 8*19(RSP), F12 147 FMOVD 8*20(RSP), F13 148 FMOVD 8*21(RSP), F14 149 FMOVD 8*22(RSP), F15 150 151 RET 152 153 // 154 // These trampolines help convert from Go calling convention to C calling convention. 155 // They should be called with asmcgocall. 156 // A pointer to the arguments is passed in R0. 157 // A single int32 result is returned in R0. 158 // (For more results, make an args/results structure.) 159 TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0 160 MOVD 0(R0), R0 // arg 1 - attr 161 CALL libc_pthread_attr_init(SB) 162 RET 163 164 TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0 165 MOVD 0(R0), R0 // arg 1 - attr 166 CALL libc_pthread_attr_destroy(SB) 167 RET 168 169 TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0 170 MOVD 8(R0), R1 // arg 2 - size 171 MOVD 0(R0), R0 // arg 1 - attr 172 CALL libc_pthread_attr_getstacksize(SB) 173 RET 174 175 TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0 176 MOVD 8(R0), R1 // arg 2 - state 177 MOVD 0(R0), R0 // arg 1 - attr 178 CALL libc_pthread_attr_setdetachstate(SB) 179 RET 180 181 TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0 182 MOVD 0(R0), R1 // arg 2 - attr 183 MOVD 8(R0), R2 // arg 3 - start 184 MOVD 16(R0), R3 // arg 4 - arg 185 SUB $16, RSP 186 MOVD RSP, R0 // arg 1 - &threadid (discard) 187 CALL libc_pthread_create(SB) 188 ADD $16, RSP 189 RET 190 191 // Exit the entire program (like C exit) 192 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0 193 MOVW code+0(FP), R0 // arg 1 - status 194 MOVD $1, R8 // sys_exit 195 INVOKE_SYSCALL 196 BCC 3(PC) 197 MOVD $0, R0 // crash on syscall failure 198 MOVD R0, (R0) 199 RET 200 201 // func exitThread(wait *uint32) 202 TEXT runtime·exitThread(SB),NOSPLIT,$0 203 MOVD wait+0(FP), R0 // arg 1 - notdead 204 MOVD $302, R8 // sys___threxit 205 INVOKE_SYSCALL 206 MOVD $0, R0 // crash on syscall failure 207 MOVD R0, (R0) 208 JMP 0(PC) 209 210 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0 211 MOVD name+0(FP), R0 // arg 1 - path 212 MOVW mode+8(FP), R1 // arg 2 - mode 213 MOVW perm+12(FP), R2 // arg 3 - perm 214 MOVD $5, R8 // sys_open 215 INVOKE_SYSCALL 216 BCC 2(PC) 217 MOVW $-1, R0 218 MOVW R0, ret+16(FP) 219 RET 220 221 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0 222 MOVW fd+0(FP), R0 // arg 1 - fd 223 MOVD $6, R8 // sys_close 224 INVOKE_SYSCALL 225 BCC 2(PC) 226 MOVW $-1, R0 227 MOVW R0, ret+8(FP) 228 RET 229 230 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0 231 MOVW fd+0(FP), R0 // arg 1 - fd 232 MOVD p+8(FP), R1 // arg 2 - buf 233 MOVW n+16(FP), R2 // arg 3 - nbyte 234 MOVD $3, R8 // sys_read 235 INVOKE_SYSCALL 236 BCC 2(PC) 237 NEG R0, R0 238 MOVW R0, ret+24(FP) 239 RET 240 241 // func pipe() (r, w int32, errno int32) 242 TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12 243 MOVD $r+0(FP), R0 244 MOVW $0, R1 245 MOVD $101, R8 // sys_pipe2 246 INVOKE_SYSCALL 247 BCC 2(PC) 248 NEG R0, R0 249 MOVW R0, errno+8(FP) 250 RET 251 252 // func pipe2(flags int32) (r, w int32, errno int32) 253 TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20 254 MOVD $r+8(FP), R0 255 MOVW flags+0(FP), R1 256 MOVD $101, R8 // sys_pipe2 257 INVOKE_SYSCALL 258 BCC 2(PC) 259 NEG R0, R0 260 MOVW R0, errno+16(FP) 261 RET 262 263 TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0 264 MOVD fd+0(FP), R0 // arg 1 - fd 265 MOVD p+8(FP), R1 // arg 2 - buf 266 MOVW n+16(FP), R2 // arg 3 - nbyte 267 MOVD $4, R8 // sys_write 268 INVOKE_SYSCALL 269 BCC 2(PC) 270 NEG R0, R0 271 MOVW R0, ret+24(FP) 272 RET 273 274 TEXT runtime·usleep(SB),NOSPLIT,$24-4 275 MOVWU usec+0(FP), R3 276 MOVD R3, R5 277 MOVW $1000000, R4 278 UDIV R4, R3 279 MOVD R3, 8(RSP) // tv_sec 280 MUL R3, R4 281 SUB R4, R5 282 MOVW $1000, R4 283 MUL R4, R5 284 MOVD R5, 16(RSP) // tv_nsec 285 286 ADD $8, RSP, R0 // arg 1 - rqtp 287 MOVD $0, R1 // arg 2 - rmtp 288 MOVD $91, R8 // sys_nanosleep 289 INVOKE_SYSCALL 290 RET 291 292 TEXT runtime·getthrid(SB),NOSPLIT,$0-4 293 MOVD $299, R8 // sys_getthrid 294 INVOKE_SYSCALL 295 MOVW R0, ret+0(FP) 296 RET 297 298 TEXT runtime·thrkill(SB),NOSPLIT,$0-16 299 MOVW tid+0(FP), R0 // arg 1 - tid 300 MOVD sig+8(FP), R1 // arg 2 - signum 301 MOVW $0, R2 // arg 3 - tcb 302 MOVD $119, R8 // sys_thrkill 303 INVOKE_SYSCALL 304 RET 305 306 TEXT runtime·raiseproc(SB),NOSPLIT,$0 307 MOVD $20, R8 // sys_getpid 308 INVOKE_SYSCALL 309 // arg 1 - pid, already in R0 310 MOVW sig+0(FP), R1 // arg 2 - signum 311 MOVD $122, R8 // sys_kill 312 INVOKE_SYSCALL 313 RET 314 315 TEXT runtime·mmap(SB),NOSPLIT,$0 316 MOVD addr+0(FP), R0 // arg 1 - addr 317 MOVD n+8(FP), R1 // arg 2 - len 318 MOVW prot+16(FP), R2 // arg 3 - prot 319 MOVW flags+20(FP), R3 // arg 4 - flags 320 MOVW fd+24(FP), R4 // arg 5 - fd 321 MOVW $0, R5 // arg 6 - pad 322 MOVW off+28(FP), R6 // arg 7 - offset 323 MOVD $197, R8 // sys_mmap 324 INVOKE_SYSCALL 325 MOVD $0, R1 326 BCC 3(PC) 327 MOVD R0, R1 // if error, move to R1 328 MOVD $0, R0 329 MOVD R0, p+32(FP) 330 MOVD R1, err+40(FP) 331 RET 332 333 TEXT runtime·munmap(SB),NOSPLIT,$0 334 MOVD addr+0(FP), R0 // arg 1 - addr 335 MOVD n+8(FP), R1 // arg 2 - len 336 MOVD $73, R8 // sys_munmap 337 INVOKE_SYSCALL 338 BCC 3(PC) 339 MOVD $0, R0 // crash on syscall failure 340 MOVD R0, (R0) 341 RET 342 343 TEXT runtime·madvise(SB),NOSPLIT,$0 344 MOVD addr+0(FP), R0 // arg 1 - addr 345 MOVD n+8(FP), R1 // arg 2 - len 346 MOVW flags+16(FP), R2 // arg 2 - flags 347 MOVD $75, R8 // sys_madvise 348 INVOKE_SYSCALL 349 BCC 2(PC) 350 MOVW $-1, R0 351 MOVW R0, ret+24(FP) 352 RET 353 354 TEXT runtime·setitimer(SB),NOSPLIT,$0 355 MOVW mode+0(FP), R0 // arg 1 - mode 356 MOVD new+8(FP), R1 // arg 2 - new value 357 MOVD old+16(FP), R2 // arg 3 - old value 358 MOVD $69, R8 // sys_setitimer 359 INVOKE_SYSCALL 360 RET 361 362 // func walltime1() (sec int64, nsec int32) 363 TEXT runtime·walltime1(SB), NOSPLIT, $32 364 MOVW CLOCK_REALTIME, R0 // arg 1 - clock_id 365 MOVD $8(RSP), R1 // arg 2 - tp 366 MOVD $87, R8 // sys_clock_gettime 367 INVOKE_SYSCALL 368 369 MOVD 8(RSP), R0 // sec 370 MOVD 16(RSP), R1 // nsec 371 MOVD R0, sec+0(FP) 372 MOVW R1, nsec+8(FP) 373 374 RET 375 376 // int64 nanotime1(void) so really 377 // void nanotime1(int64 *nsec) 378 TEXT runtime·nanotime1(SB),NOSPLIT,$32 379 MOVW CLOCK_MONOTONIC, R0 // arg 1 - clock_id 380 MOVD $8(RSP), R1 // arg 2 - tp 381 MOVD $87, R8 // sys_clock_gettime 382 INVOKE_SYSCALL 383 384 MOVW 8(RSP), R3 // sec 385 MOVW 16(RSP), R5 // nsec 386 387 MOVD $1000000000, R4 388 MUL R4, R3 389 ADD R5, R3 390 MOVD R3, ret+0(FP) 391 RET 392 393 TEXT runtime·sigaction(SB),NOSPLIT,$0 394 MOVW sig+0(FP), R0 // arg 1 - signum 395 MOVD new+8(FP), R1 // arg 2 - new sigaction 396 MOVD old+16(FP), R2 // arg 3 - old sigaction 397 MOVD $46, R8 // sys_sigaction 398 INVOKE_SYSCALL 399 BCC 3(PC) 400 MOVD $3, R0 // crash on syscall failure 401 MOVD R0, (R0) 402 RET 403 404 TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$0 405 MOVW how+0(FP), R0 // arg 1 - mode 406 MOVW new+4(FP), R1 // arg 2 - new 407 MOVD $48, R8 // sys_sigprocmask 408 INVOKE_SYSCALL 409 BCC 3(PC) 410 MOVD $3, R8 // crash on syscall failure 411 MOVD R8, (R8) 412 MOVW R0, ret+8(FP) 413 RET 414 415 TEXT runtime·sigaltstack(SB),NOSPLIT,$0 416 MOVD new+0(FP), R0 // arg 1 - new sigaltstack 417 MOVD old+8(FP), R1 // arg 2 - old sigaltstack 418 MOVD $288, R8 // sys_sigaltstack 419 INVOKE_SYSCALL 420 BCC 3(PC) 421 MOVD $0, R8 // crash on syscall failure 422 MOVD R8, (R8) 423 RET 424 425 TEXT runtime·osyield(SB),NOSPLIT,$0 426 MOVD $298, R8 // sys_sched_yield 427 INVOKE_SYSCALL 428 RET 429 430 TEXT runtime·thrsleep(SB),NOSPLIT,$0 431 MOVD ident+0(FP), R0 // arg 1 - ident 432 MOVW clock_id+8(FP), R1 // arg 2 - clock_id 433 MOVD tsp+16(FP), R2 // arg 3 - tsp 434 MOVD lock+24(FP), R3 // arg 4 - lock 435 MOVD abort+32(FP), R4 // arg 5 - abort 436 MOVD $94, R8 // sys___thrsleep 437 INVOKE_SYSCALL 438 MOVW R0, ret+40(FP) 439 RET 440 441 TEXT runtime·thrwakeup(SB),NOSPLIT,$0 442 MOVD ident+0(FP), R0 // arg 1 - ident 443 MOVW n+8(FP), R1 // arg 2 - n 444 MOVD $301, R8 // sys___thrwakeup 445 INVOKE_SYSCALL 446 MOVW R0, ret+16(FP) 447 RET 448 449 TEXT runtime·sysctl(SB),NOSPLIT,$0 450 MOVD mib+0(FP), R0 // arg 1 - mib 451 MOVW miblen+8(FP), R1 // arg 2 - miblen 452 MOVD out+16(FP), R2 // arg 3 - out 453 MOVD size+24(FP), R3 // arg 4 - size 454 MOVD dst+32(FP), R4 // arg 5 - dest 455 MOVD ndst+40(FP), R5 // arg 6 - newlen 456 MOVD $202, R8 // sys___sysctl 457 INVOKE_SYSCALL 458 BCC 2(PC) 459 NEG R0, R0 460 MOVW R0, ret+48(FP) 461 RET 462 463 // int32 runtime·kqueue(void); 464 TEXT runtime·kqueue(SB),NOSPLIT,$0 465 MOVD $269, R8 // sys_kqueue 466 INVOKE_SYSCALL 467 BCC 2(PC) 468 NEG R0, R0 469 MOVW R0, ret+0(FP) 470 RET 471 472 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout); 473 TEXT runtime·kevent(SB),NOSPLIT,$0 474 MOVW kq+0(FP), R0 // arg 1 - kq 475 MOVD ch+8(FP), R1 // arg 2 - changelist 476 MOVW nch+16(FP), R2 // arg 3 - nchanges 477 MOVD ev+24(FP), R3 // arg 4 - eventlist 478 MOVW nev+32(FP), R4 // arg 5 - nevents 479 MOVD ts+40(FP), R5 // arg 6 - timeout 480 MOVD $72, R8 // sys_kevent 481 INVOKE_SYSCALL 482 BCC 2(PC) 483 NEG R0, R0 484 MOVW R0, ret+48(FP) 485 RET 486 487 // func closeonexec(fd int32) 488 TEXT runtime·closeonexec(SB),NOSPLIT,$0 489 MOVW fd+0(FP), R0 // arg 1 - fd 490 MOVD $2, R1 // arg 2 - cmd (F_SETFD) 491 MOVD $1, R2 // arg 3 - arg (FD_CLOEXEC) 492 MOVD $92, R8 // sys_fcntl 493 INVOKE_SYSCALL 494 RET 495 496 // func runtime·setNonblock(int32 fd) 497 TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4 498 MOVW fd+0(FP), R0 // arg 1 - fd 499 MOVD $3, R1 // arg 2 - cmd (F_GETFL) 500 MOVD $0, R2 // arg 3 501 MOVD $92, R8 // sys_fcntl 502 INVOKE_SYSCALL 503 MOVD $4, R2 // O_NONBLOCK 504 ORR R0, R2 // arg 3 - flags 505 MOVW fd+0(FP), R0 // arg 1 - fd 506 MOVD $4, R1 // arg 2 - cmd (F_SETFL) 507 MOVD $92, R8 // sys_fcntl 508 INVOKE_SYSCALL 509 RET