github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/runtime/sys_openbsd_arm64.s (about)

     1  // Copyright 2019 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  // System calls and other sys.stuff for arm64, OpenBSD
     6  // System calls are implemented in libc/libpthread, this file
     7  // contains trampolines that convert from Go to C calling convention.
     8  // Some direct system call implementations currently remain.
     9  //
    10  
    11  #include "go_asm.h"
    12  #include "go_tls.h"
    13  #include "textflag.h"
    14  
    15  #define CLOCK_REALTIME	$0
    16  #define	CLOCK_MONOTONIC	$3
    17  
    18  // With OpenBSD 6.7 onwards, an arm64 syscall returns two instructions
    19  // after the SVC instruction, to allow for a speculative execution
    20  // barrier to be placed after the SVC without impacting performance.
    21  // For now use hardware no-ops as this works with both older and newer
    22  // kernels. After OpenBSD 6.8 is released this should be changed to
    23  // speculation barriers.
    24  #define	INVOKE_SYSCALL	\
    25  	SVC;		\
    26  	NOOP;		\
    27  	NOOP
    28  
    29  // mstart_stub is the first function executed on a new thread started by pthread_create.
    30  // It just does some low-level setup and then calls mstart.
    31  // Note: called with the C calling convention.
    32  TEXT runtime·mstart_stub(SB),NOSPLIT,$160
    33  	// R0 points to the m.
    34  	// We are already on m's g0 stack.
    35  
    36  	// Save callee-save registers.
    37  	MOVD	R19, 8(RSP)
    38  	MOVD	R20, 16(RSP)
    39  	MOVD	R21, 24(RSP)
    40  	MOVD	R22, 32(RSP)
    41  	MOVD	R23, 40(RSP)
    42  	MOVD	R24, 48(RSP)
    43  	MOVD	R25, 56(RSP)
    44  	MOVD	R26, 64(RSP)
    45  	MOVD	R27, 72(RSP)
    46  	MOVD	g, 80(RSP)
    47  	MOVD	R29, 88(RSP)
    48  	FMOVD	F8, 96(RSP)
    49  	FMOVD	F9, 104(RSP)
    50  	FMOVD	F10, 112(RSP)
    51  	FMOVD	F11, 120(RSP)
    52  	FMOVD	F12, 128(RSP)
    53  	FMOVD	F13, 136(RSP)
    54  	FMOVD	F14, 144(RSP)
    55  	FMOVD	F15, 152(RSP)
    56  
    57  	MOVD    m_g0(R0), g
    58  	BL	runtime·save_g(SB)
    59  
    60  	BL	runtime·mstart(SB)
    61  
    62  	// Restore callee-save registers.
    63  	MOVD	8(RSP), R19
    64  	MOVD	16(RSP), R20
    65  	MOVD	24(RSP), R21
    66  	MOVD	32(RSP), R22
    67  	MOVD	40(RSP), R23
    68  	MOVD	48(RSP), R24
    69  	MOVD	56(RSP), R25
    70  	MOVD	64(RSP), R26
    71  	MOVD	72(RSP), R27
    72  	MOVD	80(RSP), g
    73  	MOVD	88(RSP), R29
    74  	FMOVD	96(RSP), F8
    75  	FMOVD	104(RSP), F9
    76  	FMOVD	112(RSP), F10
    77  	FMOVD	120(RSP), F11
    78  	FMOVD	128(RSP), F12
    79  	FMOVD	136(RSP), F13
    80  	FMOVD	144(RSP), F14
    81  	FMOVD	152(RSP), F15
    82  
    83  	// Go is all done with this OS thread.
    84  	// Tell pthread everything is ok (we never join with this thread, so
    85  	// the value here doesn't really matter).
    86  	MOVD	$0, R0
    87  
    88  	RET
    89  
    90  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
    91  	MOVW	sig+8(FP), R0
    92  	MOVD	info+16(FP), R1
    93  	MOVD	ctx+24(FP), R2
    94  	MOVD	fn+0(FP), R11
    95  	BL	(R11)			// Alignment for ELF ABI?
    96  	RET
    97  
    98  TEXT runtime·sigtramp(SB),NOSPLIT,$192
    99  	// Save callee-save registers in the case of signal forwarding.
   100  	// Please refer to https://golang.org/issue/31827 .
   101  	MOVD	R19, 8*4(RSP)
   102  	MOVD	R20, 8*5(RSP)
   103  	MOVD	R21, 8*6(RSP)
   104  	MOVD	R22, 8*7(RSP)
   105  	MOVD	R23, 8*8(RSP)
   106  	MOVD	R24, 8*9(RSP)
   107  	MOVD	R25, 8*10(RSP)
   108  	MOVD	R26, 8*11(RSP)
   109  	MOVD	R27, 8*12(RSP)
   110  	MOVD	g, 8*13(RSP)
   111  	MOVD	R29, 8*14(RSP)
   112  	FMOVD	F8, 8*15(RSP)
   113  	FMOVD	F9, 8*16(RSP)
   114  	FMOVD	F10, 8*17(RSP)
   115  	FMOVD	F11, 8*18(RSP)
   116  	FMOVD	F12, 8*19(RSP)
   117  	FMOVD	F13, 8*20(RSP)
   118  	FMOVD	F14, 8*21(RSP)
   119  	FMOVD	F15, 8*22(RSP)
   120  
   121  	// If called from an external code context, g will not be set.
   122  	// Save R0, since runtime·load_g will clobber it.
   123  	MOVW	R0, 8(RSP)		// signum
   124  	BL	runtime·load_g(SB)
   125  
   126  	MOVD	R1, 16(RSP)
   127  	MOVD	R2, 24(RSP)
   128  	BL	runtime·sigtrampgo(SB)
   129  
   130  	// Restore callee-save registers.
   131  	MOVD	8*4(RSP), R19
   132  	MOVD	8*5(RSP), R20
   133  	MOVD	8*6(RSP), R21
   134  	MOVD	8*7(RSP), R22
   135  	MOVD	8*8(RSP), R23
   136  	MOVD	8*9(RSP), R24
   137  	MOVD	8*10(RSP), R25
   138  	MOVD	8*11(RSP), R26
   139  	MOVD	8*12(RSP), R27
   140  	MOVD	8*13(RSP), g
   141  	MOVD	8*14(RSP), R29
   142  	FMOVD	8*15(RSP), F8
   143  	FMOVD	8*16(RSP), F9
   144  	FMOVD	8*17(RSP), F10
   145  	FMOVD	8*18(RSP), F11
   146  	FMOVD	8*19(RSP), F12
   147  	FMOVD	8*20(RSP), F13
   148  	FMOVD	8*21(RSP), F14
   149  	FMOVD	8*22(RSP), F15
   150  
   151  	RET
   152  
   153  //
   154  // These trampolines help convert from Go calling convention to C calling convention.
   155  // They should be called with asmcgocall.
   156  // A pointer to the arguments is passed in R0.
   157  // A single int32 result is returned in R0.
   158  // (For more results, make an args/results structure.)
   159  TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
   160  	MOVD	0(R0), R0		// arg 1 - attr
   161  	CALL	libc_pthread_attr_init(SB)
   162  	RET
   163  
   164  TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
   165  	MOVD	0(R0), R0		// arg 1 - attr
   166  	CALL	libc_pthread_attr_destroy(SB)
   167  	RET
   168  
   169  TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
   170  	MOVD	8(R0), R1		// arg 2 - size
   171  	MOVD	0(R0), R0		// arg 1 - attr
   172  	CALL	libc_pthread_attr_getstacksize(SB)
   173  	RET
   174  
   175  TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
   176  	MOVD	8(R0), R1		// arg 2 - state
   177  	MOVD	0(R0), R0		// arg 1 - attr
   178  	CALL	libc_pthread_attr_setdetachstate(SB)
   179  	RET
   180  
   181  TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
   182  	MOVD	0(R0), R1		// arg 2 - attr
   183  	MOVD	8(R0), R2		// arg 3 - start
   184  	MOVD	16(R0), R3		// arg 4 - arg
   185  	SUB	$16, RSP
   186  	MOVD	RSP, R0			// arg 1 - &threadid (discard)
   187  	CALL	libc_pthread_create(SB)
   188  	ADD	$16, RSP
   189  	RET
   190  
   191  // Exit the entire program (like C exit)
   192  TEXT runtime·exit(SB),NOSPLIT|NOFRAME,$0
   193  	MOVW	code+0(FP), R0		// arg 1 - status
   194  	MOVD	$1, R8			// sys_exit
   195  	INVOKE_SYSCALL
   196  	BCC	3(PC)
   197  	MOVD	$0, R0			// crash on syscall failure
   198  	MOVD	R0, (R0)
   199  	RET
   200  
   201  // func exitThread(wait *uint32)
   202  TEXT runtime·exitThread(SB),NOSPLIT,$0
   203  	MOVD	wait+0(FP), R0		// arg 1 - notdead
   204  	MOVD	$302, R8		// sys___threxit
   205  	INVOKE_SYSCALL
   206  	MOVD	$0, R0			// crash on syscall failure
   207  	MOVD	R0, (R0)
   208  	JMP	0(PC)
   209  
   210  TEXT runtime·open(SB),NOSPLIT|NOFRAME,$0
   211  	MOVD	name+0(FP), R0		// arg 1 - path
   212  	MOVW	mode+8(FP), R1		// arg 2 - mode
   213  	MOVW	perm+12(FP), R2		// arg 3 - perm
   214  	MOVD	$5, R8			// sys_open
   215  	INVOKE_SYSCALL
   216  	BCC	2(PC)
   217  	MOVW	$-1, R0
   218  	MOVW	R0, ret+16(FP)
   219  	RET
   220  
   221  TEXT runtime·closefd(SB),NOSPLIT|NOFRAME,$0
   222  	MOVW	fd+0(FP), R0		// arg 1 - fd
   223  	MOVD	$6, R8			// sys_close
   224  	INVOKE_SYSCALL
   225  	BCC	2(PC)
   226  	MOVW	$-1, R0
   227  	MOVW	R0, ret+8(FP)
   228  	RET
   229  
   230  TEXT runtime·read(SB),NOSPLIT|NOFRAME,$0
   231  	MOVW	fd+0(FP), R0		// arg 1 - fd
   232  	MOVD	p+8(FP), R1		// arg 2 - buf
   233  	MOVW	n+16(FP), R2		// arg 3 - nbyte
   234  	MOVD	$3, R8			// sys_read
   235  	INVOKE_SYSCALL
   236  	BCC	2(PC)
   237  	NEG	R0, R0
   238  	MOVW	R0, ret+24(FP)
   239  	RET
   240  
   241  // func pipe() (r, w int32, errno int32)
   242  TEXT runtime·pipe(SB),NOSPLIT|NOFRAME,$0-12
   243  	MOVD	$r+0(FP), R0
   244  	MOVW	$0, R1
   245  	MOVD	$101, R8		// sys_pipe2
   246  	INVOKE_SYSCALL
   247  	BCC	2(PC)
   248  	NEG	R0, R0
   249  	MOVW	R0, errno+8(FP)
   250  	RET
   251  
   252  // func pipe2(flags int32) (r, w int32, errno int32)
   253  TEXT runtime·pipe2(SB),NOSPLIT|NOFRAME,$0-20
   254  	MOVD	$r+8(FP), R0
   255  	MOVW	flags+0(FP), R1
   256  	MOVD	$101, R8		// sys_pipe2
   257  	INVOKE_SYSCALL
   258  	BCC	2(PC)
   259  	NEG	R0, R0
   260  	MOVW	R0, errno+16(FP)
   261  	RET
   262  
   263  TEXT runtime·write1(SB),NOSPLIT|NOFRAME,$0
   264  	MOVD	fd+0(FP), R0		// arg 1 - fd
   265  	MOVD	p+8(FP), R1		// arg 2 - buf
   266  	MOVW	n+16(FP), R2		// arg 3 - nbyte
   267  	MOVD	$4, R8			// sys_write
   268  	INVOKE_SYSCALL
   269  	BCC	2(PC)
   270  	NEG	R0, R0
   271  	MOVW	R0, ret+24(FP)
   272  	RET
   273  
   274  TEXT runtime·usleep(SB),NOSPLIT,$24-4
   275  	MOVWU	usec+0(FP), R3
   276  	MOVD	R3, R5
   277  	MOVW	$1000000, R4
   278  	UDIV	R4, R3
   279  	MOVD	R3, 8(RSP)		// tv_sec
   280  	MUL	R3, R4
   281  	SUB	R4, R5
   282  	MOVW	$1000, R4
   283  	MUL	R4, R5
   284  	MOVD	R5, 16(RSP)		// tv_nsec
   285  
   286  	ADD	$8, RSP, R0		// arg 1 - rqtp
   287  	MOVD	$0, R1			// arg 2 - rmtp
   288  	MOVD	$91, R8			// sys_nanosleep
   289  	INVOKE_SYSCALL
   290  	RET
   291  
   292  TEXT runtime·getthrid(SB),NOSPLIT,$0-4
   293  	MOVD	$299, R8		// sys_getthrid
   294  	INVOKE_SYSCALL
   295  	MOVW	R0, ret+0(FP)
   296  	RET
   297  
   298  TEXT runtime·thrkill(SB),NOSPLIT,$0-16
   299  	MOVW	tid+0(FP), R0		// arg 1 - tid
   300  	MOVD	sig+8(FP), R1		// arg 2 - signum
   301  	MOVW	$0, R2			// arg 3 - tcb
   302  	MOVD	$119, R8		// sys_thrkill
   303  	INVOKE_SYSCALL
   304  	RET
   305  
   306  TEXT runtime·raiseproc(SB),NOSPLIT,$0
   307  	MOVD	$20, R8			// sys_getpid
   308  	INVOKE_SYSCALL
   309  					// arg 1 - pid, already in R0
   310  	MOVW	sig+0(FP), R1		// arg 2 - signum
   311  	MOVD	$122, R8		// sys_kill
   312  	INVOKE_SYSCALL
   313  	RET
   314  
   315  TEXT runtime·mmap(SB),NOSPLIT,$0
   316  	MOVD	addr+0(FP), R0		// arg 1 - addr
   317  	MOVD	n+8(FP), R1		// arg 2 - len
   318  	MOVW	prot+16(FP), R2		// arg 3 - prot
   319  	MOVW	flags+20(FP), R3	// arg 4 - flags
   320  	MOVW	fd+24(FP), R4		// arg 5 - fd
   321  	MOVW	$0, R5			// arg 6 - pad
   322  	MOVW	off+28(FP), R6		// arg 7 - offset
   323  	MOVD	$197, R8		// sys_mmap
   324  	INVOKE_SYSCALL
   325  	MOVD	$0, R1
   326  	BCC	3(PC)
   327  	MOVD	R0, R1			// if error, move to R1
   328  	MOVD	$0, R0
   329  	MOVD	R0, p+32(FP)
   330  	MOVD	R1, err+40(FP)
   331  	RET
   332  
   333  TEXT runtime·munmap(SB),NOSPLIT,$0
   334  	MOVD	addr+0(FP), R0		// arg 1 - addr
   335  	MOVD	n+8(FP), R1		// arg 2 - len
   336  	MOVD	$73, R8			// sys_munmap
   337  	INVOKE_SYSCALL
   338  	BCC	3(PC)
   339  	MOVD	$0, R0			// crash on syscall failure
   340  	MOVD	R0, (R0)
   341  	RET
   342  
   343  TEXT runtime·madvise(SB),NOSPLIT,$0
   344  	MOVD	addr+0(FP), R0		// arg 1 - addr
   345  	MOVD	n+8(FP), R1		// arg 2 - len
   346  	MOVW	flags+16(FP), R2	// arg 2 - flags
   347  	MOVD	$75, R8			// sys_madvise
   348  	INVOKE_SYSCALL
   349  	BCC	2(PC)
   350  	MOVW	$-1, R0
   351  	MOVW	R0, ret+24(FP)
   352  	RET
   353  
   354  TEXT runtime·setitimer(SB),NOSPLIT,$0
   355  	MOVW	mode+0(FP), R0		// arg 1 - mode
   356  	MOVD	new+8(FP), R1		// arg 2 - new value
   357  	MOVD	old+16(FP), R2		// arg 3 - old value
   358  	MOVD	$69, R8			// sys_setitimer
   359  	INVOKE_SYSCALL
   360  	RET
   361  
   362  // func walltime1() (sec int64, nsec int32)
   363  TEXT runtime·walltime1(SB), NOSPLIT, $32
   364  	MOVW	CLOCK_REALTIME, R0	// arg 1 - clock_id
   365  	MOVD	$8(RSP), R1		// arg 2 - tp
   366  	MOVD	$87, R8			// sys_clock_gettime
   367  	INVOKE_SYSCALL
   368  
   369  	MOVD	8(RSP), R0		// sec
   370  	MOVD	16(RSP), R1		// nsec
   371  	MOVD	R0, sec+0(FP)
   372  	MOVW	R1, nsec+8(FP)
   373  
   374  	RET
   375  
   376  // int64 nanotime1(void) so really
   377  // void nanotime1(int64 *nsec)
   378  TEXT runtime·nanotime1(SB),NOSPLIT,$32
   379  	MOVW	CLOCK_MONOTONIC, R0	// arg 1 - clock_id
   380  	MOVD	$8(RSP), R1		// arg 2 - tp
   381  	MOVD	$87, R8			// sys_clock_gettime
   382  	INVOKE_SYSCALL
   383  
   384  	MOVW	8(RSP), R3		// sec
   385  	MOVW	16(RSP), R5		// nsec
   386  
   387  	MOVD	$1000000000, R4
   388  	MUL	R4, R3
   389  	ADD	R5, R3
   390  	MOVD	R3, ret+0(FP)
   391  	RET
   392  
   393  TEXT runtime·sigaction(SB),NOSPLIT,$0
   394  	MOVW	sig+0(FP), R0		// arg 1 - signum
   395  	MOVD	new+8(FP), R1		// arg 2 - new sigaction
   396  	MOVD	old+16(FP), R2		// arg 3 - old sigaction
   397  	MOVD	$46, R8			// sys_sigaction
   398  	INVOKE_SYSCALL
   399  	BCC	3(PC)
   400  	MOVD	$3, R0			// crash on syscall failure
   401  	MOVD	R0, (R0)
   402  	RET
   403  
   404  TEXT runtime·obsdsigprocmask(SB),NOSPLIT,$0
   405  	MOVW	how+0(FP), R0		// arg 1 - mode
   406  	MOVW	new+4(FP), R1		// arg 2 - new
   407  	MOVD	$48, R8			// sys_sigprocmask
   408  	INVOKE_SYSCALL
   409  	BCC	3(PC)
   410  	MOVD	$3, R8			// crash on syscall failure
   411  	MOVD	R8, (R8)
   412  	MOVW	R0, ret+8(FP)
   413  	RET
   414  
   415  TEXT runtime·sigaltstack(SB),NOSPLIT,$0
   416  	MOVD	new+0(FP), R0		// arg 1 - new sigaltstack
   417  	MOVD	old+8(FP), R1		// arg 2 - old sigaltstack
   418  	MOVD	$288, R8		// sys_sigaltstack
   419  	INVOKE_SYSCALL
   420  	BCC	3(PC)
   421  	MOVD	$0, R8			// crash on syscall failure
   422  	MOVD	R8, (R8)
   423  	RET
   424  
   425  TEXT runtime·osyield(SB),NOSPLIT,$0
   426  	MOVD	$298, R8		// sys_sched_yield
   427  	INVOKE_SYSCALL
   428  	RET
   429  
   430  TEXT runtime·thrsleep(SB),NOSPLIT,$0
   431  	MOVD	ident+0(FP), R0		// arg 1 - ident
   432  	MOVW	clock_id+8(FP), R1	// arg 2 - clock_id
   433  	MOVD	tsp+16(FP), R2		// arg 3 - tsp
   434  	MOVD	lock+24(FP), R3		// arg 4 - lock
   435  	MOVD	abort+32(FP), R4	// arg 5 - abort
   436  	MOVD	$94, R8			// sys___thrsleep
   437  	INVOKE_SYSCALL
   438  	MOVW	R0, ret+40(FP)
   439  	RET
   440  
   441  TEXT runtime·thrwakeup(SB),NOSPLIT,$0
   442  	MOVD	ident+0(FP), R0		// arg 1 - ident
   443  	MOVW	n+8(FP), R1		// arg 2 - n
   444  	MOVD	$301, R8		// sys___thrwakeup
   445  	INVOKE_SYSCALL
   446  	MOVW	R0, ret+16(FP)
   447  	RET
   448  
   449  TEXT runtime·sysctl(SB),NOSPLIT,$0
   450  	MOVD	mib+0(FP), R0		// arg 1 - mib
   451  	MOVW	miblen+8(FP), R1	// arg 2 - miblen
   452  	MOVD	out+16(FP), R2		// arg 3 - out
   453  	MOVD	size+24(FP), R3		// arg 4 - size
   454  	MOVD	dst+32(FP), R4		// arg 5 - dest
   455  	MOVD	ndst+40(FP), R5		// arg 6 - newlen
   456  	MOVD	$202, R8		// sys___sysctl
   457  	INVOKE_SYSCALL
   458  	BCC	2(PC)
   459  	NEG	R0, R0
   460  	MOVW	R0, ret+48(FP)
   461  	RET
   462  
   463  // int32 runtime·kqueue(void);
   464  TEXT runtime·kqueue(SB),NOSPLIT,$0
   465  	MOVD	$269, R8		// sys_kqueue
   466  	INVOKE_SYSCALL
   467  	BCC	2(PC)
   468  	NEG	R0, R0
   469  	MOVW	R0, ret+0(FP)
   470  	RET
   471  
   472  // int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
   473  TEXT runtime·kevent(SB),NOSPLIT,$0
   474  	MOVW	kq+0(FP), R0		// arg 1 - kq
   475  	MOVD	ch+8(FP), R1		// arg 2 - changelist
   476  	MOVW	nch+16(FP), R2		// arg 3 - nchanges
   477  	MOVD	ev+24(FP), R3		// arg 4 - eventlist
   478  	MOVW	nev+32(FP), R4		// arg 5 - nevents
   479  	MOVD	ts+40(FP), R5		// arg 6 - timeout
   480  	MOVD	$72, R8			// sys_kevent
   481  	INVOKE_SYSCALL
   482  	BCC	2(PC)
   483  	NEG	R0, R0
   484  	MOVW	R0, ret+48(FP)
   485  	RET
   486  
   487  // func closeonexec(fd int32)
   488  TEXT runtime·closeonexec(SB),NOSPLIT,$0
   489  	MOVW	fd+0(FP), R0		// arg 1 - fd
   490  	MOVD	$2, R1			// arg 2 - cmd (F_SETFD)
   491  	MOVD	$1, R2			// arg 3 - arg (FD_CLOEXEC)
   492  	MOVD	$92, R8			// sys_fcntl
   493  	INVOKE_SYSCALL
   494  	RET
   495  
   496  // func runtime·setNonblock(int32 fd)
   497  TEXT runtime·setNonblock(SB),NOSPLIT|NOFRAME,$0-4
   498  	MOVW	fd+0(FP), R0		// arg 1 - fd
   499  	MOVD	$3, R1			// arg 2 - cmd (F_GETFL)
   500  	MOVD	$0, R2			// arg 3
   501  	MOVD	$92, R8			// sys_fcntl
   502  	INVOKE_SYSCALL
   503  	MOVD	$4, R2			// O_NONBLOCK
   504  	ORR	R0, R2			// arg 3 - flags
   505  	MOVW	fd+0(FP), R0		// arg 1 - fd
   506  	MOVD	$4, R1			// arg 2 - cmd (F_SETFL)
   507  	MOVD	$92, R8			// sys_fcntl
   508  	INVOKE_SYSCALL
   509  	RET