github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/runtime/sys_openbsd_arm.s (about)

     1  // Copyright 2009 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 ARM, OpenBSD
     6  // /usr/src/sys/kern/syscalls.master for syscall numbers.
     7  //
     8  
     9  #include "go_asm.h"
    10  #include "go_tls.h"
    11  #include "textflag.h"
    12  
    13  #define	CLOCK_REALTIME	$0
    14  #define	CLOCK_MONOTONIC	$3
    15  
    16  // With OpenBSD 6.7 onwards, an armv7 syscall returns two instructions
    17  // after the SWI instruction, to allow for a speculative execution
    18  // barrier to be placed after the SWI without impacting performance.
    19  // For now use hardware no-ops as this works with both older and newer
    20  // kernels. After OpenBSD 6.8 is released this should be changed to
    21  // speculation barriers.
    22  #define NOOP	MOVW    R0, R0
    23  #define	INVOKE_SYSCALL	\
    24  	SWI	$0;	\
    25  	NOOP;		\
    26  	NOOP
    27  
    28  // mstart_stub is the first function executed on a new thread started by pthread_create.
    29  // It just does some low-level setup and then calls mstart.
    30  // Note: called with the C calling convention.
    31  TEXT runtime·mstart_stub(SB),NOSPLIT,$0
    32  	// R0 points to the m.
    33  	// We are already on m's g0 stack.
    34  
    35  	// Save callee-save registers.
    36  	MOVM.DB.W [R4-R11], (R13)
    37  
    38  	MOVW	m_g0(R0), g
    39  	BL	runtime·save_g(SB)
    40  
    41  	BL	runtime·mstart(SB)
    42  
    43  	// Restore callee-save registers.
    44  	MOVM.IA.W (R13), [R4-R11]
    45  
    46  	// Go is all done with this OS thread.
    47  	// Tell pthread everything is ok (we never join with this thread, so
    48  	// the value here doesn't really matter).
    49  	MOVW	$0, R0
    50  	RET
    51  
    52  TEXT runtime·sigfwd(SB),NOSPLIT,$0-16
    53  	MOVW	sig+4(FP), R0
    54  	MOVW	info+8(FP), R1
    55  	MOVW	ctx+12(FP), R2
    56  	MOVW	fn+0(FP), R3
    57  	MOVW	R13, R9
    58  	SUB	$24, R13
    59  	BIC	$0x7, R13 // alignment for ELF ABI
    60  	BL	(R3)
    61  	MOVW	R9, R13
    62  	RET
    63  
    64  TEXT runtime·sigtramp(SB),NOSPLIT,$0
    65  	// Reserve space for callee-save registers and arguments.
    66  	MOVM.DB.W [R4-R11], (R13)
    67  	SUB	$16, R13
    68  
    69  	// If called from an external code context, g will not be set.
    70  	// Save R0, since runtime·load_g will clobber it.
    71  	MOVW	R0, 4(R13)		// signum
    72  	BL	runtime·load_g(SB)
    73  
    74  	MOVW	R1, 8(R13)
    75  	MOVW	R2, 12(R13)
    76  	BL	runtime·sigtrampgo(SB)
    77  
    78  	// Restore callee-save registers.
    79  	ADD	$16, R13
    80  	MOVM.IA.W (R13), [R4-R11]
    81  
    82  	RET
    83  
    84  TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
    85  	B	runtime·armPublicationBarrier(SB)
    86  
    87  // TODO(jsing): OpenBSD only supports GOARM=7 machines... this
    88  // should not be needed, however the linker still allows GOARM=5
    89  // on this platform.
    90  TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
    91  	MOVM.WP	[R1, R2, R3, R12], (R13)
    92  	MOVW	$330, R12		// sys___get_tcb
    93  	INVOKE_SYSCALL
    94  	MOVM.IAW (R13), [R1, R2, R3, R12]
    95  	RET
    96  
    97  // These trampolines help convert from Go calling convention to C calling convention.
    98  // They should be called with asmcgocall - note that while asmcgocall does
    99  // stack alignment, creation of a frame undoes it again.
   100  // A pointer to the arguments is passed in R0.
   101  // A single int32 result is returned in R0.
   102  // (For more results, make an args/results structure.)
   103  TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
   104  	MOVW	R13, R9
   105  	BIC     $0x7, R13		// align for ELF ABI
   106  	MOVW	0(R0), R0		// arg 1 attr
   107  	CALL	libc_pthread_attr_init(SB)
   108  	MOVW	R9, R13
   109  	RET
   110  
   111  TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
   112  	MOVW	R13, R9
   113  	BIC     $0x7, R13		// align for ELF ABI
   114  	MOVW	0(R0), R0		// arg 1 attr
   115  	CALL	libc_pthread_attr_destroy(SB)
   116  	MOVW	R9, R13
   117  	RET
   118  
   119  TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
   120  	MOVW	R13, R9
   121  	BIC     $0x7, R13		// align for ELF ABI
   122  	MOVW	4(R0), R1		// arg 2 size
   123  	MOVW	0(R0), R0		// arg 1 attr
   124  	CALL	libc_pthread_attr_getstacksize(SB)
   125  	MOVW	R9, R13
   126  	RET
   127  
   128  TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
   129  	MOVW	R13, R9
   130  	BIC     $0x7, R13		// align for ELF ABI
   131  	MOVW	4(R0), R1		// arg 2 state
   132  	MOVW	0(R0), R0		// arg 1 attr
   133  	CALL	libc_pthread_attr_setdetachstate(SB)
   134  	MOVW	R9, R13
   135  	RET
   136  
   137  TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
   138  	MOVW	R13, R9
   139  	SUB	$16, R13
   140  	BIC     $0x7, R13		// align for ELF ABI
   141  	MOVW	0(R0), R1		// arg 2 attr
   142  	MOVW	4(R0), R2		// arg 3 start
   143  	MOVW	8(R0), R3		// arg 4 arg
   144  	MOVW	R13, R0			// arg 1 &threadid (discarded)
   145  	CALL	libc_pthread_create(SB)
   146  	MOVW	R9, R13
   147  	RET
   148  
   149  TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
   150  	MOVW	R13, R9
   151  	BIC     $0x7, R13		// align for ELF ABI
   152  	MOVW	4(R0), R1		// arg 2 - signal
   153  	MOVW	$0, R2			// arg 3 - tcb
   154  	MOVW	0(R0), R0		// arg 1 - tid
   155  	CALL	libc_thrkill(SB)
   156  	MOVW	R9, R13
   157  	RET
   158  
   159  TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
   160  	MOVW	R13, R9
   161  	SUB	$16, R13
   162  	BIC     $0x7, R13		// align for ELF ABI
   163  	MOVW	4(R0), R1		// arg 2 - clock_id
   164  	MOVW	8(R0), R2		// arg 3 - abstime
   165  	MOVW	12(R0), R3		// arg 4 - lock
   166  	MOVW	16(R0), R4		// arg 5 - abort (on stack)
   167  	MOVW	R4, 0(R13)
   168  	MOVW	0(R0), R0		// arg 1 - id
   169  	CALL	libc_thrsleep(SB)
   170  	MOVW	R9, R13
   171  	RET
   172  
   173  TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
   174  	MOVW	R13, R9
   175  	BIC     $0x7, R13		// align for ELF ABI
   176  	MOVW	4(R0), R1		// arg 2 - count
   177  	MOVW	0(R0), R0		// arg 1 - id
   178  	CALL	libc_thrwakeup(SB)
   179  	MOVW	R9, R13
   180  	RET
   181  
   182  TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
   183  	MOVW	R13, R9
   184  	BIC     $0x7, R13		// align for ELF ABI
   185  	MOVW	0(R0), R0		// arg 1 exit status
   186  	BL	libc_exit(SB)
   187  	MOVW	$0, R8			// crash on failure
   188  	MOVW	R8, (R8)
   189  	MOVW	R9, R13
   190  	RET
   191  
   192  TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
   193  	MOVW	R13, R9
   194  	MOVW	R0, R8
   195  	BIC     $0x7, R13		// align for ELF ABI
   196  	BL	libc_getthrid(SB)
   197  	MOVW	R0, 0(R8)
   198  	MOVW	R9, R13
   199  	RET
   200  
   201  TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
   202  	MOVW	R13, R9
   203  	BIC     $0x7, R13		// align for ELF ABI
   204  	MOVW	R0, R4
   205  	BL	libc_getpid(SB)		// arg 1 pid
   206  	MOVW	R4, R1			// arg 2 signal
   207  	BL	libc_kill(SB)
   208  	MOVW	R9, R13
   209  	RET
   210  
   211  TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
   212  	MOVW	R13, R9
   213  	BIC     $0x7, R13		// align for ELF ABI
   214  	BL	libc_sched_yield(SB)
   215  	MOVW	R9, R13
   216  	RET
   217  
   218  TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
   219  	MOVW	R13, R9
   220  	SUB	$16, R13
   221  	BIC     $0x7, R13		// align for ELF ABI
   222  	MOVW	R0, R8
   223  	MOVW	4(R0), R1		// arg 2 len
   224  	MOVW	8(R0), R2		// arg 3 prot
   225  	MOVW	12(R0), R3		// arg 4 flags
   226  	MOVW	16(R0), R4		// arg 5 fid (on stack)
   227  	MOVW	R4, 0(R13)
   228  	MOVW	$0, R5			// pad (on stack)
   229  	MOVW	R5, 4(R13)
   230  	MOVW	20(R0), R6		// arg 6 offset (on stack)
   231  	MOVW	R6, 8(R13)		// low 32 bits
   232  	MOVW    $0, R7
   233  	MOVW	R7, 12(R13)		// high 32 bits
   234  	MOVW	0(R0), R0		// arg 1 addr
   235  	BL	libc_mmap(SB)
   236  	MOVW	$0, R1
   237  	CMP	$-1, R0
   238  	BNE	ok
   239  	BL	libc_errno(SB)
   240  	MOVW	(R0), R1		// errno
   241  	MOVW	$0, R0
   242  ok:
   243  	MOVW	R0, 24(R8)
   244  	MOVW	R1, 28(R8)
   245  	MOVW	R9, R13
   246  	RET
   247  
   248  TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
   249  	MOVW	R13, R9
   250  	BIC     $0x7, R13		// align for ELF ABI
   251  	MOVW	4(R0), R1		// arg 2 len
   252  	MOVW	0(R0), R0		// arg 1 addr
   253  	BL	libc_munmap(SB)
   254  	CMP	$-1, R0
   255  	BNE	3(PC)
   256  	MOVW	$0, R8			// crash on failure
   257  	MOVW	R8, (R8)
   258  	MOVW	R9, R13
   259  	RET
   260  
   261  TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
   262  	MOVW	R13, R9
   263  	BIC     $0x7, R13		// align for ELF ABI
   264  	MOVW	4(R0), R1		// arg 2 len
   265  	MOVW	8(R0), R2		// arg 3 advice
   266  	MOVW	0(R0), R0		// arg 1 addr
   267  	BL	libc_madvise(SB)
   268  	// ignore failure - maybe pages are locked
   269  	MOVW	R9, R13
   270  	RET
   271  
   272  TEXT runtime·open_trampoline(SB),NOSPLIT,$0
   273  	MOVW	R13, R9
   274  	SUB	$8, R13
   275  	BIC     $0x7, R13		// align for ELF ABI
   276  	MOVW	4(R0), R1		// arg 2 - flags
   277  	MOVW	8(R0), R2		// arg 3 - mode (vararg, on stack)
   278  	MOVW	R2, 0(R13)
   279  	MOVW	0(R0), R0		// arg 1 - path
   280  	MOVW	R13, R4
   281  	BIC     $0x7, R13		// align for ELF ABI
   282  	BL	libc_open(SB)
   283  	MOVW	R9, R13
   284  	RET
   285  
   286  TEXT runtime·close_trampoline(SB),NOSPLIT,$0
   287  	MOVW	R13, R9
   288  	BIC     $0x7, R13		// align for ELF ABI
   289  	MOVW	0(R0), R0		// arg 1 - fd
   290  	BL	libc_close(SB)
   291  	MOVW	R9, R13
   292  	RET
   293  
   294  TEXT runtime·read_trampoline(SB),NOSPLIT,$0
   295  	MOVW	R13, R9
   296  	BIC     $0x7, R13		// align for ELF ABI
   297  	MOVW	4(R0), R1		// arg 2 - buf
   298  	MOVW	8(R0), R2		// arg 3 - count
   299  	MOVW	0(R0), R0		// arg 1 - fd
   300  	BL	libc_read(SB)
   301  	CMP	$-1, R0
   302  	BNE	noerr
   303  	BL	libc_errno(SB)
   304  	MOVW	(R0), R0		// errno
   305  	RSB.CS	$0, R0			// caller expects negative errno
   306  noerr:
   307  	MOVW	R9, R13
   308  	RET
   309  
   310  TEXT runtime·write_trampoline(SB),NOSPLIT,$0
   311  	MOVW	R13, R9
   312  	BIC     $0x7, R13		// align for ELF ABI
   313  	MOVW	4(R0), R1		// arg 2 buf
   314  	MOVW	8(R0), R2		// arg 3 count
   315  	MOVW	0(R0), R0		// arg 1 fd
   316  	BL	libc_write(SB)
   317  	CMP	$-1, R0
   318  	BNE	noerr
   319  	BL	libc_errno(SB)
   320  	MOVW	(R0), R0		// errno
   321  	RSB.CS	$0, R0			// caller expects negative errno
   322  noerr:
   323  	MOVW	R9, R13
   324  	RET
   325  
   326  TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
   327  	MOVW	R13, R9
   328  	BIC     $0x7, R13		// align for ELF ABI
   329  	MOVW	4(R0), R1		// arg 2 flags
   330  	MOVW	0(R0), R0		// arg 1 filedes
   331  	BL	libc_pipe2(SB)
   332  	CMP	$-1, R0
   333  	BNE	3(PC)
   334  	BL	libc_errno(SB)
   335  	MOVW	(R0), R0		// errno
   336  	RSB.CS	$0, R0			// caller expects negative errno
   337  	MOVW	R9, R13
   338  	RET
   339  
   340  TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
   341  	MOVW	R13, R9
   342  	BIC     $0x7, R13		// align for ELF ABI
   343  	MOVW	4(R0), R1		// arg 2 new
   344  	MOVW	8(R0), R2		// arg 3 old
   345  	MOVW	0(R0), R0		// arg 1 which
   346  	BL	libc_setitimer(SB)
   347  	MOVW	R9, R13
   348  	RET
   349  
   350  TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   351  	MOVW	R13, R9
   352  	BIC     $0x7, R13		// align for ELF ABI
   353  	MOVW	0(R0), R0		// arg 1 usec
   354  	BL	libc_usleep(SB)
   355  	MOVW	R9, R13
   356  	RET
   357  
   358  TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
   359  	MOVW	R13, R9
   360  	SUB	$8, R13
   361  	BIC     $0x7, R13		// align for ELF ABI
   362  	MOVW	4(R0), R1		// arg 2 miblen
   363  	MOVW	8(R0), R2		// arg 3 out
   364  	MOVW	12(R0), R3		// arg 4 size
   365  	MOVW	16(R0), R4		// arg 5 dst (on stack)
   366  	MOVW	R4, 0(R13)
   367  	MOVW	20(R0), R5		// arg 6 ndst (on stack)
   368  	MOVW	R5, 4(R13)
   369  	MOVW	0(R0), R0		// arg 1 mib
   370  	BL	libc_sysctl(SB)
   371  	MOVW	R9, R13
   372  	RET
   373  
   374  TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   375  	MOVW	R13, R9
   376  	BIC     $0x7, R13		// align for ELF ABI
   377  	BL	libc_kqueue(SB)
   378  	MOVW	R9, R13
   379  	RET
   380  
   381  TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
   382  	MOVW	R13, R9
   383  	SUB	$8, R13
   384  	BIC     $0x7, R13		// align for ELF ABI
   385  	MOVW	4(R0), R1		// arg 2 keventt
   386  	MOVW	8(R0), R2		// arg 3 nch
   387  	MOVW	12(R0), R3		// arg 4 ev
   388  	MOVW	16(R0), R4		// arg 5 nev (on stack)
   389  	MOVW	R4, 0(R13)
   390  	MOVW	20(R0), R5		// arg 6 ts (on stack)
   391  	MOVW	R5, 4(R13)
   392  	MOVW	0(R0), R0		// arg 1 kq
   393  	BL	libc_kevent(SB)
   394  	CMP	$-1, R0
   395  	BNE	ok
   396  	BL	libc_errno(SB)
   397  	MOVW	(R0), R0		// errno
   398  	RSB.CS	$0, R0			// caller expects negative errno
   399  ok:
   400  	MOVW	R9, R13
   401  	RET
   402  
   403  TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
   404  	MOVW	R13, R9
   405  	BIC     $0x7, R13		// align for ELF ABI
   406  	MOVW	4(R0), R1		// arg 2 tp
   407  	MOVW	0(R0), R0		// arg 1 clock_id
   408  	BL	libc_clock_gettime(SB)
   409  	CMP	$-1, R0
   410  	BNE	noerr
   411  	BL	libc_errno(SB)
   412  	MOVW	(R0), R0		// errno
   413  	RSB.CS	$0, R0			// caller expects negative errno
   414  noerr:
   415  	MOVW	R9, R13
   416  	RET
   417  
   418  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   419  	MOVW	R13, R9
   420  	SUB	$8, R13
   421  	BIC     $0x7, R13		// align for ELF ABI
   422  	MOVW	4(R0), R1		// arg 2 cmd
   423  	MOVW	8(R0), R2		// arg 3 arg (vararg, on stack)
   424  	MOVW	R2, 0(R13)
   425  	MOVW	0(R0), R0		// arg 1 fd
   426  	BL	libc_fcntl(SB)
   427  	MOVW	R9, R13
   428  	RET
   429  
   430  TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
   431  	MOVW	R13, R9
   432  	BIC     $0x7, R13		// align for ELF ABI
   433  	MOVW	4(R0), R1		// arg 2 new
   434  	MOVW	8(R0), R2		// arg 3 old
   435  	MOVW	0(R0), R0		// arg 1 sig
   436  	BL	libc_sigaction(SB)
   437  	CMP	$-1, R0
   438  	BNE	3(PC)
   439  	MOVW	$0, R8			// crash on failure
   440  	MOVW	R8, (R8)
   441  	MOVW	R9, R13
   442  	RET
   443  
   444  TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   445  	MOVW	R13, R9
   446  	BIC     $0x7, R13		// align for ELF ABI
   447  	MOVW	4(R0), R1		// arg 2 new
   448  	MOVW	8(R0), R2		// arg 3 old
   449  	MOVW	0(R0), R0		// arg 1 how
   450  	BL	libc_pthread_sigmask(SB)
   451  	CMP	$-1, R0
   452  	BNE	3(PC)
   453  	MOVW	$0, R8			// crash on failure
   454  	MOVW	R8, (R8)
   455  	MOVW	R9, R13
   456  	RET
   457  
   458  TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   459  	MOVW	R13, R9
   460  	BIC     $0x7, R13		// align for ELF ABI
   461  	MOVW	4(R0), R1		// arg 2 old
   462  	MOVW	0(R0), R0		// arg 1 new
   463  	BL	libc_sigaltstack(SB)
   464  	CMP	$-1, R0
   465  	BNE	3(PC)
   466  	MOVW	$0, R8			// crash on failure
   467  	MOVW	R8, (R8)
   468  	MOVW	R9, R13
   469  	RET
   470  
   471  // syscall calls a function in libc on behalf of the syscall package.
   472  // syscall takes a pointer to a struct like:
   473  // struct {
   474  //	fn    uintptr
   475  //	a1    uintptr
   476  //	a2    uintptr
   477  //	a3    uintptr
   478  //	r1    uintptr
   479  //	r2    uintptr
   480  //	err   uintptr
   481  // }
   482  // syscall must be called on the g0 stack with the
   483  // C calling convention (use libcCall).
   484  //
   485  // syscall expects a 32-bit result and tests for 32-bit -1
   486  // to decide there was an error.
   487  TEXT runtime·syscall(SB),NOSPLIT,$0
   488  	MOVW	R13, R9
   489  	BIC     $0x7, R13		// align for ELF ABI
   490  
   491  	MOVW	R0, R8
   492  
   493  	MOVW	(0*4)(R8), R7 // fn
   494  	MOVW	(1*4)(R8), R0 // a1
   495  	MOVW	(2*4)(R8), R1 // a2
   496  	MOVW	(3*4)(R8), R2 // a3
   497  
   498  	BL	(R7)
   499  
   500  	MOVW	R0, (4*4)(R8) // r1
   501  	MOVW	R1, (5*4)(R8) // r2
   502  
   503  	// Standard libc functions return -1 on error and set errno.
   504  	CMP	$-1, R0
   505  	BNE	ok
   506  
   507  	// Get error code from libc.
   508  	BL	libc_errno(SB)
   509  	MOVW	(R0), R1
   510  	MOVW	R1, (6*4)(R8) // err
   511  
   512  ok:
   513  	MOVW	$0, R0		// no error (it's ignored anyway)
   514  	MOVW	R9, R13
   515  	RET
   516  
   517  // syscallX calls a function in libc on behalf of the syscall package.
   518  // syscallX takes a pointer to a struct like:
   519  // struct {
   520  //	fn    uintptr
   521  //	a1    uintptr
   522  //	a2    uintptr
   523  //	a3    uintptr
   524  //	r1    uintptr
   525  //	r2    uintptr
   526  //	err   uintptr
   527  // }
   528  // syscallX must be called on the g0 stack with the
   529  // C calling convention (use libcCall).
   530  //
   531  // syscallX is like syscall but expects a 64-bit result
   532  // and tests for 64-bit -1 to decide there was an error.
   533  TEXT runtime·syscallX(SB),NOSPLIT,$0
   534  	MOVW	R13, R9
   535  	BIC     $0x7, R13		// align for ELF ABI
   536  
   537  	MOVW	R0, R8
   538  
   539  	MOVW	(0*4)(R8), R7 // fn
   540  	MOVW	(1*4)(R8), R0 // a1
   541  	MOVW	(2*4)(R8), R1 // a2
   542  	MOVW	(3*4)(R8), R2 // a3
   543  
   544  	BL	(R7)
   545  
   546  	MOVW	R0, (4*4)(R8) // r1
   547  	MOVW	R1, (5*4)(R8) // r2
   548  
   549  	// Standard libc functions return -1 on error and set errno.
   550  	CMP	$-1, R0
   551  	BNE	ok
   552  	CMP	$-1, R1
   553  	BNE	ok
   554  
   555  	// Get error code from libc.
   556  	BL	libc_errno(SB)
   557  	MOVW	(R0), R1
   558  	MOVW	R1, (6*4)(R8) // err
   559  
   560  ok:
   561  	MOVW	$0, R0		// no error (it's ignored anyway)
   562  	MOVW	R9, R13
   563  	RET
   564  
   565  // syscall6 calls a function in libc on behalf of the syscall package.
   566  // syscall6 takes a pointer to a struct like:
   567  // struct {
   568  //	fn    uintptr
   569  //	a1    uintptr
   570  //	a2    uintptr
   571  //	a3    uintptr
   572  //	a4    uintptr
   573  //	a5    uintptr
   574  //	a6    uintptr
   575  //	r1    uintptr
   576  //	r2    uintptr
   577  //	err   uintptr
   578  // }
   579  // syscall6 must be called on the g0 stack with the
   580  // C calling convention (use libcCall).
   581  //
   582  // syscall6 expects a 32-bit result and tests for 32-bit -1
   583  // to decide there was an error.
   584  TEXT runtime·syscall6(SB),NOSPLIT,$0
   585  	MOVW	R13, R9
   586  	SUB	$8, R13
   587  	BIC     $0x7, R13		// align for ELF ABI
   588  
   589  	MOVW	R0, R8
   590  
   591  	MOVW	(0*4)(R8), R7 // fn
   592  	MOVW	(1*4)(R8), R0 // a1
   593  	MOVW	(2*4)(R8), R1 // a2
   594  	MOVW	(3*4)(R8), R2 // a3
   595  	MOVW	(4*4)(R8), R3 // a4
   596  	MOVW	(5*4)(R8), R4 // a5
   597  	MOVW	R4, 0(R13)
   598  	MOVW	(6*4)(R8), R5 // a6
   599  	MOVW	R5, 4(R13)
   600  
   601  	BL	(R7)
   602  
   603  	MOVW	R0, (7*4)(R8) // r1
   604  	MOVW	R1, (8*4)(R8) // r2
   605  
   606  	// Standard libc functions return -1 on error and set errno.
   607  	CMP	$-1, R0
   608  	BNE	ok
   609  
   610  	// Get error code from libc.
   611  	BL	libc_errno(SB)
   612  	MOVW	(R0), R1
   613  	MOVW	R1, (9*4)(R8) // err
   614  
   615  ok:
   616  	MOVW	$0, R0		// no error (it's ignored anyway)
   617  	MOVW	R9, R13
   618  	RET
   619  
   620  // syscall6X calls a function in libc on behalf of the syscall package.
   621  // syscall6X takes a pointer to a struct like:
   622  // struct {
   623  //	fn    uintptr
   624  //	a1    uintptr
   625  //	a2    uintptr
   626  //	a3    uintptr
   627  //	a4    uintptr
   628  //	a5    uintptr
   629  //	a6    uintptr
   630  //	r1    uintptr
   631  //	r2    uintptr
   632  //	err   uintptr
   633  // }
   634  // syscall6X must be called on the g0 stack with the
   635  // C calling convention (use libcCall).
   636  //
   637  // syscall6X is like syscall6 but expects a 64-bit result
   638  // and tests for 64-bit -1 to decide there was an error.
   639  TEXT runtime·syscall6X(SB),NOSPLIT,$0
   640  	MOVW	R13, R9
   641  	SUB	$8, R13
   642  	BIC     $0x7, R13		// align for ELF ABI
   643  
   644  	MOVW	R0, R8
   645  
   646  	MOVW	(0*4)(R8), R7 // fn
   647  	MOVW	(1*4)(R8), R0 // a1
   648  	MOVW	(2*4)(R8), R1 // a2
   649  	MOVW	(3*4)(R8), R2 // a3
   650  	MOVW	(4*4)(R8), R3 // a4
   651  	MOVW	(5*4)(R8), R4 // a5
   652  	MOVW	R4, 0(R13)
   653  	MOVW	(6*4)(R8), R5 // a6
   654  	MOVW	R5, 4(R13)
   655  
   656  	BL	(R7)
   657  
   658  	MOVW	R0, (7*4)(R8) // r1
   659  	MOVW	R1, (8*4)(R8) // r2
   660  
   661  	// Standard libc functions return -1 on error and set errno.
   662  	CMP	$-1, R0
   663  	BNE	ok
   664  	CMP	$-1, R1
   665  	BNE	ok
   666  
   667  	// Get error code from libc.
   668  	BL	libc_errno(SB)
   669  	MOVW	(R0), R1
   670  	MOVW	R1, (9*4)(R8) // err
   671  
   672  ok:
   673  	MOVW	$0, R0		// no error (it's ignored anyway)
   674  	MOVW	R9, R13
   675  	RET
   676  
   677  // syscall10 calls a function in libc on behalf of the syscall package.
   678  // syscall10 takes a pointer to a struct like:
   679  // struct {
   680  //	fn    uintptr
   681  //	a1    uintptr
   682  //	a2    uintptr
   683  //	a3    uintptr
   684  //	a4    uintptr
   685  //	a5    uintptr
   686  //	a6    uintptr
   687  //	a7    uintptr
   688  //	a8    uintptr
   689  //	a9    uintptr
   690  //	a10   uintptr
   691  //	r1    uintptr
   692  //	r2    uintptr
   693  //	err   uintptr
   694  // }
   695  // syscall10 must be called on the g0 stack with the
   696  // C calling convention (use libcCall).
   697  TEXT runtime·syscall10(SB),NOSPLIT,$0
   698  	MOVW	R13, R9
   699  	SUB	$24, R13
   700  	BIC     $0x7, R13		// align for ELF ABI
   701  
   702  	MOVW	R0, R8
   703  
   704  	MOVW	(0*4)(R8), R7 // fn
   705  	MOVW	(1*4)(R8), R0 // a1
   706  	MOVW	(2*4)(R8), R1 // a2
   707  	MOVW	(3*4)(R8), R2 // a3
   708  	MOVW	(4*4)(R8), R3 // a4
   709  	MOVW	(5*4)(R8), R4 // a5
   710  	MOVW	R4, 0(R13)
   711  	MOVW	(6*4)(R8), R5 // a6
   712  	MOVW	R5, 4(R13)
   713  	MOVW	(7*4)(R8), R6 // a7
   714  	MOVW	R6, 8(R13)
   715  	MOVW	(8*4)(R8), R4 // a8
   716  	MOVW	R4, 12(R13)
   717  	MOVW	(9*4)(R8), R5 // a9
   718  	MOVW	R5, 16(R13)
   719  	MOVW	(10*4)(R8), R6 // a10
   720  	MOVW	R6, 20(R13)
   721  
   722  	BL	(R7)
   723  
   724  	MOVW	R0, (11*4)(R8) // r1
   725  	MOVW	R1, (12*4)(R8) // r2
   726  
   727  	// Standard libc functions return -1 on error and set errno.
   728  	CMP	$-1, R0
   729  	BNE	ok
   730  
   731  	// Get error code from libc.
   732  	BL	libc_errno(SB)
   733  	MOVW	(R0), R1
   734  	MOVW	R1, (13*4)(R8) // err
   735  
   736  ok:
   737  	MOVW	$0, R0		// no error (it's ignored anyway)
   738  	MOVW	R9, R13
   739  	RET
   740  
   741  // syscall10X calls a function in libc on behalf of the syscall package.
   742  // syscall10X takes a pointer to a struct like:
   743  // struct {
   744  //	fn    uintptr
   745  //	a1    uintptr
   746  //	a2    uintptr
   747  //	a3    uintptr
   748  //	a4    uintptr
   749  //	a5    uintptr
   750  //	a6    uintptr
   751  //	a7    uintptr
   752  //	a8    uintptr
   753  //	a9    uintptr
   754  //	a10   uintptr
   755  //	r1    uintptr
   756  //	r2    uintptr
   757  //	err   uintptr
   758  // }
   759  // syscall10X must be called on the g0 stack with the
   760  // C calling convention (use libcCall).
   761  //
   762  // syscall10X is like syscall10 but expects a 64-bit result
   763  // and tests for 64-bit -1 to decide there was an error.
   764  TEXT runtime·syscall10X(SB),NOSPLIT,$0
   765  	MOVW	R13, R9
   766  	SUB	$24, R13
   767  	BIC     $0x7, R13		// align for ELF ABI
   768  
   769  	MOVW	R0, R8
   770  
   771  	MOVW	(0*4)(R8), R7 // fn
   772  	MOVW	(1*4)(R8), R0 // a1
   773  	MOVW	(2*4)(R8), R1 // a2
   774  	MOVW	(3*4)(R8), R2 // a3
   775  	MOVW	(4*4)(R8), R3 // a4
   776  	MOVW	(5*4)(R8), R4 // a5
   777  	MOVW	R4, 0(R13)
   778  	MOVW	(6*4)(R8), R5 // a6
   779  	MOVW	R5, 4(R13)
   780  	MOVW	(7*4)(R8), R6 // a7
   781  	MOVW	R6, 8(R13)
   782  	MOVW	(8*4)(R8), R4 // a8
   783  	MOVW	R4, 12(R13)
   784  	MOVW	(9*4)(R8), R5 // a9
   785  	MOVW	R5, 16(R13)
   786  	MOVW	(10*4)(R8), R6 // a10
   787  	MOVW	R6, 20(R13)
   788  
   789  	BL	(R7)
   790  
   791  	MOVW	R0, (11*4)(R8) // r1
   792  	MOVW	R1, (12*4)(R8) // r2
   793  
   794  	// Standard libc functions return -1 on error and set errno.
   795  	CMP	$-1, R0
   796  	BNE	ok
   797  	CMP	$-1, R1
   798  	BNE	ok
   799  
   800  	// Get error code from libc.
   801  	BL	libc_errno(SB)
   802  	MOVW	(R0), R1
   803  	MOVW	R1, (13*4)(R8) // err
   804  
   805  ok:
   806  	MOVW	$0, R0		// no error (it's ignored anyway)
   807  	MOVW	R9, R13
   808  	RET