Text file
src/runtime/sys_linux_riscv64.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 //
6 // System calls and other sys.stuff for riscv64, Linux
7 //
8
9 #include "textflag.h"
10 #include "go_asm.h"
11
12 #define AT_FDCWD -100
13 #define CLOCK_REALTIME 0
14 #define CLOCK_MONOTONIC 1
15
16 #define SYS_brk 214
17 #define SYS_clock_gettime 113
18 #define SYS_clone 220
19 #define SYS_close 57
20 #define SYS_connect 203
21 #define SYS_epoll_create1 20
22 #define SYS_epoll_ctl 21
23 #define SYS_epoll_pwait 22
24 #define SYS_exit 93
25 #define SYS_exit_group 94
26 #define SYS_faccessat 48
27 #define SYS_fcntl 25
28 #define SYS_futex 98
29 #define SYS_getpid 172
30 #define SYS_gettid 178
31 #define SYS_gettimeofday 169
32 #define SYS_kill 129
33 #define SYS_madvise 233
34 #define SYS_mincore 232
35 #define SYS_mmap 222
36 #define SYS_munmap 215
37 #define SYS_nanosleep 101
38 #define SYS_openat 56
39 #define SYS_pipe2 59
40 #define SYS_pselect6 72
41 #define SYS_read 63
42 #define SYS_rt_sigaction 134
43 #define SYS_rt_sigprocmask 135
44 #define SYS_rt_sigreturn 139
45 #define SYS_sched_getaffinity 123
46 #define SYS_sched_yield 124
47 #define SYS_setitimer 103
48 #define SYS_sigaltstack 132
49 #define SYS_socket 198
50 #define SYS_tgkill 131
51 #define SYS_timer_create 107
52 #define SYS_timer_delete 111
53 #define SYS_timer_settime 110
54 #define SYS_tkill 130
55 #define SYS_write 64
56
57 // func exit(code int32)
58 TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
59 MOVW code+0(FP), A0
60 MOV $SYS_exit_group, A7
61 ECALL
62 RET
63
64 // func exitThread(wait *uint32)
65 TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
66 MOV wait+0(FP), A0
67 // We're done using the stack.
68 FENCE
69 MOVW ZERO, (A0)
70 FENCE
71 MOV $0, A0 // exit code
72 MOV $SYS_exit, A7
73 ECALL
74 JMP 0(PC)
75
76 // func open(name *byte, mode, perm int32) int32
77 TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
78 MOV $AT_FDCWD, A0
79 MOV name+0(FP), A1
80 MOVW mode+8(FP), A2
81 MOVW perm+12(FP), A3
82 MOV $SYS_openat, A7
83 ECALL
84 MOV $-4096, T0
85 BGEU T0, A0, 2(PC)
86 MOV $-1, A0
87 MOVW A0, ret+16(FP)
88 RET
89
90 // func closefd(fd int32) int32
91 TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
92 MOVW fd+0(FP), A0
93 MOV $SYS_close, A7
94 ECALL
95 MOV $-4096, T0
96 BGEU T0, A0, 2(PC)
97 MOV $-1, A0
98 MOVW A0, ret+8(FP)
99 RET
100
101 // func write1(fd uintptr, p unsafe.Pointer, n int32) int32
102 TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
103 MOV fd+0(FP), A0
104 MOV p+8(FP), A1
105 MOVW n+16(FP), A2
106 MOV $SYS_write, A7
107 ECALL
108 MOVW A0, ret+24(FP)
109 RET
110
111 // func read(fd int32, p unsafe.Pointer, n int32) int32
112 TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
113 MOVW fd+0(FP), A0
114 MOV p+8(FP), A1
115 MOVW n+16(FP), A2
116 MOV $SYS_read, A7
117 ECALL
118 MOVW A0, ret+24(FP)
119 RET
120
121 // func pipe() (r, w int32, errno int32)
122 TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12
123 MOV $r+0(FP), A0
124 MOV ZERO, A1
125 MOV $SYS_pipe2, A7
126 ECALL
127 MOVW A0, errno+8(FP)
128 RET
129
130 // func pipe2(flags int32) (r, w int32, errno int32)
131 TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
132 MOV $r+8(FP), A0
133 MOVW flags+0(FP), A1
134 MOV $SYS_pipe2, A7
135 ECALL
136 MOVW A0, errno+16(FP)
137 RET
138
139 // func usleep(usec uint32)
140 TEXT runtime·usleep(SB),NOSPLIT,$24-4
141 MOVWU usec+0(FP), A0
142 MOV $1000, A1
143 MUL A1, A0, A0
144 MOV $1000000000, A1
145 DIV A1, A0, A2
146 MOV A2, 8(X2)
147 REM A1, A0, A3
148 MOV A3, 16(X2)
149 ADD $8, X2, A0
150 MOV ZERO, A1
151 MOV $SYS_nanosleep, A7
152 ECALL
153 RET
154
155 // func gettid() uint32
156 TEXT runtime·gettid(SB),NOSPLIT,$0-4
157 MOV $SYS_gettid, A7
158 ECALL
159 MOVW A0, ret+0(FP)
160 RET
161
162 // func raise(sig uint32)
163 TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
164 MOV $SYS_gettid, A7
165 ECALL
166 // arg 1 tid - already in A0
167 MOVW sig+0(FP), A1 // arg 2
168 MOV $SYS_tkill, A7
169 ECALL
170 RET
171
172 // func raiseproc(sig uint32)
173 TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
174 MOV $SYS_getpid, A7
175 ECALL
176 // arg 1 pid - already in A0
177 MOVW sig+0(FP), A1 // arg 2
178 MOV $SYS_kill, A7
179 ECALL
180 RET
181
182 // func getpid() int
183 TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
184 MOV $SYS_getpid, A7
185 ECALL
186 MOV A0, ret+0(FP)
187 RET
188
189 // func tgkill(tgid, tid, sig int)
190 TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24
191 MOV tgid+0(FP), A0
192 MOV tid+8(FP), A1
193 MOV sig+16(FP), A2
194 MOV $SYS_tgkill, A7
195 ECALL
196 RET
197
198 // func setitimer(mode int32, new, old *itimerval)
199 TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
200 MOVW mode+0(FP), A0
201 MOV new+8(FP), A1
202 MOV old+16(FP), A2
203 MOV $SYS_setitimer, A7
204 ECALL
205 RET
206
207 // func timer_create(clockid int32, sevp *sigevent, timerid *int32) int32
208 TEXT runtime·timer_create(SB),NOSPLIT,$0-28
209 MOVW clockid+0(FP), A0
210 MOV sevp+8(FP), A1
211 MOV timerid+16(FP), A2
212 MOV $SYS_timer_create, A7
213 ECALL
214 MOVW A0, ret+24(FP)
215 RET
216
217 // func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32
218 TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
219 MOVW timerid+0(FP), A0
220 MOVW flags+4(FP), A1
221 MOV new+8(FP), A2
222 MOV old+16(FP), A3
223 MOV $SYS_timer_settime, A7
224 ECALL
225 MOVW A0, ret+24(FP)
226 RET
227
228 // func timer_delete(timerid int32) int32
229 TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
230 MOVW timerid+0(FP), A0
231 MOV $SYS_timer_delete, A7
232 ECALL
233 MOVW A0, ret+8(FP)
234 RET
235
236 // func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
237 TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
238 MOV addr+0(FP), A0
239 MOV n+8(FP), A1
240 MOV dst+16(FP), A2
241 MOV $SYS_mincore, A7
242 ECALL
243 MOVW A0, ret+24(FP)
244 RET
245
246 // func walltime() (sec int64, nsec int32)
247 TEXT runtime·walltime(SB),NOSPLIT,$40-12
248 MOV $CLOCK_REALTIME, A0
249
250 MOV runtime·vdsoClockgettimeSym(SB), A7
251 BEQZ A7, fallback
252 MOV X2, S2 // S2,S3,S4 is unchanged by C code
253 MOV g_m(g), S3 // S3 = m
254
255 // Save the old values on stack for reentrant
256 MOV m_vdsoPC(S3), T0
257 MOV T0, 24(X2)
258 MOV m_vdsoSP(S3), T0
259 MOV T0, 32(X2)
260
261 MOV RA, m_vdsoPC(S3)
262 MOV $ret-8(FP), T1 // caller's SP
263 MOV T1, m_vdsoSP(S3)
264
265 MOV m_curg(S3), T1
266 BNE g, T1, noswitch
267
268 MOV m_g0(S3), T1
269 MOV (g_sched+gobuf_sp)(T1), X2
270
271 noswitch:
272 ADDI $-24, X2 // Space for result
273 ANDI $~7, X2 // Align for C code
274 MOV $8(X2), A1
275
276 // Store g on gsignal's stack, see sys_linux_arm64.s for detail
277 MOVBU runtime·iscgo(SB), S4
278 BNEZ S4, nosaveg
279 MOV m_gsignal(S3), S4 // g.m.gsignal
280 BEQZ S4, nosaveg
281 BEQ g, S4, nosaveg
282 MOV (g_stack+stack_lo)(S4), S4 // g.m.gsignal.stack.lo
283 MOV g, (S4)
284
285 JALR RA, A7
286
287 MOV ZERO, (S4)
288 JMP finish
289
290 nosaveg:
291 JALR RA, A7
292
293 finish:
294 MOV 8(X2), T0 // sec
295 MOV 16(X2), T1 // nsec
296
297 MOV S2, X2 // restore stack
298 MOV 24(X2), A2
299 MOV A2, m_vdsoPC(S3)
300
301 MOV 32(X2), A3
302 MOV A3, m_vdsoSP(S3)
303
304 MOV T0, sec+0(FP)
305 MOVW T1, nsec+8(FP)
306 RET
307
308 fallback:
309 MOV $8(X2), A1
310 MOV $SYS_clock_gettime, A7
311 ECALL
312 MOV 8(X2), T0 // sec
313 MOV 16(X2), T1 // nsec
314 MOV T0, sec+0(FP)
315 MOVW T1, nsec+8(FP)
316 RET
317
318 // func nanotime1() int64
319 TEXT runtime·nanotime1(SB),NOSPLIT,$40-8
320 MOV $CLOCK_MONOTONIC, A0
321
322 MOV runtime·vdsoClockgettimeSym(SB), A7
323 BEQZ A7, fallback
324
325 MOV X2, S2 // S2 = RSP, S2 is unchanged by C code
326 MOV g_m(g), S3 // S3 = m
327 // Save the old values on stack for reentrant
328 MOV m_vdsoPC(S3), T0
329 MOV T0, 24(X2)
330 MOV m_vdsoSP(S3), T0
331 MOV T0, 32(X2)
332
333 MOV RA, m_vdsoPC(S3)
334 MOV $ret-8(FP), T0 // caller's SP
335 MOV T0, m_vdsoSP(S3)
336
337 MOV m_curg(S3), T1
338 BNE g, T1, noswitch
339
340 MOV m_g0(S3), T1
341 MOV (g_sched+gobuf_sp)(T1), X2
342
343 noswitch:
344 ADDI $-24, X2 // Space for result
345 ANDI $~7, X2 // Align for C code
346 MOV $8(X2), A1
347
348 // Store g on gsignal's stack, see sys_linux_arm64.s for detail
349 MOVBU runtime·iscgo(SB), S4
350 BNEZ S4, nosaveg
351 MOV m_gsignal(S3), S4 // g.m.gsignal
352 BEQZ S4, nosaveg
353 BEQ g, S4, nosaveg
354 MOV (g_stack+stack_lo)(S4), S4 // g.m.gsignal.stack.lo
355 MOV g, (S4)
356
357 JALR RA, A7
358
359 MOV ZERO, (S4)
360 JMP finish
361
362 nosaveg:
363 JALR RA, A7
364
365 finish:
366 MOV 8(X2), T0 // sec
367 MOV 16(X2), T1 // nsec
368 // restore stack
369 MOV S2, X2
370 MOV 24(X2), T2
371 MOV T2, m_vdsoPC(S3)
372
373 MOV 32(X2), T2
374 MOV T2, m_vdsoSP(S3)
375 // sec is in T0, nsec in T1
376 // return nsec in T0
377 MOV $1000000000, T2
378 MUL T2, T0
379 ADD T1, T0
380 MOV T0, ret+0(FP)
381 RET
382
383 fallback:
384 MOV $8(X2), A1
385 MOV $SYS_clock_gettime, A7
386 ECALL
387 MOV 8(X2), T0 // sec
388 MOV 16(X2), T1 // nsec
389 MOV $1000000000, T2
390 MUL T2, T0
391 ADD T1, T0
392 MOV T0, ret+0(FP)
393 RET
394
395 // func rtsigprocmask(how int32, new, old *sigset, size int32)
396 TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
397 MOVW how+0(FP), A0
398 MOV new+8(FP), A1
399 MOV old+16(FP), A2
400 MOVW size+24(FP), A3
401 MOV $SYS_rt_sigprocmask, A7
402 ECALL
403 MOV $-4096, T0
404 BLTU A0, T0, 2(PC)
405 WORD $0 // crash
406 RET
407
408 // func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32
409 TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
410 MOV sig+0(FP), A0
411 MOV new+8(FP), A1
412 MOV old+16(FP), A2
413 MOV size+24(FP), A3
414 MOV $SYS_rt_sigaction, A7
415 ECALL
416 MOVW A0, ret+32(FP)
417 RET
418
419 // func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
420 TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
421 MOVW sig+8(FP), A0
422 MOV info+16(FP), A1
423 MOV ctx+24(FP), A2
424 MOV fn+0(FP), T1
425 JALR RA, T1
426 RET
427
428 // func sigtramp(signo, ureg, ctxt unsafe.Pointer)
429 TEXT runtime·sigtramp(SB),NOSPLIT,$64
430 MOVW A0, 8(X2)
431 MOV A1, 16(X2)
432 MOV A2, 24(X2)
433
434 // this might be called in external code context,
435 // where g is not set.
436 MOVBU runtime·iscgo(SB), A0
437 BEQ A0, ZERO, 2(PC)
438 CALL runtime·load_g(SB)
439
440 MOV $runtime·sigtrampgo(SB), A0
441 JALR RA, A0
442 RET
443
444 // func cgoSigtramp()
445 TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
446 MOV $runtime·sigtramp(SB), T1
447 JALR ZERO, T1
448
449 // func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int)
450 TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
451 MOV addr+0(FP), A0
452 MOV n+8(FP), A1
453 MOVW prot+16(FP), A2
454 MOVW flags+20(FP), A3
455 MOVW fd+24(FP), A4
456 MOVW off+28(FP), A5
457 MOV $SYS_mmap, A7
458 ECALL
459 MOV $-4096, T0
460 BGEU T0, A0, 5(PC)
461 SUB A0, ZERO, A0
462 MOV ZERO, p+32(FP)
463 MOV A0, err+40(FP)
464 RET
465 ok:
466 MOV A0, p+32(FP)
467 MOV ZERO, err+40(FP)
468 RET
469
470 // func munmap(addr unsafe.Pointer, n uintptr)
471 TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
472 MOV addr+0(FP), A0
473 MOV n+8(FP), A1
474 MOV $SYS_munmap, A7
475 ECALL
476 MOV $-4096, T0
477 BLTU A0, T0, 2(PC)
478 WORD $0 // crash
479 RET
480
481 // func madvise(addr unsafe.Pointer, n uintptr, flags int32)
482 TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
483 MOV addr+0(FP), A0
484 MOV n+8(FP), A1
485 MOVW flags+16(FP), A2
486 MOV $SYS_madvise, A7
487 ECALL
488 MOVW A0, ret+24(FP)
489 RET
490
491 // func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32
492 TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
493 MOV addr+0(FP), A0
494 MOVW op+8(FP), A1
495 MOVW val+12(FP), A2
496 MOV ts+16(FP), A3
497 MOV addr2+24(FP), A4
498 MOVW val3+32(FP), A5
499 MOV $SYS_futex, A7
500 ECALL
501 MOVW A0, ret+40(FP)
502 RET
503
504 // func clone(flags int32, stk, mp, gp, fn unsafe.Pointer) int32
505 TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
506 MOVW flags+0(FP), A0
507 MOV stk+8(FP), A1
508
509 // Copy mp, gp, fn off parent stack for use by child.
510 MOV mp+16(FP), T0
511 MOV gp+24(FP), T1
512 MOV fn+32(FP), T2
513
514 MOV T0, -8(A1)
515 MOV T1, -16(A1)
516 MOV T2, -24(A1)
517 MOV $1234, T0
518 MOV T0, -32(A1)
519
520 MOV $SYS_clone, A7
521 ECALL
522
523 // In parent, return.
524 BEQ ZERO, A0, child
525 MOVW ZERO, ret+40(FP)
526 RET
527
528 child:
529 // In child, on new stack.
530 MOV -32(X2), T0
531 MOV $1234, A0
532 BEQ A0, T0, good
533 WORD $0 // crash
534
535 good:
536 // Initialize m->procid to Linux tid
537 MOV $SYS_gettid, A7
538 ECALL
539
540 MOV -24(X2), T2 // fn
541 MOV -16(X2), T1 // g
542 MOV -8(X2), T0 // m
543
544 BEQ ZERO, T0, nog
545 BEQ ZERO, T1, nog
546
547 MOV A0, m_procid(T0)
548
549 // In child, set up new stack
550 MOV T0, g_m(T1)
551 MOV T1, g
552
553 nog:
554 // Call fn
555 JALR RA, T2
556
557 // It shouldn't return. If it does, exit this thread.
558 MOV $111, A0
559 MOV $SYS_exit, A7
560 ECALL
561 JMP -3(PC) // keep exiting
562
563 // func sigaltstack(new, old *stackt)
564 TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
565 MOV new+0(FP), A0
566 MOV old+8(FP), A1
567 MOV $SYS_sigaltstack, A7
568 ECALL
569 MOV $-4096, T0
570 BLTU A0, T0, 2(PC)
571 WORD $0 // crash
572 RET
573
574 // func osyield()
575 TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
576 MOV $SYS_sched_yield, A7
577 ECALL
578 RET
579
580 // func sched_getaffinity(pid, len uintptr, buf *uintptr) int32
581 TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
582 MOV pid+0(FP), A0
583 MOV len+8(FP), A1
584 MOV buf+16(FP), A2
585 MOV $SYS_sched_getaffinity, A7
586 ECALL
587 MOV A0, ret+24(FP)
588 RET
589
590 // func epollcreate(size int32) int32
591 TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
592 MOV $0, A0
593 MOV $SYS_epoll_create1, A7
594 ECALL
595 MOVW A0, ret+8(FP)
596 RET
597
598 // func epollcreate1(flags int32) int32
599 TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
600 MOVW flags+0(FP), A0
601 MOV $SYS_epoll_create1, A7
602 ECALL
603 MOVW A0, ret+8(FP)
604 RET
605
606 // func epollctl(epfd, op, fd int32, ev *epollevent) int32
607 TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
608 MOVW epfd+0(FP), A0
609 MOVW op+4(FP), A1
610 MOVW fd+8(FP), A2
611 MOV ev+16(FP), A3
612 MOV $SYS_epoll_ctl, A7
613 ECALL
614 MOVW A0, ret+24(FP)
615 RET
616
617 // func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32
618 TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
619 MOVW epfd+0(FP), A0
620 MOV ev+8(FP), A1
621 MOVW nev+16(FP), A2
622 MOVW timeout+20(FP), A3
623 MOV $0, A4
624 MOV $SYS_epoll_pwait, A7
625 ECALL
626 MOVW A0, ret+24(FP)
627 RET
628
629 // func closeonexec(int32)
630 TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
631 MOVW fd+0(FP), A0 // fd
632 MOV $2, A1 // F_SETFD
633 MOV $1, A2 // FD_CLOEXEC
634 MOV $SYS_fcntl, A7
635 ECALL
636 RET
637
638 // func runtime·setNonblock(int32 fd)
639 TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4
640 MOVW fd+0(FP), A0 // fd
641 MOV $3, A1 // F_GETFL
642 MOV $0, A2
643 MOV $SYS_fcntl, A7
644 ECALL
645 MOV $0x800, A2 // O_NONBLOCK
646 OR A0, A2
647 MOVW fd+0(FP), A0 // fd
648 MOV $4, A1 // F_SETFL
649 MOV $SYS_fcntl, A7
650 ECALL
651 RET
652
653 // func sbrk0() uintptr
654 TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
655 // Implemented as brk(NULL).
656 MOV $0, A0
657 MOV $SYS_brk, A7
658 ECALL
659 MOVW A0, ret+0(FP)
660 RET
661
View as plain text