1 // Copyright 2015 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 // +build linux 6 // +build mips64 mips64le 7 8 // 9 // System calls and other sys.stuff for mips64, Linux 10 // 11 12 #include "go_asm.h" 13 #include "go_tls.h" 14 #include "textflag.h" 15 16 #define SYS_exit 5058 17 #define SYS_read 5000 18 #define SYS_write 5001 19 #define SYS_open 5002 20 #define SYS_close 5003 21 #define SYS_getpid 5038 22 #define SYS_kill 5060 23 #define SYS_fcntl 5080 24 #define SYS_gettimeofday 5094 25 #define SYS_mmap 5009 26 #define SYS_munmap 5011 27 #define SYS_setitimer 5036 28 #define SYS_clone 5055 29 #define SYS_newselect 5022 30 #define SYS_sched_yield 5023 31 #define SYS_rt_sigreturn 5211 32 #define SYS_rt_sigaction 5013 33 #define SYS_rt_sigprocmask 5014 34 #define SYS_sigaltstack 5129 35 #define SYS_getrlimit 5095 36 #define SYS_madvise 5027 37 #define SYS_mincore 5026 38 #define SYS_gettid 5178 39 #define SYS_tkill 5192 40 #define SYS_futex 5194 41 #define SYS_sched_getaffinity 5196 42 #define SYS_exit_group 5205 43 #define SYS_epoll_create 5207 44 #define SYS_epoll_ctl 5208 45 #define SYS_epoll_wait 5209 46 #define SYS_clock_gettime 5222 47 #define SYS_epoll_create1 5285 48 #define SYS_brk 5012 49 50 TEXT runtimeexit(SB),NOSPLIT,$-8-4 51 MOVW code+0(FP), R4 52 MOVV $SYS_exit_group, R2 53 SYSCALL 54 RET 55 56 // func exitThread(wait *uint32) 57 TEXT runtimeexitThread(SB),NOSPLIT,$-8-8 58 MOVV wait+0(FP), R1 59 // We're done using the stack. 60 MOVW $0, R2 61 SYNC 62 MOVW R2, (R1) 63 SYNC 64 MOVW $0, R4 // exit code 65 MOVV $SYS_exit, R2 66 SYSCALL 67 JMP 0(PC) 68 69 TEXT runtimeopen(SB),NOSPLIT,$-8-20 70 MOVV name+0(FP), R4 71 MOVW mode+8(FP), R5 72 MOVW perm+12(FP), R6 73 MOVV $SYS_open, R2 74 SYSCALL 75 BEQ R7, 2(PC) 76 MOVW $-1, R2 77 MOVW R2, ret+16(FP) 78 RET 79 80 TEXT runtimeclosefd(SB),NOSPLIT,$-8-12 81 MOVW fd+0(FP), R4 82 MOVV $SYS_close, R2 83 SYSCALL 84 BEQ R7, 2(PC) 85 MOVW $-1, R2 86 MOVW R2, ret+8(FP) 87 RET 88 89 TEXT runtimewrite(SB),NOSPLIT,$-8-28 90 MOVV fd+0(FP), R4 91 MOVV p+8(FP), R5 92 MOVW n+16(FP), R6 93 MOVV $SYS_write, R2 94 SYSCALL 95 BEQ R7, 2(PC) 96 MOVW $-1, R2 97 MOVW R2, ret+24(FP) 98 RET 99 100 TEXT runtimeread(SB),NOSPLIT,$-8-28 101 MOVW fd+0(FP), R4 102 MOVV p+8(FP), R5 103 MOVW n+16(FP), R6 104 MOVV $SYS_read, R2 105 SYSCALL 106 BEQ R7, 2(PC) 107 MOVW $-1, R2 108 MOVW R2, ret+24(FP) 109 RET 110 111 TEXT runtimegetrlimit(SB),NOSPLIT,$-8-20 112 MOVW kind+0(FP), R4 // _RLIMIT_AS = 6 on linux/mips 113 MOVV limit+8(FP), R5 114 MOVV $SYS_getrlimit, R2 115 SYSCALL 116 MOVW R2, ret+16(FP) 117 RET 118 119 TEXT runtimeusleep(SB),NOSPLIT,$16-4 120 MOVWU usec+0(FP), R3 121 MOVV R3, R5 122 MOVW $1000000, R4 123 DIVVU R4, R3 124 MOVV LO, R3 125 MOVV R3, 8(R29) 126 MULVU R3, R4 127 MOVV LO, R4 128 SUBVU R4, R5 129 MOVV R5, 16(R29) 130 131 // select(0, 0, 0, 0, &tv) 132 MOVW $0, R4 133 MOVW $0, R5 134 MOVW $0, R6 135 MOVW $0, R7 136 ADDV $8, R29, R8 137 MOVV $SYS_newselect, R2 138 SYSCALL 139 RET 140 141 TEXT runtimegettid(SB),NOSPLIT,$0-4 142 MOVV $SYS_gettid, R2 143 SYSCALL 144 MOVW R2, ret+0(FP) 145 RET 146 147 TEXT runtimeraise(SB),NOSPLIT,$-8 148 MOVV $SYS_gettid, R2 149 SYSCALL 150 MOVW R2, R4 // arg 1 tid 151 MOVW sig+0(FP), R5 // arg 2 152 MOVV $SYS_tkill, R2 153 SYSCALL 154 RET 155 156 TEXT runtimeraiseproc(SB),NOSPLIT,$-8 157 MOVV $SYS_getpid, R2 158 SYSCALL 159 MOVW R2, R4 // arg 1 pid 160 MOVW sig+0(FP), R5 // arg 2 161 MOVV $SYS_kill, R2 162 SYSCALL 163 RET 164 165 TEXT runtimesetitimer(SB),NOSPLIT,$-8-24 166 MOVW mode+0(FP), R4 167 MOVV new+8(FP), R5 168 MOVV old+16(FP), R6 169 MOVV $SYS_setitimer, R2 170 SYSCALL 171 RET 172 173 TEXT runtimemincore(SB),NOSPLIT,$-8-28 174 MOVV addr+0(FP), R4 175 MOVV n+8(FP), R5 176 MOVV dst+16(FP), R6 177 MOVV $SYS_mincore, R2 178 SYSCALL 179 SUBVU R2, R0, R2 // caller expects negative errno 180 MOVW R2, ret+24(FP) 181 RET 182 183 // func walltime() (sec int64, nsec int32) 184 TEXT runtimewalltime(SB),NOSPLIT,$16 185 MOVW $0, R4 // CLOCK_REALTIME 186 MOVV $0(R29), R5 187 MOVV $SYS_clock_gettime, R2 188 SYSCALL 189 MOVV 0(R29), R3 // sec 190 MOVV 8(R29), R5 // nsec 191 MOVV R3, sec+0(FP) 192 MOVW R5, nsec+8(FP) 193 RET 194 195 TEXT runtimenanotime(SB),NOSPLIT,$16 196 MOVW $1, R4 // CLOCK_MONOTONIC 197 MOVV $0(R29), R5 198 MOVV $SYS_clock_gettime, R2 199 SYSCALL 200 MOVV 0(R29), R3 // sec 201 MOVV 8(R29), R5 // nsec 202 // sec is in R3, nsec in R5 203 // return nsec in R3 204 MOVV $1000000000, R4 205 MULVU R4, R3 206 MOVV LO, R3 207 ADDVU R5, R3 208 MOVV R3, ret+0(FP) 209 RET 210 211 TEXT runtimertsigprocmask(SB),NOSPLIT,$-8-28 212 MOVW how+0(FP), R4 213 MOVV new+8(FP), R5 214 MOVV old+16(FP), R6 215 MOVW size+24(FP), R7 216 MOVV $SYS_rt_sigprocmask, R2 217 SYSCALL 218 BEQ R7, 2(PC) 219 MOVV R0, 0xf1(R0) // crash 220 RET 221 222 TEXT runtimert_sigaction(SB),NOSPLIT,$-8-36 223 MOVV sig+0(FP), R4 224 MOVV new+8(FP), R5 225 MOVV old+16(FP), R6 226 MOVV size+24(FP), R7 227 MOVV $SYS_rt_sigaction, R2 228 SYSCALL 229 MOVW R2, ret+32(FP) 230 RET 231 232 TEXT runtimesigfwd(SB),NOSPLIT,$0-32 233 MOVW sig+8(FP), R4 234 MOVV info+16(FP), R5 235 MOVV ctx+24(FP), R6 236 MOVV fn+0(FP), R25 237 JAL (R25) 238 RET 239 240 TEXT runtimesigtramp(SB),NOSPLIT,$64 241 // initialize REGSB = PC&0xffffffff00000000 242 BGEZAL R0, 1(PC) 243 SRLV $32, R31, RSB 244 SLLV $32, RSB 245 246 // this might be called in external code context, 247 // where g is not set. 248 MOVB runtimeiscgo(SB), R1 249 BEQ R1, 2(PC) 250 JAL runtimeload_g(SB) 251 252 MOVW R4, 8(R29) 253 MOVV R5, 16(R29) 254 MOVV R6, 24(R29) 255 MOVV $runtimesigtrampgo(SB), R1 256 JAL (R1) 257 RET 258 259 TEXT runtimecgoSigtramp(SB),NOSPLIT,$0 260 JMP runtimesigtramp(SB) 261 262 TEXT runtimemmap(SB),NOSPLIT,$-8 263 MOVV addr+0(FP), R4 264 MOVV n+8(FP), R5 265 MOVW prot+16(FP), R6 266 MOVW flags+20(FP), R7 267 MOVW fd+24(FP), R8 268 MOVW off+28(FP), R9 269 270 MOVV $SYS_mmap, R2 271 SYSCALL 272 BEQ R7, ok 273 MOVV $0, p+32(FP) 274 MOVV R2, err+40(FP) 275 RET 276 ok: 277 MOVV R2, p+32(FP) 278 MOVV $0, err+40(FP) 279 RET 280 281 TEXT runtimemunmap(SB),NOSPLIT,$-8 282 MOVV addr+0(FP), R4 283 MOVV n+8(FP), R5 284 MOVV $SYS_munmap, R2 285 SYSCALL 286 BEQ R7, 2(PC) 287 MOVV R0, 0xf3(R0) // crash 288 RET 289 290 TEXT runtimemadvise(SB),NOSPLIT,$-8 291 MOVV addr+0(FP), R4 292 MOVV n+8(FP), R5 293 MOVW flags+16(FP), R6 294 MOVV $SYS_madvise, R2 295 SYSCALL 296 // ignore failure - maybe pages are locked 297 RET 298 299 // int64 futex(int32 *uaddr, int32 op, int32 val, 300 // struct timespec *timeout, int32 *uaddr2, int32 val2); 301 TEXT runtimefutex(SB),NOSPLIT,$-8 302 MOVV addr+0(FP), R4 303 MOVW op+8(FP), R5 304 MOVW val+12(FP), R6 305 MOVV ts+16(FP), R7 306 MOVV addr2+24(FP), R8 307 MOVW val3+32(FP), R9 308 MOVV $SYS_futex, R2 309 SYSCALL 310 MOVW R2, ret+40(FP) 311 RET 312 313 // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 314 TEXT runtimeclone(SB),NOSPLIT,$-8 315 MOVW flags+0(FP), R4 316 MOVV stk+8(FP), R5 317 318 // Copy mp, gp, fn off parent stack for use by child. 319 // Careful: Linux system call clobbers ???. 320 MOVV mp+16(FP), R16 321 MOVV gp+24(FP), R17 322 MOVV fn+32(FP), R18 323 324 MOVV R16, -8(R5) 325 MOVV R17, -16(R5) 326 MOVV R18, -24(R5) 327 MOVV $1234, R16 328 MOVV R16, -32(R5) 329 330 MOVV $SYS_clone, R2 331 SYSCALL 332 333 // In parent, return. 334 BEQ R2, 3(PC) 335 MOVW R2, ret+40(FP) 336 RET 337 338 // In child, on new stack. 339 MOVV -32(R29), R16 340 MOVV $1234, R1 341 BEQ R16, R1, 2(PC) 342 MOVV R0, 0(R0) 343 344 // Initialize m->procid to Linux tid 345 MOVV $SYS_gettid, R2 346 SYSCALL 347 348 MOVV -24(R29), R18 // fn 349 MOVV -16(R29), R17 // g 350 MOVV -8(R29), R16 // m 351 352 BEQ R16, nog 353 BEQ R17, nog 354 355 MOVV R2, m_procid(R16) 356 357 // TODO: setup TLS. 358 359 // In child, set up new stack 360 MOVV R16, g_m(R17) 361 MOVV R17, g 362 //CALL runtimestackcheck(SB) 363 364 nog: 365 // Call fn 366 JAL (R18) 367 368 // It shouldn't return. If it does, exit that thread. 369 MOVW $111, R4 370 MOVV $SYS_exit, R2 371 SYSCALL 372 JMP -3(PC) // keep exiting 373 374 TEXT runtimesigaltstack(SB),NOSPLIT,$-8 375 MOVV new+0(FP), R4 376 MOVV old+8(FP), R5 377 MOVV $SYS_sigaltstack, R2 378 SYSCALL 379 BEQ R7, 2(PC) 380 MOVV R0, 0xf1(R0) // crash 381 RET 382 383 TEXT runtimeosyield(SB),NOSPLIT,$-8 384 MOVV $SYS_sched_yield, R2 385 SYSCALL 386 RET 387 388 TEXT runtimesched_getaffinity(SB),NOSPLIT,$-8 389 MOVV pid+0(FP), R4 390 MOVV len+8(FP), R5 391 MOVV buf+16(FP), R6 392 MOVV $SYS_sched_getaffinity, R2 393 SYSCALL 394 MOVW R2, ret+24(FP) 395 RET 396 397 // int32 runtimeepollcreate(int32 size); 398 TEXT runtimeepollcreate(SB),NOSPLIT,$-8 399 MOVW size+0(FP), R4 400 MOVV $SYS_epoll_create, R2 401 SYSCALL 402 MOVW R2, ret+8(FP) 403 RET 404 405 // int32 runtimeepollcreate1(int32 flags); 406 TEXT runtimeepollcreate1(SB),NOSPLIT,$-8 407 MOVW flags+0(FP), R4 408 MOVV $SYS_epoll_create1, R2 409 SYSCALL 410 MOVW R2, ret+8(FP) 411 RET 412 413 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 414 TEXT runtimeepollctl(SB),NOSPLIT,$-8 415 MOVW epfd+0(FP), R4 416 MOVW op+4(FP), R5 417 MOVW fd+8(FP), R6 418 MOVV ev+16(FP), R7 419 MOVV $SYS_epoll_ctl, R2 420 SYSCALL 421 MOVW R2, ret+24(FP) 422 RET 423 424 // int32 runtimeepollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 425 TEXT runtimeepollwait(SB),NOSPLIT,$-8 426 MOVW epfd+0(FP), R4 427 MOVV ev+8(FP), R5 428 MOVW nev+16(FP), R6 429 MOVW timeout+20(FP), R7 430 MOVV $SYS_epoll_wait, R2 431 SYSCALL 432 MOVW R2, ret+24(FP) 433 RET 434 435 // void runtimecloseonexec(int32 fd); 436 TEXT runtimecloseonexec(SB),NOSPLIT,$-8 437 MOVW fd+0(FP), R4 // fd 438 MOVV $2, R5 // F_SETFD 439 MOVV $1, R6 // FD_CLOEXEC 440 MOVV $SYS_fcntl, R2 441 SYSCALL 442 RET 443 444 // func sbrk0() uintptr 445 TEXT runtimesbrk0(SB),NOSPLIT,$-8-8 446 // Implemented as brk(NULL). 447 MOVV $0, R4 448 MOVV $SYS_brk, R2 449 SYSCALL 450 MOVV R2, ret+0(FP) 451 RET 452