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