github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/runtime/sys_linux_mipsx.s (about) 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 //go:build linux && (mips || mipsle) 6 7 // 8 // System calls and other sys.stuff for mips, Linux 9 // 10 11 #include "go_asm.h" 12 #include "go_tls.h" 13 #include "textflag.h" 14 15 #define SYS_exit 4001 16 #define SYS_read 4003 17 #define SYS_write 4004 18 #define SYS_open 4005 19 #define SYS_close 4006 20 #define SYS_getpid 4020 21 #define SYS_kill 4037 22 #define SYS_pipe 4042 23 #define SYS_brk 4045 24 #define SYS_fcntl 4055 25 #define SYS_mmap 4090 26 #define SYS_munmap 4091 27 #define SYS_setitimer 4104 28 #define SYS_clone 4120 29 #define SYS_sched_yield 4162 30 #define SYS_nanosleep 4166 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_madvise 4218 36 #define SYS_mincore 4217 37 #define SYS_gettid 4222 38 #define SYS_futex 4238 39 #define SYS_sched_getaffinity 4240 40 #define SYS_exit_group 4246 41 #define SYS_epoll_create 4248 42 #define SYS_epoll_ctl 4249 43 #define SYS_epoll_wait 4250 44 #define SYS_timer_create 4257 45 #define SYS_timer_settime 4258 46 #define SYS_timer_delete 4261 47 #define SYS_clock_gettime 4263 48 #define SYS_tgkill 4266 49 #define SYS_epoll_create1 4326 50 #define SYS_pipe2 4328 51 52 TEXT runtime·exit(SB),NOSPLIT,$0-4 53 MOVW code+0(FP), R4 54 MOVW $SYS_exit_group, R2 55 SYSCALL 56 UNDEF 57 RET 58 59 // func exitThread(wait *uint32) 60 TEXT runtime·exitThread(SB),NOSPLIT,$0-4 61 MOVW wait+0(FP), R1 62 // We're done using the stack. 63 MOVW $0, R2 64 SYNC 65 MOVW R2, (R1) 66 SYNC 67 MOVW $0, R4 // exit code 68 MOVW $SYS_exit, R2 69 SYSCALL 70 UNDEF 71 JMP 0(PC) 72 73 TEXT runtime·open(SB),NOSPLIT,$0-16 74 MOVW name+0(FP), R4 75 MOVW mode+4(FP), R5 76 MOVW perm+8(FP), R6 77 MOVW $SYS_open, R2 78 SYSCALL 79 BEQ R7, 2(PC) 80 MOVW $-1, R2 81 MOVW R2, ret+12(FP) 82 RET 83 84 TEXT runtime·closefd(SB),NOSPLIT,$0-8 85 MOVW fd+0(FP), R4 86 MOVW $SYS_close, R2 87 SYSCALL 88 BEQ R7, 2(PC) 89 MOVW $-1, R2 90 MOVW R2, ret+4(FP) 91 RET 92 93 TEXT runtime·write1(SB),NOSPLIT,$0-16 94 MOVW fd+0(FP), R4 95 MOVW p+4(FP), R5 96 MOVW n+8(FP), R6 97 MOVW $SYS_write, R2 98 SYSCALL 99 BEQ R7, 2(PC) 100 SUBU R2, R0, R2 // caller expects negative errno 101 MOVW R2, ret+12(FP) 102 RET 103 104 TEXT runtime·read(SB),NOSPLIT,$0-16 105 MOVW fd+0(FP), R4 106 MOVW p+4(FP), R5 107 MOVW n+8(FP), R6 108 MOVW $SYS_read, R2 109 SYSCALL 110 BEQ R7, 2(PC) 111 SUBU R2, R0, R2 // caller expects negative errno 112 MOVW R2, ret+12(FP) 113 RET 114 115 // func pipe() (r, w int32, errno int32) 116 TEXT runtime·pipe(SB),NOSPLIT,$0-12 117 MOVW $SYS_pipe, R2 118 SYSCALL 119 BEQ R7, pipeok 120 MOVW $-1, R1 121 MOVW R1, r+0(FP) 122 MOVW R1, w+4(FP) 123 SUBU R2, R0, R2 // caller expects negative errno 124 MOVW R2, errno+8(FP) 125 RET 126 pipeok: 127 MOVW R2, r+0(FP) 128 MOVW R3, w+4(FP) 129 MOVW R0, errno+8(FP) 130 RET 131 132 // func pipe2(flags int32) (r, w int32, errno int32) 133 TEXT runtime·pipe2(SB),NOSPLIT,$0-16 134 MOVW $r+4(FP), R4 135 MOVW flags+0(FP), R5 136 MOVW $SYS_pipe2, R2 137 SYSCALL 138 BEQ R7, 2(PC) 139 SUBU R2, R0, R2 // caller expects negative errno 140 MOVW R2, errno+12(FP) 141 RET 142 143 TEXT runtime·usleep(SB),NOSPLIT,$28-4 144 MOVW usec+0(FP), R3 145 MOVW R3, R5 146 MOVW $1000000, R4 147 DIVU R4, R3 148 MOVW LO, R3 149 MOVW R3, 24(R29) 150 MOVW $1000, R4 151 MULU R3, R4 152 MOVW LO, R4 153 SUBU R4, R5 154 MOVW R5, 28(R29) 155 156 // nanosleep(&ts, 0) 157 ADDU $24, R29, R4 158 MOVW $0, R5 159 MOVW $SYS_nanosleep, R2 160 SYSCALL 161 RET 162 163 TEXT runtime·gettid(SB),NOSPLIT,$0-4 164 MOVW $SYS_gettid, R2 165 SYSCALL 166 MOVW R2, ret+0(FP) 167 RET 168 169 TEXT runtime·raise(SB),NOSPLIT,$0-4 170 MOVW $SYS_getpid, R2 171 SYSCALL 172 MOVW R2, R16 173 MOVW $SYS_gettid, R2 174 SYSCALL 175 MOVW R2, R5 // arg 2 tid 176 MOVW R16, R4 // arg 1 pid 177 MOVW sig+0(FP), R6 // arg 3 178 MOVW $SYS_tgkill, R2 179 SYSCALL 180 RET 181 182 TEXT runtime·raiseproc(SB),NOSPLIT,$0 183 MOVW $SYS_getpid, R2 184 SYSCALL 185 MOVW R2, R4 // arg 1 pid 186 MOVW sig+0(FP), R5 // arg 2 187 MOVW $SYS_kill, R2 188 SYSCALL 189 RET 190 191 TEXT ·getpid(SB),NOSPLIT,$0-4 192 MOVW $SYS_getpid, R2 193 SYSCALL 194 MOVW R2, ret+0(FP) 195 RET 196 197 TEXT ·tgkill(SB),NOSPLIT,$0-12 198 MOVW tgid+0(FP), R4 199 MOVW tid+4(FP), R5 200 MOVW sig+8(FP), R6 201 MOVW $SYS_tgkill, R2 202 SYSCALL 203 RET 204 205 TEXT runtime·setitimer(SB),NOSPLIT,$0-12 206 MOVW mode+0(FP), R4 207 MOVW new+4(FP), R5 208 MOVW old+8(FP), R6 209 MOVW $SYS_setitimer, R2 210 SYSCALL 211 RET 212 213 TEXT runtime·timer_create(SB),NOSPLIT,$0-16 214 MOVW clockid+0(FP), R4 215 MOVW sevp+4(FP), R5 216 MOVW timerid+8(FP), R6 217 MOVW $SYS_timer_create, R2 218 SYSCALL 219 MOVW R2, ret+12(FP) 220 RET 221 222 TEXT runtime·timer_settime(SB),NOSPLIT,$0-20 223 MOVW timerid+0(FP), R4 224 MOVW flags+4(FP), R5 225 MOVW new+8(FP), R6 226 MOVW old+12(FP), R7 227 MOVW $SYS_timer_settime, R2 228 SYSCALL 229 MOVW R2, ret+16(FP) 230 RET 231 232 TEXT runtime·timer_delete(SB),NOSPLIT,$0-8 233 MOVW timerid+0(FP), R4 234 MOVW $SYS_timer_delete, R2 235 SYSCALL 236 MOVW R2, ret+4(FP) 237 RET 238 239 TEXT runtime·mincore(SB),NOSPLIT,$0-16 240 MOVW addr+0(FP), R4 241 MOVW n+4(FP), R5 242 MOVW dst+8(FP), R6 243 MOVW $SYS_mincore, R2 244 SYSCALL 245 SUBU R2, R0, R2 // caller expects negative errno 246 MOVW R2, ret+12(FP) 247 RET 248 249 // func walltime() (sec int64, nsec int32) 250 TEXT runtime·walltime(SB),NOSPLIT,$8-12 251 MOVW $0, R4 // CLOCK_REALTIME 252 MOVW $4(R29), R5 253 MOVW $SYS_clock_gettime, R2 254 SYSCALL 255 MOVW 4(R29), R3 // sec 256 MOVW 8(R29), R5 // nsec 257 MOVW $sec+0(FP), R6 258 #ifdef GOARCH_mips 259 MOVW R3, 4(R6) 260 MOVW R0, 0(R6) 261 #else 262 MOVW R3, 0(R6) 263 MOVW R0, 4(R6) 264 #endif 265 MOVW R5, nsec+8(FP) 266 RET 267 268 TEXT runtime·nanotime1(SB),NOSPLIT,$8-8 269 MOVW $1, R4 // CLOCK_MONOTONIC 270 MOVW $4(R29), R5 271 MOVW $SYS_clock_gettime, R2 272 SYSCALL 273 MOVW 4(R29), R3 // sec 274 MOVW 8(R29), R5 // nsec 275 // sec is in R3, nsec in R5 276 // return nsec in R3 277 MOVW $1000000000, R4 278 MULU R4, R3 279 MOVW LO, R3 280 ADDU R5, R3 281 SGTU R5, R3, R4 282 MOVW $ret+0(FP), R6 283 #ifdef GOARCH_mips 284 MOVW R3, 4(R6) 285 #else 286 MOVW R3, 0(R6) 287 #endif 288 MOVW HI, R3 289 ADDU R4, R3 290 #ifdef GOARCH_mips 291 MOVW R3, 0(R6) 292 #else 293 MOVW R3, 4(R6) 294 #endif 295 RET 296 297 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-16 298 MOVW how+0(FP), R4 299 MOVW new+4(FP), R5 300 MOVW old+8(FP), R6 301 MOVW size+12(FP), R7 302 MOVW $SYS_rt_sigprocmask, R2 303 SYSCALL 304 BEQ R7, 2(PC) 305 UNDEF // crash 306 RET 307 308 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-20 309 MOVW sig+0(FP), R4 310 MOVW new+4(FP), R5 311 MOVW old+8(FP), R6 312 MOVW size+12(FP), R7 313 MOVW $SYS_rt_sigaction, R2 314 SYSCALL 315 BEQ R7, 2(PC) 316 SUBU R2, R0, R2 // caller expects negative errno 317 MOVW R2, ret+16(FP) 318 RET 319 320 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16 321 MOVW sig+4(FP), R4 322 MOVW info+8(FP), R5 323 MOVW ctx+12(FP), R6 324 MOVW fn+0(FP), R25 325 MOVW R29, R22 326 SUBU $16, R29 327 AND $~7, R29 // shadow space for 4 args aligned to 8 bytes as per O32 ABI 328 JAL (R25) 329 MOVW R22, R29 330 RET 331 332 TEXT runtime·sigtramp(SB),NOSPLIT,$12 333 // this might be called in external code context, 334 // where g is not set. 335 MOVB runtime·iscgo(SB), R1 336 BEQ R1, 2(PC) 337 JAL runtime·load_g(SB) 338 339 MOVW R4, 4(R29) 340 MOVW R5, 8(R29) 341 MOVW R6, 12(R29) 342 MOVW $runtime·sigtrampgo(SB), R1 343 JAL (R1) 344 RET 345 346 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 347 JMP runtime·sigtramp(SB) 348 349 TEXT runtime·mmap(SB),NOSPLIT,$20-32 350 MOVW addr+0(FP), R4 351 MOVW n+4(FP), R5 352 MOVW prot+8(FP), R6 353 MOVW flags+12(FP), R7 354 MOVW fd+16(FP), R8 355 MOVW off+20(FP), R9 356 MOVW R8, 16(R29) 357 MOVW R9, 20(R29) 358 359 MOVW $SYS_mmap, R2 360 SYSCALL 361 BEQ R7, ok 362 MOVW $0, p+24(FP) 363 MOVW R2, err+28(FP) 364 RET 365 ok: 366 MOVW R2, p+24(FP) 367 MOVW $0, err+28(FP) 368 RET 369 370 TEXT runtime·munmap(SB),NOSPLIT,$0-8 371 MOVW addr+0(FP), R4 372 MOVW n+4(FP), R5 373 MOVW $SYS_munmap, R2 374 SYSCALL 375 BEQ R7, 2(PC) 376 UNDEF // crash 377 RET 378 379 TEXT runtime·madvise(SB),NOSPLIT,$0-16 380 MOVW addr+0(FP), R4 381 MOVW n+4(FP), R5 382 MOVW flags+8(FP), R6 383 MOVW $SYS_madvise, R2 384 SYSCALL 385 MOVW R2, ret+12(FP) 386 RET 387 388 // int32 futex(int32 *uaddr, int32 op, int32 val, struct timespec *timeout, int32 *uaddr2, int32 val2); 389 TEXT runtime·futex(SB),NOSPLIT,$20-28 390 MOVW addr+0(FP), R4 391 MOVW op+4(FP), R5 392 MOVW val+8(FP), R6 393 MOVW ts+12(FP), R7 394 395 MOVW addr2+16(FP), R8 396 MOVW val3+20(FP), R9 397 398 MOVW R8, 16(R29) 399 MOVW R9, 20(R29) 400 401 MOVW $SYS_futex, R2 402 SYSCALL 403 BEQ R7, 2(PC) 404 SUBU R2, R0, R2 // caller expects negative errno 405 MOVW R2, ret+24(FP) 406 RET 407 408 409 // int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 410 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0-24 411 MOVW flags+0(FP), R4 412 MOVW stk+4(FP), R5 413 MOVW R0, R6 // ptid 414 MOVW R0, R7 // tls 415 416 // O32 syscall handler unconditionally copies arguments 5-8 from stack, 417 // even for syscalls with less than 8 arguments. Reserve 32 bytes of new 418 // stack so that any syscall invoked immediately in the new thread won't fail. 419 ADD $-32, R5 420 421 // Copy mp, gp, fn off parent stack for use by child. 422 MOVW mp+8(FP), R16 423 MOVW gp+12(FP), R17 424 MOVW fn+16(FP), R18 425 426 MOVW $1234, R1 427 428 MOVW R16, 0(R5) 429 MOVW R17, 4(R5) 430 MOVW R18, 8(R5) 431 432 MOVW R1, 12(R5) 433 434 MOVW $SYS_clone, R2 435 SYSCALL 436 BEQ R7, 2(PC) 437 SUBU R2, R0, R2 // caller expects negative errno 438 439 // In parent, return. 440 BEQ R2, 3(PC) 441 MOVW R2, ret+20(FP) 442 RET 443 444 // In child, on new stack. 445 // Check that SP is as we expect 446 NOP R29 // tell vet R29/SP changed - stop checking offsets 447 MOVW 12(R29), R16 448 MOVW $1234, R1 449 BEQ R16, R1, 2(PC) 450 MOVW (R0), R0 451 452 // Initialize m->procid to Linux tid 453 MOVW $SYS_gettid, R2 454 SYSCALL 455 456 MOVW 0(R29), R16 // m 457 MOVW 4(R29), R17 // g 458 MOVW 8(R29), R18 // fn 459 460 BEQ R16, nog 461 BEQ R17, nog 462 463 MOVW R2, m_procid(R16) 464 465 // In child, set up new stack 466 MOVW R16, g_m(R17) 467 MOVW R17, g 468 469 // TODO(mips32): doesn't have runtime·stackcheck(SB) 470 471 nog: 472 // Call fn 473 ADDU $32, R29 474 JAL (R18) 475 476 // It shouldn't return. If it does, exit that thread. 477 ADDU $-32, R29 478 MOVW $0xf4, R4 479 MOVW $SYS_exit, R2 480 SYSCALL 481 UNDEF 482 483 TEXT runtime·sigaltstack(SB),NOSPLIT,$0 484 MOVW new+0(FP), R4 485 MOVW old+4(FP), R5 486 MOVW $SYS_sigaltstack, R2 487 SYSCALL 488 BEQ R7, 2(PC) 489 UNDEF // crash 490 RET 491 492 TEXT runtime·osyield(SB),NOSPLIT,$0 493 MOVW $SYS_sched_yield, R2 494 SYSCALL 495 RET 496 497 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0-16 498 MOVW pid+0(FP), R4 499 MOVW len+4(FP), R5 500 MOVW buf+8(FP), R6 501 MOVW $SYS_sched_getaffinity, R2 502 SYSCALL 503 BEQ R7, 2(PC) 504 SUBU R2, R0, R2 // caller expects negative errno 505 MOVW R2, ret+12(FP) 506 RET 507 508 // int32 runtime·epollcreate(int32 size); 509 TEXT runtime·epollcreate(SB),NOSPLIT,$0-8 510 MOVW size+0(FP), R4 511 MOVW $SYS_epoll_create, R2 512 SYSCALL 513 BEQ R7, 2(PC) 514 SUBU R2, R0, R2 // caller expects negative errno 515 MOVW R2, ret+4(FP) 516 RET 517 518 // int32 runtime·epollcreate1(int32 flags); 519 TEXT runtime·epollcreate1(SB),NOSPLIT,$0-8 520 MOVW flags+0(FP), R4 521 MOVW $SYS_epoll_create1, R2 522 SYSCALL 523 BEQ R7, 2(PC) 524 SUBU R2, R0, R2 // caller expects negative errno 525 MOVW R2, ret+4(FP) 526 RET 527 528 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 529 TEXT runtime·epollctl(SB),NOSPLIT,$0-20 530 MOVW epfd+0(FP), R4 531 MOVW op+4(FP), R5 532 MOVW fd+8(FP), R6 533 MOVW ev+12(FP), R7 534 MOVW $SYS_epoll_ctl, R2 535 SYSCALL 536 SUBU R2, R0, R2 // caller expects negative errno 537 MOVW R2, ret+16(FP) 538 RET 539 540 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 541 TEXT runtime·epollwait(SB),NOSPLIT,$0-20 542 MOVW epfd+0(FP), R4 543 MOVW ev+4(FP), R5 544 MOVW nev+8(FP), R6 545 MOVW timeout+12(FP), R7 546 MOVW $SYS_epoll_wait, R2 547 SYSCALL 548 BEQ R7, 2(PC) 549 SUBU R2, R0, R2 // caller expects negative errno 550 MOVW R2, ret+16(FP) 551 RET 552 553 // void runtime·closeonexec(int32 fd); 554 TEXT runtime·closeonexec(SB),NOSPLIT,$0-4 555 MOVW fd+0(FP), R4 // fd 556 MOVW $2, R5 // F_SETFD 557 MOVW $1, R6 // FD_CLOEXEC 558 MOVW $SYS_fcntl, R2 559 SYSCALL 560 RET 561 562 // func runtime·setNonblock(int32 fd) 563 TEXT runtime·setNonblock(SB),NOSPLIT,$0-4 564 MOVW fd+0(FP), R4 // fd 565 MOVW $3, R5 // F_GETFL 566 MOVW $0, R6 567 MOVW $SYS_fcntl, R2 568 SYSCALL 569 MOVW $0x80, R6 // O_NONBLOCK 570 OR R2, R6 571 MOVW fd+0(FP), R4 // fd 572 MOVW $4, R5 // F_SETFL 573 MOVW $SYS_fcntl, R2 574 SYSCALL 575 RET 576 577 // func sbrk0() uintptr 578 TEXT runtime·sbrk0(SB),NOSPLIT,$0-4 579 // Implemented as brk(NULL). 580 MOVW $0, R4 581 MOVW $SYS_brk, R2 582 SYSCALL 583 MOVW R2, ret+0(FP) 584 RET 585 586 TEXT runtime·access(SB),$0-12 587 BREAK // unimplemented, only needed for android; declared in stubs_linux.go 588 MOVW R0, ret+8(FP) // for vet 589 RET 590 591 TEXT runtime·connect(SB),$0-16 592 BREAK // unimplemented, only needed for android; declared in stubs_linux.go 593 MOVW R0, ret+12(FP) // for vet 594 RET 595 596 TEXT runtime·socket(SB),$0-16 597 BREAK // unimplemented, only needed for android; declared in stubs_linux.go 598 MOVW R0, ret+12(FP) // for vet 599 RET