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 50TEXT runtime·exit(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) 57TEXT runtime·exitThread(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 69TEXT runtime·open(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 80TEXT runtime·closefd(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 89TEXT runtime·write(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 100TEXT runtime·read(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 111TEXT runtime·getrlimit(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 119TEXT runtime·usleep(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 141TEXT runtime·gettid(SB),NOSPLIT,$0-4 142 MOVV $SYS_gettid, R2 143 SYSCALL 144 MOVW R2, ret+0(FP) 145 RET 146 147TEXT runtime·raise(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 156TEXT runtime·raiseproc(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 165TEXT runtime·setitimer(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 173TEXT runtime·mincore(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) 184TEXT runtime·walltime(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 195TEXT runtime·nanotime(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 211TEXT runtime·rtsigprocmask(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 222TEXT runtime·rt_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 232TEXT runtime·sigfwd(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 240TEXT runtime·sigtramp(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 runtime·iscgo(SB), R1 249 BEQ R1, 2(PC) 250 JAL runtime·load_g(SB) 251 252 MOVW R4, 8(R29) 253 MOVV R5, 16(R29) 254 MOVV R6, 24(R29) 255 MOVV $runtime·sigtrampgo(SB), R1 256 JAL (R1) 257 RET 258 259TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0 260 JMP runtime·sigtramp(SB) 261 262TEXT runtime·mmap(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 276ok: 277 MOVV R2, p+32(FP) 278 MOVV $0, err+40(FP) 279 RET 280 281TEXT runtime·munmap(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 290TEXT runtime·madvise(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); 301TEXT runtime·futex(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)); 314TEXT runtime·clone(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 runtime·stackcheck(SB) 363 364nog: 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 374TEXT runtime·sigaltstack(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 383TEXT runtime·osyield(SB),NOSPLIT,$-8 384 MOVV $SYS_sched_yield, R2 385 SYSCALL 386 RET 387 388TEXT runtime·sched_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 runtime·epollcreate(int32 size); 398TEXT runtime·epollcreate(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 runtime·epollcreate1(int32 flags); 406TEXT runtime·epollcreate1(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 414TEXT runtime·epollctl(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 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout); 425TEXT runtime·epollwait(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 runtime·closeonexec(int32 fd); 436TEXT runtime·closeonexec(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 445TEXT runtime·sbrk0(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