Text file
src/runtime/sys_linux_mips64x.s
Documentation: runtime
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
48TEXT 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)
55TEXT 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
67TEXT 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
80TEXT 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
89TEXT 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
100TEXT 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)
112TEXT 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
122TEXT 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
142TEXT runtime·gettid(SB),NOSPLIT,$0-4
143 MOVV $SYS_gettid, R2
144 SYSCALL
145 MOVW R2, ret+0(FP)
146 RET
147
148TEXT 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
161TEXT 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
170TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
171 MOVV $SYS_getpid, R2
172 SYSCALL
173 MOVV R2, ret+0(FP)
174 RET
175
176TEXT ·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
184TEXT 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
192TEXT 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
201TEXT 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
211TEXT 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
218TEXT 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)
229TEXT 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
254noswitch:
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
275finish:
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
294fallback:
295 MOVV $SYS_clock_gettime, R2
296 SYSCALL
297 JMP finish
298
299TEXT 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
324noswitch:
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
343finish:
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
367fallback:
368 MOVV $SYS_clock_gettime, R2
369 SYSCALL
370 JMP finish
371
372TEXT 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
383TEXT 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
395TEXT 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
403TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$64
404 // initialize REGSB = PC&0xffffffff00000000
405 BGEZAL R0, 1(PC)
406 SRLV $32, R31, RSB
407 SLLV $32, RSB
408
409 // this might be called in external code context,
410 // where g is not set.
411 MOVB runtime·iscgo(SB), R1
412 BEQ R1, 2(PC)
413 JAL runtime·load_g(SB)
414
415 MOVW R4, 8(R29)
416 MOVV R5, 16(R29)
417 MOVV R6, 24(R29)
418 MOVV $runtime·sigtrampgo(SB), R1
419 JAL (R1)
420 RET
421
422TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
423 JMP runtime·sigtramp(SB)
424
425TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
426 MOVV addr+0(FP), R4
427 MOVV n+8(FP), R5
428 MOVW prot+16(FP), R6
429 MOVW flags+20(FP), R7
430 MOVW fd+24(FP), R8
431 MOVW off+28(FP), R9
432
433 MOVV $SYS_mmap, R2
434 SYSCALL
435 BEQ R7, ok
436 MOVV $0, p+32(FP)
437 MOVV R2, err+40(FP)
438 RET
439ok:
440 MOVV R2, p+32(FP)
441 MOVV $0, err+40(FP)
442 RET
443
444TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
445 MOVV addr+0(FP), R4
446 MOVV n+8(FP), R5
447 MOVV $SYS_munmap, R2
448 SYSCALL
449 BEQ R7, 2(PC)
450 MOVV R0, 0xf3(R0) // crash
451 RET
452
453TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
454 MOVV addr+0(FP), R4
455 MOVV n+8(FP), R5
456 MOVW flags+16(FP), R6
457 MOVV $SYS_madvise, R2
458 SYSCALL
459 MOVW R2, ret+24(FP)
460 RET
461
462// int64 futex(int32 *uaddr, int32 op, int32 val,
463// struct timespec *timeout, int32 *uaddr2, int32 val2);
464TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
465 MOVV addr+0(FP), R4
466 MOVW op+8(FP), R5
467 MOVW val+12(FP), R6
468 MOVV ts+16(FP), R7
469 MOVV addr2+24(FP), R8
470 MOVW val3+32(FP), R9
471 MOVV $SYS_futex, R2
472 SYSCALL
473 BEQ R7, 2(PC)
474 SUBVU R2, R0, R2 // caller expects negative errno
475 MOVW R2, ret+40(FP)
476 RET
477
478// int64 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
479TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
480 MOVW flags+0(FP), R4
481 MOVV stk+8(FP), R5
482
483 // Copy mp, gp, fn off parent stack for use by child.
484 // Careful: Linux system call clobbers ???.
485 MOVV mp+16(FP), R16
486 MOVV gp+24(FP), R17
487 MOVV fn+32(FP), R18
488
489 MOVV R16, -8(R5)
490 MOVV R17, -16(R5)
491 MOVV R18, -24(R5)
492 MOVV $1234, R16
493 MOVV R16, -32(R5)
494
495 MOVV $SYS_clone, R2
496 SYSCALL
497 BEQ R7, 2(PC)
498 SUBVU R2, R0, R2 // caller expects negative errno
499
500 // In parent, return.
501 BEQ R2, 3(PC)
502 MOVW R2, ret+40(FP)
503 RET
504
505 // In child, on new stack.
506 MOVV -32(R29), R16
507 MOVV $1234, R1
508 BEQ R16, R1, 2(PC)
509 MOVV R0, 0(R0)
510
511 // Initialize m->procid to Linux tid
512 MOVV $SYS_gettid, R2
513 SYSCALL
514
515 MOVV -24(R29), R18 // fn
516 MOVV -16(R29), R17 // g
517 MOVV -8(R29), R16 // m
518
519 BEQ R16, nog
520 BEQ R17, nog
521
522 MOVV R2, m_procid(R16)
523
524 // TODO: setup TLS.
525
526 // In child, set up new stack
527 MOVV R16, g_m(R17)
528 MOVV R17, g
529 //CALL runtime·stackcheck(SB)
530
531nog:
532 // Call fn
533 JAL (R18)
534
535 // It shouldn't return. If it does, exit that thread.
536 MOVW $111, R4
537 MOVV $SYS_exit, R2
538 SYSCALL
539 JMP -3(PC) // keep exiting
540
541TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
542 MOVV new+0(FP), R4
543 MOVV old+8(FP), R5
544 MOVV $SYS_sigaltstack, R2
545 SYSCALL
546 BEQ R7, 2(PC)
547 MOVV R0, 0xf1(R0) // crash
548 RET
549
550TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
551 MOVV $SYS_sched_yield, R2
552 SYSCALL
553 RET
554
555TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
556 MOVV pid+0(FP), R4
557 MOVV len+8(FP), R5
558 MOVV buf+16(FP), R6
559 MOVV $SYS_sched_getaffinity, R2
560 SYSCALL
561 BEQ R7, 2(PC)
562 SUBVU R2, R0, R2 // caller expects negative errno
563 MOVW R2, ret+24(FP)
564 RET
565
566// func sbrk0() uintptr
567TEXT runtime·sbrk0(SB),NOSPLIT|NOFRAME,$0-8
568 // Implemented as brk(NULL).
569 MOVV $0, R4
570 MOVV $SYS_brk, R2
571 SYSCALL
572 MOVV R2, ret+0(FP)
573 RET
574
575TEXT runtime·access(SB),$0-20
576 MOVV R0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go
577 MOVW R0, ret+16(FP) // for vet
578 RET
579
580TEXT runtime·connect(SB),$0-28
581 MOVV R0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go
582 MOVW R0, ret+24(FP) // for vet
583 RET
584
585TEXT runtime·socket(SB),$0-20
586 MOVV R0, 2(R0) // unimplemented, only needed for android; declared in stubs_linux.go
587 MOVW R0, ret+16(FP) // for vet
588 RET
View as plain text