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