Black Lives Matter. Support the Equal Justice Initiative.

Text file src/runtime/sys_openbsd_arm.s

Documentation: runtime

     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	3(PC)
   411  	MOVW	$0, R8			// crash on failure
   412  	MOVW	R8, (R8)
   413  	MOVW	R9, R13
   414  	RET
   415  
   416  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   417  	MOVW	R13, R9
   418  	SUB	$8, R13
   419  	BIC     $0x7, R13		// align for ELF ABI
   420  	MOVW	4(R0), R1		// arg 2 cmd
   421  	MOVW	8(R0), R2		// arg 3 arg (vararg, on stack)
   422  	MOVW	R2, 0(R13)
   423  	MOVW	0(R0), R0		// arg 1 fd
   424  	BL	libc_fcntl(SB)
   425  	MOVW	R9, R13
   426  	RET
   427  
   428  TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
   429  	MOVW	R13, R9
   430  	BIC     $0x7, R13		// align for ELF ABI
   431  	MOVW	4(R0), R1		// arg 2 new
   432  	MOVW	8(R0), R2		// arg 3 old
   433  	MOVW	0(R0), R0		// arg 1 sig
   434  	BL	libc_sigaction(SB)
   435  	CMP	$-1, R0
   436  	BNE	3(PC)
   437  	MOVW	$0, R8			// crash on failure
   438  	MOVW	R8, (R8)
   439  	MOVW	R9, R13
   440  	RET
   441  
   442  TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   443  	MOVW	R13, R9
   444  	BIC     $0x7, R13		// align for ELF ABI
   445  	MOVW	4(R0), R1		// arg 2 new
   446  	MOVW	8(R0), R2		// arg 3 old
   447  	MOVW	0(R0), R0		// arg 1 how
   448  	BL	libc_pthread_sigmask(SB)
   449  	CMP	$-1, R0
   450  	BNE	3(PC)
   451  	MOVW	$0, R8			// crash on failure
   452  	MOVW	R8, (R8)
   453  	MOVW	R9, R13
   454  	RET
   455  
   456  TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   457  	MOVW	R13, R9
   458  	BIC     $0x7, R13		// align for ELF ABI
   459  	MOVW	4(R0), R1		// arg 2 old
   460  	MOVW	0(R0), R0		// arg 1 new
   461  	BL	libc_sigaltstack(SB)
   462  	CMP	$-1, R0
   463  	BNE	3(PC)
   464  	MOVW	$0, R8			// crash on failure
   465  	MOVW	R8, (R8)
   466  	MOVW	R9, R13
   467  	RET
   468  
   469  // syscall calls a function in libc on behalf of the syscall package.
   470  // syscall takes a pointer to a struct like:
   471  // struct {
   472  //	fn    uintptr
   473  //	a1    uintptr
   474  //	a2    uintptr
   475  //	a3    uintptr
   476  //	r1    uintptr
   477  //	r2    uintptr
   478  //	err   uintptr
   479  // }
   480  // syscall must be called on the g0 stack with the
   481  // C calling convention (use libcCall).
   482  //
   483  // syscall expects a 32-bit result and tests for 32-bit -1
   484  // to decide there was an error.
   485  TEXT runtime·syscall(SB),NOSPLIT,$0
   486  	MOVW	R13, R9
   487  	BIC     $0x7, R13		// align for ELF ABI
   488  
   489  	MOVW	R0, R8
   490  
   491  	MOVW	(0*4)(R8), R7 // fn
   492  	MOVW	(1*4)(R8), R0 // a1
   493  	MOVW	(2*4)(R8), R1 // a2
   494  	MOVW	(3*4)(R8), R2 // a3
   495  
   496  	BL	(R7)
   497  
   498  	MOVW	R0, (4*4)(R8) // r1
   499  	MOVW	R1, (5*4)(R8) // r2
   500  
   501  	// Standard libc functions return -1 on error and set errno.
   502  	CMP	$-1, R0
   503  	BNE	ok
   504  
   505  	// Get error code from libc.
   506  	BL	libc_errno(SB)
   507  	MOVW	(R0), R1
   508  	MOVW	R1, (6*4)(R8) // err
   509  
   510  ok:
   511  	MOVW	$0, R0		// no error (it's ignored anyway)
   512  	MOVW	R9, R13
   513  	RET
   514  
   515  // syscallX calls a function in libc on behalf of the syscall package.
   516  // syscallX takes a pointer to a struct like:
   517  // struct {
   518  //	fn    uintptr
   519  //	a1    uintptr
   520  //	a2    uintptr
   521  //	a3    uintptr
   522  //	r1    uintptr
   523  //	r2    uintptr
   524  //	err   uintptr
   525  // }
   526  // syscallX must be called on the g0 stack with the
   527  // C calling convention (use libcCall).
   528  //
   529  // syscallX is like syscall but expects a 64-bit result
   530  // and tests for 64-bit -1 to decide there was an error.
   531  TEXT runtime·syscallX(SB),NOSPLIT,$0
   532  	MOVW	R13, R9
   533  	BIC     $0x7, R13		// align for ELF ABI
   534  
   535  	MOVW	R0, R8
   536  
   537  	MOVW	(0*4)(R8), R7 // fn
   538  	MOVW	(1*4)(R8), R0 // a1
   539  	MOVW	(2*4)(R8), R1 // a2
   540  	MOVW	(3*4)(R8), R2 // a3
   541  
   542  	BL	(R7)
   543  
   544  	MOVW	R0, (4*4)(R8) // r1
   545  	MOVW	R1, (5*4)(R8) // r2
   546  
   547  	// Standard libc functions return -1 on error and set errno.
   548  	CMP	$-1, R0
   549  	BNE	ok
   550  	CMP	$-1, R1
   551  	BNE	ok
   552  
   553  	// Get error code from libc.
   554  	BL	libc_errno(SB)
   555  	MOVW	(R0), R1
   556  	MOVW	R1, (6*4)(R8) // err
   557  
   558  ok:
   559  	MOVW	$0, R0		// no error (it's ignored anyway)
   560  	MOVW	R9, R13
   561  	RET
   562  
   563  // syscall6 calls a function in libc on behalf of the syscall package.
   564  // syscall6 takes a pointer to a struct like:
   565  // struct {
   566  //	fn    uintptr
   567  //	a1    uintptr
   568  //	a2    uintptr
   569  //	a3    uintptr
   570  //	a4    uintptr
   571  //	a5    uintptr
   572  //	a6    uintptr
   573  //	r1    uintptr
   574  //	r2    uintptr
   575  //	err   uintptr
   576  // }
   577  // syscall6 must be called on the g0 stack with the
   578  // C calling convention (use libcCall).
   579  //
   580  // syscall6 expects a 32-bit result and tests for 32-bit -1
   581  // to decide there was an error.
   582  TEXT runtime·syscall6(SB),NOSPLIT,$0
   583  	MOVW	R13, R9
   584  	SUB	$8, R13
   585  	BIC     $0x7, R13		// align for ELF ABI
   586  
   587  	MOVW	R0, R8
   588  
   589  	MOVW	(0*4)(R8), R7 // fn
   590  	MOVW	(1*4)(R8), R0 // a1
   591  	MOVW	(2*4)(R8), R1 // a2
   592  	MOVW	(3*4)(R8), R2 // a3
   593  	MOVW	(4*4)(R8), R3 // a4
   594  	MOVW	(5*4)(R8), R4 // a5
   595  	MOVW	R4, 0(R13)
   596  	MOVW	(6*4)(R8), R5 // a6
   597  	MOVW	R5, 4(R13)
   598  
   599  	BL	(R7)
   600  
   601  	MOVW	R0, (7*4)(R8) // r1
   602  	MOVW	R1, (8*4)(R8) // r2
   603  
   604  	// Standard libc functions return -1 on error and set errno.
   605  	CMP	$-1, R0
   606  	BNE	ok
   607  
   608  	// Get error code from libc.
   609  	BL	libc_errno(SB)
   610  	MOVW	(R0), R1
   611  	MOVW	R1, (9*4)(R8) // err
   612  
   613  ok:
   614  	MOVW	$0, R0		// no error (it's ignored anyway)
   615  	MOVW	R9, R13
   616  	RET
   617  
   618  // syscall6X calls a function in libc on behalf of the syscall package.
   619  // syscall6X takes a pointer to a struct like:
   620  // struct {
   621  //	fn    uintptr
   622  //	a1    uintptr
   623  //	a2    uintptr
   624  //	a3    uintptr
   625  //	a4    uintptr
   626  //	a5    uintptr
   627  //	a6    uintptr
   628  //	r1    uintptr
   629  //	r2    uintptr
   630  //	err   uintptr
   631  // }
   632  // syscall6X must be called on the g0 stack with the
   633  // C calling convention (use libcCall).
   634  //
   635  // syscall6X is like syscall6 but expects a 64-bit result
   636  // and tests for 64-bit -1 to decide there was an error.
   637  TEXT runtime·syscall6X(SB),NOSPLIT,$0
   638  	MOVW	R13, R9
   639  	SUB	$8, R13
   640  	BIC     $0x7, R13		// align for ELF ABI
   641  
   642  	MOVW	R0, R8
   643  
   644  	MOVW	(0*4)(R8), R7 // fn
   645  	MOVW	(1*4)(R8), R0 // a1
   646  	MOVW	(2*4)(R8), R1 // a2
   647  	MOVW	(3*4)(R8), R2 // a3
   648  	MOVW	(4*4)(R8), R3 // a4
   649  	MOVW	(5*4)(R8), R4 // a5
   650  	MOVW	R4, 0(R13)
   651  	MOVW	(6*4)(R8), R5 // a6
   652  	MOVW	R5, 4(R13)
   653  
   654  	BL	(R7)
   655  
   656  	MOVW	R0, (7*4)(R8) // r1
   657  	MOVW	R1, (8*4)(R8) // r2
   658  
   659  	// Standard libc functions return -1 on error and set errno.
   660  	CMP	$-1, R0
   661  	BNE	ok
   662  	CMP	$-1, R1
   663  	BNE	ok
   664  
   665  	// Get error code from libc.
   666  	BL	libc_errno(SB)
   667  	MOVW	(R0), R1
   668  	MOVW	R1, (9*4)(R8) // err
   669  
   670  ok:
   671  	MOVW	$0, R0		// no error (it's ignored anyway)
   672  	MOVW	R9, R13
   673  	RET
   674  
   675  // syscall10 calls a function in libc on behalf of the syscall package.
   676  // syscall10 takes a pointer to a struct like:
   677  // struct {
   678  //	fn    uintptr
   679  //	a1    uintptr
   680  //	a2    uintptr
   681  //	a3    uintptr
   682  //	a4    uintptr
   683  //	a5    uintptr
   684  //	a6    uintptr
   685  //	a7    uintptr
   686  //	a8    uintptr
   687  //	a9    uintptr
   688  //	a10   uintptr
   689  //	r1    uintptr
   690  //	r2    uintptr
   691  //	err   uintptr
   692  // }
   693  // syscall10 must be called on the g0 stack with the
   694  // C calling convention (use libcCall).
   695  TEXT runtime·syscall10(SB),NOSPLIT,$0
   696  	MOVW	R13, R9
   697  	SUB	$24, R13
   698  	BIC     $0x7, R13		// align for ELF ABI
   699  
   700  	MOVW	R0, R8
   701  
   702  	MOVW	(0*4)(R8), R7 // fn
   703  	MOVW	(1*4)(R8), R0 // a1
   704  	MOVW	(2*4)(R8), R1 // a2
   705  	MOVW	(3*4)(R8), R2 // a3
   706  	MOVW	(4*4)(R8), R3 // a4
   707  	MOVW	(5*4)(R8), R4 // a5
   708  	MOVW	R4, 0(R13)
   709  	MOVW	(6*4)(R8), R5 // a6
   710  	MOVW	R5, 4(R13)
   711  	MOVW	(7*4)(R8), R6 // a7
   712  	MOVW	R6, 8(R13)
   713  	MOVW	(8*4)(R8), R4 // a8
   714  	MOVW	R4, 12(R13)
   715  	MOVW	(9*4)(R8), R5 // a9
   716  	MOVW	R5, 16(R13)
   717  	MOVW	(10*4)(R8), R6 // a10
   718  	MOVW	R6, 20(R13)
   719  
   720  	BL	(R7)
   721  
   722  	MOVW	R0, (11*4)(R8) // r1
   723  	MOVW	R1, (12*4)(R8) // r2
   724  
   725  	// Standard libc functions return -1 on error and set errno.
   726  	CMP	$-1, R0
   727  	BNE	ok
   728  
   729  	// Get error code from libc.
   730  	BL	libc_errno(SB)
   731  	MOVW	(R0), R1
   732  	MOVW	R1, (13*4)(R8) // err
   733  
   734  ok:
   735  	MOVW	$0, R0		// no error (it's ignored anyway)
   736  	MOVW	R9, R13
   737  	RET
   738  
   739  // syscall10X calls a function in libc on behalf of the syscall package.
   740  // syscall10X takes a pointer to a struct like:
   741  // struct {
   742  //	fn    uintptr
   743  //	a1    uintptr
   744  //	a2    uintptr
   745  //	a3    uintptr
   746  //	a4    uintptr
   747  //	a5    uintptr
   748  //	a6    uintptr
   749  //	a7    uintptr
   750  //	a8    uintptr
   751  //	a9    uintptr
   752  //	a10   uintptr
   753  //	r1    uintptr
   754  //	r2    uintptr
   755  //	err   uintptr
   756  // }
   757  // syscall10X must be called on the g0 stack with the
   758  // C calling convention (use libcCall).
   759  //
   760  // syscall10X is like syscall10 but expects a 64-bit result
   761  // and tests for 64-bit -1 to decide there was an error.
   762  TEXT runtime·syscall10X(SB),NOSPLIT,$0
   763  	MOVW	R13, R9
   764  	SUB	$24, R13
   765  	BIC     $0x7, R13		// align for ELF ABI
   766  
   767  	MOVW	R0, R8
   768  
   769  	MOVW	(0*4)(R8), R7 // fn
   770  	MOVW	(1*4)(R8), R0 // a1
   771  	MOVW	(2*4)(R8), R1 // a2
   772  	MOVW	(3*4)(R8), R2 // a3
   773  	MOVW	(4*4)(R8), R3 // a4
   774  	MOVW	(5*4)(R8), R4 // a5
   775  	MOVW	R4, 0(R13)
   776  	MOVW	(6*4)(R8), R5 // a6
   777  	MOVW	R5, 4(R13)
   778  	MOVW	(7*4)(R8), R6 // a7
   779  	MOVW	R6, 8(R13)
   780  	MOVW	(8*4)(R8), R4 // a8
   781  	MOVW	R4, 12(R13)
   782  	MOVW	(9*4)(R8), R5 // a9
   783  	MOVW	R5, 16(R13)
   784  	MOVW	(10*4)(R8), R6 // a10
   785  	MOVW	R6, 20(R13)
   786  
   787  	BL	(R7)
   788  
   789  	MOVW	R0, (11*4)(R8) // r1
   790  	MOVW	R1, (12*4)(R8) // r2
   791  
   792  	// Standard libc functions return -1 on error and set errno.
   793  	CMP	$-1, R0
   794  	BNE	ok
   795  	CMP	$-1, R1
   796  	BNE	ok
   797  
   798  	// Get error code from libc.
   799  	BL	libc_errno(SB)
   800  	MOVW	(R0), R1
   801  	MOVW	R1, (13*4)(R8) // err
   802  
   803  ok:
   804  	MOVW	$0, R0		// no error (it's ignored anyway)
   805  	MOVW	R9, R13
   806  	RET
   807  

View as plain text