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

View as plain text