...

Text file src/runtime/sys_darwin_arm64.s

Documentation: runtime

     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
    16TEXT notok<>(SB),NOSPLIT,$0
    17	MOVD	$0, R8
    18	MOVD	R8, (R8)
    19	B	0(PC)
    20
    21TEXT 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
    31TEXT runtime·close_trampoline(SB),NOSPLIT,$0
    32	MOVW	0(R0), R0	// arg 1 fd
    33	BL	libc_close(SB)
    34	RET
    35
    36TEXT 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
    47noerr:
    48	RET
    49
    50TEXT 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
    61noerr:
    62	RET
    63
    64TEXT 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
    72TEXT 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
    79TEXT 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
    87TEXT 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
   103ok:
   104	MOVD	R0, 32(R19) // ret 1 p
   105	MOVD	R1, 40(R19)	// ret 2 err
   106	RET
   107
   108TEXT 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
   117TEXT 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
   124TEXT 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
   130TEXT 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
   137TEXT 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
   143GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
   144
   145TEXT 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
   166initialized:
   167	MOVW	R20, 8(R19)
   168	MOVW	R21, 12(R19)
   169	RET
   170
   171TEXT 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
   179TEXT 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
   204nog:
   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
   241TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
   242	JMP	runtime·sigtramp(SB)
   243
   244TEXT 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
   254TEXT 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
   264TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   265	MOVW	0(R0), R0	// arg 1 usec
   266	BL	libc_usleep(SB)
   267	RET
   268
   269TEXT 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
   279TEXT 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
   289TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   290	BL	libc_kqueue(SB)
   291	RET
   292
   293TEXT 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
   307ok:
   308	RET
   309
   310TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   311	SUB	$16, RSP
   312	MOVD	R0, R19
   313	MOVW	0(R19), R0	// arg 1 fd
   314	MOVW	4(R19), R1	// arg 2 cmd
   315	MOVW	8(R19), R2	// arg 3 arg
   316	MOVW	R2, (RSP)	// arg 3 is variadic, pass on stack
   317	BL	libc_fcntl(SB)
   318	MOVD	$0, R1
   319	MOVD	$-1, R2
   320	CMP	R0, R2
   321	BNE	noerr
   322	BL	libc_error(SB)
   323	MOVW	(R0), R1
   324	MOVW	$-1, R0
   325noerr:
   326	MOVW	R0, 12(R19)
   327	MOVW	R1, 16(R19)
   328	ADD	$16, RSP
   329	RET
   330
   331TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   332#ifdef GOOS_ios
   333	// sigaltstack on iOS is not supported and will always
   334	// run the signal handler on the main stack, so our sigtramp has
   335	// to do the stack switch ourselves.
   336	MOVW	$43, R0
   337	BL	libc_exit(SB)
   338#else
   339	MOVD	8(R0), R1		// arg 2 old
   340	MOVD	0(R0), R0		// arg 1 new
   341	CALL	libc_sigaltstack(SB)
   342	CBZ	R0, 2(PC)
   343	BL	notok<>(SB)
   344#endif
   345	RET
   346
   347// Thread related functions
   348
   349// mstart_stub is the first function executed on a new thread started by pthread_create.
   350// It just does some low-level setup and then calls mstart.
   351// Note: called with the C calling convention.
   352TEXT runtime·mstart_stub(SB),NOSPLIT,$160
   353	// R0 points to the m.
   354	// We are already on m's g0 stack.
   355
   356	// Save callee-save registers.
   357	SAVE_R19_TO_R28(8)
   358	SAVE_F8_TO_F15(88)
   359
   360	MOVD	m_g0(R0), g
   361	BL	·save_g(SB)
   362
   363	BL	runtime·mstart(SB)
   364
   365	// Restore callee-save registers.
   366	RESTORE_R19_TO_R28(8)
   367	RESTORE_F8_TO_F15(88)
   368
   369	// Go is all done with this OS thread.
   370	// Tell pthread everything is ok (we never join with this thread, so
   371	// the value here doesn't really matter).
   372	MOVD	$0, R0
   373
   374	RET
   375
   376TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
   377	MOVD	0(R0), R0	// arg 1 attr
   378	BL	libc_pthread_attr_init(SB)
   379	RET
   380
   381TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
   382	MOVD	8(R0), R1	// arg 2 size
   383	MOVD	0(R0), R0	// arg 1 attr
   384	BL	libc_pthread_attr_getstacksize(SB)
   385	RET
   386
   387TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
   388	MOVD	8(R0), R1	// arg 2 state
   389	MOVD	0(R0), R0	// arg 1 attr
   390	BL	libc_pthread_attr_setdetachstate(SB)
   391	RET
   392
   393TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
   394	SUB	$16, RSP
   395	MOVD	0(R0), R1	// arg 2 state
   396	MOVD	8(R0), R2	// arg 3 start
   397	MOVD	16(R0), R3	// arg 4 arg
   398	MOVD	RSP, R0 	// arg 1 &threadid (which we throw away)
   399	BL	libc_pthread_create(SB)
   400	ADD	$16, RSP
   401	RET
   402
   403TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
   404	MOVW	0(R0), R0	// arg 1 sig
   405	BL	libc_raise(SB)
   406	RET
   407
   408TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
   409	MOVD	8(R0), R1	// arg 2 attr
   410	MOVD	0(R0), R0	// arg 1 mutex
   411	BL	libc_pthread_mutex_init(SB)
   412	RET
   413
   414TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
   415	MOVD	0(R0), R0	// arg 1 mutex
   416	BL	libc_pthread_mutex_lock(SB)
   417	RET
   418
   419TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
   420	MOVD	0(R0), R0	// arg 1 mutex
   421	BL	libc_pthread_mutex_unlock(SB)
   422	RET
   423
   424TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
   425	MOVD	8(R0), R1	// arg 2 attr
   426	MOVD	0(R0), R0	// arg 1 cond
   427	BL	libc_pthread_cond_init(SB)
   428	RET
   429
   430TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
   431	MOVD	8(R0), R1	// arg 2 mutex
   432	MOVD	0(R0), R0	// arg 1 cond
   433	BL	libc_pthread_cond_wait(SB)
   434	RET
   435
   436TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
   437	MOVD	8(R0), R1	// arg 2 mutex
   438	MOVD	16(R0), R2	// arg 3 timeout
   439	MOVD	0(R0), R0	// arg 1 cond
   440	BL	libc_pthread_cond_timedwait_relative_np(SB)
   441	RET
   442
   443TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
   444	MOVD	0(R0), R0	// arg 1 cond
   445	BL	libc_pthread_cond_signal(SB)
   446	RET
   447
   448TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
   449	MOVD	R0, R19		// R19 is callee-save
   450	BL	libc_pthread_self(SB)
   451	MOVD	R0, 0(R19)	// return value
   452	RET
   453
   454TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
   455	MOVD	8(R0), R1	// arg 2 sig
   456	MOVD	0(R0), R0	// arg 1 thread
   457	BL	libc_pthread_kill(SB)
   458	RET
   459
   460TEXT runtime·pthread_key_create_trampoline(SB),NOSPLIT,$0
   461	MOVD	8(R0), R1	// arg 2 destructor
   462	MOVD	0(R0), R0	// arg 1 *key
   463	BL	libc_pthread_key_create(SB)
   464	RET
   465
   466TEXT runtime·pthread_setspecific_trampoline(SB),NOSPLIT,$0
   467	MOVD	8(R0), R1	// arg 2 value
   468	MOVD	0(R0), R0	// arg 1 key
   469	BL	libc_pthread_setspecific(SB)
   470	RET
   471
   472TEXT runtime·osinit_hack_trampoline(SB),NOSPLIT,$0
   473	MOVD	$0, R0	// arg 1 val
   474	BL	libc_notify_is_valid_token(SB)
   475	BL	libc_xpc_date_create_from_current(SB)
   476	RET
   477
   478// syscall calls a function in libc on behalf of the syscall package.
   479// syscall takes a pointer to a struct like:
   480// struct {
   481//	fn    uintptr
   482//	a1    uintptr
   483//	a2    uintptr
   484//	a3    uintptr
   485//	r1    uintptr
   486//	r2    uintptr
   487//	err   uintptr
   488// }
   489// syscall must be called on the g0 stack with the
   490// C calling convention (use libcCall).
   491TEXT runtime·syscall(SB),NOSPLIT,$0
   492	SUB	$16, RSP	// push structure pointer
   493	MOVD	R0, 8(RSP)
   494
   495	MOVD	0(R0), R12	// fn
   496	MOVD	16(R0), R1	// a2
   497	MOVD	24(R0), R2	// a3
   498	MOVD	8(R0), R0	// a1
   499
   500	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   501	// (Because ios decided not to adhere to the standard arm64 calling convention, sigh...)
   502	// The only libSystem calls we support that are vararg are open, fcntl, and ioctl,
   503	// which are all of the form fn(x, y, ...). So we just need to put the 3rd arg
   504	// on the stack as well.
   505	// If we ever have other vararg libSystem calls, we might need to handle more cases.
   506	MOVD	R2, (RSP)
   507
   508	BL	(R12)
   509
   510	MOVD	8(RSP), R2	// pop structure pointer
   511	ADD	$16, RSP
   512	MOVD	R0, 32(R2)	// save r1
   513	MOVD	R1, 40(R2)	// save r2
   514	CMPW	$-1, R0
   515	BNE	ok
   516	SUB	$16, RSP	// push structure pointer
   517	MOVD	R2, 8(RSP)
   518	BL	libc_error(SB)
   519	MOVW	(R0), R0
   520	MOVD	8(RSP), R2	// pop structure pointer
   521	ADD	$16, RSP
   522	MOVD	R0, 48(R2)	// save err
   523ok:
   524	RET
   525
   526// syscallX calls a function in libc on behalf of the syscall package.
   527// syscallX takes a pointer to a struct like:
   528// struct {
   529//	fn    uintptr
   530//	a1    uintptr
   531//	a2    uintptr
   532//	a3    uintptr
   533//	r1    uintptr
   534//	r2    uintptr
   535//	err   uintptr
   536// }
   537// syscallX must be called on the g0 stack with the
   538// C calling convention (use libcCall).
   539TEXT runtime·syscallX(SB),NOSPLIT,$0
   540	SUB	$16, RSP	// push structure pointer
   541	MOVD	R0, (RSP)
   542
   543	MOVD	0(R0), R12	// fn
   544	MOVD	16(R0), R1	// a2
   545	MOVD	24(R0), R2	// a3
   546	MOVD	8(R0), R0	// a1
   547	BL	(R12)
   548
   549	MOVD	(RSP), R2	// pop structure pointer
   550	ADD	$16, RSP
   551	MOVD	R0, 32(R2)	// save r1
   552	MOVD	R1, 40(R2)	// save r2
   553	CMP	$-1, R0
   554	BNE	ok
   555	SUB	$16, RSP	// push structure pointer
   556	MOVD	R2, (RSP)
   557	BL	libc_error(SB)
   558	MOVW	(R0), R0
   559	MOVD	(RSP), R2	// pop structure pointer
   560	ADD	$16, RSP
   561	MOVD	R0, 48(R2)	// save err
   562ok:
   563	RET
   564
   565// syscallPtr is like syscallX except that the libc function reports an
   566// error by returning NULL and setting errno.
   567TEXT runtime·syscallPtr(SB),NOSPLIT,$0
   568	SUB	$16, RSP	// push structure pointer
   569	MOVD	R0, (RSP)
   570
   571	MOVD	0(R0), R12	// fn
   572	MOVD	16(R0), R1	// a2
   573	MOVD	24(R0), R2	// a3
   574	MOVD	8(R0), R0	// a1
   575	BL	(R12)
   576
   577	MOVD	(RSP), R2	// pop structure pointer
   578	ADD	$16, RSP
   579	MOVD	R0, 32(R2)	// save r1
   580	MOVD	R1, 40(R2)	// save r2
   581	CMP	$0, R0
   582	BNE	ok
   583	SUB	$16, RSP	// push structure pointer
   584	MOVD	R2, (RSP)
   585	BL	libc_error(SB)
   586	MOVW	(R0), R0
   587	MOVD	(RSP), R2	// pop structure pointer
   588	ADD	$16, RSP
   589	MOVD	R0, 48(R2)	// save err
   590ok:
   591	RET
   592
   593// syscall6 calls a function in libc on behalf of the syscall package.
   594// syscall6 takes a pointer to a struct like:
   595// struct {
   596//	fn    uintptr
   597//	a1    uintptr
   598//	a2    uintptr
   599//	a3    uintptr
   600//	a4    uintptr
   601//	a5    uintptr
   602//	a6    uintptr
   603//	r1    uintptr
   604//	r2    uintptr
   605//	err   uintptr
   606// }
   607// syscall6 must be called on the g0 stack with the
   608// C calling convention (use libcCall).
   609TEXT runtime·syscall6(SB),NOSPLIT,$0
   610	SUB	$16, RSP	// push structure pointer
   611	MOVD	R0, 8(RSP)
   612
   613	MOVD	0(R0), R12	// fn
   614	MOVD	16(R0), R1	// a2
   615	MOVD	24(R0), R2	// a3
   616	MOVD	32(R0), R3	// a4
   617	MOVD	40(R0), R4	// a5
   618	MOVD	48(R0), R5	// a6
   619	MOVD	8(R0), R0	// a1
   620
   621	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   622	// See syscall above. The only function this applies to is openat, for which the 4th
   623	// arg must be on the stack.
   624	MOVD	R3, (RSP)
   625
   626	BL	(R12)
   627
   628	MOVD	8(RSP), R2	// pop structure pointer
   629	ADD	$16, RSP
   630	MOVD	R0, 56(R2)	// save r1
   631	MOVD	R1, 64(R2)	// save r2
   632	CMPW	$-1, R0
   633	BNE	ok
   634	SUB	$16, RSP	// push structure pointer
   635	MOVD	R2, 8(RSP)
   636	BL	libc_error(SB)
   637	MOVW	(R0), R0
   638	MOVD	8(RSP), R2	// pop structure pointer
   639	ADD	$16, RSP
   640	MOVD	R0, 72(R2)	// save err
   641ok:
   642	RET
   643
   644// syscall6X calls a function in libc on behalf of the syscall package.
   645// syscall6X takes a pointer to a struct like:
   646// struct {
   647//	fn    uintptr
   648//	a1    uintptr
   649//	a2    uintptr
   650//	a3    uintptr
   651//	a4    uintptr
   652//	a5    uintptr
   653//	a6    uintptr
   654//	r1    uintptr
   655//	r2    uintptr
   656//	err   uintptr
   657// }
   658// syscall6X must be called on the g0 stack with the
   659// C calling convention (use libcCall).
   660TEXT runtime·syscall6X(SB),NOSPLIT,$0
   661	SUB	$16, RSP	// push structure pointer
   662	MOVD	R0, (RSP)
   663
   664	MOVD	0(R0), R12	// fn
   665	MOVD	16(R0), R1	// a2
   666	MOVD	24(R0), R2	// a3
   667	MOVD	32(R0), R3	// a4
   668	MOVD	40(R0), R4	// a5
   669	MOVD	48(R0), R5	// a6
   670	MOVD	8(R0), R0	// a1
   671	BL	(R12)
   672
   673	MOVD	(RSP), R2	// pop structure pointer
   674	ADD	$16, RSP
   675	MOVD	R0, 56(R2)	// save r1
   676	MOVD	R1, 64(R2)	// save r2
   677	CMP	$-1, R0
   678	BNE	ok
   679	SUB	$16, RSP	// push structure pointer
   680	MOVD	R2, (RSP)
   681	BL	libc_error(SB)
   682	MOVW	(R0), R0
   683	MOVD	(RSP), R2	// pop structure pointer
   684	ADD	$16, RSP
   685	MOVD	R0, 72(R2)	// save err
   686ok:
   687	RET
   688
   689// syscall9 calls a function in libc on behalf of the syscall package.
   690// syscall9 takes a pointer to a struct like:
   691// struct {
   692//	fn    uintptr
   693//	a1    uintptr
   694//	a2    uintptr
   695//	a3    uintptr
   696//	a4    uintptr
   697//	a5    uintptr
   698//	a6    uintptr
   699//	a7    uintptr
   700//	a8    uintptr
   701//	a9    uintptr
   702//	r1    uintptr
   703//	r2    uintptr
   704//	err   uintptr
   705// }
   706// syscall9 must be called on the g0 stack with the
   707// C calling convention (use libcCall).
   708TEXT runtime·syscall9(SB),NOSPLIT,$0
   709	SUB	$16, RSP	// push structure pointer
   710	MOVD	R0, 8(RSP)
   711
   712	MOVD	0(R0), R12	// fn
   713	MOVD	16(R0), R1	// a2
   714	MOVD	24(R0), R2	// a3
   715	MOVD	32(R0), R3	// a4
   716	MOVD	40(R0), R4	// a5
   717	MOVD	48(R0), R5	// a6
   718	MOVD	56(R0), R6	// a7
   719	MOVD	64(R0), R7	// a8
   720	MOVD	72(R0), R8	// a9
   721	MOVD	8(R0), R0	// a1
   722
   723	// If fn is declared as vararg, we have to pass the vararg arguments on the stack.
   724	// See syscall above. The only function this applies to is openat, for which the 4th
   725	// arg must be on the stack.
   726	MOVD	R3, (RSP)
   727
   728	BL	(R12)
   729
   730	MOVD	8(RSP), R2	// pop structure pointer
   731	ADD	$16, RSP
   732	MOVD	R0, 80(R2)	// save r1
   733	MOVD	R1, 88(R2)	// save r2
   734	CMPW	$-1, R0
   735	BNE	ok
   736	SUB	$16, RSP	// push structure pointer
   737	MOVD	R2, 8(RSP)
   738	BL	libc_error(SB)
   739	MOVW	(R0), R0
   740	MOVD	8(RSP), R2	// pop structure pointer
   741	ADD	$16, RSP
   742	MOVD	R0, 96(R2)	// save err
   743ok:
   744	RET
   745
   746// syscall_x509 is for crypto/x509. It is like syscall6 but does not check for errors,
   747// takes 5 uintptrs and 1 float64, and only returns one value,
   748// for use with standard C ABI functions.
   749TEXT runtime·syscall_x509(SB),NOSPLIT,$0
   750	SUB	$16, RSP	// push structure pointer
   751	MOVD	R0, (RSP)
   752
   753	MOVD	0(R0), R12	// fn
   754	MOVD	16(R0), R1	// a2
   755	MOVD	24(R0), R2	// a3
   756	MOVD	32(R0), R3	// a4
   757	MOVD	40(R0), R4	// a5
   758	FMOVD	48(R0), F0	// f1
   759	MOVD	8(R0), R0	// a1
   760	BL	(R12)
   761
   762	MOVD	(RSP), R2	// pop structure pointer
   763	ADD	$16, RSP
   764	MOVD	R0, 56(R2)	// save r1
   765	RET
   766
   767TEXT runtime·issetugid_trampoline(SB),NOSPLIT,$0
   768	BL	libc_issetugid(SB)
   769	RET
   770
   771// mach_vm_region_trampoline calls mach_vm_region from libc.
   772TEXT runtime·mach_vm_region_trampoline(SB),NOSPLIT,$0
   773	MOVD	0(R0), R1	// address
   774	MOVD	8(R0), R2	// size
   775	MOVW	16(R0), R3	// flavor
   776	MOVD	24(R0), R4	// info
   777	MOVD	32(R0), R5	// count
   778	MOVD	40(R0), R6  // object_name
   779	MOVD	$libc_mach_task_self_(SB), R0
   780	MOVW	0(R0), R0
   781	BL	libc_mach_vm_region(SB)
   782	RET
   783
   784// proc_regionfilename_trampoline calls proc_regionfilename for
   785// the current process.
   786TEXT runtime·proc_regionfilename_trampoline(SB),NOSPLIT,$0
   787	MOVD	8(R0), R1	// address
   788	MOVD	16(R0), R2	// buffer
   789	MOVD	24(R0), R3	// buffer_size
   790	MOVD	0(R0), R0 // pid
   791	BL	libc_proc_regionfilename(SB)
   792	RET

View as plain text