[MLton-commit] r4718
Matthew Fluet
fluet at mlton.org
Thu Oct 5 09:41:30 PDT 2006
Moved the jumpToSML/returnToC code from x86-main.h to x86-codegen.fun.
This code essentially establishes the interface by which C jumps into
SML code (both initially and for exported SML functions) and by which
SML returns to C (for exported SML functions). The key property is
that all C activation frames must be accounted for on the C stack.
Each time C jumps to SML via jumpToSML, the current C stack pointer
is saved for C calls from SML. Additionally, we ensure that the saved
C stack pointer is 16-byte aligned.
Previously, this logic was handled in x86-main.h via inline assembly.
This had a number of disadvantages:
1. We couldn't be sure of what gcc was doing with %esp before the
inline assembly began. In fact, we couldn't be sure that %esp
necessarily pointed to the top of the C stack.
2. We needed extra logic from CPP and from MLton_main arguments to
determine whether or not %esp was reserved for sigstack handling and
whether or not extra "_" were required by assembly labels.
Moving the definition of this code to x86-codegen.fun solves these
problems:
1. Since we control the entire execution, we know that %esp is
16-aligned on entry (modulo the return address pushed by the call
instruction) and can maintain this property easily.
2. We can save temporaries in the C stack frame corresponding to the
call to MLton_jumpToC.
3. We know whether or not to reserve %esp and whether or not labels
need an extra "_".
The downside is that writing out the assembly via the datatype
interface is much more verbose.
----------------------------------------------------------------------
U mlton/trunk/include/x86-main.h
U mlton/trunk/mlton/codegen/x86-codegen/x86-codegen.fun
U mlton/trunk/mlton/codegen/x86-codegen/x86-mlton-basic.sig
----------------------------------------------------------------------
Modified: mlton/trunk/include/x86-main.h
===================================================================
--- mlton/trunk/include/x86-main.h 2006-10-05 01:37:54 UTC (rev 4717)
+++ mlton/trunk/include/x86-main.h 2006-10-05 16:41:15 UTC (rev 4718)
@@ -50,63 +50,12 @@
#define DEBUG_X86CODEGEN FALSE
#endif
-#if (defined (__CYGWIN__) || defined (__Darwin__) || defined (__MSVCRT__))
-#define ReturnToC "_Thread_returnToC"
-#elif (defined (__FreeBSD__) || defined (__linux__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__sun__))
-#define ReturnToC "Thread_returnToC"
-#else
-#error ReturnToC not defined
-#endif
-
static Word32 returnAddressToFrameIndex (Word32 w) {
return *((Word32*)(w - sizeof(Word32)));
}
-#define Main(al, mg, mfs, mmc, pk, ps, ml, reserveEsp) \
-void MLton_jumpToSML (pointer jump) { \
- Word c_stackPLast; \
- Word c_stackPLastTrue; \
- \
- if (DEBUG_X86CODEGEN) \
- fprintf (stderr, "MLton_jumpToSML(0x%08x) starting\n", (uint)jump); \
- c_stackPLast = c_stackP; \
- c_stackPLastTrue = c_stackPTrue; \
- if (reserveEsp) \
- __asm__ __volatile__ \
- ("pusha\n\t" \
- "movl %%esp,%0\n\t" \
- "andl $-16,%%esp\n\t" \
- "movl %%esp,%1\n\t" \
- "movl %2,%%ebp\n\t" \
- "movl %3,%%edi\n\t" \
- "jmp *%4\n" \
- ".global "ReturnToC"\n"ReturnToC":\n\t" \
- "movl %0,%%esp\n\t" \
- "popa\n" \
- : "=o" (c_stackPTrue), "=o" (c_stackP) \
- : "o" (gcState.stackTop), "o" (gcState.frontier), "r" (jump) \
- ); \
- else \
- __asm__ __volatile__ \
- ("pusha\n\t" \
- "movl %%esp,%0\n\t" \
- "andl $-16,%%esp\n\t" \
- "movl %%esp,%1\n\t" \
- "movl %2,%%ebp\n\t" \
- "movl %3,%%esp\n\t" \
- "jmp *%4\n" \
- ".global "ReturnToC"\n"ReturnToC":\n\t" \
- "movl %0,%%esp\n\t" \
- "popa\n" \
- : "=o" (c_stackPTrue), "=o" (c_stackP) \
- : "o" (gcState.stackTop), "o" (gcState.frontier), "r" (jump) \
- ); \
- c_stackP = c_stackPLast; \
- c_stackPTrue = c_stackPLastTrue; \
- if (DEBUG_X86CODEGEN) \
- fprintf (stderr, "MLton_jumpToSML(0x%08x) done\n", (uint)jump); \
- return; \
-} \
+#define Main(al, mg, mfs, mmc, pk, ps, ml) \
+void MLton_jumpToSML (pointer jump); \
void MLton_callFromC () { \
pointer jump; \
GC_state s; \
Modified: mlton/trunk/mlton/codegen/x86-codegen/x86-codegen.fun
===================================================================
--- mlton/trunk/mlton/codegen/x86-codegen/x86-codegen.fun 2006-10-05 01:37:54 UTC (rev 4717)
+++ mlton/trunk/mlton/codegen/x86-codegen/x86-codegen.fun 2006-10-05 16:41:15 UTC (rev 4718)
@@ -62,12 +62,6 @@
structure x86Validate
= x86Validate (structure x86 = x86)
- structure C =
- struct
- val truee = "TRUE"
- val falsee = "FALSE"
- end
-
open x86
fun output {program as Machine.Program.T {chunks, frameLayouts, handlesSignals,
main, ...},
@@ -137,7 +131,7 @@
then String.dropPrefix (mainLabel, 1)
else mainLabel
in
- [mainLabel, if reserveEsp then C.truee else C.falsee]
+ [mainLabel]
end
fun declareLocals () =
List.foreach
@@ -179,6 +173,174 @@
x86.Assembly.label x86MLton.fileNameLabel,
x86.Assembly.pseudoop_string [file]]
+ fun outputJumpToSML print =
+ let
+ val jumpToSML = x86.Label.fromString "MLton_jumpToSML"
+ val returnToC = x86.Label.fromString "Thread_returnToC"
+ val {frontierReg, stackTopReg} =
+ if reserveEsp
+ then {frontierReg = x86.Register.edi,
+ stackTopReg = x86.Register.ebp}
+ else {frontierReg = x86.Register.esp,
+ stackTopReg = x86.Register.ebp}
+ val asm =
+ [
+ x86.Assembly.pseudoop_text (),
+ x86.Assembly.pseudoop_p2align
+ (x86.Immediate.const_int 4, NONE, NONE),
+ x86.Assembly.pseudoop_global jumpToSML,
+ x86.Assembly.label jumpToSML,
+ x86.Assembly.instruction_binal
+ {oper = x86.Instruction.SUB,
+ src = x86.Operand.immediate_const_int 28,
+ dst = x86.Operand.register x86.Register.esp,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 32),
+ base = SOME x86.Register.esp,
+ index= NONE, scale = NONE},
+ dst = x86.Operand.register x86.Register.eax,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = x86.Operand.register x86.Register.ebp,
+ dst = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 24),
+ base = SOME x86.Register.esp,
+ index= NONE, scale = NONE},
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = x86.Operand.register x86.Register.ebx,
+ dst = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 20),
+ base = SOME x86.Register.esp,
+ index= NONE, scale = NONE},
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = x86.Operand.register x86.Register.edi,
+ dst = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 16),
+ base = SOME x86.Register.esp,
+ index= NONE, scale = NONE},
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = x86.Operand.register x86.Register.esi,
+ dst = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 12),
+ base = SOME x86.Register.esp,
+ index = NONE, scale = NONE},
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.label x86MLton.c_stackP),
+ base = NONE, index = NONE, scale = NONE},
+ dst = x86.Operand.register x86.Register.ebx,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = x86.Operand.register x86.Register.ebx,
+ dst = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 8),
+ base = SOME x86.Register.esp,
+ index = NONE, scale = NONE},
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = x86.Operand.register x86.Register.esp,
+ dst = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.label x86MLton.c_stackP),
+ base = NONE, index = NONE, scale = NONE},
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = (x86.Operand.address o x86.Address.T)
+ {disp = (SOME o x86.Immediate.binexp)
+ {oper = x86.Immediate.Addition,
+ exp1 = x86.Immediate.label x86MLton.gcState_label,
+ exp2 = x86.Immediate.const_int
+ (Bytes.toInt
+ (Machine.Runtime.GCField.offset
+ Machine.Runtime.GCField.StackTop))},
+ base = NONE, index = NONE, scale = NONE},
+ dst = x86.Operand.register stackTopReg,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = (x86.Operand.address o x86.Address.T)
+ {disp = (SOME o x86.Immediate.binexp)
+ {oper = x86.Immediate.Addition,
+ exp1 = x86.Immediate.label x86MLton.gcState_label,
+ exp2 = x86.Immediate.const_int
+ (Bytes.toInt
+ (Machine.Runtime.GCField.offset
+ Machine.Runtime.GCField.Frontier))},
+ base = NONE, index = NONE, scale = NONE},
+ dst = x86.Operand.register frontierReg,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_jmp
+ {target = x86.Operand.register x86.Register.eax,
+ absolute = true},
+ x86.Assembly.pseudoop_p2align
+ (x86.Immediate.const_int 4, NONE, NONE),
+ x86.Assembly.pseudoop_global returnToC,
+ x86.Assembly.label returnToC,
+ x86.Assembly.instruction_mov
+ {src = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.label x86MLton.c_stackP),
+ base = NONE, index = NONE, scale = NONE},
+ dst = x86.Operand.register x86.Register.esp,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 8),
+ base = SOME x86.Register.esp,
+ index = NONE, scale = NONE},
+ dst = x86.Operand.register x86.Register.ebx,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = x86.Operand.register x86.Register.ebx,
+ dst = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.label x86MLton.c_stackP),
+ base = NONE, index = NONE, scale = NONE},
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 12),
+ base = SOME x86.Register.esp,
+ index = NONE, scale = NONE},
+ dst = x86.Operand.register x86.Register.esi,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 16),
+ base = SOME x86.Register.esp,
+ index = NONE, scale = NONE},
+ dst = x86.Operand.register x86.Register.edi,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 20),
+ base = SOME x86.Register.esp,
+ index = NONE, scale = NONE},
+ dst = x86.Operand.register x86.Register.ebx,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_mov
+ {src = (x86.Operand.address o x86.Address.T)
+ {disp = SOME (x86.Immediate.const_int 24),
+ base = SOME x86.Register.esp,
+ index = NONE, scale = NONE},
+ dst = x86.Operand.register x86.Register.ebp,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_binal
+ {oper = x86.Instruction.ADD,
+ src = x86.Operand.immediate_const_int 28,
+ dst = x86.Operand.register x86.Register.esp,
+ size = x86.Size.LONG},
+ x86.Assembly.instruction_ret {src = NONE}
+ ]
+ in
+ List.foreach
+ (asm,
+ fn asm => (Layout.print(Assembly.layout asm, print);
+ print "\n"))
+ end
+
val liveInfo = x86Liveness.LiveInfo.newLiveInfo ()
val jumpInfo = x86JumpInfo.newJumpInfo ()
@@ -194,6 +356,11 @@
val isMain
= Machine.ChunkLabel.equals(#chunkLabel main, chunkLabel)
+ val ()
+ = if isMain
+ then outputJumpToSML print
+ else ()
+
val {chunk}
= x86Translate.translateChunk
{chunk = chunk,
@@ -243,7 +410,7 @@
in
List.fold
(validated_assembly,
- 0,
+ if isMain then 30 else 0,
fn (block, n)
=> List.fold
(block,
Modified: mlton/trunk/mlton/codegen/x86-codegen/x86-mlton-basic.sig
===================================================================
--- mlton/trunk/mlton/codegen/x86-codegen/x86-mlton-basic.sig 2006-10-05 01:37:54 UTC (rev 4717)
+++ mlton/trunk/mlton/codegen/x86-codegen/x86-mlton-basic.sig 2006-10-05 16:41:15 UTC (rev 4718)
@@ -78,6 +78,7 @@
end
(* CStack locations *)
+ val c_stackP : x86.Label.t
val c_stackPContents : x86.MemLoc.t
val c_stackPContentsOperand : x86.Operand.t
val c_stackPDerefOperand : x86.Operand.t
More information about the MLton-commit
mailing list