Text file
src/runtime/sys_windows_386.s
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 // void runtime·asmstdcall(void *c);
11 TEXT runtime·asmstdcall(SB),NOSPLIT,$0
12 MOVL fn+0(FP), BX
13
14 // SetLastError(0).
15 MOVL $0, 0x34(FS)
16
17 // Copy args to the stack.
18 MOVL SP, BP
19 MOVL libcall_n(BX), CX // words
20 MOVL CX, AX
21 SALL $2, AX
22 SUBL AX, SP // room for args
23 MOVL SP, DI
24 MOVL libcall_args(BX), SI
25 CLD
26 REP; MOVSL
27
28 // Call stdcall or cdecl function.
29 // DI SI BP BX are preserved, SP is not
30 CALL libcall_fn(BX)
31 MOVL BP, SP
32
33 // Return result.
34 MOVL fn+0(FP), BX
35 MOVL AX, libcall_r1(BX)
36 MOVL DX, libcall_r2(BX)
37
38 // GetLastError().
39 MOVL 0x34(FS), AX
40 MOVL AX, libcall_err(BX)
41
42 RET
43
44 TEXT runtime·badsignal2(SB),NOSPLIT,$24
45 // stderr
46 MOVL $-12, 0(SP)
47 MOVL SP, BP
48 CALL *runtime·_GetStdHandle(SB)
49 MOVL BP, SP
50
51 MOVL AX, 0(SP) // handle
52 MOVL $runtime·badsignalmsg(SB), DX // pointer
53 MOVL DX, 4(SP)
54 MOVL runtime·badsignallen(SB), DX // count
55 MOVL DX, 8(SP)
56 LEAL 20(SP), DX // written count
57 MOVL $0, 0(DX)
58 MOVL DX, 12(SP)
59 MOVL $0, 16(SP) // overlapped
60 CALL *runtime·_WriteFile(SB)
61
62 // Does not return.
63 CALL runtime·abort(SB)
64 RET
65
66 // faster get/set last error
67 TEXT runtime·getlasterror(SB),NOSPLIT,$0
68 MOVL 0x34(FS), AX
69 MOVL AX, ret+0(FP)
70 RET
71
72 // Called by Windows as a Vectored Exception Handler (VEH).
73 // First argument is pointer to struct containing
74 // exception record and context pointers.
75 // Handler function is stored in AX.
76 // Return 0 for 'not handled', -1 for handled.
77 TEXT sigtramp<>(SB),NOSPLIT,$0-0
78 MOVL ptrs+0(FP), CX
79 SUBL $40, SP
80
81 // save callee-saved registers
82 MOVL BX, 28(SP)
83 MOVL BP, 16(SP)
84 MOVL SI, 20(SP)
85 MOVL DI, 24(SP)
86
87 MOVL AX, SI // save handler address
88
89 // find g
90 get_tls(DX)
91 CMPL DX, $0
92 JNE 3(PC)
93 MOVL $0, AX // continue
94 JMP done
95 MOVL g(DX), DX
96 CMPL DX, $0
97 JNE 2(PC)
98 CALL runtime·badsignal2(SB)
99
100 // save g in case of stack switch
101 MOVL DX, 32(SP) // g
102 MOVL SP, 36(SP)
103
104 // do we need to switch to the g0 stack?
105 MOVL g_m(DX), BX
106 MOVL m_g0(BX), BX
107 CMPL DX, BX
108 JEQ g0
109
110 // switch to the g0 stack
111 get_tls(BP)
112 MOVL BX, g(BP)
113 MOVL (g_sched+gobuf_sp)(BX), DI
114 // make room for sighandler arguments
115 // and re-save old SP for restoring later.
116 // (note that the 36(DI) here must match the 36(SP) above.)
117 SUBL $40, DI
118 MOVL SP, 36(DI)
119 MOVL DI, SP
120
121 g0:
122 MOVL 0(CX), BX // ExceptionRecord*
123 MOVL 4(CX), CX // Context*
124 MOVL BX, 0(SP)
125 MOVL CX, 4(SP)
126 MOVL DX, 8(SP)
127 CALL SI // call handler
128 // AX is set to report result back to Windows
129 MOVL 12(SP), AX
130
131 // switch back to original stack and g
132 // no-op if we never left.
133 MOVL 36(SP), SP
134 MOVL 32(SP), DX // note: different SP
135 get_tls(BP)
136 MOVL DX, g(BP)
137
138 done:
139 // restore callee-saved registers
140 MOVL 24(SP), DI
141 MOVL 20(SP), SI
142 MOVL 16(SP), BP
143 MOVL 28(SP), BX
144
145 ADDL $40, SP
146 // RET 4 (return and pop 4 bytes parameters)
147 BYTE $0xC2; WORD $4
148 RET // unreached; make assembler happy
149
150 TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
151 MOVL $runtime·exceptionhandler(SB), AX
152 JMP sigtramp<>(SB)
153
154 TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
155 // is never called
156 INT $3
157
158 TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
159 MOVL $runtime·lastcontinuehandler(SB), AX
160 JMP sigtramp<>(SB)
161
162 GLOBL runtime·cbctxts(SB), NOPTR, $4
163
164 TEXT runtime·callbackasm1(SB),NOSPLIT,$0
165 MOVL 0(SP), AX // will use to find our callback context
166
167 // remove return address from stack, we are not returning to callbackasm, but to its caller.
168 ADDL $4, SP
169
170 // address to callback parameters into CX
171 LEAL 4(SP), CX
172
173 // save registers as required for windows callback
174 PUSHL DI
175 PUSHL SI
176 PUSHL BP
177 PUSHL BX
178
179 // Go ABI requires DF flag to be cleared.
180 CLD
181
182 // determine index into runtime·cbs table
183 SUBL $runtime·callbackasm(SB), AX
184 MOVL $0, DX
185 MOVL $5, BX // divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
186 DIVL BX
187 SUBL $1, AX // subtract 1 because return PC is to the next slot
188
189 // Create a struct callbackArgs on our stack.
190 SUBL $(12+callbackArgs__size), SP
191 MOVL AX, (12+callbackArgs_index)(SP) // callback index
192 MOVL CX, (12+callbackArgs_args)(SP) // address of args vector
193 MOVL $0, (12+callbackArgs_result)(SP) // result
194 LEAL 12(SP), AX // AX = &callbackArgs{...}
195
196 // Call cgocallback, which will call callbackWrap(frame).
197 MOVL $0, 8(SP) // context
198 MOVL AX, 4(SP) // frame (address of callbackArgs)
199 LEAL ·callbackWrap(SB), AX
200 MOVL AX, 0(SP) // PC of function to call
201 CALL runtime·cgocallback(SB)
202
203 // Get callback result.
204 MOVL (12+callbackArgs_result)(SP), AX
205 // Get popRet.
206 MOVL (12+callbackArgs_retPop)(SP), CX // Can't use a callee-save register
207 ADDL $(12+callbackArgs__size), SP
208
209 // restore registers as required for windows callback
210 POPL BX
211 POPL BP
212 POPL SI
213 POPL DI
214
215 // remove callback parameters before return (as per Windows spec)
216 POPL DX
217 ADDL CX, SP
218 PUSHL DX
219
220 CLD
221
222 RET
223
224 // void tstart(M *newm);
225 TEXT tstart<>(SB),NOSPLIT,$0
226 MOVL newm+0(FP), CX // m
227 MOVL m_g0(CX), DX // g
228
229 // Layout new m scheduler stack on os stack.
230 MOVL SP, AX
231 MOVL AX, (g_stack+stack_hi)(DX)
232 SUBL $(64*1024), AX // initial stack size (adjusted later)
233 MOVL AX, (g_stack+stack_lo)(DX)
234 ADDL $const__StackGuard, AX
235 MOVL AX, g_stackguard0(DX)
236 MOVL AX, g_stackguard1(DX)
237
238 // Set up tls.
239 LEAL m_tls(CX), SI
240 MOVL SI, 0x14(FS)
241 MOVL CX, g_m(DX)
242 MOVL DX, g(SI)
243
244 // Someday the convention will be D is always cleared.
245 CLD
246
247 CALL runtime·stackcheck(SB) // clobbers AX,CX
248 CALL runtime·mstart(SB)
249
250 RET
251
252 // uint32 tstart_stdcall(M *newm);
253 TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
254 MOVL newm+0(FP), BX
255
256 PUSHL BX
257 CALL tstart<>(SB)
258 POPL BX
259
260 // Adjust stack for stdcall to return properly.
261 MOVL (SP), AX // save return address
262 ADDL $4, SP // remove single parameter
263 MOVL AX, (SP) // restore return address
264
265 XORL AX, AX // return 0 == success
266
267 RET
268
269 // setldt(int entry, int address, int limit)
270 TEXT runtime·setldt(SB),NOSPLIT,$0
271 MOVL base+4(FP), CX
272 MOVL CX, 0x14(FS)
273 RET
274
275 // Runs on OS stack.
276 // duration (in -100ns units) is in dt+0(FP).
277 // g may be nil.
278 TEXT runtime·usleep2(SB),NOSPLIT,$20-4
279 MOVL dt+0(FP), BX
280 MOVL $-1, hi-4(SP)
281 MOVL BX, lo-8(SP)
282 LEAL lo-8(SP), BX
283 MOVL BX, ptime-12(SP)
284 MOVL $0, alertable-16(SP)
285 MOVL $-1, handle-20(SP)
286 MOVL SP, BP
287 MOVL runtime·_NtWaitForSingleObject(SB), AX
288 CALL AX
289 MOVL BP, SP
290 RET
291
292 // Runs on OS stack.
293 // duration (in -100ns units) is in dt+0(FP).
294 // g is valid.
295 TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36-4
296 MOVL dt+0(FP), BX
297 MOVL $-1, hi-4(SP)
298 MOVL BX, lo-8(SP)
299
300 get_tls(CX)
301 MOVL g(CX), CX
302 MOVL g_m(CX), CX
303 MOVL (m_mOS+mOS_highResTimer)(CX), CX
304 MOVL CX, saved_timer-12(SP)
305
306 MOVL $0, fResume-16(SP)
307 MOVL $0, lpArgToCompletionRoutine-20(SP)
308 MOVL $0, pfnCompletionRoutine-24(SP)
309 MOVL $0, lPeriod-28(SP)
310 LEAL lo-8(SP), BX
311 MOVL BX, lpDueTime-32(SP)
312 MOVL CX, hTimer-36(SP)
313 MOVL SP, BP
314 MOVL runtime·_SetWaitableTimer(SB), AX
315 CALL AX
316 MOVL BP, SP
317
318 MOVL $0, ptime-28(SP)
319 MOVL $0, alertable-32(SP)
320 MOVL saved_timer-12(SP), CX
321 MOVL CX, handle-36(SP)
322 MOVL SP, BP
323 MOVL runtime·_NtWaitForSingleObject(SB), AX
324 CALL AX
325 MOVL BP, SP
326
327 RET
328
329 // Runs on OS stack.
330 TEXT runtime·switchtothread(SB),NOSPLIT,$0
331 MOVL SP, BP
332 MOVL runtime·_SwitchToThread(SB), AX
333 CALL AX
334 MOVL BP, SP
335 RET
336
337 TEXT runtime·nanotime1(SB),NOSPLIT,$0-8
338 CMPB runtime·useQPCTime(SB), $0
339 JNE useQPC
340 loop:
341 MOVL (_INTERRUPT_TIME+time_hi1), AX
342 MOVL (_INTERRUPT_TIME+time_lo), CX
343 MOVL (_INTERRUPT_TIME+time_hi2), DI
344 CMPL AX, DI
345 JNE loop
346
347 // wintime = DI:CX, multiply by 100
348 MOVL $100, AX
349 MULL CX
350 IMULL $100, DI
351 ADDL DI, DX
352 // wintime*100 = DX:AX
353 MOVL AX, ret_lo+0(FP)
354 MOVL DX, ret_hi+4(FP)
355 RET
356 useQPC:
357 JMP runtime·nanotimeQPC(SB)
358 RET
359
View as plain text