Add ARM codegen for indirect branches.
authorBob Wilson <bob.wilson@apple.com>
Fri, 30 Oct 2009 05:45:42 +0000 (05:45 +0000)
committerBob Wilson <bob.wilson@apple.com>
Fri, 30 Oct 2009 05:45:42 +0000 (05:45 +0000)
clang/test/CodeGen/indirect-goto.c runs! (unoptimized)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85577 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMISelLowering.h
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb.td
lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp

index 4a482fb6ec27f07a9780d916606edb9c31155975..773166a4682c3ea88801590d68e54084b10a292c 100644 (file)
@@ -363,6 +363,7 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
   setOperationAction(ISD::ConstantPool,  MVT::i32,   Custom);
   setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom);
   setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
+  setOperationAction(ISD::BlockAddress, MVT::i32, Custom);
 
   // Use the default implementation.
   setOperationAction(ISD::VASTART,            MVT::Other, Custom);
@@ -1183,12 +1184,12 @@ ARMTargetLowering::LowerReturn(SDValue Chain,
   return result;
 }
 
-// ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as
-// their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is
-// one of the above mentioned nodes. It has to be wrapped because otherwise
-// Select(N) returns N. So the raw TargetGlobalAddress nodes, etc. can only
-// be used to form addressing mode. These wrapped nodes will be selected
-// into MOVi.
+// ConstantPool, BlockAddress, JumpTable, GlobalAddress, and ExternalSymbol are
+// lowered as their target counterpart wrapped in the ARMISD::Wrapper
+// node. Suppose N is one of the above mentioned nodes. It has to be wrapped
+// because otherwise Select(N) returns N. So the raw TargetGlobalAddress
+// nodes, etc. can only be used to form addressing mode. These wrapped nodes
+// will be selected into MOVi.
 static SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) {
   EVT PtrVT = Op.getValueType();
   // FIXME there is no actual debug info here
@@ -1204,6 +1205,13 @@ static SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) {
   return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res);
 }
 
+SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) {
+  DebugLoc DL = Op.getDebugLoc();
+  BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
+  SDValue Result = DAG.getBlockAddress(BA, DL, /*isTarget=*/true);
+  return DAG.getNode(ARMISD::Wrapper, DL, getPointerTy(), Result);
+}
+
 // Lower ISD::GlobalTLSAddress using the "general dynamic" model
 SDValue
 ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
@@ -2744,6 +2752,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
   switch (Op.getOpcode()) {
   default: llvm_unreachable("Don't know how to custom lower this!");
   case ISD::ConstantPool:  return LowerConstantPool(Op, DAG);
+  case ISD::BlockAddress:  return LowerBlockAddress(Op, DAG);
   case ISD::GlobalAddress:
     return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) :
       LowerGlobalAddressELF(Op, DAG);
index ac962c1a8a2f0d2bbcddca56f8f8b0810fbc1534..9c7a91d68d2f4e77ed4842464a9a48052f099e01 100644 (file)
@@ -268,6 +268,7 @@ namespace llvm {
                              ISD::ArgFlagsTy Flags);
     SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG);
     SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG);
+    SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG);
     SDValue LowerGlobalAddressDarwin(SDValue Op, SelectionDAG &DAG);
     SDValue LowerGlobalAddressELF(SDValue Op, SelectionDAG &DAG);
     SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
index b4a9c4f951c2cd9b425f9e18971e1dbe0a71db16..21c185cbeaeee59e0bf6436bbd7ac046eb8be805 100644 (file)
@@ -1607,6 +1607,7 @@ let Defs =
 // ConstantPool, GlobalAddress, and JumpTable
 def : ARMPat<(ARMWrapper  tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>;
 def : ARMPat<(ARMWrapper  tconstpool  :$dst), (LEApcrel tconstpool  :$dst)>;
+def : ARMPat<(ARMWrapper  tblockaddress:$dst), (LEApcrel tblockaddress:$dst)>;
 def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
              (LEApcrelJT tjumptable:$dst, imm:$id)>;
 
index 3823ba6e3a68de98af2adaa89fd9fe9422f98456..4ceb4eff9b1484a68059a4dff91ebfeab14dc9ee 100644 (file)
@@ -676,6 +676,7 @@ def : T1Pat<(subc   tGPR:$lhs, tGPR:$rhs),
 // ConstantPool, GlobalAddress
 def : T1Pat<(ARMWrapper  tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>;
 def : T1Pat<(ARMWrapper  tconstpool  :$dst), (tLEApcrel tconstpool  :$dst)>;
+def : T1Pat<(ARMWrapper  tblockaddress:$dst), (tLEApcrel tblockaddress:$dst)>;
 
 // JumpTable
 def : T1Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
index 3ee0355584aaa1d94755efc1d9dd629d711d57a6..6d7ffd13800c2947219a36509288b2be92724b44 100644 (file)
@@ -1167,6 +1167,7 @@ def : T2Pat<(sub GPR:$LHS, t2_so_imm2part:$RHS),
 // ConstantPool, GlobalAddress, and JumpTable
 def : T2Pat<(ARMWrapper  tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>;
 def : T2Pat<(ARMWrapper  tconstpool  :$dst), (t2LEApcrel tconstpool  :$dst)>;
+def : T2Pat<(ARMWrapper  tblockaddress:$dst), (t2LEApcrel tblockaddress:$dst)>;
 def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
             (t2LEApcrelJT tjumptable:$dst, imm:$id)>;
 
index 757164e682af6166e16eeac1637efe3cc99a72f9..8686961db45ebb15a707b5fe6f9fe8d04d87c5c3 100644 (file)
@@ -158,6 +158,10 @@ void ARMMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
     case MachineOperand::MO_ConstantPoolIndex:
       MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
       break;
+    case MachineOperand::MO_BlockAddress:
+      MCOp = LowerSymbolOperand(MO, Printer.GetBlockAddressSymbol(
+                                              MO.getBlockAddress()));
+      break;
     }
     
     OutMI.addOperand(MCOp);