]> Joshua Wise's Git repositories - snipe.git/blobdiff - codegen/x86.sml
Initial import of l2c
[snipe.git] / codegen / x86.sml
index b7055f6f326189da2c4bf471beeb4ca3a7b02c14..33ddd60914bbe880e36904ace59226e6a7edf097 100644 (file)
@@ -1,28 +1,60 @@
+(* L2 compiler
+ * X86 instruction/operand internal representation and manipulation
+ * Author: Joshua Wise <jwise@andrew.cmu.edu>
+ * Author: Chris Lu <czl@andrew.cmu.edu>
+ *)
+
 signature X86 =
 sig
 signature X86 =
 sig
+  (* register type *)
   datatype reg =
     EAX | EBX | ECX | EDX | ESI | EDI | EBP | RSP | R8D | R9D | R10D | R11D | R12D | R13D | R14D | R15D
   datatype reg =
     EAX | EBX | ECX | EDX | ESI | EDI | EBP | RSP | R8D | R9D | R10D | R11D | R12D | R13D | R14D | R15D
+  (* operands to instructions *)
   datatype oper = REG of reg | TEMP of Temp.temp | CONST of Word32.word | REL of (reg * int)
   datatype oper = REG of reg | TEMP of Temp.temp | CONST of Word32.word | REL of (reg * int)
+  (* instructions
+   * a better way to do SET would be SET of cc * oper,
+   * same with JMP
+   *)
   datatype insn =
     DIRECTIVE of string |
     COMMENT of string |
   datatype insn =
     DIRECTIVE of string |
     COMMENT of string |
+    LABEL of Label.label |
     MOVL of oper * oper |
     SUBL of oper * oper |
     IMUL of oper * oper |
     IMUL3 of oper * oper * Word32.word |
     ADDL of oper * oper |
     MOVL of oper * oper |
     SUBL of oper * oper |
     IMUL of oper * oper |
     IMUL3 of oper * oper * Word32.word |
     ADDL of oper * oper |
-    LEAL of oper * oper * oper |
     IDIVL of oper |
     NEG of oper |
     IDIVL of oper |
     NEG of oper |
+    NOTL of oper |
+    SALL of oper * oper |
+    SARL of oper * oper |
+    ANDL of oper * oper |
+    ORL of oper * oper |
+    XORL of oper * oper |
+    CMPL of oper * oper |
+    TEST of oper * oper |
+    SETNE of oper |
+    SETE of oper |
+    SETLE of oper |
+    SETL of oper |
+    SETGE of oper |
+    SETG of oper |
+    JMP of Label.label |
+    JE of Label.label |
+    JNE of Label.label |
+    MOVZBL of oper * oper |
     CLTD |
     RET
   
   val cmpoper : oper * oper -> order
   val opereq : oper * oper -> bool
   val regname : reg -> string
     CLTD |
     RET
   
   val cmpoper : oper * oper -> order
   val opereq : oper * oper -> bool
   val regname : reg -> string
+  val regnameb : reg -> string
   val regtonum : reg -> int
   val numtoreg : int -> reg
   val prettyprint_oper : oper -> string
   val regtonum : reg -> int
   val numtoreg : int -> reg
   val prettyprint_oper : oper -> string
+  val prettyprint_operb : oper -> string
   val prettyprint : insn -> string
 end
 
   val prettyprint : insn -> string
 end
 
@@ -34,17 +66,36 @@ struct
   datatype insn =
     DIRECTIVE of string |
     COMMENT of string |
   datatype insn =
     DIRECTIVE of string |
     COMMENT of string |
+    LABEL of Label.label |
     MOVL of oper * oper |
     SUBL of oper * oper |
     IMUL of oper * oper |
     IMUL3 of oper * oper * Word32.word |
     ADDL of oper * oper |
     MOVL of oper * oper |
     SUBL of oper * oper |
     IMUL of oper * oper |
     IMUL3 of oper * oper * Word32.word |
     ADDL of oper * oper |
-    LEAL of oper * oper * oper |
     IDIVL of oper |
     NEG of oper |
     IDIVL of oper |
     NEG of oper |
+    NOTL of oper |
+    SALL of oper * oper |
+    SARL of oper * oper |
+    ANDL of oper * oper |
+    ORL of oper * oper |
+    XORL of oper * oper |
+    CMPL of oper * oper |
+    TEST of oper * oper |
+    SETNE of oper |
+    SETE of oper |
+    SETLE of oper |
+    SETL of oper |
+    SETGE of oper |
+    SETG of oper |
+    JMP of Label.label |
+    JE of Label.label |
+    JNE of Label.label |
+    MOVZBL of oper * oper |
     CLTD |
     RET
     CLTD |
     RET
-  
+
+  (* gives name of reg *)
   fun regname EAX = "eax"
     | regname EBX = "ebx"
     | regname ECX = "ecx"
   fun regname EAX = "eax"
     | regname EBX = "ebx"
     | regname ECX = "ecx"
@@ -61,7 +112,26 @@ struct
     | regname R13D = "r13d"
     | regname R14D = "r14d"
     | regname R15D = "r15d"
     | regname R13D = "r13d"
     | regname R14D = "r14d"
     | regname R15D = "r15d"
-  
+
+  (* like regname, but for the byte name *)
+  fun regnameb EAX = "al"
+    | regnameb EBX = "bl"
+    | regnameb ECX = "cl"
+    | regnameb EDX = "dl"
+    | regnameb ESI = "sil"
+    | regnameb EDI = "dil"
+    | regnameb EBP = "bpl"
+    | regnameb RSP = "spl"
+    | regnameb R8D = "r8b"
+    | regnameb R9D = "r9b"
+    | regnameb R10D = "r10b"
+    | regnameb R11D = "r11b"
+    | regnameb R12D = "r12b"
+    | regnameb R13D = "r13b"
+    | regnameb R14D = "r14b"
+    | regnameb R15D = "r15b"
+
+  (* gives number (color) associated with reg *)
   fun regtonum EAX = 0
     | regtonum EBX = 1
     | regtonum ECX = 2
   fun regtonum EAX = 0
     | regtonum EBX = 1
     | regtonum ECX = 2
@@ -78,7 +148,8 @@ struct
     | regtonum R15D = 13
     | regtonum EBP = 14                (* Dummy numbers -- not permitted for allocation, but there so that we can compare *)
     | regtonum RSP = 15
     | regtonum R15D = 13
     | regtonum EBP = 14                (* Dummy numbers -- not permitted for allocation, but there so that we can compare *)
     | regtonum RSP = 15
-  
+
+  (* gives reg associated with number (color) *)
   fun numtoreg 0 = EAX
     | numtoreg 1 = EBX
     | numtoreg 2 = ECX
   fun numtoreg 0 = EAX
     | numtoreg 1 = EBX
     | numtoreg 2 = ECX
@@ -94,9 +165,13 @@ struct
     | numtoreg 12 = R14D
     | numtoreg 13 = R15D
     | numtoreg n = raise ErrorMsg.InternalError ("numtoreg: Unknown register "^(Int.toString n))
     | numtoreg 12 = R14D
     | numtoreg 13 = R15D
     | numtoreg n = raise ErrorMsg.InternalError ("numtoreg: Unknown register "^(Int.toString n))
-  
+
+  (* register compare *)
   fun regcmp (r1, r2) = Int.compare (regtonum r1, regtonum r2)
 
   fun regcmp (r1, r2) = Int.compare (regtonum r1, regtonum r2)
 
+  (* 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)
   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)
@@ -112,28 +187,55 @@ struct
     | cmpoper (REG _, _) = LESS
     | cmpoper (REL _, _) = LESS
     | cmpoper (_, _) = GREATER
     | cmpoper (REG _, _) = LESS
     | cmpoper (REL _, _) = LESS
     | cmpoper (_, _) = GREATER
-  
+
   fun opereq (a, b) = cmpoper (a, b) = EQUAL
   fun opereq (a, b) = cmpoper (a, b) = EQUAL
-  
+
+  (* integer tostring, except with more - and less ~ *)
   fun moreDifferentToString (i) =
        if (i >= 0) then Int.toString i
        else "-" ^ (Int.toString (~i))
   fun moreDifferentToString (i) =
        if (i >= 0) then Int.toString i
        else "-" ^ (Int.toString (~i))
-  
+
+  (* pretty prints an operand *)  
   fun prettyprint_oper (REG r) = "%" ^ (regname r)
     | prettyprint_oper (TEMP t) = Temp.name t
     | prettyprint_oper (CONST c) = "$0x" ^ (Word32.toString c)
     | prettyprint_oper (REL (r, i)) = (moreDifferentToString i) ^ "(%" ^ (regname r) ^ ")"
 
   fun prettyprint_oper (REG r) = "%" ^ (regname r)
     | prettyprint_oper (TEMP t) = Temp.name t
     | prettyprint_oper (CONST c) = "$0x" ^ (Word32.toString c)
     | prettyprint_oper (REL (r, i)) = (moreDifferentToString i) ^ "(%" ^ (regname r) ^ ")"
 
+  (* pretty prints an operand as a byte *)
+  fun prettyprint_operb (REG r) = "%" ^ (regnameb r)
+    | prettyprint_operb (TEMP t) = Temp.name t ^ "b"
+    | prettyprint_operb (CONST c) = "$0x" ^ (Word32.toString (c mod 0w32))
+    | prettyprint_operb x = prettyprint_oper x
+
+  (* pretty prints (no...) *)
   fun prettyprint (DIRECTIVE(str)) = str ^ "\n"
     | prettyprint (COMMENT(str)) = "// " ^ str ^ "\n"
   fun prettyprint (DIRECTIVE(str)) = str ^ "\n"
     | prettyprint (COMMENT(str)) = "// " ^ str ^ "\n"
+    | prettyprint (LABEL(l)) = Label.name l ^ "\n"
     | prettyprint (MOVL(src, dst)) = "\tMOVL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (SUBL(src, dst)) = "\tSUBL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (IMUL(src, dst)) = "\tIMUL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (IMUL3(dst, tmp, const)) = "\tIMUL\t" ^ (prettyprint_oper (CONST const)) ^ ", " ^ (prettyprint_oper tmp) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (ADDL(src, dst)) = "\tADDL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (MOVL(src, dst)) = "\tMOVL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (SUBL(src, dst)) = "\tSUBL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (IMUL(src, dst)) = "\tIMUL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (IMUL3(dst, tmp, const)) = "\tIMUL\t" ^ (prettyprint_oper (CONST const)) ^ ", " ^ (prettyprint_oper tmp) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (ADDL(src, dst)) = "\tADDL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
-    | prettyprint (LEAL(src1, src2, dst)) = "\tLEAL\t(" ^ (prettyprint_oper src1) ^ "," ^ (prettyprint_oper src2) ^ ")," ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (IDIVL(src)) = "\tIDIVL\t" ^ (prettyprint_oper src) ^ "\n"
     | prettyprint (NEG (src)) = "\tNEG\t" ^ (prettyprint_oper src) ^ "\n"
     | prettyprint (IDIVL(src)) = "\tIDIVL\t" ^ (prettyprint_oper src) ^ "\n"
     | prettyprint (NEG (src)) = "\tNEG\t" ^ (prettyprint_oper src) ^ "\n"
+    | prettyprint (NOTL (src)) = "\tNOTL\t" ^ (prettyprint_oper src) ^ "\n"
+    | prettyprint (SALL (dst, shft)) = "\tSALL\t" ^ (prettyprint_oper dst) ^ ", " ^ (prettyprint_operb shft) ^ "\n"
+    | prettyprint (SARL (dst, shft)) = "\tSARL\t" ^ (prettyprint_oper dst) ^ ", " ^ (prettyprint_operb shft) ^ "\n"
+    | prettyprint (ANDL(src, dst)) = "\tANDL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
+    | prettyprint (ORL(src, dst)) = "\tORL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
+    | prettyprint (XORL(src, dst)) = "\tXORL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
+    | prettyprint (CMPL(src, dst)) = "\tCMPL\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
+    | prettyprint (TEST(src, dst)) = "\tTEST\t" ^ (prettyprint_oper src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
+    | prettyprint (SETNE(dst)) = "\tSETNE\t" ^ (prettyprint_operb dst) ^ "\n"
+    | prettyprint (SETE(dst)) = "\tSETE\t" ^ (prettyprint_operb dst) ^ "\n"
+    | prettyprint (SETLE(dst)) = "\tSETLE\t" ^ (prettyprint_operb dst) ^ "\n"
+    | prettyprint (SETL(dst)) = "\tSETL\t" ^ (prettyprint_operb dst) ^ "\n"
+    | prettyprint (SETGE(dst)) = "\tSETGE\t" ^ (prettyprint_operb dst) ^ "\n"
+    | prettyprint (SETG(dst)) = "\tSETG\t" ^ (prettyprint_operb dst) ^ "\n"
+    | prettyprint (JMP(label)) = "\tJMP\t" ^ (Label.name label) ^ "\n"
+    | prettyprint (JE(label)) = "\tJE\t" ^ (Label.name label) ^ "\n"
+    | prettyprint (JNE(label)) = "\tJNE\t" ^ (Label.name label) ^ "\n"
+    | prettyprint (MOVZBL(src, dst)) = "\tMOVZBL\t" ^ (prettyprint_operb src) ^ ", " ^ (prettyprint_oper dst) ^ "\n"
     | prettyprint (CLTD) = "\tCLTD\n"
     | prettyprint (RET) = "\tRET\n"
 (*    | prettyprint _ = raise ErrorMsg.InternalError ("prettyprint: unknown instruction")*)
     | prettyprint (CLTD) = "\tCLTD\n"
     | prettyprint (RET) = "\tRET\n"
 (*    | prettyprint _ = raise ErrorMsg.InternalError ("prettyprint: unknown instruction")*)
This page took 0.029287 seconds and 4 git commands to generate.