rsc.io/go@v0.0.0-20150416155037-e040fd465409/src/runtime/sys_linux_arm64.s (about) 1 // Copyright 2014 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 // 6 // System calls and other sys.stuff for arm64, Linux 7 // 8 9 #include "go_asm.h" 10 #include "go_tls.h" 11 #include "textflag.h" 12 13 #define AT_FDCWD -100 14 15 #define SYS_exit 93 16 #define SYS_read 63 17 #define SYS_write 64 18 #define SYS_openat 56 19 #define SYS_close 57 20 #define SYS_fcntl 25 21 #define SYS_gettimeofday 169 22 #define SYS_pselect6 72 23 #define SYS_mmap 222 24 #define SYS_munmap 215 25 #define SYS_setitimer 103 26 #define SYS_clone 220 27 #define SYS_sched_yield 124 28 #define SYS_rt_sigreturn 139 29 #define SYS_rt_sigaction 134 30 #define SYS_rt_sigprocmask 135 31 #define SYS_sigaltstack 132 32 #define SYS_getrlimit 163 33 #define SYS_madvise 233 34 #define SYS_mincore 232 35 #define SYS_gettid 178 36 #define SYS_tkill 130 37 #define SYS_futex 98 38 #define SYS_sched_getaffinity 123 39 #define SYS_exit_group 94 40 #define SYS_epoll_create1 20 41 #define SYS_epoll_ctl 21 42 #define SYS_epoll_pwait 22 43 #define SYS_clock_gettime 113 44 45 TEXT runtime·exit(SB),NOSPLIT,$-8-4 46 MOVW code+0(FP), R0 47 MOVD $SYS_exit_group, R8 48 SVC 49 RET 50 51 TEXT runtime·exit1(SB),NOSPLIT,$-8-4 52 MOVW code+0(FP), R0 53 MOVD $SYS_exit, R8 54 SVC 55 RET 56 57 TEXT runtime·open(SB),NOSPLIT,$-8-20 58 MOVD $AT_FDCWD, R0 59 MOVD name+0(FP), R1 60 MOVW mode+8(FP), R2 61 MOVW perm+12(FP), R3 62 MOVD $SYS_openat, R8 63 SVC 64 CMN $4095, R0 65 BCC done 66 MOVW $-1, R0 67 done: 68 MOVW R0, ret+16(FP) 69 RET 70 71 TEXT runtime·closefd(SB),NOSPLIT,$-8-12 72 MOVW fd+0(FP), R0 73 MOVD $SYS_close, R8 74 SVC 75 BCC done 76 MOVW $-1, R0 77 done: 78 MOVW R0, ret+8(FP) 79 RET 80 81 TEXT runtime·write(SB),NOSPLIT,$-8-28 82 MOVD fd+0(FP), R0 83 MOVD p+8(FP), R1 84 MOVW n+16(FP), R2 85 MOVD $SYS_write, R8 86 SVC 87 BCC done 88 MOVW $-1, R0 89 done: 90 MOVW R0, ret+24(FP) 91 RET 92 93 TEXT runtime·read(SB),NOSPLIT,$-8-28 94 MOVW fd+0(FP), R0 95 MOVD p+8(FP), R1 96 MOVW n+16(FP), R2 97 MOVD $SYS_read, R8 98 SVC 99 BCC done 100 MOVW $-1, R0 101 done: 102 MOVW R0, ret+24(FP) 103 RET 104 105 TEXT runtime·getrlimit(SB),NOSPLIT,$-8-20 106 MOVW kind+0(FP), R0 107 MOVD limit+8(FP), R1 108 MOVD $SYS_getrlimit, R8 109 SVC 110 MOVW R0, ret+16(FP) 111 RET 112 113 TEXT runtime·usleep(SB),NOSPLIT,$16-4 114 MOVWU usec+0(FP), R3 115 MOVD R3, R5 116 MOVW $1000000, R4 117 UDIV R4, R3 118 MOVD R3, 8(RSP) 119 MUL R3, R4 120 SUB R4, R5 121 MOVW $1000, R4 122 MUL R4, R5 123 MOVD R5, 16(RSP) 124 125 // pselect6(0, 0, 0, 0, &ts, 0) 126 MOVD $0, R0 127 MOVD R0, R1 128 MOVD R0, R2 129 MOVD R0, R3 130 ADD $8, RSP, R4 131 MOVD R0, R5 132 MOVD $SYS_pselect6, R8 133 SVC 134 RET 135 136 TEXT runtime·raise(SB),NOSPLIT,$-8 137 MOVD $SYS_gettid, R8 138 SVC 139 MOVW R0, R0 // arg 1 tid 140 MOVW sig+0(FP), R1 // arg 2 141 MOVD $SYS_tkill, R8 142 SVC 143 RET 144 145 TEXT runtime·setitimer(SB),NOSPLIT,$-8-24 146 MOVW mode+0(FP), R0 147 MOVD new+8(FP), R1 148 MOVD old+16(FP), R2 149 MOVD $SYS_setitimer, R8 150 SVC 151 RET 152 153 TEXT runtime·mincore(SB),NOSPLIT,$-8-28 154 MOVD addr+0(FP), R0 155 MOVD n+8(FP), R1 156 MOVD dst+16(FP), R2 157 MOVD $SYS_mincore, R8 158 SVC 159 MOVW R0, ret+24(FP) 160 RET 161 162 // func now() (sec int64, nsec int32) 163 TEXT time·now(SB),NOSPLIT,$16-12 164 MOVD RSP, R0 165 MOVD $0, R1 166 MOVD $SYS_gettimeofday, R8 167 SVC 168 MOVD 0(RSP), R3 // sec 169 MOVD 8(RSP), R5 // usec 170 MOVD $1000, R4 171 MUL R4, R5 172 MOVD R3, sec+0(FP) 173 MOVW R5, nsec+8(FP) 174 RET 175 176 TEXT runtime·nanotime(SB),NOSPLIT,$16-8 177 MOVW $1, R0 // CLOCK_MONOTONIC 178 MOVD RSP, R1 179 MOVD $SYS_clock_gettime, R8 180 SVC 181 MOVD 0(RSP), R3 // sec 182 MOVD 8(RSP), R5 // nsec 183 // sec is in R3, nsec in R5 184 // return nsec in R3 185 MOVD $1000000000, R4 186 MUL R4, R3 187 ADD R5, R3 188 MOVD R3, ret+0(FP) 189 RET 190 191 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$-8-28 192 MOVW sig+0(FP), R0 193 MOVD new+8(FP), R1 194 MOVD old+16(FP), R2 195 MOVW size+24(FP), R3 196 MOVD $SYS_rt_sigprocmask, R8 197 SVC 198 CMN $4095, R0 199 BCC done 200 MOVD $0, R0 201 MOVD R0, (R0) // crash 202 done: 203 RET 204 205 TEXT runtime·rt_sigaction(SB),NOSPLIT,$-8-36 206 MOVD sig+0(FP), R0 207 MOVD new+8(FP), R1 208 MOVD old+16(FP), R2 209 MOVD size+24(FP), R3 210 MOVD $SYS_rt_sigaction, R8 211 SVC 212 MOVW R0, ret+32(FP) 213 RET 214 215 TEXT runtime·sigtramp(SB),NOSPLIT,$64 216 // this might be called in external code context, 217 // where g is not set. 218 // first save R0, because runtime·load_g will clobber it 219 MOVW R0, 8(RSP) 220 MOVBU runtime·iscgo(SB), R0 221 CMP $0, R0 222 BEQ 2(PC) 223 BL runtime·load_g(SB) 224 225 // check that g exists 226 CMP g, ZR 227 BNE ok 228 MOVD $runtime·badsignal(SB), R0 229 BL (R0) 230 RET 231 232 ok: 233 // save g 234 MOVD g, 40(RSP) 235 MOVD g, R6 236 237 // g = m->gsignal 238 MOVD g_m(g), R7 239 MOVD m_gsignal(R7), g 240 241 // R0 is already saved above 242 MOVD R1, 16(RSP) 243 MOVD R2, 24(RSP) 244 MOVD R6, 32(RSP) 245 246 BL runtime·sighandler(SB) 247 248 // restore g 249 MOVD 40(RSP), g 250 RET 251 252 TEXT runtime·mmap(SB),NOSPLIT,$-8 253 MOVD addr+0(FP), R0 254 MOVD n+8(FP), R1 255 MOVW prot+16(FP), R2 256 MOVW flags+20(FP), R3 257 MOVW fd+24(FP), R4 258 MOVW off+28(FP), R5 259 260 MOVD $SYS_mmap, R8 261 SVC 262 MOVD R0, ret+32(FP) 263 RET 264 265 TEXT runtime·munmap(SB),NOSPLIT,$-8 266 MOVD addr+0(FP), R0 267 MOVD n+8(FP), R1 268 MOVD $SYS_munmap, R8 269 SVC 270 CMN $4095, R0 271 BCC cool 272 MOVD R0, 0xf0(R0) 273 cool: 274 RET 275 276 TEXT runtime·madvise(SB),NOSPLIT,$-8 277 MOVD addr+0(FP), R0 278 MOVD n+8(FP), R1 279 MOVW flags+16(FP), R2 280 MOVD $SYS_madvise, R8 281 SVC 282 // ignore failure - maybe pages are locked 283 RET 284 285 // int64 futex(int32 *uaddr, int32 op, int32 val, 286 // struct timespec *timeout, int32 *uaddr2, int32 val2); 287 TEXT runtime·futex(SB),NOSPLIT,$-8 288 MOVD addr+0(FP), R0 289 MOVW op+8(FP), R1 290 MOVW val+12(FP), R2 291 MOVD ts+16(FP), R3 292 MOVD addr2+24(FP), R4 293 MOVW val3+32(FP), R5 294 MOVD $SYS_futex, R8 295 SVC 296 MOVW R0, ret+40(FP) 297 RET 298 299 // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 300 TEXT runtime·clone(SB),NOSPLIT,$-8 301 MOVW flags+0(FP), R0 302 MOVD stk+8(FP), R1 303 304 // Copy mp, gp, fn off parent stack for use by child. 305 MOVD mm+16(FP), R10 306 MOVD gg+24(FP), R11 307 MOVD fn+32(FP), R12 308 309 MOVD R10, -8(R1) 310 MOVD R11, -16(R1) 311 MOVD R12, -24(R1) 312 MOVD $1234, R10 313 MOVD R10, -32(R1) 314 315 MOVD $SYS_clone, R8 316 SVC 317 318 // In parent, return. 319 CMP ZR, R0 320 BEQ child 321 MOVW R0, ret+40(FP) 322 RET 323 child: 324 325 // In child, on new stack. 326 MOVD -32(RSP), R10 327 MOVD $1234, R0 328 CMP R0, R10 329 BEQ good 330 MOVD $0, R0 331 MOVD R0, (R0) // crash 332 333 // Initialize m->procid to Linux tid 334 good: 335 MOVD $SYS_gettid, R8 336 SVC 337 338 MOVD -24(RSP), R12 339 MOVD -16(RSP), R11 340 MOVD -8(RSP), R10 341 342 MOVD R0, m_procid(R10) 343 344 // TODO: setup TLS. 345 346 // In child, set up new stack 347 MOVD R10, g_m(R11) 348 MOVD R11, g 349 //CALL runtime·stackcheck(SB) 350 351 // Call fn 352 MOVD R12, R0 353 BL (R0) 354 355 // It shouldn't return. If it does, exit 356 MOVW $111, R0 357 again: 358 MOVD $SYS_exit_group, R8 359 SVC 360 B again // keep exiting 361 362 // int32 clone0(int32 flags, void *stack, void* fn, void* fnarg); 363 TEXT runtime·clone0(SB),NOSPLIT,$0 364 // TODO(spetrovic): Implement this method. 365 MOVW $-1, R0 366 MOVW R0, ret+32(FP) 367 RET 368 369 TEXT runtime·sigaltstack(SB),NOSPLIT,$-8 370 MOVD new+0(FP), R0 371 MOVD old+8(FP), R1 372 MOVD $SYS_sigaltstack, R8 373 SVC 374 CMN $4095, R0 375 BCC ok 376 MOVD $0, R0 377 MOVD R0, (R0) // crash 378 ok: 379 RET 380 381 TEXT runtime·osyield(SB),NOSPLIT,$-8 382 MOVD $SYS_sched_yield, R8 383 SVC 384 RET 385 386 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$-8 387 MOVD pid+0(FP), R0 388 MOVD len+8(FP), R1 389 MOVD buf+16(FP), R2 390 MOVD $SYS_sched_getaffinity, R8 391 SVC 392 MOVW R0, ret+24(FP) 393 RET 394 395 // int32 runtime·epollcreate(int32 size); 396 TEXT runtime·epollcreate(SB),NOSPLIT,$-8 397 MOVW $0, R0 398 MOVD $SYS_epoll_create1, R8 399 SVC 400 MOVW R0, ret+8(FP) 401 RET 402 403 // int32 runtime·epollcreate1(int32 flags); 404 TEXT runtime·epollcreate1(SB),NOSPLIT,$-8 405 MOVW flags+0(FP), R0 406 MOVD $SYS_epoll_create1, R8 407 SVC 408 MOVW R0, ret+8(FP) 409 RET 410 411 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 412 TEXT runtime·epollctl(SB),NOSPLIT,$-8 413 MOVW epfd+0(FP), R0 414 MOVW op+4(FP), R1 415 MOVW fd+8(FP), R2 416 MOVD ev+16(FP), R3 417 MOVD $SYS_epoll_ctl, R8 418 SVC 419 MOVW R0, ret+24(FP) 420 RET 421 422 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 423 TEXT runtime·epollwait(SB),NOSPLIT,$-8 424 MOVW epfd+0(FP), R0 425 MOVD ev+8(FP), R1 426 MOVW nev+16(FP), R2 427 MOVW timeout+20(FP), R3 428 MOVD $0, R4 429 MOVD $SYS_epoll_pwait, R8 430 SVC 431 MOVW R0, ret+24(FP) 432 RET 433 434 // void runtime·closeonexec(int32 fd); 435 TEXT runtime·closeonexec(SB),NOSPLIT,$-8 436 MOVW fd+0(FP), R0 // fd 437 MOVD $2, R1 // F_SETFD 438 MOVD $1, R2 // FD_CLOEXEC 439 MOVD $SYS_fcntl, R8 440 SVC 441 RET