Text file src/runtime/sys_darwin_arm64.s

     1  // Copyright 2015 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, Darwin
     6  // System calls are implemented in libSystem, this file contains
     7  // trampolines that convert from Go to C calling convention.
     8  
     9  #include "go_asm.h"
    10  #include "go_tls.h"
    11  #include "textflag.h"
    12  #include "cgo/abi_arm64.h"
    13  
    14  #define CLOCK_REALTIME		0
    15  
    16  TEXT notok<>(SB),NOSPLIT,$0
    17  	MOVD	$0, R8
    18  	MOVD	R8, (R8)
    19  	B	0(PC)
    20  
    21  TEXT runtime·open_trampoline(SB),NOSPLIT,$0
    22  	SUB	$16, RSP
    23  	MOVW	8(R0), R1	// arg 2 flags
    24  	MOVW	12(R0), R2	// arg 3 mode
    25  	MOVW	R2, (RSP)	// arg 3 is variadic, pass on stack
    26  	MOVD	0(R0), R0	// arg 1 pathname
    27  	BL	libc_open(SB)
    28  	ADD	$16, RSP
    29  	RET
    30  
    31  TEXT runtime·close_trampoline(SB),NOSPLIT,$0
    32  	MOVW	0(R0), R0	// arg 1 fd
    33  	BL	libc_close(SB)
    34  	RET
    35  
    36  TEXT runtime·write_trampoline(SB),NOSPLIT,$0
    37  	MOVD	8(R0), R1	// arg 2 buf
    38  	MOVW	16(R0), R2	// arg 3 count
    39  	MOVW	0(R0), R0	// arg 1 fd
    40  	BL	libc_write(SB)
    41  	MOVD	$-1, R1
    42  	CMP	R0, R1
    43  	BNE	noerr
    44  	BL	libc_error(SB)
    45  	MOVW	(R0), R0
    46  	NEG	R0, R0		// caller expects negative errno value
    47  noerr:
    48  	RET
    49  
    50  TEXT runtime·read_trampoline(SB),NOSPLIT,$0
    51  	MOVD	8(R0), R1	// arg 2 buf
    52  	MOVW	16(R0), R2	// arg 3 count
    53  	MOVW	0(R0), R0	// arg 1 fd
    54  	BL	libc_read(SB)
    55  	MOVD	$-1, R1
    56  	CMP	R0, R1
    57  	BNE	noerr
    58  	BL	libc_error(SB)
    59  	MOVW	(R0), R0
    60  	NEG	R0, R0		// caller expects negative errno value
    61  noerr:
    62  	RET
    63  
    64  TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0
    65  	BL	libc_pipe(SB)	// pointer already in R0
    66  	CMP	$0, R0
    67  	BEQ	3(PC)
    68  	BL	libc_error(SB)	// return negative errno value
    69  	NEG	R0, R0
    70  	RET
    71  
    72  TEXT runtime·exit_trampoline(SB),NOSPLIT|NOFRAME,$0
    73  	MOVW	0(R0), R0
    74  	BL	libc_exit(SB)
    75  	MOVD	$1234, R0
    76  	MOVD	$1002, R1
    77  	MOVD	R0, (R1)	// fail hard
    78  
    79  TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
    80  	MOVD	0(R0), R19	// signal
    81  	BL	libc_getpid(SB)
    82  	// arg 1 pid already in R0 from getpid
    83  	MOVD	R19, R1	// arg 2 signal
    84  	BL	libc_kill(SB)
    85  	RET
    86  
    87  TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
    88  	MOVD	R0, R19
    89  	MOVD	0(R19), R0	// arg 1 addr
    90  	MOVD	8(R19), R1	// arg 2 len
    91  	MOVW	16(R19), R2	// arg 3 prot
    92  	MOVW	20(R19), R3	// arg 4 flags
    93  	MOVW	24(R19), R4	// arg 5 fd
    94  	MOVW	28(R19), R5	// arg 6 off
    95  	BL	libc_mmap(SB)
    96  	MOVD	$0, R1
    97  	MOVD	$-1, R2
    98  	CMP	R0, R2
    99  	BNE	ok
   100  	BL	libc_error(SB)
   101  	MOVW	(R0), R1
   102  	MOVD	$0, R0
   103  ok:
   104  	MOVD	R0, 32(R19) // ret 1 p
   105  	MOVD	R1, 40(R19)	// ret 2 err
   106  	RET
   107  
   108  TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
   109  	MOVD	8(R0), R1	// arg 2 len
   110  	MOVD	0(R0), R0	// arg 1 addr
   111  	BL	libc_munmap(SB)
   112  	CMP	$0, R0
   113  	BEQ	2(PC)
   114  	BL	notok<>(SB)
   115  	RET
   116  
   117  TEXT runtime·madvise_trampoline(SB),NOSPLIT,$0
   118  	MOVD	8(R0), R1	// arg 2 len
   119  	MOVW	16(R0), R2	// arg 3 advice
   120  	MOVD	0(R0), R0	// arg 1 addr
   121  	BL	libc_madvise(SB)
   122  	RET
   123  
   124  TEXT runtime·mlock_trampoline(SB),NOSPLIT,$0
   125  	MOVD	8(R0), R1	// arg 2 len
   126  	MOVD	0(R0), R0	// arg 1 addr
   127  	BL	libc_mlock(SB)
   128  	RET
   129  
   130  TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
   131  	MOVD	8(R0), R1	// arg 2 new
   132  	MOVD	16(R0), R2	// arg 3 old
   133  	MOVW	0(R0), R0	// arg 1 which
   134  	BL	libc_setitimer(SB)
   135  	RET
   136  
   137  TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
   138  	MOVD	R0, R1			// arg 2 timespec
   139  	MOVW	$CLOCK_REALTIME, R0 	// arg 1 clock_id
   140  	BL	libc_clock_gettime(SB)
   141  	RET
   142  
   143  GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
   144  
   145  TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40
   146  	MOVD	R0, R19
   147  	BL	libc_mach_absolute_time(SB)
   148  	MOVD	R0, 0(R19)
   149  	MOVW	timebase<>+machTimebaseInfo_numer(SB), R20
   150  	MOVD	$timebase<>+machTimebaseInfo_denom(SB), R21
   151  	LDARW	(R21), R21	// atomic read
   152  	CMP	$0, R21
   153  	BNE	initialized
   154  
   155  	SUB	$(machTimebaseInfo__size+15)/16*16, RSP
   156  	MOVD	RSP, R0
   157  	BL	libc_mach_timebase_info(SB)
   158  	MOVW	machTimebaseInfo_numer(RSP), R20
   159  	MOVW	machTimebaseInfo_denom(RSP), R21
   160  	ADD	$(machTimebaseInfo__size+15)/16*16, RSP
   161  
   162  	MOVW	R20, timebase<>+machTimebaseInfo_numer(SB)
   163  	MOVD	$timebase<>+machTimebaseInfo_denom(SB), R22
   164  	STLRW	R21, (R22)	// atomic write
   165  
   166  initialized:
   167  	MOVW	R20, 8(R19)
   168  	MOVW	R21, 12(R19)
   169  	RET
   170  
   171  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   172  	MOVW	sig+8(FP), R0
   173  	MOVD	info+16(FP), R1
   174  	MOVD	ctx+24(FP), R2
   175  	MOVD	fn+0(FP), R11
   176  	BL	(R11)
   177  	RET
   178  
   179  TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$176
   180  	// Save callee-save registers in the case of signal forwarding.
   181  	// Please refer to https://golang.org/issue/31827 .
   182  	SAVE_R19_TO_R28(8*4)
   183  	SAVE_F8_TO_F15(8*14)
   184  
   185  	// Save arguments.
   186  	MOVW	R0, (8*1)(RSP)	// sig
   187  	MOVD	R1, (8*2)(RSP)	// info
   188  	MOVD	R2, (8*3)(RSP)	// ctx
   189  
   190  	// this might be called in external code context,
   191  	// where g is not set.
   192  	BL	runtime·load_g(SB)
   193  
   194  #ifdef GOOS_ios
   195  	MOVD	RSP, R6
   196  	CMP	$0, g
   197  	BEQ	nog
   198  	// iOS always use the main stack to run the signal handler.
   199  	// We need to switch to gsignal ourselves.
   200  	MOVD	g_m(g), R11
   201  	MOVD	m_gsignal(R11), R5
   202  	MOVD	(g_stack+stack_hi)(R5), R6
   203  
   204  nog:
   205  	// Restore arguments.
   206  	MOVW	(8*1)(RSP), R0
   207  	MOVD	(8*2)(RSP), R1
   208  	MOVD	(8*3)(RSP), R2
   209  
   210  	// Reserve space for args and the stack pointer on the
   211  	// gsignal stack.
   212  	SUB	$48, R6
   213  	// Save stack pointer.
   214  	MOVD	RSP, R4
   215  	MOVD	R4, (8*4)(R6)
   216  	// Switch to gsignal stack.
   217  	MOVD	R6, RSP
   218  
   219  	// Save arguments.
   220  	MOVW	R0, (8*1)(RSP)
   221  	MOVD	R1, (8*2)(RSP)
   222  	MOVD	R2, (8*3)(RSP)
   223  #endif
   224  
   225  	// Call sigtrampgo.
   226  	MOVD	$runtime·sigtrampgo(SB), R11
   227  	BL	(R11)
   228  
   229  #ifdef GOOS_ios
   230  	// Switch to old stack.
   231  	MOVD	(8*4)(RSP), R5
   232  	MOVD	R5, RSP
   233  #endif
   234  
   235  	// Restore callee-save registers.
   236  	RESTORE_R19_TO_R28(8*4)
   237  	RESTORE_F8_TO_F15(8*14)
   238  
   239  	RET
   240  
   241  TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
   242  	JMP	runtime·sigtramp(SB)
   243  
   244  TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   245  	MOVD	8(R0), R1	// arg 2 new
   246  	MOVD	16(R0), R2	// arg 3 old
   247  	MOVW	0(R0), R0	// arg 1 how
   248  	BL	libc_pthread_sigmask(SB)
   249  	CMP	$0, R0
   250  	BEQ	2(PC)
   251  	BL	notok<>(SB)
   252  	RET
   253  
   254  TEXT runtime·sigaction_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 how
   258  	BL	libc_sigaction(SB)
   259  	CMP	$0, R0
   260  	BEQ	2(PC)
   261  	BL	notok<>(SB)
   262  	RET
   263  
   264  TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   265  	MOVW	0(R0), R0	// arg 1 usec
   266  	BL	libc_usleep(SB)
   267  	RET
   268  
   269  TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
   270  	MOVW	8(R0), R1	// arg 2 miblen
   271  	MOVD	16(R0), R2	// arg 3 oldp
   272  	MOVD	24(R0), R3	// arg 4 oldlenp
   273  	MOVD	32(R0), R4	// arg 5 newp
   274  	MOVD	40(R0), R5	// arg 6 newlen
   275  	MOVD	0(R0), R0	// arg 1 mib
   276  	BL	libc_sysctl(SB)
   277  	RET
   278  
   279  TEXT runtime·sysctlbyname_trampoline(SB),NOSPLIT,$0
   280  	MOVD	8(R0), R1	// arg 2 oldp
   281  	MOVD	16(R0), R2	// arg 3 oldlenp
   282  	MOVD	24(R0), R3	// arg 4 newp
   283  	MOVD	32(R0), R4	// arg 5 newlen
   284  	MOVD	0(R0), R0	// arg 1 name
   285  	BL	libc_sysctlbyname(SB)
   286  	RET
   287  
   288  
   289  TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   290  	BL	libc_kqueue(SB)
   291  	RET
   292  
   293  TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
   294  	MOVD	8(R0), R1	// arg 2 keventt
   295  	MOVW	16(R0), R2	// arg 3 nch
   296  	MOVD	24(R0), R3	// arg 4 ev
   297  	MOVW	32(R0), R4	// arg 5 nev
   298  	MOVD	40(R0), R5	// arg 6 ts
   299  	MOVW	0(R0), R0	// arg 1 kq
   300  	BL	libc_kevent(SB)
   301  	MOVD	$-1, R2
   302  	CMP	R0, R2
   303  	BNE	ok
   304  	BL	libc_error(SB)
   305  	MOVW	(R0), R0	// errno
   306  	NEG	R0, R0	// caller wants it as a negative error code
   307  ok:
   308  	RET
   309  
   310  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   311  	SUB	$16, RSP
   312  	MOVW	4(R0), R1	// arg 2 cmd
   313  	MOVW	8(R0), R2	// arg 3 arg
   314  	MOVW	R2, (RSP)	// arg 3 is variadic, pass on stack
   315  	MOVW	0(R0), R0	// arg 1 fd
   316  	BL	libc_fcntl(SB)
   317  	ADD	$16, RSP
   318  	RET
   319  
   320  TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   321  #ifdef GOOS_ios
   322  	// sigaltstack on iOS is not supported and will always
   323  	// run the signal handler on the main stack, so our sigtramp has
   324  	// to do the stack switch ourselves.
   325  	MOVW	$43, R0
   326  	BL	libc_exit(SB)
   327  #else
   328  	MOVD	8(R0), R1		// arg 2 old
   329  	MOVD	0(R0), R0		// arg 1 new
   330  	CALL	libc_sigaltstack(SB)
   331  	CBZ	R0, 2(PC)
   332  	BL	notok<>(SB)
   333  #endif
   334  	RET
   335  
   336  // Thread related functions
   337  
   338  // mstart_stub is the first function executed on a new thread started by pthread_create.
   339  // It just does some low-level setup and then calls mstart.
   340  // Note: called with the C calling convention.
   341  TEXT runtime·mstart_stub(SB),NOSPLIT,$160
   342  	// R0 points to the m.
   343  	// We are already on m's g0 stack.
   344  
   345  	// Save callee-save registers.
   346  	SAVE_R19_TO_R28(8)
   347  	SAVE_F8_TO_F15(88)
   348  
   349  	MOVD	m_g0(R0), g
   350  	BL	·save_g(SB)
   351  
   352  	BL	runtime·mstart(SB)
   353  
   354  	// Restore callee-save registers.
   355  	RESTORE_R19_TO_R28(8)
   356  	RESTORE_F8_TO_F15(88)
   357  
   358  	// Go is all done with this OS thread.
   359  	// Tell pthread everything is ok (we never join with this thread, so
   360  	// the value here doesn't really matter).
   361  	MOVD	$0, R0
   362  
   363  	RET
   364  
   365  TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
   366  	MOVD	0(R0), R0	// arg 1 attr
   367  	BL	libc_pthread_attr_init(SB)
   368  	RET
   369  
   370  TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
   371  	MOVD	8(R0), R1	// arg 2 size
   372  	MOVD	0(R0), R0	// arg 1 attr
   373  	BL	libc_pthread_attr_getstacksize(SB)
   374  	RET
   375  
   376  TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
   377  	MOVD	8(R0), R1	// arg 2 state
   378  	MOVD	0(R0), R0	// arg 1 attr
   379  	BL	libc_pthread_attr_setdetachstate(SB)
   380  	RET
   381  
   382  TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
   383  	SUB	$16, RSP
   384  	MOVD	0(R0), R1	// arg 2 state
   385  	MOVD	8(R0), R2	// arg 3 start
   386  	MOVD	16(R0), R3	// arg 4 arg
   387  	MOVD	RSP, R0 	// arg 1 &threadid (which we throw away)
   388  	BL	libc_pthread_create(SB)
   389  	ADD	$16, RSP
   390  	RET
   391  
   392  TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
   393  	MOVW	0(R0), R0	// arg 1 sig
   394  	BL	libc_raise(SB)
   395  	RET
   396  
   397  TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
   398  	MOVD	8(R0), R1	// arg 2 attr
   399  	MOVD	0(R0), R0	// arg 1 mutex
   400  	BL	libc_pthread_mutex_init(SB)
   401  	RET
   402  
   403  TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
   404  	MOVD	0(R0), R0	// arg 1 mutex
   405  	BL	libc_pthread_mutex_lock(SB)
   406  	RET
   407  
   408  TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
   409  	MOVD	0(R0), R0	// arg 1 mutex
   410  	BL	libc_pthread_mutex_unlock(SB)
   411  	RET
   412  
   413  TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
   414  	MOVD	8(R0), R1	// arg 2 attr
   415  	MOVD	0(R0), R0	// arg 1 cond
   416  	BL	libc_pthread_cond_init(SB)
   417  	RET
   418  
   419  TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
   420  	MOVD	8(R0), R1	// arg 2 mutex
   421  	MOVD	0(R0), R0	// arg 1 cond
   422  	BL	libc_pthread_cond_wait(SB)
   423  	RET
   424  
   425  TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
   426  	MOVD	8(R0), R1	// arg 2 mutex
   427  	MOVD	16(R0), R2	// arg 3 timeout
   428  	MOVD	0(R0), R0	// arg 1 cond
   429  	BL	libc_pthread_cond_timedwait_relative_np(SB)
   430  	RET
   431  
   432  TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
   433  	MOVD	0(R0), R0	// arg 1 cond
   434  	BL	libc_pthread_cond_signal(SB)
   435  	RET
   436  
   437  TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
   438  	MOVD	R0, R19		// R19 is callee-save
   439  	BL	libc_pthread_self(SB)
   440  	MOVD	R0, 0(R19)	// return value
   441  	RET
   442  
   443  TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
   444  	MOVD	8(R0), R1	// arg 2 sig
   445  	MOVD	0(R0), R0	// arg 1 thread
   446  	BL	libc_pthread_kill(SB)
   447  	RET
   448  
   449  TEXT runtime·pthread_key_create_trampoline(SB),NOSPLIT,$0
   450  	MOVD	8(R0), R1	// arg 2 destructor
   451  	MOVD	0(R0), R0	// arg 1 *key
   452  	BL	libc_pthread_key_create(SB)
   453  	RET
   454  
   455  TEXT runtime·pthread_setspecific_trampoline(SB),NOSPLIT,$0
   456  	MOVD	8(R0), R1	// arg 2 value
   457  	MOVD	0(R0), R0	// arg 1 key
   458  	BL	libc_pthread_setspecific(SB)
   459  	RET
   460  
   461  // syscall calls a function in libc on behalf of the syscall package.
   462  // syscall takes a pointer to a struct like:
   463  // struct {
   464  //	fn    uintptr
   465  //	a1    uintptr
   466  //	a2    uintptr
   467  //	a3    uintptr
   468  //	r1    uintptr
   469  //	r2    uintptr
   470  //	err   uintptr
   471  // }
   472  // syscall must be called on the g0 stack with the
   473  // C calling convention (use libcCall).
   474  TEXT runtime·syscall(SB),NOSPLIT,$0
   475  	SUB	$16, RSP	// push structure pointer
   476  	MOVD	R0, 8(RSP)
   477  
   478  	MOVD	0(R0), R12	// fn
   479  	MOVD	16(R0), R1	// a2
   480  	MOVD	24(R0), R2	// a3
   481  	MOVD	8(R0), R0	// a1
   482  
   483  	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   484  	// (Because ios decided not to adhere to the standard arm64 calling convention, sigh...)
   485  	// The only libSystem calls we support that are vararg are open, fcntl, and ioctl,
   486  	// which are all of the form fn(x, y, ...). So we just need to put the 3rd arg
   487  	// on the stack as well.
   488  	// If we ever have other vararg libSystem calls, we might need to handle more cases.
   489  	MOVD	R2, (RSP)
   490  
   491  	BL	(R12)
   492  
   493  	MOVD	8(RSP), R2	// pop structure pointer
   494  	ADD	$16, RSP
   495  	MOVD	R0, 32(R2)	// save r1
   496  	MOVD	R1, 40(R2)	// save r2
   497  	CMPW	$-1, R0
   498  	BNE	ok
   499  	SUB	$16, RSP	// push structure pointer
   500  	MOVD	R2, 8(RSP)
   501  	BL	libc_error(SB)
   502  	MOVW	(R0), R0
   503  	MOVD	8(RSP), R2	// pop structure pointer
   504  	ADD	$16, RSP
   505  	MOVD	R0, 48(R2)	// save err
   506  ok:
   507  	RET
   508  
   509  // syscallX calls a function in libc on behalf of the syscall package.
   510  // syscallX takes a pointer to a struct like:
   511  // struct {
   512  //	fn    uintptr
   513  //	a1    uintptr
   514  //	a2    uintptr
   515  //	a3    uintptr
   516  //	r1    uintptr
   517  //	r2    uintptr
   518  //	err   uintptr
   519  // }
   520  // syscallX must be called on the g0 stack with the
   521  // C calling convention (use libcCall).
   522  TEXT runtime·syscallX(SB),NOSPLIT,$0
   523  	SUB	$16, RSP	// push structure pointer
   524  	MOVD	R0, (RSP)
   525  
   526  	MOVD	0(R0), R12	// fn
   527  	MOVD	16(R0), R1	// a2
   528  	MOVD	24(R0), R2	// a3
   529  	MOVD	8(R0), R0	// a1
   530  	BL	(R12)
   531  
   532  	MOVD	(RSP), R2	// pop structure pointer
   533  	ADD	$16, RSP
   534  	MOVD	R0, 32(R2)	// save r1
   535  	MOVD	R1, 40(R2)	// save r2
   536  	CMP	$-1, R0
   537  	BNE	ok
   538  	SUB	$16, RSP	// push structure pointer
   539  	MOVD	R2, (RSP)
   540  	BL	libc_error(SB)
   541  	MOVW	(R0), R0
   542  	MOVD	(RSP), R2	// pop structure pointer
   543  	ADD	$16, RSP
   544  	MOVD	R0, 48(R2)	// save err
   545  ok:
   546  	RET
   547  
   548  // syscallPtr is like syscallX except that the libc function reports an
   549  // error by returning NULL and setting errno.
   550  TEXT runtime·syscallPtr(SB),NOSPLIT,$0
   551  	SUB	$16, RSP	// push structure pointer
   552  	MOVD	R0, (RSP)
   553  
   554  	MOVD	0(R0), R12	// fn
   555  	MOVD	16(R0), R1	// a2
   556  	MOVD	24(R0), R2	// a3
   557  	MOVD	8(R0), R0	// a1
   558  	BL	(R12)
   559  
   560  	MOVD	(RSP), R2	// pop structure pointer
   561  	ADD	$16, RSP
   562  	MOVD	R0, 32(R2)	// save r1
   563  	MOVD	R1, 40(R2)	// save r2
   564  	CMP	$0, R0
   565  	BNE	ok
   566  	SUB	$16, RSP	// push structure pointer
   567  	MOVD	R2, (RSP)
   568  	BL	libc_error(SB)
   569  	MOVW	(R0), R0
   570  	MOVD	(RSP), R2	// pop structure pointer
   571  	ADD	$16, RSP
   572  	MOVD	R0, 48(R2)	// save err
   573  ok:
   574  	RET
   575  
   576  // syscall6 calls a function in libc on behalf of the syscall package.
   577  // syscall6 takes a pointer to a struct like:
   578  // struct {
   579  //	fn    uintptr
   580  //	a1    uintptr
   581  //	a2    uintptr
   582  //	a3    uintptr
   583  //	a4    uintptr
   584  //	a5    uintptr
   585  //	a6    uintptr
   586  //	r1    uintptr
   587  //	r2    uintptr
   588  //	err   uintptr
   589  // }
   590  // syscall6 must be called on the g0 stack with the
   591  // C calling convention (use libcCall).
   592  TEXT runtime·syscall6(SB),NOSPLIT,$0
   593  	SUB	$16, RSP	// push structure pointer
   594  	MOVD	R0, 8(RSP)
   595  
   596  	MOVD	0(R0), R12	// fn
   597  	MOVD	16(R0), R1	// a2
   598  	MOVD	24(R0), R2	// a3
   599  	MOVD	32(R0), R3	// a4
   600  	MOVD	40(R0), R4	// a5
   601  	MOVD	48(R0), R5	// a6
   602  	MOVD	8(R0), R0	// a1
   603  
   604  	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   605  	// See syscall above. The only function this applies to is openat, for which the 4th
   606  	// arg must be on the stack.
   607  	MOVD	R3, (RSP)
   608  
   609  	BL	(R12)
   610  
   611  	MOVD	8(RSP), R2	// pop structure pointer
   612  	ADD	$16, RSP
   613  	MOVD	R0, 56(R2)	// save r1
   614  	MOVD	R1, 64(R2)	// save r2
   615  	CMPW	$-1, R0
   616  	BNE	ok
   617  	SUB	$16, RSP	// push structure pointer
   618  	MOVD	R2, 8(RSP)
   619  	BL	libc_error(SB)
   620  	MOVW	(R0), R0
   621  	MOVD	8(RSP), R2	// pop structure pointer
   622  	ADD	$16, RSP
   623  	MOVD	R0, 72(R2)	// save err
   624  ok:
   625  	RET
   626  
   627  // syscall6X calls a function in libc on behalf of the syscall package.
   628  // syscall6X takes a pointer to a struct like:
   629  // struct {
   630  //	fn    uintptr
   631  //	a1    uintptr
   632  //	a2    uintptr
   633  //	a3    uintptr
   634  //	a4    uintptr
   635  //	a5    uintptr
   636  //	a6    uintptr
   637  //	r1    uintptr
   638  //	r2    uintptr
   639  //	err   uintptr
   640  // }
   641  // syscall6X must be called on the g0 stack with the
   642  // C calling convention (use libcCall).
   643  TEXT runtime·syscall6X(SB),NOSPLIT,$0
   644  	SUB	$16, RSP	// push structure pointer
   645  	MOVD	R0, (RSP)
   646  
   647  	MOVD	0(R0), R12	// fn
   648  	MOVD	16(R0), R1	// a2
   649  	MOVD	24(R0), R2	// a3
   650  	MOVD	32(R0), R3	// a4
   651  	MOVD	40(R0), R4	// a5
   652  	MOVD	48(R0), R5	// a6
   653  	MOVD	8(R0), R0	// a1
   654  	BL	(R12)
   655  
   656  	MOVD	(RSP), R2	// pop structure pointer
   657  	ADD	$16, RSP
   658  	MOVD	R0, 56(R2)	// save r1
   659  	MOVD	R1, 64(R2)	// save r2
   660  	CMP	$-1, R0
   661  	BNE	ok
   662  	SUB	$16, RSP	// push structure pointer
   663  	MOVD	R2, (RSP)
   664  	BL	libc_error(SB)
   665  	MOVW	(R0), R0
   666  	MOVD	(RSP), R2	// pop structure pointer
   667  	ADD	$16, RSP
   668  	MOVD	R0, 72(R2)	// save err
   669  ok:
   670  	RET
   671  
   672  // syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
   673  // takes 5 uintptrs and 1 float64, and only returns one value,
   674  // for use with standard C ABI functions.
   675  TEXT runtime·syscall_x509(SB),NOSPLIT,$0
   676  	SUB	$16, RSP	// push structure pointer
   677  	MOVD	R0, (RSP)
   678  
   679  	MOVD	0(R0), R12	// fn
   680  	MOVD	16(R0), R1	// a2
   681  	MOVD	24(R0), R2	// a3
   682  	MOVD	32(R0), R3	// a4
   683  	MOVD	40(R0), R4	// a5
   684  	FMOVD	48(R0), F0	// f1
   685  	MOVD	8(R0), R0	// a1
   686  	BL	(R12)
   687  
   688  	MOVD	(RSP), R2	// pop structure pointer
   689  	ADD	$16, RSP
   690  	MOVD	R0, 56(R2)	// save r1
   691  	RET
   692  

View as plain text