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,$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    $184, SP
   130  
   131  	// save registers
   132  	MOVQ    BX, 32(SP)
   133  	MOVQ    BP, 40(SP)
   134  	MOVQ	R12, 48(SP)
   135  	MOVQ	R13, 56(SP)
   136  	MOVQ	R14, 64(SP)
   137  	MOVQ	R15, 72(SP)
   138  
   139  	get_tls(BX)
   140  	// check that g exists
   141  	MOVQ	g(BX), R10
   142  	CMPQ	R10, $0
   143  	JNE	allgood
   144  	MOVQ	SI, 80(SP)
   145  	MOVQ	DX, 88(SP)
   146  	LEAQ	80(SP), AX
   147  	MOVQ	DI, 0(SP)
   148  	MOVQ	AX, 8(SP)
   149  	MOVQ	$runtime·badsignal(SB), AX
   150  	CALL	AX
   151  	JMP	exit
   152  
   153  allgood:
   154  	// Save m->libcall and m->scratch. We need to do this because we
   155  	// might get interrupted by a signal in runtime·asmcgocall.
   156  
   157  	// save m->libcall
   158  	MOVQ	g_m(R10), BP
   159  	LEAQ	m_libcall(BP), R11
   160  	MOVQ	libcall_fn(R11), R10
   161  	MOVQ	R10, 88(SP)
   162  	MOVQ	libcall_args(R11), R10
   163  	MOVQ	R10, 96(SP)
   164  	MOVQ	libcall_n(R11), R10
   165  	MOVQ	R10, 104(SP)
   166  	MOVQ    libcall_r1(R11), R10
   167  	MOVQ    R10, 168(SP)
   168  	MOVQ    libcall_r2(R11), R10
   169  	MOVQ    R10, 176(SP)
   170  
   171  	// save m->scratch
   172  	LEAQ	(m_mOS+mOS_scratch)(BP), R11
   173  	MOVQ	0(R11), R10
   174  	MOVQ	R10, 112(SP)
   175  	MOVQ	8(R11), R10
   176  	MOVQ	R10, 120(SP)
   177  	MOVQ	16(R11), R10
   178  	MOVQ	R10, 128(SP)
   179  	MOVQ	24(R11), R10
   180  	MOVQ	R10, 136(SP)
   181  	MOVQ	32(R11), R10
   182  	MOVQ	R10, 144(SP)
   183  	MOVQ	40(R11), R10
   184  	MOVQ	R10, 152(SP)
   185  
   186  	// save errno, it might be EINTR; stuff we do here might reset it.
   187  	MOVQ	(m_mOS+mOS_perrno)(BP), R10
   188  	MOVL	0(R10), R10
   189  	MOVQ	R10, 160(SP)
   190  
   191  	// prepare call
   192  	MOVQ	DI, 0(SP)
   193  	MOVQ	SI, 8(SP)
   194  	MOVQ	DX, 16(SP)
   195  	CALL	runtime·sigtrampgo(SB)
   196  
   197  	get_tls(BX)
   198  	MOVQ	g(BX), BP
   199  	MOVQ	g_m(BP), BP
   200  	// restore libcall
   201  	LEAQ	m_libcall(BP), R11
   202  	MOVQ	88(SP), R10
   203  	MOVQ	R10, libcall_fn(R11)
   204  	MOVQ	96(SP), R10
   205  	MOVQ	R10, libcall_args(R11)
   206  	MOVQ	104(SP), R10
   207  	MOVQ	R10, libcall_n(R11)
   208  	MOVQ    168(SP), R10
   209  	MOVQ    R10, libcall_r1(R11)
   210  	MOVQ    176(SP), R10
   211  	MOVQ    R10, libcall_r2(R11)
   212  
   213  	// restore scratch
   214  	LEAQ	(m_mOS+mOS_scratch)(BP), R11
   215  	MOVQ	112(SP), R10
   216  	MOVQ	R10, 0(R11)
   217  	MOVQ	120(SP), R10
   218  	MOVQ	R10, 8(R11)
   219  	MOVQ	128(SP), R10
   220  	MOVQ	R10, 16(R11)
   221  	MOVQ	136(SP), R10
   222  	MOVQ	R10, 24(R11)
   223  	MOVQ	144(SP), R10
   224  	MOVQ	R10, 32(R11)
   225  	MOVQ	152(SP), R10
   226  	MOVQ	R10, 40(R11)
   227  
   228  	// restore errno
   229  	MOVQ	(m_mOS+mOS_perrno)(BP), R11
   230  	MOVQ	160(SP), R10
   231  	MOVL	R10, 0(R11)
   232  
   233  exit:
   234  	// restore registers
   235  	MOVQ	32(SP), BX
   236  	MOVQ	40(SP), BP
   237  	MOVQ	48(SP), R12
   238  	MOVQ	56(SP), R13
   239  	MOVQ	64(SP), R14
   240  	MOVQ	72(SP), R15
   241  
   242  	ADDQ    $184, SP
   243  	RET
   244  
   245  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   246  	MOVQ	fn+0(FP),    AX
   247  	MOVL	sig+8(FP),   DI
   248  	MOVQ	info+16(FP), SI
   249  	MOVQ	ctx+24(FP),  DX
   250  	PUSHQ	BP
   251  	MOVQ	SP, BP
   252  	ANDQ	$~15, SP     // alignment for x86_64 ABI
   253  	CALL	AX
   254  	MOVQ	BP, SP
   255  	POPQ	BP
   256  	RET
   257  
   258  // Called from runtime·usleep (Go). Can be called on Go stack, on OS stack,
   259  // can also be called in cgo callback path without a g->m.
   260  TEXT runtime·usleep1(SB),NOSPLIT,$0
   261  	MOVL	usec+0(FP), DI
   262  	MOVQ	$usleep2<>(SB), AX // to hide from 6l
   263  
   264  	// Execute call on m->g0.
   265  	get_tls(R15)
   266  	CMPQ	R15, $0
   267  	JE	noswitch
   268  
   269  	MOVQ	g(R15), R13
   270  	CMPQ	R13, $0
   271  	JE	noswitch
   272  	MOVQ	g_m(R13), R13
   273  	CMPQ	R13, $0
   274  	JE	noswitch
   275  	// TODO(aram): do something about the cpu profiler here.
   276  
   277  	MOVQ	m_g0(R13), R14
   278  	CMPQ	g(R15), R14
   279  	JNE	switch
   280  	// executing on m->g0 already
   281  	CALL	AX
   282  	RET
   283  
   284  switch:
   285  	// Switch to m->g0 stack and back.
   286  	MOVQ	(g_sched+gobuf_sp)(R14), R14
   287  	MOVQ	SP, -8(R14)
   288  	LEAQ	-8(R14), SP
   289  	CALL	AX
   290  	MOVQ	0(SP), SP
   291  	RET
   292  
   293  noswitch:
   294  	// Not a Go-managed thread. Do not switch stack.
   295  	CALL	AX
   296  	RET
   297  
   298  // Runs on OS stack. duration (in µs units) is in DI.
   299  TEXT usleep2<>(SB),NOSPLIT,$0
   300  	LEAQ	libc_usleep(SB), AX
   301  	CALL	AX
   302  	RET
   303  
   304  // Runs on OS stack, called from runtime·osyield.
   305  TEXT runtime·osyield1(SB),NOSPLIT,$0
   306  	LEAQ	libc_sched_yield(SB), AX
   307  	CALL	AX
   308  	RET
   309  

View as plain text