diff options
Diffstat (limited to 'src/pkg/runtime/windows/386/sys.s')
-rw-r--r-- | src/pkg/runtime/windows/386/sys.s | 157 |
1 files changed, 82 insertions, 75 deletions
diff --git a/src/pkg/runtime/windows/386/sys.s b/src/pkg/runtime/windows/386/sys.s index e36ef53e0..7f99b34de 100644 --- a/src/pkg/runtime/windows/386/sys.s +++ b/src/pkg/runtime/windows/386/sys.s @@ -4,105 +4,112 @@ #include "386/asm.h" -TEXT get_kernel_module(SB),7,$0 - MOVL 0x30(FS), AX // get PEB - MOVL 0x0c(AX), AX // get PEB_LDR_DATA - MOVL 0x1c(AX), AX // get init order module list - MOVL (AX), AX // get next entry (kernel module) - MOVL 0x08(AX), AX // get base of module - RET - -// void *stdcall_raw(void *fn, ...); -// Call fn with stdcall calling convention. -// fn parameters are on stack. -TEXT stdcall_raw(SB),7,$0 - get_tls(CX) - MOVL m(CX), CX - POPL m_return_address(CX) // save return address - POPL AX // first arg is function pointer - MOVL SP, m_stack_pointer(CX) // save stack pointer - CALL AX - get_tls(CX) - MOVL m(CX), CX - MOVL m_stack_pointer(CX), SP - PUSHL AX - PUSHL m_return_address(CX) - RET +// void *stdcall_raw(void *fn, int32 count, uintptr *args) +TEXT runtime·stdcall_raw(SB),7,$4 + // Copy arguments from stack. + MOVL fn+0(FP), AX + MOVL count+4(FP), CX // words + MOVL args+8(FP), BP -// void syscall(StdcallParams *p); -// Call p.fn syscall + GetLastError on os stack. -TEXT syscall(SB),7,$16 - MOVL p+0(FP), AX - MOVL SP, CX - - // Figure out if we need to switch to m->g0 stack. + // Switch to m->g0 if needed. get_tls(DI) MOVL m(DI), DX + MOVL g(DI), SI + MOVL SI, 0(SP) // save g + MOVL SP, m_gostack(DX) // save SP MOVL m_g0(DX), SI CMPL g(DI), SI - JEQ 2(PC) + JEQ 3(PC) MOVL (m_sched+gobuf_sp)(DX), SP - - // Now on a scheduling stack (an os stack). - MOVL g(DI), BP - MOVL BP, 8(SP) MOVL SI, g(DI) - MOVL CX, 4(SP) - MOVL AX, 0(SP) - CALL call_syscall(SB) - - // Back; switch to original g and stack, re-establish - // "DF is clear" invariant. + + // Copy args to new stack. + SUBL $(10*4), SP // padding + MOVL CX, BX + SALL $2, BX + SUBL BX, SP // room for args + MOVL SP, DI + MOVL BP, SI CLD + REP; MOVSL + + // Call stdcall function. + CALL AX + + // Restore original SP, g. get_tls(DI) - MOVL 8(SP), SI + MOVL m(DI), DX + MOVL m_gostack(DX), SP // restore SP + MOVL 0(SP), SI // restore g MOVL SI, g(DI) - MOVL 4(SP), SP - RET -TEXT threadstart(SB),7,$0 - MOVL 4(SP), AX // threadstart param - MOVL 0(AX), BX // newosproc arg stack - MOVL 0(BX), CX // m - MOVL 4(BX), DX // g + // Someday the convention will be D is always cleared. + CLD + + RET + +// void tstart(M *newm); +TEXT runtime·tstart(SB),7,$0 + MOVL newm+4(SP), CX // m + MOVL m_g0(CX), DX // g + + MOVL SP, DI // remember stack - // set up tls + // Layout new m scheduler stack on os stack. + MOVL SP, AX + SUBL $256, AX // just some space for ourselves + MOVL AX, g_stackbase(DX) + SUBL $8192, AX // stack size + MOVL AX, g_stackguard(DX) + + // Set up tls. LEAL m_tls(CX), SI MOVL SI, 0x2c(FS) MOVL CX, m(SI) MOVL DX, g(SI) - MOVL SP, m_os_stack_pointer(CX) - - PUSHL 8(BX) // stk - PUSHL 12(BX) // fn - PUSHL 4(AX) // event_handle - - // signal that we're done with thread args - MOVL SetEvent(SB), BX - CALL BX // SetEvent(event_handle) - POPL BX // fn - POPL SP // stk - - CALL stackcheck(SB) // clobbers AX,CX - CALL BX // fn() - - // cleanup stack before returning as we are stdcall - get_tls(CX) - MOVL m(CX), CX - MOVL m_os_stack_pointer(CX), SP - POPL AX // return address - MOVL AX, (SP) - XORL AX, AX + + // Use scheduler stack now. + MOVL g_stackbase(DX), SP + + // Someday the convention will be D is always cleared. + CLD + + PUSHL DI // original stack + + CALL runtime·stackcheck(SB) // clobbers AX,CX + + CALL runtime·mstart(SB) + + POPL DI // original stack + MOVL DI, SP + + RET + +// uint32 tstart_stdcall(M *newm); +TEXT runtime·tstart_stdcall(SB),7,$0 + MOVL newm+4(SP), BX + + PUSHL BX + CALL runtime·tstart(SB) + POPL BX + + // Adjust stack for stdcall to return properly. + MOVL (SP), AX // save return address + ADDL $4, SP // remove single parameter + MOVL AX, (SP) // restore return address + + XORL AX, AX // return 0 == success + RET // setldt(int entry, int address, int limit) -TEXT setldt(SB),7,$0 +TEXT runtime·setldt(SB),7,$0 MOVL address+4(FP), CX MOVL CX, 0x2c(FS) RET // for now, return 0,0. only used for internal performance monitoring. -TEXT gettime(SB),7,$0 +TEXT runtime·gettime(SB),7,$0 MOVL sec+0(FP), DI MOVL $0, (DI) MOVL $0, 4(DI) // zero extend 32 -> 64 bits |