Text file src/runtime/sys_solaris_amd64.s

     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  // Call a library function with SysV calling conventions.
    33  // The called function can take a maximum of 6 INTEGER class arguments,
    34  // see
    35  //   Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
    36  //   System V Application Binary Interface
    37  //   AMD64 Architecture Processor Supplement
    38  // section 3.2.3.
    39  //
    40  // Called by runtime·asmcgocall or runtime·cgocall.
    41  // NOT USING GO CALLING CONVENTION.
    42  TEXT runtime·asmsysvicall6(SB),NOSPLIT,$0
    43  	// asmcgocall will put first argument into DI.
    44  	PUSHQ	DI			// save for later
    45  	MOVQ	libcall_fn(DI), AX
    46  	MOVQ	libcall_args(DI), R11
    47  	MOVQ	libcall_n(DI), R10
    48  
    49  	get_tls(CX)
    50  	MOVQ	g(CX), BX
    51  	CMPQ	BX, $0
    52  	JEQ	skiperrno1
    53  	MOVQ	g_m(BX), BX
    54  	MOVQ	(m_mOS+mOS_perrno)(BX), DX
    55  	CMPQ	DX, $0
    56  	JEQ	skiperrno1
    57  	MOVL	$0, 0(DX)
    58  
    59  skiperrno1:
    60  	CMPQ	R11, $0
    61  	JEQ	skipargs
    62  	// Load 6 args into correspondent registers.
    63  	MOVQ	0(R11), DI
    64  	MOVQ	8(R11), SI
    65  	MOVQ	16(R11), DX
    66  	MOVQ	24(R11), CX
    67  	MOVQ	32(R11), R8
    68  	MOVQ	40(R11), R9
    69  skipargs:
    70  
    71  	// Call SysV function
    72  	CALL	AX
    73  
    74  	// Return result
    75  	POPQ	DI
    76  	MOVQ	AX, libcall_r1(DI)
    77  	MOVQ	DX, libcall_r2(DI)
    78  
    79  	get_tls(CX)
    80  	MOVQ	g(CX), BX
    81  	CMPQ	BX, $0
    82  	JEQ	skiperrno2
    83  	MOVQ	g_m(BX), BX
    84  	MOVQ	(m_mOS+mOS_perrno)(BX), AX
    85  	CMPQ	AX, $0
    86  	JEQ	skiperrno2
    87  	MOVL	0(AX), AX
    88  	MOVQ	AX, libcall_err(DI)
    89  
    90  skiperrno2:
    91  	RET
    92  
    93  // uint32 tstart_sysvicall(M *newm);
    94  TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0
    95  	// DI contains first arg newm
    96  	MOVQ	m_g0(DI), DX		// g
    97  
    98  	// Make TLS entries point at g and m.
    99  	get_tls(BX)
   100  	MOVQ	DX, g(BX)
   101  	MOVQ	DI, g_m(DX)
   102  
   103  	// Layout new m scheduler stack on os stack.
   104  	MOVQ	SP, AX
   105  	MOVQ	AX, (g_stack+stack_hi)(DX)
   106  	SUBQ	$(0x100000), AX		// stack size
   107  	MOVQ	AX, (g_stack+stack_lo)(DX)
   108  	ADDQ	$const_stackGuard, AX
   109  	MOVQ	AX, g_stackguard0(DX)
   110  	MOVQ	AX, g_stackguard1(DX)
   111  
   112  	// Someday the convention will be D is always cleared.
   113  	CLD
   114  
   115  	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
   116  	CALL	runtime·mstart(SB)
   117  
   118  	XORL	AX, AX			// return 0 == success
   119  	MOVL	AX, ret+8(FP)
   120  	RET
   121  
   122  // Careful, this is called by __sighndlr, a libc function. We must preserve
   123  // registers as per AMD 64 ABI.
   124  TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME|NOFRAME,$0
   125  	// Note that we are executing on altsigstack here, so we have
   126  	// more stack available than NOSPLIT would have us believe.
   127  	// To defeat the linker, we make our own stack frame with
   128  	// more space:
   129  	SUBQ    $168, SP
   130  	// save registers
   131  	MOVQ    BX, 24(SP)
   132  	MOVQ    BP, 32(SP)
   133  	MOVQ	R12, 40(SP)
   134  	MOVQ	R13, 48(SP)
   135  	MOVQ	R14, 56(SP)
   136  	MOVQ	R15, 64(SP)
   137  
   138  	get_tls(BX)
   139  	// check that g exists
   140  	MOVQ	g(BX), R10
   141  	CMPQ	R10, $0
   142  	JNE	allgood
   143  	MOVQ	SI, 72(SP)
   144  	MOVQ	DX, 80(SP)
   145  	LEAQ	72(SP), AX
   146  	MOVQ	DI, 0(SP)
   147  	MOVQ	AX, 8(SP)
   148  	MOVQ	$runtime·badsignal(SB), AX
   149  	CALL	AX
   150  	JMP	exit
   151  
   152  allgood:
   153  	// Save m->libcall and m->scratch. We need to do this because we
   154  	// might get interrupted by a signal in runtime·asmcgocall.
   155  
   156  	// save m->libcall
   157  	MOVQ	g_m(R10), BP
   158  	LEAQ	m_libcall(BP), R11
   159  	MOVQ	libcall_fn(R11), R10
   160  	MOVQ	R10, 72(SP)
   161  	MOVQ	libcall_args(R11), R10
   162  	MOVQ	R10, 80(SP)
   163  	MOVQ	libcall_n(R11), R10
   164  	MOVQ	R10, 88(SP)
   165  	MOVQ    libcall_r1(R11), R10
   166  	MOVQ    R10, 152(SP)
   167  	MOVQ    libcall_r2(R11), R10
   168  	MOVQ    R10, 160(SP)
   169  
   170  	// save m->scratch
   171  	LEAQ	(m_mOS+mOS_scratch)(BP), R11
   172  	MOVQ	0(R11), R10
   173  	MOVQ	R10, 96(SP)
   174  	MOVQ	8(R11), R10
   175  	MOVQ	R10, 104(SP)
   176  	MOVQ	16(R11), R10
   177  	MOVQ	R10, 112(SP)
   178  	MOVQ	24(R11), R10
   179  	MOVQ	R10, 120(SP)
   180  	MOVQ	32(R11), R10
   181  	MOVQ	R10, 128(SP)
   182  	MOVQ	40(R11), R10
   183  	MOVQ	R10, 136(SP)
   184  
   185  	// save errno, it might be EINTR; stuff we do here might reset it.
   186  	MOVQ	(m_mOS+mOS_perrno)(BP), R10
   187  	MOVL	0(R10), R10
   188  	MOVQ	R10, 144(SP)
   189  
   190  	// prepare call
   191  	MOVQ	DI, 0(SP)
   192  	MOVQ	SI, 8(SP)
   193  	MOVQ	DX, 16(SP)
   194  	CALL	runtime·sigtrampgo(SB)
   195  
   196  	get_tls(BX)
   197  	MOVQ	g(BX), BP
   198  	MOVQ	g_m(BP), BP
   199  	// restore libcall
   200  	LEAQ	m_libcall(BP), R11
   201  	MOVQ	72(SP), R10
   202  	MOVQ	R10, libcall_fn(R11)
   203  	MOVQ	80(SP), R10
   204  	MOVQ	R10, libcall_args(R11)
   205  	MOVQ	88(SP), R10
   206  	MOVQ	R10, libcall_n(R11)
   207  	MOVQ    152(SP), R10
   208  	MOVQ    R10, libcall_r1(R11)
   209  	MOVQ    160(SP), R10
   210  	MOVQ    R10, libcall_r2(R11)
   211  
   212  	// restore scratch
   213  	LEAQ	(m_mOS+mOS_scratch)(BP), R11
   214  	MOVQ	96(SP), R10
   215  	MOVQ	R10, 0(R11)
   216  	MOVQ	104(SP), R10
   217  	MOVQ	R10, 8(R11)
   218  	MOVQ	112(SP), R10
   219  	MOVQ	R10, 16(R11)
   220  	MOVQ	120(SP), R10
   221  	MOVQ	R10, 24(R11)
   222  	MOVQ	128(SP), R10
   223  	MOVQ	R10, 32(R11)
   224  	MOVQ	136(SP), R10
   225  	MOVQ	R10, 40(R11)
   226  
   227  	// restore errno
   228  	MOVQ	(m_mOS+mOS_perrno)(BP), R11
   229  	MOVQ	144(SP), R10
   230  	MOVL	R10, 0(R11)
   231  
   232  exit:
   233  	// restore registers
   234  	MOVQ	24(SP), BX
   235  	MOVQ	32(SP), BP
   236  	MOVQ	40(SP), R12
   237  	MOVQ	48(SP), R13
   238  	MOVQ	56(SP), R14
   239  	MOVQ	64(SP), R15
   240  	ADDQ    $168, SP
   241  	RET
   242  
   243  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   244  	MOVQ	fn+0(FP),    AX
   245  	MOVL	sig+8(FP),   DI
   246  	MOVQ	info+16(FP), SI
   247  	MOVQ	ctx+24(FP),  DX
   248  	MOVQ	SP, BX		// callee-saved
   249  	ANDQ	$~15, SP	// alignment for x86_64 ABI
   250  	CALL	AX
   251  	MOVQ	BX, SP
   252  	RET
   253  
   254  // Called from runtime·usleep (Go). Can be called on Go stack, on OS stack,
   255  // can also be called in cgo callback path without a g->m.
   256  TEXT runtime·usleep1(SB),NOSPLIT,$0
   257  	MOVL	usec+0(FP), DI
   258  	MOVQ	$usleep2<>(SB), AX // to hide from 6l
   259  
   260  	// Execute call on m->g0.
   261  	get_tls(R15)
   262  	CMPQ	R15, $0
   263  	JE	noswitch
   264  
   265  	MOVQ	g(R15), R13
   266  	CMPQ	R13, $0
   267  	JE	noswitch
   268  	MOVQ	g_m(R13), R13
   269  	CMPQ	R13, $0
   270  	JE	noswitch
   271  	// TODO(aram): do something about the cpu profiler here.
   272  
   273  	MOVQ	m_g0(R13), R14
   274  	CMPQ	g(R15), R14
   275  	JNE	switch
   276  	// executing on m->g0 already
   277  	CALL	AX
   278  	RET
   279  
   280  switch:
   281  	// Switch to m->g0 stack and back.
   282  	MOVQ	(g_sched+gobuf_sp)(R14), R14
   283  	MOVQ	SP, -8(R14)
   284  	LEAQ	-8(R14), SP
   285  	CALL	AX
   286  	MOVQ	0(SP), SP
   287  	RET
   288  
   289  noswitch:
   290  	// Not a Go-managed thread. Do not switch stack.
   291  	CALL	AX
   292  	RET
   293  
   294  // Runs on OS stack. duration (in µs units) is in DI.
   295  TEXT usleep2<>(SB),NOSPLIT,$0
   296  	LEAQ	libc_usleep(SB), AX
   297  	CALL	AX
   298  	RET
   299  
   300  // Runs on OS stack, called from runtime·osyield.
   301  TEXT runtime·osyield1(SB),NOSPLIT,$0
   302  	LEAQ	libc_sched_yield(SB), AX
   303  	CALL	AX
   304  	RET
   305  

View as plain text