github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/runtime/sys_darwin_amd64.s (about)

     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)
    14  TEXT 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  
    23  TEXT 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  
    34  TEXT 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  
    42  TEXT 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  
    52  TEXT 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  
    62  TEXT 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  
    72  TEXT 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  
    83  GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
    84  
    85  TEXT 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  
   107  initialized:
   108  	MOVL	SI, 8(BX)
   109  	MOVL	DI, 12(BX)
   110  	MOVQ	BP, SP
   111  	POPQ	BP
   112  	RET
   113  
   114  TEXT 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  
   123  TEXT 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  
   136  TEXT 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  
   149  TEXT 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  
   161  TEXT 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  
   172  TEXT 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.
   187  TEXT 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.
   221  TEXT 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  
   268  sigtramp:
   269  	JMP	runtime·sigtramp(SB)
   270  
   271  sigtrampnog:
   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  
   295  TEXT 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
   312  ok:
   313  	MOVQ	AX, 32(BX)
   314  	MOVQ	DX, 40(BX)
   315  	POPQ	BP
   316  	RET
   317  
   318  TEXT 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  
   330  TEXT 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  
   338  TEXT runtime·settls(SB),NOSPLIT,$32
   339  	// Nothing to do on Darwin, pthread already set thread-local storage up.
   340  	RET
   341  
   342  TEXT 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  
   355  TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   356  	PUSHQ	BP
   357  	MOVQ	SP, BP
   358  	CALL	libc_kqueue(SB)
   359  	POPQ	BP
   360  	RET
   361  
   362  TEXT 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
   377  ok:
   378  	POPQ	BP
   379  	RET
   380  
   381  TEXT 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.
   395  TEXT 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.)
   438  TEXT 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  
   446  TEXT 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  
   455  TEXT 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  
   464  TEXT 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  
   477  TEXT 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  
   485  TEXT 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  
   494  TEXT 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  
   502  TEXT 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  
   510  TEXT 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  
   519  TEXT 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  
   528  TEXT 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  
   538  TEXT 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).
   559  TEXT 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  
   587  ok:
   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).
   606  TEXT 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  
   634  ok:
   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.
   641  TEXT 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).
   661  TEXT 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  
   689  ok:
   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).
   711  TEXT 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  
   739  ok:
   740  	XORL	AX, AX        // no error (it's ignored anyway)
   741  	MOVQ	BP, SP
   742  	POPQ	BP
   743  	RET