...

Text file src/runtime/sys_openbsd_arm64.s

Documentation: runtime

     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.
    22TEXT 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
    46TEXT 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
    54TEXT 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.)
    82TEXT 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
    87TEXT 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
    92TEXT 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
    98TEXT 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
   104TEXT 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
   114TEXT 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
   121TEXT 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
   130TEXT 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
   136TEXT 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
   143TEXT 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
   149TEXT 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
   156TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
   157	CALL	libc_sched_yield(SB)
   158	RET
   159
   160TEXT 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
   175noerr:
   176	MOVD	R0, 32(R19)
   177	MOVD	R1, 40(R19)
   178	RET
   179
   180TEXT 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
   190TEXT 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
   198TEXT 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
   206TEXT runtime·close_trampoline(SB),NOSPLIT,$0
   207	MOVD	0(R0), R0		// arg 1 - fd
   208	CALL	libc_close(SB)
   209	RET
   210
   211TEXT 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
   221noerr:
   222	RET
   223
   224TEXT 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
   234noerr:
   235	RET
   236
   237TEXT 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
   246noerr:
   247	RET
   248
   249TEXT 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
   256TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   257	MOVD	0(R0), R0		// arg 1 - usec
   258	CALL	libc_usleep(SB)
   259	RET
   260
   261TEXT 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
   271TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   272	CALL	libc_kqueue(SB)
   273	RET
   274
   275TEXT 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
   288noerr:
   289	RET
   290
   291TEXT 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
   300noerr:
   301	RET
   302
   303TEXT 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
   316noerr:
   317	MOVW	R0, 12(R19)
   318	MOVW	R1, 16(R19)
   319	RET
   320
   321TEXT 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
   332TEXT 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
   343TEXT 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.
   369TEXT 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
   393ok:
   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.
   412TEXT 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
   436ok:
   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.
   458TEXT 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
   485ok:
   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.
   507TEXT 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
   534ok:
   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).
   557TEXT 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
   588ok:
   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.
   614TEXT 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
   645ok:
   646	RET
   647
   648TEXT 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

View as plain text