...

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

View as plain text