Thumb unconditional branch binary encoding. rdar://8754994
[oota-llvm.git] / lib / Target / ARM / ARMInstrThumb.td
index 7322b035c98906b759bf8ece9543c4e30ae7a6eb..e25e9cc9d90f6041d380538765cae633260046a9 100644 (file)
@@ -74,10 +74,18 @@ def t_imm_s4 : Operand<i32> {
 
 // Define Thumb specific addressing modes.
 
-def t_brtarget : Operand<i32> {
+def t_brtarget : Operand<OtherVT> {
   let EncoderMethod = "getThumbBRTargetOpValue";
 }
 
+def t_bcctarget : Operand<i32> {
+  let EncoderMethod = "getThumbBCCTargetOpValue";
+}
+
+def t_cbtarget : Operand<i32> {
+  let EncoderMethod = "getThumbCBTargetOpValue";
+}
+
 def t_bltarget : Operand<i32> {
   let EncoderMethod = "getThumbBLTargetOpValue";
 }
@@ -104,7 +112,7 @@ def t_addrmode_rr : Operand<i32>,
 //
 def t_addrmode_s4 : Operand<i32>,
                     ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> {
-  let EncoderMethod = "getAddrModeS4OpValue";
+  let EncoderMethod = "getAddrModeSOpValue";
   let PrintMethod = "printThumbAddrModeS4Operand";
   let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
   let ParserMatchClass = MemModeThumbAsmOperand;
@@ -115,7 +123,7 @@ def t_addrmode_s4 : Operand<i32>,
 //
 def t_addrmode_s2 : Operand<i32>,
                     ComplexPattern<i32, 3, "SelectThumbAddrModeS2", []> {
-  let EncoderMethod = "getAddrModeS2OpValue";
+  let EncoderMethod = "getAddrModeSOpValue";
   let PrintMethod = "printThumbAddrModeS2Operand";
   let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
   let ParserMatchClass = MemModeThumbAsmOperand;
@@ -126,7 +134,7 @@ def t_addrmode_s2 : Operand<i32>,
 //
 def t_addrmode_s1 : Operand<i32>,
                     ComplexPattern<i32, 3, "SelectThumbAddrModeS1", []> {
-  let EncoderMethod = "getAddrModeS1OpValue";
+  let EncoderMethod = "getAddrModeSOpValue";
   let PrintMethod = "printThumbAddrModeS1Operand";
   let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
   let ParserMatchClass = MemModeThumbAsmOperand;
@@ -488,11 +496,15 @@ let isCall = 1,
 
 let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
   let isPredicable = 1 in
-  def tB   : T1I<(outs), (ins brtarget:$target), IIC_Br,
+  def tB   : T1I<(outs), (ins t_brtarget:$target), IIC_Br,
                  "b\t$target", [(br bb:$target)]>,
-             T1Encoding<{1,1,1,0,0,?}>;
+             T1Encoding<{1,1,1,0,0,?}> {
+    bits<11> target;
+    let Inst{10-0} = target;
+  }
 
   // Far jump
+  // FIXME: Encoding. This should probably be a pseudo for tBL
   let Defs = [LR] in
   def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br,
                     "bl\t$target",[]>;
@@ -508,17 +520,19 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
 // FIXME: should be able to write a pattern for ARMBrcond, but can't use
 // a two-value operand where a dag node expects two operands. :(
 let isBranch = 1, isTerminator = 1 in
-  def tBcc : T1I<(outs), (ins brtarget:$target, pred:$p), IIC_Br,
+  def tBcc : T1I<(outs), (ins t_bcctarget:$target, pred:$p), IIC_Br,
                  "b${p}\t$target",
                  [/*(ARMbrcond bb:$target, imm:$cc)*/]>,
              T1Encoding<{1,1,0,1,?,?}> {
   bits<4> p;
+  bits<8> target;
   let Inst{11-8} = p;
+  let Inst{7-0} = target;
 }
 
 // Compare and branch on zero / non-zero
 let isBranch = 1, isTerminator = 1 in {
-  def tCBZ  : T1I<(outs), (ins tGPR:$Rn, t_brtarget:$target), IIC_Br,
+  def tCBZ  : T1I<(outs), (ins tGPR:$Rn, t_cbtarget:$target), IIC_Br,
                   "cbz\t$Rn, $target", []>,
               T1Misc<{0,0,?,1,?,?,?}> {
     // A8.6.27
@@ -529,7 +543,7 @@ let isBranch = 1, isTerminator = 1 in {
     let Inst{2-0} = Rn;
   }
 
-  def tCBNZ : T1I<(outs), (ins tGPR:$cmp, t_brtarget:$target), IIC_Br,
+  def tCBNZ : T1I<(outs), (ins tGPR:$cmp, t_cbtarget:$target), IIC_Br,
                   "cbnz\t$cmp, $target", []>,
               T1Misc<{1,0,?,1,?,?,?}> {
     // A8.6.27