Text file
src/runtime/sys_linux_mipsx.s
Documentation: runtime
1 // Copyright 2016 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 && (mips || mipsle)
6 // +build linux
7 // +build mips mipsle
8
9 //
10 // System calls and other sys.stuff for mips, Linux
11 //
12
13 #include "go_asm.h"
14 #include "go_tls.h"
15 #include "textflag.h"
16
17 #define SYS_exit 4001
18 #define SYS_read 4003
19 #define SYS_write 4004
20 #define SYS_open 4005
21 #define SYS_close 4006
22 #define SYS_getpid 4020
23 #define SYS_kill 4037
24 #define SYS_pipe 4042
25 #define SYS_brk 4045
26 #define SYS_fcntl 4055
27 #define SYS_mmap 4090
28 #define SYS_munmap 4091
29 #define SYS_setitimer 4104
30 #define SYS_clone 4120
31 #define SYS_sched_yield 4162
32 #define SYS_nanosleep 4166
33 #define SYS_rt_sigreturn 4193
34 #define SYS_rt_sigaction 4194
35 #define SYS_rt_sigprocmask 4195
36 #define SYS_sigaltstack 4206
37 #define SYS_madvise 4218
38 #define SYS_mincore 4217
39 #define SYS_gettid 4222
40 #define SYS_futex 4238
41 #define SYS_sched_getaffinity 4240
42 #define SYS_exit_group 4246
43 #define SYS_epoll_create 4248
44 #define SYS_epoll_ctl 4249
45 #define SYS_epoll_wait 4250
46 #define SYS_clock_gettime 4263
47 #define SYS_tgkill 4266
48 #define SYS_epoll_create1 4326
49 #define SYS_pipe2 4328
50
51 TEXT runtime·exit(SB),NOSPLIT,$0-4
52 MOVW code+0(FP), R4
53 MOVW $SYS_exit_group, R2
54 SYSCALL
55 UNDEF
56 RET
57
58 // func exitThread(wait *uint32)
59 TEXT runtime·exitThread(SB),NOSPLIT,$0-4
60 MOVW 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 MOVW $SYS_exit, R2
68 SYSCALL
69 UNDEF
70 JMP 0(PC)
71
72 TEXT runtime·open(SB),NOSPLIT,$0-16
73 MOVW name+0(FP), R4
74 MOVW mode+4(FP), R5
75 MOVW perm+8(FP), R6
76 MOVW $SYS_open, R2
77 SYSCALL
78 BEQ R7, 2(PC)
79 MOVW $-1, R2
80 MOVW R2, ret+12(FP)
81 RET
82
83 TEXT runtime·closefd(SB),NOSPLIT,$0-8
84 MOVW fd+0(FP), R4
85 MOVW $SYS_close, R2
86 SYSCALL
87 BEQ R7, 2(PC)
88 MOVW $-1, R2
89 MOVW R2, ret+4(FP)
90 RET
91
92 TEXT runtime·write1(SB),NOSPLIT,$0-16
93 MOVW fd+0(FP), R4
94 MOVW p+4(FP), R5
95 MOVW n+8(FP), R6
96 MOVW $SYS_write, R2
97 SYSCALL
98 BEQ R7, 2(PC)
99 SUBU R2, R0, R2 // caller expects negative errno
100 MOVW R2, ret+12(FP)
101 RET
102
103 TEXT runtime·read(SB),NOSPLIT,$0-16
104 MOVW fd+0(FP), R4
105 MOVW p+4(FP), R5
106 MOVW n+8(FP), R6
107 MOVW $SYS_read, R2
108 SYSCALL
109 BEQ R7, 2(PC)
110 SUBU R2, R0, R2 // caller expects negative errno
111 MOVW R2, ret+12(FP)
112 RET
113
114 // func pipe() (r, w int32, errno int32)
115 TEXT runtime·pipe(SB),NOSPLIT,$0-12
116 MOVW $SYS_pipe, R2
117 SYSCALL
118 BEQ R7, pipeok
119 MOVW $-1, R1
120 MOVW R1, r+0(FP)
121 MOVW R1, w+4(FP)
122 SUBU R2, R0, R2 // caller expects negative errno
123 MOVW R2, errno+8(FP)
124 RET
125 pipeok:
126 MOVW R2, r+0(FP)
127 MOVW R3, w+4(FP)
128 MOVW R0, errno+8(FP)
129 RET
130
131 // func pipe2(flags int32) (r, w int32, errno int32)
132 TEXT runtime·pipe2(SB),NOSPLIT,$0-16
133 MOVW $r+4(FP), R4
134 MOVW flags+0(FP), R5
135 MOVW $SYS_pipe2, R2
136 SYSCALL
137 BEQ R7, 2(PC)
138 SUBU R2, R0, R2 // caller expects negative errno
139 MOVW R2, errno+12(FP)
140 RET
141
142 TEXT runtime·usleep(SB),NOSPLIT,$28-4
143 MOVW usec+0(FP), R3
144 MOVW R3, R5
145 MOVW $1000000, R4
146 DIVU R4, R3
147 MOVW LO, R3
148 MOVW R3, 24(R29)
149 MOVW $1000, R4
150 MULU R3, R4
151 MOVW LO, R4
152 SUBU R4, R5
153 MOVW R5, 28(R29)
154
155 // nanosleep(&ts, 0)
156 ADDU $24, R29, R4
157 MOVW $0, R5
158 MOVW $SYS_nanosleep, R2
159 SYSCALL
160 RET
161
162 TEXT runtime·gettid(SB),NOSPLIT,$0-4
163 MOVW $SYS_gettid, R2
164 SYSCALL
165 MOVW R2, ret+0(FP)
166 RET
167
168 TEXT runtime·raise(SB),NOSPLIT,$0-4
169 MOVW $SYS_getpid, R2
170 SYSCALL
171 MOVW R2, R16
172 MOVW $SYS_gettid, R2
173 SYSCALL
174 MOVW R2, R5 // arg 2 tid
175 MOVW R16, R4 // arg 1 pid
176 MOVW sig+0(FP), R6 // arg 3
177 MOVW $SYS_tgkill, R2
178 SYSCALL
179 RET
180
181 TEXT runtime·raiseproc(SB),NOSPLIT,$0
182 MOVW $SYS_getpid, R2
183 SYSCALL
184 MOVW R2, R4 // arg 1 pid
185 MOVW sig+0(FP), R5 // arg 2
186 MOVW $SYS_kill, R2
187 SYSCALL
188 RET
189
190 TEXT ·getpid(SB),NOSPLIT,$0-4
191 MOVW $SYS_getpid, R2
192 SYSCALL
193 MOVW R2, ret+0(FP)
194 RET
195
196 TEXT ·tgkill(SB),NOSPLIT,$0-12
197 MOVW tgid+0(FP), R4
198 MOVW tid+4(FP), R5
199 MOVW sig+8(FP), R6
200 MOVW $SYS_tgkill, R2
201 SYSCALL
202 RET
203
204 TEXT runtime·setitimer(SB),NOSPLIT,$0-12
205 MOVW mode+0(FP), R4
206 MOVW new+4(FP), R5
207 MOVW old+8(FP), R6
208 MOVW $SYS_setitimer, R2
209 SYSCALL
210 RET
211
212 TEXT runtime·mincore(SB),NOSPLIT,$0-16
213 MOVW addr+0(FP), R4
214 MOVW n+4(FP), R5
215 MOVW dst+8(FP), R6
216 MOVW $SYS_mincore, R2
217 SYSCALL
218 SUBU R2, R0, R2 // caller expects negative errno
219 MOVW R2, ret+12(FP)
220 RET
221
222 // func walltime() (sec int64, nsec int32)
223 TEXT runtime·walltime(SB),NOSPLIT,$8-12
224 MOVW $0, R4 // CLOCK_REALTIME
225 MOVW $4(R29), R5
226 MOVW $SYS_clock_gettime, R2
227 SYSCALL
228 MOVW 4(R29), R3 // sec
229 MOVW 8(R29), R5 // nsec
230 MOVW $sec+0(FP), R6
231 #ifdef GOARCH_mips
232 MOVW R3, 4(R6)
233 MOVW R0, 0(R6)
234 #else
235 MOVW R3, 0(R6)
236 MOVW R0, 4(R6)
237 #endif
238 MOVW R5, nsec+8(FP)
239 RET
240
241 TEXT runtime·nanotime1(SB),NOSPLIT,$8-8
242 MOVW $1, R4 // CLOCK_MONOTONIC
243 MOVW $4(R29), R5
244 MOVW $SYS_clock_gettime, R2
245 SYSCALL
246 MOVW 4(R29), R3 // sec
247 MOVW 8(R29), R5 // nsec
248 // sec is in R3, nsec in R5
249 // return nsec in R3
250 MOVW $1000000000, R4
251 MULU R4, R3
252 MOVW LO, R3
253 ADDU R5, R3
254 SGTU R5, R3, R4
255 MOVW $ret+0(FP), R6
256 #ifdef GOARCH_mips
257 MOVW R3, 4(R6)
258 #else
259 MOVW R3, 0(R6)
260 #endif
261 MOVW HI, R3
262 ADDU R4, R3
263 #ifdef GOARCH_mips
264 MOVW R3, 0(R6)
265 #else
266 MOVW R3, 4(R6)
267 #endif
268 RET
269
270 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-16
271 MOVW how+0(FP), R4
272 MOVW new+4(FP), R5
273 MOVW old+8(FP), R6
274 MOVW size+12(FP), R7
275 MOVW $SYS_rt_sigprocmask, R2
276 SYSCALL
277 BEQ R7, 2(PC)
278 UNDEF // crash
279 RET
280
281 TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-20
282 MOVW sig+0(FP), R4
283 MOVW new+4(FP), R5
284 MOVW old+8(FP), R6
285 MOVW size+12(FP), R7
286 MOVW $SYS_rt_sigaction, R2
287 SYSCALL
288 BEQ R7, 2(PC)
289 SUBU R2, R0, R2 // caller expects negative errno
290 MOVW R2, ret+16(FP)
291 RET
292
293 TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
294 MOVW sig+4(FP), R4
295 MOVW info+8(FP), R5
296 MOVW ctx+12(FP), R6
297 MOVW fn+0(FP), R25
298 MOVW R29, R22
299 SUBU $16, R29
300 AND $~7, R29 // shadow space for 4 args aligned to 8 bytes as per O32 ABI
301 JAL (R25)
302 MOVW R22, R29
303 RET
304
305 TEXT runtime·sigtramp(SB),NOSPLIT,$12
306 // this might be called in external code context,
307 // where g is not set.
308 MOVB runtime·iscgo(SB), R1
309 BEQ R1, 2(PC)
310 JAL runtime·load_g(SB)
311
312 MOVW R4, 4(R29)
313 MOVW R5, 8(R29)
314 MOVW R6, 12(R29)
315 MOVW $runtime·sigtrampgo(SB), R1
316 JAL (R1)
317 RET
318
319 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
320 JMP runtime·sigtramp(SB)
321
322 TEXT runtime·mmap(SB),NOSPLIT,$20-32
323 MOVW addr+0(FP), R4
324 MOVW n+4(FP), R5
325 MOVW prot+8(FP), R6
326 MOVW flags+12(FP), R7
327 MOVW fd+16(FP), R8
328 MOVW off+20(FP), R9
329 MOVW R8, 16(R29)
330 MOVW R9, 20(R29)
331
332 MOVW $SYS_mmap, R2
333 SYSCALL
334 BEQ R7, ok
335 MOVW $0, p+24(FP)
336 MOVW R2, err+28(FP)
337 RET
338 ok:
339 MOVW R2, p+24(FP)
340 MOVW $0, err+28(FP)
341 RET
342
343 TEXT runtime·munmap(SB),NOSPLIT,$0-8
344 MOVW addr+0(FP), R4
345 MOVW n+4(FP), R5
346 MOVW $SYS_munmap, R2
347 SYSCALL
348 BEQ R7, 2(PC)
349 UNDEF // crash
350 RET
351
352 TEXT runtime·madvise(SB),NOSPLIT,$0-16
353 MOVW addr+0(FP), R4
354 MOVW n+4(FP), R5
355 MOVW flags+8(FP), R6
356 MOVW $SYS_madvise, R2
357 SYSCALL
358 MOVW R2, ret+12(FP)
359 RET
360
361 // int32 futex(int32 *uaddr, int32 op, int32 val, struct timespec *timeout, int32 *uaddr2, int32 val2);
362 TEXT runtime·futex(SB),NOSPLIT,$20-28
363 MOVW addr+0(FP), R4
364 MOVW op+4(FP), R5
365 MOVW val+8(FP), R6
366 MOVW ts+12(FP), R7
367
368 MOVW addr2+16(FP), R8
369 MOVW val3+20(FP), R9
370
371 MOVW R8, 16(R29)
372 MOVW R9, 20(R29)
373
374 MOVW $SYS_futex, R2
375 SYSCALL
376 BEQ R7, 2(PC)
377 SUBU R2, R0, R2 // caller expects negative errno
378 MOVW R2, ret+24(FP)
379 RET
380
381
382 // int32 clone(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
383 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0-24
384 MOVW flags+0(FP), R4
385 MOVW stk+4(FP), R5
386 MOVW R0, R6 // ptid
387 MOVW R0, R7 // tls
388
389 // O32 syscall handler unconditionally copies arguments 5-8 from stack,
390 // even for syscalls with less than 8 arguments. Reserve 32 bytes of new
391 // stack so that any syscall invoked immediately in the new thread won't fail.
392 ADD $-32, R5
393
394 // Copy mp, gp, fn off parent stack for use by child.
395 MOVW mp+8(FP), R16
396 MOVW gp+12(FP), R17
397 MOVW fn+16(FP), R18
398
399 MOVW $1234, R1
400
401 MOVW R16, 0(R5)
402 MOVW R17, 4(R5)
403 MOVW R18, 8(R5)
404
405 MOVW R1, 12(R5)
406
407 MOVW $SYS_clone, R2
408 SYSCALL
409 BEQ R7, 2(PC)
410 SUBU R2, R0, R2 // caller expects negative errno
411
412 // In parent, return.
413 BEQ R2, 3(PC)
414 MOVW R2, ret+20(FP)
415 RET
416
417 // In child, on new stack.
418 // Check that SP is as we expect
419 NOP R29 // tell vet R29/SP changed - stop checking offsets
420 MOVW 12(R29), R16
421 MOVW $1234, R1
422 BEQ R16, R1, 2(PC)
423 MOVW (R0), R0
424
425 // Initialize m->procid to Linux tid
426 MOVW $SYS_gettid, R2
427 SYSCALL
428
429 MOVW 0(R29), R16 // m
430 MOVW 4(R29), R17 // g
431 MOVW 8(R29), R18 // fn
432
433 BEQ R16, nog
434 BEQ R17, nog
435
436 MOVW R2, m_procid(R16)
437
438 // In child, set up new stack
439 MOVW R16, g_m(R17)
440 MOVW R17, g
441
442 // TODO(mips32): doesn't have runtime·stackcheck(SB)
443
444 nog:
445 // Call fn
446 ADDU $32, R29
447 JAL (R18)
448
449 // It shouldn't return. If it does, exit that thread.
450 ADDU $-32, R29
451 MOVW $0xf4, R4
452 MOVW $SYS_exit, R2
453 SYSCALL
454 UNDEF
455
456 TEXT runtime·sigaltstack(SB),NOSPLIT,$0
457 MOVW new+0(FP), R4
458 MOVW old+4(FP), R5
459 MOVW $SYS_sigaltstack, R2
460 SYSCALL
461 BEQ R7, 2(PC)
462 UNDEF // crash
463 RET
464
465 TEXT runtime·osyield(SB),NOSPLIT,$0
466 MOVW $SYS_sched_yield, R2
467 SYSCALL
468 RET
469
470 TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0-16
471 MOVW pid+0(FP), R4
472 MOVW len+4(FP), R5
473 MOVW buf+8(FP), R6
474 MOVW $SYS_sched_getaffinity, R2
475 SYSCALL
476 BEQ R7, 2(PC)
477 SUBU R2, R0, R2 // caller expects negative errno
478 MOVW R2, ret+12(FP)
479 RET
480
481 // int32 runtime·epollcreate(int32 size);
482 TEXT runtime·epollcreate(SB),NOSPLIT,$0-8
483 MOVW size+0(FP), R4
484 MOVW $SYS_epoll_create, R2
485 SYSCALL
486 BEQ R7, 2(PC)
487 SUBU R2, R0, R2 // caller expects negative errno
488 MOVW R2, ret+4(FP)
489 RET
490
491 // int32 runtime·epollcreate1(int32 flags);
492 TEXT runtime·epollcreate1(SB),NOSPLIT,$0-8
493 MOVW flags+0(FP), R4
494 MOVW $SYS_epoll_create1, R2
495 SYSCALL
496 BEQ R7, 2(PC)
497 SUBU R2, R0, R2 // caller expects negative errno
498 MOVW R2, ret+4(FP)
499 RET
500
501 // func epollctl(epfd, op, fd int32, ev *epollEvent) int
502 TEXT runtime·epollctl(SB),NOSPLIT,$0-20
503 MOVW epfd+0(FP), R4
504 MOVW op+4(FP), R5
505 MOVW fd+8(FP), R6
506 MOVW ev+12(FP), R7
507 MOVW $SYS_epoll_ctl, R2
508 SYSCALL
509 SUBU R2, R0, R2 // caller expects negative errno
510 MOVW R2, ret+16(FP)
511 RET
512
513 // int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
514 TEXT runtime·epollwait(SB),NOSPLIT,$0-20
515 MOVW epfd+0(FP), R4
516 MOVW ev+4(FP), R5
517 MOVW nev+8(FP), R6
518 MOVW timeout+12(FP), R7
519 MOVW $SYS_epoll_wait, R2
520 SYSCALL
521 BEQ R7, 2(PC)
522 SUBU R2, R0, R2 // caller expects negative errno
523 MOVW R2, ret+16(FP)
524 RET
525
526 // void runtime·closeonexec(int32 fd);
527 TEXT runtime·closeonexec(SB),NOSPLIT,$0-4
528 MOVW fd+0(FP), R4 // fd
529 MOVW $2, R5 // F_SETFD
530 MOVW $1, R6 // FD_CLOEXEC
531 MOVW $SYS_fcntl, R2
532 SYSCALL
533 RET
534
535 // func runtime·setNonblock(int32 fd)
536 TEXT runtime·setNonblock(SB),NOSPLIT,$0-4
537 MOVW fd+0(FP), R4 // fd
538 MOVW $3, R5 // F_GETFL
539 MOVW $0, R6
540 MOVW $SYS_fcntl, R2
541 SYSCALL
542 MOVW $0x80, R6 // O_NONBLOCK
543 OR R2, R6
544 MOVW fd+0(FP), R4 // fd
545 MOVW $4, R5 // F_SETFL
546 MOVW $SYS_fcntl, R2
547 SYSCALL
548 RET
549
550 // func sbrk0() uintptr
551 TEXT runtime·sbrk0(SB),NOSPLIT,$0-4
552 // Implemented as brk(NULL).
553 MOVW $0, R4
554 MOVW $SYS_brk, R2
555 SYSCALL
556 MOVW R2, ret+0(FP)
557 RET
558
559 TEXT runtime·access(SB),$0-12
560 BREAK // unimplemented, only needed for android; declared in stubs_linux.go
561 MOVW R0, ret+8(FP) // for vet
562 RET
563
564 TEXT runtime·connect(SB),$0-16
565 BREAK // unimplemented, only needed for android; declared in stubs_linux.go
566 MOVW R0, ret+12(FP) // for vet
567 RET
568
569 TEXT runtime·socket(SB),$0-16
570 BREAK // unimplemented, only needed for android; declared in stubs_linux.go
571 MOVW R0, ret+12(FP) // for vet
572 RET
573
View as plain text