Text file src/runtime/sys_openbsd_arm64.s

     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  #include "cgo/abi_arm64.h"
    15  
    16  #define CLOCK_REALTIME	$0
    17  #define	CLOCK_MONOTONIC	$3
    18  
    19  // mstart_stub is the first function executed on a new thread started by pthread_create.
    20  // It just does some low-level setup and then calls mstart.
    21  // Note: called with the C calling convention.
    22  TEXT runtime·mstart_stub(SB),NOSPLIT,$144
    23  	// R0 points to the m.
    24  	// We are already on m's g0 stack.
    25  
    26  	// Save callee-save registers.
    27  	SAVE_R19_TO_R28(8)
    28  	SAVE_F8_TO_F15(88)
    29  
    30  	MOVD    m_g0(R0), g
    31  	BL	runtime·save_g(SB)
    32  
    33  	BL	runtime·mstart(SB)
    34  
    35  	// Restore callee-save registers.
    36  	RESTORE_R19_TO_R28(8)
    37  	RESTORE_F8_TO_F15(88)
    38  
    39  	// Go is all done with this OS thread.
    40  	// Tell pthread everything is ok (we never join with this thread, so
    41  	// the value here doesn't really matter).
    42  	MOVD	$0, R0
    43  
    44  	RET
    45  
    46  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
    47  	MOVW	sig+8(FP), R0
    48  	MOVD	info+16(FP), R1
    49  	MOVD	ctx+24(FP), R2
    50  	MOVD	fn+0(FP), R11
    51  	BL	(R11)			// Alignment for ELF ABI?
    52  	RET
    53  
    54  TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$192
    55  	// Save callee-save registers in the case of signal forwarding.
    56  	// Please refer to https://golang.org/issue/31827 .
    57  	SAVE_R19_TO_R28(8*4)
    58  	SAVE_F8_TO_F15(8*14)
    59  
    60  	// If called from an external code context, g will not be set.
    61  	// Save R0, since runtime·load_g will clobber it.
    62  	MOVW	R0, 8(RSP)		// signum
    63  	BL	runtime·load_g(SB)
    64  
    65  	// Restore signum to R0.
    66  	MOVW	8(RSP), R0
    67  	// R1 and R2 already contain info and ctx, respectively.
    68  	BL	runtime·sigtrampgo<ABIInternal>(SB)
    69  
    70  	// Restore callee-save registers.
    71  	RESTORE_R19_TO_R28(8*4)
    72  	RESTORE_F8_TO_F15(8*14)
    73  
    74  	RET
    75  
    76  //
    77  // These trampolines help convert from Go calling convention to C calling convention.
    78  // They should be called with asmcgocall.
    79  // A pointer to the arguments is passed in R0.
    80  // A single int32 result is returned in R0.
    81  // (For more results, make an args/results structure.)
    82  TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
    83  	MOVD	0(R0), R0		// arg 1 - attr
    84  	CALL	libc_pthread_attr_init(SB)
    85  	RET
    86  
    87  TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
    88  	MOVD	0(R0), R0		// arg 1 - attr
    89  	CALL	libc_pthread_attr_destroy(SB)
    90  	RET
    91  
    92  TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
    93  	MOVD	8(R0), R1		// arg 2 - size
    94  	MOVD	0(R0), R0		// arg 1 - attr
    95  	CALL	libc_pthread_attr_getstacksize(SB)
    96  	RET
    97  
    98  TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
    99  	MOVD	8(R0), R1		// arg 2 - state
   100  	MOVD	0(R0), R0		// arg 1 - attr
   101  	CALL	libc_pthread_attr_setdetachstate(SB)
   102  	RET
   103  
   104  TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
   105  	MOVD	0(R0), R1		// arg 2 - attr
   106  	MOVD	8(R0), R2		// arg 3 - start
   107  	MOVD	16(R0), R3		// arg 4 - arg
   108  	SUB	$16, RSP
   109  	MOVD	RSP, R0			// arg 1 - &threadid (discard)
   110  	CALL	libc_pthread_create(SB)
   111  	ADD	$16, RSP
   112  	RET
   113  
   114  TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
   115  	MOVW	8(R0), R1		// arg 2 - signal
   116  	MOVD	$0, R2			// arg 3 - tcb
   117  	MOVW	0(R0), R0		// arg 1 - tid
   118  	CALL	libc_thrkill(SB)
   119  	RET
   120  
   121  TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
   122  	MOVW	8(R0), R1		// arg 2 - clock_id
   123  	MOVD	16(R0), R2		// arg 3 - abstime
   124  	MOVD	24(R0), R3		// arg 4 - lock
   125  	MOVD	32(R0), R4		// arg 5 - abort
   126  	MOVD	0(R0), R0		// arg 1 - id
   127  	CALL	libc_thrsleep(SB)
   128  	RET
   129  
   130  TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
   131  	MOVW	8(R0), R1		// arg 2 - count
   132  	MOVD	0(R0), R0		// arg 1 - id
   133  	CALL	libc_thrwakeup(SB)
   134  	RET
   135  
   136  TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
   137  	MOVW	0(R0), R0		// arg 1 - status
   138  	CALL	libc_exit(SB)
   139  	MOVD	$0, R0			// crash on failure
   140  	MOVD	R0, (R0)
   141  	RET
   142  
   143  TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
   144  	MOVD	R0, R19			// pointer to args
   145  	CALL	libc_getthrid(SB)
   146  	MOVW	R0, 0(R19)		// return value
   147  	RET
   148  
   149  TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
   150  	MOVD	R0, R19			// pointer to args
   151  	CALL	libc_getpid(SB)		// arg 1 - pid
   152  	MOVW	0(R19), R1		// arg 2 - signal
   153  	CALL	libc_kill(SB)
   154  	RET
   155  
   156  TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
   157  	CALL	libc_sched_yield(SB)
   158  	RET
   159  
   160  TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
   161  	MOVD    R0, R19			// pointer to args
   162  	MOVD	0(R19), R0		// arg 1 - addr
   163  	MOVD	8(R19), R1		// arg 2 - len
   164  	MOVW	16(R19), R2		// arg 3 - prot
   165  	MOVW	20(R19), R3		// arg 4 - flags
   166  	MOVW	24(R19), R4		// arg 5 - fid
   167  	MOVW	28(R19), R5		// arg 6 - offset
   168  	CALL	libc_mmap(SB)
   169  	MOVD	$0, R1
   170  	CMP	$-1, R0
   171  	BNE	noerr
   172  	CALL	libc_errno(SB)
   173  	MOVW	(R0), R1		// errno
   174  	MOVD	$0, R0
   175  noerr:
   176  	MOVD	R0, 32(R19)
   177  	MOVD	R1, 40(R19)
   178  	RET
   179  
   180  TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
   181  	MOVD	8(R0), R1		// arg 2 - len
   182  	MOVD	0(R0), R0		// arg 1 - addr
   183  	CALL	libc_munmap(SB)
   184  	CMP	$-1, R0
   185  	BNE	3(PC)
   186  	MOVD	$0, R0			// crash on failure
   187  	MOVD	R0, (R0)
   188  	RET
   189  
   190  TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
   191  	MOVD	8(R0), R1		// arg 2 - len
   192  	MOVW	16(R0), R2		// arg 3 - advice
   193  	MOVD	0(R0), R0		// arg 1 - addr
   194  	CALL	libc_madvise(SB)
   195  	// ignore failure - maybe pages are locked
   196  	RET
   197  
   198  TEXT runtime·open_trampoline(SB),NOSPLIT,$0
   199  	MOVW	8(R0), R1		// arg 2 - flags
   200  	MOVW	12(R0), R2		// arg 3 - mode
   201  	MOVD	0(R0), R0		// arg 1 - path
   202  	MOVD	$0, R3			// varargs
   203  	CALL	libc_open(SB)
   204  	RET
   205  
   206  TEXT runtime·close_trampoline(SB),NOSPLIT,$0
   207  	MOVD	0(R0), R0		// arg 1 - fd
   208  	CALL	libc_close(SB)
   209  	RET
   210  
   211  TEXT runtime·read_trampoline(SB),NOSPLIT,$0
   212  	MOVD	8(R0), R1		// arg 2 - buf
   213  	MOVW	16(R0), R2		// arg 3 - count
   214  	MOVW	0(R0), R0		// arg 1 - fd
   215  	CALL	libc_read(SB)
   216  	CMP	$-1, R0
   217  	BNE	noerr
   218  	CALL	libc_errno(SB)
   219  	MOVW	(R0), R0		// errno
   220  	NEG	R0, R0			// caller expects negative errno value
   221  noerr:
   222  	RET
   223  
   224  TEXT runtime·write_trampoline(SB),NOSPLIT,$0
   225  	MOVD	8(R0), R1		// arg 2 - buf
   226  	MOVW	16(R0), R2		// arg 3 - count
   227  	MOVW	0(R0), R0		// arg 1 - fd
   228  	CALL	libc_write(SB)
   229  	CMP	$-1, R0
   230  	BNE	noerr
   231  	CALL	libc_errno(SB)
   232  	MOVW	(R0), R0		// errno
   233  	NEG	R0, R0			// caller expects negative errno value
   234  noerr:
   235  	RET
   236  
   237  TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
   238  	MOVW	8(R0), R1		// arg 2 - flags
   239  	MOVD	0(R0), R0		// arg 1 - filedes
   240  	CALL	libc_pipe2(SB)
   241  	CMP	$-1, R0
   242  	BNE	noerr
   243  	CALL	libc_errno(SB)
   244  	MOVW	(R0), R0		// errno
   245  	NEG	R0, R0			// caller expects negative errno value
   246  noerr:
   247  	RET
   248  
   249  TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
   250  	MOVD	8(R0), R1		// arg 2 - new
   251  	MOVD	16(R0), R2		// arg 3 - old
   252  	MOVW	0(R0), R0		// arg 1 - which
   253  	CALL	libc_setitimer(SB)
   254  	RET
   255  
   256  TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   257  	MOVD	0(R0), R0		// arg 1 - usec
   258  	CALL	libc_usleep(SB)
   259  	RET
   260  
   261  TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
   262  	MOVW	8(R0), R1		// arg 2 - miblen
   263  	MOVD	16(R0), R2		// arg 3 - out
   264  	MOVD	24(R0), R3		// arg 4 - size
   265  	MOVD	32(R0), R4		// arg 5 - dst
   266  	MOVD	40(R0), R5		// arg 6 - ndst
   267  	MOVD	0(R0), R0		// arg 1 - mib
   268  	CALL	libc_sysctl(SB)
   269  	RET
   270  
   271  TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   272  	CALL	libc_kqueue(SB)
   273  	RET
   274  
   275  TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
   276  	MOVD	8(R0), R1		// arg 2 - keventt
   277  	MOVW	16(R0), R2		// arg 3 - nch
   278  	MOVD	24(R0), R3		// arg 4 - ev
   279  	MOVW	32(R0), R4		// arg 5 - nev
   280  	MOVD	40(R0), R5		// arg 6 - ts
   281  	MOVW	0(R0), R0		// arg 1 - kq
   282  	CALL	libc_kevent(SB)
   283  	CMP	$-1, R0
   284  	BNE	noerr
   285  	CALL	libc_errno(SB)
   286  	MOVW	(R0), R0		// errno
   287  	NEG	R0, R0			// caller expects negative errno value
   288  noerr:
   289  	RET
   290  
   291  TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
   292  	MOVD	8(R0), R1		// arg 2 - tp
   293  	MOVD	0(R0), R0		// arg 1 - clock_id
   294  	CALL	libc_clock_gettime(SB)
   295  	CMP	$-1, R0
   296  	BNE	noerr
   297  	CALL	libc_errno(SB)
   298  	MOVW	(R0), R0		// errno
   299  	NEG	R0, R0			// caller expects negative errno value
   300  noerr:
   301  	RET
   302  
   303  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   304  	MOVD	R0, R19
   305  	MOVW	0(R19), R0		// arg 1 - fd
   306  	MOVW	4(R19), R1		// arg 2 - cmd
   307  	MOVW	8(R19), R2		// arg 3 - arg
   308  	MOVD	$0, R3			// vararg
   309  	CALL	libc_fcntl(SB)
   310  	MOVD	$0, R1
   311  	CMP	$-1, R0
   312  	BNE	noerr
   313  	CALL	libc_errno(SB)
   314  	MOVW	(R0), R1
   315  	MOVW	$-1, R0
   316  noerr:
   317  	MOVW	R0, 12(R19)
   318  	MOVW	R1, 16(R19)
   319  	RET
   320  
   321  TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
   322  	MOVD	8(R0), R1		// arg 2 - new
   323  	MOVD	16(R0), R2		// arg 3 - old
   324  	MOVW	0(R0), R0		// arg 1 - sig
   325  	CALL	libc_sigaction(SB)
   326  	CMP	$-1, R0
   327  	BNE	3(PC)
   328  	MOVD	$0, R0			// crash on syscall failure
   329  	MOVD	R0, (R0)
   330  	RET
   331  
   332  TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   333  	MOVD	8(R0), R1		// arg 2 - new
   334  	MOVD	16(R0), R2		// arg 3 - old
   335  	MOVW	0(R0), R0		// arg 1 - how
   336  	CALL	libc_pthread_sigmask(SB)
   337  	CMP	$-1, R0
   338  	BNE	3(PC)
   339  	MOVD	$0, R0			// crash on syscall failure
   340  	MOVD	R0, (R0)
   341  	RET
   342  
   343  TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   344  	MOVD	8(R0), R1		// arg 2 - old
   345  	MOVD	0(R0), R0		// arg 1 - new
   346  	CALL	libc_sigaltstack(SB)
   347  	CMP	$-1, R0
   348  	BNE	3(PC)
   349  	MOVD	$0, R0			// crash on syscall failure
   350  	MOVD	R0, (R0)
   351  	RET
   352  
   353  // syscall calls a function in libc on behalf of the syscall package.
   354  // syscall takes a pointer to a struct like:
   355  // struct {
   356  //	fn    uintptr
   357  //	a1    uintptr
   358  //	a2    uintptr
   359  //	a3    uintptr
   360  //	r1    uintptr
   361  //	r2    uintptr
   362  //	err   uintptr
   363  // }
   364  // syscall must be called on the g0 stack with the
   365  // C calling convention (use libcCall).
   366  //
   367  // syscall expects a 32-bit result and tests for 32-bit -1
   368  // to decide there was an error.
   369  TEXT runtime·syscall(SB),NOSPLIT,$0
   370  	MOVD    R0, R19			// pointer to args
   371  
   372  	MOVD	(0*8)(R19), R11		// fn
   373  	MOVD	(1*8)(R19), R0		// a1
   374  	MOVD	(2*8)(R19), R1		// a2
   375  	MOVD	(3*8)(R19), R2		// a3
   376  	MOVD	$0, R3			// vararg
   377  
   378  	CALL	R11
   379  
   380  	MOVD	R0, (4*8)(R19)		// r1
   381  	MOVD	R1, (5*8)(R19)		// r2
   382  
   383  	// Standard libc functions return -1 on error
   384  	// and set errno.
   385  	CMPW	$-1, R0
   386  	BNE	ok
   387  
   388  	// Get error code from libc.
   389  	CALL	libc_errno(SB)
   390  	MOVW	(R0), R0
   391  	MOVD	R0, (6*8)(R19)		// err
   392  
   393  ok:
   394  	RET
   395  
   396  // syscallX calls a function in libc on behalf of the syscall package.
   397  // syscallX takes a pointer to a struct like:
   398  // struct {
   399  //	fn    uintptr
   400  //	a1    uintptr
   401  //	a2    uintptr
   402  //	a3    uintptr
   403  //	r1    uintptr
   404  //	r2    uintptr
   405  //	err   uintptr
   406  // }
   407  // syscallX must be called on the g0 stack with the
   408  // C calling convention (use libcCall).
   409  //
   410  // syscallX is like syscall but expects a 64-bit result
   411  // and tests for 64-bit -1 to decide there was an error.
   412  TEXT runtime·syscallX(SB),NOSPLIT,$0
   413  	MOVD    R0, R19			// pointer to args
   414  
   415  	MOVD	(0*8)(R19), R11		// fn
   416  	MOVD	(1*8)(R19), R0		// a1
   417  	MOVD	(2*8)(R19), R1		// a2
   418  	MOVD	(3*8)(R19), R2		// a3
   419  	MOVD	$0, R3			// vararg
   420  
   421  	CALL	R11
   422  
   423  	MOVD	R0, (4*8)(R19)		// r1
   424  	MOVD	R1, (5*8)(R19)		// r2
   425  
   426  	// Standard libc functions return -1 on error
   427  	// and set errno.
   428  	CMP	$-1, R0
   429  	BNE	ok
   430  
   431  	// Get error code from libc.
   432  	CALL	libc_errno(SB)
   433  	MOVW	(R0), R0
   434  	MOVD	R0, (6*8)(R19)		// err
   435  
   436  ok:
   437  	RET
   438  
   439  // syscall6 calls a function in libc on behalf of the syscall package.
   440  // syscall6 takes a pointer to a struct like:
   441  // struct {
   442  //	fn    uintptr
   443  //	a1    uintptr
   444  //	a2    uintptr
   445  //	a3    uintptr
   446  //	a4    uintptr
   447  //	a5    uintptr
   448  //	a6    uintptr
   449  //	r1    uintptr
   450  //	r2    uintptr
   451  //	err   uintptr
   452  // }
   453  // syscall6 must be called on the g0 stack with the
   454  // C calling convention (use libcCall).
   455  //
   456  // syscall6 expects a 32-bit result and tests for 32-bit -1
   457  // to decide there was an error.
   458  TEXT runtime·syscall6(SB),NOSPLIT,$0
   459  	MOVD    R0, R19			// pointer to args
   460  
   461  	MOVD	(0*8)(R19), R11		// fn
   462  	MOVD	(1*8)(R19), R0		// a1
   463  	MOVD	(2*8)(R19), R1		// a2
   464  	MOVD	(3*8)(R19), R2		// a3
   465  	MOVD	(4*8)(R19), R3		// a4
   466  	MOVD	(5*8)(R19), R4		// a5
   467  	MOVD	(6*8)(R19), R5		// a6
   468  	MOVD	$0, R6			// vararg
   469  
   470  	CALL	R11
   471  
   472  	MOVD	R0, (7*8)(R19)		// r1
   473  	MOVD	R1, (8*8)(R19)		// r2
   474  
   475  	// Standard libc functions return -1 on error
   476  	// and set errno.
   477  	CMPW	$-1, R0
   478  	BNE	ok
   479  
   480  	// Get error code from libc.
   481  	CALL	libc_errno(SB)
   482  	MOVW	(R0), R0
   483  	MOVD	R0, (9*8)(R19)		// err
   484  
   485  ok:
   486  	RET
   487  
   488  // syscall6X calls a function in libc on behalf of the syscall package.
   489  // syscall6X takes a pointer to a struct like:
   490  // struct {
   491  //	fn    uintptr
   492  //	a1    uintptr
   493  //	a2    uintptr
   494  //	a3    uintptr
   495  //	a4    uintptr
   496  //	a5    uintptr
   497  //	a6    uintptr
   498  //	r1    uintptr
   499  //	r2    uintptr
   500  //	err   uintptr
   501  // }
   502  // syscall6X must be called on the g0 stack with the
   503  // C calling convention (use libcCall).
   504  //
   505  // syscall6X is like syscall6 but expects a 64-bit result
   506  // and tests for 64-bit -1 to decide there was an error.
   507  TEXT runtime·syscall6X(SB),NOSPLIT,$0
   508  	MOVD    R0, R19			// pointer to args
   509  
   510  	MOVD	(0*8)(R19), R11		// fn
   511  	MOVD	(1*8)(R19), R0		// a1
   512  	MOVD	(2*8)(R19), R1		// a2
   513  	MOVD	(3*8)(R19), R2		// a3
   514  	MOVD	(4*8)(R19), R3		// a4
   515  	MOVD	(5*8)(R19), R4		// a5
   516  	MOVD	(6*8)(R19), R5		// a6
   517  	MOVD	$0, R6			// vararg
   518  
   519  	CALL	R11
   520  
   521  	MOVD	R0, (7*8)(R19)		// r1
   522  	MOVD	R1, (8*8)(R19)		// r2
   523  
   524  	// Standard libc functions return -1 on error
   525  	// and set errno.
   526  	CMP	$-1, R0
   527  	BNE	ok
   528  
   529  	// Get error code from libc.
   530  	CALL	libc_errno(SB)
   531  	MOVW	(R0), R0
   532  	MOVD	R0, (9*8)(R19)		// err
   533  
   534  ok:
   535  	RET
   536  
   537  // syscall10 calls a function in libc on behalf of the syscall package.
   538  // syscall10 takes a pointer to a struct like:
   539  // struct {
   540  //	fn    uintptr
   541  //	a1    uintptr
   542  //	a2    uintptr
   543  //	a3    uintptr
   544  //	a4    uintptr
   545  //	a5    uintptr
   546  //	a6    uintptr
   547  //	a7    uintptr
   548  //	a8    uintptr
   549  //	a9    uintptr
   550  //	a10   uintptr
   551  //	r1    uintptr
   552  //	r2    uintptr
   553  //	err   uintptr
   554  // }
   555  // syscall10 must be called on the g0 stack with the
   556  // C calling convention (use libcCall).
   557  TEXT runtime·syscall10(SB),NOSPLIT,$0
   558  	MOVD    R0, R19			// pointer to args
   559  
   560  	MOVD	(0*8)(R19), R11		// fn
   561  	MOVD	(1*8)(R19), R0		// a1
   562  	MOVD	(2*8)(R19), R1		// a2
   563  	MOVD	(3*8)(R19), R2		// a3
   564  	MOVD	(4*8)(R19), R3		// a4
   565  	MOVD	(5*8)(R19), R4		// a5
   566  	MOVD	(6*8)(R19), R5		// a6
   567  	MOVD	(7*8)(R19), R6		// a7
   568  	MOVD	(8*8)(R19), R7		// a8
   569  	MOVD	(9*8)(R19), R8		// a9
   570  	MOVD	(10*8)(R19), R9		// a10
   571  	MOVD	$0, R10			// vararg
   572  
   573  	CALL	R11
   574  
   575  	MOVD	R0, (11*8)(R19)		// r1
   576  	MOVD	R1, (12*8)(R19)		// r2
   577  
   578  	// Standard libc functions return -1 on error
   579  	// and set errno.
   580  	CMPW	$-1, R0
   581  	BNE	ok
   582  
   583  	// Get error code from libc.
   584  	CALL	libc_errno(SB)
   585  	MOVW	(R0), R0
   586  	MOVD	R0, (13*8)(R19)		// err
   587  
   588  ok:
   589  	RET
   590  
   591  // syscall10X calls a function in libc on behalf of the syscall package.
   592  // syscall10X takes a pointer to a struct like:
   593  // struct {
   594  //	fn    uintptr
   595  //	a1    uintptr
   596  //	a2    uintptr
   597  //	a3    uintptr
   598  //	a4    uintptr
   599  //	a5    uintptr
   600  //	a6    uintptr
   601  //	a7    uintptr
   602  //	a8    uintptr
   603  //	a9    uintptr
   604  //	a10   uintptr
   605  //	r1    uintptr
   606  //	r2    uintptr
   607  //	err   uintptr
   608  // }
   609  // syscall10X must be called on the g0 stack with the
   610  // C calling convention (use libcCall).
   611  //
   612  // syscall10X is like syscall10 but expects a 64-bit result
   613  // and tests for 64-bit -1 to decide there was an error.
   614  TEXT runtime·syscall10X(SB),NOSPLIT,$0
   615  	MOVD    R0, R19			// pointer to args
   616  
   617  	MOVD	(0*8)(R19), R11		// fn
   618  	MOVD	(1*8)(R19), R0		// a1
   619  	MOVD	(2*8)(R19), R1		// a2
   620  	MOVD	(3*8)(R19), R2		// a3
   621  	MOVD	(4*8)(R19), R3		// a4
   622  	MOVD	(5*8)(R19), R4		// a5
   623  	MOVD	(6*8)(R19), R5		// a6
   624  	MOVD	(7*8)(R19), R6		// a7
   625  	MOVD	(8*8)(R19), R7		// a8
   626  	MOVD	(9*8)(R19), R8		// a9
   627  	MOVD	(10*8)(R19), R9		// a10
   628  	MOVD	$0, R10			// vararg
   629  
   630  	CALL	R11
   631  
   632  	MOVD	R0, (11*8)(R19)		// r1
   633  	MOVD	R1, (12*8)(R19)		// r2
   634  
   635  	// Standard libc functions return -1 on error
   636  	// and set errno.
   637  	CMP	$-1, R0
   638  	BNE	ok
   639  
   640  	// Get error code from libc.
   641  	CALL	libc_errno(SB)
   642  	MOVW	(R0), R0
   643  	MOVD	R0, (13*8)(R19)		// err
   644  
   645  ok:
   646  	RET
   647  
   648  TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
   649  	MOVD	R0, R19			// pointer to args
   650  	CALL	libc_issetugid(SB)
   651  	MOVW	R0, 0(R19)		// return value
   652  	RET
   653  

View as plain text