Changes in directory llvm/lib/Target/ARM:
ARMAsmPrinter.cpp updated: 1.64 -> 1.65 ARMConstantPoolValue.cpp updated: 1.2 -> 1.3 ARMConstantPoolValue.h updated: 1.2 -> 1.3 ARMISelLowering.cpp updated: 1.44 -> 1.45 ARMISelLowering.h updated: 1.13 -> 1.14 --- Log message: Implement PIC for arm-linux. --- Diffs of the changes: (+83 -12) ARMAsmPrinter.cpp | 8 ++++++- ARMConstantPoolValue.cpp | 20 ++++++++++++++--- ARMConstantPoolValue.h | 10 +++++++- ARMISelLowering.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++---- ARMISelLowering.h | 4 ++- 5 files changed, 83 insertions(+), 12 deletions(-) Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp diff -u llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.64 llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.65 --- llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.64 Tue Apr 3 19:13:29 2007 +++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp Sat Apr 21 19:04:12 2007 @@ -133,6 +133,7 @@ O << TAI->getPrivateGlobalPrefix() << Name << "$stub"; } else O << Name; + if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")"; if (ACPV->getPCAdjustment() != 0) O << "-(" << TAI->getPrivateGlobalPrefix() << "PC" << utostr(ACPV->getLabelId()) @@ -284,7 +285,9 @@ FnStubs.insert(Name); } else O << Name; - + if (isCallOp && Subtarget->isTargetELF() && + TM.getRelocationModel() == Reloc::PIC_) + O << "(PLT)"; if (GV->hasExternalWeakLinkage()) ExtWeakSymbols.insert(GV); break; @@ -299,6 +302,9 @@ FnStubs.insert(Name); } else O << Name; + if (isCallOp && Subtarget->isTargetELF() && + TM.getRelocationModel() == Reloc::PIC_) + O << "(PLT)"; break; } case MachineOperand::MO_ConstantPoolIndex: Index: llvm/lib/Target/ARM/ARMConstantPoolValue.cpp diff -u llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.2 llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.3 --- llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.2 Tue Jan 30 14:37:08 2007 +++ llvm/lib/Target/ARM/ARMConstantPoolValue.cpp Sat Apr 21 19:04:12 2007 @@ -19,15 +19,26 @@ ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, unsigned id, ARMCP::ARMCPKind k, - unsigned char PCAdj) + unsigned char PCAdj, + const char *Modif) : MachineConstantPoolValue((const Type*)gv->getType()), - GV(gv), S(NULL), LabelId(id), Kind(k), PCAdjust(PCAdj) {} + GV(gv), S(NULL), LabelId(id), Kind(k), PCAdjust(PCAdj), + Modifier(Modif) {} ARMConstantPoolValue::ARMConstantPoolValue(const char *s, unsigned id, ARMCP::ARMCPKind k, - unsigned char PCAdj) + unsigned char PCAdj, + const char *Modif) : MachineConstantPoolValue((const Type*)Type::Int32Ty), - GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj) {} + GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj), + Modifier(Modif) {} + +ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, + ARMCP::ARMCPKind k, + const char *Modif) + : MachineConstantPoolValue((const Type*)Type::Int32Ty), + GV(gv), S(NULL), LabelId(0), Kind(k), PCAdjust(0), + Modifier(Modif) {} int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) { @@ -66,6 +77,7 @@ O << S; if (isNonLazyPointer()) O << "$non_lazy_ptr"; else if (isStub()) O << "$stub"; + if (Modifier) O << "(" << Modifier << ")"; if (PCAdjust != 0) O << "-(LPIC" << LabelId << "+" << (unsigned)PCAdjust << ")"; } Index: llvm/lib/Target/ARM/ARMConstantPoolValue.h diff -u llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.2 llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.3 --- llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.2 Tue Jan 30 14:37:08 2007 +++ llvm/lib/Target/ARM/ARMConstantPoolValue.h Sat Apr 21 19:04:12 2007 @@ -36,17 +36,23 @@ ARMCP::ARMCPKind Kind; // non_lazy_ptr or stub? unsigned char PCAdjust; // Extra adjustment if constantpool is pc relative. // 8 for ARM, 4 for Thumb. + const char *Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8)) public: ARMConstantPoolValue(GlobalValue *gv, unsigned id, ARMCP::ARMCPKind Kind = ARMCP::CPValue, - unsigned char PCAdj = 0); + unsigned char PCAdj = 0, const char *Modifier = NULL); ARMConstantPoolValue(const char *s, unsigned id, ARMCP::ARMCPKind Kind = ARMCP::CPValue, - unsigned char PCAdj = 0); + unsigned char PCAdj = 0, const char *Modifier = NULL); + ARMConstantPoolValue(GlobalValue *GV, ARMCP::ARMCPKind Kind, + const char *Modifier); + GlobalValue *getGV() const { return GV; } const char *getSymbol() const { return S; } + const char *getModifier() const { return Modifier; } + bool hasModifier() const { return Modifier != NULL; } unsigned getLabelId() const { return LabelId; } bool isNonLazyPointer() const { return Kind == ARMCP::CPNonLazyPtr; } bool isStub() const { return Kind == ARMCP::CPStub; } Index: llvm/lib/Target/ARM/ARMISelLowering.cpp diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.44 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.45 --- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.44 Fri Apr 13 01:50:55 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp Sat Apr 21 19:04:12 2007 @@ -179,6 +179,7 @@ setOperationAction(ISD::RET, MVT::Other, Custom); setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); setOperationAction(ISD::ConstantPool, MVT::i32, Custom); + setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); // Expand mem operations genericly. setOperationAction(ISD::MEMSET , MVT::Other, Expand); @@ -694,6 +695,31 @@ return DAG.getNode(ARMISD::Wrapper, MVT::i32, Res); } +SDOperand ARMTargetLowering::LowerGlobalAddressELF(SDOperand Op, + SelectionDAG &DAG) { + MVT::ValueType PtrVT = getPointerTy(); + GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); + Reloc::Model RelocM = getTargetMachine().getRelocationModel(); + if (RelocM == Reloc::PIC_) { + bool UseGOTOFF = GV->hasInternalLinkage(); + ARMConstantPoolValue *CPV = + new ARMConstantPoolValue(GV, ARMCP::CPValue, UseGOTOFF ? "GOTOFF":"GOT"); + SDOperand CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 2); + CPAddr = DAG.getNode(ARMISD::Wrapper, MVT::i32, CPAddr); + SDOperand Result = DAG.getLoad(PtrVT, DAG.getEntryNode(), CPAddr, NULL, 0); + SDOperand Chain = Result.getValue(1); + SDOperand GOT = DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, PtrVT); + Result = DAG.getNode(ISD::ADD, PtrVT, Result, GOT); + if (!UseGOTOFF) + Result = DAG.getLoad(PtrVT, Chain, Result, NULL, 0); + return Result; + } else { + SDOperand CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 2); + CPAddr = DAG.getNode(ARMISD::Wrapper, MVT::i32, CPAddr); + return DAG.getLoad(PtrVT, DAG.getEntryNode(), CPAddr, NULL, 0); + } +} + /// GVIsIndirectSymbol - true if the GV will be accessed via an indirect symbol /// even in dynamic-no-pic mode. static bool GVIsIndirectSymbol(GlobalValue *GV) { @@ -701,12 +727,12 @@ (GV->isDeclaration() && !GV->hasNotBeenReadFromBytecode())); } -SDOperand ARMTargetLowering::LowerGlobalAddress(SDOperand Op, - SelectionDAG &DAG) { +SDOperand ARMTargetLowering::LowerGlobalAddressDarwin(SDOperand Op, + SelectionDAG &DAG) { MVT::ValueType PtrVT = getPointerTy(); GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); Reloc::Model RelocM = getTargetMachine().getRelocationModel(); - bool IsIndirect = Subtarget->isTargetDarwin() && GVIsIndirectSymbol(GV); + bool IsIndirect = GVIsIndirectSymbol(GV); SDOperand CPAddr; if (RelocM == Reloc::Static) CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 2); @@ -734,6 +760,22 @@ return Result; } +SDOperand ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDOperand Op, + SelectionDAG &DAG){ + assert(Subtarget->isTargetELF() && + "GLOBAL OFFSET TABLE not implemented for non-ELF targets"); + MVT::ValueType PtrVT = getPointerTy(); + unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; + ARMConstantPoolValue *CPV = new ARMConstantPoolValue("_GLOBAL_OFFSET_TABLE_", + ARMPCLabelIndex, + ARMCP::CPValue, PCAdj); + SDOperand CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 2); + CPAddr = DAG.getNode(ARMISD::Wrapper, MVT::i32, CPAddr); + SDOperand Result = DAG.getLoad(PtrVT, DAG.getEntryNode(), CPAddr, NULL, 0); + SDOperand PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32); + return DAG.getNode(ARMISD::PIC_ADD, PtrVT, Result, PICLabel); +} + static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG, unsigned VarArgsFrameIndex) { // vastart just stores the address of the VarArgsFrameIndex slot into the @@ -1198,7 +1240,9 @@ switch (Op.getOpcode()) { default: assert(0 && "Don't know how to custom lower this!"); abort(); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); - case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG); + case ISD::GlobalAddress: + return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) : + LowerGlobalAddressELF(Op, DAG); case ISD::CALL: return LowerCALL(Op, DAG); case ISD::RET: return LowerRET(Op, DAG); case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG, Subtarget); @@ -1220,6 +1264,7 @@ return LowerFORMAL_ARGUMENTS(Op, DAG); case ISD::RETURNADDR: break; case ISD::FRAMEADDR: break; + case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); } return SDOperand(); } Index: llvm/lib/Target/ARM/ARMISelLowering.h diff -u llvm/lib/Target/ARM/ARMISelLowering.h:1.13 llvm/lib/Target/ARM/ARMISelLowering.h:1.14 --- llvm/lib/Target/ARM/ARMISelLowering.h:1.13 Mon Apr 9 18:33:39 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.h Sat Apr 21 19:04:12 2007 @@ -123,7 +123,9 @@ unsigned ARMPCLabelIndex; SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG); - SDOperand LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerGlobalAddressDarwin(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerGlobalAddressELF(SDOperand Op, SelectionDAG &DAG); + SDOperand LowerGLOBAL_OFFSET_TABLE(SDOperand Op, SelectionDAG &DAG); SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG); SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG); }; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits