github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/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 aligned
    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	SI, 80(SP)
   177  	MOVQ	DX, 88(SP)
   178  	LEAQ	80(SP), AX
   179  	MOVQ	DI, 0(SP)
   180  	MOVQ	AX, 8(SP)
   181  	MOVQ	$runtime·badsignal(SB), AX
   182  	CALL	AX
   183  	JMP	exit
   184  
   185  allgood:
   186  	// Save m->libcall and m->scratch. We need to do this because we
   187  	// might get interrupted by a signal in runtime·asmcgocall.
   188  
   189  	// save m->libcall 
   190  	MOVQ	g_m(R10), BP
   191  	LEAQ	m_libcall(BP), R11
   192  	MOVQ	libcall_fn(R11), R10
   193  	MOVQ	R10, 88(SP)
   194  	MOVQ	libcall_args(R11), R10
   195  	MOVQ	R10, 96(SP)
   196  	MOVQ	libcall_n(R11), R10
   197  	MOVQ	R10, 104(SP)
   198  	MOVQ    libcall_r1(R11), R10
   199  	MOVQ    R10, 168(SP)
   200  	MOVQ    libcall_r2(R11), R10
   201  	MOVQ    R10, 176(SP)
   202  
   203  	// save m->scratch
   204  	LEAQ	(m_mOS+mOS_scratch)(BP), R11
   205  	MOVQ	0(R11), R10
   206  	MOVQ	R10, 112(SP)
   207  	MOVQ	8(R11), R10
   208  	MOVQ	R10, 120(SP)
   209  	MOVQ	16(R11), R10
   210  	MOVQ	R10, 128(SP)
   211  	MOVQ	24(R11), R10
   212  	MOVQ	R10, 136(SP)
   213  	MOVQ	32(R11), R10
   214  	MOVQ	R10, 144(SP)
   215  	MOVQ	40(R11), R10
   216  	MOVQ	R10, 152(SP)
   217  
   218  	// save errno, it might be EINTR; stuff we do here might reset it.
   219  	MOVQ	(m_mOS+mOS_perrno)(BP), R10
   220  	MOVL	0(R10), R10
   221  	MOVQ	R10, 160(SP)
   222  
   223  	// prepare call
   224  	MOVQ	DI, 0(SP)
   225  	MOVQ	SI, 8(SP)
   226  	MOVQ	DX, 16(SP)
   227  	CALL	runtime·sigtrampgo(SB)
   228  
   229  	get_tls(BX)
   230  	MOVQ	g(BX), BP
   231  	MOVQ	g_m(BP), BP
   232  	// restore libcall
   233  	LEAQ	m_libcall(BP), R11
   234  	MOVQ	88(SP), R10
   235  	MOVQ	R10, libcall_fn(R11)
   236  	MOVQ	96(SP), R10
   237  	MOVQ	R10, libcall_args(R11)
   238  	MOVQ	104(SP), R10
   239  	MOVQ	R10, libcall_n(R11)
   240  	MOVQ    168(SP), R10
   241  	MOVQ    R10, libcall_r1(R11)
   242  	MOVQ    176(SP), R10
   243  	MOVQ    R10, libcall_r2(R11)
   244  
   245  	// restore scratch
   246  	LEAQ	(m_mOS+mOS_scratch)(BP), R11
   247  	MOVQ	112(SP), R10
   248  	MOVQ	R10, 0(R11)
   249  	MOVQ	120(SP), R10
   250  	MOVQ	R10, 8(R11)
   251  	MOVQ	128(SP), R10
   252  	MOVQ	R10, 16(R11)
   253  	MOVQ	136(SP), R10
   254  	MOVQ	R10, 24(R11)
   255  	MOVQ	144(SP), R10
   256  	MOVQ	R10, 32(R11)
   257  	MOVQ	152(SP), R10
   258  	MOVQ	R10, 40(R11)
   259  
   260  	// restore errno
   261  	MOVQ	(m_mOS+mOS_perrno)(BP), R11
   262  	MOVQ	160(SP), R10
   263  	MOVL	R10, 0(R11)
   264  
   265  exit:
   266  	// restore registers
   267  	MOVQ	32(SP), BX
   268  	MOVQ	40(SP), BP
   269  	MOVQ	48(SP), R12
   270  	MOVQ	56(SP), R13
   271  	MOVQ	64(SP), R14
   272  	MOVQ	72(SP), R15
   273  
   274  	ADDQ    $184, SP
   275  	RET
   276  
   277  TEXT runtime·sigfwd(SB),NOSPLIT,$0-32
   278  	MOVQ	fn+0(FP),    AX
   279  	MOVL	sig+8(FP),   DI
   280  	MOVQ	info+16(FP), SI
   281  	MOVQ	ctx+24(FP),  DX
   282  	PUSHQ	BP
   283  	MOVQ	SP, BP
   284  	ANDQ	$~15, SP     // alignment for x86_64 ABI
   285  	CALL	AX
   286  	MOVQ	BP, SP
   287  	POPQ	BP
   288  	RET
   289  
   290  // Called from runtime·usleep (Go). Can be called on Go stack, on OS stack,
   291  // can also be called in cgo callback path without a g->m.
   292  TEXT runtime·usleep1(SB),NOSPLIT,$0
   293  	MOVL	usec+0(FP), DI
   294  	MOVQ	$runtime·usleep2(SB), AX // to hide from 6l
   295  
   296  	// Execute call on m->g0.
   297  	get_tls(R15)
   298  	CMPQ	R15, $0
   299  	JE	noswitch
   300  
   301  	MOVQ	g(R15), R13
   302  	CMPQ	R13, $0
   303  	JE	noswitch
   304  	MOVQ	g_m(R13), R13
   305  	CMPQ	R13, $0
   306  	JE	noswitch
   307  	// TODO(aram): do something about the cpu profiler here.
   308  
   309  	MOVQ	m_g0(R13), R14
   310  	CMPQ	g(R15), R14
   311  	JNE	switch
   312  	// executing on m->g0 already
   313  	CALL	AX
   314  	RET
   315  
   316  switch:
   317  	// Switch to m->g0 stack and back.
   318  	MOVQ	(g_sched+gobuf_sp)(R14), R14
   319  	MOVQ	SP, -8(R14)
   320  	LEAQ	-8(R14), SP
   321  	CALL	AX
   322  	MOVQ	0(SP), SP
   323  	RET
   324  
   325  noswitch:
   326  	// Not a Go-managed thread. Do not switch stack.
   327  	CALL	AX
   328  	RET
   329  
   330  // Runs on OS stack. duration (in µs units) is in DI.
   331  TEXT runtime·usleep2(SB),NOSPLIT,$0
   332  	LEAQ	libc_usleep(SB), AX
   333  	CALL	AX
   334  	RET
   335  
   336  // Runs on OS stack, called from runtime·osyield.
   337  TEXT runtime·osyield1(SB),NOSPLIT,$0
   338  	LEAQ	libc_sched_yield(SB), AX
   339  	CALL	AX
   340  	RET
   341  
   342  // func walltime() (sec int64, nsec int32)
   343  TEXT runtime·walltime(SB),NOSPLIT,$8-12
   344  	CALL	runtime·nanotime(SB)
   345  	MOVQ	0(SP), AX
   346  
   347  	// generated code for
   348  	//	func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
   349  	// adapted to reduce duplication
   350  	MOVQ	AX, CX
   351  	MOVQ	$1360296554856532783, AX
   352  	MULQ	CX
   353  	ADDQ	CX, DX
   354  	RCRQ	$1, DX
   355  	SHRQ	$29, DX
   356  	MOVQ	DX, sec+0(FP)
   357  	IMULQ	$1000000000, DX
   358  	SUBQ	DX, CX
   359  	MOVL	CX, nsec+8(FP)
   360  	RET