Text file src/runtime/sys_darwin_amd64.s

Documentation: runtime

     1// Copyright 2009 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 AMD64, 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// Exit the entire program (like C exit)
    14TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
    15	PUSHQ	BP
    16	MOVQ	SP, BP
    17	MOVL	0(DI), DI		// arg 1 exit status
    18	CALL	libc_exit(SB)
    19	MOVL	$0xf1, 0xf1  // crash
    20	POPQ	BP
    21	RET
    22
    23TEXT runtime·open_trampoline(SB),NOSPLIT,$0
    24	PUSHQ	BP
    25	MOVQ	SP, BP
    26	MOVL	8(DI), SI		// arg 2 flags
    27	MOVL	12(DI), DX		// arg 3 mode
    28	MOVQ	0(DI), DI		// arg 1 pathname
    29	XORL	AX, AX			// vararg: say "no float args"
    30	CALL	libc_open(SB)
    31	POPQ	BP
    32	RET
    33
    34TEXT runtime·close_trampoline(SB),NOSPLIT,$0
    35	PUSHQ	BP
    36	MOVQ	SP, BP
    37	MOVL	0(DI), DI		// arg 1 fd
    38	CALL	libc_close(SB)
    39	POPQ	BP
    40	RET
    41
    42TEXT runtime·read_trampoline(SB),NOSPLIT,$0
    43	PUSHQ	BP
    44	MOVQ	SP, BP
    45	MOVQ	8(DI), SI		// arg 2 buf
    46	MOVL	16(DI), DX		// arg 3 count
    47	MOVL	0(DI), DI		// arg 1 fd
    48	CALL	libc_read(SB)
    49	TESTL	AX, AX
    50	JGE	noerr
    51	CALL	libc_error(SB)
    52	MOVL	(AX), AX
    53	NEGL	AX			// caller expects negative errno value
    54noerr:
    55	POPQ	BP
    56	RET
    57
    58TEXT runtime·write_trampoline(SB),NOSPLIT,$0
    59	PUSHQ	BP
    60	MOVQ	SP, BP
    61	MOVQ	8(DI), SI		// arg 2 buf
    62	MOVL	16(DI), DX		// arg 3 count
    63	MOVQ	0(DI), DI		// arg 1 fd
    64	CALL	libc_write(SB)
    65	TESTL	AX, AX
    66	JGE	noerr
    67	CALL	libc_error(SB)
    68	MOVL	(AX), AX
    69	NEGL	AX			// caller expects negative errno value
    70noerr:
    71	POPQ	BP
    72	RET
    73
    74TEXT runtime·pipe_trampoline(SB),NOSPLIT,$0
    75	PUSHQ	BP
    76	MOVQ	SP, BP
    77	CALL	libc_pipe(SB)		// pointer already in DI
    78	TESTL	AX, AX
    79	JEQ	3(PC)
    80	CALL	libc_error(SB)		// return negative errno value
    81	NEGL	AX
    82	POPQ	BP
    83	RET
    84
    85TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
    86	PUSHQ	BP
    87	MOVQ	SP, BP
    88	MOVQ	8(DI), SI		// arg 2 new
    89	MOVQ	16(DI), DX		// arg 3 old
    90	MOVL	0(DI), DI		// arg 1 which
    91	CALL	libc_setitimer(SB)
    92	POPQ	BP
    93	RET
    94
    95TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
    96	PUSHQ	BP
    97	MOVQ	SP, BP
    98	MOVQ	8(DI), SI	// arg 2 len
    99	MOVL	16(DI), DX	// arg 3 advice
   100	MOVQ	0(DI), DI	// arg 1 addr
   101	CALL	libc_madvise(SB)
   102	// ignore failure - maybe pages are locked
   103	POPQ	BP
   104	RET
   105
   106GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
   107
   108TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
   109	PUSHQ	BP
   110	MOVQ	SP, BP
   111	MOVQ	DI, BX
   112	CALL	libc_mach_absolute_time(SB)
   113	MOVQ	AX, 0(BX)
   114	MOVL	timebase<>+machTimebaseInfo_numer(SB), SI
   115	MOVL	timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
   116	TESTL	DI, DI
   117	JNE	initialized
   118
   119	SUBQ	$(machTimebaseInfo__size+15)/16*16, SP
   120	MOVQ	SP, DI
   121	CALL	libc_mach_timebase_info(SB)
   122	MOVL	machTimebaseInfo_numer(SP), SI
   123	MOVL	machTimebaseInfo_denom(SP), DI
   124	ADDQ	$(machTimebaseInfo__size+15)/16*16, SP
   125
   126	MOVL	SI, timebase<>+machTimebaseInfo_numer(SB)
   127	MOVL	DI, AX
   128	XCHGL	AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write
   129
   130initialized:
   131	MOVL	SI, 8(BX)
   132	MOVL	DI, 12(BX)
   133	MOVQ	BP, SP
   134	POPQ	BP
   135	RET
   136
   137TEXT runtime·walltime_trampoline(SB),NOSPLIT,$0
   138	PUSHQ	BP			// make a frame; keep stack aligned
   139	MOVQ	SP, BP
   140	// DI already has *timeval
   141	XORL	SI, SI // no timezone needed
   142	CALL	libc_gettimeofday(SB)
   143	POPQ	BP
   144	RET
   145
   146TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
   147	PUSHQ	BP
   148	MOVQ	SP, BP
   149	MOVQ	8(DI), SI		// arg 2 new
   150	MOVQ	16(DI), DX		// arg 3 old
   151	MOVL	0(DI), DI		// arg 1 sig
   152	CALL	libc_sigaction(SB)
   153	TESTL	AX, AX
   154	JEQ	2(PC)
   155	MOVL	$0xf1, 0xf1  // crash
   156	POPQ	BP
   157	RET
   158
   159TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   160	PUSHQ	BP
   161	MOVQ	SP, BP
   162	MOVQ	8(DI), SI	// arg 2 new
   163	MOVQ	16(DI), DX	// arg 3 old
   164	MOVL	0(DI), DI	// arg 1 how
   165	CALL	libc_pthread_sigmask(SB)
   166	TESTL	AX, AX
   167	JEQ	2(PC)
   168	MOVL	$0xf1, 0xf1  // crash
   169	POPQ	BP
   170	RET
   171
   172TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   173	PUSHQ	BP
   174	MOVQ	SP, BP
   175	MOVQ	8(DI), SI		// arg 2 old
   176	MOVQ	0(DI), DI		// arg 1 new
   177	CALL	libc_sigaltstack(SB)
   178	TESTQ	AX, AX
   179	JEQ	2(PC)
   180	MOVL	$0xf1, 0xf1  // crash
   181	POPQ	BP
   182	RET
   183
   184TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
   185	PUSHQ	BP
   186	MOVQ	SP, BP
   187	MOVL	0(DI), BX	// signal
   188	CALL	libc_getpid(SB)
   189	MOVL	AX, DI		// arg 1 pid
   190	MOVL	BX, SI		// arg 2 signal
   191	CALL	libc_kill(SB)
   192	POPQ	BP
   193	RET
   194
   195TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   196	MOVQ	fn+0(FP),    AX
   197	MOVL	sig+8(FP),   DI
   198	MOVQ	info+16(FP), SI
   199	MOVQ	ctx+24(FP),  DX
   200	PUSHQ	BP
   201	MOVQ	SP, BP
   202	ANDQ	$~15, SP     // alignment for x86_64 ABI
   203	CALL	AX
   204	MOVQ	BP, SP
   205	POPQ	BP
   206	RET
   207
   208// This is the function registered during sigaction and is invoked when
   209// a signal is received. It just redirects to the Go function sigtrampgo.
   210TEXT runtime·sigtramp(SB),NOSPLIT,$0
   211	// This runs on the signal stack, so we have lots of stack available.
   212	// We allocate our own stack space, because if we tell the linker
   213	// how much we're using, the NOSPLIT check fails.
   214	PUSHQ	BP
   215	MOVQ	SP, BP
   216	SUBQ	$64, SP
   217
   218	// Save callee-save registers.
   219	MOVQ	BX, 24(SP)
   220	MOVQ	R12, 32(SP)
   221	MOVQ	R13, 40(SP)
   222	MOVQ	R14, 48(SP)
   223	MOVQ	R15, 56(SP)
   224
   225	// Call into the Go signal handler
   226	MOVL	DI, 0(SP)  // sig
   227	MOVQ	SI, 8(SP)  // info
   228	MOVQ	DX, 16(SP) // ctx
   229	CALL runtime·sigtrampgo(SB)
   230
   231	// Restore callee-save registers.
   232	MOVQ	24(SP), BX
   233	MOVQ	32(SP), R12
   234	MOVQ	40(SP), R13
   235	MOVQ	48(SP), R14
   236	MOVQ	56(SP), R15
   237
   238	MOVQ	BP, SP
   239	POPQ	BP
   240	RET
   241
   242// Used instead of sigtramp in programs that use cgo.
   243// Arguments from kernel are in DI, SI, DX.
   244TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0
   245	// If no traceback function, do usual sigtramp.
   246	MOVQ	runtime·cgoTraceback(SB), AX
   247	TESTQ	AX, AX
   248	JZ	sigtramp
   249
   250	// If no traceback support function, which means that
   251	// runtime/cgo was not linked in, do usual sigtramp.
   252	MOVQ	_cgo_callers(SB), AX
   253	TESTQ	AX, AX
   254	JZ	sigtramp
   255
   256	// Figure out if we are currently in a cgo call.
   257	// If not, just do usual sigtramp.
   258	get_tls(CX)
   259	MOVQ	g(CX),AX
   260	TESTQ	AX, AX
   261	JZ	sigtrampnog     // g == nil
   262	MOVQ	g_m(AX), AX
   263	TESTQ	AX, AX
   264	JZ	sigtramp        // g.m == nil
   265	MOVL	m_ncgo(AX), CX
   266	TESTL	CX, CX
   267	JZ	sigtramp        // g.m.ncgo == 0
   268	MOVQ	m_curg(AX), CX
   269	TESTQ	CX, CX
   270	JZ	sigtramp        // g.m.curg == nil
   271	MOVQ	g_syscallsp(CX), CX
   272	TESTQ	CX, CX
   273	JZ	sigtramp        // g.m.curg.syscallsp == 0
   274	MOVQ	m_cgoCallers(AX), R8
   275	TESTQ	R8, R8
   276	JZ	sigtramp        // g.m.cgoCallers == nil
   277	MOVL	m_cgoCallersUse(AX), CX
   278	TESTL	CX, CX
   279	JNZ	sigtramp	// g.m.cgoCallersUse != 0
   280
   281	// Jump to a function in runtime/cgo.
   282	// That function, written in C, will call the user's traceback
   283	// function with proper unwind info, and will then call back here.
   284	// The first three arguments, and the fifth, are already in registers.
   285	// Set the two remaining arguments now.
   286	MOVQ	runtime·cgoTraceback(SB), CX
   287	MOVQ	$runtime·sigtramp(SB), R9
   288	MOVQ	_cgo_callers(SB), AX
   289	JMP	AX
   290
   291sigtramp:
   292	JMP	runtime·sigtramp(SB)
   293
   294sigtrampnog:
   295	// Signal arrived on a non-Go thread. If this is SIGPROF, get a
   296	// stack trace.
   297	CMPL	DI, $27 // 27 == SIGPROF
   298	JNZ	sigtramp
   299
   300	// Lock sigprofCallersUse.
   301	MOVL	$0, AX
   302	MOVL	$1, CX
   303	MOVQ	$runtime·sigprofCallersUse(SB), R11
   304	LOCK
   305	CMPXCHGL	CX, 0(R11)
   306	JNZ	sigtramp  // Skip stack trace if already locked.
   307
   308	// Jump to the traceback function in runtime/cgo.
   309	// It will call back to sigprofNonGo, which will ignore the
   310	// arguments passed in registers.
   311	// First three arguments to traceback function are in registers already.
   312	MOVQ	runtime·cgoTraceback(SB), CX
   313	MOVQ	$runtime·sigprofCallers(SB), R8
   314	MOVQ	$runtime·sigprofNonGo(SB), R9
   315	MOVQ	_cgo_callers(SB), AX
   316	JMP	AX
   317
   318TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
   319	PUSHQ	BP			// make a frame; keep stack aligned
   320	MOVQ	SP, BP
   321	MOVQ	DI, BX
   322	MOVQ	0(BX), DI		// arg 1 addr
   323	MOVQ	8(BX), SI		// arg 2 len
   324	MOVL	16(BX), DX		// arg 3 prot
   325	MOVL	20(BX), CX		// arg 4 flags
   326	MOVL	24(BX), R8		// arg 5 fid
   327	MOVL	28(BX), R9		// arg 6 offset
   328	CALL	libc_mmap(SB)
   329	XORL	DX, DX
   330	CMPQ	AX, $-1
   331	JNE	ok
   332	CALL	libc_error(SB)
   333	MOVLQSX	(AX), DX		// errno
   334	XORL	AX, AX
   335ok:
   336	MOVQ	AX, 32(BX)
   337	MOVQ	DX, 40(BX)
   338	POPQ	BP
   339	RET
   340
   341TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
   342	PUSHQ	BP
   343	MOVQ	SP, BP
   344	MOVQ	8(DI), SI		// arg 2 len
   345	MOVQ	0(DI), DI		// arg 1 addr
   346	CALL	libc_munmap(SB)
   347	TESTQ	AX, AX
   348	JEQ	2(PC)
   349	MOVL	$0xf1, 0xf1  // crash
   350	POPQ	BP
   351	RET
   352
   353TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   354	PUSHQ	BP
   355	MOVQ	SP, BP
   356	MOVL	0(DI), DI	// arg 1 usec
   357	CALL	libc_usleep(SB)
   358	POPQ	BP
   359	RET
   360
   361TEXT runtime·settls(SB),NOSPLIT,$32
   362	// Nothing to do on Darwin, pthread already set thread-local storage up.
   363	RET
   364
   365TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
   366	PUSHQ	BP
   367	MOVQ	SP, BP
   368	MOVL	8(DI), SI		// arg 2 miblen
   369	MOVQ	16(DI), DX		// arg 3 out
   370	MOVQ	24(DI), CX		// arg 4 size
   371	MOVQ	32(DI), R8		// arg 5 dst
   372	MOVQ	40(DI), R9		// arg 6 ndst
   373	MOVQ	0(DI), DI		// arg 1 mib
   374	CALL	libc_sysctl(SB)
   375	POPQ	BP
   376	RET
   377
   378TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   379	PUSHQ	BP
   380	MOVQ	SP, BP
   381	CALL	libc_kqueue(SB)
   382	POPQ	BP
   383	RET
   384
   385TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
   386	PUSHQ	BP
   387	MOVQ	SP, BP
   388	MOVQ	8(DI), SI		// arg 2 keventt
   389	MOVL	16(DI), DX		// arg 3 nch
   390	MOVQ	24(DI), CX		// arg 4 ev
   391	MOVL	32(DI), R8		// arg 5 nev
   392	MOVQ	40(DI), R9		// arg 6 ts
   393	MOVL	0(DI), DI		// arg 1 kq
   394	CALL	libc_kevent(SB)
   395	CMPL	AX, $-1
   396	JNE	ok
   397	CALL	libc_error(SB)
   398	MOVLQSX	(AX), AX		// errno
   399	NEGQ	AX			// caller wants it as a negative error code
   400ok:
   401	POPQ	BP
   402	RET
   403
   404TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   405	PUSHQ	BP
   406	MOVQ	SP, BP
   407	MOVL	4(DI), SI		// arg 2 cmd
   408	MOVL	8(DI), DX		// arg 3 arg
   409	MOVL	0(DI), DI		// arg 1 fd
   410	XORL	AX, AX			// vararg: say "no float args"
   411	CALL	libc_fcntl(SB)
   412	POPQ	BP
   413	RET
   414
   415// mstart_stub is the first function executed on a new thread started by pthread_create.
   416// It just does some low-level setup and then calls mstart.
   417// Note: called with the C calling convention.
   418TEXT runtime·mstart_stub(SB),NOSPLIT,$0
   419	// DI points to the m.
   420	// We are already on m's g0 stack.
   421
   422	// Save callee-save registers.
   423	SUBQ	$40, SP
   424	MOVQ	BX, 0(SP)
   425	MOVQ	R12, 8(SP)
   426	MOVQ	R13, 16(SP)
   427	MOVQ	R14, 24(SP)
   428	MOVQ	R15, 32(SP)
   429
   430	MOVQ	m_g0(DI), DX // g
   431
   432	// Initialize TLS entry.
   433	// See cmd/link/internal/ld/sym.go:computeTLSOffset.
   434	MOVQ	DX, 0x30(GS)
   435
   436	// Someday the convention will be D is always cleared.
   437	CLD
   438
   439	CALL	runtime·mstart(SB)
   440
   441	// Restore callee-save registers.
   442	MOVQ	0(SP), BX
   443	MOVQ	8(SP), R12
   444	MOVQ	16(SP), R13
   445	MOVQ	24(SP), R14
   446	MOVQ	32(SP), R15
   447
   448	// Go is all done with this OS thread.
   449	// Tell pthread everything is ok (we never join with this thread, so
   450	// the value here doesn't really matter).
   451	XORL	AX, AX
   452
   453	ADDQ	$40, SP
   454	RET
   455
   456// These trampolines help convert from Go calling convention to C calling convention.
   457// They should be called with asmcgocall.
   458// A pointer to the arguments is passed in DI.
   459// A single int32 result is returned in AX.
   460// (For more results, make an args/results structure.)
   461TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
   462	PUSHQ	BP	// make frame, keep stack 16-byte aligned.
   463	MOVQ	SP, BP
   464	MOVQ	0(DI), DI // arg 1 attr
   465	CALL	libc_pthread_attr_init(SB)
   466	POPQ	BP
   467	RET
   468
   469TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
   470	PUSHQ	BP
   471	MOVQ	SP, BP
   472	MOVQ	8(DI), SI	// arg 2 size
   473	MOVQ	0(DI), DI	// arg 1 attr
   474	CALL	libc_pthread_attr_getstacksize(SB)
   475	POPQ	BP
   476	RET
   477
   478TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
   479	PUSHQ	BP
   480	MOVQ	SP, BP
   481	MOVQ	8(DI), SI	// arg 2 state
   482	MOVQ	0(DI), DI	// arg 1 attr
   483	CALL	libc_pthread_attr_setdetachstate(SB)
   484	POPQ	BP
   485	RET
   486
   487TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
   488	PUSHQ	BP
   489	MOVQ	SP, BP
   490	SUBQ	$16, SP
   491	MOVQ	0(DI), SI	// arg 2 attr
   492	MOVQ	8(DI), DX	// arg 3 start
   493	MOVQ	16(DI), CX	// arg 4 arg
   494	MOVQ	SP, DI		// arg 1 &threadid (which we throw away)
   495	CALL	libc_pthread_create(SB)
   496	MOVQ	BP, SP
   497	POPQ	BP
   498	RET
   499
   500TEXT runtime·raise_trampoline(SB),NOSPLIT,$0
   501	PUSHQ	BP
   502	MOVQ	SP, BP
   503	MOVL	0(DI), DI	// arg 1 signal
   504	CALL	libc_raise(SB)
   505	POPQ	BP
   506	RET
   507
   508TEXT runtime·pthread_mutex_init_trampoline(SB),NOSPLIT,$0
   509	PUSHQ	BP
   510	MOVQ	SP, BP
   511	MOVQ	8(DI), SI	// arg 2 attr
   512	MOVQ	0(DI), DI	// arg 1 mutex
   513	CALL	libc_pthread_mutex_init(SB)
   514	POPQ	BP
   515	RET
   516
   517TEXT runtime·pthread_mutex_lock_trampoline(SB),NOSPLIT,$0
   518	PUSHQ	BP
   519	MOVQ	SP, BP
   520	MOVQ	0(DI), DI	// arg 1 mutex
   521	CALL	libc_pthread_mutex_lock(SB)
   522	POPQ	BP
   523	RET
   524
   525TEXT runtime·pthread_mutex_unlock_trampoline(SB),NOSPLIT,$0
   526	PUSHQ	BP
   527	MOVQ	SP, BP
   528	MOVQ	0(DI), DI	// arg 1 mutex
   529	CALL	libc_pthread_mutex_unlock(SB)
   530	POPQ	BP
   531	RET
   532
   533TEXT runtime·pthread_cond_init_trampoline(SB),NOSPLIT,$0
   534	PUSHQ	BP
   535	MOVQ	SP, BP
   536	MOVQ	8(DI), SI	// arg 2 attr
   537	MOVQ	0(DI), DI	// arg 1 cond
   538	CALL	libc_pthread_cond_init(SB)
   539	POPQ	BP
   540	RET
   541
   542TEXT runtime·pthread_cond_wait_trampoline(SB),NOSPLIT,$0
   543	PUSHQ	BP
   544	MOVQ	SP, BP
   545	MOVQ	8(DI), SI	// arg 2 mutex
   546	MOVQ	0(DI), DI	// arg 1 cond
   547	CALL	libc_pthread_cond_wait(SB)
   548	POPQ	BP
   549	RET
   550
   551TEXT runtime·pthread_cond_timedwait_relative_np_trampoline(SB),NOSPLIT,$0
   552	PUSHQ	BP
   553	MOVQ	SP, BP
   554	MOVQ	8(DI), SI	// arg 2 mutex
   555	MOVQ	16(DI), DX	// arg 3 timeout
   556	MOVQ	0(DI), DI	// arg 1 cond
   557	CALL	libc_pthread_cond_timedwait_relative_np(SB)
   558	POPQ	BP
   559	RET
   560
   561TEXT runtime·pthread_cond_signal_trampoline(SB),NOSPLIT,$0
   562	PUSHQ	BP
   563	MOVQ	SP, BP
   564	MOVQ	0(DI), DI	// arg 1 cond
   565	CALL	libc_pthread_cond_signal(SB)
   566	POPQ	BP
   567	RET
   568
   569TEXT runtime·pthread_self_trampoline(SB),NOSPLIT,$0
   570	PUSHQ	BP
   571	MOVQ	SP, BP
   572	MOVQ	DI, BX		// BX is caller-save
   573	CALL	libc_pthread_self(SB)
   574	MOVQ	AX, 0(BX)	// return value
   575	POPQ	BP
   576	RET
   577
   578TEXT runtime·pthread_kill_trampoline(SB),NOSPLIT,$0
   579	PUSHQ	BP
   580	MOVQ	SP, BP
   581	MOVQ	8(DI), SI	// arg 2 sig
   582	MOVQ	0(DI), DI	// arg 1 thread
   583	CALL	libc_pthread_kill(SB)
   584	POPQ	BP
   585	RET
   586
   587// syscall calls a function in libc on behalf of the syscall package.
   588// syscall takes a pointer to a struct like:
   589// struct {
   590//	fn    uintptr
   591//	a1    uintptr
   592//	a2    uintptr
   593//	a3    uintptr
   594//	r1    uintptr
   595//	r2    uintptr
   596//	err   uintptr
   597// }
   598// syscall must be called on the g0 stack with the
   599// C calling convention (use libcCall).
   600//
   601// syscall expects a 32-bit result and tests for 32-bit -1
   602// to decide there was an error.
   603TEXT runtime·syscall(SB),NOSPLIT,$0
   604	PUSHQ	BP
   605	MOVQ	SP, BP
   606	SUBQ	$16, SP
   607	MOVQ	(0*8)(DI), CX // fn
   608	MOVQ	(2*8)(DI), SI // a2
   609	MOVQ	(3*8)(DI), DX // a3
   610	MOVQ	DI, (SP)
   611	MOVQ	(1*8)(DI), DI // a1
   612	XORL	AX, AX	      // vararg: say "no float args"
   613
   614	CALL	CX
   615
   616	MOVQ	(SP), DI
   617	MOVQ	AX, (4*8)(DI) // r1
   618	MOVQ	DX, (5*8)(DI) // r2
   619
   620	// Standard libc functions return -1 on error
   621	// and set errno.
   622	CMPL	AX, $-1	      // Note: high 32 bits are junk
   623	JNE	ok
   624
   625	// Get error code from libc.
   626	CALL	libc_error(SB)
   627	MOVLQSX	(AX), AX
   628	MOVQ	(SP), DI
   629	MOVQ	AX, (6*8)(DI) // err
   630
   631ok:
   632	XORL	AX, AX        // no error (it's ignored anyway)
   633	MOVQ	BP, SP
   634	POPQ	BP
   635	RET
   636
   637// syscallX calls a function in libc on behalf of the syscall package.
   638// syscallX takes a pointer to a struct like:
   639// struct {
   640//	fn    uintptr
   641//	a1    uintptr
   642//	a2    uintptr
   643//	a3    uintptr
   644//	r1    uintptr
   645//	r2    uintptr
   646//	err   uintptr
   647// }
   648// syscallX must be called on the g0 stack with the
   649// C calling convention (use libcCall).
   650//
   651// syscallX is like syscall but expects a 64-bit result
   652// and tests for 64-bit -1 to decide there was an error.
   653TEXT runtime·syscallX(SB),NOSPLIT,$0
   654	PUSHQ	BP
   655	MOVQ	SP, BP
   656	SUBQ	$16, SP
   657	MOVQ	(0*8)(DI), CX // fn
   658	MOVQ	(2*8)(DI), SI // a2
   659	MOVQ	(3*8)(DI), DX // a3
   660	MOVQ	DI, (SP)
   661	MOVQ	(1*8)(DI), DI // a1
   662	XORL	AX, AX	      // vararg: say "no float args"
   663
   664	CALL	CX
   665
   666	MOVQ	(SP), DI
   667	MOVQ	AX, (4*8)(DI) // r1
   668	MOVQ	DX, (5*8)(DI) // r2
   669
   670	// Standard libc functions return -1 on error
   671	// and set errno.
   672	CMPQ	AX, $-1
   673	JNE	ok
   674
   675	// Get error code from libc.
   676	CALL	libc_error(SB)
   677	MOVLQSX	(AX), AX
   678	MOVQ	(SP), DI
   679	MOVQ	AX, (6*8)(DI) // err
   680
   681ok:
   682	XORL	AX, AX        // no error (it's ignored anyway)
   683	MOVQ	BP, SP
   684	POPQ	BP
   685	RET
   686
   687// syscallPtr is like syscallX except that the libc function reports an
   688// error by returning NULL and setting errno.
   689TEXT runtime·syscallPtr(SB),NOSPLIT,$0
   690	PUSHQ	BP
   691	MOVQ	SP, BP
   692	SUBQ	$16, SP
   693	MOVQ	(0*8)(DI), CX // fn
   694	MOVQ	(2*8)(DI), SI // a2
   695	MOVQ	(3*8)(DI), DX // a3
   696	MOVQ	DI, (SP)
   697	MOVQ	(1*8)(DI), DI // a1
   698	XORL	AX, AX	      // vararg: say "no float args"
   699
   700	CALL	CX
   701
   702	MOVQ	(SP), DI
   703	MOVQ	AX, (4*8)(DI) // r1
   704	MOVQ	DX, (5*8)(DI) // r2
   705
   706	// syscallPtr libc functions return NULL on error
   707	// and set errno.
   708	TESTQ	AX, AX
   709	JNE	ok
   710
   711	// Get error code from libc.
   712	CALL	libc_error(SB)
   713	MOVLQSX	(AX), AX
   714	MOVQ	(SP), DI
   715	MOVQ	AX, (6*8)(DI) // err
   716
   717ok:
   718	XORL	AX, AX        // no error (it's ignored anyway)
   719	MOVQ	BP, SP
   720	POPQ	BP
   721	RET
   722
   723// syscall6 calls a function in libc on behalf of the syscall package.
   724// syscall6 takes a pointer to a struct like:
   725// struct {
   726//	fn    uintptr
   727//	a1    uintptr
   728//	a2    uintptr
   729//	a3    uintptr
   730//	a4    uintptr
   731//	a5    uintptr
   732//	a6    uintptr
   733//	r1    uintptr
   734//	r2    uintptr
   735//	err   uintptr
   736// }
   737// syscall6 must be called on the g0 stack with the
   738// C calling convention (use libcCall).
   739//
   740// syscall6 expects a 32-bit result and tests for 32-bit -1
   741// to decide there was an error.
   742TEXT runtime·syscall6(SB),NOSPLIT,$0
   743	PUSHQ	BP
   744	MOVQ	SP, BP
   745	SUBQ	$16, SP
   746	MOVQ	(0*8)(DI), R11// fn
   747	MOVQ	(2*8)(DI), SI // a2
   748	MOVQ	(3*8)(DI), DX // a3
   749	MOVQ	(4*8)(DI), CX // a4
   750	MOVQ	(5*8)(DI), R8 // a5
   751	MOVQ	(6*8)(DI), R9 // a6
   752	MOVQ	DI, (SP)
   753	MOVQ	(1*8)(DI), DI // a1
   754	XORL	AX, AX	      // vararg: say "no float args"
   755
   756	CALL	R11
   757
   758	MOVQ	(SP), DI
   759	MOVQ	AX, (7*8)(DI) // r1
   760	MOVQ	DX, (8*8)(DI) // r2
   761
   762	CMPL	AX, $-1
   763	JNE	ok
   764
   765	CALL	libc_error(SB)
   766	MOVLQSX	(AX), AX
   767	MOVQ	(SP), DI
   768	MOVQ	AX, (9*8)(DI) // err
   769
   770ok:
   771	XORL	AX, AX        // no error (it's ignored anyway)
   772	MOVQ	BP, SP
   773	POPQ	BP
   774	RET
   775
   776// syscall6X calls a function in libc on behalf of the syscall package.
   777// syscall6X takes a pointer to a struct like:
   778// struct {
   779//	fn    uintptr
   780//	a1    uintptr
   781//	a2    uintptr
   782//	a3    uintptr
   783//	a4    uintptr
   784//	a5    uintptr
   785//	a6    uintptr
   786//	r1    uintptr
   787//	r2    uintptr
   788//	err   uintptr
   789// }
   790// syscall6X must be called on the g0 stack with the
   791// C calling convention (use libcCall).
   792//
   793// syscall6X is like syscall6 but expects a 64-bit result
   794// and tests for 64-bit -1 to decide there was an error.
   795TEXT runtime·syscall6X(SB),NOSPLIT,$0
   796	PUSHQ	BP
   797	MOVQ	SP, BP
   798	SUBQ	$16, SP
   799	MOVQ	(0*8)(DI), R11// fn
   800	MOVQ	(2*8)(DI), SI // a2
   801	MOVQ	(3*8)(DI), DX // a3
   802	MOVQ	(4*8)(DI), CX // a4
   803	MOVQ	(5*8)(DI), R8 // a5
   804	MOVQ	(6*8)(DI), R9 // a6
   805	MOVQ	DI, (SP)
   806	MOVQ	(1*8)(DI), DI // a1
   807	XORL	AX, AX	      // vararg: say "no float args"
   808
   809	CALL	R11
   810
   811	MOVQ	(SP), DI
   812	MOVQ	AX, (7*8)(DI) // r1
   813	MOVQ	DX, (8*8)(DI) // r2
   814
   815	CMPQ	AX, $-1
   816	JNE	ok
   817
   818	CALL	libc_error(SB)
   819	MOVLQSX	(AX), AX
   820	MOVQ	(SP), DI
   821	MOVQ	AX, (9*8)(DI) // err
   822
   823ok:
   824	XORL	AX, AX        // no error (it's ignored anyway)
   825	MOVQ	BP, SP
   826	POPQ	BP
   827	RET

View as plain text