forked from OSchip/llvm-project
Add ARM codegen for indirect branches.
clang/test/CodeGen/indirect-goto.c runs! (unoptimized) llvm-svn: 85577
This commit is contained in:
parent
252d36e74c
commit
1cf0b03064
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)>;
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)>;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue