github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/sys_freebsd_arm.s (about) 1 // Copyright 2012 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, FreeBSD 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 // for EABI, as we don't support OABI 14 #define SYS_BASE 0x0 15 16 #define SYS_exit (SYS_BASE + 1) 17 #define SYS_read (SYS_BASE + 3) 18 #define SYS_write (SYS_BASE + 4) 19 #define SYS_open (SYS_BASE + 5) 20 #define SYS_close (SYS_BASE + 6) 21 #define SYS_getpid (SYS_BASE + 20) 22 #define SYS_kill (SYS_BASE + 37) 23 #define SYS_sigaltstack (SYS_BASE + 53) 24 #define SYS_munmap (SYS_BASE + 73) 25 #define SYS_madvise (SYS_BASE + 75) 26 #define SYS_setitimer (SYS_BASE + 83) 27 #define SYS_fcntl (SYS_BASE + 92) 28 #define SYS___sysctl (SYS_BASE + 202) 29 #define SYS_nanosleep (SYS_BASE + 240) 30 #define SYS_clock_gettime (SYS_BASE + 232) 31 #define SYS_sched_yield (SYS_BASE + 331) 32 #define SYS_sigprocmask (SYS_BASE + 340) 33 #define SYS_kqueue (SYS_BASE + 362) 34 #define SYS_sigaction (SYS_BASE + 416) 35 #define SYS_thr_exit (SYS_BASE + 431) 36 #define SYS_thr_self (SYS_BASE + 432) 37 #define SYS_thr_kill (SYS_BASE + 433) 38 #define SYS__umtx_op (SYS_BASE + 454) 39 #define SYS_thr_new (SYS_BASE + 455) 40 #define SYS_mmap (SYS_BASE + 477) 41 #define SYS_cpuset_getaffinity (SYS_BASE + 487) 42 #define SYS_pipe2 (SYS_BASE + 542) 43 #define SYS_kevent (SYS_BASE + 560) 44 45 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0 46 MOVW addr+0(FP), R0 47 MOVW mode+4(FP), R1 48 MOVW val+8(FP), R2 49 MOVW uaddr1+12(FP), R3 50 ADD $20, R13 // arg 5 is passed on stack 51 MOVW $SYS__umtx_op, R7 52 SWI $0 53 RSB.CS $0, R0 54 SUB $20, R13 55 // BCS error 56 MOVW R0, ret+20(FP) 57 RET 58 59 TEXT runtime·thr_new(SB),NOSPLIT,$0 60 MOVW param+0(FP), R0 61 MOVW size+4(FP), R1 62 MOVW $SYS_thr_new, R7 63 SWI $0 64 RSB.CS $0, R0 65 MOVW R0, ret+8(FP) 66 RET 67 68 TEXT runtime·thr_start(SB),NOSPLIT,$0 69 // set up g 70 MOVW m_g0(R0), g 71 MOVW R0, g_m(g) 72 BL runtime·emptyfunc(SB) // fault if stack check is wrong 73 BL runtime·mstart(SB) 74 75 MOVW $2, R8 // crash (not reached) 76 MOVW R8, (R8) 77 RET 78 79 // Exit the entire program (like C exit) 80 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0 81 MOVW code+0(FP), R0 // arg 1 exit status 82 MOVW $SYS_exit, R7 83 SWI $0 84 MOVW.CS $0, R8 // crash on syscall failure 85 MOVW.CS R8, (R8) 86 RET 87 88 // func exitThread(wait *atomic.Uint32) 89 TEXT runtime·exitThread(SB),NOSPLIT,$0-4 90 MOVW wait+0(FP), R0 91 // We're done using the stack. 92 MOVW $0, R2 93 storeloop: 94 LDREX (R0), R4 // loads R4 95 STREX R2, (R0), R1 // stores R2 96 CMP $0, R1 97 BNE storeloop 98 MOVW $0, R0 // arg 1 long *state 99 MOVW $SYS_thr_exit, R7 100 SWI $0 101 MOVW.CS $0, R8 // crash on syscall failure 102 MOVW.CS R8, (R8) 103 JMP 0(PC) 104 105 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0 106 MOVW name+0(FP), R0 // arg 1 name 107 MOVW mode+4(FP), R1 // arg 2 mode 108 MOVW perm+8(FP), R2 // arg 3 perm 109 MOVW $SYS_open, R7 110 SWI $0 111 MOVW.CS $-1, R0 112 MOVW R0, ret+12(FP) 113 RET 114 115 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0 116 MOVW fd+0(FP), R0 // arg 1 fd 117 MOVW p+4(FP), R1 // arg 2 buf 118 MOVW n+8(FP), R2 // arg 3 count 119 MOVW $SYS_read, R7 120 SWI $0 121 RSB.CS $0, R0 // caller expects negative errno 122 MOVW R0, ret+12(FP) 123 RET 124 125 // func pipe2(flags int32) (r, w int32, errno int32) 126 TEXT runtime·pipe2(SB),NOSPLIT,$0-16 127 MOVW $r+4(FP), R0 128 MOVW flags+0(FP), R1 129 MOVW $SYS_pipe2, R7 130 SWI $0 131 RSB.CS $0, R0 132 MOVW R0, errno+12(FP) 133 RET 134 135 TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0 136 MOVW fd+0(FP), R0 // arg 1 fd 137 MOVW p+4(FP), R1 // arg 2 buf 138 MOVW n+8(FP), R2 // arg 3 count 139 MOVW $SYS_write, R7 140 SWI $0 141 RSB.CS $0, R0 // caller expects negative errno 142 MOVW R0, ret+12(FP) 143 RET 144 145 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0 146 MOVW fd+0(FP), R0 // arg 1 fd 147 MOVW $SYS_close, R7 148 SWI $0 149 MOVW.CS $-1, R0 150 MOVW R0, ret+4(FP) 151 RET 152 153 TEXT runtime·thr_self(SB),NOSPLIT,$0-4 154 // thr_self(&0(FP)) 155 MOVW $ret+0(FP), R0 // arg 1 156 MOVW $SYS_thr_self, R7 157 SWI $0 158 RET 159 160 TEXT runtime·thr_kill(SB),NOSPLIT,$0-8 161 // thr_kill(tid, sig) 162 MOVW tid+0(FP), R0 // arg 1 id 163 MOVW sig+4(FP), R1 // arg 2 signal 164 MOVW $SYS_thr_kill, R7 165 SWI $0 166 RET 167 168 TEXT runtime·raiseproc(SB),NOSPLIT,$0 169 // getpid 170 MOVW $SYS_getpid, R7 171 SWI $0 172 // kill(self, sig) 173 // arg 1 - pid, now in R0 174 MOVW sig+0(FP), R1 // arg 2 - signal 175 MOVW $SYS_kill, R7 176 SWI $0 177 RET 178 179 TEXT runtime·setitimer(SB), NOSPLIT|NOFRAME, $0 180 MOVW mode+0(FP), R0 181 MOVW new+4(FP), R1 182 MOVW old+8(FP), R2 183 MOVW $SYS_setitimer, R7 184 SWI $0 185 RET 186 187 // func fallback_walltime() (sec int64, nsec int32) 188 TEXT runtime·fallback_walltime(SB), NOSPLIT, $32-12 189 MOVW $0, R0 // CLOCK_REALTIME 190 MOVW $8(R13), R1 191 MOVW $SYS_clock_gettime, R7 192 SWI $0 193 194 MOVW 8(R13), R0 // sec.low 195 MOVW 12(R13), R1 // sec.high 196 MOVW 16(R13), R2 // nsec 197 198 MOVW R0, sec_lo+0(FP) 199 MOVW R1, sec_hi+4(FP) 200 MOVW R2, nsec+8(FP) 201 RET 202 203 // func fallback_nanotime() int64 204 TEXT runtime·fallback_nanotime(SB), NOSPLIT, $32 205 MOVW $4, R0 // CLOCK_MONOTONIC 206 MOVW $8(R13), R1 207 MOVW $SYS_clock_gettime, R7 208 SWI $0 209 210 MOVW 8(R13), R0 // sec.low 211 MOVW 12(R13), R4 // sec.high 212 MOVW 16(R13), R2 // nsec 213 214 MOVW $1000000000, R3 215 MULLU R0, R3, (R1, R0) 216 MUL R3, R4 217 ADD.S R2, R0 218 ADC R4, R1 219 220 MOVW R0, ret_lo+0(FP) 221 MOVW R1, ret_hi+4(FP) 222 RET 223 224 TEXT runtime·asmSigaction(SB),NOSPLIT|NOFRAME,$0 225 MOVW sig+0(FP), R0 // arg 1 sig 226 MOVW new+4(FP), R1 // arg 2 act 227 MOVW old+8(FP), R2 // arg 3 oact 228 MOVW $SYS_sigaction, R7 229 SWI $0 230 MOVW.CS $-1, R0 231 MOVW R0, ret+12(FP) 232 RET 233 234 TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$0 235 // Reserve space for callee-save registers and arguments. 236 MOVM.DB.W [R4-R11], (R13) 237 SUB $16, R13 238 239 // this might be called in external code context, 240 // where g is not set. 241 // first save R0, because runtime·load_g will clobber it 242 MOVW R0, 4(R13) // signum 243 MOVB runtime·iscgo(SB), R0 244 CMP $0, R0 245 BL.NE runtime·load_g(SB) 246 247 MOVW R1, 8(R13) 248 MOVW R2, 12(R13) 249 BL runtime·sigtrampgo(SB) 250 251 // Restore callee-save registers. 252 ADD $16, R13 253 MOVM.IA.W (R13), [R4-R11] 254 255 RET 256 257 TEXT runtime·mmap(SB),NOSPLIT,$16 258 MOVW addr+0(FP), R0 // arg 1 addr 259 MOVW n+4(FP), R1 // arg 2 len 260 MOVW prot+8(FP), R2 // arg 3 prot 261 MOVW flags+12(FP), R3 // arg 4 flags 262 // arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack 263 // note the C runtime only passes the 32-bit offset_lo to us 264 MOVW fd+16(FP), R4 // arg 5 265 MOVW R4, 4(R13) 266 MOVW off+20(FP), R5 // arg 6 lower 32-bit 267 // the word at 8(R13) is skipped due to 64-bit argument alignment. 268 MOVW R5, 12(R13) 269 MOVW $0, R6 // higher 32-bit for arg 6 270 MOVW R6, 16(R13) 271 ADD $4, R13 272 MOVW $SYS_mmap, R7 273 SWI $0 274 SUB $4, R13 275 MOVW $0, R1 276 MOVW.CS R0, R1 // if failed, put in R1 277 MOVW.CS $0, R0 278 MOVW R0, p+24(FP) 279 MOVW R1, err+28(FP) 280 RET 281 282 TEXT runtime·munmap(SB),NOSPLIT,$0 283 MOVW addr+0(FP), R0 // arg 1 addr 284 MOVW n+4(FP), R1 // arg 2 len 285 MOVW $SYS_munmap, R7 286 SWI $0 287 MOVW.CS $0, R8 // crash on syscall failure 288 MOVW.CS R8, (R8) 289 RET 290 291 TEXT runtime·madvise(SB),NOSPLIT,$0 292 MOVW addr+0(FP), R0 // arg 1 addr 293 MOVW n+4(FP), R1 // arg 2 len 294 MOVW flags+8(FP), R2 // arg 3 flags 295 MOVW $SYS_madvise, R7 296 SWI $0 297 MOVW.CS $-1, R0 298 MOVW R0, ret+12(FP) 299 RET 300 301 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0 302 MOVW new+0(FP), R0 303 MOVW old+4(FP), R1 304 MOVW $SYS_sigaltstack, R7 305 SWI $0 306 MOVW.CS $0, R8 // crash on syscall failure 307 MOVW.CS R8, (R8) 308 RET 309 310 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16 311 MOVW sig+4(FP), R0 312 MOVW info+8(FP), R1 313 MOVW ctx+12(FP), R2 314 MOVW fn+0(FP), R11 315 MOVW R13, R4 316 SUB $24, R13 317 BIC $0x7, R13 // alignment for ELF ABI 318 BL (R11) 319 MOVW R4, R13 320 RET 321 322 TEXT runtime·usleep(SB),NOSPLIT,$16 323 MOVW usec+0(FP), R0 324 CALL runtime·usplitR0(SB) 325 // 0(R13) is the saved LR, don't use it 326 MOVW R0, 4(R13) // tv_sec.low 327 MOVW $0, R0 328 MOVW R0, 8(R13) // tv_sec.high 329 MOVW $1000, R2 330 MUL R1, R2 331 MOVW R2, 12(R13) // tv_nsec 332 333 MOVW $4(R13), R0 // arg 1 - rqtp 334 MOVW $0, R1 // arg 2 - rmtp 335 MOVW $SYS_nanosleep, R7 336 SWI $0 337 RET 338 339 TEXT runtime·sysctl(SB),NOSPLIT,$0 340 MOVW mib+0(FP), R0 // arg 1 - name 341 MOVW miblen+4(FP), R1 // arg 2 - namelen 342 MOVW out+8(FP), R2 // arg 3 - old 343 MOVW size+12(FP), R3 // arg 4 - oldlenp 344 // arg 5 (newp) and arg 6 (newlen) are passed on stack 345 ADD $20, R13 346 MOVW $SYS___sysctl, R7 347 SWI $0 348 SUB.CS $0, R0, R0 349 SUB $20, R13 350 MOVW R0, ret+24(FP) 351 RET 352 353 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0 354 MOVW $SYS_sched_yield, R7 355 SWI $0 356 RET 357 358 TEXT runtime·sigprocmask(SB),NOSPLIT,$0 359 MOVW how+0(FP), R0 // arg 1 - how 360 MOVW new+4(FP), R1 // arg 2 - set 361 MOVW old+8(FP), R2 // arg 3 - oset 362 MOVW $SYS_sigprocmask, R7 363 SWI $0 364 MOVW.CS $0, R8 // crash on syscall failure 365 MOVW.CS R8, (R8) 366 RET 367 368 // int32 runtime·kqueue(void) 369 TEXT runtime·kqueue(SB),NOSPLIT,$0 370 MOVW $SYS_kqueue, R7 371 SWI $0 372 RSB.CS $0, R0 373 MOVW R0, ret+0(FP) 374 RET 375 376 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout) 377 TEXT runtime·kevent(SB),NOSPLIT,$0 378 MOVW kq+0(FP), R0 // kq 379 MOVW ch+4(FP), R1 // changelist 380 MOVW nch+8(FP), R2 // nchanges 381 MOVW ev+12(FP), R3 // eventlist 382 ADD $20, R13 // pass arg 5 and 6 on stack 383 MOVW $SYS_kevent, R7 384 SWI $0 385 RSB.CS $0, R0 386 SUB $20, R13 387 MOVW R0, ret+24(FP) 388 RET 389 390 // void runtime·closeonexec(int32 fd) 391 TEXT runtime·closeonexec(SB),NOSPLIT,$0 392 MOVW fd+0(FP), R0 // fd 393 MOVW $2, R1 // F_SETFD 394 MOVW $1, R2 // FD_CLOEXEC 395 MOVW $SYS_fcntl, R7 396 SWI $0 397 RET 398 399 // TODO: this is only valid for ARMv7+ 400 TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0 401 B runtime·armPublicationBarrier(SB) 402 403 // TODO(minux): this only supports ARMv6K+. 404 TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0 405 WORD $0xee1d0f70 // mrc p15, 0, r0, c13, c0, 3 406 RET 407 408 // func cpuset_getaffinity(level int, which int, id int64, size int, mask *byte) int32 409 TEXT runtime·cpuset_getaffinity(SB), NOSPLIT, $0-28 410 MOVW level+0(FP), R0 411 MOVW which+4(FP), R1 412 MOVW id_lo+8(FP), R2 413 MOVW id_hi+12(FP), R3 414 ADD $20, R13 // Pass size and mask on stack. 415 MOVW $SYS_cpuset_getaffinity, R7 416 SWI $0 417 RSB.CS $0, R0 418 SUB $20, R13 419 MOVW R0, ret+24(FP) 420 RET 421 422 // func getCntxct(physical bool) uint32 423 TEXT runtime·getCntxct(SB),NOSPLIT|NOFRAME,$0-8 424 MOVB runtime·goarm(SB), R11 425 CMP $7, R11 426 BLT 2(PC) 427 DMB 428 429 MOVB physical+0(FP), R0 430 CMP $1, R0 431 B.NE 3(PC) 432 433 // get CNTPCT (Physical Count Register) into R0(low) R1(high) 434 // mrrc 15, 0, r0, r1, cr14 435 WORD $0xec510f0e 436 B 2(PC) 437 438 // get CNTVCT (Virtual Count Register) into R0(low) R1(high) 439 // mrrc 15, 1, r0, r1, cr14 440 WORD $0xec510f1e 441 442 MOVW R0, ret+4(FP) 443 RET