Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] View of /sml/trunk/src/MLRISC/x86/emit/x86MC.sml
ViewVC logotype

View of /sml/trunk/src/MLRISC/x86/emit/x86MC.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1009 - (download) (annotate)
Wed Jan 9 19:44:22 2002 UTC (17 years, 9 months ago) by george
File size: 11463 byte(s)
	Removed the native COPY and FCOPY instructions
	from all the architectures and replaced it with the
	explicit COPY instruction from the previous commit.

	It is now possible to simplify many of the optimizations
	modules that manipulate copies. This has not been
	done in this change.
(*
 * WARNING: This file was automatically generated by MDLGen (v3.0)
 * from the machine description file "x86/x86.mdl".
 * DO NOT EDIT this file directly
 *)


functor X86MCEmitter(structure Instr : X86INSTR
                     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
   
   (* X86 is little endian *)
   
   fun error msg = MLRiscErrorMsg.error("X86MC",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.MemReg _ => extension {opc=opc, opnd=memReg opnd}
       | I.FDirect _ => extension {opc=opc, opnd=memReg opnd}
       | I.Displace{base, disp, ...} => 
         let 
(*#line 472.13 "x86/x86.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.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.CMPL{lsrc, rsrc}) = error "CMPL"
     | emitInstr (I.CMPW{lsrc, rsrc}) = error "CMPW"
     | emitInstr (I.CMPB{lsrc, rsrc}) = error "CMPB"
     | 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.CMPXCHG{lock, sz, src, dst}) = error "CMPXCHG"
     | emitInstr (I.MULTDIV{multDivOp, src}) = error "MULTDIV"
     | emitInstr (I.MUL3{dst, src2, src1}) = error "MUL3"
     | emitInstr (I.UNARY{unOp, opnd}) = error "UNARY"
     | emitInstr (I.SET{cond, opnd}) = error "SET"
     | emitInstr (I.CMOV{cond, src, dst}) = error "CMOV"
     | 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.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{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


root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0