-(* L1 Compiler
- * Gathers tiberium, fires rockets
+(* L2 Compiler
* Takes a list of mappings of temporaries to colors and a pseudoasm listing,
* then produces x86 code.
+ * Author: Chris Lu <czl@andrew.cmu.edu>
* Author: Joshua Wise <jwise@andrew.cmu.edu>
*)
fun temptoreg (t: T.temp) : x86.reg =
numtoreg (temptonum t)
handle Empty =>
- (let
- val () = print (" Uncolored temp "^(Temp.name t)^" -- dead code?\n")
- in
- X.R15D (*If we don't care about the output, then it is cool to explode this; R15D is guaranteed not to be used across builtin blocks.*)
- end)
+ (ErrorMsg.warn NONE ("Uncolored temp "^(Temp.name t)^" -- dead code?") ;
+ X.R15D) (*If we don't care about the output, then it is cool to explode this; R15D is guaranteed not to be used across builtin blocks.*)
val spillreg1 = X.R14D
- val spillreg2 = X.R15D
val prologue = [X.DIRECTIVE "\tpush %rbx\n\tpush %r12\n\tpush %r13\n\tpush %r14\n\tpush %r15"] (* Could be done better. *)
val epilogue = [X.DIRECTIVE "\tpop %r15\n\tpop %r14\n\tpop %r13\n\tpop %r12\n\tpop %rbx"]
realoper src handle Spilled => stackoper src)]
| transform (X.SUBL (dest, src)) =
unspill (src, spillreg1) @
- unspill (dest, spillreg2) @
[ X.SUBL(
- realoper dest handle Spilled => X.REG spillreg2,
- realoper src handle Spilled => X.REG spillreg1)] @
- spill (dest, spillreg2)
+ realoper dest handle Spilled => stackoper dest,
+ realoper src handle Spilled => X.REG spillreg1)]
| transform (X.IMUL (dest, src)) =
unspill (dest, spillreg1) @
[ X.IMUL(
[ X.ADDL(
realoper dest handle Spilled => raise ErrorMsg.InternalError "But we said that wasn't spilled?",
realoper src handle Spilled => stackoper src)]
- | transform (X.LEAL (dest, src1, src2)) =
- unspill (src1, spillreg1) @
- unspill (src2, spillreg2) @
- [ X.LEAL(
- realoper dest handle Spilled => X.REG spillreg1,
- realoper src1 handle Spilled => X.REG spillreg1,
- realoper src2 handle Spilled => X.REG spillreg2)] @
- spill (dest, spillreg1)
| transform (X.IDIVL (src)) = [ X.IDIVL(realoper src handle Spilled => stackoper src)]
| transform (X.NEG (src)) = [ X.NEG(realoper src handle Spilled => stackoper src)]
+ | transform (X.NOTL (src)) = [ X.NOTL(realoper src handle Spilled => stackoper src)]
+ | transform (X.SALL (dest, shft)) =
+ [ X.SALL (
+ realoper dest handle Spilled => stackoper dest,
+ shft)]
+ | transform (X.SARL (dest, shft)) =
+ [ X.SARL (
+ realoper dest handle Spilled => stackoper dest,
+ shft)]
| transform (X.CLTD) = [ X.CLTD ]
+ | transform (X.ANDL (dest, src)) =
+ unspill (src, spillreg1) @
+ [ X.ANDL(
+ realoper dest handle Spilled => stackoper dest,
+ realoper src handle Spilled => X.REG spillreg1)]
+ | transform (X.ORL (dest, src)) =
+ unspill (src, spillreg1) @
+ [ X.ORL(
+ realoper dest handle Spilled => stackoper dest,
+ realoper src handle Spilled => X.REG spillreg1)]
+ | transform (X.XORL (dest, src)) =
+ unspill (src, spillreg1) @
+ [ X.XORL(
+ realoper dest handle Spilled => stackoper dest,
+ realoper src handle Spilled => X.REG spillreg1)]
+ | transform (X.CMPL (op1, op2)) =
+ unspill (op2, spillreg1) @
+ [ X.CMPL(
+ realoper op1 handle Spilled => stackoper op1,
+ realoper op2 handle Spilled => X.REG spillreg1)]
+ | transform (X.TEST (op1, op2)) =
+ unspill (op2, spillreg1) @
+ [ X.TEST(
+ realoper op1 handle Spilled => stackoper op1,
+ realoper op2 handle Spilled => X.REG spillreg1)]
+ | transform (X.SETNE (src)) = [ X.SETNE(realoper src handle Spilled => stackoper src)]
+ | transform (X.SETE (src)) = [ X.SETE(realoper src handle Spilled => stackoper src)]
+ | transform (X.SETLE (src)) = [ X.SETLE(realoper src handle Spilled => stackoper src)]
+ | transform (X.SETL (src)) = [ X.SETL(realoper src handle Spilled => stackoper src)]
+ | transform (X.SETGE (src)) = [ X.SETGE(realoper src handle Spilled => stackoper src)]
+ | transform (X.SETG (src)) = [ X.SETG(realoper src handle Spilled => stackoper src)]
+ | transform (X.MOVZBL (dest, src)) =
+ [ X.MOVZBL(
+ realoper dest handle Spilled => X.REG spillreg1,
+ realoper src handle Spilled => stackoper src)]
+ @ spill (dest, spillreg1)
| transform (X.RET) = epilogue @ [X.RET]
+ | transform (X.LABEL l) = [ X.LABEL l ]
+ | transform (X.JMP l) = [ X.JMP l ]
+ | transform (X.JE l) = [ X.JE l]
+ | transform (X.JNE l) = [ X.JNE l]
(* | transform _ = raise ErrorMsg.InternalError ("Unimplemented transform")*)
in
List.concat (prologue :: (map transform instrs))