]> Joshua Wise's Git repositories - snipe.git/blobdiff - codegen/x86.sml
Initial import of l5c
[snipe.git] / codegen / x86.sml
index e54d4beb2b0ec77085398cf5368e31670df14413..c0ff0b8a9ec8fdbafa692d5127c3d203b2fe7c1f 100644 (file)
@@ -10,15 +10,20 @@ sig
   datatype reg =
     EAX | EBX | ECX | EDX | ESI | EDI | EBP | RSP | R8D | R9D | R10D | R11D | R12D | R13D | R14D | R15D
   (* operands to instructions *)
-  datatype size = Byte | Word | Long | Qword
-  datatype oper = REG of reg | TEMP of Temp.temp | CONST of Word32.word | REL of (oper * oper) | STACKARG of int | OSIZE of (size * oper)
-  datatype cc = E | NE | GE | LE | L | G
+  datatype basicop = REG of reg |
+                     TEMP of Temp.temp |
+                     CONST of Word32.word |
+                     REL of ((basicop * Temp.size) * (basicop * Temp.size) * Word32.word) |
+                     STACKARG of int
+  type oper = basicop * Temp.size
+  datatype cc = E | NE | GE | LE | L | G | B | BE | A | AE
   (* instructions *)
   datatype insn =
     DIRECTIVE of string |
     COMMENT of string |
     LABEL of Label.label |
     MOV of oper * oper |
+    MOVSC of oper * oper |
     LEA of oper * oper |
     SUB of oper * oper |
     IMUL of oper * oper |
@@ -35,6 +40,7 @@ sig
     CMP of oper * oper |
     TEST of oper * oper |
     SETcc of cc * oper |
+    CMOVcc of cc * oper * oper |
     JMP of Label.label |
     Jcc of cc * Label.label |
     CALL of Symbol.symbol * int |
@@ -42,41 +48,48 @@ sig
     CLTD |
     LIVEIGN of insn |
     RET
-  
+
   structure OperSet : ORD_SET
-    where type Key.ord_key = oper;
+    where type Key.ord_key = basicop;
   structure LiveMap : ORD_MAP
     where type Key.ord_key = int;
   
-  val sts : int -> size
-  val sizeoper : oper -> size * oper
-  val stripsize : oper -> oper
-  val osize : oper -> size
+  val resize : Temp.size -> oper -> oper
+  val regcmp : reg * reg -> order
+  val getop : oper -> basicop
+  val osize : oper -> Temp.size
   val cmpoper : oper * oper -> order
+  val cmpbasic : basicop * basicop -> order
   val opereq : oper * oper -> bool
-  val regname : size -> reg -> string
+  val basiceq : basicop * basicop -> bool
+  val regname : Temp.size -> reg -> string
   val regtonum : reg -> int
   val numtoreg : int -> reg
   val ccname : cc -> string
   val opsused : insn list -> OperSet.set
-  val prettyprint_oper : size -> oper -> string
-  val prettyprint : insn -> string
+  val pp_oper : oper -> string
+  val print : insn -> string
 end
 
 structure x86 :> X86 =
 struct
 
-
   datatype reg =
     EAX | EBX | ECX | EDX | ESI | EDI | EBP | RSP | R8D | R9D | R10D | R11D | R12D | R13D | R14D | R15D
-  datatype size = Byte | Word | Long | Qword
-  datatype oper = REG of reg | TEMP of Temp.temp | CONST of Word32.word | REL of (oper * oper) | STACKARG of int | OSIZE of (size * oper)
-  datatype cc = E | NE | GE | LE | L | G
+  (* operands to instructions *)
+  datatype basicop = REG of reg |
+                     TEMP of Temp.temp |
+                     CONST of Word32.word |
+                     REL of ((basicop * Temp.size) * (basicop * Temp.size) * Word32.word) |
+                     STACKARG of int
+  datatype cc = E | NE | GE | LE | L | G | B | BE | A | AE
+  type oper = basicop * Temp.size
   datatype insn =
     DIRECTIVE of string |
     COMMENT of string |
     LABEL of Label.label |
     MOV of oper * oper |
+    MOVSC of oper * oper |
     LEA of oper * oper |
     SUB of oper * oper |
     IMUL of oper * oper |
@@ -93,6 +106,7 @@ struct
     CMP of oper * oper |
     TEST of oper * oper |
     SETcc of cc * oper |
+    CMOVcc of cc * oper * oper |
     JMP of Label.label |
     Jcc of cc * Label.label |
     CALL of Symbol.symbol * int |
@@ -127,10 +141,10 @@ struct
       val (n, (b, w, l, q)) = valOf (List.find (fn (r, _) => r = reg) regnames)
     in
       case sz
-      of Byte => b
-       | Word => w
-       | Long => l
-       | Qword => q
+      of Temp.Byte => b
+       | Temp.Word => w
+       | Temp.Long => l
+       | Temp.Quad => q
     end
 
   fun ccname E  = "e"
@@ -139,6 +153,10 @@ struct
     | ccname LE = "le"
     | ccname G  = "g"
     | ccname L  = "l"
+    | ccname B  = "b"
+    | ccname A  = "a"
+    | ccname AE  = "ae"
+    | ccname BE  = "be"
 
   (* gives number (color) associated with reg *)
   fun regtonum EAX = 0
@@ -151,11 +169,11 @@ struct
     | regtonum R10D = 7
     | regtonum R11D = 8
     | regtonum EBX = 9
-    | regtonum R12D = 10
-    | regtonum R13D = 11
-    | regtonum R14D = 12
-    | regtonum R15D = 13
-    | regtonum EBP = 14                (* Dummy numbers -- not permitted for allocation, but there so that we can compare *)
+    | regtonum EBP = 10
+    | regtonum R12D = 11
+    | regtonum R13D = 12
+    | regtonum R14D = 13
+    | regtonum R15D = 14
     | regtonum RSP = 15
 
   (* gives reg associated with number (color) *)
@@ -169,45 +187,54 @@ struct
     | numtoreg 7 = R10D
     | numtoreg 8 = R11D
     | numtoreg 9 = EBX
-    | numtoreg 10 = R12D
-    | numtoreg 11 = R13D
-    | numtoreg 12 = R14D
-    | numtoreg 13 = R15D
-    | numtoreg n = raise ErrorMsg.InternalError ("numtoreg: Unknown register "^(Int.toString n))
+    | numtoreg 10 = EBP
+    | numtoreg 11 = R12D
+    | numtoreg 12 = R13D
+    | numtoreg 13 = R14D
+    | numtoreg 14 = R15D
+    | numtoreg n = raise ErrorMsg.InternalError ("numtoreg: Invalid register "^(Int.toString n))
 
   (* register compare *)
   fun regcmp (r1, r2) = Int.compare (regtonum r1, regtonum r2)
+  fun osize (_,s) = s
+  fun resize ss (a,_) = (a,ss)
+  fun getop (a,_) = a
 
   (* operand compare; arbitrary order imposed to make
    * various things easier (e.g. liveness, for sorting)
    *)
-  fun cmpoper (REG(reg1), REG(reg2)) = regcmp (reg1, reg2)
-    | cmpoper (TEMP(temp1), TEMP(temp2)) = Temp.compare (temp1,temp2)
-    | cmpoper (CONST(const1), CONST(const2)) = Word32.compare (const1, const2)
-    | cmpoper (REL (r1, i1), REL (r2, i2)) =
-        let 
-          val order1 = cmpoper (r1, r2)
-          val order2 = cmpoper (i1, i2)
+  fun cmpbasic (REG reg1, REG reg2) = regcmp (reg1, reg2)
+    | cmpbasic (TEMP temp1, TEMP temp2) = Temp.compare (temp1,temp2)
+    | cmpbasic (CONST(const1), CONST(const2)) = Word32.compare (const1, const2)
+    | cmpbasic (REL (r1, i1, m1), REL (r2, i2, m2)) =
+        let
+          val orderm = Word32.compare (m1,m2)
+          val order1 = cmpbasic (getop r1, getop r2)
+          val order2 = cmpbasic (getop i1, getop i2)
+          val o1 = if(order1 = EQUAL) then order2 else order1
         in
-          if (order1 = EQUAL) then order2
-          else order1
+          if (o1 = EQUAL) then orderm
+          else o1
         end
-    | cmpoper (CONST _, _) = LESS
-    | cmpoper (REG _, _) = LESS
-    | cmpoper (REL _, _) = LESS
-    | cmpoper (_, _) = GREATER
+    | cmpbasic (CONST _, _) = LESS
+    | cmpbasic (REG _, _) = LESS
+    | cmpbasic (REL _, _) = LESS
+    | cmpbasic (_, _) = GREATER
+
+  fun cmpoper ((o1,s1),(o2,s2)) = (case (cmpbasic (o1,o2)) of EQUAL => Temp.cmpsize (s1,s2) | a => a)
+
+  fun basiceq (REG a, REG b) = a = b
+    | basiceq (TEMP a, TEMP b) = Temp.eq (a, b)
+    | basiceq (CONST a, CONST b) = a = b
+    | basiceq (REL (a1, b1, m1), REL (a2, b2, m2)) = m1 = m2 andalso basiceq (getop a1, getop a2) andalso basiceq (getop b1, getop b2)
+    | basiceq (_, _) = false
+
+  fun opereq ((o1,s1),(o2,s2)) = basiceq (o1,o2) andalso s1 = s2
 
-  fun opereq (REG a, REG b) = a = b
-    | opereq (TEMP a, TEMP b) = Temp.eq (a, b)
-    | opereq (CONST a, CONST b) = a = b
-    | opereq (REL (a1, b1), REL (a2, b2)) = opereq (a1,a2) andalso opereq (b1,b2)
-(*    | opereq (OSIZE (s1, o1), OSIZE (s2, o2)) = (s1 = s2) andalso opereq (o1, o2)*) (* This breaks the peepholer, shit *)
-    | opereq (_, _) = false
-    
   structure OperSet = ListSetFn (
     struct
-      type ord_key = oper
-      val compare = cmpoper
+      type ord_key = basicop
+      val compare = cmpbasic
     end)
   
   structure LiveMap = SplayMapFn(struct
@@ -219,87 +246,73 @@ struct
     | opsused ((DIRECTIVE _)::l) = opsused l
     | opsused ((COMMENT _)::l) = opsused l
     | opsused ((LABEL _)::l) = opsused l
-    | opsused ((MOV (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((LEA (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((SUB (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((IMUL (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((IMUL3 (dst, src, _))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((ADD (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((IDIV (src))::l) = OperSet.addList (opsused l, [src, REG EDX, REG EAX])
-    | opsused ((NEG (dst))::l) = OperSet.addList (opsused l, [dst])
-    | opsused ((NOT (dst))::l) = OperSet.addList (opsused l, [dst])
-    | opsused ((SAL (dst, shft))::l) = OperSet.addList (opsused l, [dst, shft])
-    | opsused ((SAR (dst, shft))::l) = OperSet.addList (opsused l, [dst, shft])
-    | opsused ((AND (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((OR (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((XOR (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((CMP (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((TEST (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
-    | opsused ((SETcc (c, dst))::l) = OperSet.addList (opsused l, [dst])
+    | opsused ((MOV ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((MOVSC((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((LEA ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((SUB ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((IMUL ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((IMUL3 ((dst,_), (src,_), _))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((ADD ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((IDIV (src,_))::l) = OperSet.addList (opsused l, [src, REG EDX, REG EAX])
+    | opsused ((NEG (dst,_))::l) = OperSet.addList (opsused l, [dst])
+    | opsused ((NOT (dst,_))::l) = OperSet.addList (opsused l, [dst])
+    | opsused ((SAL ((dst,_), (shft,_)))::l) = OperSet.addList (opsused l, [dst, shft])
+    | opsused ((SAR ((dst,_), (shft,_)))::l) = OperSet.addList (opsused l, [dst, shft])
+    | opsused ((AND ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((OR ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((XOR ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((CMP ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((TEST ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((SETcc (c, (dst,_)))::l) = OperSet.addList (opsused l, [dst])
+    | opsused ((CMOVcc (c, (dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
     | opsused ((JMP _)::l) = opsused l
     | opsused ((Jcc _)::l) = opsused l
     | opsused ((CALL _)::l) = opsused l
-    | opsused ((MOVZB (dst, src))::l) = OperSet.addList (opsused l, [dst, src])
+    | opsused ((MOVZB ((dst,_), (src,_)))::l) = OperSet.addList (opsused l, [dst, src])
     | opsused ((CLTD)::l) = opsused l
     | opsused ((RET)::l) = opsused l
     | opsused ((LIVEIGN i)::l) = opsused (i::l)
 
-  fun sts 8 = Qword
-    | sts 4 = Long
-    | sts 2 = Word
-    | sts 1 = Byte
-    | sts _ = raise ErrorMsg.InternalError "invalid size"
-
-  (* pretty prints an operand *)  
-  fun sfx Byte = "b"
-    | sfx Word = "w"
-    | sfx Long = "l"
-    | sfx Qword = "q"
-
-  fun osize (OSIZE (s, _)) = s
-    | osize _ = Long
-
-  fun stripsize (OSIZE (_, oo)) = stripsize oo
-    | stripsize oo = oo
-
-  fun sizeoper (OSIZE (s, oo)) = (s, stripsize oo)
-    | sizeoper oo = (Long, oo)
 
-  fun prettyprint_oper s (REG r) = "%" ^ (regname s r)
-    | prettyprint_oper _ (TEMP t) = (Temp.name t) ^ (sfx (sts (Temp.size t)))
-    | prettyprint_oper _ (CONST c) = "$0x" ^ (Word32.toString c)
-    | prettyprint_oper _ (REL (r, CONST n)) = (Word32Signed.toString n) ^ "(" ^ (prettyprint_oper Qword r) ^ ")"
-    | prettyprint_oper s (REL (r1, r2)) = "(" ^ (prettyprint_oper Qword (stripsize r1)) ^ "," ^ (prettyprint_oper Qword (stripsize r2)) ^ ")"
-    | prettyprint_oper _ (STACKARG i) = "arg#"^Int.toString i
-    | prettyprint_oper _ (OSIZE (s, oo)) = prettyprint_oper s (stripsize oo)
+  fun pp_oper (REG r, s) = "%" ^ (regname s r)
+    | pp_oper (TEMP t, _) = (Temp.name t) ^ (Temp.sfx (Temp.size t))
+    | pp_oper (CONST c, _) = "$" ^ Word32Signed.toString c
+    | pp_oper (REL ((CONST n, _), _, _), _) = Word32Signed.toString n
+    | pp_oper (REL (r, (CONST n, _), _), _) = (Word32Signed.toString n) ^ "(" ^ (pp_oper r) ^ ")"
+    | pp_oper (REL (r1, r2, m), _) = "(" ^ (pp_oper r1) ^ "," ^ (pp_oper r2) ^ "," ^
+                                           (Word32.toString m) ^ ")"
+    | pp_oper (STACKARG i, _) = "arg#"^Int.toString i
 
-  (* pretty prints (no...) *)
-  fun prettyprint (DIRECTIVE(str)) = str ^ "\n"
-    | prettyprint (COMMENT(str)) = "// " ^ str ^ "\n"
-    | prettyprint (LABEL(l)) = Label.name l ^ ":\n"
-    | prettyprint (LEA(dst, src)) = "\tlea" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (MOV(dst, src)) = "\tmov" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (SUB(dst, src)) = "\tsub" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (IMUL(dst, src)) = "\timul" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (IMUL3(dst, tmp, const)) = "\timul" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (CONST const)) ^ ", " ^ (prettyprint_oper (osize dst) (stripsize tmp)) ^ ", " ^ (prettyprint_oper (osize dst) dst) ^ "\n"
-    | prettyprint (ADD(dst, src)) = "\tadd" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (IDIV(src)) = "\tidiv" ^ (sfx (osize src)) ^ "\t" ^ (prettyprint_oper (osize src) src) ^ "\n"
-    | prettyprint (NEG (dst)) = "\tneg" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (NOT (dst)) = "\tnot" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (SAL (dst, shft)) = "\tsal" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper Byte shft) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (SAR (dst, shft)) = "\tsar" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper Byte shft) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (AND (dst, src)) = "\tand" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (OR (dst, src)) = "\tor" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (XOR (dst, src)) = "\txor" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (CMP (dst, src)) = "\tcmp" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (TEST (dst, src)) = "\ttest" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper (osize dst) (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (SETcc (c, dst)) = "\tset" ^ (ccname c) ^ "\t" ^ (prettyprint_oper Byte (stripsize dst)) ^ "\n"
-    | prettyprint (JMP (label)) = "\tjmp\t" ^ (Label.name label) ^ "\n"
-    | prettyprint (Jcc (c,label)) = "\tj" ^ (ccname c) ^ "\t" ^ (Label.name label) ^ "\n"
-    | prettyprint (CALL (l,n)) = "\tcall\t" ^ Symbol.name l ^ "\t # (" ^ Int.toString n ^ "args)\n"
-    | prettyprint (MOVZB (dst, src)) = "\tmovzb" ^ (sfx (osize dst)) ^ "\t" ^ (prettyprint_oper Byte (stripsize src)) ^ ", " ^ (prettyprint_oper Long dst) ^ "\n"
-    | prettyprint (CLTD) = "\tcltd\n"
-    | prettyprint (RET) = "\tret\n"
-    | prettyprint (LIVEIGN i) = prettyprint i
-(*    | prettyprint _ = raise ErrorMsg.InternalError ("prettyprint: Type A? Hatchar de coneccion?")*)
+  (* pretty prints the asm *)
+  fun print (DIRECTIVE(str)) = str ^ "\n"
+    | print (COMMENT(str)) = "// " ^ str ^ "\n"
+    | print (LABEL(l)) = Label.name l ^ ":\n"
+    | print (LEA(dst, src)) = "\tlea" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (MOV(dst, src)) = "\tmov" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (MOVSC((d,Temp.Long), (s,Temp.Quad))) = "\tmov" ^ (Temp.sfx Temp.Long) ^ "\t" ^ (pp_oper (s,Temp.Long)) ^ ", " ^ (pp_oper (d,Temp.Long)) ^ " // sex change\n"
+    | print (MOVSC((d,Temp.Quad), (s,Temp.Long))) = "\tmov" ^ (Temp.sfx Temp.Long) ^ "\t" ^ (pp_oper (s,Temp.Long)) ^ ", " ^ (pp_oper (d,Temp.Long)) ^ " // sex change\n"
+    | print (MOVSC(_,_)) = raise ErrorMsg.InternalError "invalid size change"
+    | print (SUB(dst, src)) = "\tsub" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (IMUL(dst, src)) = "\timul" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (IMUL3(dst, tmp, const)) = "\timul" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper (CONST const, Temp.Long)) ^ ", " ^ (pp_oper tmp) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (ADD(dst, src)) = "\tadd" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (IDIV(src)) = "\tidiv" ^ (Temp.sfx (osize src)) ^ "\t" ^ (pp_oper src) ^ "\n"
+    | print (NEG (dst)) = "\tneg" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper dst) ^ "\n"
+    | print (NOT (dst)) = "\tnot" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper dst) ^ "\n"
+    | print (SAL (dst, shft)) = "\tsal" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper shft) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (SAR (dst, shft)) = "\tsar" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper shft) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (AND (dst, src)) = "\tand" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (OR (dst, src)) = "\tor" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (XOR (dst, src)) = "\txor" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (CMP (dst, src)) = "\tcmp" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (TEST (dst, src)) = "\ttest" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (SETcc (c, dst)) = "\tset" ^ (ccname c) ^ "\t" ^ (pp_oper dst) ^ "\n"
+    | print (CMOVcc (c, dst, src)) = "\tcmov" ^ (ccname c) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (JMP (label)) = "\tjmp\t" ^ (Label.name label) ^ "\n"
+    | print (Jcc (c,label)) = "\tj" ^ (ccname c) ^ "\t" ^ (Label.name label) ^ "\n"
+    | print (CALL (l,n)) = "\tcall\t" ^ Symbol.name l ^ "\t # (" ^ Int.toString n ^ "args)\n"
+    | print (MOVZB (dst, src)) = "\tmovzb" ^ (Temp.sfx (osize dst)) ^ "\t" ^ (pp_oper src) ^ ", " ^ (pp_oper dst) ^ "\n"
+    | print (CLTD) = "\tcltd\n"
+    | print (RET) = "\tret\n"
+    | print (LIVEIGN i) = print i
 end
This page took 0.034382 seconds and 4 git commands to generate.