...

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

View as plain text