...
Run Format

Text file src/runtime/sys_solaris_amd64.s

Documentation: runtime

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

View as plain text