Thumb jumptable support.
[oota-llvm.git] / lib / Target / ARM / ARMInstrThumb.td
index 52b8939e24ccc6991807842ff60a4f5dfa335d15..c494be470569e37402009f541ba43dab8b033d30 100644 (file)
@@ -56,6 +56,10 @@ class TIt<dag ops, string asm, list<dag> pattern>
 class TIx2<dag ops, string asm, list<dag> pattern>
   : ThumbI<ops, AddrModeNone, Size4Bytes, asm, "", pattern>;
 
+// BR_JT instructions
+class TJTI<dag ops, string asm, list<dag> pattern>
+  : ThumbI<ops, AddrModeNone, SizeSpecial, asm, "", pattern>;
+
 def imm_neg_XFORM : SDNodeXForm<imm, [{
   return CurDAG->getTargetConstant(-(int)N->getValue(), MVT::i32);
 }]>;
@@ -188,9 +192,14 @@ let isCall = 1, noResults = 1,
                   [(ARMcall_nolink GPR:$dst)]>;
 }
 
-let isBranch = 1, isTerminator = 1, isBarrier = 1 in
+let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
   def tB   : TI<(ops brtarget:$dst), "b $dst", [(br bb:$dst)]>;
 
+  def tBR_JTr : TJTI<(ops GPR:$dst, jtblock_operand:$jt, i32imm:$id),
+                     "cpy pc, $dst \n\t.align\t2\n$jt",
+                     [(ARMbrjt GPR:$dst, tjumptable:$jt, imm:$id)]>;
+}
+
 let isBranch = 1, isTerminator = 1, noResults = 1, isBarrier = 1 in
   def tBcc : TI<(ops brtarget:$dst, CCOp:$cc), "b$cc $dst",
                  [(ARMbrcond bb:$dst, imm:$cc)]>;
@@ -477,6 +486,13 @@ def tLEApcrelCall : TI<(ops GPR:$dst, i32imm:$label),
                                          "add $dst, pc, #PCRELV${:uid}")),
                    []>;
 
+def tLEApcrelJT : TI<(ops GPR:$dst, i32imm:$label, i32imm:$id),
+          !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(",
+                                         "${:private}PCRELL${:uid}+4))\n"),
+                              !strconcat("${:private}PCRELL${:uid}:\n\t",
+                                         "add $dst, pc, #PCRELV${:uid}")),
+                   []>;
+
 //===----------------------------------------------------------------------===//
 // Non-Instruction Patterns
 //
@@ -489,6 +505,10 @@ def : ThumbPat<(ARMWrapperCall tglobaladdr :$dst),
 def : ThumbPat<(ARMWrapperCall texternalsym:$dst),
                (tLEApcrelCall  texternalsym:$dst)>;
 
+// JumpTable
+def : ThumbPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
+               (tLEApcrelJT tjumptable:$dst, imm:$id)>;
+
 // Direct calls
 def : ThumbPat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>;
 def : ThumbV5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>;