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

View as plain text