Text file src/runtime/sys_openbsd_amd64.s

     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, 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  #include "cgo/abi_amd64.h"
    15  
    16  #define CLOCK_MONOTONIC	$3
    17  
    18  TEXT runtime·settls(SB),NOSPLIT,$0
    19  	// Nothing to do, pthread already set thread-local storage up.
    20  	RET
    21  
    22  // mstart_stub is the first function executed on a new thread started by pthread_create.
    23  // It just does some low-level setup and then calls mstart.
    24  // Note: called with the C calling convention.
    25  TEXT runtime·mstart_stub(SB),NOSPLIT,$0
    26  	// DI points to the m.
    27  	// We are already on m's g0 stack.
    28  
    29  	// Transition from C ABI to Go ABI.
    30  	PUSH_REGS_HOST_TO_ABI0()
    31  
    32  	// Load g and save to TLS entry.
    33  	// See cmd/link/internal/ld/sym.go:computeTLSOffset.
    34  	MOVQ	m_g0(DI), DX // g
    35  	MOVQ	DX, -8(FS)
    36  
    37  	CALL	runtime·mstart(SB)
    38  
    39  	POP_REGS_HOST_TO_ABI0()
    40  
    41  	// Go is all done with this OS thread.
    42  	// Tell pthread everything is ok (we never join with this thread, so
    43  	// the value here doesn't really matter).
    44  	XORL	AX, AX
    45  	RET
    46  
    47  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
    48  	MOVQ	fn+0(FP),    AX
    49  	MOVL	sig+8(FP),   DI
    50  	MOVQ	info+16(FP), SI
    51  	MOVQ	ctx+24(FP),  DX
    52  	PUSHQ	BP
    53  	MOVQ	SP, BP
    54  	ANDQ	$~15, SP     // alignment for x86_64 ABI
    55  	CALL	AX
    56  	MOVQ	BP, SP
    57  	POPQ	BP
    58  	RET
    59  
    60  // Called using C ABI.
    61  TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$0
    62  	// Transition from C ABI to Go ABI.
    63  	PUSH_REGS_HOST_TO_ABI0()
    64  
    65  	// Set up ABIInternal environment: g in R14, cleared X15.
    66  	get_tls(R12)
    67  	MOVQ	g(R12), R14
    68  	PXOR	X15, X15
    69  
    70  	// Reserve space for spill slots.
    71  	NOP	SP		// disable vet stack checking
    72  	ADJSP   $24
    73  
    74  	// Call into the Go signal handler
    75  	MOVQ	DI, AX	// sig
    76  	MOVQ	SI, BX	// info
    77  	MOVQ	DX, CX	// ctx
    78  	CALL	·sigtrampgo<ABIInternal>(SB)
    79  
    80  	ADJSP	$-24
    81  
    82  	POP_REGS_HOST_TO_ABI0()
    83  	RET
    84  
    85  //
    86  // These trampolines help convert from Go calling convention to C calling convention.
    87  // They should be called with asmcgocall.
    88  // A pointer to the arguments is passed in DI.
    89  // A single int32 result is returned in AX.
    90  // (For more results, make an args/results structure.)
    91  TEXT runtime·pthread_attr_init_trampoline(SB),NOSPLIT,$0
    92  	PUSHQ	BP
    93  	MOVQ	SP, BP
    94  	MOVQ	0(DI), DI		// arg 1 - attr
    95  	CALL	libc_pthread_attr_init(SB)
    96  	POPQ	BP
    97  	RET
    98  
    99  TEXT runtime·pthread_attr_destroy_trampoline(SB),NOSPLIT,$0
   100  	PUSHQ	BP
   101  	MOVQ	SP, BP
   102  	MOVQ	0(DI), DI		// arg 1 - attr
   103  	CALL	libc_pthread_attr_destroy(SB)
   104  	POPQ	BP
   105  	RET
   106  
   107  TEXT runtime·pthread_attr_getstacksize_trampoline(SB),NOSPLIT,$0
   108  	PUSHQ	BP
   109  	MOVQ	SP, BP
   110  	MOVQ	8(DI), SI		// arg 2 - stacksize
   111  	MOVQ	0(DI), DI		// arg 1 - attr
   112  	CALL	libc_pthread_attr_getstacksize(SB)
   113  	POPQ	BP
   114  	RET
   115  
   116  TEXT runtime·pthread_attr_setdetachstate_trampoline(SB),NOSPLIT,$0
   117  	PUSHQ	BP
   118  	MOVQ	SP, BP
   119  	MOVQ	8(DI), SI		// arg 2 - detachstate
   120  	MOVQ	0(DI), DI		// arg 1 - attr
   121  	CALL	libc_pthread_attr_setdetachstate(SB)
   122  	POPQ	BP
   123  	RET
   124  
   125  TEXT runtime·pthread_create_trampoline(SB),NOSPLIT,$0
   126  	PUSHQ	BP
   127  	MOVQ	SP, BP
   128  	SUBQ	$16, SP
   129  	MOVQ	0(DI), SI		// arg 2 - attr
   130  	MOVQ	8(DI), DX		// arg 3 - start
   131  	MOVQ	16(DI), CX		// arg 4 - arg
   132  	MOVQ	SP, DI			// arg 1 - &thread (discarded)
   133  	CALL	libc_pthread_create(SB)
   134  	MOVQ	BP, SP
   135  	POPQ	BP
   136  	RET
   137  
   138  TEXT runtime·thrkill_trampoline(SB),NOSPLIT,$0
   139  	PUSHQ	BP
   140  	MOVQ	SP, BP
   141  	MOVL	8(DI), SI		// arg 2 - signal
   142  	MOVQ	$0, DX			// arg 3 - tcb
   143  	MOVL	0(DI), DI		// arg 1 - tid
   144  	CALL	libc_thrkill(SB)
   145  	POPQ	BP
   146  	RET
   147  
   148  TEXT runtime·thrsleep_trampoline(SB),NOSPLIT,$0
   149  	PUSHQ	BP
   150  	MOVQ	SP, BP
   151  	MOVL	8(DI), SI		// arg 2 - clock_id
   152  	MOVQ	16(DI), DX		// arg 3 - abstime
   153  	MOVQ	24(DI), CX		// arg 4 - lock
   154  	MOVQ	32(DI), R8		// arg 5 - abort
   155  	MOVQ	0(DI), DI		// arg 1 - id
   156  	CALL	libc_thrsleep(SB)
   157  	POPQ	BP
   158  	RET
   159  
   160  TEXT runtime·thrwakeup_trampoline(SB),NOSPLIT,$0
   161  	PUSHQ	BP
   162  	MOVQ	SP, BP
   163  	MOVL	8(DI), SI		// arg 2 - count
   164  	MOVQ	0(DI), DI		// arg 1 - id
   165  	CALL	libc_thrwakeup(SB)
   166  	POPQ	BP
   167  	RET
   168  
   169  TEXT runtime·exit_trampoline(SB),NOSPLIT,$0
   170  	PUSHQ	BP
   171  	MOVQ	SP, BP
   172  	MOVL	0(DI), DI		// arg 1 exit status
   173  	CALL	libc_exit(SB)
   174  	MOVL	$0xf1, 0xf1  // crash
   175  	POPQ	BP
   176  	RET
   177  
   178  TEXT runtime·getthrid_trampoline(SB),NOSPLIT,$0
   179  	PUSHQ	BP
   180  	MOVQ	SP, BP
   181  	MOVQ	DI, BX			// BX is caller-save
   182  	CALL	libc_getthrid(SB)
   183  	MOVL	AX, 0(BX)		// return value
   184  	POPQ	BP
   185  	RET
   186  
   187  TEXT runtime·raiseproc_trampoline(SB),NOSPLIT,$0
   188  	PUSHQ	BP
   189  	MOVQ	SP, BP
   190  	MOVL	0(DI), BX	// signal
   191  	CALL	libc_getpid(SB)
   192  	MOVL	AX, DI		// arg 1 pid
   193  	MOVL	BX, SI		// arg 2 signal
   194  	CALL	libc_kill(SB)
   195  	POPQ	BP
   196  	RET
   197  
   198  TEXT runtime·sched_yield_trampoline(SB),NOSPLIT,$0
   199  	PUSHQ	BP
   200  	MOVQ	SP, BP
   201  	CALL	libc_sched_yield(SB)
   202  	POPQ	BP
   203  	RET
   204  
   205  TEXT runtime·mmap_trampoline(SB),NOSPLIT,$0
   206  	PUSHQ	BP			// make a frame; keep stack aligned
   207  	MOVQ	SP, BP
   208  	MOVQ	DI, BX
   209  	MOVQ	0(BX), DI		// arg 1 addr
   210  	MOVQ	8(BX), SI		// arg 2 len
   211  	MOVL	16(BX), DX		// arg 3 prot
   212  	MOVL	20(BX), CX		// arg 4 flags
   213  	MOVL	24(BX), R8		// arg 5 fid
   214  	MOVL	28(BX), R9		// arg 6 offset
   215  	CALL	libc_mmap(SB)
   216  	XORL	DX, DX
   217  	CMPQ	AX, $-1
   218  	JNE	ok
   219  	CALL	libc_errno(SB)
   220  	MOVLQSX	(AX), DX		// errno
   221  	XORQ	AX, AX
   222  ok:
   223  	MOVQ	AX, 32(BX)
   224  	MOVQ	DX, 40(BX)
   225  	POPQ	BP
   226  	RET
   227  
   228  TEXT runtime·munmap_trampoline(SB),NOSPLIT,$0
   229  	PUSHQ	BP
   230  	MOVQ	SP, BP
   231  	MOVQ	8(DI), SI		// arg 2 len
   232  	MOVQ	0(DI), DI		// arg 1 addr
   233  	CALL	libc_munmap(SB)
   234  	TESTQ	AX, AX
   235  	JEQ	2(PC)
   236  	MOVL	$0xf1, 0xf1  // crash
   237  	POPQ	BP
   238  	RET
   239  
   240  TEXT runtime·madvise_trampoline(SB), NOSPLIT, $0
   241  	PUSHQ	BP
   242  	MOVQ	SP, BP
   243  	MOVQ	8(DI), SI	// arg 2 len
   244  	MOVL	16(DI), DX	// arg 3 advice
   245  	MOVQ	0(DI), DI	// arg 1 addr
   246  	CALL	libc_madvise(SB)
   247  	// ignore failure - maybe pages are locked
   248  	POPQ	BP
   249  	RET
   250  
   251  TEXT runtime·open_trampoline(SB),NOSPLIT,$0
   252  	PUSHQ	BP
   253  	MOVQ	SP, BP
   254  	MOVL	8(DI), SI		// arg 2 - flags
   255  	MOVL	12(DI), DX		// arg 3 - mode
   256  	MOVQ	0(DI), DI		// arg 1 - path
   257  	XORL	AX, AX			// vararg: say "no float args"
   258  	CALL	libc_open(SB)
   259  	POPQ	BP
   260  	RET
   261  
   262  TEXT runtime·close_trampoline(SB),NOSPLIT,$0
   263  	PUSHQ	BP
   264  	MOVQ	SP, BP
   265  	MOVL	0(DI), DI		// arg 1 - fd
   266  	CALL	libc_close(SB)
   267  	POPQ	BP
   268  	RET
   269  
   270  TEXT runtime·read_trampoline(SB),NOSPLIT,$0
   271  	PUSHQ	BP
   272  	MOVQ	SP, BP
   273  	MOVQ	8(DI), SI		// arg 2 - buf
   274  	MOVL	16(DI), DX		// arg 3 - count
   275  	MOVL	0(DI), DI		// arg 1 - fd
   276  	CALL	libc_read(SB)
   277  	TESTL	AX, AX
   278  	JGE	noerr
   279  	CALL	libc_errno(SB)
   280  	MOVL	(AX), AX		// errno
   281  	NEGL	AX			// caller expects negative errno value
   282  noerr:
   283  	POPQ	BP
   284  	RET
   285  
   286  TEXT runtime·write_trampoline(SB),NOSPLIT,$0
   287  	PUSHQ	BP
   288  	MOVQ	SP, BP
   289  	MOVQ	8(DI), SI		// arg 2 buf
   290  	MOVL	16(DI), DX		// arg 3 count
   291  	MOVL	0(DI), DI		// arg 1 fd
   292  	CALL	libc_write(SB)
   293  	TESTL	AX, AX
   294  	JGE	noerr
   295  	CALL	libc_errno(SB)
   296  	MOVL	(AX), AX		// errno
   297  	NEGL	AX			// caller expects negative errno value
   298  noerr:
   299  	POPQ	BP
   300  	RET
   301  
   302  TEXT runtime·pipe2_trampoline(SB),NOSPLIT,$0
   303  	PUSHQ	BP
   304  	MOVQ	SP, BP
   305  	MOVL	8(DI), SI		// arg 2 flags
   306  	MOVQ	0(DI), DI		// arg 1 filedes
   307  	CALL	libc_pipe2(SB)
   308  	TESTL	AX, AX
   309  	JEQ	3(PC)
   310  	CALL	libc_errno(SB)
   311  	MOVL	(AX), AX		// errno
   312  	NEGL	AX			// caller expects negative errno value
   313  	POPQ	BP
   314  	RET
   315  
   316  TEXT runtime·setitimer_trampoline(SB),NOSPLIT,$0
   317  	PUSHQ	BP
   318  	MOVQ	SP, BP
   319  	MOVQ	8(DI), SI		// arg 2 new
   320  	MOVQ	16(DI), DX		// arg 3 old
   321  	MOVL	0(DI), DI		// arg 1 which
   322  	CALL	libc_setitimer(SB)
   323  	POPQ	BP
   324  	RET
   325  
   326  TEXT runtime·usleep_trampoline(SB),NOSPLIT,$0
   327  	PUSHQ	BP
   328  	MOVQ	SP, BP
   329  	MOVL	0(DI), DI		// arg 1 usec
   330  	CALL	libc_usleep(SB)
   331  	POPQ	BP
   332  	RET
   333  
   334  TEXT runtime·sysctl_trampoline(SB),NOSPLIT,$0
   335  	PUSHQ	BP
   336  	MOVQ	SP, BP
   337  	MOVL	8(DI), SI		// arg 2 miblen
   338  	MOVQ	16(DI), DX		// arg 3 out
   339  	MOVQ	24(DI), CX		// arg 4 size
   340  	MOVQ	32(DI), R8		// arg 5 dst
   341  	MOVQ	40(DI), R9		// arg 6 ndst
   342  	MOVQ	0(DI), DI		// arg 1 mib
   343  	CALL	libc_sysctl(SB)
   344  	POPQ	BP
   345  	RET
   346  
   347  TEXT runtime·kqueue_trampoline(SB),NOSPLIT,$0
   348  	PUSHQ	BP
   349  	MOVQ	SP, BP
   350  	CALL	libc_kqueue(SB)
   351  	POPQ	BP
   352  	RET
   353  
   354  TEXT runtime·kevent_trampoline(SB),NOSPLIT,$0
   355  	PUSHQ	BP
   356  	MOVQ	SP, BP
   357  	MOVQ	8(DI), SI		// arg 2 keventt
   358  	MOVL	16(DI), DX		// arg 3 nch
   359  	MOVQ	24(DI), CX		// arg 4 ev
   360  	MOVL	32(DI), R8		// arg 5 nev
   361  	MOVQ	40(DI), R9		// arg 6 ts
   362  	MOVL	0(DI), DI		// arg 1 kq
   363  	CALL	libc_kevent(SB)
   364  	CMPL	AX, $-1
   365  	JNE	ok
   366  	CALL	libc_errno(SB)
   367  	MOVL	(AX), AX		// errno
   368  	NEGL	AX			// caller expects negative errno value
   369  ok:
   370  	POPQ	BP
   371  	RET
   372  
   373  TEXT runtime·clock_gettime_trampoline(SB),NOSPLIT,$0
   374  	PUSHQ	BP			// make a frame; keep stack aligned
   375  	MOVQ	SP, BP
   376  	MOVQ	8(DI), SI		// arg 2 tp
   377  	MOVL	0(DI), DI		// arg 1 clock_id
   378  	CALL	libc_clock_gettime(SB)
   379  	TESTL	AX, AX
   380  	JEQ	noerr
   381  	CALL	libc_errno(SB)
   382  	MOVL	(AX), AX		// errno
   383  	NEGL	AX			// caller expects negative errno value
   384  noerr:
   385  	POPQ	BP
   386  	RET
   387  
   388  TEXT runtime·fcntl_trampoline(SB),NOSPLIT,$0
   389  	PUSHQ	BP
   390  	MOVQ	SP, BP
   391  	MOVL	4(DI), SI		// arg 2 cmd
   392  	MOVL	8(DI), DX		// arg 3 arg
   393  	MOVL	0(DI), DI		// arg 1 fd
   394  	XORL	AX, AX			// vararg: say "no float args"
   395  	CALL	libc_fcntl(SB)
   396  	POPQ	BP
   397  	RET
   398  
   399  TEXT runtime·sigaction_trampoline(SB),NOSPLIT,$0
   400  	PUSHQ	BP
   401  	MOVQ	SP, BP
   402  	MOVQ	8(DI), SI		// arg 2 new
   403  	MOVQ	16(DI), DX		// arg 3 old
   404  	MOVL	0(DI), DI		// arg 1 sig
   405  	CALL	libc_sigaction(SB)
   406  	TESTL	AX, AX
   407  	JEQ	2(PC)
   408  	MOVL	$0xf1, 0xf1  // crash
   409  	POPQ	BP
   410  	RET
   411  
   412  TEXT runtime·sigprocmask_trampoline(SB),NOSPLIT,$0
   413  	PUSHQ	BP
   414  	MOVQ	SP, BP
   415  	MOVQ	8(DI), SI	// arg 2 new
   416  	MOVQ	16(DI), DX	// arg 3 old
   417  	MOVL	0(DI), DI	// arg 1 how
   418  	CALL	libc_pthread_sigmask(SB)
   419  	TESTL	AX, AX
   420  	JEQ	2(PC)
   421  	MOVL	$0xf1, 0xf1  // crash
   422  	POPQ	BP
   423  	RET
   424  
   425  TEXT runtime·sigaltstack_trampoline(SB),NOSPLIT,$0
   426  	PUSHQ	BP
   427  	MOVQ	SP, BP
   428  	MOVQ	8(DI), SI		// arg 2 old
   429  	MOVQ	0(DI), DI		// arg 1 new
   430  	CALL	libc_sigaltstack(SB)
   431  	TESTQ	AX, AX
   432  	JEQ	2(PC)
   433  	MOVL	$0xf1, 0xf1  // crash
   434  	POPQ	BP
   435  	RET
   436  
   437  // syscall calls a function in libc on behalf of the syscall package.
   438  // syscall takes a pointer to a struct like:
   439  // struct {
   440  //	fn    uintptr
   441  //	a1    uintptr
   442  //	a2    uintptr
   443  //	a3    uintptr
   444  //	r1    uintptr
   445  //	r2    uintptr
   446  //	err   uintptr
   447  // }
   448  // syscall must be called on the g0 stack with the
   449  // C calling convention (use libcCall).
   450  //
   451  // syscall expects a 32-bit result and tests for 32-bit -1
   452  // to decide there was an error.
   453  TEXT runtime·syscall(SB),NOSPLIT,$0
   454  	PUSHQ	BP
   455  	MOVQ	SP, BP
   456  	SUBQ	$16, SP
   457  	MOVQ	(0*8)(DI), CX // fn
   458  	MOVQ	(2*8)(DI), SI // a2
   459  	MOVQ	(3*8)(DI), DX // a3
   460  	MOVQ	DI, (SP)
   461  	MOVQ	(1*8)(DI), DI // a1
   462  	XORL	AX, AX	      // vararg: say "no float args"
   463  
   464  	CALL	CX
   465  
   466  	MOVQ	(SP), DI
   467  	MOVQ	AX, (4*8)(DI) // r1
   468  	MOVQ	DX, (5*8)(DI) // r2
   469  
   470  	// Standard libc functions return -1 on error
   471  	// and set errno.
   472  	CMPL	AX, $-1	      // Note: high 32 bits are junk
   473  	JNE	ok
   474  
   475  	// Get error code from libc.
   476  	CALL	libc_errno(SB)
   477  	MOVLQSX	(AX), AX
   478  	MOVQ	(SP), DI
   479  	MOVQ	AX, (6*8)(DI) // err
   480  
   481  ok:
   482  	XORL	AX, AX        // no error (it's ignored anyway)
   483  	MOVQ	BP, SP
   484  	POPQ	BP
   485  	RET
   486  
   487  // syscallX calls a function in libc on behalf of the syscall package.
   488  // syscallX takes a pointer to a struct like:
   489  // struct {
   490  //	fn    uintptr
   491  //	a1    uintptr
   492  //	a2    uintptr
   493  //	a3    uintptr
   494  //	r1    uintptr
   495  //	r2    uintptr
   496  //	err   uintptr
   497  // }
   498  // syscallX must be called on the g0 stack with the
   499  // C calling convention (use libcCall).
   500  //
   501  // syscallX is like syscall but expects a 64-bit result
   502  // and tests for 64-bit -1 to decide there was an error.
   503  TEXT runtime·syscallX(SB),NOSPLIT,$0
   504  	PUSHQ	BP
   505  	MOVQ	SP, BP
   506  	SUBQ	$16, SP
   507  	MOVQ	(0*8)(DI), CX // fn
   508  	MOVQ	(2*8)(DI), SI // a2
   509  	MOVQ	(3*8)(DI), DX // a3
   510  	MOVQ	DI, (SP)
   511  	MOVQ	(1*8)(DI), DI // a1
   512  	XORL	AX, AX	      // vararg: say "no float args"
   513  
   514  	CALL	CX
   515  
   516  	MOVQ	(SP), DI
   517  	MOVQ	AX, (4*8)(DI) // r1
   518  	MOVQ	DX, (5*8)(DI) // r2
   519  
   520  	// Standard libc functions return -1 on error
   521  	// and set errno.
   522  	CMPQ	AX, $-1
   523  	JNE	ok
   524  
   525  	// Get error code from libc.
   526  	CALL	libc_errno(SB)
   527  	MOVLQSX	(AX), AX
   528  	MOVQ	(SP), DI
   529  	MOVQ	AX, (6*8)(DI) // err
   530  
   531  ok:
   532  	XORL	AX, AX        // no error (it's ignored anyway)
   533  	MOVQ	BP, SP
   534  	POPQ	BP
   535  	RET
   536  
   537  // syscall6 calls a function in libc on behalf of the syscall package.
   538  // syscall6 takes a pointer to a struct like:
   539  // struct {
   540  //	fn    uintptr
   541  //	a1    uintptr
   542  //	a2    uintptr
   543  //	a3    uintptr
   544  //	a4    uintptr
   545  //	a5    uintptr
   546  //	a6    uintptr
   547  //	r1    uintptr
   548  //	r2    uintptr
   549  //	err   uintptr
   550  // }
   551  // syscall6 must be called on the g0 stack with the
   552  // C calling convention (use libcCall).
   553  //
   554  // syscall6 expects a 32-bit result and tests for 32-bit -1
   555  // to decide there was an error.
   556  TEXT runtime·syscall6(SB),NOSPLIT,$0
   557  	PUSHQ	BP
   558  	MOVQ	SP, BP
   559  	SUBQ	$16, SP
   560  	MOVQ	(0*8)(DI), R11// fn
   561  	MOVQ	(2*8)(DI), SI // a2
   562  	MOVQ	(3*8)(DI), DX // a3
   563  	MOVQ	(4*8)(DI), CX // a4
   564  	MOVQ	(5*8)(DI), R8 // a5
   565  	MOVQ	(6*8)(DI), R9 // a6
   566  	MOVQ	DI, (SP)
   567  	MOVQ	(1*8)(DI), DI // a1
   568  	XORL	AX, AX	      // vararg: say "no float args"
   569  
   570  	CALL	R11
   571  
   572  	MOVQ	(SP), DI
   573  	MOVQ	AX, (7*8)(DI) // r1
   574  	MOVQ	DX, (8*8)(DI) // r2
   575  
   576  	CMPL	AX, $-1
   577  	JNE	ok
   578  
   579  	CALL	libc_errno(SB)
   580  	MOVLQSX	(AX), AX
   581  	MOVQ	(SP), DI
   582  	MOVQ	AX, (9*8)(DI) // err
   583  
   584  ok:
   585  	XORL	AX, AX        // no error (it's ignored anyway)
   586  	MOVQ	BP, SP
   587  	POPQ	BP
   588  	RET
   589  
   590  // syscall6X calls a function in libc on behalf of the syscall package.
   591  // syscall6X takes a pointer to a struct like:
   592  // struct {
   593  //	fn    uintptr
   594  //	a1    uintptr
   595  //	a2    uintptr
   596  //	a3    uintptr
   597  //	a4    uintptr
   598  //	a5    uintptr
   599  //	a6    uintptr
   600  //	r1    uintptr
   601  //	r2    uintptr
   602  //	err   uintptr
   603  // }
   604  // syscall6X must be called on the g0 stack with the
   605  // C calling convention (use libcCall).
   606  //
   607  // syscall6X is like syscall6 but expects a 64-bit result
   608  // and tests for 64-bit -1 to decide there was an error.
   609  TEXT runtime·syscall6X(SB),NOSPLIT,$0
   610  	PUSHQ	BP
   611  	MOVQ	SP, BP
   612  	SUBQ	$16, SP
   613  	MOVQ	(0*8)(DI), R11// fn
   614  	MOVQ	(2*8)(DI), SI // a2
   615  	MOVQ	(3*8)(DI), DX // a3
   616  	MOVQ	(4*8)(DI), CX // a4
   617  	MOVQ	(5*8)(DI), R8 // a5
   618  	MOVQ	(6*8)(DI), R9 // a6
   619  	MOVQ	DI, (SP)
   620  	MOVQ	(1*8)(DI), DI // a1
   621  	XORL	AX, AX	      // vararg: say "no float args"
   622  
   623  	CALL	R11
   624  
   625  	MOVQ	(SP), DI
   626  	MOVQ	AX, (7*8)(DI) // r1
   627  	MOVQ	DX, (8*8)(DI) // r2
   628  
   629  	CMPQ	AX, $-1
   630  	JNE	ok
   631  
   632  	CALL	libc_errno(SB)
   633  	MOVLQSX	(AX), AX
   634  	MOVQ	(SP), DI
   635  	MOVQ	AX, (9*8)(DI) // err
   636  
   637  ok:
   638  	XORL	AX, AX        // no error (it's ignored anyway)
   639  	MOVQ	BP, SP
   640  	POPQ	BP
   641  	RET
   642  
   643  // syscall10 calls a function in libc on behalf of the syscall package.
   644  // syscall10 takes a pointer to a struct like:
   645  // struct {
   646  //	fn    uintptr
   647  //	a1    uintptr
   648  //	a2    uintptr
   649  //	a3    uintptr
   650  //	a4    uintptr
   651  //	a5    uintptr
   652  //	a6    uintptr
   653  //	a7    uintptr
   654  //	a8    uintptr
   655  //	a9    uintptr
   656  //	a10   uintptr
   657  //	r1    uintptr
   658  //	r2    uintptr
   659  //	err   uintptr
   660  // }
   661  // syscall10 must be called on the g0 stack with the
   662  // C calling convention (use libcCall).
   663  TEXT runtime·syscall10(SB),NOSPLIT,$0
   664  	PUSHQ	BP
   665  	MOVQ	SP, BP
   666  	SUBQ    $48, SP
   667  
   668  	// Arguments a1 to a6 get passed in registers, with a7 onwards being
   669  	// passed via the stack per the x86-64 System V ABI
   670  	// (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
   671  	MOVQ	(7*8)(DI), R10	// a7
   672  	MOVQ	(8*8)(DI), R11	// a8
   673  	MOVQ	(9*8)(DI), R12	// a9
   674  	MOVQ	(10*8)(DI), R13	// a10
   675  	MOVQ	R10, (0*8)(SP)	// a7
   676  	MOVQ	R11, (1*8)(SP)	// a8
   677  	MOVQ	R12, (2*8)(SP)	// a9
   678  	MOVQ	R13, (3*8)(SP)	// a10
   679  	MOVQ	(0*8)(DI), R11	// fn
   680  	MOVQ	(2*8)(DI), SI	// a2
   681  	MOVQ	(3*8)(DI), DX	// a3
   682  	MOVQ	(4*8)(DI), CX	// a4
   683  	MOVQ	(5*8)(DI), R8	// a5
   684  	MOVQ	(6*8)(DI), R9	// a6
   685  	MOVQ	DI, (4*8)(SP)
   686  	MOVQ	(1*8)(DI), DI	// a1
   687  	XORL	AX, AX	     	// vararg: say "no float args"
   688  
   689  	CALL	R11
   690  
   691  	MOVQ	(4*8)(SP), DI
   692  	MOVQ	AX, (11*8)(DI) // r1
   693  	MOVQ	DX, (12*8)(DI) // r2
   694  
   695  	CMPL	AX, $-1
   696  	JNE	ok
   697  
   698  	CALL	libc_errno(SB)
   699  	MOVLQSX	(AX), AX
   700  	MOVQ	(4*8)(SP), DI
   701  	MOVQ	AX, (13*8)(DI) // err
   702  
   703  ok:
   704  	XORL	AX, AX        // no error (it's ignored anyway)
   705  	MOVQ	BP, SP
   706  	POPQ	BP
   707  	RET
   708  
   709  // syscall10X calls a function in libc on behalf of the syscall package.
   710  // syscall10X takes a pointer to a struct like:
   711  // struct {
   712  //	fn    uintptr
   713  //	a1    uintptr
   714  //	a2    uintptr
   715  //	a3    uintptr
   716  //	a4    uintptr
   717  //	a5    uintptr
   718  //	a6    uintptr
   719  //	a7    uintptr
   720  //	a8    uintptr
   721  //	a9    uintptr
   722  //	a10   uintptr
   723  //	r1    uintptr
   724  //	r2    uintptr
   725  //	err   uintptr
   726  // }
   727  // syscall10X must be called on the g0 stack with the
   728  // C calling convention (use libcCall).
   729  //
   730  // syscall10X is like syscall10 but expects a 64-bit result
   731  // and tests for 64-bit -1 to decide there was an error.
   732  TEXT runtime·syscall10X(SB),NOSPLIT,$0
   733  	PUSHQ	BP
   734  	MOVQ	SP, BP
   735  	SUBQ    $48, SP
   736  
   737  	// Arguments a1 to a6 get passed in registers, with a7 onwards being
   738  	// passed via the stack per the x86-64 System V ABI
   739  	// (https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf).
   740  	MOVQ	(7*8)(DI), R10	// a7
   741  	MOVQ	(8*8)(DI), R11	// a8
   742  	MOVQ	(9*8)(DI), R12	// a9
   743  	MOVQ	(10*8)(DI), R13	// a10
   744  	MOVQ	R10, (0*8)(SP)	// a7
   745  	MOVQ	R11, (1*8)(SP)	// a8
   746  	MOVQ	R12, (2*8)(SP)	// a9
   747  	MOVQ	R13, (3*8)(SP)	// a10
   748  	MOVQ	(0*8)(DI), R11	// fn
   749  	MOVQ	(2*8)(DI), SI	// a2
   750  	MOVQ	(3*8)(DI), DX	// a3
   751  	MOVQ	(4*8)(DI), CX	// a4
   752  	MOVQ	(5*8)(DI), R8	// a5
   753  	MOVQ	(6*8)(DI), R9	// a6
   754  	MOVQ	DI, (4*8)(SP)
   755  	MOVQ	(1*8)(DI), DI	// a1
   756  	XORL	AX, AX	     	// vararg: say "no float args"
   757  
   758  	CALL	R11
   759  
   760  	MOVQ	(4*8)(SP), DI
   761  	MOVQ	AX, (11*8)(DI) // r1
   762  	MOVQ	DX, (12*8)(DI) // r2
   763  
   764  	CMPQ	AX, $-1
   765  	JNE	ok
   766  
   767  	CALL	libc_errno(SB)
   768  	MOVLQSX	(AX), AX
   769  	MOVQ	(4*8)(SP), DI
   770  	MOVQ	AX, (13*8)(DI) // err
   771  
   772  ok:
   773  	XORL	AX, AX        // no error (it's ignored anyway)
   774  	MOVQ	BP, SP
   775  	POPQ	BP
   776  	RET
   777  

View as plain text