1// Copyright 2016 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 mips mipsle 7 8// 9// System calls and other sys.stuff for mips, Linux 10// 11 12#include "go_asm.h" 13#include "go_tls.h" 14#include "textflag.h" 15 16#define SYS_exit 4001 17#define SYS_read 4003 18#define SYS_write 4004 19#define SYS_open 4005 20#define SYS_close 4006 21#define SYS_getpid 4020 22#define SYS_kill 4037 23#define SYS_fcntl 4055 24#define SYS_gettimeofday 4078 25#define SYS_mmap 4090 26#define SYS_munmap 4091 27#define SYS_setitimer 4104 28#define SYS_clone 4120 29#define SYS_newselect 4142 30#define SYS_sched_yield 4162 31#define SYS_rt_sigreturn 4193 32#define SYS_rt_sigaction 4194 33#define SYS_rt_sigprocmask 4195 34#define SYS_sigaltstack 4206 35#define SYS_getrlimit 4076 36#define SYS_madvise 4218 37#define SYS_mincore 4217 38#define SYS_gettid 4222 39#define SYS_tkill 4236 40#define SYS_futex 4238 41#define SYS_sched_getaffinity 4240 42#define SYS_exit_group 4246 43#define SYS_epoll_create 4248 44#define SYS_epoll_ctl 4249 45#define SYS_epoll_wait 4250 46#define SYS_clock_gettime 4263 47#define SYS_epoll_create1 4326 48 49TEXT runtime·exit(SB),NOSPLIT,$0-4 50 MOVW code+0(FP), R4 51 MOVW $SYS_exit_group, R2 52 SYSCALL 53 UNDEF 54 RET 55 56TEXT runtime·exit1(SB),NOSPLIT,$0-4 57 MOVW code+0(FP), R4 58 MOVW $SYS_exit, R2 59 SYSCALL 60 UNDEF 61 RET 62 63TEXT runtime·open(SB),NOSPLIT,$0-16 64 MOVW name+0(FP), R4 65 MOVW mode+4(FP), R5 66 MOVW perm+8(FP), R6 67 MOVW $SYS_open, R2 68 SYSCALL 69 BEQ R7, 2(PC) 70 MOVW $-1, R2 71 MOVW R2, ret+12(FP) 72 RET 73 74TEXT runtime·closefd(SB),NOSPLIT,$0-8 75 MOVW fd+0(FP), R4 76 MOVW $SYS_close, R2 77 SYSCALL 78 BEQ R7, 2(PC) 79 MOVW $-1, R2 80 MOVW R2, ret+4(FP) 81 RET 82 83TEXT runtime·write(SB),NOSPLIT,$0-16 84 MOVW fd+0(FP), R4 85 MOVW p+4(FP), R5 86 MOVW n+8(FP), R6 87 MOVW $SYS_write, R2 88 SYSCALL 89 BEQ R7, 2(PC) 90 MOVW $-1, R2 91 MOVW R2, ret+12(FP) 92 RET 93 94TEXT runtime·read(SB),NOSPLIT,$0-16 95 MOVW fd+0(FP), R4 96 MOVW p+4(FP), R5 97 MOVW n+8(FP), R6 98 MOVW $SYS_read, R2 99 SYSCALL 100 BEQ R7, 2(PC) 101 MOVW $-1, R2 102 MOVW R2, ret+12(FP) 103 RET 104 105TEXT runtime·getrlimit(SB),NOSPLIT,$0-12 106 MOVW kind+0(FP), R4 107 MOVW limit+4(FP), R5 108 MOVW $SYS_getrlimit, R2 109 SYSCALL 110 MOVW R2, ret+8(FP) 111 RET 112 113TEXT runtime·usleep(SB),NOSPLIT,$28-4 114 MOVW usec+0(FP), R3 115 MOVW R3, R5 116 MOVW $1000000, R4 117 DIVU R4, R3 118 MOVW LO, R3 119 MOVW R3, 24(R29) 120 MULU R3, R4 121 MOVW LO, R4 122 SUBU R4, R5 123 MOVW R5, 28(R29) 124 125 // select(0, 0, 0, 0, &tv) 126 MOVW $0, R4 127 MOVW $0, R5 128 MOVW $0, R6 129 MOVW $0, R7 130 ADDU $24, R29, R8 131 MOVW R8, 16(R29) 132 MOVW $SYS_newselect, R2 133 SYSCALL 134 RET 135 136TEXT runtime·gettid(SB),NOSPLIT,$0-4 137 MOVW $SYS_gettid, R2 138 SYSCALL 139 MOVW R2, ret+0(FP) 140 RET 141 142TEXT runtime·raise(SB),NOSPLIT,$0-4 143 MOVW $SYS_gettid, R2 144 SYSCALL 145 MOVW R2, R4 // arg 1 tid 146 MOVW sig+0(FP), R5 // arg 2 147 MOVW $SYS_tkill, R2 148 SYSCALL 149 RET 150 151TEXT runtime·raiseproc(SB),NOSPLIT,$0 152 MOVW $SYS_getpid, R2 153 SYSCALL 154 MOVW R2, R4 // arg 1 pid 155 MOVW sig+0(FP), R5 // arg 2 156 MOVW $SYS_kill, R2 157 SYSCALL 158 RET 159 160TEXT runtime·setitimer(SB),NOSPLIT,$0-12 161 MOVW mode+0(FP), R4 162 MOVW new+4(FP), R5 163 MOVW old+8(FP), R6 164 MOVW $SYS_setitimer, R2 165 SYSCALL 166 RET 167 168TEXT runtime·mincore(SB),NOSPLIT,$0-16 169 MOVW addr+0(FP), R4 170 MOVW n+4(FP), R5 171 MOVW dst+8(FP), R6 172 MOVW $SYS_mincore, R2 173 SYSCALL 174 SUBU R2, R0, R2 // caller expects negative errno 175 MOVW R2, ret+12(FP) 176 RET 177 178// func now() (sec int64, nsec int32) 179TEXT time·now(SB),NOSPLIT,$8-12 180 MOVW $0, R4 // CLOCK_REALTIME 181 MOVW $4(R29), R5 182 MOVW $SYS_clock_gettime, R2 183 SYSCALL 184 MOVW 4(R29), R3 // sec 185 MOVW 8(R29), R5 // nsec 186#ifdef GOARCH_mips 187 MOVW R3, sec_lo+4(FP) 188 MOVW R0, sec_hi+0(FP) 189#else 190 MOVW R3, sec_lo+0(FP) 191 MOVW R0, sec_hi+4(FP) 192#endif 193 MOVW R5, nsec+8(FP) 194 RET 195 196TEXT runtime·nanotime(SB),NOSPLIT,$8-8 197 MOVW $1, R4 // CLOCK_MONOTONIC 198 MOVW $4(R29), R5 199 MOVW $SYS_clock_gettime, R2 200 SYSCALL 201 MOVW 4(R29), R3 // sec 202 MOVW 8(R29), R5 // nsec 203 // sec is in R3, nsec in R5 204 // return nsec in R3 205 MOVW $1000000000, R4 206 MULU R4, R3 207 MOVW LO, R3 208 ADDU R5, R3 209 SGTU R5, R3, R4 210#ifdef GOARCH_mips 211 MOVW R3, ret_lo+4(FP) 212#else 213 MOVW R3, ret_lo+0(FP) 214#endif 215 MOVW HI, R3 216 ADDU R4, R3 217#ifdef GOARCH_mips 218 MOVW R3, ret_hi+0(FP) 219#else 220 MOVW R3, ret_hi+4(FP) 221#endif 222 RET 223 224TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-16 225 MOVW how+0(FP), R4 226 MOVW new+4(FP), R5 227 MOVW old+8(FP), R6 228 MOVW size+12(FP), R7 229 MOVW $SYS_rt_sigprocmask, R2 230 SYSCALL 231 BEQ R7, 2(PC) 232 UNDEF // crash 233 RET 234 235TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-20 236 MOVW sig+0(FP), R4 237 MOVW new+4(FP), R5 238 MOVW old+8(FP), R6 239 MOVW size+12(FP), R7 240 MOVW $SYS_rt_sigaction, R2 241 SYSCALL 242 MOVW R2, ret+16(FP) 243 RET 244 245TEXT runtime·sigfwd(SB),NOSPLIT,$0-16 246 MOVW sig+4(FP), R4 247 MOVW info+8(FP), R5 248 MOVW ctx+12(FP), R6 249 MOVW fn+0(FP), R25 250 MOVW R29, R22 251 SUBU $16, R29 252 AND $~7, R29 // shadow space for 4 args aligned to 8 bytes as per O32 ABI 253 JAL (R25) 254 MOVW R22, R29 255 RET 256 257TEXT runtime·sigtramp(SB),NOSPLIT,$12 258 // this might be called in external code context, 259 // where g is not set. 260 MOVB runtime·iscgo(SB), R1 261 BEQ R1, 2(PC) 262 JAL runtime·load_g(SB) 263 264 MOVW R4, 4(R29) 265 MOVW R5, 8(R29) 266 MOVW R6, 12(R29) 267 MOVW $runtime·sigtrampgo(SB), R1 268 JAL (R1) 269 RET 270 271TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 272 JMP runtime·sigtramp(SB) 273 274TEXT runtime·mmap(SB),NOSPLIT,$20-28 275 MOVW addr+0(FP), R4 276 MOVW n+4(FP), R5 277 MOVW prot+8(FP), R6 278 MOVW flags+12(FP), R7 279 MOVW fd+16(FP), R8 280 MOVW off+20(FP), R9 281 MOVW R8, 16(R29) 282 MOVW R9, 20(R29) 283 284 MOVW $SYS_mmap, R2 285 SYSCALL 286 MOVW R2, ret+24(FP) 287 RET 288 289TEXT runtime·munmap(SB),NOSPLIT,$0-8 290 MOVW addr+0(FP), R4 291 MOVW n+4(FP), R5 292 MOVW $SYS_munmap, R2 293 SYSCALL 294 BEQ R7, 2(PC) 295 UNDEF // crash 296 RET 297 298TEXT runtime·madvise(SB),NOSPLIT,$0-12 299 MOVW addr+0(FP), R4 300 MOVW n+4(FP), R5 301 MOVW flags+8(FP), R6 302 MOVW $SYS_madvise, R2 303 SYSCALL 304 // ignore failure - maybe pages are locked 305 RET 306 307// int32 futex(int32 *uaddr, int32 op, int32 val, struct timespec *timeout, int32 *uaddr2, int32 val2); 308TEXT runtime·futex(SB),NOSPLIT,$20-28 309 MOVW addr+0(FP), R4 310 MOVW op+4(FP), R5 311 MOVW val+8(FP), R6 312 MOVW ts+12(FP), R7 313 314 MOVW addr2+16(FP), R8 315 MOVW val3+20(FP), R9 316 317 MOVW R8, 16(R29) 318 MOVW R9, 20(R29) 319 320 MOVW $SYS_futex, R2 321 SYSCALL 322 MOVW R2, ret+24(FP) 323 RET 324 325 326// int32 clone(int32 flags, void *stk, M *mm, G *gg, void (*fn)(void)); 327TEXT runtime·clone(SB),NOSPLIT,$-4-24 328 MOVW flags+0(FP), R4 329 MOVW stk+4(FP), R5 330 MOVW R0, R6 // ptid 331 MOVW R0, R7 // tls 332 333 // O32 syscall handler unconditionally copies arguments 5-8 from stack, 334 // even for syscalls with less than 8 arguments. Reserve 32 bytes of new 335 // stack so that any syscall invoked immediately in the new thread won't fail. 336 ADD $-32, R5 337 338 // Copy mm, gg, fn off parent stack for use by child. 339 MOVW mm+8(FP), R16 340 MOVW gg+12(FP), R17 341 MOVW fn+16(FP), R18 342 343 MOVW $1234, R1 344 345 MOVW R16, 0(R5) 346 MOVW R17, 4(R5) 347 MOVW R18, 8(R5) 348 349 MOVW R1, 12(R5) 350 351 MOVW $SYS_clone, R2 352 SYSCALL 353 354 // In parent, return. 355 BEQ R2, 5(PC) 356 SUBU R2, R0, R3 357 CMOVN R7, R3, R2 358 MOVW R2, ret+20(FP) 359 RET 360 361 // In child, on new stack. 362 // Check that SP is as we expect 363 MOVW 12(R29), R16 364 MOVW $1234, R1 365 BEQ R16, R1, 2(PC) 366 MOVW (R0), R0 367 368 // Initialize m->procid to Linux tid 369 MOVW $SYS_gettid, R2 370 SYSCALL 371 372 MOVW 0(R29), R16 // m 373 MOVW 4(R29), R17 // g 374 MOVW 8(R29), R18 // fn 375 376 BEQ R16, nog 377 BEQ R17, nog 378 379 MOVW R2, m_procid(R16) 380 381 // In child, set up new stack 382 MOVW R16, g_m(R17) 383 MOVW R17, g 384 385// TODO(mips32): doesn't have runtime·stackcheck(SB) 386 387nog: 388 // Call fn 389 ADDU $32, R29 390 JAL (R18) 391 392 // It shouldn't return. If it does, exit that thread. 393 ADDU $-32, R29 394 MOVW $0xf4, R4 395 MOVW $SYS_exit, R2 396 SYSCALL 397 UNDEF 398 399TEXT runtime·sigaltstack(SB),NOSPLIT,$0 400 MOVW new+0(FP), R4 401 MOVW old+4(FP), R5 402 MOVW $SYS_sigaltstack, R2 403 SYSCALL 404 BEQ R7, 2(PC) 405 UNDEF // crash 406 RET 407 408TEXT runtime·osyield(SB),NOSPLIT,$0 409 MOVW $SYS_sched_yield, R2 410 SYSCALL 411 RET 412 413TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0-16 414 MOVW pid+0(FP), R4 415 MOVW len+4(FP), R5 416 MOVW buf+8(FP), R6 417 MOVW $SYS_sched_getaffinity, R2 418 SYSCALL 419 MOVW R2, ret+12(FP) 420 RET 421 422// int32 runtime·epollcreate(int32 size); 423TEXT runtime·epollcreate(SB),NOSPLIT,$0-8 424 MOVW size+0(FP), R4 425 MOVW $SYS_epoll_create, R2 426 SYSCALL 427 MOVW R2, ret+4(FP) 428 RET 429 430// int32 runtime·epollcreate1(int32 flags); 431TEXT runtime·epollcreate1(SB),NOSPLIT,$0-8 432 MOVW flags+0(FP), R4 433 MOVW $SYS_epoll_create1, R2 434 SYSCALL 435 MOVW R2, ret+4(FP) 436 RET 437 438// func epollctl(epfd, op, fd int32, ev *epollEvent) int 439TEXT runtime·epollctl(SB),NOSPLIT,$0-20 440 MOVW epfd+0(FP), R4 441 MOVW op+4(FP), R5 442 MOVW fd+8(FP), R6 443 MOVW ev+12(FP), R7 444 MOVW $SYS_epoll_ctl, R2 445 SYSCALL 446 MOVW R2, ret+16(FP) 447 RET 448 449// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 450TEXT runtime·epollwait(SB),NOSPLIT,$0-20 451 MOVW epfd+0(FP), R4 452 MOVW ev+4(FP), R5 453 MOVW nev+8(FP), R6 454 MOVW timeout+12(FP), R7 455 MOVW $SYS_epoll_wait, R2 456 SYSCALL 457 MOVW R2, ret+16(FP) 458 RET 459 460// void runtime·closeonexec(int32 fd); 461TEXT runtime·closeonexec(SB),NOSPLIT,$0-4 462 MOVW fd+0(FP), R4 // fd 463 MOVW $2, R5 // F_SETFD 464 MOVW $1, R6 // FD_CLOEXEC 465 MOVW $SYS_fcntl, R2 466 SYSCALL 467 RET 468