Changes in directory llvm/lib/Target/ARM:
ARMAsmPrinter.cpp updated: 1.54 -> 1.55 ARMConstantPoolValue.cpp updated: 1.1 -> 1.2 ARMConstantPoolValue.h updated: 1.1 -> 1.2 ARMISelLowering.cpp updated: 1.7 -> 1.8 ARMISelLowering.h updated: 1.1 -> 1.2 ARMInstrInfo.td updated: 1.86 -> 1.87 ARMInstrThumb.td updated: 1.9 -> 1.10 --- Log message: - 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. --- Diffs of the changes: (+96 -47) ARMAsmPrinter.cpp | 28 ++++++++++++++++++++++------ ARMConstantPoolValue.cpp | 30 +++++++++++++++++++++++------- ARMConstantPoolValue.h | 21 ++++++++++++++++++--- ARMISelLowering.cpp | 36 ++++++++++++++++++++++++++---------- ARMISelLowering.h | 2 -- ARMInstrInfo.td | 5 ++--- ARMInstrThumb.td | 21 +++++---------------- 7 files changed, 96 insertions(+), 47 deletions(-) Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp diff -u llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.54 llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.55 --- llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.54 Tue Jan 30 14:08:37 2007 +++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp Tue Jan 30 14:37:08 2007 @@ -122,10 +122,15 @@ ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV; GlobalValue *GV = ACPV->getGV(); - std::string Name = Mang->getValueName(GV); + std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix(); + if (!GV) + Name += ACPV->getSymbol(); if (ACPV->isNonLazyPointer()) { GVNonLazyPtrs.insert(Name); O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr"; + } else if (ACPV->isStub()) { + FnStubs.insert(Name); + O << TAI->getPrivateGlobalPrefix() << Name << "$stub"; } else O << Name; if (ACPV->getPCAdjustment() != 0) @@ -136,7 +141,7 @@ // If the constant pool value is a extern weak symbol, remember to emit // the weak reference. - if (GV->hasExternalWeakLinkage()) + if (GV && GV->hasExternalWeakLinkage()) ExtWeakSymbols.insert(GV); } @@ -680,18 +685,29 @@ void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) { ++EmittedInsts; - if (MI->getOpcode() == ARM::CONSTPOOL_ENTRY) { + int Opc = MI->getOpcode(); + switch (Opc) { + case ARM::CONSTPOOL_ENTRY: if (!InCPMode && AFI->isThumbFunction()) { EmitAlignment(2); InCPMode = true; } - } else { + break; + default: { if (InCPMode && AFI->isThumbFunction()) { EmitAlignment(1); InCPMode = false; } - O << "\t"; - } + switch (Opc) { + case ARM::PICADD: + case ARM::PICLD: + case ARM::tPICADD: + break; + default: + O << "\t"; + break; + } + }} // Call the autogenerated instruction printer routines. printInstruction(MI); Index: llvm/lib/Target/ARM/ARMConstantPoolValue.cpp diff -u llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.1 llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.2 --- llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.1 Fri Jan 19 01:51:42 2007 +++ llvm/lib/Target/ARM/ARMConstantPoolValue.cpp Tue Jan 30 14:37:08 2007 @@ -14,12 +14,20 @@ #include "ARMConstantPoolValue.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/GlobalValue.h" +#include "llvm/Type.h" using namespace llvm; ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, unsigned id, - bool isNonLazy, unsigned char PCAdj) + ARMCP::ARMCPKind k, + unsigned char PCAdj) : MachineConstantPoolValue((const Type*)gv->getType()), - GV(gv), LabelId(id), isNonLazyPtr(isNonLazy), PCAdjust(PCAdj) {} + GV(gv), S(NULL), LabelId(id), Kind(k), PCAdjust(PCAdj) {} + +ARMConstantPoolValue::ARMConstantPoolValue(const char *s, unsigned id, + ARMCP::ARMCPKind k, + unsigned char PCAdj) + : MachineConstantPoolValue((const Type*)Type::Int32Ty), + GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj) {} int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) { @@ -30,8 +38,11 @@ (Constants[i].Offset & AlignMask) == 0) { ARMConstantPoolValue *CPV = (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; - if (CPV->GV == GV && CPV->LabelId == LabelId && - CPV->isNonLazyPtr == isNonLazyPtr) + if (CPV->GV == GV && + CPV->S == S && + CPV->LabelId == LabelId && + CPV->Kind == Kind && + CPV->PCAdjust == PCAdjust) return i; } } @@ -42,14 +53,19 @@ void ARMConstantPoolValue::AddSelectionDAGCSEId(FoldingSetNodeID &ID) { ID.AddPointer(GV); + ID.AddPointer(S); ID.AddInteger(LabelId); - ID.AddInteger((unsigned)isNonLazyPtr); + ID.AddInteger((unsigned)Kind); ID.AddInteger(PCAdjust); } void ARMConstantPoolValue::print(std::ostream &O) const { - O << GV->getName(); - if (isNonLazyPtr) O << "$non_lazy_ptr"; + if (GV) + O << GV->getName(); + else + O << S; + if (isNonLazyPointer()) O << "$non_lazy_ptr"; + else if (isStub()) O << "$stub"; if (PCAdjust != 0) O << "-(LPIC" << LabelId << "+" << (unsigned)PCAdjust << ")"; } Index: llvm/lib/Target/ARM/ARMConstantPoolValue.h diff -u llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.1 llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.2 --- llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.1 Fri Jan 19 01:51:42 2007 +++ llvm/lib/Target/ARM/ARMConstantPoolValue.h Tue Jan 30 14:37:08 2007 @@ -18,23 +18,38 @@ namespace llvm { +namespace ARMCP { + enum ARMCPKind { + CPValue, + CPNonLazyPtr, + CPStub + }; +} + /// ARMConstantPoolValue - ARM specific constantpool value. This is used to /// represent PC relative displacement between the address of the load /// instruction and the global value being loaded, i.e. (&GV-(LPIC+8)). class ARMConstantPoolValue : public MachineConstantPoolValue { GlobalValue *GV; // GlobalValue being loaded. + const char *S; // ExtSymbol being loaded. unsigned LabelId; // Label id of the load. - bool isNonLazyPtr; // True if loading a Mac OS X non_lazy_ptr stub. + ARMCP::ARMCPKind Kind; // non_lazy_ptr or stub? unsigned char PCAdjust; // Extra adjustment if constantpool is pc relative. // 8 for ARM, 4 for Thumb. public: - ARMConstantPoolValue(GlobalValue *gv, unsigned id, bool isNonLazy = false, + ARMConstantPoolValue(GlobalValue *gv, unsigned id, + ARMCP::ARMCPKind Kind = ARMCP::CPValue, + unsigned char PCAdj = 0); + ARMConstantPoolValue(const char *s, unsigned id, + ARMCP::ARMCPKind Kind = ARMCP::CPValue, unsigned char PCAdj = 0); GlobalValue *getGV() const { return GV; } + const char *getSymbol() const { return S; } unsigned getLabelId() const { return LabelId; } - bool isNonLazyPointer() const { return isNonLazyPtr; } + bool isNonLazyPointer() const { return Kind == ARMCP::CPNonLazyPtr; } + bool isStub() const { return Kind == ARMCP::CPStub; } unsigned char getPCAdjustment() const { return PCAdjust; } virtual int getExistingMachineCPValue(MachineConstantPool *CP, Index: llvm/lib/Target/ARM/ARMISelLowering.cpp diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.7 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.8 --- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.7 Tue Jan 30 14:08:37 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.cpp Tue Jan 30 14:37:08 2007 @@ -230,7 +230,6 @@ 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 @@ 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 @@ 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); Index: llvm/lib/Target/ARM/ARMISelLowering.h diff -u llvm/lib/Target/ARM/ARMISelLowering.h:1.1 llvm/lib/Target/ARM/ARMISelLowering.h:1.2 --- llvm/lib/Target/ARM/ARMISelLowering.h:1.1 Fri Jan 19 01:51:42 2007 +++ llvm/lib/Target/ARM/ARMISelLowering.h Tue Jan 30 14:37:08 2007 @@ -31,8 +31,6 @@ Wrapper, // Wrapper - A wrapper node for TargetConstantPool, // TargetExternalSymbol, and TargetGlobalAddress. - WrapperCall, // WrapperCall - Same as wrapper, but mark the wrapped - // node as call operand. WrapperJT, // WrapperJT - A wrapper node for TargetJumpTable CALL, // Function call. Index: llvm/lib/Target/ARM/ARMInstrInfo.td diff -u llvm/lib/Target/ARM/ARMInstrInfo.td:1.86 llvm/lib/Target/ARM/ARMInstrInfo.td:1.87 --- llvm/lib/Target/ARM/ARMInstrInfo.td:1.86 Fri Jan 26 08:34:51 2007 +++ llvm/lib/Target/ARM/ARMInstrInfo.td Tue Jan 30 14:37:08 2007 @@ -41,7 +41,6 @@ // Node definitions. def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>; -def ARMWrapperCall : SDNode<"ARMISD::WrapperCall", SDTIntUnaryOp>; def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>; def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeq, @@ -514,11 +513,11 @@ [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>; def PICADD : AI1<(ops GPR:$dst, GPR:$a, pclabel:$cp), - "\n$cp:\n\tadd $dst, pc, $a", + "$cp:\n\tadd $dst, pc, $a", [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>; let AddedComplexity = 10 in def PICLD : AI2<(ops GPR:$dst, addrmodepc:$addr), - "\n${addr:label}:\n\tldr $dst, $addr", + "${addr:label}:\n\tldr $dst, $addr", [(set GPR:$dst, (load addrmodepc:$addr))]>; //===----------------------------------------------------------------------===// Index: llvm/lib/Target/ARM/ARMInstrThumb.td diff -u llvm/lib/Target/ARM/ARMInstrThumb.td:1.9 llvm/lib/Target/ARM/ARMInstrThumb.td:1.10 --- llvm/lib/Target/ARM/ARMInstrThumb.td:1.9 Mon Jan 29 20:35:32 2007 +++ llvm/lib/Target/ARM/ARMInstrThumb.td Tue Jan 30 14:37:08 2007 @@ -158,7 +158,7 @@ // def tPICADD : TIt<(ops GPR:$dst, GPR:$lhs, pclabel:$cp), - "\n$cp:\n\tadd $dst, pc", + "$cp:\n\tadd $dst, pc", [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>; //===----------------------------------------------------------------------===// @@ -475,25 +475,18 @@ // tLEApcrel - Load a pc-relative address into a register without offending the // assembler. -def tLEApcrel : TI<(ops GPR:$dst, i32imm:$label), +def tLEApcrel : TIx2<(ops GPR:$dst, i32imm:$label), !strconcat(!strconcat(".set PCRELV${:uid}, ($label-(", "${:private}PCRELL${:uid}+4))\n"), !strconcat("${:private}PCRELL${:uid}:\n\t", - "add $dst, pc, #PCRELV${:uid}")), + "mov $dst, #PCRELV${:uid}\n\tadd $dst, pc")), []>; -def tLEApcrelCall : TI<(ops GPR:$dst, i32imm:$label), - !strconcat(!strconcat(".set PCRELV${:uid}, (${label:call}-(", - "${:private}PCRELL${:uid}+4))\n"), - !strconcat("${:private}PCRELL${:uid}:\n\t", - "add $dst, pc, #PCRELV${:uid}")), - []>; - -def tLEApcrelJT : TI<(ops GPR:$dst, i32imm:$label, i32imm:$id), +def tLEApcrelJT : TIx2<(ops GPR:$dst, i32imm:$label, i32imm:$id), !strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(", "${:private}PCRELL${:uid}+4))\n"), !strconcat("${:private}PCRELL${:uid}:\n\t", - "add $dst, pc, #PCRELV${:uid}")), + "mov $dst, #PCRELV${:uid}\n\tadd $dst, pc")), []>; //===----------------------------------------------------------------------===// @@ -503,10 +496,6 @@ // ConstantPool, GlobalAddress def : ThumbPat<(ARMWrapper tglobaladdr :$dst), (tLEApcrel tglobaladdr :$dst)>; def : ThumbPat<(ARMWrapper tconstpool :$dst), (tLEApcrel tconstpool :$dst)>; -def : ThumbPat<(ARMWrapperCall tglobaladdr :$dst), - (tLEApcrelCall tglobaladdr :$dst)>; -def : ThumbPat<(ARMWrapperCall texternalsym:$dst), - (tLEApcrelCall texternalsym:$dst)>; // JumpTable def : ThumbPat<(ARMWrapperJT tjumptable:$dst, imm:$id), _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits