github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/runtime/sys_windows_amd64.s (about)

     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 "zasm_GOOS_GOARCH.h"
     6  #include "../../cmd/ld/textflag.h"
     7  
     8  // maxargs should be divisible by 2, as Windows stack
     9  // must be kept 16-byte aligned on syscall entry.
    10  #define maxargs 16
    11  
    12  // void runtime·asmstdcall(void *c);
    13  TEXT runtime·asmstdcall(SB),NOSPLIT,$0
    14  	// asmcgocall will put first argument into CX.
    15  	PUSHQ	CX			// save for later
    16  	MOVQ	wincall_fn(CX), AX
    17  	MOVQ	wincall_args(CX), SI
    18  	MOVQ	wincall_n(CX), CX
    19  
    20  	// SetLastError(0).
    21  	MOVQ	0x30(GS), DI
    22  	MOVL	$0, 0x68(DI)
    23  
    24  	SUBQ	$(maxargs*8), SP	// room for args
    25  
    26  	// Fast version, do not store args on the stack.
    27  	CMPL	CX, $4
    28  	JLE	loadregs
    29  
    30  	// Check we have enough room for args.
    31  	CMPL	CX, $maxargs
    32  	JLE	2(PC)
    33  	INT	$3			// not enough room -> crash
    34  
    35  	// Copy args to the stack.
    36  	MOVQ	SP, DI
    37  	CLD
    38  	REP; MOVSQ
    39  	MOVQ	SP, SI
    40  
    41  loadregs:
    42  	// Load first 4 args into correspondent registers.
    43  	MOVQ	0(SI), CX
    44  	MOVQ	8(SI), DX
    45  	MOVQ	16(SI), R8
    46  	MOVQ	24(SI), R9
    47  
    48  	// Call stdcall function.
    49  	CALL	AX
    50  
    51  	ADDQ	$(maxargs*8), SP
    52  
    53  	// Return result.
    54  	POPQ	CX
    55  	MOVQ	AX, wincall_r1(CX)
    56  
    57  	// GetLastError().
    58  	MOVQ	0x30(GS), DI
    59  	MOVL	0x68(DI), AX
    60  	MOVQ	AX, wincall_err(CX)
    61  
    62  	RET
    63  
    64  TEXT runtime·badsignal2(SB),NOSPLIT,$48
    65  	// stderr
    66  	MOVQ	$-12, CX // stderr
    67  	MOVQ	CX, 0(SP)
    68  	MOVQ	runtime·GetStdHandle(SB), AX
    69  	CALL	AX
    70  
    71  	MOVQ	AX, CX	// handle
    72  	MOVQ	CX, 0(SP)
    73  	MOVQ	$runtime·badsignalmsg(SB), DX // pointer
    74  	MOVQ	DX, 8(SP)
    75  	MOVL	$runtime·badsignallen(SB), R8 // count
    76  	MOVQ	R8, 16(SP)
    77  	LEAQ	40(SP), R9  // written count
    78  	MOVQ	$0, 0(R9)
    79  	MOVQ	R9, 24(SP)
    80  	MOVQ	$0, 32(SP)	// overlapped
    81  	MOVQ	runtime·WriteFile(SB), AX
    82  	CALL	AX
    83  	
    84  	RET
    85  
    86  // faster get/set last error
    87  TEXT runtime·getlasterror(SB),NOSPLIT,$0
    88  	MOVQ	0x30(GS), AX
    89  	MOVL	0x68(AX), AX
    90  	RET
    91  
    92  TEXT runtime·setlasterror(SB),NOSPLIT,$0
    93  	MOVL	err+0(FP), AX
    94  	MOVQ	0x30(GS),	CX
    95  	MOVL	AX, 0x68(CX)
    96  	RET
    97  
    98  TEXT runtime·sigtramp(SB),NOSPLIT,$0
    99  	// CX: exception record
   100  	// R8: context
   101  
   102  	// unwinding?
   103  	TESTL	$6, 4(CX)		// exception flags
   104  	MOVL	$1, AX
   105  	JNZ	sigdone
   106  
   107  	// copy arguments for call to sighandler.
   108  
   109  	// Stack adjustment is here to hide from 6l,
   110  	// which doesn't understand that sigtramp
   111  	// runs on essentially unlimited stack.
   112  	SUBQ	$56, SP
   113  	MOVQ	CX, 0(SP)
   114  	MOVQ	R8, 8(SP)
   115  
   116  	get_tls(CX)
   117  
   118  	// check that m exists
   119  	MOVQ	m(CX), AX
   120  	CMPQ	AX, $0
   121  	JNE	2(PC)
   122  	CALL	runtime·badsignal2(SB)
   123  
   124  	MOVQ	g(CX), CX
   125  	MOVQ	CX, 16(SP)
   126  
   127  	MOVQ	BX, 24(SP)
   128  	MOVQ	BP, 32(SP)
   129  	MOVQ	SI, 40(SP)
   130  	MOVQ	DI, 48(SP)
   131  
   132  	CALL	runtime·sighandler(SB)
   133  
   134  	MOVQ	24(SP), BX
   135  	MOVQ	32(SP), BP
   136  	MOVQ	40(SP), SI
   137  	MOVQ	48(SP), DI
   138  	ADDQ	$56, SP
   139  
   140  sigdone:
   141  	RET
   142  
   143  TEXT runtime·ctrlhandler(SB),NOSPLIT,$8
   144  	MOVQ	CX, 16(SP)		// spill
   145  	MOVQ	$runtime·ctrlhandler1(SB), CX
   146  	MOVQ	CX, 0(SP)
   147  	CALL	runtime·externalthreadhandler(SB)
   148  	RET
   149  
   150  TEXT runtime·profileloop(SB),NOSPLIT,$8
   151  	MOVQ	$runtime·profileloop1(SB), CX
   152  	MOVQ	CX, 0(SP)
   153  	CALL	runtime·externalthreadhandler(SB)
   154  	RET
   155  
   156  TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
   157  	PUSHQ	BP
   158  	MOVQ	SP, BP
   159  	PUSHQ	BX
   160  	PUSHQ	SI
   161  	PUSHQ	DI
   162  	PUSHQ	0x28(GS)
   163  	MOVQ	SP, DX
   164  
   165  	// setup dummy m, g
   166  	SUBQ	$m_end, SP		// space for M
   167  	MOVQ	SP, 0(SP)
   168  	MOVQ	$m_end, 8(SP)
   169  	CALL	runtime·memclr(SB)	// smashes AX,BX,CX
   170  
   171  	LEAQ	m_tls(SP), CX
   172  	MOVQ	CX, 0x28(GS)
   173  	MOVQ	SP, m(CX)
   174  	MOVQ	SP, BX
   175  	SUBQ	$g_end, SP		// space for G
   176  	MOVQ	SP, g(CX)
   177  	MOVQ	SP, m_g0(BX)
   178  
   179  	MOVQ	SP, 0(SP)
   180  	MOVQ	$g_end, 8(SP)
   181  	CALL	runtime·memclr(SB)	// smashes AX,BX,CX
   182  	LEAQ	-8192(SP), CX
   183  	MOVQ	CX, g_stackguard(SP)
   184  	MOVQ	DX, g_stackbase(SP)
   185  
   186  	PUSHQ	32(BP)			// arg for handler
   187  	CALL	16(BP)
   188  	POPQ	CX
   189  
   190  	get_tls(CX)
   191  	MOVQ	g(CX), CX
   192  	MOVQ	g_stackbase(CX), SP
   193  	POPQ	0x28(GS)
   194  	POPQ	DI
   195  	POPQ	SI
   196  	POPQ	BX
   197  	POPQ	BP
   198  	RET
   199  
   200  GLOBL runtime·cbctxts(SB), $8
   201  
   202  TEXT runtime·callbackasm1(SB),NOSPLIT,$0
   203  	// Construct args vector for cgocallback().
   204  	// By windows/amd64 calling convention first 4 args are in CX, DX, R8, R9
   205  	// args from the 5th on are on the stack.
   206  	// In any case, even if function has 0,1,2,3,4 args, there is reserved
   207  	// but uninitialized "shadow space" for the first 4 args.
   208  	// The values are in registers.
   209    	MOVQ	CX, (16+0)(SP)
   210    	MOVQ	DX, (16+8)(SP)
   211    	MOVQ	R8, (16+16)(SP)
   212    	MOVQ	R9, (16+24)(SP)
   213  
   214  	// remove return address from stack, we are not returning there
   215    	MOVQ	0(SP), AX
   216  	ADDQ	$8, SP
   217  
   218  	// determine index into runtime·cbctxts table
   219  	SUBQ	$runtime·callbackasm(SB), AX
   220  	MOVQ	$0, DX
   221  	MOVQ	$5, CX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
   222  	DIVL	CX,
   223  
   224  	// find correspondent runtime·cbctxts table entry
   225  	MOVQ	runtime·cbctxts(SB), CX
   226  	MOVQ	-8(CX)(AX*8), AX
   227  
   228  	// extract callback context
   229  	MOVQ	cbctxt_argsize(AX), DX
   230  	MOVQ	cbctxt_gobody(AX), AX
   231  
   232  	// preserve whatever's at the memory location that
   233  	// the callback will use to store the return value
   234  	LEAQ	8(SP), CX       // args vector, skip return address
   235  	PUSHQ	0(CX)(DX*1)     // store 8 bytes from just after the args array
   236  	ADDQ	$8, DX          // extend argsize by size of return value
   237  
   238  	// DI SI BP BX R12 R13 R14 R15 registers and DF flag are preserved
   239  	// as required by windows callback convention.
   240  	PUSHFQ
   241  	SUBQ	$64, SP
   242  	MOVQ	DI, 56(SP)
   243  	MOVQ	SI, 48(SP)
   244  	MOVQ	BP, 40(SP)
   245  	MOVQ	BX, 32(SP)
   246  	MOVQ	R12, 24(SP)
   247  	MOVQ	R13, 16(SP)
   248  	MOVQ	R14, 8(SP)
   249  	MOVQ	R15, 0(SP)
   250  
   251  	// prepare call stack.  use SUBQ to hide from stack frame checks
   252  	// cgocallback(Go func, void *frame, uintptr framesize)
   253  	SUBQ	$24, SP
   254  	MOVQ	DX, 16(SP)	// argsize (including return value)
   255  	MOVQ	CX, 8(SP)	// callback parameters
   256  	MOVQ	AX, 0(SP)	// address of target Go function
   257  	CLD
   258  	CALL	runtime·cgocallback_gofunc(SB)
   259  	MOVQ	0(SP), AX
   260  	MOVQ	8(SP), CX
   261  	MOVQ	16(SP), DX
   262  	ADDQ	$24, SP
   263  
   264  	// restore registers as required for windows callback
   265  	MOVQ	0(SP), R15
   266  	MOVQ	8(SP), R14
   267  	MOVQ	16(SP), R13
   268  	MOVQ	24(SP), R12
   269  	MOVQ	32(SP), BX
   270  	MOVQ	40(SP), BP
   271  	MOVQ	48(SP), SI
   272  	MOVQ	56(SP), DI
   273  	ADDQ	$64, SP
   274  	POPFQ
   275  
   276  	MOVL	-8(CX)(DX*1), AX  // return value
   277  	POPQ	-8(CX)(DX*1)      // restore bytes just after the args
   278  	RET
   279  
   280  TEXT runtime·setstacklimits(SB),NOSPLIT,$0
   281  	MOVQ	0x30(GS), CX
   282  	MOVQ	$0, 0x10(CX)
   283  	MOVQ	$0xffffffffffff, AX
   284  	MOVQ	AX, 0x08(CX)
   285  	RET
   286  
   287  // uint32 tstart_stdcall(M *newm);
   288  TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
   289  	// CX contains first arg newm
   290  	MOVQ	m_g0(CX), DX		// g
   291  
   292  	// Layout new m scheduler stack on os stack.
   293  	MOVQ	SP, AX
   294  	MOVQ	AX, g_stackbase(DX)
   295  	SUBQ	$(64*1024), AX		// stack size
   296  	MOVQ	AX, g_stackguard(DX)
   297  
   298  	// Set up tls.
   299  	LEAQ	m_tls(CX), SI
   300  	MOVQ	SI, 0x28(GS)
   301  	MOVQ	CX, m(SI)
   302  	MOVQ	DX, g(SI)
   303  
   304  	// Someday the convention will be D is always cleared.
   305  	CLD
   306  
   307  	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
   308  	CALL	runtime·mstart(SB)
   309  
   310  	XORL	AX, AX			// return 0 == success
   311  	RET
   312  
   313  // set tls base to DI
   314  TEXT runtime·settls(SB),NOSPLIT,$0
   315  	MOVQ	DI, 0x28(GS)
   316  	RET
   317  
   318  // void install_exception_handler()
   319  TEXT runtime·install_exception_handler(SB),NOSPLIT,$0
   320  	CALL	runtime·setstacklimits(SB)
   321  	RET
   322  
   323  TEXT runtime·remove_exception_handler(SB),NOSPLIT,$0
   324  	RET
   325  
   326  // Sleep duration is in 100ns units.
   327  TEXT runtime·usleep1(SB),NOSPLIT,$0
   328  	MOVL	duration+0(FP), BX
   329  	MOVQ	$runtime·usleep2(SB), AX // to hide from 6l
   330  
   331  	// Execute call on m->g0 stack, in case we are not actually
   332  	// calling a system call wrapper, like when running under WINE.
   333  	get_tls(R15)
   334  	CMPQ	R15, $0
   335  	JNE	3(PC)
   336  	// Not a Go-managed thread. Do not switch stack.
   337  	CALL	AX
   338  	RET
   339  
   340  	MOVQ	m(R15), R14
   341  	MOVQ	m_g0(R14), R14
   342  	CMPQ	g(R15), R14
   343  	JNE	3(PC)
   344  	// executing on m->g0 already
   345  	CALL	AX
   346  	RET
   347  
   348  	// Switch to m->g0 stack and back.
   349  	MOVQ	(g_sched+gobuf_sp)(R14), R14
   350  	MOVQ	SP, -8(R14)
   351  	LEAQ	-8(R14), SP
   352  	CALL	AX
   353  	MOVQ	0(SP), SP
   354  	RET
   355  
   356  // Runs on OS stack. duration (in 100ns units) is in BX.
   357  TEXT runtime·usleep2(SB),NOSPLIT,$8
   358  	// Want negative 100ns units.
   359  	NEGQ	BX
   360  	MOVQ	SP, R8 // ptime
   361  	MOVQ	BX, (R8)
   362  	MOVQ	$-1, CX // handle
   363  	MOVQ	$0, DX // alertable
   364  	MOVQ	runtime·NtWaitForSingleObject(SB), AX
   365  	CALL	AX
   366  	RET