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

View as plain text