github.com/tcnksm/go@v0.0.0-20141208075154-439b32936367/src/runtime/sys_solaris_amd64.s (about)

     1  // Copyright 2014 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, SunOS
     6  // /usr/include/sys/syscall.h for syscall numbers.
     7  //
     8  
     9  #include "go_asm.h"
    10  #include "go_tls.h"
    11  #include "textflag.h"
    12  
    13  // This is needed by asm_amd64.s
    14  TEXT runtime·settls(SB),NOSPLIT,$8
    15  	RET
    16  
    17  // void libc_miniterrno(void *(*___errno)(void));
    18  //
    19  // Set the TLS errno pointer in M.
    20  //
    21  // Called using runtime·asmcgocall from os_solaris.c:/minit.
    22  // NOT USING GO CALLING CONVENTION.
    23  TEXT runtime·miniterrno(SB),NOSPLIT,$0
    24  	// asmcgocall will put first argument into DI.
    25  	CALL	DI	// SysV ABI so returns in AX
    26  	get_tls(CX)
    27  	MOVQ	g(CX), BX
    28  	MOVQ	g_m(BX), BX
    29  	MOVQ	AX,	m_perrno(BX)
    30  	RET
    31  
    32  // int64 runtime·nanotime1(void);
    33  //
    34  // clock_gettime(3c) wrapper because Timespec is too large for
    35  // runtime·nanotime stack.
    36  //
    37  // Called using runtime·sysvicall6 from os_solaris.c:/nanotime.
    38  // NOT USING GO CALLING CONVENTION.
    39  TEXT runtime·nanotime1(SB),NOSPLIT,$0
    40  	// need space for the timespec argument.
    41  	SUBQ	$64, SP	// 16 bytes will do, but who knows in the future?
    42  	MOVQ	$3, DI	// CLOCK_REALTIME from <sys/time_impl.h>
    43  	MOVQ	SP, SI
    44  	MOVQ	libc_clock_gettime(SB), AX
    45  	CALL	AX
    46  	MOVQ	(SP), AX	// tv_sec from struct timespec
    47  	IMULQ	$1000000000, AX	// multiply into nanoseconds
    48  	ADDQ	8(SP), AX	// tv_nsec, offset should be stable.
    49  	ADDQ	$64, SP
    50  	RET
    51  
    52  // pipe(3c) wrapper that returns fds in AX, DX.
    53  // NOT USING GO CALLING CONVENTION.
    54  TEXT runtime·pipe1(SB),NOSPLIT,$0
    55  	SUBQ	$16, SP // 8 bytes will do, but stack has to be 16-byte alligned
    56  	MOVQ	SP, DI
    57  	MOVQ	libc_pipe(SB), AX
    58  	CALL	AX
    59  	MOVL	0(SP), AX
    60  	MOVL	4(SP), DX
    61  	ADDQ	$16, SP
    62  	RET
    63  
    64  // Call a library function with SysV calling conventions.
    65  // The called function can take a maximum of 6 INTEGER class arguments,
    66  // see 
    67  //   Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
    68  //   System V Application Binary Interface 
    69  //   AMD64 Architecture Processor Supplement
    70  // section 3.2.3.
    71  //
    72  // Called by runtime·asmcgocall or runtime·cgocall.
    73  // NOT USING GO CALLING CONVENTION.
    74  TEXT runtime·asmsysvicall6(SB),NOSPLIT,$0
    75  	// asmcgocall will put first argument into DI.
    76  	PUSHQ	DI			// save for later
    77  	MOVQ	libcall_fn(DI), AX
    78  	MOVQ	libcall_args(DI), R11
    79  	MOVQ	libcall_n(DI), R10
    80  
    81  	get_tls(CX)
    82  	MOVQ	g(CX), BX
    83  	MOVQ	g_m(BX), BX
    84  	MOVQ	m_perrno(BX), DX
    85  	CMPQ	DX, $0
    86  	JEQ	skiperrno1
    87  	MOVL	$0, 0(DX)
    88  
    89  skiperrno1:
    90  	CMPQ	R11, $0
    91  	JEQ	skipargs
    92  	// Load 6 args into correspondent registers.
    93  	MOVQ	0(R11), DI
    94  	MOVQ	8(R11), SI
    95  	MOVQ	16(R11), DX
    96  	MOVQ	24(R11), CX
    97  	MOVQ	32(R11), R8
    98  	MOVQ	40(R11), R9
    99  skipargs:
   100  
   101  	// Call SysV function
   102  	CALL	AX
   103  
   104  	// Return result
   105  	POPQ	DI
   106  	MOVQ	AX, libcall_r1(DI)
   107  	MOVQ	DX, libcall_r2(DI)
   108  
   109  	get_tls(CX)
   110  	MOVQ	g(CX), BX
   111  	MOVQ	g_m(BX), BX
   112  	MOVQ	m_perrno(BX), AX
   113  	CMPQ	AX, $0
   114  	JEQ	skiperrno2
   115  	MOVL	0(AX), AX
   116  	MOVQ	AX, libcall_err(DI)
   117  
   118  skiperrno2:	
   119  	RET
   120  
   121  // uint32 tstart_sysvicall(M *newm);
   122  TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0
   123  	// DI contains first arg newm
   124  	MOVQ	m_g0(DI), DX		// g
   125  
   126  	// Make TLS entries point at g and m.
   127  	get_tls(BX)
   128  	MOVQ	DX, g(BX)
   129  	MOVQ	DI, g_m(DX)
   130  
   131  	// Layout new m scheduler stack on os stack.
   132  	MOVQ	SP, AX
   133  	MOVQ	AX, (g_stack+stack_hi)(DX)
   134  	SUBQ	$(0x100000), AX		// stack size
   135  	MOVQ	AX, (g_stack+stack_lo)(DX)
   136  	ADDQ	$const__StackGuard, AX
   137  	MOVQ	AX, g_stackguard0(DX)
   138  	MOVQ	AX, g_stackguard1(DX)
   139  
   140  	// Someday the convention will be D is always cleared.
   141  	CLD
   142  
   143  	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
   144  	CALL	runtime·mstart(SB)
   145  
   146  	XORL	AX, AX			// return 0 == success
   147  	MOVL	AX, ret+8(FP)
   148  	RET
   149  
   150  // Careful, this is called by __sighndlr, a libc function. We must preserve
   151  // registers as per AMD 64 ABI.
   152  TEXT runtime·sigtramp(SB),NOSPLIT,$0
   153  	// Note that we are executing on altsigstack here, so we have
   154  	// more stack available than NOSPLIT would have us believe.
   155  	// To defeat the linker, we make our own stack frame with
   156  	// more space:
   157  	SUBQ    $184, SP
   158  
   159  	// save registers
   160  	MOVQ    BX, 32(SP)
   161  	MOVQ    BP, 40(SP)
   162  	MOVQ	R12, 48(SP)
   163  	MOVQ	R13, 56(SP)
   164  	MOVQ	R14, 64(SP)
   165  	MOVQ	R15, 72(SP)
   166  
   167  	get_tls(BX)
   168  	// check that g exists
   169  	MOVQ	g(BX), R10
   170  	CMPQ	R10, $0
   171  	JNE	allgood
   172  	MOVQ	DI, 0(SP)
   173  	MOVQ	$runtime·badsignal(SB), AX
   174  	CALL	AX
   175  	JMP	exit
   176  
   177  allgood:
   178  	// save g
   179  	MOVQ	R10, 80(SP)
   180  
   181  	// Save m->libcall and m->scratch. We need to do this because we
   182  	// might get interrupted by a signal in runtime·asmcgocall.
   183  
   184  	// save m->libcall 
   185  	MOVQ	g_m(R10), BP
   186  	LEAQ	m_libcall(BP), R11
   187  	MOVQ	libcall_fn(R11), R10
   188  	MOVQ	R10, 88(SP)
   189  	MOVQ	libcall_args(R11), R10
   190  	MOVQ	R10, 96(SP)
   191  	MOVQ	libcall_n(R11), R10
   192  	MOVQ	R10, 104(SP)
   193  	MOVQ    libcall_r1(R11), R10
   194  	MOVQ    R10, 168(SP)
   195  	MOVQ    libcall_r2(R11), R10
   196  	MOVQ    R10, 176(SP)
   197  
   198  	// save m->scratch
   199  	LEAQ	m_scratch(BP), R11
   200  	MOVQ	0(R11), R10
   201  	MOVQ	R10, 112(SP)
   202  	MOVQ	8(R11), R10
   203  	MOVQ	R10, 120(SP)
   204  	MOVQ	16(R11), R10
   205  	MOVQ	R10, 128(SP)
   206  	MOVQ	24(R11), R10
   207  	MOVQ	R10, 136(SP)
   208  	MOVQ	32(R11), R10
   209  	MOVQ	R10, 144(SP)
   210  	MOVQ	40(R11), R10
   211  	MOVQ	R10, 152(SP)
   212  
   213  	// save errno, it might be EINTR; stuff we do here might reset it.
   214  	MOVQ	m_perrno(BP), R10
   215  	MOVL	0(R10), R10
   216  	MOVQ	R10, 160(SP)
   217  
   218  	MOVQ	g(BX), R10
   219  	// g = m->gsignal
   220  	MOVQ	m_gsignal(BP), BP
   221  	MOVQ	BP, g(BX)
   222  
   223  	// prepare call
   224  	MOVQ	DI, 0(SP)
   225  	MOVQ	SI, 8(SP)
   226  	MOVQ	DX, 16(SP)
   227  	MOVQ	R10, 24(SP)
   228  	CALL	runtime·sighandler(SB)
   229  
   230  	get_tls(BX)
   231  	MOVQ	g(BX), BP
   232  	MOVQ	g_m(BP), BP
   233  	// restore libcall
   234  	LEAQ	m_libcall(BP), R11
   235  	MOVQ	88(SP), R10
   236  	MOVQ	R10, libcall_fn(R11)
   237  	MOVQ	96(SP), R10
   238  	MOVQ	R10, libcall_args(R11)
   239  	MOVQ	104(SP), R10
   240  	MOVQ	R10, libcall_n(R11)
   241  	MOVQ    168(SP), R10
   242  	MOVQ    R10, libcall_r1(R11)
   243  	MOVQ    176(SP), R10
   244  	MOVQ    R10, libcall_r2(R11)
   245  
   246  	// restore scratch
   247  	LEAQ	m_scratch(BP), R11
   248  	MOVQ	112(SP), R10
   249  	MOVQ	R10, 0(R11)
   250  	MOVQ	120(SP), R10
   251  	MOVQ	R10, 8(R11)
   252  	MOVQ	128(SP), R10
   253  	MOVQ	R10, 16(R11)
   254  	MOVQ	136(SP), R10
   255  	MOVQ	R10, 24(R11)
   256  	MOVQ	144(SP), R10
   257  	MOVQ	R10, 32(R11)
   258  	MOVQ	152(SP), R10
   259  	MOVQ	R10, 40(R11)
   260  
   261  	// restore errno
   262  	MOVQ	m_perrno(BP), R11
   263  	MOVQ	160(SP), R10
   264  	MOVL	R10, 0(R11)
   265  
   266  	// restore g
   267  	MOVQ	80(SP), R10
   268  	MOVQ	R10, g(BX)
   269  
   270  exit:
   271  	// restore registers
   272  	MOVQ	32(SP), BX
   273  	MOVQ	40(SP), BP
   274  	MOVQ	48(SP), R12
   275  	MOVQ	56(SP), R13
   276  	MOVQ	64(SP), R14
   277  	MOVQ	72(SP), R15
   278  
   279  	ADDQ    $184, SP
   280  	RET
   281  
   282  // Called from runtime·usleep (Go). Can be called on Go stack, on OS stack,
   283  // can also be called in cgo callback path without a g->m.
   284  TEXT runtime·usleep1(SB),NOSPLIT,$0
   285  	MOVL	usec+0(FP), DI
   286  	MOVQ	$runtime·usleep2(SB), AX // to hide from 6l
   287  
   288  	// Execute call on m->g0.
   289  	get_tls(R15)
   290  	CMPQ	R15, $0
   291  	JE	noswitch
   292  
   293  	MOVQ	g(R15), R13
   294  	CMPQ	R13, $0
   295  	JE	noswitch
   296  	MOVQ	g_m(R13), R13
   297  	CMPQ	R13, $0
   298  	JE	noswitch
   299  	// TODO(aram): do something about the cpu profiler here.
   300  
   301  	MOVQ	m_g0(R13), R14
   302  	CMPQ	g(R15), R14
   303  	JNE	switch
   304  	// executing on m->g0 already
   305  	CALL	AX
   306  	RET
   307  
   308  switch:
   309  	// Switch to m->g0 stack and back.
   310  	MOVQ	(g_sched+gobuf_sp)(R14), R14
   311  	MOVQ	SP, -8(R14)
   312  	LEAQ	-8(R14), SP
   313  	CALL	AX
   314  	MOVQ	0(SP), SP
   315  	RET
   316  
   317  noswitch:
   318  	// Not a Go-managed thread. Do not switch stack.
   319  	CALL	AX
   320  	RET
   321  
   322  // Runs on OS stack. duration (in µs units) is in DI.
   323  TEXT runtime·usleep2(SB),NOSPLIT,$0
   324  	MOVQ	libc_usleep(SB), AX
   325  	CALL	AX
   326  	RET
   327  
   328  // Runs on OS stack, called from runtime·osyield.
   329  TEXT runtime·osyield1(SB),NOSPLIT,$0
   330  	MOVQ	libc_sched_yield(SB), AX
   331  	CALL	AX
   332  	RET
   333  
   334  // func now() (sec int64, nsec int32)
   335  TEXT time·now(SB),NOSPLIT,$8-12
   336  	CALL	runtime·nanotime(SB)
   337  	MOVQ	0(SP), AX
   338  
   339  	// generated code for
   340  	//	func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
   341  	// adapted to reduce duplication
   342  	MOVQ	AX, CX
   343  	MOVQ	$1360296554856532783, AX
   344  	MULQ	CX
   345  	ADDQ	CX, DX
   346  	RCRQ	$1, DX
   347  	SHRQ	$29, DX
   348  	MOVQ	DX, sec+0(FP)
   349  	IMULQ	$1000000000, DX
   350  	SUBQ	DX, CX
   351  	MOVL	CX, nsec+8(FP)
   352  	RET