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/x86Asm.sml
ViewVC logotype

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 565 - (download) (annotate)
Sun Mar 5 04:10:18 2000 UTC (19 years, 6 months ago) by leunga
File size: 17037 byte(s)

Fix up a few floating point bugs on the x86 that are discovered by Fermin.
Rewritten the Sethi-Ullman code.  Added new FP instructions to the x86,
including FIxxxx, FCOMxx, and FLDxx.
(*
 * This file was automatically generated by MDGen (v2.0)
 * from the machine description file "x86/x86.md".
 *)


functor X86AsmEmitter(structure Instr : X86INSTR
                      structure Stream : INSTRUCTION_STREAM
                      structure Shuffle : X86SHUFFLE
                         where I = Instr

(*#line 181.7 "x86/x86.md"*)
                      structure MemRegs : MEMORY_REGISTERS where I=Instr
                     ) : INSTRUCTION_EMITTER =
struct
   structure I  = Instr
   structure C  = I.C
   structure S  = Stream
   structure P  = S.P
   structure LabelExp = I.LabelExp
   structure Constant = I.Constant
   
   val show_cellset = MLRiscControl.getFlag "asm-show-cellset"
   val show_region  = MLRiscControl.getFlag "asm-show-region"
   
   fun error msg = MLRiscErrorMsg.error("X86AsmEmitter",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 := !tabs + 1
       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(Label.nameOf lab)
       fun emit_labexp le = emit(LabelExp.toString 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(Label.nameOf lab^":\n")
       fun entryLabel lab = defineLabel lab
       fun comment msg = emit("\t/* " ^ msg ^ " */")
       fun annotation a = (comment(Annotations.toString a); nl())
       fun doNothing _ = ()
       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)
       fun init size = (comment("Code Size = " ^ ms size); nl())
       fun emitter regmap =
       let
           val emitRegInfo = AsmFormatUtil.reginfo
                                (emit,regmap,formatAnnotations)
   fun emit_GP r = 
       ( emit (C.showGP (regmap r)); 
       emitRegInfo r )
   and emit_FP r = 
       ( emit (C.showFP (regmap r)); 
       emitRegInfo r )
   and emit_CC r = 
       ( emit (C.showCC (regmap r)); 
       emitRegInfo r )
   and emit_MEM r = 
       ( emit (C.showMEM (regmap r)); 
       emitRegInfo r )
   and emit_CTRL r = 
       ( emit (C.showCTRL (regmap r)); 
       emitRegInfo r )
   
       fun emit_cellset(title,cellset) =
         (nl(); comment(title^C.cellsetToString' regmap 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)
   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.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.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.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"
   and emit_binaryOp x = emit (asm_binaryOp x)
   and asm_multDivOp (I.UMUL) = "umul"
     | asm_multDivOp (I.IDIV) = "idiv"
     | asm_multDivOp (I.UDIV) = "udiv"
   and emit_multDivOp x = emit (asm_multDivOp x)
   and asm_unaryOp (I.DECL) = "decl"
     | asm_unaryOp (I.INCL) = "incl"
     | asm_unaryOp (I.NEGL) = "negl"
     | asm_unaryOp (I.NOTL) = "notl"
     | asm_unaryOp (I.NOTW) = "notw"
     | asm_unaryOp (I.NOTB) = "notb"
   and emit_unaryOp x = emit (asm_unaryOp x)
   and asm_move (I.MOVL) = "movl"
     | asm_move (I.MOVB) = "movb"
     | asm_move (I.MOVW) = "movw"
     | asm_move (I.MOVSWL) = "movswl"
     | asm_move (I.MOVZWL) = "movzwl"
     | asm_move (I.MOVSBL) = "movsbl"
     | asm_move (I.MOVZBL) = "movzbl"
   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.FABS) = "fabs"
     | asm_funOp (I.FCHS) = "fchs"
     | asm_funOp (I.FSIN) = "fsin"
     | asm_funOp (I.FCOS) = "fcos"
     | asm_funOp (I.FTAN) = "ftan"
     | asm_funOp (I.FSCALE) = "fscale"
     | asm_funOp (I.FRNDINT) = "frndint"
     | asm_funOp (I.FSQRT) = "fsqrt"
     | asm_funOp (I.FTST) = "ftst"
     | asm_funOp (I.FXAM) = "fxam"
     | asm_funOp (I.FINCSTP) = "fincstp"
     | asm_funOp (I.FDECSTP) = "fdecstp"
   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)

(*#line 183.6 "x86/x86.md"*)
   val memReg = MemRegs.memReg regmap

(*#line 184.6 "x86/x86.md"*)
   fun emitInt32 i = let

(*#line 185.10 "x86/x86.md"*)
          val s = Int32.toString i

(*#line 186.10 "x86/x86.md"*)
          val s = (if (i >= 0)
                 then s
                 else ("-" ^ (String.substring (s, 1, (size s) - 1))))
       in emit s
       end


(*#line 189.6 "x86/x86.md"*)
   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 r => emit_GP r
      | I.MemReg r => emit_operand (memReg opn)
      | I.ST f => emit_FP f
      | I.FDirect f => emit_operand (memReg opn)
      | I.Displace{base, disp, mem, ...} => 
        ( emit_disp disp; 
        emit "("; 
        emit_GP base; 
        emit ")"; 
        emit_region mem )
      | I.Indexed{base=NONE, index, scale, disp, mem, ...} => 
        ( emit_disp disp; 
        emit "("; 
        emit_GP index; 
        comma (); 
        emitScale scale; 
        emit ")"; 
        emit_region mem )
      | I.Indexed{base=SOME base, index, scale, disp, mem, ...} => 
        ( emit_disp disp; 
        emit "("; 
        emit_GP base; 
        comma (); 
        emit_GP index; 
        comma (); 
        emitScale scale; 
        emit ")"; 
        emit_region mem )
       )
   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 228.7 "x86/x86.md"*)
   fun stupidGas (I.ImmedLabel lexp) = emit_labexp lexp
     | stupidGas (I.LabelEA _) = error "stupidGas"
     | stupidGas opnd = emit_operand opnd

(*#line 233.7 "x86/x86.md"*)
   fun isMemOpnd (I.MemReg _) = true
     | isMemOpnd (I.FDirect f) = true
     | isMemOpnd (I.LabelEA _) = true
     | isMemOpnd (I.Displace _) = true
     | isMemOpnd (I.Indexed _) = true
     | isMemOpnd _ = false

(*#line 239.7 "x86/x86.md"*)
   fun chop fbinOp = let

(*#line 240.15 "x86/x86.md"*)
          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 246.7 "x86/x86.md"*)
   val emit_dst = emit_operand

(*#line 247.7 "x86/x86.md"*)
   val emit_src = emit_operand

(*#line 248.7 "x86/x86.md"*)
   val emit_opnd = emit_operand

(*#line 249.7 "x86/x86.md"*)
   val emit_rsrc = emit_operand

(*#line 250.7 "x86/x86.md"*)
   val emit_lsrc = emit_operand

(*#line 251.7 "x86/x86.md"*)
   val emit_addr = emit_operand

(*#line 252.7 "x86/x86.md"*)
   val emit_src1 = emit_operand
   fun emitInstr instr = 
       ( tab (); 
       
       (
        case instr of
        I.NOP => emit "nop"
      | I.JMP(operand, label) => 
        ( emit "jmp\t"; 
        stupidGas operand )
      | I.JCC{cond, opnd} => 
        ( emit "j"; 
        emit_cond cond; 
        emit "\t"; 
        stupidGas opnd )
      | I.CALL(operand, cellset1, cellset2, region) => 
        ( emit "call\t"; 
        stupidGas operand; 
        emit_region region; 
        emit_defs cellset1; 
        emit_uses cellset2 )
      | I.LEAVE => emit "leave"
      | I.RET operand => 
        ( emit "ret"; 
        
        (
         case operand 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_GP r32 )
      | 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.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.BINARY{binOp, src, dst} => 
        (
         case (src, binOp) of
         (I.Direct _, (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.MULTDIV{multDivOp, src} => 
        ( emit_multDivOp multDivOp; 
        emit "l\t"; 
        emit_src src )
      | I.MUL3{dst, src2, src1} => 
        (
         case src2 of
         NONE => 
         ( emit "imul\t"; 
         emit_src1 src1; 
         emit ", "; 
         emit_GP dst )
       | SOME i => 
         ( emit "imul\t$"; 
         emitInt32 i; 
         emit ", "; 
         emit_src1 src1; 
         emit ", "; 
         emit_GP 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_opnd opnd )
      | I.CMOV{cond, src, dst} => 
        ( emit "cmov"; 
        emit_cond cond; 
        emit "\t"; 
        emit_src src; 
        emit ", "; 
        emit_GP dst )
      | 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.POP operand => 
        ( emit "popl\t"; 
        emit_operand operand )
      | I.CDQ => emit "cdq"
      | I.INTO => emit "into"
      | I.COPY{dst, src, tmp} => emitInstrs (Shuffle.shuffle {regmap=regmap, tmp=tmp, dst=dst, src=src})
      | I.FCOPY{dst, src, tmp} => emitInstrs (Shuffle.shufflefp {regmap=regmap, tmp=tmp, dst=dst, src=src})
      | I.FBINARY{binOp, src, dst} => (if (isMemOpnd src)
           then 
           ( emit_fbinOp binOp; 
           emit "\t"; 
           emit_src src )
           else 
           ( emit (chop (asm_fbinOp binOp)); 
           emit "\t"; 
           emit_src src; 
           emit ", "; 
           emit_dst dst ))
      | I.FIBINARY{binOp, src} => 
        ( emit_fibinOp binOp; 
        emit "\t"; 
        emit_src src )
      | I.FUNARY funOp => emit_funOp funOp
      | I.FUCOMPP => emit "fucompp"
      | I.FCOMPP => emit "fcompp"
      | I.FXCH{opnd} => 
        ( emit "fxch\t"; 
        (if (opnd = (C.ST 1))
           then ()
           else (emit_FP opnd)))
      | I.FSTPL 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.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 => 
        ( 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.SAHF => emit "sahf"
      | I.ANNOTATION{i, a} => 
        ( emitInstr i; 
        comment (Annotations.toString a))
       ); 
       nl ())
          and emitInstrs [] = ()
            | emitInstrs (i::is) =
           (emitInstr i; app (fn i => (tab(); emitInstr i)) is)
      in  emitInstr end
   
   in  S.STREAM{beginCluster=init,
                pseudoOp=pseudoOp,
                emit=emitter,
                endCluster=doNothing,
                defineLabel=defineLabel,
                entryLabel=entryLabel,
                comment=comment,
                exitBlock=doNothing,
                annotation=annotation,
                phi=doNothing,
                alias=doNothing
               }
   end
end


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