Text file src/runtime/sys_windows_amd64.s

     1  // Copyright 2011 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  #include "cgo/abi_amd64.h"
    10  
    11  // maxargs should be divisible by 2, as Windows stack
    12  // must be kept 16-byte aligned on syscall entry.
    13  #define maxargs 18
    14  
    15  // void runtime·asmstdcall(void *c);
    16  TEXT runtime·asmstdcall<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
    17  	// asmcgocall will put first argument into CX.
    18  	PUSHQ	CX			// save for later
    19  	MOVQ	libcall_fn(CX), AX
    20  	MOVQ	libcall_args(CX), SI
    21  	MOVQ	libcall_n(CX), CX
    22  
    23  	// SetLastError(0).
    24  	MOVQ	0x30(GS), DI
    25  	MOVL	$0, 0x68(DI)
    26  
    27  	SUBQ	$(maxargs*8), SP	// room for args
    28  
    29  	// Fast version, do not store args on the stack.
    30  	CMPL	CX, $4
    31  	JLE	loadregs
    32  
    33  	// Check we have enough room for args.
    34  	CMPL	CX, $maxargs
    35  	JLE	2(PC)
    36  	INT	$3			// not enough room -> crash
    37  
    38  	// Copy args to the stack.
    39  	MOVQ	SP, DI
    40  	CLD
    41  	REP; MOVSQ
    42  	MOVQ	SP, SI
    43  
    44  loadregs:
    45  	// Load first 4 args into correspondent registers.
    46  	MOVQ	0(SI), CX
    47  	MOVQ	8(SI), DX
    48  	MOVQ	16(SI), R8
    49  	MOVQ	24(SI), R9
    50  	// Floating point arguments are passed in the XMM
    51  	// registers. Set them here in case any of the arguments
    52  	// are floating point values. For details see
    53  	//	https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
    54  	MOVQ	CX, X0
    55  	MOVQ	DX, X1
    56  	MOVQ	R8, X2
    57  	MOVQ	R9, X3
    58  
    59  	// Call stdcall function.
    60  	CALL	AX
    61  
    62  	ADDQ	$(maxargs*8), SP
    63  
    64  	// Return result.
    65  	POPQ	CX
    66  	MOVQ	AX, libcall_r1(CX)
    67  	// Floating point return values are returned in XMM0. Setting r2 to this
    68  	// value in case this call returned a floating point value. For details,
    69  	// see https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention
    70  	MOVQ    X0, libcall_r2(CX)
    71  
    72  	// GetLastError().
    73  	MOVQ	0x30(GS), DI
    74  	MOVL	0x68(DI), AX
    75  	MOVQ	AX, libcall_err(CX)
    76  
    77  	RET
    78  
    79  TEXT runtime·badsignal2(SB),NOSPLIT|NOFRAME,$48
    80  	// stderr
    81  	MOVQ	$-12, CX // stderr
    82  	MOVQ	CX, 0(SP)
    83  	MOVQ	runtime·_GetStdHandle(SB), AX
    84  	CALL	AX
    85  
    86  	MOVQ	AX, CX	// handle
    87  	MOVQ	CX, 0(SP)
    88  	MOVQ	$runtime·badsignalmsg(SB), DX // pointer
    89  	MOVQ	DX, 8(SP)
    90  	MOVL	$runtime·badsignallen(SB), R8 // count
    91  	MOVQ	R8, 16(SP)
    92  	LEAQ	40(SP), R9  // written count
    93  	MOVQ	$0, 0(R9)
    94  	MOVQ	R9, 24(SP)
    95  	MOVQ	$0, 32(SP)	// overlapped
    96  	MOVQ	runtime·_WriteFile(SB), AX
    97  	CALL	AX
    98  
    99  	// Does not return.
   100  	CALL	runtime·abort(SB)
   101  	RET
   102  
   103  // faster get/set last error
   104  TEXT runtime·getlasterror(SB),NOSPLIT,$0
   105  	MOVQ	0x30(GS), AX
   106  	MOVL	0x68(AX), AX
   107  	MOVL	AX, ret+0(FP)
   108  	RET
   109  
   110  // Called by Windows as a Vectored Exception Handler (VEH).
   111  // First argument is pointer to struct containing
   112  // exception record and context pointers.
   113  // Handler function is stored in AX.
   114  // Return 0 for 'not handled', -1 for handled.
   115  TEXT sigtramp<>(SB),NOSPLIT|NOFRAME,$0-0
   116  	// CX: PEXCEPTION_POINTERS ExceptionInfo
   117  
   118  	// Switch from the host ABI to the Go ABI.
   119  	PUSH_REGS_HOST_TO_ABI0()
   120  	// Make stack space for the rest of the function.
   121  	ADJSP	$48
   122  
   123  	MOVQ	AX, R15	// save handler address
   124  
   125  	// find g
   126  	get_tls(DX)
   127  	CMPQ	DX, $0
   128  	JNE	3(PC)
   129  	MOVQ	$0, AX // continue
   130  	JMP	done
   131  	MOVQ	g(DX), DX
   132  	CMPQ	DX, $0
   133  	JNE	2(PC)
   134  	CALL	runtime·badsignal2(SB)
   135  
   136  	// save g and SP in case of stack switch
   137  	MOVQ	DX, 32(SP) // g
   138  	MOVQ	SP, 40(SP)
   139  
   140  	// do we need to switch to the g0 stack?
   141  	MOVQ	g_m(DX), BX
   142  	MOVQ	m_g0(BX), BX
   143  	CMPQ	DX, BX
   144  	JEQ	g0
   145  
   146  	// switch to g0 stack
   147  	get_tls(BP)
   148  	MOVQ	BX, g(BP)
   149  	MOVQ	(g_sched+gobuf_sp)(BX), DI
   150  	// make room for sighandler arguments
   151  	// and re-save old SP for restoring later.
   152  	// Adjust g0 stack by the space we're using and
   153  	// save SP at the same place on the g0 stack.
   154  	// The 40(DI) here must match the 40(SP) above.
   155  	SUBQ	$(REGS_HOST_TO_ABI0_STACK + 48), DI
   156  	MOVQ	SP, 40(DI)
   157  	MOVQ	DI, SP
   158  
   159  g0:
   160  	MOVQ	0(CX), BX // ExceptionRecord*
   161  	MOVQ	8(CX), CX // Context*
   162  	MOVQ	BX, 0(SP)
   163  	MOVQ	CX, 8(SP)
   164  	MOVQ	DX, 16(SP)
   165  	CALL	R15	// call handler
   166  	// AX is set to report result back to Windows
   167  	MOVL	24(SP), AX
   168  
   169  	// switch back to original stack and g
   170  	// no-op if we never left.
   171  	MOVQ	40(SP), SP
   172  	MOVQ	32(SP), DX
   173  	get_tls(BP)
   174  	MOVQ	DX, g(BP)
   175  
   176  done:
   177  	ADJSP	$-48
   178  	POP_REGS_HOST_TO_ABI0()
   179  
   180  	RET
   181  
   182  TEXT runtime·exceptiontramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0
   183  	MOVQ	$runtime·exceptionhandler(SB), AX
   184  	JMP	sigtramp<>(SB)
   185  
   186  TEXT runtime·firstcontinuetramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
   187  	MOVQ	$runtime·firstcontinuehandler(SB), AX
   188  	JMP	sigtramp<>(SB)
   189  
   190  TEXT runtime·lastcontinuetramp<ABIInternal>(SB),NOSPLIT|NOFRAME,$0-0
   191  	MOVQ	$runtime·lastcontinuehandler(SB), AX
   192  	JMP	sigtramp<>(SB)
   193  
   194  GLOBL runtime·cbctxts(SB), NOPTR, $8
   195  
   196  TEXT runtime·callbackasm1(SB),NOSPLIT,$0
   197  	// Construct args vector for cgocallback().
   198  	// By windows/amd64 calling convention first 4 args are in CX, DX, R8, R9
   199  	// args from the 5th on are on the stack.
   200  	// In any case, even if function has 0,1,2,3,4 args, there is reserved
   201  	// but uninitialized "shadow space" for the first 4 args.
   202  	// The values are in registers.
   203    	MOVQ	CX, (16+0)(SP)
   204    	MOVQ	DX, (16+8)(SP)
   205    	MOVQ	R8, (16+16)(SP)
   206    	MOVQ	R9, (16+24)(SP)
   207  	// R8 = address of args vector
   208  	LEAQ	(16+0)(SP), R8
   209  
   210  	// remove return address from stack, we are not returning to callbackasm, but to its caller.
   211    	MOVQ	0(SP), AX
   212  	ADDQ	$8, SP
   213  
   214  	// determine index into runtime·cbs table
   215  	MOVQ	$runtime·callbackasm<ABIInternal>(SB), DX
   216  	SUBQ	DX, AX
   217  	MOVQ	$0, DX
   218  	MOVQ	$5, CX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
   219  	DIVL	CX
   220  	SUBQ	$1, AX	// subtract 1 because return PC is to the next slot
   221  
   222  	// Switch from the host ABI to the Go ABI.
   223  	PUSH_REGS_HOST_TO_ABI0()
   224  
   225  	// Create a struct callbackArgs on our stack to be passed as
   226  	// the "frame" to cgocallback and on to callbackWrap.
   227  	SUBQ	$(24+callbackArgs__size), SP
   228  	MOVQ	AX, (24+callbackArgs_index)(SP) 	// callback index
   229  	MOVQ	R8, (24+callbackArgs_args)(SP)  	// address of args vector
   230  	MOVQ	$0, (24+callbackArgs_result)(SP)	// result
   231  	LEAQ	24(SP), AX
   232  	// Call cgocallback, which will call callbackWrap(frame).
   233  	MOVQ	$0, 16(SP)	// context
   234  	MOVQ	AX, 8(SP)	// frame (address of callbackArgs)
   235  	LEAQ	·callbackWrap<ABIInternal>(SB), BX	// cgocallback takes an ABIInternal entry-point
   236  	MOVQ	BX, 0(SP)	// PC of function value to call (callbackWrap)
   237  	CALL	·cgocallback(SB)
   238  	// Get callback result.
   239  	MOVQ	(24+callbackArgs_result)(SP), AX
   240  	ADDQ	$(24+callbackArgs__size), SP
   241  
   242  	POP_REGS_HOST_TO_ABI0()
   243  
   244  	// The return value was placed in AX above.
   245  	RET
   246  
   247  // uint32 tstart_stdcall(M *newm);
   248  TEXT runtime·tstart_stdcall<ABIInternal>(SB),NOSPLIT,$0
   249  	// Switch from the host ABI to the Go ABI.
   250  	PUSH_REGS_HOST_TO_ABI0()
   251  
   252  	// CX contains first arg newm
   253  	MOVQ	m_g0(CX), DX		// g
   254  
   255  	// Layout new m scheduler stack on os stack.
   256  	MOVQ	SP, AX
   257  	MOVQ	AX, (g_stack+stack_hi)(DX)
   258  	SUBQ	$(64*1024), AX		// initial stack size (adjusted later)
   259  	MOVQ	AX, (g_stack+stack_lo)(DX)
   260  	ADDQ	$const__StackGuard, AX
   261  	MOVQ	AX, g_stackguard0(DX)
   262  	MOVQ	AX, g_stackguard1(DX)
   263  
   264  	// Set up tls.
   265  	LEAQ	m_tls(CX), SI
   266  	MOVQ	SI, 0x28(GS)
   267  	MOVQ	CX, g_m(DX)
   268  	MOVQ	DX, g(SI)
   269  
   270  	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
   271  	CALL	runtime·mstart(SB)
   272  
   273  	POP_REGS_HOST_TO_ABI0()
   274  
   275  	XORL	AX, AX			// return 0 == success
   276  	RET
   277  
   278  // set tls base to DI
   279  TEXT runtime·settls(SB),NOSPLIT,$0
   280  	MOVQ	DI, 0x28(GS)
   281  	RET
   282  
   283  // Runs on OS stack.
   284  // duration (in -100ns units) is in dt+0(FP).
   285  // g may be nil.
   286  // The function leaves room for 4 syscall parameters
   287  // (as per windows amd64 calling convention).
   288  TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$48-4
   289  	MOVLQSX	dt+0(FP), BX
   290  	MOVQ	SP, AX
   291  	ANDQ	$~15, SP	// alignment as per Windows requirement
   292  	MOVQ	AX, 40(SP)
   293  	LEAQ	32(SP), R8  // ptime
   294  	MOVQ	BX, (R8)
   295  	MOVQ	$-1, CX // handle
   296  	MOVQ	$0, DX // alertable
   297  	MOVQ	runtime·_NtWaitForSingleObject(SB), AX
   298  	CALL	AX
   299  	MOVQ	40(SP), SP
   300  	RET
   301  
   302  // Runs on OS stack. duration (in -100ns units) is in dt+0(FP).
   303  // g is valid.
   304  TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$72-4
   305  	MOVLQSX	dt+0(FP), BX
   306  	get_tls(CX)
   307  
   308  	MOVQ	SP, AX
   309  	ANDQ	$~15, SP	// alignment as per Windows requirement
   310  	MOVQ	AX, 64(SP)
   311  
   312  	MOVQ	g(CX), CX
   313  	MOVQ	g_m(CX), CX
   314  	MOVQ	(m_mOS+mOS_highResTimer)(CX), CX	// hTimer
   315  	MOVQ	CX, 48(SP)				// save hTimer for later
   316  	LEAQ	56(SP), DX				// lpDueTime
   317  	MOVQ	BX, (DX)
   318  	MOVQ	$0, R8					// lPeriod
   319  	MOVQ	$0, R9					// pfnCompletionRoutine
   320  	MOVQ	$0, AX
   321  	MOVQ	AX, 32(SP)				// lpArgToCompletionRoutine
   322  	MOVQ	AX, 40(SP)				// fResume
   323  	MOVQ	runtime·_SetWaitableTimer(SB), AX
   324  	CALL	AX
   325  
   326  	MOVQ	48(SP), CX				// handle
   327  	MOVQ	$0, DX					// alertable
   328  	MOVQ	$0, R8					// ptime
   329  	MOVQ	runtime·_NtWaitForSingleObject(SB), AX
   330  	CALL	AX
   331  
   332  	MOVQ	64(SP), SP
   333  	RET
   334  
   335  // Runs on OS stack.
   336  TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
   337  	MOVQ	SP, AX
   338  	ANDQ	$~15, SP	// alignment as per Windows requirement
   339  	SUBQ	$(48), SP	// room for SP and 4 args as per Windows requirement
   340  				// plus one extra word to keep stack 16 bytes aligned
   341  	MOVQ	AX, 32(SP)
   342  	MOVQ	runtime·_SwitchToThread(SB), AX
   343  	CALL	AX
   344  	MOVQ	32(SP), SP
   345  	RET
   346  
   347  TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
   348  	CMPB	runtime·useQPCTime(SB), $0
   349  	JNE	useQPC
   350  	MOVQ	$_INTERRUPT_TIME, DI
   351  	MOVQ	time_lo(DI), AX
   352  	IMULQ	$100, AX
   353  	MOVQ	AX, ret+0(FP)
   354  	RET
   355  useQPC:
   356  	JMP	runtime·nanotimeQPC(SB)
   357  	RET
   358  
   359  // func osSetupTLS(mp *m)
   360  // Setup TLS. for use by needm on Windows.
   361  TEXT runtime·osSetupTLS(SB),NOSPLIT,$0-8
   362  	MOVQ	mp+0(FP), AX
   363  	LEAQ	m_tls(AX), DI
   364  	CALL	runtime·settls(SB)
   365  	RET
   366  

View as plain text