Add binary encoding support for multiply instructions. Some blanks left to fill in...
[oota-llvm.git] / lib / Target / ARM / ARMInstrInfo.td
index 0ab0f9865fbc76698f24ec0e74e6d2630bc367e7..d2ea2b1088a9f73e2b3b4678b2dc5e578d0b66be 100644 (file)
@@ -310,10 +310,11 @@ def AddrMode2    : AddrMode<2>;
 def AddrMode3    : AddrMode<3>;
 def AddrMode4    : AddrMode<4>;
 def AddrMode5    : AddrMode<5>;
-def AddrModeT1   : AddrMode<6>;
-def AddrModeT2   : AddrMode<7>;
-def AddrModeT4   : AddrMode<8>;
-def AddrModeTs   : AddrMode<9>;
+def AddrMode6    : AddrMode<6>;
+def AddrModeT1   : AddrMode<7>;
+def AddrModeT2   : AddrMode<8>;
+def AddrModeT4   : AddrMode<9>;
+def AddrModeTs   : AddrMode<10>;
 
 // Instruction size.
 class SizeFlagVal<bits<3> val> {
@@ -344,13 +345,13 @@ include "ARMInstrFormats.td"
 /// AsI1_bin_irs - Defines a set of (op r, {so_imm|r|so_reg}) patterns for a
 /// binop that produces a value.
 multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode> {
-  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), BinaryFrm,
+  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPRIm,
                opc, " $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>;
-  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), BinaryFrm,
+  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPRReg,
                opc, " $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>;
-  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), BinaryFrm,
+  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPRSoReg,
                opc, " $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>;
 }
@@ -359,13 +360,13 @@ multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode> {
 /// instruction modifies the CSPR register.
 let Defs = [CPSR] in {
 multiclass ASI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode> {
-  def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), BinaryFrm,
+  def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPRImS,
                opc, "s $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>;
-  def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), BinaryFrm,
+  def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPRRegS,
                opc, "s $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>;
-  def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), BinaryFrm,
+  def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPRSoRegS,
                opc, "s $dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>;
 }
@@ -376,13 +377,13 @@ multiclass ASI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode> {
 /// a explicit result, only implicitly set CPSR.
 let Defs = [CPSR] in {
 multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode> {
-  def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), UnaryFrm,
+  def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPRnIm,
                opc, " $a, $b",
                [(opnode GPR:$a, so_imm:$b)]>;
-  def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), UnaryFrm,
+  def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPRnReg,
                opc, " $a, $b",
                [(opnode GPR:$a, GPR:$b)]>;
-  def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), UnaryFrm,
+  def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPRnSoReg,
                opc, " $a, $b",
                [(opnode GPR:$a, so_reg:$b)]>;
 }
@@ -419,13 +420,13 @@ multiclass AI_bin_rrot<bits<4> opcod, string opc, PatFrag opnode> {
 let Uses = [CPSR] in {
 multiclass AsXI1_bin_c_irs<bits<4> opcod, string opc, PatFrag opnode> {
   def ri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b, cc_out:$s),
-                BinaryFrm, !strconcat(opc, "${s} $dst, $a, $b"),
+                DPRIm, !strconcat(opc, "${s} $dst, $a, $b"),
                [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>;
   def rr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b, cc_out:$s),
-                BinaryFrm, !strconcat(opc, "${s} $dst, $a, $b"),
+                DPRReg, !strconcat(opc, "${s} $dst, $a, $b"),
                [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>;
   def rs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b, cc_out:$s),
-                BinaryFrm, !strconcat(opc, "${s} $dst, $a, $b"),
+                DPRSoReg, !strconcat(opc, "${s} $dst, $a, $b"),
                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>;
 }
 }
@@ -452,12 +453,12 @@ let Defs = [SP], Uses = [SP] in {
 def ADJCALLSTACKUP :
 PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p),
            "@ ADJCALLSTACKUP $amt1",
-           [(ARMcallseq_end imm:$amt1, imm:$amt2)]>;
+           [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
 
 def ADJCALLSTACKDOWN : 
 PseudoInst<(outs), (ins i32imm:$amt, pred:$p),
            "@ ADJCALLSTACKDOWN $amt",
-           [(ARMcallseq_start imm:$amt)]>;
+           [(ARMcallseq_start timm:$amt)]>;
 }
 
 def DWARF_LOC :
@@ -466,7 +467,7 @@ PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
            [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
 
 let isNotDuplicable = 1 in {
-def PICADD : AXI1<0x0, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
+def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
                   Pseudo, "$cp:\n\tadd$p $dst, pc, $a",
                    [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
 
@@ -520,7 +521,11 @@ def PICSTRB : AXI2stb<0x0, (outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
 //
 
 let isReturn = 1, isTerminator = 1 in
-  def BX_RET : AI<0x1, (outs), (ins), BranchMisc, "bx", " lr", [(ARMretflag)]>;
+  def BX_RET : AI<0x0, (outs), (ins), BranchMisc, "bx", " lr", [(ARMretflag)]> {
+  let Inst{7-4}   = 0b0001;
+  let Inst{19-8}  = 0b111111111111;
+  let Inst{27-20} = 0b00010010;
+}
 
 // FIXME: remove when we have a way to marking a MI with these properties.
 // FIXME: $dst1 should be a def. But the extra ops must be in the end of the
@@ -543,9 +548,14 @@ let isCall = 1,
                    [(ARMcall_pred tglobaladdr:$func)]>;
 
   // ARMv5T and above
-  def BLX : ABLXI<0x2, (outs), (ins GPR:$func, variable_ops), BranchMisc,
+  def BLX : AXI<0x0, (outs), (ins GPR:$func, variable_ops), BranchMisc,
                 "blx $func",
-                [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T]>;
+                [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T]> {
+    let Inst{7-4}   = 0b0011;
+    let Inst{19-8}  = 0b111111111111;
+    let Inst{27-20} = 0b00010010;
+  }
+
   let Uses = [LR] in {
     // ARMv4T
     def BX : AXIx2<0x0, (outs), (ins GPR:$func, variable_ops),
@@ -558,18 +568,18 @@ let isBranch = 1, isTerminator = 1 in {
   // B is "predicable" since it can be xformed into a Bcc.
   let isBarrier = 1 in {
     let isPredicable = 1 in
-    def B : AXI<0xA, (outs), (ins brtarget:$target), Branch, "b $target",
+    def B : ABI<0xA, (outs), (ins brtarget:$target), Branch, "b $target",
                 [(br bb:$target)]>;
 
   let isNotDuplicable = 1, isIndirectBranch = 1 in {
-  def BR_JTr : JTI<0x0, (outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
+  def BR_JTr : JTI<0b1101, (outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
                     "mov pc, $target \n$jt",
                     [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
   def BR_JTm : JTI2<0x0, (outs), (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
                      "ldr pc, $target \n$jt",
                      [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
                        imm:$id)]>;
-  def BR_JTadd : JTI1<0x0, (outs), (ins GPR:$target, GPR:$idx, jtblock_operand:$jt,
+  def BR_JTadd : JTI1<0b0100, (outs), (ins GPR:$target, GPR:$idx, jtblock_operand:$jt,
                        i32imm:$id),
                        "add pc, $target, $idx \n$jt",
                        [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
@@ -743,16 +753,16 @@ def STM : AXI4st<0x0, (outs),
 //  Move Instructions.
 //
 
-def MOVr : AsI1<0xD, (outs GPR:$dst), (ins GPR:$src), UnaryFrm,
+def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPRdReg,
                  "mov", " $dst, $src", []>;
-def MOVs : AsI1<0xD, (outs GPR:$dst), (ins so_reg:$src), UnaryFrm,
+def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), DPRdSoReg,
                  "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>;
 
 let isReMaterializable = 1 in
-def MOVi : AsI1<0xD, (outs GPR:$dst), (ins so_imm:$src), UnaryFrm,
+def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPRdIm,
                  "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>;
 
-def MOVrx : AsI1<0xD, (outs GPR:$dst), (ins GPR:$src), UnaryFrm,
+def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPRdMisc,
                  "mov", " $dst, $src, rrx",
                  [(set GPR:$dst, (ARMrrx GPR:$src))]>;
 
@@ -760,10 +770,10 @@ def MOVrx : AsI1<0xD, (outs GPR:$dst), (ins GPR:$src), UnaryFrm,
 // due to flag operands.
 
 let Defs = [CPSR] in {
-def MOVsrl_flag : AI1<0xD, (outs GPR:$dst), (ins GPR:$src), UnaryFrm,
+def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPRdMisc,
                       "mov", "s $dst, $src, lsr #1",
                       [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>;
-def MOVsra_flag : AI1<0xD, (outs GPR:$dst), (ins GPR:$src), UnaryFrm,
+def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPRdMisc,
                       "mov", "s $dst, $src, asr #1",
                       [(set GPR:$dst, (ARMsra_flag GPR:$src))]>;
 }
@@ -811,43 +821,49 @@ defm UXTAH : AI_bin_rrot<0x0, "uxtah",
 //  Arithmetic Instructions.
 //
 
-defm ADD  : AsI1_bin_irs<0x4, "add", BinOpFrag<(add  node:$LHS, node:$RHS)>>;
-defm SUB  : AsI1_bin_irs<0x2, "sub", BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
+defm ADD  : AsI1_bin_irs<0b0100, "add",
+                         BinOpFrag<(add  node:$LHS, node:$RHS)>>;
+defm SUB  : AsI1_bin_irs<0b0010, "sub",
+                         BinOpFrag<(sub  node:$LHS, node:$RHS)>>;
 
 // ADD and SUB with 's' bit set.
-defm ADDS : ASI1_bin_s_irs<0x4, "add", BinOpFrag<(addc node:$LHS, node:$RHS)>>;
-defm SUBS : ASI1_bin_s_irs<0x2, "sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
+defm ADDS : ASI1_bin_s_irs<0b0100, "add",
+                           BinOpFrag<(addc node:$LHS, node:$RHS)>>;
+defm SUBS : ASI1_bin_s_irs<0b0010, "sub",
+                           BinOpFrag<(subc node:$LHS, node:$RHS)>>;
 
 // FIXME: Do not allow ADC / SBC to be predicated for now.
-defm ADC  : AsXI1_bin_c_irs<0x5, "adc", BinOpFrag<(adde node:$LHS, node:$RHS)>>;
-defm SBC  : AsXI1_bin_c_irs<0x6, "sbc", BinOpFrag<(sube node:$LHS, node:$RHS)>>;
+defm ADC  : AsXI1_bin_c_irs<0b0101, "adc",
+                            BinOpFrag<(adde node:$LHS, node:$RHS)>>;
+defm SBC  : AsXI1_bin_c_irs<0b0110, "sbc",
+                            BinOpFrag<(sube node:$LHS, node:$RHS)>>;
 
 // These don't define reg/reg forms, because they are handled above.
-def RSBri : AsI1<0x3, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), BinaryFrm,
+def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPRIm,
                   "rsb", " $dst, $a, $b",
                   [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]>;
 
-def RSBrs : AsI1<0x3, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), BinaryFrm,
+def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPRSoReg,
                   "rsb", " $dst, $a, $b",
                   [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]>;
 
 // RSB with 's' bit set.
 let Defs = [CPSR] in {
-def RSBSri : AI1<0x3, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), BinaryFrm,
+def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPRIm,
                  "rsb", "s $dst, $a, $b",
                  [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]>;
-def RSBSrs : AI1<0x3, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), BinaryFrm,
+def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPRSoReg,
                  "rsb", "s $dst, $a, $b",
                  [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>;
 }
 
 // FIXME: Do not allow RSC to be predicated for now. But they can set CPSR.
 let Uses = [CPSR] in {
-def RSCri : AXI1<0x7, (outs GPR:$dst), (ins GPR:$a, so_imm:$b, cc_out:$s),
-                 BinaryFrm, "rsc${s} $dst, $a, $b",
+def RSCri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b, cc_out:$s),
+                 DPRIm, "rsc${s} $dst, $a, $b",
                  [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>;
-def RSCrs : AXI1<0x7, (outs GPR:$dst), (ins GPR:$a, so_reg:$b, cc_out:$s),
-                 BinaryFrm, "rsc${s} $dst, $a, $b",
+def RSCrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b, cc_out:$s),
+                 DPRSoReg, "rsc${s} $dst, $a, $b",
                  [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>;
 }
 
@@ -871,17 +887,21 @@ def : ARMPat<(add    GPR:$src, so_imm_neg:$imm),
 //  Bitwise Instructions.
 //
 
-defm AND   : AsI1_bin_irs<0x0, "and", BinOpFrag<(and node:$LHS, node:$RHS)>>;
-defm ORR   : AsI1_bin_irs<0xC, "orr", BinOpFrag<(or  node:$LHS, node:$RHS)>>;
-defm EOR   : AsI1_bin_irs<0x1, "eor", BinOpFrag<(xor node:$LHS, node:$RHS)>>;
-defm BIC   : AsI1_bin_irs<0xE, "bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
+defm AND   : AsI1_bin_irs<0b0000, "and",
+                          BinOpFrag<(and node:$LHS, node:$RHS)>>;
+defm ORR   : AsI1_bin_irs<0b1100, "orr",
+                          BinOpFrag<(or  node:$LHS, node:$RHS)>>;
+defm EOR   : AsI1_bin_irs<0b0001, "eor",
+                          BinOpFrag<(xor node:$LHS, node:$RHS)>>;
+defm BIC   : AsI1_bin_irs<0b1110, "bic",
+                          BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
 
-def  MVNr  : AsI1<0xE, (outs GPR:$dst), (ins GPR:$src), UnaryFrm,
+def  MVNr  : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPRdReg,
                   "mvn", " $dst, $src", [(set GPR:$dst, (not GPR:$src))]>;
-def  MVNs  : AsI1<0xE, (outs GPR:$dst), (ins so_reg:$src), UnaryFrm,
+def  MVNs  : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPRdSoReg,
                   "mvn", " $dst, $src", [(set GPR:$dst, (not so_reg:$src))]>;
 let isReMaterializable = 1 in
-def  MVNi  : AsI1<0xE, (outs GPR:$dst), (ins so_imm:$imm), UnaryFrm,
+def  MVNi  : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPRdIm,
                   "mvn", " $dst, $imm", [(set GPR:$dst, so_imm_not:$imm)]>;
 
 def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
@@ -891,49 +911,53 @@ def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
 //  Multiply Instructions.
 //
 
-def MUL  : AsI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
-               "mul", " $dst, $a, $b",
-               [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
+def MUL   : AsI6<0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
+                 "mul", " $dst, $a, $b",
+                 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
 
-def MLA  : AsI<0x2, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
-               MulFrm, "mla", " $dst, $a, $b, $c",
-               [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
+def MLA   : AsI6<0b0010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
+                 MulFrm, "mla", " $dst, $a, $b, $c",
+                 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
 
 // Extra precision multiplies with low / high results
-def SMULL : AsI<0xC, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
-                MulFrm, "smull", " $ldst, $hdst, $a, $b", []>;
+def SMULL : AsI6<0b1100, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
+                 MulFrm, "smull", " $ldst, $hdst, $a, $b", []>;
 
-def UMULL : AsI<0x8, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
-                MulFrm, "umull", " $ldst, $hdst, $a, $b", []>;
+def UMULL : AsI6<0b1000, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
+                 MulFrm, "umull", " $ldst, $hdst, $a, $b", []>;
 
 // Multiply + accumulate
-def SMLAL : AsI<0xE, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
-                MulFrm, "smlal", " $ldst, $hdst, $a, $b", []>;
+def SMLAL : AsI6<0b1110, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
+                 MulFrm, "smlal", " $ldst, $hdst, $a, $b", []>;
 
-def UMLAL : AsI<0xA, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
-                MulFrm, "umlal", " $ldst, $hdst, $a, $b", []>;
+def UMLAL : AsI6<0b1010, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
+                 MulFrm, "umlal", " $ldst, $hdst, $a, $b", []>;
 
-def UMAAL : AI<0x0, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), MulFrm,
-               "umaal", " $ldst, $hdst, $a, $b", []>,
-            Requires<[IsARM, HasV6]>;
+def UMAAL : AI6 <0b0000, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), 
+                 MulFrm, "umaal", " $ldst, $hdst, $a, $b", []>,
+                 Requires<[IsARM, HasV6]>;
 
 // Most significant word multiply
+// FIXME: encoding
 def SMMUL : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
                "smmul", " $dst, $a, $b",
                [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
             Requires<[IsARM, HasV6]>;
 
+// FIXME: encoding
 def SMMLA : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), MulFrm,
                "smmla", " $dst, $a, $b, $c",
                [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
             Requires<[IsARM, HasV6]>;
 
 
+// FIXME: encoding
 def SMMLS : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), MulFrm,
                "smmls", " $dst, $a, $b, $c",
                [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
                Requires<[IsARM, HasV6]>;
 
+// FIXME: encoding
 multiclass AI_smul<string opc, PatFrag opnode> {
   def BB : AI<0x8, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulSMUL,
               !strconcat(opc, "bb"), " $dst, $a, $b",
@@ -973,6 +997,7 @@ multiclass AI_smul<string opc, PatFrag opnode> {
 }
 
 
+// FIXME: encoding
 multiclass AI_smla<string opc, PatFrag opnode> {
   def BB : AI<0x8, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), MulSMLA,
               !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
@@ -1012,7 +1037,9 @@ multiclass AI_smla<string opc, PatFrag opnode> {
             Requires<[IsARM, HasV5TE]>;
 }
 
+// FIXME: encoding
 defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
+// FIXME: encoding
 defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
 
 // TODO: Halfword multiple accumulate long: SMLAL<x><y>
@@ -1080,9 +1107,9 @@ def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
 //  Comparison Instructions...
 //
 
-defm CMP  : AI1_cmp_irs<0xA, "cmp",
+defm CMP  : AI1_cmp_irs<0b1010, "cmp",
                         BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
-defm CMN  : AI1_cmp_irs<0xB, "cmn",
+defm CMN  : AI1_cmp_irs<0b1011, "cmn",
                         BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
 
 // Note that TST/TEQ don't set all the same flags that CMP does!
@@ -1091,9 +1118,9 @@ defm TST  : AI1_cmp_irs<0x8, "tst",
 defm TEQ  : AI1_cmp_irs<0x9, "teq",
                         BinOpFrag<(ARMcmpNZ (xor node:$LHS, node:$RHS), 0)>>;
 
-defm CMPnz : AI1_cmp_irs<0xA, "cmp",
+defm CMPnz : AI1_cmp_irs<0b1010, "cmp",
                          BinOpFrag<(ARMcmpNZ node:$LHS, node:$RHS)>>;
-defm CMNnz : AI1_cmp_irs<0xA, "cmn",
+defm CMNnz : AI1_cmp_irs<0b1011, "cmn",
                          BinOpFrag<(ARMcmpNZ node:$LHS,(ineg node:$RHS))>>;
 
 def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
@@ -1107,17 +1134,17 @@ def : ARMPat<(ARMcmpNZ GPR:$src, so_imm_neg:$imm),
 // FIXME: should be able to write a pattern for ARMcmov, but can't use
 // a two-value operand where a dag node expects two operands. :( 
 def MOVCCr : AI<0xD, (outs GPR:$dst), (ins GPR:$false, GPR:$true),
-                UnaryFrm, "mov", " $dst, $true",
+                DPRdReg, "mov", " $dst, $true",
       [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
                 RegConstraint<"$false = $dst">;
 
 def MOVCCs : AI<0xD, (outs GPR:$dst), (ins GPR:$false, so_reg:$true),
-                UnaryFrm, "mov", " $dst, $true",
+                DPRdSoReg, "mov", " $dst, $true",
    [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
                 RegConstraint<"$false = $dst">;
 
 def MOVCCi : AI<0xD, (outs GPR:$dst), (ins GPR:$false, so_imm:$true),
-                UnaryFrm, "mov", " $dst, $true",
+                DPRdIm, "mov", " $dst, $true",
    [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
                 RegConstraint<"$false = $dst">;
 
@@ -1165,7 +1192,7 @@ def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
 
 // Two piece so_imms.
 let isReMaterializable = 1 in
-def MOVi2pieces : AI1x2<0x0, (outs GPR:$dst), (ins so_imm2part:$src), Pseudo,
+def MOVi2pieces : AI1x2<0x0, (outs GPR:$dst), (ins so_imm2part:$src), DPRdMisc,
                          "mov", " $dst, $src",
                          [(set GPR:$dst, so_imm2part:$src)]>;