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