github.com/m10x/go/src@v0.0.0-20220112094212-ba61592315da/runtime/sys_windows_386.s (about) 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