diff options
Diffstat (limited to 'src/pkg/runtime/sys_windows_386.s')
-rw-r--r-- | src/pkg/runtime/sys_windows_386.s | 182 |
1 files changed, 99 insertions, 83 deletions
diff --git a/src/pkg/runtime/sys_windows_386.s b/src/pkg/runtime/sys_windows_386.s index 206cdccc4..20753638e 100644 --- a/src/pkg/runtime/sys_windows_386.s +++ b/src/pkg/runtime/sys_windows_386.s @@ -3,9 +3,10 @@ // license that can be found in the LICENSE file. #include "zasm_GOOS_GOARCH.h" +#include "../../cmd/ld/textflag.h" // void runtime·asmstdcall(void *c); -TEXT runtime·asmstdcall(SB),7,$0 +TEXT runtime·asmstdcall(SB),NOSPLIT,$0 MOVL c+0(FP), BX // SetLastError(0). @@ -38,27 +39,7 @@ TEXT runtime·asmstdcall(SB),7,$0 RET -TEXT runtime·badcallback(SB),7,$24 - // stderr - MOVL $-12, 0(SP) - MOVL SP, BP - CALL *runtime·GetStdHandle(SB) - MOVL BP, SP - - MOVL AX, 0(SP) // handle - MOVL $runtime·badcallbackmsg(SB), DX // pointer - MOVL DX, 4(SP) - MOVL runtime·badcallbacklen(SB), DX // count - MOVL DX, 8(SP) - LEAL 20(SP), DX // written count - MOVL $0, 0(DX) - MOVL DX, 12(SP) - MOVL $0, 16(SP) // overlapped - CALL *runtime·WriteFile(SB) - MOVL BP, SI - RET - -TEXT runtime·badsignal(SB),7,$24 +TEXT runtime·badsignal2(SB),NOSPLIT,$24 // stderr MOVL $-12, 0(SP) MOVL SP, BP @@ -79,16 +60,16 @@ TEXT runtime·badsignal(SB),7,$24 RET // faster get/set last error -TEXT runtime·getlasterror(SB),7,$0 +TEXT runtime·getlasterror(SB),NOSPLIT,$0 MOVL 0x34(FS), AX RET -TEXT runtime·setlasterror(SB),7,$0 +TEXT runtime·setlasterror(SB),NOSPLIT,$0 MOVL err+0(FP), AX MOVL AX, 0x34(FS) RET -TEXT runtime·sigtramp(SB),7,$28 +TEXT runtime·sigtramp(SB),NOSPLIT,$28 // unwinding? MOVL info+0(FP), CX TESTL $6, 4(CX) // exception flags @@ -106,7 +87,7 @@ TEXT runtime·sigtramp(SB),7,$28 MOVL m(CX), AX CMPL AX, $0 JNE 2(PC) - CALL runtime·badsignal(SB) + CALL runtime·badsignal2(SB) MOVL g(CX), CX MOVL CX, 8(SP) @@ -126,21 +107,21 @@ TEXT runtime·sigtramp(SB),7,$28 sigdone: RET -TEXT runtime·ctrlhandler(SB),7,$0 +TEXT runtime·ctrlhandler(SB),NOSPLIT,$0 PUSHL $runtime·ctrlhandler1(SB) CALL runtime·externalthreadhandler(SB) MOVL 4(SP), CX ADDL $12, SP JMP CX -TEXT runtime·profileloop(SB),7,$0 +TEXT runtime·profileloop(SB),NOSPLIT,$0 PUSHL $runtime·profileloop1(SB) CALL runtime·externalthreadhandler(SB) MOVL 4(SP), CX ADDL $12, SP JMP CX -TEXT runtime·externalthreadhandler(SB),7,$0 +TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0 PUSHL BP MOVL SP, BP PUSHL BX @@ -184,19 +165,16 @@ TEXT runtime·externalthreadhandler(SB),7,$0 POPL BP RET -// Called from dynamic function created by ../thread.c compilecallback, -// running on Windows stack (not Go stack). -// BX, BP, SI, DI registers and DF flag are preserved -// as required by windows callback convention. -// AX = address of go func we need to call -// DX = total size of arguments -// -TEXT runtime·callbackasm+0(SB),7,$0 - // preserve whatever's at the memory location that - // the callback will use to store the return value - LEAL 8(SP), CX - PUSHL 0(CX)(DX*1) - ADDL $4, DX // extend argsize by size of return value +GLOBL runtime·cbctxts(SB), $4 + +TEXT runtime·callbackasm1+0(SB),NOSPLIT,$0 + MOVL 0(SP), AX // will use to find our callback context + + // remove return address from stack, we are not returning there + ADDL $4, SP + + // address to callback parameters into CX + LEAL 4(SP), CX // save registers as required for windows callback PUSHL DI @@ -209,19 +187,51 @@ TEXT runtime·callbackasm+0(SB),7,$0 PUSHL 0(FS) MOVL SP, 0(FS) - // callback parameters - PUSHL DX - PUSHL CX - PUSHL AX + // determine index into runtime·cbctxts table + SUBL $runtime·callbackasm(SB), AX + MOVL $0, DX + MOVL $5, BX // divide by 5 because each call instruction in runtime·callbacks is 5 bytes long + DIVL BX, - CLD + // find correspondent runtime·cbctxts table entry + MOVL runtime·cbctxts(SB), BX + MOVL -4(BX)(AX*4), BX - CALL runtime·cgocallback_gofunc(SB) + // extract callback context + MOVL cbctxt_gobody(BX), AX + MOVL cbctxt_argsize(BX), DX + + // preserve whatever's at the memory location that + // the callback will use to store the return value + PUSHL 0(CX)(DX*1) + + // extend argsize by size of return value + ADDL $4, DX + + // remember how to restore stack on return + MOVL cbctxt_restorestack(BX), BX + PUSHL BX + // call target Go function + PUSHL DX // argsize (including return value) + PUSHL CX // callback parameters + PUSHL AX // address of target Go function + CLD + CALL runtime·cgocallback_gofunc(SB) POPL AX POPL CX POPL DX + // how to restore stack on return + POPL BX + + // return value into AX (as per Windows spec) + // and restore previously preserved value + MOVL -4(CX)(DX*1), AX + POPL -4(CX)(DX*1) + + MOVL BX, CX // cannot use BX anymore + // pop SEH frame POPL 0(FS) POPL BX @@ -232,14 +242,17 @@ TEXT runtime·callbackasm+0(SB),7,$0 POPL SI POPL DI + // remove callback parameters before return (as per Windows spec) + POPL DX + ADDL CX, SP + PUSHL DX + CLD - MOVL -4(CX)(DX*1), AX - POPL -4(CX)(DX*1) RET // void tstart(M *newm); -TEXT runtime·tstart(SB),7,$0 +TEXT runtime·tstart(SB),NOSPLIT,$0 MOVL newm+4(SP), CX // m MOVL m_g0(CX), DX // g @@ -264,7 +277,7 @@ TEXT runtime·tstart(SB),7,$0 RET // uint32 tstart_stdcall(M *newm); -TEXT runtime·tstart_stdcall(SB),7,$0 +TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0 MOVL newm+4(SP), BX PUSHL BX @@ -281,13 +294,13 @@ TEXT runtime·tstart_stdcall(SB),7,$0 RET // setldt(int entry, int address, int limit) -TEXT runtime·setldt(SB),7,$0 +TEXT runtime·setldt(SB),NOSPLIT,$0 MOVL address+4(FP), CX MOVL CX, 0x14(FS) RET // void install_exception_handler() -TEXT runtime·install_exception_handler(SB),7,$0 +TEXT runtime·install_exception_handler(SB),NOSPLIT,$0 get_tls(CX) MOVL m(CX), CX // m @@ -304,7 +317,7 @@ TEXT runtime·install_exception_handler(SB),7,$0 RET // void remove_exception_handler() -TEXT runtime·remove_exception_handler(SB),7,$0 +TEXT runtime·remove_exception_handler(SB),NOSPLIT,$0 get_tls(CX) MOVL m(CX), CX // m @@ -315,28 +328,39 @@ TEXT runtime·remove_exception_handler(SB),7,$0 RET -TEXT runtime·osyield(SB),7,$20 - // Tried NtYieldExecution but it doesn't yield hard enough. - // NtWaitForSingleObject being used here as Sleep(0). - MOVL runtime·NtWaitForSingleObject(SB), AX - MOVL $-1, hi-4(SP) - MOVL $-1, lo-8(SP) - LEAL lo-8(SP), BX - MOVL BX, ptime-12(SP) - MOVL $0, alertable-16(SP) - MOVL $-1, handle-20(SP) - MOVL SP, BP - CALL checkstack4<>(SB) +// Sleep duration is in 100ns units. +TEXT runtime·usleep1(SB),NOSPLIT,$0 + MOVL duration+0(FP), BX + MOVL $runtime·usleep2(SB), AX // to hide from 8l + + // Execute call on m->g0 stack, in case we are not actually + // calling a system call wrapper, like when running under WINE. + get_tls(CX) + CMPL CX, $0 + JNE 3(PC) + // Not a Go-managed thread. Do not switch stack. CALL AX - MOVL BP, SP RET -TEXT runtime·usleep(SB),7,$20 - MOVL runtime·NtWaitForSingleObject(SB), AX - // Have 1us units; need negative 100ns units. - // Assume multiply by 10 will not overflow 32-bit word. - MOVL usec+0(FP), BX - IMULL $10, BX + MOVL m(CX), BP + MOVL m_g0(BP), SI + CMPL g(CX), SI + JNE 3(PC) + // executing on m->g0 already + CALL AX + RET + + // Switch to m->g0 stack and back. + MOVL (g_sched+gobuf_sp)(SI), SI + MOVL SP, -4(SI) + LEAL -4(SI), SP + CALL AX + MOVL 0(SP), SP + RET + +// Runs on OS stack. duration (in 100ns units) is in BX. +TEXT runtime·usleep2(SB),NOSPLIT,$20 + // Want negative 100ns units. NEGL BX MOVL $-1, hi-4(SP) MOVL BX, lo-8(SP) @@ -345,15 +369,7 @@ TEXT runtime·usleep(SB),7,$20 MOVL $0, alertable-16(SP) MOVL $-1, handle-20(SP) MOVL SP, BP - CALL checkstack4<>(SB) + MOVL runtime·NtWaitForSingleObject(SB), AX CALL AX MOVL BP, SP RET - -// This function requires 4 bytes of stack, -// to simulate what calling NtWaitForSingleObject will use. -// (It is just a CALL to the system call dispatch.) -// If the linker okays the call to checkstack4 (a NOSPLIT function) -// then the call to NtWaitForSingleObject is okay too. -TEXT checkstack4<>(SB),7,$4 - RET |