Text file
src/runtime/sys_windows_amd64.s
Documentation: runtime
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 loop:
352 MOVL time_hi1(DI), AX
353 MOVL time_lo(DI), BX
354 MOVL time_hi2(DI), CX
355 CMPL AX, CX
356 JNE loop
357 SHLQ $32, CX
358 ORQ BX, CX
359 IMULQ $100, CX
360 MOVQ CX, ret+0(FP)
361 RET
362 useQPC:
363 JMP runtime·nanotimeQPC(SB)
364 RET
365
366 // func osSetupTLS(mp *m)
367 // Setup TLS. for use by needm on Windows.
368 TEXT runtime·osSetupTLS(SB),NOSPLIT,$0-8
369 MOVQ mp+0(FP), AX
370 LEAQ m_tls(AX), DI
371 CALL runtime·settls(SB)
372 RET
373
View as plain text