From 1cf0b03064fb60a8250b9a8030455c600bd7503d Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Fri, 30 Oct 2009 05:45:42 +0000 Subject: [PATCH] Add ARM codegen for indirect branches. clang/test/CodeGen/indirect-goto.c runs! (unoptimized) llvm-svn: 85577 --- llvm/lib/Target/ARM/ARMISelLowering.cpp | 21 +++++++++++++------ llvm/lib/Target/ARM/ARMISelLowering.h | 1 + llvm/lib/Target/ARM/ARMInstrInfo.td | 1 + llvm/lib/Target/ARM/ARMInstrThumb.td | 1 + llvm/lib/Target/ARM/ARMInstrThumb2.td | 1 + .../Target/ARM/AsmPrinter/ARMMCInstLower.cpp | 4 ++++ 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 4a482fb6ec27..773166a4682c 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -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(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); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.h b/llvm/lib/Target/ARM/ARMISelLowering.h index ac962c1a8a2f..9c7a91d68d2f 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.h +++ b/llvm/lib/Target/ARM/ARMISelLowering.h @@ -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); diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index b4a9c4f951c2..21c185cbeaee 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -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)>; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index 3823ba6e3a68..4ceb4eff9b14 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -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), diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 3ee0355584aa..6d7ffd13800c 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -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)>; diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp b/llvm/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp index 757164e682af..8686961db45e 100644 --- a/llvm/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMMCInstLower.cpp @@ -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);