x86 backend update
Matthew Fluet
fluet@research.nj.nec.com
Thu, 29 Jun 2000 15:20:14 -0400 (EDT)
Well, I'm still a bit away from spitting out code ready for the assembler,
but I think I've got a good ammount of the framework down. Currently, I've
written (most of) the translation from the MachineOutput IL to the
pseudo-assembly IL. The pseudo-assembly uses x86 instructions, but
removes all restrictions on source and destination locations. So, for
right now, almost everything looks like an immediate value or an abstract
memory location. For example
RI(2) = Int_sub(SI(4), 1);
is translated into
# begin applyPrim(Int_sub)
movl MEM(l)[MEM(l)[stackTop]+4],MEM(l)[(localI+(2*4))]
subl $1,MEM(l)[(localI+(2*4))]
# end applyPrim(Int_sub)
The idea is to translate the "C-registers" into a set of static memory
locations. Hence, RI(2) => MEM(l)[(localI+(2*4))] where localI a label
in the data segment marking the beginning of space allocated for integer
"C-registers". Hence, localI+(2*4) is the address of the 2nd such local.
Similarly with SI(4), but stackTop is the label for the memory location
which will hold the stack pointer, so the nested MEM's.
The next step will be to crawl over the assembly instructions and enforce
the x86 restrictions. Some MEM's will be turned into appropriate
addressing modes, some will need to be expanded into a set of instructions
to do the appropriate dereferencing. This is where we can be more
aggressive later on and try to reduce the memory traffic if that is a
factor.
Then I'll start working on modifying the existing runtime system. Ror a
first pass, I'm planning on dumping both a "C" stub file which will
probably do a lot of the setup work, and include a main function that will
jump to the appropriate assembly label for the beginning of the ML
program. Later on, we should be able to migrate almost everything into
the assembly file and hopefully we can get by without the need for a
dynamically created .c file for each program.
For right now, I'm trying to get by without floating point support. I'd
like to try to get this working before tackling those issues.
Anyways, here's what's being output for a simple fib program. You can see
the framework for limitChecks, invoking the runtime system, FF calls, and
some of the primitives. It's heavily commented, but it's useful for
distinguishing sections of the code.
# begin program
# begin chunk: Ch_2
# begin block: initGlobals
initGlobals_0:
# begin limitCheck
movl MEM(l)[frontier],MEM(l)[limitCheckTemp]
addl $8,MEM(l)[limitCheckTemp]
cmpl MEM(l)[limitCheckTemp],MEM(l)[limit]
jle skipLimitCheck_0
doLimitCheck_0:
# begin invokeRuntime
addl $4,MEM(l)[stackTop]
movl $L_10,MEM(l)[MEM(l)[stackTop]+0]
# begin applyFF
movl MEM(l)[c_stackP],%esp
movl MEM(l)[c_frameP],%ebp
pushl $0
pushl $8
pushl $gcState
call GC_gc
# end applyFF
jmp *MEM(l)[MEM(l)[stackTop]+0]
L_10:
subl $4,MEM(l)[stackTop]
# end invokeRuntime
skipLimitCheck_0:
# end limitCheck
# begin Statement.Allocate
movl $0x80008000,MEM(l)[MEM(l)[frontier]+0]
movl MEM(l)[frontier],MEM(l)[(localP+(2*4))]
addl $4,MEM(l)[(localP+(2*4))]
movl $0,MEM(l)[MEM(l)[frontier]+4]
addl $8,MEM(l)[frontier]
# end Statement.Allocate
# begin Jump
jmp main_0
# end Jump
# end block: initGlobals
# end chunk: Ch_2
# begin chunk: Ch_1
# begin block: main_0
main_0:
# begin limitCheck
cmpl MEM(l)[stackTop],MEM(l)[stackLimit]
jge doLimitCheck_1
movl MEM(l)[frontier],MEM(l)[limitCheckTemp]
addl $0,MEM(l)[limitCheckTemp]
cmpl MEM(l)[limitCheckTemp],MEM(l)[limit]
jle skipLimitCheck_1
doLimitCheck_1:
# begin invokeRuntime
addl $12,MEM(l)[stackTop]
movl $L_11,MEM(l)[MEM(l)[stackTop]+0]
# begin applyFF
movl MEM(l)[c_stackP],%esp
movl MEM(l)[c_frameP],%ebp
pushl $0
pushl $0
pushl $gcState
call GC_gc
# end applyFF
jmp *MEM(l)[MEM(l)[stackTop]+0]
L_11:
subl $12,MEM(l)[stackTop]
# end invokeRuntime
skipLimitCheck_1:
# end limitCheck
# begin Statement.Move
movl $L_12,MEM(l)[MEM(l)[stackTop]+4]
# end Statement.Move
# begin Statement.SaveExnStack
movl MEM(l)[exnStack],MEM(l)[MEM(l)[stackTop]+8]
movl MEM(l)[stackTop],MEM(l)[exnStack]
addl $4,MEM(l)[exnStack]
subl MEM(l)[stackBottom],MEM(l)[exnStack]
# end Statement.SaveExnStack
# begin Statement.Move
movl $1,MEM(l)[MEM(l)[(localP+(2*4))]+0]
# end Statement.Move
# begin Statement.Move
movl $20,MEM(l)[MEM(l)[stackTop]+16]
# end Statement.Move
# begin Statement.Push
addl $12,MEM(l)[stackTop]
# end Statement.Push
# begin Statement.Move
movl $L_13,MEM(l)[MEM(l)[stackTop]+0]
# end Statement.Move
# begin Jump
jmp fib_0
# end Jump
# end block: main_0
# begin block: main_0
L_4:
# begin Statement.Assign
# begin applyPrim(printf)
# begin applyFF
movl MEM(l)[c_stackP],%esp
movl MEM(l)[c_frameP],%ebp
pushl MEM(l)[MEM(l)[stackTop]+12]
pushl MEM(l)[(localP+(0*4))]
call printf
movl %eax,MEM(l)[(localI+(0*4))]
# end applyFF
# end applyPrim(printf)
# end Statement.Assign
# begin Statement.SideEffect
# begin applyPrim(MLton_halt)
# begin applyFF
movl MEM(l)[c_stackP],%esp
movl MEM(l)[c_frameP],%ebp
pushl $0
call MLton_halt
# end applyFF
# end applyPrim(MLton_halt)
# end Statement.SideEffect
# begin Jump
jmp L_0
# end Jump
# end block: main_0
# begin block: main_0
L_13:
# begin Statement.Push
addl $-12,MEM(l)[stackTop]
# end Statement.Push
# begin Statement.Move
movl MEM(l)[MEM(l)[stackTop]+16],MEM(l)[MEM(l)[stackTop]+12]
# end Statement.Move
# begin Jump
jmp L_4
# end Jump
# end block: main_0
# begin block: main_0
L_0:
# begin Statement.RestoreExnStack
movl MEM(l)[MEM(l)[stackTop]+8],MEM(l)[exnStack]
# end Statement.RestoreExnStack
# begin Statement.Move
movl MEM(l)[MEM(l)[(localP+(2*4))]+0],MEM(l)[(localI+(0*4))]
# end Statement.Move
# begin Switch
testl MEM(l)[(localI+(0*4))],MEM(l)[(localI+(0*4))]
jz L_2
jmp L_1
# end Switch
# end block: main_0
# begin block: main_0
L_2:
# begin Statement.SideEffect
# begin applyPrim(MLton_bug)
# begin applyFF
movl MEM(l)[c_stackP],%esp
movl MEM(l)[c_frameP],%ebp
pushl MEM(l)[(localP+(1*4))]
call MLton_bug
# end applyFF
# end applyPrim(MLton_bug)
# end Statement.SideEffect
# begin Return
jmp *MEM(l)[MEM(l)[stackTop]+0]
# end Return
# end block: main_0
# begin block: main_0
L_1:
# begin Statement.SideEffect
# begin applyPrim(MLton_halt)
# begin applyFF
movl MEM(l)[c_stackP],%esp
movl MEM(l)[c_frameP],%ebp
pushl $1
call MLton_halt
# end applyFF
# end applyPrim(MLton_halt)
# end Statement.SideEffect
# begin Raise
movl MEM(l)[stackBottom],MEM(l)[stackTop]
addl MEM(l)[exnStack],MEM(l)[stackTop]
jmp *MEM(l)[MEM(l)[stackTop]+0]
# end Raise
# end block: main_0
# begin block: main_0
L_12:
# begin Statement.Push
addl $-4,MEM(l)[stackTop]
# end Statement.Push
# begin Jump
jmp L_0
# end Jump
# end block: main_0
# end chunk: Ch_1
# begin chunk: Ch_0
# begin block: fib_0
fib_0:
# begin limitCheck
cmpl MEM(l)[stackTop],MEM(l)[stackLimit]
jge doLimitCheck_2
movl MEM(l)[frontier],MEM(l)[limitCheckTemp]
addl $0,MEM(l)[limitCheckTemp]
cmpl MEM(l)[limitCheckTemp],MEM(l)[limit]
jle skipLimitCheck_2
doLimitCheck_2:
# begin invokeRuntime
addl $8,MEM(l)[stackTop]
movl $L_14,MEM(l)[MEM(l)[stackTop]+0]
# begin applyFF
movl MEM(l)[c_stackP],%esp
movl MEM(l)[c_frameP],%ebp
pushl $0
pushl $0
pushl $gcState
call GC_gc
# end applyFF
jmp *MEM(l)[MEM(l)[stackTop]+0]
L_14:
subl $8,MEM(l)[stackTop]
# end invokeRuntime
skipLimitCheck_2:
# end limitCheck
# begin Statement.Assign
# begin applyPrim(MLton_eq)
cmpl MEM(l)[MEM(l)[stackTop]+4],$0
sete MEM(l)[(localI+(0*4))]
# end applyPrim(MLton_eq)
# end Statement.Assign
# begin Switch
testl MEM(l)[(localI+(0*4))],MEM(l)[(localI+(0*4))]
jz L_15
jmp L_16
# end Switch
# end block: fib_0
# begin block: fib_0
L_15:
# begin Statement.Assign
# begin applyPrim(MLton_eq)
cmpl MEM(l)[MEM(l)[stackTop]+4],$1
sete MEM(l)[(localI+(1*4))]
# end applyPrim(MLton_eq)
# end Statement.Assign
# begin Switch
testl MEM(l)[(localI+(1*4))],MEM(l)[(localI+(1*4))]
jz L_17
jmp L_18
# end Switch
# end block: fib_0
# begin block: fib_0
L_17:
# begin Statement.Assign
# begin applyPrim(Int_sub)
movl MEM(l)[MEM(l)[stackTop]+4],MEM(l)[(localI+(2*4))]
subl $1,MEM(l)[(localI+(2*4))]
# end applyPrim(Int_sub)
# end Statement.Assign
# begin Statement.Move
movl MEM(l)[(localI+(2*4))],MEM(l)[MEM(l)[stackTop]+12]
# end Statement.Move
# begin Statement.Push
addl $8,MEM(l)[stackTop]
# end Statement.Push
# begin Statement.Move
movl $L_19,MEM(l)[MEM(l)[stackTop]+0]
# end Statement.Move
# begin Jump
jmp fib_0
# end Jump
# end block: fib_0
# begin block: fib_0
L_20:
# begin Statement.Assign
# begin applyPrim(Int_sub)
movl MEM(l)[MEM(l)[stackTop]+4],MEM(l)[(localI+(3*4))]
subl $2,MEM(l)[(localI+(3*4))]
# end applyPrim(Int_sub)
# end Statement.Assign
# begin Statement.Move
movl MEM(l)[(localI+(3*4))],MEM(l)[MEM(l)[stackTop]+16]
# end Statement.Move
# begin Statement.Push
addl $12,MEM(l)[stackTop]
# end Statement.Push
# begin Statement.Move
movl $L_21,MEM(l)[MEM(l)[stackTop]+0]
# end Statement.Move
# begin Jump
jmp fib_0
# end Jump
# end block: fib_0
# begin block: fib_0
L_22:
# begin Statement.Assign
# begin applyPrim(Int_add)
movl MEM(l)[MEM(l)[stackTop]+8],MEM(l)[(localI+(4*4))]
addl MEM(l)[MEM(l)[stackTop]+12],MEM(l)[(localI+(4*4))]
# end applyPrim(Int_add)
# end Statement.Assign
# begin Statement.Move
movl MEM(l)[(localI+(4*4))],MEM(l)[MEM(l)[stackTop]+4]
# end Statement.Move
# begin Return
jmp *MEM(l)[MEM(l)[stackTop]+0]
# end Return
# end block: fib_0
# begin block: fib_0
L_21:
# begin Statement.Push
addl $-12,MEM(l)[stackTop]
# end Statement.Push
# begin Statement.Move
movl MEM(l)[MEM(l)[stackTop]+16],MEM(l)[MEM(l)[stackTop]+12]
# end Statement.Move
# begin Jump
jmp L_22
# end Jump
# end block: fib_0
# begin block: fib_0
L_19:
# begin Statement.Push
addl $-8,MEM(l)[stackTop]
# end Statement.Push
# begin Statement.Move
movl MEM(l)[MEM(l)[stackTop]+12],MEM(l)[MEM(l)[stackTop]+8]
# end Statement.Move
# begin Jump
jmp L_20
# end Jump
# end block: fib_0
# begin block: fib_0
L_18:
# begin Statement.Move
movl $1,MEM(l)[MEM(l)[stackTop]+4]
# end Statement.Move
# begin Return
jmp *MEM(l)[MEM(l)[stackTop]+0]
# end Return
# end block: fib_0
# begin block: fib_0
L_16:
# begin Statement.Move
movl $1,MEM(l)[MEM(l)[stackTop]+4]
# end Statement.Move
# begin Return
jmp *MEM(l)[MEM(l)[stackTop]+0]
# end Return
# end block: fib_0
# end chunk: Ch_0
# end program