github.com/fjballest/golang@v0.0.0-20151209143359-e4c5fe594ca8/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_mOS+mOS_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  	LEAQ	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  	LEAQ	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  	CMPQ	BX, $0
    84  	JEQ	skiperrno1
    85  	MOVQ	g_m(BX), BX
    86  	MOVQ	(m_mOS+mOS_perrno)(BX), DX
    87  	CMPQ	DX, $0
    88  	JEQ	skiperrno1
    89  	MOVL	$0, 0(DX)
    90  
    91  skiperrno1:
    92  	CMPQ	R11, $0
    93  	JEQ	skipargs
    94  	// Load 6 args into correspondent registers.
    95  	MOVQ	0(R11), DI
    96  	MOVQ	8(R11), SI
    97  	MOVQ	16(R11), DX
    98  	MOVQ	24(R11), CX
    99  	MOVQ	32(R11), R8
   100  	MOVQ	40(R11), R9
   101  skipargs:
   102  
   103  	// Call SysV function
   104  	CALL	AX
   105  
   106  	// Return result
   107  	POPQ	DI
   108  	MOVQ	AX, libcall_r1(DI)
   109  	MOVQ	DX, libcall_r2(DI)
   110  
   111  	get_tls(CX)
   112  	MOVQ	g(CX), BX
   113  	CMPQ	BX, $0
   114  	JEQ	skiperrno2
   115  	MOVQ	g_m(BX), BX
   116  	MOVQ	(m_mOS+mOS_perrno)(BX), AX
   117  	CMPQ	AX, $0
   118  	JEQ	skiperrno2
   119  	MOVL	0(AX), AX
   120  	MOVQ	AX, libcall_err(DI)
   121  
   122  skiperrno2:	
   123  	RET
   124  
   125  // uint32 tstart_sysvicall(M *newm);
   126  TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0
   127  	// DI contains first arg newm
   128  	MOVQ	m_g0(DI), DX		// g
   129  
   130  	// Make TLS entries point at g and m.
   131  	get_tls(BX)
   132  	MOVQ	DX, g(BX)
   133  	MOVQ	DI, g_m(DX)
   134  
   135  	// Layout new m scheduler stack on os stack.
   136  	MOVQ	SP, AX
   137  	MOVQ	AX, (g_stack+stack_hi)(DX)
   138  	SUBQ	$(0x100000), AX		// stack size
   139  	MOVQ	AX, (g_stack+stack_lo)(DX)
   140  	ADDQ	$const__StackGuard, AX
   141  	MOVQ	AX, g_stackguard0(DX)
   142  	MOVQ	AX, g_stackguard1(DX)
   143  
   144  	// Someday the convention will be D is always cleared.
   145  	CLD
   146  
   147  	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
   148  	CALL	runtime·mstart(SB)
   149  
   150  	XORL	AX, AX			// return 0 == success
   151  	MOVL	AX, ret+8(FP)
   152  	RET
   153  
   154  // Careful, this is called by __sighndlr, a libc function. We must preserve
   155  // registers as per AMD 64 ABI.
   156  TEXT runtime·sigtramp(SB),NOSPLIT,$0
   157  	// Note that we are executing on altsigstack here, so we have
   158  	// more stack available than NOSPLIT would have us believe.
   159  	// To defeat the linker, we make our own stack frame with
   160  	// more space:
   161  	SUBQ    $184, SP
   162  
   163  	// save registers
   164  	MOVQ    BX, 32(SP)
   165  	MOVQ    BP, 40(SP)
   166  	MOVQ	R12, 48(SP)
   167  	MOVQ	R13, 56(SP)
   168  	MOVQ	R14, 64(SP)
   169  	MOVQ	R15, 72(SP)
   170  
   171  	get_tls(BX)
   172  	// check that g exists
   173  	MOVQ	g(BX), R10
   174  	CMPQ	R10, $0
   175  	JNE	allgood
   176  	MOVQ	DI, 0(SP)
   177  	MOVQ	$runtime·badsignal(SB), AX
   178  	CALL	AX
   179  	JMP	exit
   180  
   181  allgood:
   182  	// save g
   183  	MOVQ	R10, 80(SP)
   184  
   185  	// Save m->libcall and m->scratch. We need to do this because we
   186  	// might get interrupted by a signal in runtime·asmcgocall.
   187  
   188  	// save m->libcall 
   189  	MOVQ	g_m(R10), BP
   190  	LEAQ	m_libcall(BP), R11
   191  	MOVQ	libcall_fn(R11), R10
   192  	MOVQ	R10, 88(SP)
   193  	MOVQ	libcall_args(R11), R10
   194  	MOVQ	R10, 96(SP)
   195  	MOVQ	libcall_n(R11), R10
   196  	MOVQ	R10, 104(SP)
   197  	MOVQ    libcall_r1(R11), R10
   198  	MOVQ    R10, 168(SP)
   199  	MOVQ    libcall_r2(R11), R10
   200  	MOVQ    R10, 176(SP)
   201  
   202  	// save m->scratch
   203  	LEAQ	(m_mOS+mOS_scratch)(BP), R11
   204  	MOVQ	0(R11), R10
   205  	MOVQ	R10, 112(SP)
   206  	MOVQ	8(R11), R10
   207  	MOVQ	R10, 120(SP)
   208  	MOVQ	16(R11), R10
   209  	MOVQ	R10, 128(SP)
   210  	MOVQ	24(R11), R10
   211  	MOVQ	R10, 136(SP)
   212  	MOVQ	32(R11), R10
   213  	MOVQ	R10, 144(SP)
   214  	MOVQ	40(R11), R10
   215  	MOVQ	R10, 152(SP)
   216  
   217  	// save errno, it might be EINTR; stuff we do here might reset it.
   218  	MOVQ	(m_mOS+mOS_perrno)(BP), R10
   219  	MOVL	0(R10), R10
   220  	MOVQ	R10, 160(SP)
   221  
   222  	MOVQ	g(BX), R10
   223  	// g = m->gsignal
   224  	MOVQ	m_gsignal(BP), BP
   225  	MOVQ	BP, g(BX)
   226  
   227  	// prepare call
   228  	MOVQ	DI, 0(SP)
   229  	MOVQ	SI, 8(SP)
   230  	MOVQ	DX, 16(SP)
   231  	MOVQ	R10, 24(SP)
   232  	CALL	runtime·sighandler(SB)
   233  
   234  	get_tls(BX)
   235  	MOVQ	g(BX), BP
   236  	MOVQ	g_m(BP), BP
   237  	// restore libcall
   238  	LEAQ	m_libcall(BP), R11
   239  	MOVQ	88(SP), R10
   240  	MOVQ	R10, libcall_fn(R11)
   241  	MOVQ	96(SP), R10
   242  	MOVQ	R10, libcall_args(R11)
   243  	MOVQ	104(SP), R10
   244  	MOVQ	R10, libcall_n(R11)
   245  	MOVQ    168(SP), R10
   246  	MOVQ    R10, libcall_r1(R11)
   247  	MOVQ    176(SP), R10
   248  	MOVQ    R10, libcall_r2(R11)
   249  
   250  	// restore scratch
   251  	LEAQ	(m_mOS+mOS_scratch)(BP), R11
   252  	MOVQ	112(SP), R10
   253  	MOVQ	R10, 0(R11)
   254  	MOVQ	120(SP), R10
   255  	MOVQ	R10, 8(R11)
   256  	MOVQ	128(SP), R10
   257  	MOVQ	R10, 16(R11)
   258  	MOVQ	136(SP), R10
   259  	MOVQ	R10, 24(R11)
   260  	MOVQ	144(SP), R10
   261  	MOVQ	R10, 32(R11)
   262  	MOVQ	152(SP), R10
   263  	MOVQ	R10, 40(R11)
   264  
   265  	// restore errno
   266  	MOVQ	(m_mOS+mOS_perrno)(BP), R11
   267  	MOVQ	160(SP), R10
   268  	MOVL	R10, 0(R11)
   269  
   270  	// restore g
   271  	MOVQ	80(SP), R10
   272  	MOVQ	R10, g(BX)
   273  
   274  exit:
   275  	// restore registers
   276  	MOVQ	32(SP), BX
   277  	MOVQ	40(SP), BP
   278  	MOVQ	48(SP), R12
   279  	MOVQ	56(SP), R13
   280  	MOVQ	64(SP), R14
   281  	MOVQ	72(SP), R15
   282  
   283  	ADDQ    $184, SP
   284  	RET
   285  
   286  // Called from runtime·usleep (Go). Can be called on Go stack, on OS stack,
   287  // can also be called in cgo callback path without a g->m.
   288  TEXT runtime·usleep1(SB),NOSPLIT,$0
   289  	MOVL	usec+0(FP), DI
   290  	MOVQ	$runtime·usleep2(SB), AX // to hide from 6l
   291  
   292  	// Execute call on m->g0.
   293  	get_tls(R15)
   294  	CMPQ	R15, $0
   295  	JE	noswitch
   296  
   297  	MOVQ	g(R15), R13
   298  	CMPQ	R13, $0
   299  	JE	noswitch
   300  	MOVQ	g_m(R13), R13
   301  	CMPQ	R13, $0
   302  	JE	noswitch
   303  	// TODO(aram): do something about the cpu profiler here.
   304  
   305  	MOVQ	m_g0(R13), R14
   306  	CMPQ	g(R15), R14
   307  	JNE	switch
   308  	// executing on m->g0 already
   309  	CALL	AX
   310  	RET
   311  
   312  switch:
   313  	// Switch to m->g0 stack and back.
   314  	MOVQ	(g_sched+gobuf_sp)(R14), R14
   315  	MOVQ	SP, -8(R14)
   316  	LEAQ	-8(R14), SP
   317  	CALL	AX
   318  	MOVQ	0(SP), SP
   319  	RET
   320  
   321  noswitch:
   322  	// Not a Go-managed thread. Do not switch stack.
   323  	CALL	AX
   324  	RET
   325  
   326  // Runs on OS stack. duration (in µs units) is in DI.
   327  TEXT runtime·usleep2(SB),NOSPLIT,$0
   328  	LEAQ	libc_usleep(SB), AX
   329  	CALL	AX
   330  	RET
   331  
   332  // Runs on OS stack, called from runtime·osyield.
   333  TEXT runtime·osyield1(SB),NOSPLIT,$0
   334  	LEAQ	libc_sched_yield(SB), AX
   335  	CALL	AX
   336  	RET
   337  
   338  // func now() (sec int64, nsec int32)
   339  TEXT time·now(SB),NOSPLIT,$8-12
   340  	CALL	runtime·nanotime(SB)
   341  	MOVQ	0(SP), AX
   342  
   343  	// generated code for
   344  	//	func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
   345  	// adapted to reduce duplication
   346  	MOVQ	AX, CX
   347  	MOVQ	$1360296554856532783, AX
   348  	MULQ	CX
   349  	ADDQ	CX, DX
   350  	RCRQ	$1, DX
   351  	SHRQ	$29, DX
   352  	MOVQ	DX, sec+0(FP)
   353  	IMULQ	$1000000000, DX
   354  	SUBQ	DX, CX
   355  	MOVL	CX, nsec+8(FP)
   356  	RET