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