summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMISelLowering.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2007-01-30 20:37:08 +0000
committerEvan Cheng <evan.cheng@apple.com>2007-01-30 20:37:08 +0000
commitc60e76d139a96cc8bb7454929172cdb992e16971 (patch)
treefe8d8431e2477af5a3c4ab2b2ead8b931904071a /lib/Target/ARM/ARMISelLowering.cpp
parent5cbf985dcbc89fba3208e7baf8b6f488b06d3ec9 (diff)
downloadllvm-c60e76d139a96cc8bb7454929172cdb992e16971.tar.gz
llvm-c60e76d139a96cc8bb7454929172cdb992e16971.tar.bz2
llvm-c60e76d139a96cc8bb7454929172cdb992e16971.tar.xz
- Fix codegen for pc relative constant (e.g. JT) in thumb mode:
.set PCRELV0, (LJTI1_0_0-(LPCRELL0+4)) LPCRELL0: add r1, pc, #PCRELV0 This is not legal since add r1, pc, #c requires the constant be a multiple of 4. Do the following instead: .set PCRELV0, (LJTI1_0_0-(LPCRELL0+4)) LPCRELL0: mov r1, #PCRELV0 add r1, pc - In thumb mode, it's not possible to use .set generate a pc relative stub address. The stub is ARM code which is in a different section from the thumb code. Load the value from a constpool instead. - Some asm printing clean up. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33664 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp36
1 files changed, 26 insertions, 10 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 24357cfe16..0b1c3ac629 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -230,7 +230,6 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch (Opcode) {
default: return 0;
case ARMISD::Wrapper: return "ARMISD::Wrapper";
- case ARMISD::WrapperCall: return "ARMISD::WrapperCall";
case ARMISD::WrapperJT: return "ARMISD::WrapperJT";
case ARMISD::CALL: return "ARMISD::CALL";
case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK";
@@ -465,25 +464,40 @@ SDOperand ARMTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
bool isARMFunc = false;
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
GlobalValue *GV = G->getGlobal();
- Callee = DAG.getTargetGlobalAddress(GV, getPointerTy());
isDirect = true;
bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage());
bool isStub = (isExt && Subtarget->isTargetDarwin()) &&
getTargetMachine().getRelocationModel() != Reloc::Static;
isARMFunc = !Subtarget->isThumb() || isStub;
- // Wrap it since tBX takes a register source operand.
- if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps())
- Callee = DAG.getNode(ARMISD::WrapperCall, MVT::i32, Callee);
+ // tBX takes a register source operand.
+ if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps()) {
+ ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex,
+ ARMCP::CPStub, 4);
+ SDOperand CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 2);
+ CPAddr = DAG.getNode(ARMISD::Wrapper, MVT::i32, CPAddr);
+ Callee = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), CPAddr, NULL, 0);
+ SDOperand PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32);
+ Callee = DAG.getNode(ARMISD::PIC_ADD, getPointerTy(), Callee, PICLabel);
+ } else
+ Callee = DAG.getTargetGlobalAddress(GV, getPointerTy());
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
- Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
isDirect = true;
bool isStub = Subtarget->isTargetDarwin() &&
getTargetMachine().getRelocationModel() != Reloc::Static;
isARMFunc = !Subtarget->isThumb() || isStub;
- // Wrap it since tBX takes a register source operand.
- if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps())
- Callee = DAG.getNode(ARMISD::WrapperCall, MVT::i32, Callee);
+ // tBX takes a register source operand.
+ const char *Sym = S->getSymbol();
+ if (isARMFunc && Subtarget->isThumb() && !Subtarget->hasV5TOps()) {
+ ARMConstantPoolValue *CPV = new ARMConstantPoolValue(Sym, ARMPCLabelIndex,
+ ARMCP::CPStub, 4);
+ SDOperand CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 2);
+ CPAddr = DAG.getNode(ARMISD::Wrapper, MVT::i32, CPAddr);
+ Callee = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), CPAddr, NULL, 0);
+ SDOperand PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32);
+ Callee = DAG.getNode(ARMISD::PIC_ADD, getPointerTy(), Callee, PICLabel);
+ } else
+ Callee = DAG.getTargetExternalSymbol(Sym, getPointerTy());
}
std::vector<MVT::ValueType> NodeTys;
@@ -647,8 +661,10 @@ SDOperand ARMTargetLowering::LowerGlobalAddress(SDOperand Op,
else {
unsigned PCAdj = (RelocM != Reloc::PIC_)
? 0 : (Subtarget->isThumb() ? 4 : 8);
+ ARMCP::ARMCPKind Kind = IsIndirect ? ARMCP::CPNonLazyPtr
+ : ARMCP::CPValue;
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, ARMPCLabelIndex,
- IsIndirect, PCAdj);
+ Kind, PCAdj);
CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 2);
}
CPAddr = DAG.getNode(ARMISD::Wrapper, MVT::i32, CPAddr);