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