...

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
    14TEXT 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.
    23TEXT 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.
    42TEXT 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
    59skiperrno1:
    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
    69skipargs:
    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
    90skiperrno2:
    91	RET
    92
    93// uint32 tstart_sysvicall(M *newm);
    94TEXT 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.
   124TEXT 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
   152allgood:
   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
   232exit:
   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
   243TEXT 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.
   256TEXT 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
   280switch:
   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
   289noswitch:
   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.
   295TEXT 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.
   301TEXT runtime·osyield1(SB),NOSPLIT,$0
   302	LEAQ	libc_sched_yield(SB), AX
   303	CALL	AX
   304	RET

View as plain text