...

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	// 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	$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 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

View as plain text