summaryrefslogtreecommitdiffstats
path: root/src/runtime/sys_linux_riscv64.s
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:16:40 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:16:40 +0000
commit47ab3d4a42e9ab51c465c4322d2ec233f6324e6b (patch)
treea61a0ffd83f4a3def4b36e5c8e99630c559aa723 /src/runtime/sys_linux_riscv64.s
parentInitial commit. (diff)
downloadgolang-1.18-upstream.tar.xz
golang-1.18-upstream.zip
Adding upstream version 1.18.10.upstream/1.18.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/runtime/sys_linux_riscv64.s')
-rw-r--r--src/runtime/sys_linux_riscv64.s660
1 files changed, 660 insertions, 0 deletions
diff --git a/src/runtime/sys_linux_riscv64.s b/src/runtime/sys_linux_riscv64.s
new file mode 100644
index 0000000..8b1b26b
--- /dev/null
+++ b/src/runtime/sys_linux_riscv64.s
@@ -0,0 +1,660 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls and other sys.stuff for riscv64, Linux
+//
+
+#include "textflag.h"
+#include "go_asm.h"
+
+#define AT_FDCWD -100
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 1
+
+#define SYS_brk 214
+#define SYS_clock_gettime 113
+#define SYS_clone 220
+#define SYS_close 57
+#define SYS_connect 203
+#define SYS_epoll_create1 20
+#define SYS_epoll_ctl 21
+#define SYS_epoll_pwait 22
+#define SYS_exit 93
+#define SYS_exit_group 94
+#define SYS_faccessat 48
+#define SYS_fcntl 25
+#define SYS_futex 98
+#define SYS_getpid 172
+#define SYS_gettid 178
+#define SYS_gettimeofday 169
+#define SYS_kill 129
+#define SYS_madvise 233
+#define SYS_mincore 232
+#define SYS_mmap 222
+#define SYS_munmap 215
+#define SYS_nanosleep 101
+#define SYS_openat 56
+#define SYS_pipe2 59
+#define SYS_pselect6 72
+#define SYS_read 63
+#define SYS_rt_sigaction 134
+#define SYS_rt_sigprocmask 135
+#define SYS_rt_sigreturn 139
+#define SYS_sched_getaffinity 123
+#define SYS_sched_yield 124
+#define SYS_setitimer 103
+#define SYS_sigaltstack 132
+#define SYS_socket 198
+#define SYS_tgkill 131
+#define SYS_timer_create 107
+#define SYS_timer_delete 111
+#define SYS_timer_settime 110
+#define SYS_tkill 130
+#define SYS_write 64
+
+// func exit(code int32)
+TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0-4
+ MOVW code+0(FP), A0
+ MOV $SYS_exit_group, A7
+ ECALL
+ RET
+
+// func exitThread(wait *atomic.Uint32)
+TEXT runtime·exitThread(SB),NOSPLIT|NOFRAME,$0-8
+ MOV wait+0(FP), A0
+ // We're done using the stack.
+ FENCE
+ MOVW ZERO, (A0)
+ FENCE
+ MOV $0, A0 // exit code
+ MOV $SYS_exit, A7
+ ECALL
+ JMP 0(PC)
+
+// func open(name *byte, mode, perm int32) int32
+TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0-20
+ MOV $AT_FDCWD, A0
+ MOV name+0(FP), A1
+ MOVW mode+8(FP), A2
+ MOVW perm+12(FP), A3
+ MOV $SYS_openat, A7
+ ECALL
+ MOV $-4096, T0
+ BGEU T0, A0, 2(PC)
+ MOV $-1, A0
+ MOVW A0, ret+16(FP)
+ RET
+
+// func closefd(fd int32) int32
+TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0-12
+ MOVW fd+0(FP), A0
+ MOV $SYS_close, A7
+ ECALL
+ MOV $-4096, T0
+ BGEU T0, A0, 2(PC)
+ MOV $-1, A0
+ MOVW A0, ret+8(FP)
+ RET
+
+// func write1(fd uintptr, p unsafe.Pointer, n int32) int32
+TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0-28
+ MOV fd+0(FP), A0
+ MOV p+8(FP), A1
+ MOVW n+16(FP), A2
+ MOV $SYS_write, A7
+ ECALL
+ MOVW A0, ret+24(FP)
+ RET
+
+// func read(fd int32, p unsafe.Pointer, n int32) int32
+TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0-28
+ MOVW fd+0(FP), A0
+ MOV p+8(FP), A1
+ MOVW n+16(FP), A2
+ MOV $SYS_read, A7
+ ECALL
+ MOVW A0, ret+24(FP)
+ RET
+
+// func pipe() (r, w int32, errno int32)
+TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12
+ MOV $r+0(FP), A0
+ MOV ZERO, A1
+ MOV $SYS_pipe2, A7
+ ECALL
+ MOVW A0, errno+8(FP)
+ RET
+
+// func pipe2(flags int32) (r, w int32, errno int32)
+TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
+ MOV $r+8(FP), A0
+ MOVW flags+0(FP), A1
+ MOV $SYS_pipe2, A7
+ ECALL
+ MOVW A0, errno+16(FP)
+ RET
+
+// func usleep(usec uint32)
+TEXT runtime·usleep(SB),NOSPLIT,$24-4
+ MOVWU usec+0(FP), A0
+ MOV $1000, A1
+ MUL A1, A0, A0
+ MOV $1000000000, A1
+ DIV A1, A0, A2
+ MOV A2, 8(X2)
+ REM A1, A0, A3
+ MOV A3, 16(X2)
+ ADD $8, X2, A0
+ MOV ZERO, A1
+ MOV $SYS_nanosleep, A7
+ ECALL
+ RET
+
+// func gettid() uint32
+TEXT runtime·gettid(SB),NOSPLIT,$0-4
+ MOV $SYS_gettid, A7
+ ECALL
+ MOVW A0, ret+0(FP)
+ RET
+
+// func raise(sig uint32)
+TEXT runtime·raise(SB),NOSPLIT|NOFRAME,$0
+ MOV $SYS_gettid, A7
+ ECALL
+ // arg 1 tid - already in A0
+ MOVW sig+0(FP), A1 // arg 2
+ MOV $SYS_tkill, A7
+ ECALL
+ RET
+
+// func raiseproc(sig uint32)
+TEXT runtime·raiseproc(SB),NOSPLIT|NOFRAME,$0
+ MOV $SYS_getpid, A7
+ ECALL
+ // arg 1 pid - already in A0
+ MOVW sig+0(FP), A1 // arg 2
+ MOV $SYS_kill, A7
+ ECALL
+ RET
+
+// func getpid() int
+TEXT ·getpid(SB),NOSPLIT|NOFRAME,$0-8
+ MOV $SYS_getpid, A7
+ ECALL
+ MOV A0, ret+0(FP)
+ RET
+
+// func tgkill(tgid, tid, sig int)
+TEXT ·tgkill(SB),NOSPLIT|NOFRAME,$0-24
+ MOV tgid+0(FP), A0
+ MOV tid+8(FP), A1
+ MOV sig+16(FP), A2
+ MOV $SYS_tgkill, A7
+ ECALL
+ RET
+
+// func setitimer(mode int32, new, old *itimerval)
+TEXT runtime·setitimer(SB),NOSPLIT|NOFRAME,$0-24
+ MOVW mode+0(FP), A0
+ MOV new+8(FP), A1
+ MOV old+16(FP), A2
+ MOV $SYS_setitimer, A7
+ ECALL
+ RET
+
+// func timer_create(clockid int32, sevp *sigevent, timerid *int32) int32
+TEXT runtime·timer_create(SB),NOSPLIT,$0-28
+ MOVW clockid+0(FP), A0
+ MOV sevp+8(FP), A1
+ MOV timerid+16(FP), A2
+ MOV $SYS_timer_create, A7
+ ECALL
+ MOVW A0, ret+24(FP)
+ RET
+
+// func timer_settime(timerid int32, flags int32, new, old *itimerspec) int32
+TEXT runtime·timer_settime(SB),NOSPLIT,$0-28
+ MOVW timerid+0(FP), A0
+ MOVW flags+4(FP), A1
+ MOV new+8(FP), A2
+ MOV old+16(FP), A3
+ MOV $SYS_timer_settime, A7
+ ECALL
+ MOVW A0, ret+24(FP)
+ RET
+
+// func timer_delete(timerid int32) int32
+TEXT runtime·timer_delete(SB),NOSPLIT,$0-12
+ MOVW timerid+0(FP), A0
+ MOV $SYS_timer_delete, A7
+ ECALL
+ MOVW A0, ret+8(FP)
+ RET
+
+// func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
+TEXT runtime·mincore(SB),NOSPLIT|NOFRAME,$0-28
+ MOV addr+0(FP), A0
+ MOV n+8(FP), A1
+ MOV dst+16(FP), A2
+ MOV $SYS_mincore, A7
+ ECALL
+ MOVW A0, ret+24(FP)
+ RET
+
+// func walltime() (sec int64, nsec int32)
+TEXT runtime·walltime(SB),NOSPLIT,$40-12
+ MOV $CLOCK_REALTIME, A0
+
+ MOV runtime·vdsoClockgettimeSym(SB), A7
+ BEQZ A7, fallback
+ MOV X2, S2 // S2,S3,S4 is unchanged by C code
+ MOV g_m(g), S3 // S3 = m
+
+ // Save the old values on stack for reentrant
+ MOV m_vdsoPC(S3), T0
+ MOV T0, 24(X2)
+ MOV m_vdsoSP(S3), T0
+ MOV T0, 32(X2)
+
+ MOV RA, m_vdsoPC(S3)
+ MOV $ret-8(FP), T1 // caller's SP
+ MOV T1, m_vdsoSP(S3)
+
+ MOV m_curg(S3), T1
+ BNE g, T1, noswitch
+
+ MOV m_g0(S3), T1
+ MOV (g_sched+gobuf_sp)(T1), X2
+
+noswitch:
+ ADDI $-24, X2 // Space for result
+ ANDI $~7, X2 // Align for C code
+ MOV $8(X2), A1
+
+ // Store g on gsignal's stack, see sys_linux_arm64.s for detail
+ MOVBU runtime·iscgo(SB), S4
+ BNEZ S4, nosaveg
+ MOV m_gsignal(S3), S4 // g.m.gsignal
+ BEQZ S4, nosaveg
+ BEQ g, S4, nosaveg
+ MOV (g_stack+stack_lo)(S4), S4 // g.m.gsignal.stack.lo
+ MOV g, (S4)
+
+ JALR RA, A7
+
+ MOV ZERO, (S4)
+ JMP finish
+
+nosaveg:
+ JALR RA, A7
+
+finish:
+ MOV 8(X2), T0 // sec
+ MOV 16(X2), T1 // nsec
+
+ MOV S2, X2 // restore stack
+ MOV 24(X2), A2
+ MOV A2, m_vdsoPC(S3)
+
+ MOV 32(X2), A3
+ MOV A3, m_vdsoSP(S3)
+
+ MOV T0, sec+0(FP)
+ MOVW T1, nsec+8(FP)
+ RET
+
+fallback:
+ MOV $8(X2), A1
+ MOV $SYS_clock_gettime, A7
+ ECALL
+ MOV 8(X2), T0 // sec
+ MOV 16(X2), T1 // nsec
+ MOV T0, sec+0(FP)
+ MOVW T1, nsec+8(FP)
+ RET
+
+// func nanotime1() int64
+TEXT runtime·nanotime1(SB),NOSPLIT,$40-8
+ MOV $CLOCK_MONOTONIC, A0
+
+ MOV runtime·vdsoClockgettimeSym(SB), A7
+ BEQZ A7, fallback
+
+ MOV X2, S2 // S2 = RSP, S2 is unchanged by C code
+ MOV g_m(g), S3 // S3 = m
+ // Save the old values on stack for reentrant
+ MOV m_vdsoPC(S3), T0
+ MOV T0, 24(X2)
+ MOV m_vdsoSP(S3), T0
+ MOV T0, 32(X2)
+
+ MOV RA, m_vdsoPC(S3)
+ MOV $ret-8(FP), T0 // caller's SP
+ MOV T0, m_vdsoSP(S3)
+
+ MOV m_curg(S3), T1
+ BNE g, T1, noswitch
+
+ MOV m_g0(S3), T1
+ MOV (g_sched+gobuf_sp)(T1), X2
+
+noswitch:
+ ADDI $-24, X2 // Space for result
+ ANDI $~7, X2 // Align for C code
+ MOV $8(X2), A1
+
+ // Store g on gsignal's stack, see sys_linux_arm64.s for detail
+ MOVBU runtime·iscgo(SB), S4
+ BNEZ S4, nosaveg
+ MOV m_gsignal(S3), S4 // g.m.gsignal
+ BEQZ S4, nosaveg
+ BEQ g, S4, nosaveg
+ MOV (g_stack+stack_lo)(S4), S4 // g.m.gsignal.stack.lo
+ MOV g, (S4)
+
+ JALR RA, A7
+
+ MOV ZERO, (S4)
+ JMP finish
+
+nosaveg:
+ JALR RA, A7
+
+finish:
+ MOV 8(X2), T0 // sec
+ MOV 16(X2), T1 // nsec
+ // restore stack
+ MOV S2, X2
+ MOV 24(X2), T2
+ MOV T2, m_vdsoPC(S3)
+
+ MOV 32(X2), T2
+ MOV T2, m_vdsoSP(S3)
+ // sec is in T0, nsec in T1
+ // return nsec in T0
+ MOV $1000000000, T2
+ MUL T2, T0
+ ADD T1, T0
+ MOV T0, ret+0(FP)
+ RET
+
+fallback:
+ MOV $8(X2), A1
+ MOV $SYS_clock_gettime, A7
+ ECALL
+ MOV 8(X2), T0 // sec
+ MOV 16(X2), T1 // nsec
+ MOV $1000000000, T2
+ MUL T2, T0
+ ADD T1, T0
+ MOV T0, ret+0(FP)
+ RET
+
+// func rtsigprocmask(how int32, new, old *sigset, size int32)
+TEXT runtime·rtsigprocmask(SB),NOSPLIT|NOFRAME,$0-28
+ MOVW how+0(FP), A0
+ MOV new+8(FP), A1
+ MOV old+16(FP), A2
+ MOVW size+24(FP), A3
+ MOV $SYS_rt_sigprocmask, A7
+ ECALL
+ MOV $-4096, T0
+ BLTU A0, T0, 2(PC)
+ WORD $0 // crash
+ RET
+
+// func rt_sigaction(sig uintptr, new, old *sigactiont, size uintptr) int32
+TEXT runtime·rt_sigaction(SB),NOSPLIT|NOFRAME,$0-36
+ MOV sig+0(FP), A0
+ MOV new+8(FP), A1
+ MOV old+16(FP), A2
+ MOV size+24(FP), A3
+ MOV $SYS_rt_sigaction, A7
+ ECALL
+ MOVW A0, ret+32(FP)
+ RET
+
+// func sigfwd(fn uintptr, sig uint32, info *siginfo, ctx unsafe.Pointer)
+TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
+ MOVW sig+8(FP), A0
+ MOV info+16(FP), A1
+ MOV ctx+24(FP), A2
+ MOV fn+0(FP), T1
+ JALR RA, T1
+ RET
+
+// func sigtramp(signo, ureg, ctxt unsafe.Pointer)
+TEXT runtime·sigtramp(SB),NOSPLIT,$64
+ MOVW A0, 8(X2)
+ MOV A1, 16(X2)
+ MOV A2, 24(X2)
+
+ // this might be called in external code context,
+ // where g is not set.
+ MOVBU runtime·iscgo(SB), A0
+ BEQ A0, ZERO, 2(PC)
+ CALL runtime·load_g(SB)
+
+ MOV $runtime·sigtrampgo(SB), A0
+ JALR RA, A0
+ RET
+
+// func cgoSigtramp()
+TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
+ MOV $runtime·sigtramp(SB), T1
+ JALR ZERO, T1
+
+// func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int)
+TEXT runtime·mmap(SB),NOSPLIT|NOFRAME,$0
+ MOV addr+0(FP), A0
+ MOV n+8(FP), A1
+ MOVW prot+16(FP), A2
+ MOVW flags+20(FP), A3
+ MOVW fd+24(FP), A4
+ MOVW off+28(FP), A5
+ MOV $SYS_mmap, A7
+ ECALL
+ MOV $-4096, T0
+ BGEU T0, A0, 5(PC)
+ SUB A0, ZERO, A0
+ MOV ZERO, p+32(FP)
+ MOV A0, err+40(FP)
+ RET
+ok:
+ MOV A0, p+32(FP)
+ MOV ZERO, err+40(FP)
+ RET
+
+// func munmap(addr unsafe.Pointer, n uintptr)
+TEXT runtime·munmap(SB),NOSPLIT|NOFRAME,$0
+ MOV addr+0(FP), A0
+ MOV n+8(FP), A1
+ MOV $SYS_munmap, A7
+ ECALL
+ MOV $-4096, T0
+ BLTU A0, T0, 2(PC)
+ WORD $0 // crash
+ RET
+
+// func madvise(addr unsafe.Pointer, n uintptr, flags int32)
+TEXT runtime·madvise(SB),NOSPLIT|NOFRAME,$0
+ MOV addr+0(FP), A0
+ MOV n+8(FP), A1
+ MOVW flags+16(FP), A2
+ MOV $SYS_madvise, A7
+ ECALL
+ MOVW A0, ret+24(FP)
+ RET
+
+// func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32
+TEXT runtime·futex(SB),NOSPLIT|NOFRAME,$0
+ MOV addr+0(FP), A0
+ MOVW op+8(FP), A1
+ MOVW val+12(FP), A2
+ MOV ts+16(FP), A3
+ MOV addr2+24(FP), A4
+ MOVW val3+32(FP), A5
+ MOV $SYS_futex, A7
+ ECALL
+ MOVW A0, ret+40(FP)
+ RET
+
+// func clone(flags int32, stk, mp, gp, fn unsafe.Pointer) int32
+TEXT runtime·clone(SB),NOSPLIT|NOFRAME,$0
+ MOVW flags+0(FP), A0
+ MOV stk+8(FP), A1
+
+ // Copy mp, gp, fn off parent stack for use by child.
+ MOV mp+16(FP), T0
+ MOV gp+24(FP), T1
+ MOV fn+32(FP), T2
+
+ MOV T0, -8(A1)
+ MOV T1, -16(A1)
+ MOV T2, -24(A1)
+ MOV $1234, T0
+ MOV T0, -32(A1)
+
+ MOV $SYS_clone, A7
+ ECALL
+
+ // In parent, return.
+ BEQ ZERO, A0, child
+ MOVW ZERO, ret+40(FP)
+ RET
+
+child:
+ // In child, on new stack.
+ MOV -32(X2), T0
+ MOV $1234, A0
+ BEQ A0, T0, good
+ WORD $0 // crash
+
+good:
+ // Initialize m->procid to Linux tid
+ MOV $SYS_gettid, A7
+ ECALL
+
+ MOV -24(X2), T2 // fn
+ MOV -16(X2), T1 // g
+ MOV -8(X2), T0 // m
+
+ BEQ ZERO, T0, nog
+ BEQ ZERO, T1, nog
+
+ MOV A0, m_procid(T0)
+
+ // In child, set up new stack
+ MOV T0, g_m(T1)
+ MOV T1, g
+
+nog:
+ // Call fn
+ JALR RA, T2
+
+ // It shouldn't return. If it does, exit this thread.
+ MOV $111, A0
+ MOV $SYS_exit, A7
+ ECALL
+ JMP -3(PC) // keep exiting
+
+// func sigaltstack(new, old *stackt)
+TEXT runtime·sigaltstack(SB),NOSPLIT|NOFRAME,$0
+ MOV new+0(FP), A0
+ MOV old+8(FP), A1
+ MOV $SYS_sigaltstack, A7
+ ECALL
+ MOV $-4096, T0
+ BLTU A0, T0, 2(PC)
+ WORD $0 // crash
+ RET
+
+// func osyield()
+TEXT runtime·osyield(SB),NOSPLIT|NOFRAME,$0
+ MOV $SYS_sched_yield, A7
+ ECALL
+ RET
+
+// func sched_getaffinity(pid, len uintptr, buf *uintptr) int32
+TEXT runtime·sched_getaffinity(SB),NOSPLIT|NOFRAME,$0
+ MOV pid+0(FP), A0
+ MOV len+8(FP), A1
+ MOV buf+16(FP), A2
+ MOV $SYS_sched_getaffinity, A7
+ ECALL
+ MOV A0, ret+24(FP)
+ RET
+
+// func epollcreate(size int32) int32
+TEXT runtime·epollcreate(SB),NOSPLIT|NOFRAME,$0
+ MOV $0, A0
+ MOV $SYS_epoll_create1, A7
+ ECALL
+ MOVW A0, ret+8(FP)
+ RET
+
+// func epollcreate1(flags int32) int32
+TEXT runtime·epollcreate1(SB),NOSPLIT|NOFRAME,$0
+ MOVW flags+0(FP), A0
+ MOV $SYS_epoll_create1, A7
+ ECALL
+ MOVW A0, ret+8(FP)
+ RET
+
+// func epollctl(epfd, op, fd int32, ev *epollevent) int32
+TEXT runtime·epollctl(SB),NOSPLIT|NOFRAME,$0
+ MOVW epfd+0(FP), A0
+ MOVW op+4(FP), A1
+ MOVW fd+8(FP), A2
+ MOV ev+16(FP), A3
+ MOV $SYS_epoll_ctl, A7
+ ECALL
+ MOVW A0, ret+24(FP)
+ RET
+
+// func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32
+TEXT runtime·epollwait(SB),NOSPLIT|NOFRAME,$0
+ MOVW epfd+0(FP), A0
+ MOV ev+8(FP), A1
+ MOVW nev+16(FP), A2
+ MOVW timeout+20(FP), A3
+ MOV $0, A4
+ MOV $SYS_epoll_pwait, A7
+ ECALL
+ MOVW A0, ret+24(FP)
+ RET
+
+// func closeonexec(int32)
+TEXT runtime·closeonexec(SB),NOSPLIT|NOFRAME,$0
+ MOVW fd+0(FP), A0 // fd
+ MOV $2, A1 // F_SETFD
+ MOV $1, A2 // FD_CLOEXEC
+ MOV $SYS_fcntl, A7
+ ECALL
+ RET
+
+// func runtime·setNonblock(int32 fd)
+TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4
+ MOVW fd+0(FP), A0 // fd
+ MOV $3, A1 // F_GETFL
+ MOV $0, A2
+ MOV $SYS_fcntl, A7
+ ECALL
+ MOV $0x800, A2 // O_NONBLOCK
+ OR A0, A2
+ MOVW fd+0(FP), A0 // fd
+ MOV $4, A1 // F_SETFL
+ MOV $SYS_fcntl, A7
+ ECALL
+ RET
+
+// func sbrk0() uintptr
+TEXT runtime·sbrk0(SB),NOSPLIT,$0-8
+ // Implemented as brk(NULL).
+ MOV $0, A0
+ MOV $SYS_brk, A7
+ ECALL
+ MOVW A0, ret+0(FP)
+ RET