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