CVS: sml-dist/src/MLRISC/amd64/emit amd64Asm.sml, NONE, 1.1 amd64MC.sml, NONE, 1.1
Matthias Blume <[email protected]> Thu, 05 Oct 2006 08:09:17 -0700
| Newsgroups | gmane.comp.lang.sml.smlnj.commits |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/smlnj/sml-dist/src/MLRISC/amd64/emit
In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv621/amd64/emit
Added Files:
amd64Asm.sml amd64MC.sml
Log Message:
added AMD64 stuff to MLRISC tree
--- NEW FILE: amd64Asm.sml ---
(*
* WARNING: This file was automatically generated by MDLGen (v3.0)
* from the machine description file "amd64/amd64.mdl".
* DO NOT EDIT this file directly
*)
functor AMD64AsmEmitter(structure S : INSTRUCTION_STREAM
structure Instr : AMD64INSTR
where T = S.P.T
structure Shuffle : AMD64SHUFFLE
where I = Instr
structure MLTreeEval : MLTREE_EVAL
where T = Instr.T
(*#line 560.7 "amd64/amd64.mdl"*)
structure MemRegs : MEMORY_REGISTERS where I=Instr
(*#line 561.7 "amd64/amd64.mdl"*)
val memRegBase : CellsBasis.cell option
) : INSTRUCTION_EMITTER =
struct
structure I = Instr
structure C = I.C
structure T = I.T
structure S = S
structure P = S.P
structure Constant = I.Constant
open AsmFlags
fun error msg = MLRiscErrorMsg.error("AMD64AsmEmitter",msg)
fun makeStream formatAnnotations =
let val stream = !AsmStream.asmOutStream
fun emit' s = TextIO.output(stream,s)
val newline = ref true
val tabs = ref 0
fun tabbing 0 = ()
| tabbing n = (emit' "\t"; tabbing(n-1))
fun emit s = (tabbing(!tabs); tabs := 0; newline := false; emit' s)
fun nl() = (tabs := 0; if !newline then () else (newline := true; emit' "\n"))
fun comma() = emit ","
fun tab() = tabs := 1
fun indent() = tabs := 2
fun ms n = let val s = Int.toString n
in if n<0 then "-"^String.substring(s,1,size s-1)
else s
end
fun emit_label lab = emit(P.Client.AsmPseudoOps.lexpToString(T.LABEL lab))
fun emit_labexp le = emit(P.Client.AsmPseudoOps.lexpToString (T.LABEXP le))
fun emit_const c = emit(Constant.toString c)
fun emit_int i = emit(ms i)
fun paren f = (emit "("; f(); emit ")")
fun defineLabel lab = emit(P.Client.AsmPseudoOps.defineLabel lab^"\n")
fun entryLabel lab = defineLabel lab
fun comment msg = (tab(); emit("/* " ^ msg ^ " */"); nl())
fun annotation a = comment(Annotations.toString a)
fun getAnnotations() = error "getAnnotations"
fun doNothing _ = ()
fun fail _ = raise Fail "AsmEmitter"
fun emit_region mem = comment(I.Region.toString mem)
val emit_region =
if !show_region then emit_region else doNothing
fun pseudoOp pOp = (emit(P.toString pOp); emit "\n")
fun init size = (comment("Code Size = " ^ ms size); nl())
val emitCellInfo = AsmFormatUtil.reginfo
(emit,formatAnnotations)
fun emitCell r = (emit(CellsBasis.toString r); emitCellInfo r)
fun emit_cellset(title,cellset) =
(nl(); comment(title^CellsBasis.CellSet.toString cellset))
val emit_cellset =
if !show_cellset then emit_cellset else doNothing
fun emit_defs cellset = emit_cellset("defs: ",cellset)
fun emit_uses cellset = emit_cellset("uses: ",cellset)
val emit_cutsTo =
if !show_cutsTo then AsmFormatUtil.emit_cutsTo emit
else doNothing
fun emitter instr =
let
fun asm_cond (I.EQ) = "e"
| asm_cond (I.NE) = "ne"
| asm_cond (I.LT) = "l"
| asm_cond (I.LE) = "le"
| asm_cond (I.GT) = "g"
| asm_cond (I.GE) = "ge"
| asm_cond (I.B) = "b"
| asm_cond (I.BE) = "be"
| asm_cond (I.A) = "a"
| asm_cond (I.AE) = "ae"
| asm_cond (I.C) = "c"
| asm_cond (I.NC) = "nc"
| asm_cond (I.P) = "p"
| asm_cond (I.NP) = "np"
| asm_cond (I.O) = "o"
| asm_cond (I.NO) = "no"
and emit_cond x = emit (asm_cond x)
and asm_binaryOp (I.ADDQ) = "addq"
| asm_binaryOp (I.SUBQ) = "subq"
| asm_binaryOp (I.ANDQ) = "andq"
| asm_binaryOp (I.ORQ) = "orq"
| asm_binaryOp (I.XORQ) = "xorq"
| asm_binaryOp (I.SHLQ) = "shlq"
| asm_binaryOp (I.SARQ) = "sarq"
| asm_binaryOp (I.SHRQ) = "shrq"
| asm_binaryOp (I.MULQ) = "mulq"
| asm_binaryOp (I.IMULQ) = "imulq"
| asm_binaryOp (I.ADCQ) = "adcq"
| asm_binaryOp (I.SBBQ) = "sbbq"
| asm_binaryOp (I.ADDL) = "addl"
| asm_binaryOp (I.SUBL) = "subl"
| asm_binaryOp (I.ANDL) = "andl"
| asm_binaryOp (I.ORL) = "orl"
| asm_binaryOp (I.XORL) = "xorl"
| asm_binaryOp (I.SHLL) = "shll"
| asm_binaryOp (I.SARL) = "sarl"
| asm_binaryOp (I.SHRL) = "shrl"
| asm_binaryOp (I.MULL) = "mull"
| asm_binaryOp (I.IMULL) = "imull"
| asm_binaryOp (I.ADCL) = "adcl"
| asm_binaryOp (I.SBBL) = "sbbl"
| asm_binaryOp (I.ADDW) = "addw"
| asm_binaryOp (I.SUBW) = "subw"
| asm_binaryOp (I.ANDW) = "andw"
| asm_binaryOp (I.ORW) = "orw"
| asm_binaryOp (I.XORW) = "xorw"
| asm_binaryOp (I.SHLW) = "shlw"
| asm_binaryOp (I.SARW) = "sarw"
| asm_binaryOp (I.SHRW) = "shrw"
| asm_binaryOp (I.MULW) = "mulw"
| asm_binaryOp (I.IMULW) = "imulw"
| asm_binaryOp (I.ADDB) = "addb"
| asm_binaryOp (I.SUBB) = "subb"
| asm_binaryOp (I.ANDB) = "andb"
| asm_binaryOp (I.ORB) = "orb"
| asm_binaryOp (I.XORB) = "xorb"
| asm_binaryOp (I.SHLB) = "shlb"
| asm_binaryOp (I.SARB) = "sarb"
| asm_binaryOp (I.SHRB) = "shrb"
| asm_binaryOp (I.MULB) = "mulb"
| asm_binaryOp (I.IMULB) = "imulb"
| asm_binaryOp (I.BTSW) = "btsw"
| asm_binaryOp (I.BTCW) = "btcw"
| asm_binaryOp (I.BTRW) = "btrw"
| asm_binaryOp (I.BTSL) = "btsl"
| asm_binaryOp (I.BTCL) = "btcl"
| asm_binaryOp (I.BTRL) = "btrl"
| asm_binaryOp (I.ROLW) = "rolw"
| asm_binaryOp (I.RORW) = "rorw"
| asm_binaryOp (I.ROLL) = "roll"
| asm_binaryOp (I.RORL) = "rorl"
| asm_binaryOp (I.XCHGB) = "xchgb"
| asm_binaryOp (I.XCHGW) = "xchgw"
| asm_binaryOp (I.XCHGL) = "xchgl"
| asm_binaryOp (I.LOCK_ADCW) = "lock\n\tadcw"
| asm_binaryOp (I.LOCK_ADCL) = "lock\n\tadcl"
| asm_binaryOp (I.LOCK_ADDW) = "lock\n\taddw"
| asm_binaryOp (I.LOCK_ADDL) = "lock\n\taddl"
| asm_binaryOp (I.LOCK_ANDW) = "lock\n\tandw"
| asm_binaryOp (I.LOCK_ANDL) = "lock\n\tandl"
| asm_binaryOp (I.LOCK_BTSW) = "lock\n\tbtsw"
| asm_binaryOp (I.LOCK_BTSL) = "lock\n\tbtsl"
| asm_binaryOp (I.LOCK_BTRW) = "lock\n\tbtrw"
| asm_binaryOp (I.LOCK_BTRL) = "lock\n\tbtrl"
| asm_binaryOp (I.LOCK_BTCW) = "lock\n\tbtcw"
| asm_binaryOp (I.LOCK_BTCL) = "lock\n\tbtcl"
| asm_binaryOp (I.LOCK_ORW) = "lock\n\torw"
| asm_binaryOp (I.LOCK_ORL) = "lock\n\torl"
| asm_binaryOp (I.LOCK_SBBW) = "lock\n\tsbbw"
| asm_binaryOp (I.LOCK_SBBL) = "lock\n\tsbbl"
| asm_binaryOp (I.LOCK_SUBW) = "lock\n\tsubw"
| asm_binaryOp (I.LOCK_SUBL) = "lock\n\tsubl"
| asm_binaryOp (I.LOCK_XORW) = "lock\n\txorw"
| asm_binaryOp (I.LOCK_XORL) = "lock\n\txorl"
| asm_binaryOp (I.LOCK_XADDB) = "lock\n\txaddb"
| asm_binaryOp (I.LOCK_XADDW) = "lock\n\txaddw"
| asm_binaryOp (I.LOCK_XADDL) = "lock\n\txaddl"
and emit_binaryOp x = emit (asm_binaryOp x)
and asm_multDivOp (I.IMULL1) = "imull"
| asm_multDivOp (I.MULL1) = "mull"
| asm_multDivOp (I.IDIVL1) = "idivl"
| asm_multDivOp (I.DIVL1) = "divl"
| asm_multDivOp (I.IMULQ1) = "imulq"
| asm_multDivOp (I.MULQ1) = "mulq"
| asm_multDivOp (I.IDIVQ1) = "idivq"
| asm_multDivOp (I.DIVQ1) = "divq"
and emit_multDivOp x = emit (asm_multDivOp x)
and asm_unaryOp (I.DECQ) = "decq"
| asm_unaryOp (I.INCQ) = "incq"
| asm_unaryOp (I.NEGQ) = "negq"
| asm_unaryOp (I.NOTQ) = "notq"
| asm_unaryOp (I.DECL) = "decl"
| asm_unaryOp (I.INCL) = "incl"
| asm_unaryOp (I.NEGL) = "negl"
| asm_unaryOp (I.NOTL) = "notl"
| asm_unaryOp (I.DECW) = "decw"
| asm_unaryOp (I.INCW) = "incw"
| asm_unaryOp (I.NEGW) = "negw"
| asm_unaryOp (I.NOTW) = "notw"
| asm_unaryOp (I.DECB) = "decb"
| asm_unaryOp (I.INCB) = "incb"
| asm_unaryOp (I.NEGB) = "negb"
| asm_unaryOp (I.NOTB) = "notb"
| asm_unaryOp (I.LOCK_DECQ) = "lock\n\tdecq"
| asm_unaryOp (I.LOCK_INCQ) = "lock\n\tincq"
| asm_unaryOp (I.LOCK_NEGQ) = "lock\n\tnegq"
| asm_unaryOp (I.LOCK_NOTQ) = "lock\n\tnotq"
and emit_unaryOp x = emit (asm_unaryOp x)
and asm_shiftOp (I.SHLDL) = "shldl"
| asm_shiftOp (I.SHRDL) = "shrdl"
and emit_shiftOp x = emit (asm_shiftOp x)
and asm_bitOp (I.BTW) = "btw"
| asm_bitOp (I.BTL) = "btl"
| asm_bitOp (I.BTQ) = "btq"
| asm_bitOp (I.LOCK_BTW) = "lock\n\tbtw"
| asm_bitOp (I.LOCK_BTL) = "lock\n\tbtl"
and emit_bitOp x = emit (asm_bitOp x)
and asm_move (I.MOVQ) = "movq"
| asm_move (I.MOVL) = "movl"
| asm_move (I.MOVB) = "movb"
| asm_move (I.MOVW) = "movw"
| asm_move (I.MOVSWQ) = "movswq"
| asm_move (I.MOVZWQ) = "movzwq"
| asm_move (I.MOVSWL) = "movswl"
| asm_move (I.MOVZWL) = "movzwl"
| asm_move (I.MOVSBQ) = "movsbq"
| asm_move (I.MOVZBQ) = "movzbq"
| asm_move (I.MOVSBL) = "movsbl"
| asm_move (I.MOVZBL) = "movzbl"
| asm_move (I.MOVSLQ) = "movslq"
and emit_move x = emit (asm_move x)
and asm_fbinOp (I.FADDP) = "faddp"
| asm_fbinOp (I.FADDS) = "fadds"
| asm_fbinOp (I.FMULP) = "fmulp"
| asm_fbinOp (I.FMULS) = "fmuls"
| asm_fbinOp (I.FCOMS) = "fcoms"
| asm_fbinOp (I.FCOMPS) = "fcomps"
| asm_fbinOp (I.FSUBP) = "fsubp"
| asm_fbinOp (I.FSUBS) = "fsubs"
| asm_fbinOp (I.FSUBRP) = "fsubrp"
| asm_fbinOp (I.FSUBRS) = "fsubrs"
| asm_fbinOp (I.FDIVP) = "fdivp"
| asm_fbinOp (I.FDIVS) = "fdivs"
| asm_fbinOp (I.FDIVRP) = "fdivrp"
| asm_fbinOp (I.FDIVRS) = "fdivrs"
| asm_fbinOp (I.FADDL) = "faddl"
| asm_fbinOp (I.FMULL) = "fmull"
| asm_fbinOp (I.FCOML) = "fcoml"
| asm_fbinOp (I.FCOMPL) = "fcompl"
| asm_fbinOp (I.FSUBL) = "fsubl"
| asm_fbinOp (I.FSUBRL) = "fsubrl"
| asm_fbinOp (I.FDIVL) = "fdivl"
| asm_fbinOp (I.FDIVRL) = "fdivrl"
and emit_fbinOp x = emit (asm_fbinOp x)
and asm_fibinOp (I.FIADDS) = "fiadds"
| asm_fibinOp (I.FIMULS) = "fimuls"
| asm_fibinOp (I.FICOMS) = "ficoms"
| asm_fibinOp (I.FICOMPS) = "ficomps"
| asm_fibinOp (I.FISUBS) = "fisubs"
| asm_fibinOp (I.FISUBRS) = "fisubrs"
| asm_fibinOp (I.FIDIVS) = "fidivs"
| asm_fibinOp (I.FIDIVRS) = "fidivrs"
| asm_fibinOp (I.FIADDL) = "fiaddl"
| asm_fibinOp (I.FIMULL) = "fimull"
| asm_fibinOp (I.FICOML) = "ficoml"
| asm_fibinOp (I.FICOMPL) = "ficompl"
| asm_fibinOp (I.FISUBL) = "fisubl"
| asm_fibinOp (I.FISUBRL) = "fisubrl"
| asm_fibinOp (I.FIDIVL) = "fidivl"
| asm_fibinOp (I.FIDIVRL) = "fidivrl"
and emit_fibinOp x = emit (asm_fibinOp x)
and asm_funOp (I.FCHS) = "fchs"
| asm_funOp (I.FABS) = "fabs"
| asm_funOp (I.FTST) = "ftst"
| asm_funOp (I.FXAM) = "fxam"
| asm_funOp (I.FPTAN) = "fptan"
| asm_funOp (I.FPATAN) = "fpatan"
| asm_funOp (I.FXTRACT) = "fxtract"
| asm_funOp (I.FPREM1) = "fprem1"
| asm_funOp (I.FDECSTP) = "fdecstp"
| asm_funOp (I.FINCSTP) = "fincstp"
| asm_funOp (I.FPREM) = "fprem"
| asm_funOp (I.FYL2XP1) = "fyl2xp1"
| asm_funOp (I.FSQRT) = "fsqrt"
| asm_funOp (I.FSINCOS) = "fsincos"
| asm_funOp (I.FRNDINT) = "frndint"
| asm_funOp (I.FSCALE) = "fscale"
| asm_funOp (I.FSIN) = "fsin"
| asm_funOp (I.FCOS) = "fcos"
and emit_funOp x = emit (asm_funOp x)
and asm_fenvOp (I.FLDENV) = "fldenv"
| asm_fenvOp (I.FNLDENV) = "fnldenv"
| asm_fenvOp (I.FSTENV) = "fstenv"
| asm_fenvOp (I.FNSTENV) = "fnstenv"
and emit_fenvOp x = emit (asm_fenvOp x)
and asm_fsize (I.FP32) = "s"
| asm_fsize (I.FP64) = "l"
| asm_fsize (I.FP80) = "t"
and emit_fsize x = emit (asm_fsize x)
and asm_isize (I.I8) = "8"
| asm_isize (I.I16) = "16"
| asm_isize (I.I32) = "32"
| asm_isize (I.I64) = "64"
and emit_isize x = emit (asm_isize x)
(*#line 563.6 "amd64/amd64.mdl"*)
fun memReg r = MemRegs.memReg {reg=r, base=Option.valOf memRegBase}
(*#line 564.6 "amd64/amd64.mdl"*)
fun emitInt32 i =
let
(*#line 565.10 "amd64/amd64.mdl"*)
val s = Int32.toString i
(*#line 566.10 "amd64/amd64.mdl"*)
val s = (if (i >= 0)
then s
else ("-" ^ (String.substring (s, 1, (size s) - 1))))
in emit s
end
(*#line 569.6 "amd64/amd64.mdl"*)
val {low=SToffset, ...} = C.cellRange CellsBasis.FP
(*#line 571.6 "amd64/amd64.mdl"*)
fun emitScale 0 = emit "1"
| emitScale 1 = emit "2"
| emitScale 2 = emit "4"
| emitScale 3 = emit "8"
| emitScale _ = error "emitScale"
and eImmed (I.Immed i) = emitInt32 i
| eImmed (I.ImmedLabel lexp) = emit_labexp lexp
| eImmed _ = error "eImmed"
and emit_operand opn =
(case opn of
I.Immed i =>
( emit "$";
emitInt32 i )
| I.ImmedLabel lexp =>
( emit "$";
emit_labexp lexp )
| I.LabelEA le => emit_labexp le
| I.Relative _ => error "emit_operand"
| I.Direct(ty, r) => emit (CellsBasis.toStringWithSize (r, ty))
| I.ST f => emitCell f
| I.FPR f =>
( emit "%f";
emit (Int.toString (CellsBasis.registerNum f)))
| I.FDirect f => emit_operand (memReg opn)
| I.Displace{base, disp, mem, ...} =>
( emit_disp disp;
emit "(";
emitCell base;
emit ")";
emit_region mem )
| I.Indexed{base, index, scale, disp, mem, ...} =>
( emit_disp disp;
emit "(";
(case base of
NONE => ()
| SOME base => emitCell base
);
comma ();
emitCell index;
comma ();
emitScale scale;
emit ")";
emit_region mem )
)
and emit_operand8 (I.Direct(_, r)) = emit (CellsBasis.toStringWithSize (r,
8))
| emit_operand8 opn = emit_operand opn
and emit_cell32 r = emit (CellsBasis.toStringWithSize (r, 32))
and emit_disp (I.Immed 0) = ()
| emit_disp (I.Immed i) = emitInt32 i
| emit_disp (I.ImmedLabel lexp) = emit_labexp lexp
| emit_disp _ = error "emit_disp"
(*#line 618.7 "amd64/amd64.mdl"*)
fun stupidGas (I.ImmedLabel lexp) = emit_labexp lexp
| stupidGas opnd =
( emit "*";
emit_operand opnd )
(*#line 622.7 "amd64/amd64.mdl"*)
fun isMemOpnd (I.FDirect f) = true
| isMemOpnd (I.LabelEA _) = true
| isMemOpnd (I.Displace _) = true
| isMemOpnd (I.Indexed _) = true
| isMemOpnd _ = false
(*#line 628.7 "amd64/amd64.mdl"*)
fun chop fbinOp =
let
(*#line 629.15 "amd64/amd64.mdl"*)
val n = size fbinOp
in
(case Char.toLower (String.sub (fbinOp, n - 1)) of
(#"s" | #"l") => String.substring (fbinOp, 0, n - 1)
| _ => fbinOp
)
end
(*#line 635.7 "amd64/amd64.mdl"*)
fun isST0 (I.ST r) = (CellsBasis.registerNum r) = 0
| isST0 _ = false
(*#line 639.7 "amd64/amd64.mdl"*)
fun emit_fbinaryOp (binOp, src, dst) = (if (isMemOpnd src)
then
( emit_fbinOp binOp;
emit "\t";
emit_operand src )
else
( emit (chop (asm_fbinOp binOp));
emit "\t";
(case (isST0 src, isST0 dst) of
(_, true) =>
( emit_operand src;
emit ", %st" )
| (true, _) =>
( emit "%st, ";
emit_operand dst )
| _ => error "emit_fbinaryOp"
)))
(*#line 649.7 "amd64/amd64.mdl"*)
val emit_dst = emit_operand
(*#line 650.7 "amd64/amd64.mdl"*)
val emit_src = emit_operand
(*#line 651.7 "amd64/amd64.mdl"*)
val emit_opnd = emit_operand
(*#line 652.7 "amd64/amd64.mdl"*)
val emit_opnd8 = emit_operand8
(*#line 653.7 "amd64/amd64.mdl"*)
val emit_rsrc = emit_operand
(*#line 654.7 "amd64/amd64.mdl"*)
val emit_lsrc = emit_operand
(*#line 655.7 "amd64/amd64.mdl"*)
val emit_addr = emit_operand
(*#line 656.7 "amd64/amd64.mdl"*)
val emit_src1 = emit_operand
(*#line 657.7 "amd64/amd64.mdl"*)
val emit_ea = emit_operand
(*#line 658.7 "amd64/amd64.mdl"*)
val emit_count = emit_operand
fun emitInstr' instr =
(case instr of
I.NOP => emit "nop"
| I.JMP(operand, list) =>
( emit "jmp\t";
stupidGas operand )
| I.JCC{cond, opnd} =>
( emit "j";
emit_cond cond;
emit "\t";
stupidGas opnd )
| I.CALL{opnd, defs, uses, return, cutsTo, mem, pops} =>
( emit "call\t";
stupidGas opnd;
emit_region mem;
emit_defs defs;
emit_uses uses;
emit_cellset ("return", return);
emit_cutsTo cutsTo )
| I.CALLQ{opnd, defs, uses, return, cutsTo, mem, pops} =>
( emit "call\t";
stupidGas opnd;
emit_region mem;
emit_defs defs;
emit_uses uses;
emit_cellset ("return", return);
emit_cutsTo cutsTo )
| I.ENTER{src1, src2} =>
( emit "enter\t";
emit_operand src1;
emit ", ";
emit_operand src2 )
| I.LEAVE => emit "leave"
| I.RET option =>
( emit "ret";
(case option of
NONE => ()
| SOME e =>
( emit "\t";
emit_operand e )
))
| I.MOVE{mvOp, src, dst} =>
( emit_move mvOp;
emit "\t";
emit_src src;
emit ", ";
emit_dst dst )
| I.LEA{r32, addr} =>
( emit "leal\t";
emit_addr addr;
emit ", ";
emit_cell32 r32 )
| I.LEAQ{r64, addr} =>
( emit "leaq\t";
emit_addr addr;
emit ", ";
emitCell r64 )
| I.CMPQ{lsrc, rsrc} =>
( emit "cmpq\t";
emit_rsrc rsrc;
emit ", ";
emit_lsrc lsrc )
| I.CMPL{lsrc, rsrc} =>
( emit "cmpl\t";
emit_rsrc rsrc;
emit ", ";
emit_lsrc lsrc )
| I.CMPW{lsrc, rsrc} =>
( emit "cmpb\t";
emit_rsrc rsrc;
emit ", ";
emit_lsrc lsrc )
| I.CMPB{lsrc, rsrc} =>
( emit "cmpb\t";
emit_rsrc rsrc;
emit ", ";
emit_lsrc lsrc )
| I.TESTQ{lsrc, rsrc} =>
( emit "testq\t";
emit_rsrc rsrc;
emit ", ";
emit_lsrc lsrc )
| I.TESTL{lsrc, rsrc} =>
( emit "testl\t";
emit_rsrc rsrc;
emit ", ";
emit_lsrc lsrc )
| I.TESTW{lsrc, rsrc} =>
( emit "testw\t";
emit_rsrc rsrc;
emit ", ";
emit_lsrc lsrc )
| I.TESTB{lsrc, rsrc} =>
( emit "testb\t";
emit_rsrc rsrc;
emit ", ";
emit_lsrc lsrc )
| I.BITOP{bitOp, lsrc, rsrc} =>
( emit_bitOp bitOp;
emit "\t";
emit_rsrc rsrc;
emit ", ";
emit_lsrc lsrc )
| I.BINARY{binOp, src, dst} =>
(case (src, binOp) of
(I.Direct _,
( I.SARQ |
I.SHRQ |
I.SHLQ |
I.SARL |
I.SHRL |
I.SHLL |
I.SARW |
I.SHRW |
I.SHLW |
I.SARB |
I.SHRB |
I.SHLB )) =>
( emit_binaryOp binOp;
emit "\t%cl, ";
emit_dst dst )
| _ =>
( emit_binaryOp binOp;
emit "\t";
emit_src src;
emit ", ";
emit_dst dst )
)
| I.SHIFT{shiftOp, src, dst, count} =>
(case count of
I.Direct(ty, ecx) =>
( emit_shiftOp shiftOp;
emit "\t";
emit_src src;
emit ", ";
emit_dst dst )
| _ =>
( emit_shiftOp shiftOp;
emit "\t";
emit_src src;
emit ", ";
emit_count count;
emit ", ";
emit_dst dst )
)
| I.CMPXCHG{lock, sz, src, dst} =>
( (if lock
then (emit "lock\n\t")
else ());
emit "cmpxchg";
(case sz of
I.I8 => emit "b"
| I.I16 => emit "w"
| I.I32 => emit "l"
| I.I64 => error "CMPXCHG: I64"
);
( emit "\t";
emit_src src;
emit ", ";
emit_dst dst ) )
| I.MULTDIV{multDivOp, src} =>
( emit_multDivOp multDivOp;
emit "\t";
emit_src src )
| I.MUL3{dst, src2, src1} =>
( emit "imull\t$";
emitInt32 src2;
emit ", ";
emit_src1 src1;
emit ", ";
emit_cell32 dst )
| I.MULQ3{dst, src2, src1} =>
( emit "imulq\t$";
emitInt32 src2;
emit ", ";
emit_src1 src1;
emit ", ";
emitCell dst )
| I.UNARY{unOp, opnd} =>
( emit_unaryOp unOp;
emit "\t";
emit_opnd opnd )
| I.SET{cond, opnd} =>
( emit "set";
emit_cond cond;
emit "\t";
emit_opnd8 opnd )
| I.CMOV{cond, src, dst} =>
( emit "cmov";
emit_cond cond;
emit "\t";
emit_src src;
emit ", ";
emitCell dst )
| I.CMOVQ{cond, src, dst} =>
( emit "cmov";
emit_cond cond;
emit "\t";
emit_src src;
emit ", ";
emitCell dst )
| I.PUSHQ operand =>
( emit "pushq\t";
emit_operand operand )
| I.PUSHL operand =>
( emit "pushl\t";
emit_operand operand )
| I.PUSHW operand =>
( emit "pushw\t";
emit_operand operand )
| I.PUSHB operand =>
( emit "pushb\t";
emit_operand operand )
| I.PUSHFD => emit "pushfd"
| I.POPFD => emit "popfd"
| I.POP operand =>
( emit "popq\t";
emit_operand operand )
| I.CDQ => emit "cdq"
| I.INTO => emit "int $4"
| I.FBINARY{binOp, src, dst} => emit_fbinaryOp (binOp, src, dst)
| I.FIBINARY{binOp, src} =>
( emit_fibinOp binOp;
emit "\t";
emit_src src )
| I.FUNARY funOp => emit_funOp funOp
| I.FUCOM operand =>
( emit "fucom\t";
emit_operand operand )
| I.FUCOMP operand =>
( emit "fucomp\t";
emit_operand operand )
| I.FUCOMPP => emit "fucompp"
| I.FCOMPP => emit "fcompp"
| I.FCOMI operand =>
( emit "fcomi\t";
emit_operand operand;
emit ", %st" )
| I.FCOMIP operand =>
( emit "fcomip\t";
emit_operand operand;
emit ", %st" )
| I.FUCOMI operand =>
( emit "fucomi\t";
emit_operand operand;
emit ", %st" )
| I.FUCOMIP operand =>
( emit "fucomip\t";
emit_operand operand;
emit ", %st" )
| I.FXCH{opnd} =>
( emit "fxch\t";
emitCell opnd )
| I.FSTPL operand =>
(case operand of
I.ST _ =>
( emit "fstp\t";
emit_operand operand )
| _ =>
( emit "fstpl\t";
emit_operand operand )
)
| I.FSTPS operand =>
( emit "fstps\t";
emit_operand operand )
| I.FSTPT operand =>
( emit "fstps\t";
emit_operand operand )
| I.FSTL operand =>
(case operand of
I.ST _ =>
( emit "fst\t";
emit_operand operand )
| _ =>
( emit "fstl\t";
emit_operand operand )
)
| I.FSTS operand =>
( emit "fsts\t";
emit_operand operand )
| I.FLD1 => emit "fld1"
| I.FLDL2E => emit "fldl2e"
| I.FLDL2T => emit "fldl2t"
| I.FLDLG2 => emit "fldlg2"
| I.FLDLN2 => emit "fldln2"
| I.FLDPI => emit "fldpi"
| I.FLDZ => emit "fldz"
| I.FLDL operand =>
(case operand of
I.ST _ =>
( emit "fld\t";
emit_operand operand )
| _ =>
( emit "fldl\t";
emit_operand operand )
)
| I.FLDS operand =>
( emit "flds\t";
emit_operand operand )
| I.FLDT operand =>
( emit "fldt\t";
emit_operand operand )
| I.FILD operand =>
( emit "fild\t";
emit_operand operand )
| I.FILDL operand =>
( emit "fildl\t";
emit_operand operand )
| I.FILDLL operand =>
( emit "fildll\t";
emit_operand operand )
| I.FNSTSW => emit "fnstsw"
| I.FENV{fenvOp, opnd} =>
( emit_fenvOp fenvOp;
emit "\t";
emit_opnd opnd )
| I.FMOVE{fsize, src, dst} =>
( emit "fmove";
emit_fsize fsize;
emit "\t";
emit_src src;
emit ", ";
emit_dst dst )
| I.FILOAD{isize, ea, dst} =>
( emit "fiload";
emit_isize isize;
emit "\t";
emit_ea ea;
emit ", ";
emit_dst dst )
| I.FBINOP{fsize, binOp, lsrc, rsrc, dst} =>
( emit_fbinOp binOp;
emit_fsize fsize;
emit "\t";
emit_lsrc lsrc;
emit ", ";
emit_rsrc rsrc;
emit ", ";
emit_dst dst )
| I.FIBINOP{isize, binOp, lsrc, rsrc, dst} =>
( emit_fibinOp binOp;
emit_isize isize;
emit "\t";
emit_lsrc lsrc;
emit ", ";
emit_rsrc rsrc;
emit ", ";
emit_dst dst )
| I.FUNOP{fsize, unOp, src, dst} =>
( emit_funOp unOp;
emit_fsize fsize;
emit "\t";
emit_src src;
emit ", ";
emit_dst dst )
| I.FCMP{i, fsize, lsrc, rsrc} =>
( (if i
then (emit "fcmpi")
else (emit "fcmp"));
( emit_fsize fsize;
emit "\t";
emit_lsrc lsrc;
emit ", ";
emit_rsrc rsrc ) )
| I.SAHF => emit "sahf"
| I.LAHF => emit "lahf"
| I.SOURCE{} => emit "source"
| I.SINK{} => emit "sink"
| I.PHI{} => emit "phi"
)
in tab(); emitInstr' instr; nl()
end (* emitter *)
and emitInstrIndented i = (indent(); emitInstr i; nl())
and emitInstrs instrs =
app (if !indent_copies then emitInstrIndented
else emitInstr) instrs
and emitInstr(I.ANNOTATION{i,a}) =
( comment(Annotations.toString a);
nl();
emitInstr i )
| emitInstr(I.LIVE{regs, spilled}) =
comment("live= " ^ CellsBasis.CellSet.toString regs ^
"spilled= " ^ CellsBasis.CellSet.toString spilled)
| emitInstr(I.KILL{regs, spilled}) =
comment("killed:: " ^ CellsBasis.CellSet.toString regs ^
"spilled:: " ^ CellsBasis.CellSet.toString spilled)
| emitInstr(I.INSTR i) = emitter i
| emitInstr(I.COPY{k=CellsBasis.GP, sz, src, dst, tmp}) =
emitInstrs(Shuffle.shuffle{tmp=tmp, src=src, dst=dst})
| emitInstr(I.COPY{k=CellsBasis.FP, sz, src, dst, tmp}) =
emitInstrs(Shuffle.shufflefp{tmp=tmp, src=src, dst=dst})
| emitInstr _ = error "emitInstr"
in S.STREAM{beginCluster=init,
pseudoOp=pseudoOp,
emit=emitInstr,
endCluster=fail,
defineLabel=defineLabel,
entryLabel=entryLabel,
comment=comment,
exitBlock=doNothing,
annotation=annotation,
getAnnotations=getAnnotations
}
end
end
--- NEW FILE: amd64MC.sml ---
(*
* WARNING: This file was automatically generated by MDLGen (v3.0)
* from the machine description file "amd64/amd64.mdl".
* DO NOT EDIT this file directly
*)
functor AMD64MCEmitter(structure Instr : AMD64INSTR
structure MLTreeEval : MLTREE_EVAL where T = Instr.T
structure Stream : INSTRUCTION_STREAM
structure CodeString : CODE_STRING
) : INSTRUCTION_EMITTER =
struct
structure I = Instr
structure C = I.C
structure Constant = I.Constant
structure T = I.T
structure S = Stream
structure P = S.P
structure W = Word32
(* AMD64 is little endian *)
fun error msg = MLRiscErrorMsg.error("AMD64MC",msg)
fun makeStream _ =
let infix && || << >> ~>>
val op << = W.<<
val op >> = W.>>
val op ~>> = W.~>>
val op || = W.orb
val op && = W.andb
val itow = W.fromInt
fun emit_bool false = 0w0 : W.word
| emit_bool true = 0w1 : W.word
val emit_int = itow
fun emit_word w = w
fun emit_label l = itow(Label.addrOf l)
fun emit_labexp le = itow(MLTreeEval.valueOf le)
fun emit_const c = itow(Constant.valueOf c)
val loc = ref 0
(* emit a byte *)
fun eByte b =
let val i = !loc in loc := i + 1; CodeString.update(i,b) end
(* emit the low order byte of a word *)
(* note: fromLargeWord strips the high order bits! *)
fun eByteW w =
let val i = !loc
in loc := i + 1; CodeString.update(i,Word8.fromLargeWord w) end
fun doNothing _ = ()
fun fail _ = raise Fail "MCEmitter"
fun getAnnotations () = error "getAnnotations"
fun pseudoOp pOp = P.emitValue{pOp=pOp, loc= !loc,emit=eByte}
fun init n = (CodeString.init n; loc := 0)
fun eWord8 w =
let val b8 = w
in eByteW b8
end
and eWord16 w =
let val b8 = w
val w = w >> 0wx8
val b16 = w
in
( eByteW b8;
eByteW b16 )
end
and eWord32 w =
let val b8 = w
val w = w >> 0wx8
val b16 = w
val w = w >> 0wx8
val b24 = w
val w = w >> 0wx8
val b32 = w
in
( eByteW b8;
eByteW b16;
eByteW b24;
eByteW b32 )
end
fun emit_GP r = itow (CellsBasis.physicalRegisterNum r)
and emit_FP r = itow (CellsBasis.physicalRegisterNum r)
and emit_CC r = itow (CellsBasis.physicalRegisterNum r)
and emit_EFLAGS r = itow (CellsBasis.physicalRegisterNum r)
and emit_FFLAGS r = itow (CellsBasis.physicalRegisterNum r)
and emit_MEM r = itow (CellsBasis.physicalRegisterNum r)
and emit_CTRL r = itow (CellsBasis.physicalRegisterNum r)
and emit_CELLSET r = itow (CellsBasis.physicalRegisterNum r)
fun emit_cond (I.EQ) = (0wx4 : Word32.word)
| emit_cond (I.NE) = (0wx5 : Word32.word)
| emit_cond (I.LT) = (0wxC : Word32.word)
| emit_cond (I.LE) = (0wxE : Word32.word)
| emit_cond (I.GT) = (0wxF : Word32.word)
| emit_cond (I.GE) = (0wxD : Word32.word)
| emit_cond (I.B) = (0wx2 : Word32.word)
| emit_cond (I.BE) = (0wx6 : Word32.word)
| emit_cond (I.A) = (0wx7 : Word32.word)
| emit_cond (I.AE) = (0wx3 : Word32.word)
| emit_cond (I.C) = (0wx2 : Word32.word)
| emit_cond (I.NC) = (0wx3 : Word32.word)
| emit_cond (I.P) = (0wxA : Word32.word)
| emit_cond (I.NP) = (0wxB : Word32.word)
| emit_cond (I.O) = (0wx0 : Word32.word)
| emit_cond (I.NO) = (0wx1 : Word32.word)
and emit_fibinOp (I.FIADDS) = (0wxDE, 0)
| emit_fibinOp (I.FIMULS) = (0wxDE, 1)
| emit_fibinOp (I.FICOMS) = (0wxDE, 2)
| emit_fibinOp (I.FICOMPS) = (0wxDE, 3)
| emit_fibinOp (I.FISUBS) = (0wxDE, 4)
| emit_fibinOp (I.FISUBRS) = (0wxDE, 5)
| emit_fibinOp (I.FIDIVS) = (0wxDE, 6)
| emit_fibinOp (I.FIDIVRS) = (0wxDE, 7)
| emit_fibinOp (I.FIADDL) = (0wxDA, 0)
| emit_fibinOp (I.FIMULL) = (0wxDA, 1)
| emit_fibinOp (I.FICOML) = (0wxDA, 2)
| emit_fibinOp (I.FICOMPL) = (0wxDA, 3)
| emit_fibinOp (I.FISUBL) = (0wxDA, 4)
| emit_fibinOp (I.FISUBRL) = (0wxDA, 5)
| emit_fibinOp (I.FIDIVL) = (0wxDA, 6)
| emit_fibinOp (I.FIDIVRL) = (0wxDA, 7)
and emit_funOp (I.FCHS) = (0wxE0 : Word32.word)
| emit_funOp (I.FABS) = (0wxE1 : Word32.word)
| emit_funOp (I.FTST) = (0wxE4 : Word32.word)
| emit_funOp (I.FXAM) = (0wxE5 : Word32.word)
| emit_funOp (I.FPTAN) = (0wxF2 : Word32.word)
| emit_funOp (I.FPATAN) = (0wxF3 : Word32.word)
| emit_funOp (I.FXTRACT) = (0wxF4 : Word32.word)
| emit_funOp (I.FPREM1) = (0wxF5 : Word32.word)
| emit_funOp (I.FDECSTP) = (0wxF6 : Word32.word)
| emit_funOp (I.FINCSTP) = (0wxF7 : Word32.word)
| emit_funOp (I.FPREM) = (0wxF8 : Word32.word)
| emit_funOp (I.FYL2XP1) = (0wxF9 : Word32.word)
| emit_funOp (I.FSQRT) = (0wxFA : Word32.word)
| emit_funOp (I.FSINCOS) = (0wxFB : Word32.word)
| emit_funOp (I.FRNDINT) = (0wxFC : Word32.word)
| emit_funOp (I.FSCALE) = (0wxFD : Word32.word)
| emit_funOp (I.FSIN) = (0wxFE : Word32.word)
| emit_funOp (I.FCOS) = (0wxFF : Word32.word)
fun modrm {mod, reg, rm} = eWord8 ((op mod << 0wx6) + ((reg << 0wx3) + rm))
and reg {opc, reg} = eWord8 ((opc << 0wx3) + reg)
and sib {ss, index, base} = eWord8 ((ss << 0wx6) + ((index << 0wx3) + base))
and immed8 {imm} = eWord8 imm
and immed32 {imm} = eWord32 imm
and immedOpnd {opnd} =
(case opnd of
I.Immed i32 => i32
| I.ImmedLabel le => lexp le
| I.LabelEA le => lexp le
| _ => error "immedOpnd"
)
and extension {opc, opnd} =
(case opnd of
I.Direct(_, r) => modrm {mod=3, reg=opc, rm=r}
| I.FDirect _ => extension {opc=opc, opnd=memReg opnd}
| I.Displace{base, disp, ...} =>
let
(*#line 523.13 "amd64/amd64.mdl"*)
val immed = immedOpnd {opnd=disp}
in ()
end
| I.Indexed{base=NONE, index, scale, disp, ...} => ()
| I.Indexed{base=SOME b, index, scale, disp, ...} => ()
| _ => error "immedExt"
)
and encodeST {prefix, opc, st} =
let val st = emit_FP st
in eWord16 ((prefix << 0wx8) + ((opc << 0wx3) + st))
end
and encodeReg {prefix, reg, opnd} =
let val reg = emit_GP reg
in
( emit prefix;
immedExt {opc=reg, opnd=opnd})
end
and arith {opc1, opc2, src, dst} =
(case (src, dst) of
(I.ImmedLabel le, dst) => arith {opc1=opc1, opc2=opc2, src=I.Immed (lexp le),
dst=dst}
| (I.LabelEA le, dst) => arith {opc1=opc1, opc2=opc2, src=I.Immed (lexp le),
dst=dst}
| (I.Immed i, dst) => ()
| (src, I.Direct(_, r)) => encodeReg {prefix=opc1 + op3, reg=reg, opnd=src}
| (I.Direct(_, r), dst) => encodeReg {prefix=opc1 + 0wx1, reg=reg, opnd=dst}
| _ => error "arith"
)
fun emitter instr =
let
fun emitInstr (I.NOP) = error "NOP"
| emitInstr (I.JMP(operand, list)) = error "JMP"
| emitInstr (I.JCC{cond, opnd}) = error "JCC"
| emitInstr (I.CALL{opnd, defs, uses, return, cutsTo, mem, pops}) = error "CALL"
| emitInstr (I.CALLQ{opnd, defs, uses, return, cutsTo, mem, pops}) = error "CALLQ"
| emitInstr (I.ENTER{src1, src2}) = error "ENTER"
| emitInstr (I.LEAVE) = error "LEAVE"
| emitInstr (I.RET option) = error "RET"
| emitInstr (I.MOVE{mvOp, src, dst}) = error "MOVE"
| emitInstr (I.LEA{r32, addr}) = error "LEA"
| emitInstr (I.LEAQ{r64, addr}) = error "LEAQ"
| emitInstr (I.CMPQ{lsrc, rsrc}) = error "CMPQ"
| emitInstr (I.CMPL{lsrc, rsrc}) = error "CMPL"
| emitInstr (I.CMPW{lsrc, rsrc}) = error "CMPW"
| emitInstr (I.CMPB{lsrc, rsrc}) = error "CMPB"
| emitInstr (I.TESTQ{lsrc, rsrc}) = error "TESTQ"
| emitInstr (I.TESTL{lsrc, rsrc}) = error "TESTL"
| emitInstr (I.TESTW{lsrc, rsrc}) = error "TESTW"
| emitInstr (I.TESTB{lsrc, rsrc}) = error "TESTB"
| emitInstr (I.BITOP{bitOp, lsrc, rsrc}) = error "BITOP"
| emitInstr (I.BINARY{binOp, src, dst}) = error "BINARY"
| emitInstr (I.SHIFT{shiftOp, src, dst, count}) = error "SHIFT"
| emitInstr (I.CMPXCHG{lock, sz, src, dst}) = error "CMPXCHG"
| emitInstr (I.MULTDIV{multDivOp, src}) = error "MULTDIV"
| emitInstr (I.MUL3{dst, src2, src1}) = error "MUL3"
| emitInstr (I.MULQ3{dst, src2, src1}) = error "MULQ3"
| emitInstr (I.UNARY{unOp, opnd}) = error "UNARY"
| emitInstr (I.SET{cond, opnd}) = error "SET"
| emitInstr (I.CMOV{cond, src, dst}) = error "CMOV"
| emitInstr (I.CMOVQ{cond, src, dst}) = error "CMOVQ"
| emitInstr (I.PUSHQ operand) = error "PUSHQ"
| emitInstr (I.PUSHL operand) = error "PUSHL"
| emitInstr (I.PUSHW operand) = error "PUSHW"
| emitInstr (I.PUSHB operand) = error "PUSHB"
| emitInstr (I.PUSHFD) = error "PUSHFD"
| emitInstr (I.POPFD) = error "POPFD"
| emitInstr (I.POP operand) = error "POP"
| emitInstr (I.CDQ) = error "CDQ"
| emitInstr (I.INTO) = error "INTO"
| emitInstr (I.FBINARY{binOp, src, dst}) = error "FBINARY"
| emitInstr (I.FIBINARY{binOp, src}) = error "FIBINARY"
| emitInstr (I.FUNARY funOp) = error "FUNARY"
| emitInstr (I.FUCOM operand) = error "FUCOM"
| emitInstr (I.FUCOMP operand) = error "FUCOMP"
| emitInstr (I.FUCOMPP) = error "FUCOMPP"
| emitInstr (I.FCOMPP) = error "FCOMPP"
| emitInstr (I.FCOMI operand) = error "FCOMI"
| emitInstr (I.FCOMIP operand) = error "FCOMIP"
| emitInstr (I.FUCOMI operand) = error "FUCOMI"
| emitInstr (I.FUCOMIP operand) = error "FUCOMIP"
| emitInstr (I.FXCH{opnd}) = error "FXCH"
| emitInstr (I.FSTPL operand) = error "FSTPL"
| emitInstr (I.FSTPS operand) = error "FSTPS"
| emitInstr (I.FSTPT operand) = error "FSTPT"
| emitInstr (I.FSTL operand) = error "FSTL"
| emitInstr (I.FSTS operand) = error "FSTS"
| emitInstr (I.FLD1) = error "FLD1"
| emitInstr (I.FLDL2E) = error "FLDL2E"
| emitInstr (I.FLDL2T) = error "FLDL2T"
| emitInstr (I.FLDLG2) = error "FLDLG2"
| emitInstr (I.FLDLN2) = error "FLDLN2"
| emitInstr (I.FLDPI) = error "FLDPI"
| emitInstr (I.FLDZ) = error "FLDZ"
| emitInstr (I.FLDL operand) = error "FLDL"
| emitInstr (I.FLDS operand) = error "FLDS"
| emitInstr (I.FLDT operand) = error "FLDT"
| emitInstr (I.FILD operand) = error "FILD"
| emitInstr (I.FILDL operand) = error "FILDL"
| emitInstr (I.FILDLL operand) = error "FILDLL"
| emitInstr (I.FNSTSW) = error "FNSTSW"
| emitInstr (I.FENV{fenvOp, opnd}) = error "FENV"
| emitInstr (I.FMOVE{fsize, src, dst}) = error "FMOVE"
| emitInstr (I.FILOAD{isize, ea, dst}) = error "FILOAD"
| emitInstr (I.FBINOP{fsize, binOp, lsrc, rsrc, dst}) = error "FBINOP"
| emitInstr (I.FIBINOP{isize, binOp, lsrc, rsrc, dst}) = error "FIBINOP"
| emitInstr (I.FUNOP{fsize, unOp, src, dst}) = error "FUNOP"
| emitInstr (I.FCMP{i, fsize, lsrc, rsrc}) = error "FCMP"
| emitInstr (I.SAHF) = error "SAHF"
| emitInstr (I.LAHF) = error "LAHF"
| emitInstr (I.SOURCE{}) = ()
| emitInstr (I.SINK{}) = ()
| emitInstr (I.PHI{}) = ()
in
emitInstr instr
end
fun emitInstruction(I.ANNOTATION{i, ...}) = emitInstruction(i)
| emitInstruction(I.INSTR(i)) = emitter(i)
| emitInstruction(I.LIVE _) = ()
| emitInstruction(I.KILL _) = ()
| emitInstruction _ = error "emitInstruction"
in S.STREAM{beginCluster=init,
pseudoOp=pseudoOp,
emit=emitInstruction,
endCluster=fail,
defineLabel=doNothing,
entryLabel=doNothing,
comment=doNothing,
exitBlock=doNothing,
annotation=doNothing,
getAnnotations=getAnnotations
}
end
end
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV