github.com/zach-klippenstein/go@v0.0.0-20150108044943-fcfbeb3adf58/src/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_sigaltstack (SYS_BASE + 53) 22 #define SYS_munmap (SYS_BASE + 73) 23 #define SYS_madvise (SYS_BASE + 75) 24 #define SYS_setitimer (SYS_BASE + 83) 25 #define SYS_fcntl (SYS_BASE + 92) 26 #define SYS_getrlimit (SYS_BASE + 194) 27 #define SYS___sysctl (SYS_BASE + 202) 28 #define SYS_nanosleep (SYS_BASE + 240) 29 #define SYS_clock_gettime (SYS_BASE + 232) 30 #define SYS_sched_yield (SYS_BASE + 331) 31 #define SYS_sigprocmask (SYS_BASE + 340) 32 #define SYS_kqueue (SYS_BASE + 362) 33 #define SYS_kevent (SYS_BASE + 363) 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 42 TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0 43 MOVW 0(FP), R0 44 MOVW 4(FP), R1 45 MOVW 8(FP), R2 46 MOVW 12(FP), R3 47 ADD $20, R13 // arg 5 is passed on stack 48 MOVW $SYS__umtx_op, R7 49 SWI $0 50 SUB $20, R13 51 // BCS error 52 MOVW R0, ret+20(FP) 53 RET 54 55 TEXT runtime·thr_new(SB),NOSPLIT,$0 56 MOVW 0(FP), R0 57 MOVW 4(FP), R1 58 MOVW $SYS_thr_new, R7 59 SWI $0 60 RET 61 62 TEXT runtime·thr_start(SB),NOSPLIT,$0 63 // set up g 64 MOVW m_g0(R0), g 65 MOVW R0, g_m(g) 66 BL runtime·emptyfunc(SB) // fault if stack check is wrong 67 BL runtime·mstart(SB) 68 69 MOVW $2, R8 // crash (not reached) 70 MOVW R8, (R8) 71 RET 72 73 // Exit the entire program (like C exit) 74 TEXT runtime·exit(SB),NOSPLIT,$-8 75 MOVW 0(FP), R0 // arg 1 exit status 76 MOVW $SYS_exit, R7 77 SWI $0 78 MOVW.CS $0, R8 // crash on syscall failure 79 MOVW.CS R8, (R8) 80 RET 81 82 TEXT runtime·exit1(SB),NOSPLIT,$-8 83 MOVW 0(FP), R0 // arg 1 exit status 84 MOVW $SYS_thr_exit, R7 85 SWI $0 86 MOVW.CS $0, R8 // crash on syscall failure 87 MOVW.CS R8, (R8) 88 RET 89 90 TEXT runtime·open(SB),NOSPLIT,$-8 91 MOVW 0(FP), R0 // arg 1 name 92 MOVW 4(FP), R1 // arg 2 mode 93 MOVW 8(FP), R2 // arg 3 perm 94 MOVW $SYS_open, R7 95 SWI $0 96 MOVW R0, ret+12(FP) 97 RET 98 99 TEXT runtime·read(SB),NOSPLIT,$-8 100 MOVW 0(FP), R0 // arg 1 fd 101 MOVW 4(FP), R1 // arg 2 buf 102 MOVW 8(FP), R2 // arg 3 count 103 MOVW $SYS_read, R7 104 SWI $0 105 MOVW R0, ret+12(FP) 106 RET 107 108 TEXT runtime·write(SB),NOSPLIT,$-8 109 MOVW 0(FP), R0 // arg 1 fd 110 MOVW 4(FP), R1 // arg 2 buf 111 MOVW 8(FP), R2 // arg 3 count 112 MOVW $SYS_write, R7 113 SWI $0 114 MOVW R0, ret+12(FP) 115 RET 116 117 TEXT runtime·close(SB),NOSPLIT,$-8 118 MOVW 0(FP), R0 // arg 1 fd 119 MOVW $SYS_close, R7 120 SWI $0 121 MOVW R0, ret+4(FP) 122 RET 123 124 TEXT runtime·getrlimit(SB),NOSPLIT,$-8 125 MOVW 0(FP), R0 126 MOVW 4(FP), R1 127 MOVW $SYS_getrlimit, R7 128 SWI $0 129 MOVW R0, ret+8(FP) 130 RET 131 132 TEXT runtime·raise(SB),NOSPLIT,$8 133 // thr_self(&4(R13)) 134 MOVW $4(R13), R0 // arg 1 &4(R13) 135 MOVW $SYS_thr_self, R7 136 SWI $0 137 // thr_kill(self, SIGPIPE) 138 MOVW 4(R13), R0 // arg 1 id 139 MOVW sig+0(FP), R1 // arg 2 - signal 140 MOVW $SYS_thr_kill, R7 141 SWI $0 142 RET 143 144 TEXT runtime·setitimer(SB), NOSPLIT, $-8 145 MOVW 0(FP), R0 146 MOVW 4(FP), R1 147 MOVW 8(FP), R2 148 MOVW $SYS_setitimer, R7 149 SWI $0 150 RET 151 152 // func now() (sec int64, nsec int32) 153 TEXT time·now(SB), NOSPLIT, $32 154 MOVW $0, R0 // CLOCK_REALTIME 155 MOVW $8(R13), R1 156 MOVW $SYS_clock_gettime, R7 157 SWI $0 158 159 MOVW 8(R13), R0 // sec.low 160 MOVW 12(R13), R1 // sec.high 161 MOVW 16(R13), R2 // nsec 162 163 MOVW R0, 0(FP) 164 MOVW R1, 4(FP) 165 MOVW R2, 8(FP) 166 RET 167 168 // int64 nanotime(void) so really 169 // void nanotime(int64 *nsec) 170 TEXT runtime·nanotime(SB), NOSPLIT, $32 171 // We can use CLOCK_MONOTONIC_FAST here when we drop 172 // support for FreeBSD 8-STABLE. 173 MOVW $4, R0 // CLOCK_MONOTONIC 174 MOVW $8(R13), R1 175 MOVW $SYS_clock_gettime, R7 176 SWI $0 177 178 MOVW 8(R13), R0 // sec.low 179 MOVW 12(R13), R4 // sec.high 180 MOVW 16(R13), R2 // nsec 181 182 MOVW $1000000000, R3 183 MULLU R0, R3, (R1, R0) 184 MUL R3, R4 185 ADD.S R2, R0 186 ADC R4, R1 187 188 MOVW R0, ret_lo+0(FP) 189 MOVW R1, ret_hi+4(FP) 190 RET 191 192 TEXT runtime·sigaction(SB),NOSPLIT,$-8 193 MOVW 0(FP), R0 // arg 1 sig 194 MOVW 4(FP), R1 // arg 2 act 195 MOVW 8(FP), R2 // arg 3 oact 196 MOVW $SYS_sigaction, R7 197 SWI $0 198 MOVW.CS $0, R8 // crash on syscall failure 199 MOVW.CS R8, (R8) 200 RET 201 202 TEXT runtime·sigtramp(SB),NOSPLIT,$24 203 // this might be called in external code context, 204 // where g is not set. 205 // first save R0, because runtime·load_g will clobber it 206 MOVW R0, 4(R13) // signum 207 MOVB runtime·iscgo(SB), R0 208 CMP $0, R0 209 BL.NE runtime·load_g(SB) 210 211 CMP $0, g 212 BNE 4(PC) 213 // signal number is already prepared in 4(R13) 214 MOVW $runtime·badsignal(SB), R11 215 BL (R11) 216 RET 217 218 // save g 219 MOVW g, R4 220 MOVW g, 20(R13) 221 222 // g = m->signal 223 MOVW g_m(g), R8 224 MOVW m_gsignal(R8), g 225 226 // R0 is already saved 227 MOVW R1, 8(R13) // info 228 MOVW R2, 12(R13) // context 229 MOVW R4, 16(R13) // oldg 230 231 BL runtime·sighandler(SB) 232 233 // restore g 234 MOVW 20(R13), g 235 RET 236 237 TEXT runtime·mmap(SB),NOSPLIT,$16 238 MOVW 0(FP), R0 // arg 1 addr 239 MOVW 4(FP), R1 // arg 2 len 240 MOVW 8(FP), R2 // arg 3 prot 241 MOVW 12(FP), R3 // arg 4 flags 242 // arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack 243 // note the C runtime only passes the 32-bit offset_lo to us 244 MOVW 16(FP), R4 // arg 5 245 MOVW R4, 4(R13) 246 MOVW 20(FP), R5 // arg 6 lower 32-bit 247 // the word at 8(R13) is skipped due to 64-bit argument alignment. 248 MOVW R5, 12(R13) 249 MOVW $0, R6 // higher 32-bit for arg 6 250 MOVW R6, 16(R13) 251 ADD $4, R13 252 MOVW $SYS_mmap, R7 253 SWI $0 254 SUB $4, R13 255 // TODO(dfc) error checking ? 256 MOVW R0, ret+24(FP) 257 RET 258 259 TEXT runtime·munmap(SB),NOSPLIT,$0 260 MOVW 0(FP), R0 // arg 1 addr 261 MOVW 4(FP), R1 // arg 2 len 262 MOVW $SYS_munmap, R7 263 SWI $0 264 MOVW.CS $0, R8 // crash on syscall failure 265 MOVW.CS R8, (R8) 266 RET 267 268 TEXT runtime·madvise(SB),NOSPLIT,$0 269 MOVW 0(FP), R0 // arg 1 addr 270 MOVW 4(FP), R1 // arg 2 len 271 MOVW 8(FP), R2 // arg 3 flags 272 MOVW $SYS_madvise, R7 273 SWI $0 274 // ignore failure - maybe pages are locked 275 RET 276 277 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 278 MOVW new+0(FP), R0 279 MOVW old+4(FP), R1 280 MOVW $SYS_sigaltstack, R7 281 SWI $0 282 MOVW.CS $0, R8 // crash on syscall failure 283 MOVW.CS R8, (R8) 284 RET 285 286 TEXT runtime·usleep(SB),NOSPLIT,$16 287 MOVW usec+0(FP), R0 288 MOVW R0, R2 289 MOVW $1000000, R1 290 DIV R1, R0 291 // 0(R13) is the saved LR, don't use it 292 MOVW R0, 4(R13) // tv_sec.low 293 MOVW $0, R0 294 MOVW R0, 8(R13) // tv_sec.high 295 MOD R1, R2 296 MOVW $1000, R1 297 MUL R1, R2 298 MOVW R2, 12(R13) // tv_nsec 299 300 MOVW $4(R13), R0 // arg 1 - rqtp 301 MOVW $0, R1 // arg 2 - rmtp 302 MOVW $SYS_nanosleep, R7 303 SWI $0 304 RET 305 306 TEXT runtime·sysctl(SB),NOSPLIT,$0 307 MOVW 0(FP), R0 // arg 1 - name 308 MOVW 4(FP), R1 // arg 2 - namelen 309 MOVW 8(FP), R2 // arg 3 - old 310 MOVW 12(FP), R3 // arg 4 - oldlenp 311 // arg 5 (newp) and arg 6 (newlen) are passed on stack 312 ADD $20, R13 313 MOVW $SYS___sysctl, R7 314 SWI $0 315 SUB.CS $0, R0, R0 316 SUB $20, R13 317 MOVW R0, ret+24(FP) 318 RET 319 320 TEXT runtime·osyield(SB),NOSPLIT,$-4 321 MOVW $SYS_sched_yield, R7 322 SWI $0 323 RET 324 325 TEXT runtime·sigprocmask(SB),NOSPLIT,$0 326 MOVW $3, R0 // arg 1 - how (SIG_SETMASK) 327 MOVW 0(FP), R1 // arg 2 - set 328 MOVW 4(FP), R2 // arg 3 - oset 329 MOVW $SYS_sigprocmask, R7 330 SWI $0 331 MOVW.CS $0, R8 // crash on syscall failure 332 MOVW.CS R8, (R8) 333 RET 334 335 // int32 runtime·kqueue(void) 336 TEXT runtime·kqueue(SB),NOSPLIT,$0 337 MOVW $SYS_kqueue, R7 338 SWI $0 339 RSB.CS $0, R0 340 MOVW R0, ret+0(FP) 341 RET 342 343 // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout) 344 TEXT runtime·kevent(SB),NOSPLIT,$0 345 MOVW 0(FP), R0 // kq 346 MOVW 4(FP), R1 // changelist 347 MOVW 8(FP), R2 // nchanges 348 MOVW 12(FP), R3 // eventlist 349 ADD $20, R13 // pass arg 5 and 6 on stack 350 MOVW $SYS_kevent, R7 351 SWI $0 352 RSB.CS $0, R0 353 SUB $20, R13 354 MOVW R0, ret+24(FP) 355 RET 356 357 // void runtime·closeonexec(int32 fd) 358 TEXT runtime·closeonexec(SB),NOSPLIT,$0 359 MOVW 0(FP), R0 // fd 360 MOVW $2, R1 // F_SETFD 361 MOVW $1, R2 // FD_CLOEXEC 362 MOVW $SYS_fcntl, R7 363 SWI $0 364 RET 365 366 TEXT runtime·casp1(SB),NOSPLIT,$0 367 B runtime·cas(SB) 368 369 // TODO(minux): this is only valid for ARMv6+ 370 // bool armcas(int32 *val, int32 old, int32 new) 371 // Atomically: 372 // if(*val == old){ 373 // *val = new; 374 // return 1; 375 // }else 376 // return 0; 377 TEXT runtime·cas(SB),NOSPLIT,$0 378 B runtime·armcas(SB) 379 380 // TODO(minux): this only supports ARMv6K+. 381 TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4 382 WORD $0xee1d0f70 // mrc p15, 0, r0, c13, c0, 3 383 RET