...

Text file src/runtime/sys_openbsd_ppc64.s

Documentation: runtime

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

View as plain text