diff options
Diffstat (limited to 'src/runtime/asm_386.s')
-rw-r--r-- | src/runtime/asm_386.s | 94 |
1 files changed, 47 insertions, 47 deletions
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s index fa3b1be339..5cf6827c21 100644 --- a/src/runtime/asm_386.s +++ b/src/runtime/asm_386.s @@ -89,7 +89,7 @@ GLOBL _rt0_386_lib_argc<>(SB),NOPTR, $4 DATA _rt0_386_lib_argv<>(SB)/4, $0 GLOBL _rt0_386_lib_argv<>(SB),NOPTR, $4 -TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME,$0 +TEXT runtime·rt0_go(SB),NOSPLIT|NOFRAME|TOPFRAME,$0 // Copy arguments forward on an even stack. // Users of this function jump to it, they don't call it. MOVL 0(SP), AX @@ -269,35 +269,23 @@ TEXT runtime·asminit(SB),NOSPLIT,$0-0 FLDCW runtime·controlWord64(SB) RET +TEXT runtime·mstart(SB),NOSPLIT|TOPFRAME,$0 + CALL runtime·mstart0(SB) + RET // not reached + /* * go-routine */ -// void gosave(Gobuf*) -// save state in Gobuf; setjmp -TEXT runtime·gosave(SB), NOSPLIT, $0-4 - MOVL buf+0(FP), AX // gobuf - LEAL buf+0(FP), BX // caller's SP - MOVL BX, gobuf_sp(AX) - MOVL 0(SP), BX // caller's PC - MOVL BX, gobuf_pc(AX) - MOVL $0, gobuf_ret(AX) - // Assert ctxt is zero. See func save. - MOVL gobuf_ctxt(AX), BX - TESTL BX, BX - JZ 2(PC) - CALL runtime·badctxt(SB) - get_tls(CX) - MOVL g(CX), BX - MOVL BX, gobuf_g(AX) - RET - // void gogo(Gobuf*) // restore state from Gobuf; longjmp -TEXT runtime·gogo(SB), NOSPLIT, $8-4 +TEXT runtime·gogo(SB), NOSPLIT, $0-4 MOVL buf+0(FP), BX // gobuf MOVL gobuf_g(BX), DX MOVL 0(DX), CX // make sure g != nil + JMP gogo<>(SB) + +TEXT gogo<>(SB), NOSPLIT, $0 get_tls(CX) MOVL DX, g(CX) MOVL gobuf_sp(BX), SP // restore SP @@ -322,7 +310,6 @@ TEXT runtime·mcall(SB), NOSPLIT, $0-4 MOVL BX, (g_sched+gobuf_pc)(AX) LEAL fn+0(FP), BX // caller's SP MOVL BX, (g_sched+gobuf_sp)(AX) - MOVL AX, (g_sched+gobuf_g)(AX) // switch to m->g0 & its stack, call fn MOVL g(DX), BX @@ -371,18 +358,12 @@ TEXT runtime·systemstack(SB), NOSPLIT, $0-4 // switch stacks // save our state in g->sched. Pretend to // be systemstack_switch if the G stack is scanned. - MOVL $runtime·systemstack_switch(SB), (g_sched+gobuf_pc)(AX) - MOVL SP, (g_sched+gobuf_sp)(AX) - MOVL AX, (g_sched+gobuf_g)(AX) + CALL gosave_systemstack_switch<>(SB) // switch to g0 get_tls(CX) MOVL DX, g(CX) MOVL (g_sched+gobuf_sp)(DX), BX - // make it look like mstart called systemstack on g0, to stop traceback - SUBL $4, BX - MOVL $runtime·mstart(SB), DX - MOVL DX, 0(BX) MOVL BX, SP // call target function @@ -457,7 +438,6 @@ TEXT runtime·morestack(SB),NOSPLIT,$0-0 // Set g->sched to context in f. MOVL 0(SP), AX // f's PC MOVL AX, (g_sched+gobuf_pc)(SI) - MOVL SI, (g_sched+gobuf_g)(SI) LEAL 4(SP), AX // f's SP MOVL AX, (g_sched+gobuf_sp)(SI) MOVL DX, (g_sched+gobuf_ctxt)(SI) @@ -477,7 +457,7 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0 JMP runtime·morestack(SB) // reflectcall: call a function with the given argument list -// func call(argtype *_type, f *FuncVal, arg *byte, argsize, retoffset uint32). +// func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs). // we don't have variable-sized frames, so we use a small number // of constant-sized-frame functions to encode a few bits of size in the pc. // Caution: ugly multiline assembly macros in your future! @@ -489,8 +469,8 @@ TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0 JMP AX // Note: can't just "JMP NAME(SB)" - bad inlining results. -TEXT ·reflectcall(SB), NOSPLIT, $0-20 - MOVL argsize+12(FP), CX +TEXT ·reflectcall(SB), NOSPLIT, $0-28 + MOVL frameSize+20(FP), CX DISPATCH(runtime·call16, 16) DISPATCH(runtime·call32, 32) DISPATCH(runtime·call64, 64) @@ -522,11 +502,11 @@ TEXT ·reflectcall(SB), NOSPLIT, $0-20 JMP AX #define CALLFN(NAME,MAXSIZE) \ -TEXT NAME(SB), WRAPPER, $MAXSIZE-20; \ +TEXT NAME(SB), WRAPPER, $MAXSIZE-28; \ NO_LOCAL_POINTERS; \ /* copy arguments to stack */ \ - MOVL argptr+8(FP), SI; \ - MOVL argsize+12(FP), CX; \ + MOVL stackArgs+8(FP), SI; \ + MOVL stackArgsSize+12(FP), CX; \ MOVL SP, DI; \ REP;MOVSB; \ /* call function */ \ @@ -535,10 +515,10 @@ TEXT NAME(SB), WRAPPER, $MAXSIZE-20; \ PCDATA $PCDATA_StackMapIndex, $0; \ CALL AX; \ /* copy return values back */ \ - MOVL argtype+0(FP), DX; \ - MOVL argptr+8(FP), DI; \ - MOVL argsize+12(FP), CX; \ - MOVL retoffset+16(FP), BX; \ + MOVL stackArgsType+0(FP), DX; \ + MOVL stackArgs+8(FP), DI; \ + MOVL stackArgsSize+12(FP), CX; \ + MOVL stackRetOffset+16(FP), BX; \ MOVL SP, SI; \ ADDL BX, DI; \ ADDL BX, SI; \ @@ -550,11 +530,12 @@ TEXT NAME(SB), WRAPPER, $MAXSIZE-20; \ // separate function so it can allocate stack space for the arguments // to reflectcallmove. It does not follow the Go ABI; it expects its // arguments in registers. -TEXT callRet<>(SB), NOSPLIT, $16-0 +TEXT callRet<>(SB), NOSPLIT, $20-0 MOVL DX, 0(SP) MOVL DI, 4(SP) MOVL SI, 8(SP) MOVL CX, 12(SP) + MOVL $0, 16(SP) CALL runtime·reflectcallmove(SB) RET @@ -619,26 +600,45 @@ TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8 MOVL 0(DX), BX JMP BX // but first run the deferred function -// Save state of caller into g->sched. -TEXT gosave<>(SB),NOSPLIT,$0 +// Save state of caller into g->sched, +// but using fake PC from systemstack_switch. +// Must only be called from functions with no locals ($0) +// or else unwinding from systemstack_switch is incorrect. +TEXT gosave_systemstack_switch<>(SB),NOSPLIT,$0 PUSHL AX PUSHL BX get_tls(BX) MOVL g(BX), BX LEAL arg+0(FP), AX MOVL AX, (g_sched+gobuf_sp)(BX) - MOVL -4(AX), AX + MOVL $runtime·systemstack_switch(SB), AX MOVL AX, (g_sched+gobuf_pc)(BX) MOVL $0, (g_sched+gobuf_ret)(BX) // Assert ctxt is zero. See func save. MOVL (g_sched+gobuf_ctxt)(BX), AX TESTL AX, AX JZ 2(PC) - CALL runtime·badctxt(SB) + CALL runtime·abort(SB) POPL BX POPL AX RET +// func asmcgocall_no_g(fn, arg unsafe.Pointer) +// Call fn(arg) aligned appropriately for the gcc ABI. +// Called on a system stack, and there may be no g yet (during needm). +TEXT ·asmcgocall_no_g(SB),NOSPLIT,$0-8 + MOVL fn+0(FP), AX + MOVL arg+4(FP), BX + MOVL SP, DX + SUBL $32, SP + ANDL $~15, SP // alignment, perhaps unnecessary + MOVL DX, 8(SP) // save old SP + MOVL BX, 0(SP) // first argument in x86-32 ABI + CALL AX + MOVL 8(SP), DX + MOVL DX, SP + RET + // func asmcgocall(fn, arg unsafe.Pointer) int32 // Call fn(arg) on the scheduler stack, // aligned appropriately for the gcc ABI. @@ -663,7 +663,7 @@ TEXT ·asmcgocall(SB),NOSPLIT,$0-12 JEQ noswitch CMPL DI, m_gsignal(BP) JEQ noswitch - CALL gosave<>(SB) + CALL gosave_systemstack_switch<>(SB) get_tls(CX) MOVL SI, g(CX) MOVL (g_sched+gobuf_sp)(SI), SP @@ -1311,7 +1311,7 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$0 // The top-most function running on a goroutine // returns to goexit+PCQuantum. -TEXT runtime·goexit(SB),NOSPLIT,$0-0 +TEXT runtime·goexit(SB),NOSPLIT|TOPFRAME,$0-0 BYTE $0x90 // NOP CALL runtime·goexit1(SB) // does not return // traceback from goexit1 must hit code range of goexit |