github.com/comwrg/go/src@v0.0.0-20220319063731-c238d0440370/runtime/sys_linux_mips64x.s (about) 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 //go:build linux && (mips64 || mips64le) 6 // +build linux 7 // +build mips64 mips64le 8 9 // 10 // System calls and other sys.stuff for mips64, Linux 11 // 12 13 #include "go_asm.h" 14 #include "go_tls.h" 15 #include "textflag.h" 16 17 #define AT_FDCWD -100 18 19 #define SYS_exit 5058 20 #define SYS_read 5000 21 #define SYS_write 5001 22 #define SYS_close 5003 23 #define SYS_getpid 5038 24 #define SYS_kill 5060 25 #define SYS_fcntl 5070 26 #define SYS_mmap 5009 27 #define SYS_munmap 5011 28 #define SYS_setitimer 5036 29 #define SYS_clone 5055 30 #define SYS_nanosleep 5034 31 #define SYS_sched_yield 5023 32 #define SYS_rt_sigreturn 5211 33 #define SYS_rt_sigaction 5013 34 #define SYS_rt_sigprocmask 5014 35 #define SYS_sigaltstack 5129 36 #define SYS_madvise 5027 37 #define SYS_mincore 5026 38 #define SYS_gettid 5178 39 #define SYS_futex 5194 40 #define SYS_sched_getaffinity 5196 41 #define SYS_exit_group 5205 42 #define SYS_epoll_create 5207 43 #define SYS_epoll_ctl 5208 44 #define SYS_tgkill 5225 45 #define SYS_openat 5247 46 #define SYS_epoll_pwait 5272 47 #define SYS_clock_gettime 5222 48 #define SYS_epoll_create1 5285 49 #define SYS_brk 5012 50 #define SYS_pipe2 5287 51 52 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4 53 MOVW code+0(FP), R4 54 MOVV $SYS_exit_group, R2 55 SYSCALL 56 RET 57 58 // func exitThread(wait *uint32) 59 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8 60 MOVV wait+0(FP), R1 61 // We're done using the stack. 62 MOVW $0, R2 63 SYNC 64 MOVW R2, (R1) 65 SYNC 66 MOVW $0, R4 // exit code 67 MOVV $SYS_exit, R2 68 SYSCALL 69 JMP 0(PC) 70 71 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20 72 // This uses openat instead of open, because Android O blocks open. 73 MOVW $AT_FDCWD, R4 // AT_FDCWD, so this acts like open 74 MOVV name+0(FP), R5 75 MOVW mode+8(FP), R6 76 MOVW perm+12(FP), R7 77 MOVV $SYS_openat, R2 78 SYSCALL 79 BEQ R7, 2(PC) 80 MOVW $-1, R2 81 MOVW R2, ret+16(FP) 82 RET 83 84 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12 85 MOVW fd+0(FP), R4 86 MOVV $SYS_close, R2 87 SYSCALL 88 BEQ R7, 2(PC) 89 MOVW $-1, R2 90 MOVW R2, ret+8(FP) 91 RET 92 93 TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28 94 MOVV fd+0(FP), R4 95 MOVV p+8(FP), R5 96 MOVW n+16(FP), R6 97 MOVV $SYS_write, R2 98 SYSCALL 99 BEQ R7, 2(PC) 100 SUBVU R2, R0, R2 // caller expects negative errno 101 MOVW R2, ret+24(FP) 102 RET 103 104 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28 105 MOVW fd+0(FP), R4 106 MOVV p+8(FP), R5 107 MOVW n+16(FP), R6 108 MOVV $SYS_read, R2 109 SYSCALL 110 BEQ R7, 2(PC) 111 SUBVU R2, R0, R2 // caller expects negative errno 112 MOVW R2, ret+24(FP) 113 RET 114 115 // func pipe() (r, w int32, errno int32) 116 TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12 117 MOVV $r+0(FP), R4 118 MOVV R0, R5 119 MOVV $SYS_pipe2, R2 120 SYSCALL 121 BEQ R7, 2(PC) 122 SUBVU R2, R0, R2 // caller expects negative errno 123 MOVW R2, errno+8(FP) 124 RET 125 126 // func pipe2(flags int32) (r, w int32, errno int32) 127 TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20 128 MOVV $r+8(FP), R4 129 MOVW flags+0(FP), R5 130 MOVV $SYS_pipe2, R2 131 SYSCALL 132 BEQ R7, 2(PC) 133 SUBVU R2, R0, R2 // caller expects negative errno 134 MOVW R2, errno+16(FP) 135 RET 136 137 TEXT runtime·usleep(SB),NOSPLIT,$16-4 138 MOVWU usec+0(FP), R3 139 MOVV R3, R5 140 MOVW $1000000, R4 141 DIVVU R4, R3 142 MOVV LO, R3 143 MOVV R3, 8(R29) 144 MOVW $1000, R4 145 MULVU R3, R4 146 MOVV LO, R4 147 SUBVU R4, R5 148 MOVV R5, 16(R29) 149 150 // nanosleep(&ts, 0) 151 ADDV $8, R29, R4 152 MOVW $0, R5 153 MOVV $SYS_nanosleep, R2 154 SYSCALL 155 RET 156 157 TEXT runtime·gettid(SB),NOSPLIT,$0-4 158 MOVV $SYS_gettid, R2 159 SYSCALL 160 MOVW R2, ret+0(FP) 161 RET 162 163 TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0 164 MOVV $SYS_getpid, R2 165 SYSCALL 166 MOVW R2, R16 167 MOVV $SYS_gettid, R2 168 SYSCALL 169 MOVW R2, R5 // arg 2 tid 170 MOVW R16, R4 // arg 1 pid 171 MOVW sig+0(FP), R6 // arg 3 172 MOVV $SYS_tgkill, R2 173 SYSCALL 174 RET 175 176 TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0 177 MOVV $SYS_getpid, R2 178 SYSCALL 179 MOVW R2, R4 // arg 1 pid 180 MOVW sig+0(FP), R5 // arg 2 181 MOVV $SYS_kill, R2 182 SYSCALL 183 RET 184 185 TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8 186 MOVV $SYS_getpid, R2 187 SYSCALL 188 MOVV R2, ret+0(FP) 189 RET 190 191 TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24 192 MOVV tgid+0(FP), R4 193 MOVV tid+8(FP), R5 194 MOVV sig+16(FP), R6 195 MOVV $SYS_tgkill, R2 196 SYSCALL 197 RET 198 199 TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24 200 MOVW mode+0(FP), R4 201 MOVV new+8(FP), R5 202 MOVV old+16(FP), R6 203 MOVV $SYS_setitimer, R2 204 SYSCALL 205 RET 206 207 TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28 208 MOVV addr+0(FP), R4 209 MOVV n+8(FP), R5 210 MOVV dst+16(FP), R6 211 MOVV $SYS_mincore, R2 212 SYSCALL 213 SUBVU R2, R0, R2 // caller expects negative errno 214 MOVW R2, ret+24(FP) 215 RET 216 217 // func walltime() (sec int64, nsec int32) 218 TEXT runtime·walltime(SB),NOSPLIT,$16-12 219 MOVV R29, R16 // R16 is unchanged by C code 220 MOVV R29, R1 221 222 MOVV g_m(g), R17 // R17 = m 223 224 // Set vdsoPC and vdsoSP for SIGPROF traceback. 225 // Save the old values on stack and restore them on exit, 226 // so this function is reentrant. 227 MOVV m_vdsoPC(R17), R2 228 MOVV m_vdsoSP(R17), R3 229 MOVV R2, 8(R29) 230 MOVV R3, 16(R29) 231 232 MOVV $ret-8(FP), R2 // caller's SP 233 MOVV R31, m_vdsoPC(R17) 234 MOVV R2, m_vdsoSP(R17) 235 236 MOVV m_curg(R17), R4 237 MOVV g, R5 238 BNE R4, R5, noswitch 239 240 MOVV m_g0(R17), R4 241 MOVV (g_sched+gobuf_sp)(R4), R1 // Set SP to g0 stack 242 243 noswitch: 244 SUBV $16, R1 245 AND $~15, R1 // Align for C code 246 MOVV R1, R29 247 248 MOVW $0, R4 // CLOCK_REALTIME 249 MOVV $0(R29), R5 250 251 MOVV runtime·vdsoClockgettimeSym(SB), R25 252 BEQ R25, fallback 253 254 JAL (R25) 255 // check on vdso call return for kernel compatibility 256 // see https://golang.org/issues/39046 257 // if we get any error make fallback permanent. 258 BEQ R2, R0, finish 259 MOVV R0, runtime·vdsoClockgettimeSym(SB) 260 MOVW $0, R4 // CLOCK_REALTIME 261 MOVV $0(R29), R5 262 JMP fallback 263 264 finish: 265 MOVV 0(R29), R3 // sec 266 MOVV 8(R29), R5 // nsec 267 268 MOVV R16, R29 // restore SP 269 // Restore vdsoPC, vdsoSP 270 // We don't worry about being signaled between the two stores. 271 // If we are not in a signal handler, we'll restore vdsoSP to 0, 272 // and no one will care about vdsoPC. If we are in a signal handler, 273 // we cannot receive another signal. 274 MOVV 16(R29), R1 275 MOVV R1, m_vdsoSP(R17) 276 MOVV 8(R29), R1 277 MOVV R1, m_vdsoPC(R17) 278 279 MOVV R3, sec+0(FP) 280 MOVW R5, nsec+8(FP) 281 RET 282 283 fallback: 284 MOVV $SYS_clock_gettime, R2 285 SYSCALL 286 JMP finish 287 288 TEXT runtime·nanotime1(SB),NOSPLIT,$16-8 289 MOVV R29, R16 // R16 is unchanged by C code 290 MOVV R29, R1 291 292 MOVV g_m(g), R17 // R17 = m 293 294 // Set vdsoPC and vdsoSP for SIGPROF traceback. 295 // Save the old values on stack and restore them on exit, 296 // so this function is reentrant. 297 MOVV m_vdsoPC(R17), R2 298 MOVV m_vdsoSP(R17), R3 299 MOVV R2, 8(R29) 300 MOVV R3, 16(R29) 301 302 MOVV $ret-8(FP), R2 // caller's SP 303 MOVV R31, m_vdsoPC(R17) 304 MOVV R2, m_vdsoSP(R17) 305 306 MOVV m_curg(R17), R4 307 MOVV g, R5 308 BNE R4, R5, noswitch 309 310 MOVV m_g0(R17), R4 311 MOVV (g_sched+gobuf_sp)(R4), R1 // Set SP to g0 stack 312 313 noswitch: 314 SUBV $16, R1 315 AND $~15, R1 // Align for C code 316 MOVV R1, R29 317 318 MOVW $1, R4 // CLOCK_MONOTONIC 319 MOVV $0(R29), R5 320 321 MOVV runtime·vdsoClockgettimeSym(SB), R25 322 BEQ R25, fallback 323 324 JAL (R25) 325 // see walltime for detail 326 BEQ R2, R0, finish 327 MOVV R0, runtime·vdsoClockgettimeSym(SB) 328 MOVW $1, R4 // CLOCK_MONOTONIC 329 MOVV $0(R29), R5 330 JMP fallback 331 332 finish: 333 MOVV 0(R29), R3 // sec 334 MOVV 8(R29), R5 // nsec 335 336 MOVV R16, R29 // restore SP 337 // Restore vdsoPC, vdsoSP 338 // We don't worry about being signaled between the two stores. 339 // If we are not in a signal handler, we'll restore vdsoSP to 0, 340 // and no one will care about vdsoPC. If we are in a signal handler, 341 // we cannot receive another signal. 342 MOVV 16(R29), R1 343 MOVV R1, m_vdsoSP(R17) 344 MOVV 8(R29), R1 345 MOVV R1, m_vdsoPC(R17) 346 347 // sec is in R3, nsec in R5 348 // return nsec in R3 349 MOVV $1000000000, R4 350 MULVU R4, R3 351 MOVV LO, R3 352 ADDVU R5, R3 353 MOVV R3, ret+0(FP) 354 RET 355 356 fallback: 357 MOVV $SYS_clock_gettime, R2 358 SYSCALL 359 JMP finish 360 361 TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28 362 MOVW how+0(FP), R4 363 MOVV new+8(FP), R5 364 MOVV old+16(FP), R6 365 MOVW size+24(FP), R7 366 MOVV $SYS_rt_sigprocmask, R2 367 SYSCALL 368 BEQ R7, 2(PC) 369 MOVV R0, 0xf1(R0) // crash 370 RET 371 372 TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36 373 MOVV sig+0(FP), R4 374 MOVV new+8(FP), R5 375 MOVV old+16(FP), R6 376 MOVV size+24(FP), R7 377 MOVV $SYS_rt_sigaction, R2 378 SYSCALL 379 BEQ R7, 2(PC) 380 SUBVU R2, R0, R2 // caller expects negative errno 381 MOVW R2, ret+32(FP) 382 RET 383 384 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 385 MOVW sig+8(FP), R4 386 MOVV info+16(FP), R5 387 MOVV ctx+24(FP), R6 388 MOVV fn+0(FP), R25 389 JAL (R25) 390 RET 391 392 TEXT runtime·sigtramp(SB),NOSPLIT,$64 393 // initialize REGSB = PC&0xffffffff00000000 394 BGEZAL R0, 1(PC) 395 SRLV $32, R31, RSB 396 SLLV $32, RSB 397 398 // this might be called in external code context, 399 // where g is not set. 400 MOVB runtime·iscgo(SB), R1 401 BEQ R1, 2(PC) 402 JAL runtime·load_g(SB) 403 404 MOVW R4, 8(R29) 405 MOVV R5, 16(R29) 406 MOVV R6, 24(R29) 407 MOVV $runtime·sigtrampgo(SB), R1 408 JAL (R1) 409 RET 410 411 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 412 JMP runtime·sigtramp(SB) 413 414 TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0 415 MOVV addr+0(FP), R4 416 MOVV n+8(FP), R5 417 MOVW prot+16(FP), R6 418 MOVW flags+20(FP), R7 419 MOVW fd+24(FP), R8 420 MOVW off+28(FP), R9 421 422 MOVV $SYS_mmap, R2 423 SYSCALL 424 BEQ R7, ok 425 MOVV $0, p+32(FP) 426 MOVV R2, err+40(FP) 427 RET 428 ok: 429 MOVV R2, p+32(FP) 430 MOVV $0, err+40(FP) 431 RET 432 433 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0 434 MOVV addr+0(FP), R4 435 MOVV n+8(FP), R5 436 MOVV $SYS_munmap, R2 437 SYSCALL 438 BEQ R7, 2(PC) 439 MOVV R0, 0xf3(R0) // crash 440 RET 441 442 TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0 443 MOVV addr+0(FP), R4 444 MOVV n+8(FP), R5 445 MOVW flags+16(FP), R6 446 MOVV $SYS_madvise, R2 447 SYSCALL 448 MOVW R2, ret+24(FP) 449 RET 450 451 // int64 futex(int32 *uaddr, int32 op, int32 val, 452 // struct timespec *timeout, int32 *uaddr2, int32 val2); 453 TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0 454 MOVV addr+0(FP), R4 455 MOVW op+8(FP), R5 456 MOVW val+12(FP), R6 457 MOVV ts+16(FP), R7 458 MOVV addr2+24(FP), R8 459 MOVW val3+32(FP), R9 460 MOVV $SYS_futex, R2 461 SYSCALL 462 BEQ R7, 2(PC) 463 SUBVU R2, R0, R2 // caller expects negative errno 464 MOVW R2, ret+40(FP) 465 RET 466 467 // int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void)); 468 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0 469 MOVW flags+0(FP), R4 470 MOVV stk+8(FP), R5 471 472 // Copy mp, gp, fn off parent stack for use by child. 473 // Careful: Linux system call clobbers ???. 474 MOVV mp+16(FP), R16 475 MOVV gp+24(FP), R17 476 MOVV fn+32(FP), R18 477 478 MOVV R16, -8(R5) 479 MOVV R17, -16(R5) 480 MOVV R18, -24(R5) 481 MOVV $1234, R16 482 MOVV R16, -32(R5) 483 484 MOVV $SYS_clone, R2 485 SYSCALL 486 BEQ R7, 2(PC) 487 SUBVU R2, R0, R2 // caller expects negative errno 488 489 // In parent, return. 490 BEQ R2, 3(PC) 491 MOVW R2, ret+40(FP) 492 RET 493 494 // In child, on new stack. 495 MOVV -32(R29), R16 496 MOVV $1234, R1 497 BEQ R16, R1, 2(PC) 498 MOVV R0, 0(R0) 499 500 // Initialize m->procid to Linux tid 501 MOVV $SYS_gettid, R2 502 SYSCALL 503 504 MOVV -24(R29), R18 // fn 505 MOVV -16(R29), R17 // g 506 MOVV -8(R29), R16 // m 507 508 BEQ R16, nog 509 BEQ R17, nog 510 511 MOVV R2, m_procid(R16) 512 513 // TODO: setup TLS. 514 515 // In child, set up new stack 516 MOVV R16, g_m(R17) 517 MOVV R17, g 518 //CALL runtime·stackcheck(SB) 519 520 nog: 521 // Call fn 522 JAL (R18) 523 524 // It shouldn't return. If it does, exit that thread. 525 MOVW $111, R4 526 MOVV $SYS_exit, R2 527 SYSCALL 528 JMP -3(PC) // keep exiting 529 530 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0 531 MOVV new+0(FP), R4 532 MOVV old+8(FP), R5 533 MOVV $SYS_sigaltstack, R2 534 SYSCALL 535 BEQ R7, 2(PC) 536 MOVV R0, 0xf1(R0) // crash 537 RET 538 539 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0 540 MOVV $SYS_sched_yield, R2 541 SYSCALL 542 RET 543 544 TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0 545 MOVV pid+0(FP), R4 546 MOVV len+8(FP), R5 547 MOVV buf+16(FP), R6 548 MOVV $SYS_sched_getaffinity, R2 549 SYSCALL 550 BEQ R7, 2(PC) 551 SUBVU R2, R0, R2 // caller expects negative errno 552 MOVW R2, ret+24(FP) 553 RET 554 555 // int32 runtime·epollcreate(int32 size); 556 TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0 557 MOVW size+0(FP), R4 558 MOVV $SYS_epoll_create, R2 559 SYSCALL 560 BEQ R7, 2(PC) 561 SUBVU R2, R0, R2 // caller expects negative errno 562 MOVW R2, ret+8(FP) 563 RET 564 565 // int32 runtime·epollcreate1(int32 flags); 566 TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0 567 MOVW flags+0(FP), R4 568 MOVV $SYS_epoll_create1, R2 569 SYSCALL 570 BEQ R7, 2(PC) 571 SUBVU R2, R0, R2 // caller expects negative errno 572 MOVW R2, ret+8(FP) 573 RET 574 575 // func epollctl(epfd, op, fd int32, ev *epollEvent) int 576 TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0 577 MOVW epfd+0(FP), R4 578 MOVW op+4(FP), R5 579 MOVW fd+8(FP), R6 580 MOVV ev+16(FP), R7 581 MOVV $SYS_epoll_ctl, R2 582 SYSCALL 583 SUBVU R2, R0, R2 // caller expects negative errno 584 MOVW R2, ret+24(FP) 585 RET 586 587 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 588 TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0 589 // This uses pwait instead of wait, because Android O blocks wait. 590 MOVW epfd+0(FP), R4 591 MOVV ev+8(FP), R5 592 MOVW nev+16(FP), R6 593 MOVW timeout+20(FP), R7 594 MOVV $0, R8 595 MOVV $SYS_epoll_pwait, R2 596 SYSCALL 597 BEQ R7, 2(PC) 598 SUBVU R2, R0, R2 // caller expects negative errno 599 MOVW R2, ret+24(FP) 600 RET 601 602 // void runtime·closeonexec(int32 fd); 603 TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0 604 MOVW fd+0(FP), R4 // fd 605 MOVV $2, R5 // F_SETFD 606 MOVV $1, R6 // FD_CLOEXEC 607 MOVV $SYS_fcntl, R2 608 SYSCALL 609 RET 610 611 // func runtime·setNonblock(int32 fd) 612 TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4 613 MOVW fd+0(FP), R4 // fd 614 MOVV $3, R5 // F_GETFL 615 MOVV $0, R6 616 MOVV $SYS_fcntl, R2 617 SYSCALL 618 MOVW $0x80, R6 // O_NONBLOCK 619 OR R2, R6 620 MOVW fd+0(FP), R4 // fd 621 MOVV $4, R5 // F_SETFL 622 MOVV $SYS_fcntl, R2 623 SYSCALL 624 RET 625 626 // func sbrk0() uintptr 627 TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0-8 628 // Implemented as brk(NULL). 629 MOVV $0, R4 630 MOVV $SYS_brk, R2 631 SYSCALL 632 MOVV R2, ret+0(FP) 633 RET 634 635 TEXT runtime·access(SB),$0-20 636 MOVV R0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go 637 MOVW R0, ret+16(FP) // for vet 638 RET 639 640 TEXT runtime·connect(SB),$0-28 641 MOVV R0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go 642 MOVW R0, ret+24(FP) // for vet 643 RET 644 645 TEXT runtime·socket(SB),$0-20 646 MOVV R0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go 647 MOVW R0, ret+16(FP) // for vet 648 RET