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