Text file 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_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)
    54  TEXT runtime·exit<ABIInternal>(SB),NOSPLIT,$0
    55  	MOV	$SYS_exit_group, A7
    56  	ECALL
    57  	RET
    58  
    59  // func exitThread(wait *atomic.Uint32)
    60  TEXT 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
    72  TEXT 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
    86  TEXT 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
    97  TEXT 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
   103  TEXT 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)
   109  TEXT 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)
   118  TEXT 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
   134  TEXT runtime·gettid<ABIInternal>(SB),NOSPLIT,$0
   135  	MOV	$SYS_gettid, A7
   136  	ECALL
   137  	RET
   138  
   139  // func raise(sig uint32)
   140  TEXT 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)
   150  TEXT 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
   160  TEXT ·getpid<ABIInternal>(SB),NOSPLIT,$0
   161  	MOV	$SYS_getpid, A7
   162  	ECALL
   163  	RET
   164  
   165  // func tgkill(tgid, tid, sig int)
   166  TEXT ·tgkill<ABIInternal>(SB),NOSPLIT,$0
   167  	MOV	$SYS_tgkill, A7
   168  	ECALL
   169  	RET
   170  
   171  // func setitimer(mode int32, new, old *itimerval)
   172  TEXT 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
   178  TEXT 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
   184  TEXT 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
   190  TEXT 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
   196  TEXT runtime·mincore<ABIInternal>(SB),NOSPLIT,$0
   197  	MOV	$SYS_mincore, A7
   198  	ECALL
   199  	RET
   200  
   201  // func walltime() (sec int64, nsec int32)
   202  TEXT 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  
   226  noswitch:
   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  
   245  nosaveg:
   246  	JALR	RA, A7
   247  
   248  finish:
   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  
   263  fallback:
   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
   274  TEXT 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  
   298  noswitch:
   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  
   317  nosaveg:
   318  	JALR	RA, A7
   319  
   320  finish:
   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  
   338  fallback:
   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)
   351  TEXT 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
   364  TEXT 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)
   370  TEXT 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)
   379  TEXT 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()
   395  TEXT 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)
   400  TEXT 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
   415  ok:
   416  	MOV	A0, p+32(FP)
   417  	MOV	ZERO, err+40(FP)
   418  	RET
   419  
   420  // func munmap(addr unsafe.Pointer, n uintptr)
   421  TEXT 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)
   432  TEXT 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
   438  TEXT 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
   444  TEXT 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  
   467  child:
   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  
   474  good:
   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  
   492  nog:
   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)
   503  TEXT 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()
   514  TEXT 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
   520  TEXT runtime·sched_getaffinity<ABIInternal>(SB),NOSPLIT,$0
   521  	MOV	$SYS_sched_getaffinity, A7
   522  	ECALL
   523  	RET
   524  
   525  // func sbrk0() uintptr
   526  TEXT runtime·sbrk0<ABIInternal>(SB),NOSPLIT,$0
   527  	// Implemented as brk(NULL).
   528  	MOV	ZERO, A0
   529  	MOV	$SYS_brk, A7
   530  	ECALL
   531  	RET
   532  

View as plain text