...

Text file src/runtime/sys_windows_386.s

Documentation: runtime

     1// Copyright 2009 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#include "go_asm.h"
     6#include "go_tls.h"
     7#include "textflag.h"
     8#include "time_windows.h"
     9
    10// Offsets into Thread Environment Block (pointer in FS)
    11#define TEB_TlsSlots 0xE10
    12#define TEB_ArbitraryPtr 0x14
    13
    14TEXT runtime·asmstdcall_trampoline<ABIInternal>(SB),NOSPLIT,$0
    15	JMP	runtime·asmstdcall(SB)
    16
    17// void runtime·asmstdcall(void *c);
    18TEXT runtime·asmstdcall(SB),NOSPLIT,$0
    19	MOVL	fn+0(FP), BX
    20	MOVL	SP, BP	// save stack pointer
    21
    22	// SetLastError(0).
    23	MOVL	$0, 0x34(FS)
    24
    25	MOVL	libcall_n(BX), CX
    26
    27	// Fast version, do not store args on the stack.
    28	CMPL	CX, $0
    29	JE	docall
    30
    31	// Copy args to the stack.
    32	MOVL	CX, AX
    33	SALL	$2, AX
    34	SUBL	AX, SP			// room for args
    35	MOVL	SP, DI
    36	MOVL	libcall_args(BX), SI
    37	CLD
    38	REP; MOVSL
    39
    40docall:
    41	// Call stdcall or cdecl function.
    42	// DI SI BP BX are preserved, SP is not
    43	CALL	libcall_fn(BX)
    44	MOVL	BP, SP
    45
    46	// Return result.
    47	MOVL	fn+0(FP), BX
    48	MOVL	AX, libcall_r1(BX)
    49	MOVL	DX, libcall_r2(BX)
    50
    51	// GetLastError().
    52	MOVL	0x34(FS), AX
    53	MOVL	AX, libcall_err(BX)
    54
    55	RET
    56
    57// faster get/set last error
    58TEXT runtime·getlasterror(SB),NOSPLIT,$0
    59	MOVL	0x34(FS), AX
    60	MOVL	AX, ret+0(FP)
    61	RET
    62
    63TEXT runtime·sigFetchGSafe<ABIInternal>(SB),NOSPLIT,$0
    64	get_tls(AX)
    65	CMPL	AX, $0
    66	JE	2(PC)
    67	MOVL	g(AX), AX
    68	MOVL	AX, ret+0(FP)
    69	RET
    70
    71// Called by Windows as a Vectored Exception Handler (VEH).
    72// AX is pointer to struct containing
    73// exception record and context pointers.
    74// CX is the kind of sigtramp function.
    75// Return value of sigtrampgo is stored in AX.
    76TEXT sigtramp<>(SB),NOSPLIT,$0-0
    77	SUBL	$40, SP
    78
    79	// save callee-saved registers
    80	MOVL	BX, 28(SP)
    81	MOVL	BP, 16(SP)
    82	MOVL	SI, 20(SP)
    83	MOVL	DI, 24(SP)
    84
    85	MOVL	AX, 0(SP)
    86	MOVL	CX, 4(SP)
    87	CALL	runtime·sigtrampgo(SB)
    88	MOVL	8(SP), AX
    89
    90	// restore callee-saved registers
    91	MOVL	24(SP), DI
    92	MOVL	20(SP), SI
    93	MOVL	16(SP), BP
    94	MOVL	28(SP), BX
    95
    96	ADDL	$40, SP
    97	// RET 4 (return and pop 4 bytes parameters)
    98	BYTE $0xC2; WORD $4
    99	RET // unreached; make assembler happy
   100
   101// Trampoline to resume execution from exception handler.
   102// This is part of the control flow guard workaround.
   103// It switches stacks and jumps to the continuation address.
   104// DX and CX are set above at the end of sigtrampgo
   105// in the context that starts executing at sigresume.
   106TEXT runtime·sigresume(SB),NOSPLIT,$0
   107	MOVL	DX, SP
   108	JMP	CX
   109
   110TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
   111	MOVL	argframe+0(FP), AX
   112	MOVL	$const_callbackVEH, CX
   113	JMP	sigtramp<>(SB)
   114
   115TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
   116	// is never called
   117	INT	$3
   118
   119TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
   120	MOVL	argframe+0(FP), AX
   121	MOVL	$const_callbackLastVCH, CX
   122	JMP	sigtramp<>(SB)
   123
   124TEXT runtime·callbackasm1(SB),NOSPLIT,$0
   125	MOVL	0(SP), AX	// will use to find our callback context
   126
   127	// remove return address from stack, we are not returning to callbackasm, but to its caller.
   128	ADDL	$4, SP
   129
   130	// address to callback parameters into CX
   131	LEAL	4(SP), CX
   132
   133	// save registers as required for windows callback
   134	PUSHL	DI
   135	PUSHL	SI
   136	PUSHL	BP
   137	PUSHL	BX
   138
   139	// Go ABI requires DF flag to be cleared.
   140	CLD
   141
   142	// determine index into runtime·cbs table
   143	SUBL	$runtime·callbackasm(SB), AX
   144	MOVL	$0, DX
   145	MOVL	$5, BX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
   146	DIVL	BX
   147	SUBL	$1, AX	// subtract 1 because return PC is to the next slot
   148
   149	// Create a struct callbackArgs on our stack.
   150	SUBL	$(12+callbackArgs__size), SP
   151	MOVL	AX, (12+callbackArgs_index)(SP)		// callback index
   152	MOVL	CX, (12+callbackArgs_args)(SP)		// address of args vector
   153	MOVL	$0, (12+callbackArgs_result)(SP)	// result
   154	LEAL	12(SP), AX	// AX = &callbackArgs{...}
   155
   156	// Call cgocallback, which will call callbackWrap(frame).
   157	MOVL	$0, 8(SP)	// context
   158	MOVL	AX, 4(SP)	// frame (address of callbackArgs)
   159	LEAL	·callbackWrap(SB), AX
   160	MOVL	AX, 0(SP)	// PC of function to call
   161	CALL	runtime·cgocallback(SB)
   162
   163	// Get callback result.
   164	MOVL	(12+callbackArgs_result)(SP), AX
   165	// Get popRet.
   166	MOVL	(12+callbackArgs_retPop)(SP), CX	// Can't use a callee-save register
   167	ADDL	$(12+callbackArgs__size), SP
   168
   169	// restore registers as required for windows callback
   170	POPL	BX
   171	POPL	BP
   172	POPL	SI
   173	POPL	DI
   174
   175	// remove callback parameters before return (as per Windows spec)
   176	POPL	DX
   177	ADDL	CX, SP
   178	PUSHL	DX
   179
   180	CLD
   181
   182	RET
   183
   184// void tstart(M *newm);
   185TEXT tstart<>(SB),NOSPLIT,$8-4
   186	MOVL	newm+0(FP), CX		// m
   187	MOVL	m_g0(CX), DX		// g
   188
   189	// Layout new m scheduler stack on os stack.
   190	MOVL	SP, AX
   191	MOVL	AX, (g_stack+stack_hi)(DX)
   192	SUBL	$(64*1024), AX		// initial stack size (adjusted later)
   193	MOVL	AX, (g_stack+stack_lo)(DX)
   194	ADDL	$const_stackGuard, AX
   195	MOVL	AX, g_stackguard0(DX)
   196	MOVL	AX, g_stackguard1(DX)
   197
   198	// Set up tls.
   199	LEAL	m_tls(CX), DI
   200	MOVL	CX, g_m(DX)
   201	MOVL	DX, g(DI)
   202	MOVL	DI, 4(SP)
   203	CALL	runtime·setldt(SB) // clobbers CX and DX
   204
   205	// Someday the convention will be D is always cleared.
   206	CLD
   207
   208	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
   209	CALL	runtime·mstart(SB)
   210
   211	RET
   212
   213// uint32 tstart_stdcall(M *newm);
   214TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
   215	MOVL	newm+0(FP), BX
   216
   217	PUSHL	BX
   218	CALL	tstart<>(SB)
   219	POPL	BX
   220
   221	// Adjust stack for stdcall to return properly.
   222	MOVL	(SP), AX		// save return address
   223	ADDL	$4, SP			// remove single parameter
   224	MOVL	AX, (SP)		// restore return address
   225
   226	XORL	AX, AX			// return 0 == success
   227
   228	RET
   229
   230// setldt(int slot, int base, int size)
   231TEXT runtime·setldt(SB),NOSPLIT,$0-12
   232	MOVL	base+4(FP), DX
   233	MOVL	runtime·tls_g(SB), CX
   234	MOVL	DX, 0(CX)(FS)
   235	RET
   236
   237TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
   238loop:
   239	MOVL	(_INTERRUPT_TIME+time_hi1), AX
   240	MOVL	(_INTERRUPT_TIME+time_lo), CX
   241	MOVL	(_INTERRUPT_TIME+time_hi2), DI
   242	CMPL	AX, DI
   243	JNE	loop
   244
   245	// wintime = DI:CX, multiply by 100
   246	MOVL	$100, AX
   247	MULL	CX
   248	IMULL	$100, DI
   249	ADDL	DI, DX
   250	// wintime*100 = DX:AX
   251	MOVL	AX, ret_lo+0(FP)
   252	MOVL	DX, ret_hi+4(FP)
   253	RET
   254
   255// This is called from rt0_go, which runs on the system stack
   256// using the initial stack allocated by the OS.
   257TEXT runtime·wintls(SB),NOSPLIT,$0
   258	// Allocate a TLS slot to hold g across calls to external code
   259	MOVL	SP, BP
   260	MOVL	runtime·_TlsAlloc(SB), AX
   261	CALL	AX
   262	MOVL	BP, SP
   263
   264	MOVL	AX, CX	// TLS index
   265
   266	// Assert that slot is less than 64 so we can use _TEB->TlsSlots
   267	CMPL	CX, $64
   268	JB	ok
   269	// Fallback to the TEB arbitrary pointer.
   270	// TODO: don't use the arbitrary pointer (see go.dev/issue/59824)
   271	MOVL	$TEB_ArbitraryPtr, CX
   272	JMP	settls
   273ok:
   274	// Convert the TLS index at CX into
   275	// an offset from TEB_TlsSlots.
   276	SHLL	$2, CX
   277
   278	// Save offset from TLS into tls_g.
   279	ADDL	$TEB_TlsSlots, CX
   280settls:
   281	MOVL	CX, runtime·tls_g(SB)
   282	RET

View as plain text