blob: ea4f3e03563a2aa2082e2808e2b56ff40ec4f0eb [file] [log] [blame]
Wei Guangjingf83609f2011-06-29 17:37:56 +10001// 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
Russ Cox15ced2d2014-11-11 17:06:22 -05005#include "go_asm.h"
6#include "go_tls.h"
Russ Coxcb040d52014-09-04 23:05:18 -04007#include "textflag.h"
Wei Guangjingf83609f2011-06-29 17:37:56 +10008
Alex Brainmanfbdec642011-11-29 12:57:20 +11009// maxargs should be divisible by 2, as Windows stack
10// must be kept 16-byte aligned on syscall entry.
11#define maxargs 16
Wei Guangjingf83609f2011-06-29 17:37:56 +100012
Alex Brainman2a808822011-08-27 23:17:00 +100013// void runtime·asmstdcall(void *c);
Keith Randall0273dc12013-08-07 12:20:05 -070014TEXT runtime·asmstdcall(SB),NOSPLIT,$0
Alex Brainman2a808822011-08-27 23:17:00 +100015 // asmcgocall will put first argument into CX.
16 PUSHQ CX // save for later
Aram Hăvărneanua46b4342014-01-17 17:58:10 +130017 MOVQ libcall_fn(CX), AX
18 MOVQ libcall_args(CX), SI
19 MOVQ libcall_n(CX), CX
Alex Brainman2a808822011-08-27 23:17:00 +100020
21 // SetLastError(0).
22 MOVQ 0x30(GS), DI
23 MOVL $0, 0x68(DI)
24
25 SUBQ $(maxargs*8), SP // room for args
26
27 // Fast version, do not store args on the stack.
28 CMPL CX, $4
29 JLE loadregs
30
31 // Check we have enough room for args.
32 CMPL CX, $maxargs
33 JLE 2(PC)
34 INT $3 // not enough room -> crash
35
36 // Copy args to the stack.
Wei Guangjingf83609f2011-06-29 17:37:56 +100037 MOVQ SP, DI
Wei Guangjingf83609f2011-06-29 17:37:56 +100038 CLD
39 REP; MOVSQ
Alex Brainman2a808822011-08-27 23:17:00 +100040 MOVQ SP, SI
41
42loadregs:
43 // Load first 4 args into correspondent registers.
44 MOVQ 0(SI), CX
45 MOVQ 8(SI), DX
46 MOVQ 16(SI), R8
47 MOVQ 24(SI), R9
Wei Guangjingf83609f2011-06-29 17:37:56 +100048
49 // Call stdcall function.
50 CALL AX
Alex Brainman2a808822011-08-27 23:17:00 +100051
52 ADDQ $(maxargs*8), SP
53
54 // Return result.
55 POPQ CX
Aram Hăvărneanua46b4342014-01-17 17:58:10 +130056 MOVQ AX, libcall_r1(CX)
Alex Brainman2a808822011-08-27 23:17:00 +100057
58 // GetLastError().
59 MOVQ 0x30(GS), DI
60 MOVL 0x68(DI), AX
Aram Hăvărneanua46b4342014-01-17 17:58:10 +130061 MOVQ AX, libcall_err(CX)
Wei Guangjingf83609f2011-06-29 17:37:56 +100062
63 RET
64
Keith Randall0273dc12013-08-07 12:20:05 -070065TEXT runtime·badsignal2(SB),NOSPLIT,$48
Russ Coxb2369112012-03-12 15:55:18 -040066 // stderr
67 MOVQ $-12, CX // stderr
68 MOVQ CX, 0(SP)
Alex Brainmanb27c0612014-11-19 11:55:15 +110069 MOVQ runtime·_GetStdHandle(SB), AX
Russ Coxb2369112012-03-12 15:55:18 -040070 CALL AX
71
72 MOVQ AX, CX // handle
73 MOVQ CX, 0(SP)
74 MOVQ $runtime·badsignalmsg(SB), DX // pointer
75 MOVQ DX, 8(SP)
76 MOVL $runtime·badsignallen(SB), R8 // count
77 MOVQ R8, 16(SP)
78 LEAQ 40(SP), R9 // written count
79 MOVQ $0, 0(R9)
80 MOVQ R9, 24(SP)
81 MOVQ $0, 32(SP) // overlapped
Alex Brainmanb27c0612014-11-19 11:55:15 +110082 MOVQ runtime·_WriteFile(SB), AX
Russ Coxb2369112012-03-12 15:55:18 -040083 CALL AX
84
85 RET
86
Wei Guangjingf83609f2011-06-29 17:37:56 +100087// faster get/set last error
Keith Randall0273dc12013-08-07 12:20:05 -070088TEXT runtime·getlasterror(SB),NOSPLIT,$0
Wei Guangjingf83609f2011-06-29 17:37:56 +100089 MOVQ 0x30(GS), AX
90 MOVL 0x68(AX), AX
Russ Cox25f6b022014-08-27 11:32:17 -040091 MOVL AX, ret+0(FP)
Wei Guangjingf83609f2011-06-29 17:37:56 +100092 RET
93
Keith Randall0273dc12013-08-07 12:20:05 -070094TEXT runtime·setlasterror(SB),NOSPLIT,$0
Wei Guangjingf83609f2011-06-29 17:37:56 +100095 MOVL err+0(FP), AX
96 MOVQ 0x30(GS), CX
97 MOVL AX, 0x68(CX)
98 RET
99
Alex Brainmana8373472014-03-26 11:13:50 +1100100// Called by Windows as a Vectored Exception Handler (VEH).
101// First argument is pointer to struct containing
102// exception record and context pointers.
Alex Brainmane9ecd4a2014-10-15 11:11:11 +1100103// Handler function is stored in AX.
Alex Brainmana8373472014-03-26 11:13:50 +1100104// Return 0 for 'not handled', -1 for handled.
105TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
106 // CX: PEXCEPTION_POINTERS ExceptionInfo
Hector Chu9b011502011-09-03 18:27:16 +1000107
Alex Brainmana8373472014-03-26 11:13:50 +1100108 // DI SI BP BX R12 R13 R14 R15 registers and DF flag are preserved
109 // as required by windows callback convention.
110 PUSHFQ
Russ Cox201cfe42014-09-08 16:56:46 -0400111 SUBQ $112, SP
Alex Brainmana8373472014-03-26 11:13:50 +1100112 MOVQ DI, 80(SP)
113 MOVQ SI, 72(SP)
114 MOVQ BP, 64(SP)
115 MOVQ BX, 56(SP)
116 MOVQ R12, 48(SP)
117 MOVQ R13, 40(SP)
118 MOVQ R14, 32(SP)
Russ Coxc548cc22014-08-27 14:43:07 -0400119 MOVQ R15, 88(SP)
Hector Chu9b011502011-09-03 18:27:16 +1000120
Alex Brainmane9ecd4a2014-10-15 11:11:11 +1100121 MOVQ AX, R15 // save handler address
122
Russ Cox201cfe42014-09-08 16:56:46 -0400123 // find g
Alex Brainmana8373472014-03-26 11:13:50 +1100124 get_tls(DX)
Shenghou Maa1778ec2014-07-09 23:55:35 -0400125 CMPQ DX, $0
126 JNE 3(PC)
127 MOVQ $0, AX // continue
128 JMP done
Russ Cox89f185f2014-06-26 11:54:39 -0400129 MOVQ g(DX), DX
130 CMPQ DX, $0
Russ Coxb2369112012-03-12 15:55:18 -0400131 JNE 2(PC)
Shenghou Ma4a4d4832013-07-12 05:06:43 +0800132 CALL runtime·badsignal2(SB)
Russ Cox201cfe42014-09-08 16:56:46 -0400133
134 // save g and SP in case of stack switch
135 MOVQ DX, 96(SP) // g
136 MOVQ SP, 104(SP)
137
138 // do we need to switch to the g0 stack?
139 MOVQ g_m(DX), BX
140 MOVQ m_g0(BX), BX
141 CMPQ DX, BX
Russ Coxb55791e2014-10-28 21:50:16 -0400142 JEQ g0
Russ Cox201cfe42014-09-08 16:56:46 -0400143
144 // switch to g0 stack
145 get_tls(BP)
146 MOVQ BX, g(BP)
147 MOVQ (g_sched+gobuf_sp)(BX), DI
148 // make it look like mstart called us on g0, to stop traceback
149 SUBQ $8, DI
150 MOVQ $runtime·mstart(SB), SI
151 MOVQ SI, 0(DI)
152 // traceback will think that we've done PUSHFQ and SUBQ
153 // on this stack, so subtract them here to match.
154 // (we need room for sighandler arguments anyway).
155 // and re-save old SP for restoring later.
156 SUBQ $(112+8), DI
157 // save g, save old stack pointer.
158 MOVQ SP, 104(DI)
159 MOVQ DI, SP
160
Russ Coxb55791e2014-10-28 21:50:16 -0400161g0:
Russ Cox201cfe42014-09-08 16:56:46 -0400162 MOVQ 0(CX), BX // ExceptionRecord*
163 MOVQ 8(CX), CX // Context*
Alex Brainmana8373472014-03-26 11:13:50 +1100164 MOVQ BX, 0(SP)
165 MOVQ CX, 8(SP)
166 MOVQ DX, 16(SP)
Alex Brainmane9ecd4a2014-10-15 11:11:11 +1100167 CALL R15 // call handler
Alex Brainmana8373472014-03-26 11:13:50 +1100168 // AX is set to report result back to Windows
Russ Coxc548cc22014-08-27 14:43:07 -0400169 MOVL 24(SP), AX
Hector Chu9b011502011-09-03 18:27:16 +1000170
Russ Cox201cfe42014-09-08 16:56:46 -0400171 // switch back to original stack and g
172 // no-op if we never left.
173 MOVQ 104(SP), SP
174 MOVQ 96(SP), DX
175 get_tls(BP)
176 MOVQ DX, g(BP)
177
Shenghou Maa1778ec2014-07-09 23:55:35 -0400178done:
Alex Brainmana8373472014-03-26 11:13:50 +1100179 // restore registers as required for windows callback
Russ Coxc548cc22014-08-27 14:43:07 -0400180 MOVQ 88(SP), R15
Alex Brainmana8373472014-03-26 11:13:50 +1100181 MOVQ 32(SP), R14
182 MOVQ 40(SP), R13
183 MOVQ 48(SP), R12
184 MOVQ 56(SP), BX
185 MOVQ 64(SP), BP
186 MOVQ 72(SP), SI
187 MOVQ 80(SP), DI
Russ Cox201cfe42014-09-08 16:56:46 -0400188 ADDQ $112, SP
Alex Brainmana8373472014-03-26 11:13:50 +1100189 POPFQ
Russ Cox2d3cc972012-03-12 16:48:16 -0400190
Hector Chu9b011502011-09-03 18:27:16 +1000191 RET
192
Alex Brainmane9ecd4a2014-10-15 11:11:11 +1100193TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
194 MOVQ $runtime·exceptionhandler(SB), AX
195 JMP runtime·sigtramp(SB)
196
197TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
198 MOVQ $runtime·firstcontinuehandler(SB), AX
199 JMP runtime·sigtramp(SB)
200
201TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
202 MOVQ $runtime·lastcontinuehandler(SB), AX
203 JMP runtime·sigtramp(SB)
204
Keith Randall0273dc12013-08-07 12:20:05 -0700205TEXT runtime·ctrlhandler(SB),NOSPLIT,$8
Hector Chu9fd26872011-09-17 17:57:59 +1000206 MOVQ CX, 16(SP) // spill
207 MOVQ $runtime·ctrlhandler1(SB), CX
208 MOVQ CX, 0(SP)
209 CALL runtime·externalthreadhandler(SB)
210 RET
211
Keith Randall0273dc12013-08-07 12:20:05 -0700212TEXT runtime·profileloop(SB),NOSPLIT,$8
Hector Chu9fd26872011-09-17 17:57:59 +1000213 MOVQ $runtime·profileloop1(SB), CX
214 MOVQ CX, 0(SP)
215 CALL runtime·externalthreadhandler(SB)
216 RET
217
Keith Randall0273dc12013-08-07 12:20:05 -0700218TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
Wei Guangjingacfb0a12011-08-18 12:37:42 -0400219 PUSHQ BP
220 MOVQ SP, BP
221 PUSHQ BX
222 PUSHQ SI
223 PUSHQ DI
Wei Guangjing9569c672012-01-09 11:23:07 +1100224 PUSHQ 0x28(GS)
Hector Chu9fd26872011-09-17 17:57:59 +1000225 MOVQ SP, DX
Wei Guangjingacfb0a12011-08-18 12:37:42 -0400226
227 // setup dummy m, g
Keith Randall1dd01632015-01-06 20:38:44 -0800228 SUBQ $m__size, SP // space for M
Hector Chu9fd26872011-09-17 17:57:59 +1000229 MOVQ SP, 0(SP)
Keith Randall1dd01632015-01-06 20:38:44 -0800230 MOVQ $m__size, 8(SP)
Hector Chu9fd26872011-09-17 17:57:59 +1000231 CALL runtime·memclr(SB) // smashes AX,BX,CX
232
Wei Guangjingacfb0a12011-08-18 12:37:42 -0400233 LEAQ m_tls(SP), CX
Wei Guangjing9569c672012-01-09 11:23:07 +1100234 MOVQ CX, 0x28(GS)
Hector Chu9fd26872011-09-17 17:57:59 +1000235 MOVQ SP, BX
Keith Randall1dd01632015-01-06 20:38:44 -0800236 SUBQ $g__size, SP // space for G
Wei Guangjingacfb0a12011-08-18 12:37:42 -0400237 MOVQ SP, g(CX)
Hector Chu9fd26872011-09-17 17:57:59 +1000238 MOVQ SP, m_g0(BX)
239
240 MOVQ SP, 0(SP)
Keith Randall1dd01632015-01-06 20:38:44 -0800241 MOVQ $g__size, 8(SP)
Hector Chu9fd26872011-09-17 17:57:59 +1000242 CALL runtime·memclr(SB) // smashes AX,BX,CX
Keith Randall1dd01632015-01-06 20:38:44 -0800243 LEAQ g__size(SP), BX
Russ Cox89f185f2014-06-26 11:54:39 -0400244 MOVQ BX, g_m(SP)
245
Wei Guangjingacfb0a12011-08-18 12:37:42 -0400246 LEAQ -8192(SP), CX
Russ Cox8ac35be2014-09-09 14:02:37 -0400247 MOVQ CX, (g_stack+stack_lo)(SP)
Alex Brainmanb27c0612014-11-19 11:55:15 +1100248 ADDQ $const__StackGuard, CX
Russ Coxe6d35112015-01-05 16:29:21 +0000249 MOVQ CX, g_stackguard0(SP)
250 MOVQ CX, g_stackguard1(SP)
Russ Cox8ac35be2014-09-09 14:02:37 -0400251 MOVQ DX, (g_stack+stack_hi)(SP)
Wei Guangjingacfb0a12011-08-18 12:37:42 -0400252
Alex Brainman9402e492015-04-14 10:48:05 +1000253 PUSHQ AX // room for return value
Hector Chu9fd26872011-09-17 17:57:59 +1000254 PUSHQ 32(BP) // arg for handler
255 CALL 16(BP)
Wei Guangjingacfb0a12011-08-18 12:37:42 -0400256 POPQ CX
Alex Brainman9402e492015-04-14 10:48:05 +1000257 POPQ AX // pass return value to Windows in AX
Wei Guangjingacfb0a12011-08-18 12:37:42 -0400258
259 get_tls(CX)
260 MOVQ g(CX), CX
Russ Cox8ac35be2014-09-09 14:02:37 -0400261 MOVQ (g_stack+stack_hi)(CX), SP
Wei Guangjing9569c672012-01-09 11:23:07 +1100262 POPQ 0x28(GS)
Wei Guangjingacfb0a12011-08-18 12:37:42 -0400263 POPQ DI
264 POPQ SI
265 POPQ BX
266 POPQ BP
Hector Chu0f5902d2011-08-29 22:12:56 +1000267 RET
Jaroslavas Počepkoc586b5b2011-08-30 22:02:02 +1000268
Russ Cox3c94b1d2014-09-24 19:04:06 -0400269GLOBL runtime·cbctxts(SB), NOPTR, $8
Alex Brainman05a5de32013-06-24 17:17:45 +1000270
Keith Randall0273dc12013-08-07 12:20:05 -0700271TEXT runtime·callbackasm1(SB),NOSPLIT,$0
Jaroslavas Počepkoc586b5b2011-08-30 22:02:02 +1000272 // Construct args vector for cgocallback().
273 // By windows/amd64 calling convention first 4 args are in CX, DX, R8, R9
274 // args from the 5th on are on the stack.
275 // In any case, even if function has 0,1,2,3,4 args, there is reserved
276 // but uninitialized "shadow space" for the first 4 args.
277 // The values are in registers.
Alex Brainman05a5de32013-06-24 17:17:45 +1000278 MOVQ CX, (16+0)(SP)
279 MOVQ DX, (16+8)(SP)
280 MOVQ R8, (16+16)(SP)
281 MOVQ R9, (16+24)(SP)
282
283 // remove return address from stack, we are not returning there
284 MOVQ 0(SP), AX
285 ADDQ $8, SP
286
287 // determine index into runtime·cbctxts table
Russ Cox3e9c7a82014-08-18 22:12:51 -0400288 MOVQ $runtime·callbackasm(SB), DX
289 SUBQ DX, AX
Alex Brainman05a5de32013-06-24 17:17:45 +1000290 MOVQ $0, DX
291 MOVQ $5, CX // divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
Alex Brainman201b1242015-02-17 16:48:31 +1100292 DIVL CX
Alex Brainman05a5de32013-06-24 17:17:45 +1000293
294 // find correspondent runtime·cbctxts table entry
295 MOVQ runtime·cbctxts(SB), CX
296 MOVQ -8(CX)(AX*8), AX
297
298 // extract callback context
Alex Brainmanb27c0612014-11-19 11:55:15 +1100299 MOVQ wincallbackcontext_argsize(AX), DX
300 MOVQ wincallbackcontext_gobody(AX), AX
Jaroslavas Počepkoc586b5b2011-08-30 22:02:02 +1000301
302 // preserve whatever's at the memory location that
303 // the callback will use to store the return value
304 LEAQ 8(SP), CX // args vector, skip return address
305 PUSHQ 0(CX)(DX*1) // store 8 bytes from just after the args array
306 ADDQ $8, DX // extend argsize by size of return value
307
308 // DI SI BP BX R12 R13 R14 R15 registers and DF flag are preserved
309 // as required by windows callback convention.
Jaroslavas Počepkoc586b5b2011-08-30 22:02:02 +1000310 PUSHFQ
311 SUBQ $64, SP
312 MOVQ DI, 56(SP)
313 MOVQ SI, 48(SP)
314 MOVQ BP, 40(SP)
315 MOVQ BX, 32(SP)
316 MOVQ R12, 24(SP)
317 MOVQ R13, 16(SP)
318 MOVQ R14, 8(SP)
319 MOVQ R15, 0(SP)
320
Russ Cox8a1b3d52012-03-08 15:53:11 -0500321 // prepare call stack. use SUBQ to hide from stack frame checks
Russ Cox3d2dfc52013-02-22 16:08:56 -0500322 // cgocallback(Go func, void *frame, uintptr framesize)
Russ Cox8a1b3d52012-03-08 15:53:11 -0500323 SUBQ $24, SP
Alex Brainman05a5de32013-06-24 17:17:45 +1000324 MOVQ DX, 16(SP) // argsize (including return value)
325 MOVQ CX, 8(SP) // callback parameters
326 MOVQ AX, 0(SP) // address of target Go function
Jaroslavas Počepkoc586b5b2011-08-30 22:02:02 +1000327 CLD
Alex Brainman05a5de32013-06-24 17:17:45 +1000328 CALL runtime·cgocallback_gofunc(SB)
Russ Cox8a1b3d52012-03-08 15:53:11 -0500329 MOVQ 0(SP), AX
330 MOVQ 8(SP), CX
331 MOVQ 16(SP), DX
332 ADDQ $24, SP
Jaroslavas Počepkoc586b5b2011-08-30 22:02:02 +1000333
334 // restore registers as required for windows callback
Jaroslavas Počepkoc586b5b2011-08-30 22:02:02 +1000335 MOVQ 0(SP), R15
336 MOVQ 8(SP), R14
337 MOVQ 16(SP), R13
338 MOVQ 24(SP), R12
339 MOVQ 32(SP), BX
340 MOVQ 40(SP), BP
341 MOVQ 48(SP), SI
342 MOVQ 56(SP), DI
343 ADDQ $64, SP
344 POPFQ
345
346 MOVL -8(CX)(DX*1), AX // return value
347 POPQ -8(CX)(DX*1) // restore bytes just after the args
Wei Guangjingf83609f2011-06-29 17:37:56 +1000348 RET
349
Hector Chu0f5902d2011-08-29 22:12:56 +1000350// uint32 tstart_stdcall(M *newm);
Keith Randall0273dc12013-08-07 12:20:05 -0700351TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
Hector Chu0f5902d2011-08-29 22:12:56 +1000352 // CX contains first arg newm
Wei Guangjingf83609f2011-06-29 17:37:56 +1000353 MOVQ m_g0(CX), DX // g
354
Wei Guangjingf83609f2011-06-29 17:37:56 +1000355 // Layout new m scheduler stack on os stack.
356 MOVQ SP, AX
Russ Cox8ac35be2014-09-09 14:02:37 -0400357 MOVQ AX, (g_stack+stack_hi)(DX)
Hector Chu0f5902d2011-08-29 22:12:56 +1000358 SUBQ $(64*1024), AX // stack size
Russ Cox8ac35be2014-09-09 14:02:37 -0400359 MOVQ AX, (g_stack+stack_lo)(DX)
Alex Brainmanb27c0612014-11-19 11:55:15 +1100360 ADDQ $const__StackGuard, AX
Russ Coxe6d35112015-01-05 16:29:21 +0000361 MOVQ AX, g_stackguard0(DX)
362 MOVQ AX, g_stackguard1(DX)
Wei Guangjingf83609f2011-06-29 17:37:56 +1000363
364 // Set up tls.
365 LEAQ m_tls(CX), SI
Wei Guangjing9569c672012-01-09 11:23:07 +1100366 MOVQ SI, 0x28(GS)
Russ Cox89f185f2014-06-26 11:54:39 -0400367 MOVQ CX, g_m(DX)
Wei Guangjingf83609f2011-06-29 17:37:56 +1000368 MOVQ DX, g(SI)
369
370 // Someday the convention will be D is always cleared.
371 CLD
372
Hector Chu0f5902d2011-08-29 22:12:56 +1000373 CALL runtime·stackcheck(SB) // clobbers AX,CX
Russ Coxe6a3e222013-03-01 11:44:43 -0500374 CALL runtime·mstart(SB)
Wei Guangjingf83609f2011-06-29 17:37:56 +1000375
Wei Guangjingf83609f2011-06-29 17:37:56 +1000376 XORL AX, AX // return 0 == success
Wei Guangjingf83609f2011-06-29 17:37:56 +1000377 RET
378
Wei Guangjingf83609f2011-06-29 17:37:56 +1000379// set tls base to DI
Keith Randall0273dc12013-08-07 12:20:05 -0700380TEXT runtime·settls(SB),NOSPLIT,$0
Wei Guangjing9569c672012-01-09 11:23:07 +1100381 MOVQ DI, 0x28(GS)
Wei Guangjingf83609f2011-06-29 17:37:56 +1000382 RET
Alex Brainmanafe0e972012-05-30 15:10:54 +1000383
Alex Brainman45cff652013-07-16 12:36:05 +1000384// Sleep duration is in 100ns units.
Keith Randall0273dc12013-08-07 12:20:05 -0700385TEXT runtime·usleep1(SB),NOSPLIT,$0
Russ Cox25f6b022014-08-27 11:32:17 -0400386 MOVL usec+0(FP), BX
Alex Brainman45cff652013-07-16 12:36:05 +1000387 MOVQ $runtime·usleep2(SB), AX // to hide from 6l
388
389 // Execute call on m->g0 stack, in case we are not actually
390 // calling a system call wrapper, like when running under WINE.
391 get_tls(R15)
392 CMPQ R15, $0
393 JNE 3(PC)
394 // Not a Go-managed thread. Do not switch stack.
Russ Cox8aafb442013-03-07 09:18:48 -0500395 CALL AX
396 RET
397
Russ Cox89f185f2014-06-26 11:54:39 -0400398 MOVQ g(R15), R13
399 MOVQ g_m(R13), R13
Dmitriy Vyukov5e72fae2014-02-12 22:31:36 +0400400
401 // leave pc/sp for cpu profiler
402 MOVQ (SP), R12
403 MOVQ R12, m_libcallpc(R13)
Dmitriy Vyukoveca55f52014-02-14 09:20:51 +0400404 MOVQ g(R15), R12
405 MOVQ R12, m_libcallg(R13)
406 // sp must be the last, because once async cpu profiler finds
407 // all three values to be non-zero, it will use them
Russ Cox25f6b022014-08-27 11:32:17 -0400408 LEAQ usec+0(FP), R12
Dmitriy Vyukov5e72fae2014-02-12 22:31:36 +0400409 MOVQ R12, m_libcallsp(R13)
Dmitriy Vyukov5e72fae2014-02-12 22:31:36 +0400410
411 MOVQ m_g0(R13), R14
Alex Brainman45cff652013-07-16 12:36:05 +1000412 CMPQ g(R15), R14
Russ Coxb55791e2014-10-28 21:50:16 -0400413 JNE switch
Alex Brainman45cff652013-07-16 12:36:05 +1000414 // executing on m->g0 already
415 CALL AX
Russ Coxb55791e2014-10-28 21:50:16 -0400416 JMP ret
Alex Brainman45cff652013-07-16 12:36:05 +1000417
Russ Coxb55791e2014-10-28 21:50:16 -0400418switch:
Alex Brainman45cff652013-07-16 12:36:05 +1000419 // Switch to m->g0 stack and back.
420 MOVQ (g_sched+gobuf_sp)(R14), R14
421 MOVQ SP, -8(R14)
422 LEAQ -8(R14), SP
423 CALL AX
424 MOVQ 0(SP), SP
Dmitriy Vyukov5e72fae2014-02-12 22:31:36 +0400425
Russ Coxb55791e2014-10-28 21:50:16 -0400426ret:
Dmitriy Vyukov5e72fae2014-02-12 22:31:36 +0400427 MOVQ $0, m_libcallsp(R13)
Alex Brainman45cff652013-07-16 12:36:05 +1000428 RET
429
430// Runs on OS stack. duration (in 100ns units) is in BX.
Alex Brainman418b39d2014-07-10 14:23:50 +1000431TEXT runtime·usleep2(SB),NOSPLIT,$16
432 MOVQ SP, AX
433 ANDQ $~15, SP // alignment as per Windows requirement
434 MOVQ AX, 8(SP)
Alex Brainman45cff652013-07-16 12:36:05 +1000435 // Want negative 100ns units.
Russ Cox8aafb442013-03-07 09:18:48 -0500436 NEGQ BX
437 MOVQ SP, R8 // ptime
438 MOVQ BX, (R8)
439 MOVQ $-1, CX // handle
440 MOVQ $0, DX // alertable
Alex Brainmanb27c0612014-11-19 11:55:15 +1100441 MOVQ runtime·_NtWaitForSingleObject(SB), AX
Russ Cox8aafb442013-03-07 09:18:48 -0500442 CALL AX
Alex Brainman418b39d2014-07-10 14:23:50 +1000443 MOVQ 8(SP), SP
Russ Cox8aafb442013-03-07 09:18:48 -0500444 RET
Russ Cox13d0b822014-09-07 23:40:59 -0400445
446// func now() (sec int64, nsec int32)
447TEXT time·now(SB),NOSPLIT,$8-12
448 CALL runtime·unixnano(SB)
449 MOVQ 0(SP), AX
450
451 // generated code for
452 // func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
453 // adapted to reduce duplication
454 MOVQ AX, CX
455 MOVQ $1360296554856532783, AX
456 MULQ CX
457 ADDQ CX, DX
458 RCRQ $1, DX
459 SHRQ $29, DX
460 MOVQ DX, sec+0(FP)
461 IMULQ $1000000000, DX
462 SUBQ DX, CX
463 MOVL CX, nsec+8(FP)
464 RET
465