From dd6df84900df4ceb6b4c5bc9c341c14f672ffaf7 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 15 Nov 2010 03:13:19 +0000 Subject: [PATCH] convert the operand bits into bitfields since they are all combinable in different ways. Add $non_lazy_ptr support, and proper lowering for global values. Now all the ppc regression tests pass with the new instruction printer. llvm-svn: 119106 --- llvm/lib/Target/PowerPC/PPC.h | 50 +++++------ llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 67 ++++++++------- llvm/lib/Target/PowerPC/PPCMCInstLower.cpp | 91 ++++++++------------- 3 files changed, 92 insertions(+), 116 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPC.h b/llvm/lib/Target/PowerPC/PPC.h index 6fe5cef7718c..460d8e1744e6 100644 --- a/llvm/lib/Target/PowerPC/PPC.h +++ b/llvm/lib/Target/PowerPC/PPC.h @@ -28,17 +28,17 @@ namespace llvm { class MCInst; class AsmPrinter; -FunctionPass *createPPCBranchSelectionPass(); -FunctionPass *createPPCISelDag(PPCTargetMachine &TM); -FunctionPass *createPPCJITCodeEmitterPass(PPCTargetMachine &TM, - JITCodeEmitter &MCE); - -void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, - AsmPrinter &AP); - -extern Target ThePPC32Target; -extern Target ThePPC64Target; - + FunctionPass *createPPCBranchSelectionPass(); + FunctionPass *createPPCISelDag(PPCTargetMachine &TM); + FunctionPass *createPPCJITCodeEmitterPass(PPCTargetMachine &TM, + JITCodeEmitter &MCE); + + void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, + AsmPrinter &AP); + + extern Target ThePPC32Target; + extern Target ThePPC64Target; + namespace PPCII { /// Target Operand Flag enum. @@ -50,23 +50,23 @@ extern Target ThePPC64Target; /// MO_DARWIN_STUB - On a symbol operand "FOO", this indicates that the /// reference is actually to the "FOO$stub" symbol. This is used for calls /// and jumps to external functions on Tiger and earlier. - MO_DARWIN_STUB, + MO_DARWIN_STUB = 1, - /// MO_LO16 - On a symbol operand, this represents a relocation containing - /// lower 16 bit of the address. - MO_LO16, - - /// MO_HA16 - On a symbol operand, this represents a relocation containing - /// higher 16 bit of the address. - MO_HA16, + /// MO_LO16, MO_HA16 - lo16(symbol) and ha16(symbol) + MO_LO16 = 4, MO_HA16 = 8, - /// MO_LO16_PIC - On a symbol operand, this represents a relocation - /// containing lower 16 bit of the address with the picbase subtracted. - MO_LO16_PIC, + /// MO_PIC_FLAG - If this bit is set, the symbol reference is relative to + /// the function's picbase, e.g. lo16(symbol-picbase). + MO_PIC_FLAG = 16, + + /// MO_NLP_FLAG - If this bit is set, the symbol reference is actually to + /// the non_lazy_ptr for the global, e.g. lo16(symbol$non_lazy_ptr-picbase). + MO_NLP_FLAG = 32, - /// MO_HA16_PIC - On a symbol operand, this represents a relocation - /// containing higher 16 bit of the address with the picbase subtracted. - MO_HA16_PIC + /// MO_NLP_HIDDEN_FLAG - If this bit is set, the symbol reference is to a + /// symbol with hidden visibility. This causes a different kind of + /// non-lazy-pointer to be generated. + MO_NLP_HIDDEN_FLAG = 64 }; } // end namespace PPCII diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index e31cefd6be2d..7649088f04c1 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1101,14 +1101,31 @@ bool PPCTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base, /// GetLabelAccessInfo - Return true if we should reference labels using a /// PICBase, set the HiOpFlags and LoOpFlags to the target MO flags. static bool GetLabelAccessInfo(const TargetMachine &TM, unsigned &HiOpFlags, - unsigned &LoOpFlags) { + unsigned &LoOpFlags, const GlobalValue *GV = 0) { + HiOpFlags = PPCII::MO_HA16; + LoOpFlags = PPCII::MO_LO16; + // Don't use the pic base if not in PIC relocation model. Or if we are on a // non-darwin platform. We don't support PIC on other platforms yet. bool isPIC = TM.getRelocationModel() == Reloc::PIC_ && TM.getSubtarget().isDarwin(); + if (isPIC) { + HiOpFlags |= PPCII::MO_PIC_FLAG; + LoOpFlags |= PPCII::MO_PIC_FLAG; + } + + // If this is a reference to a global value that requires a non-lazy-ptr, make + // sure that instruction lowering adds it. + if (GV && TM.getSubtarget().hasLazyResolverStub(GV, TM)) { + HiOpFlags |= PPCII::MO_NLP_FLAG; + LoOpFlags |= PPCII::MO_NLP_FLAG; + + if (GV->hasHiddenVisibility()) { + HiOpFlags |= PPCII::MO_NLP_HIDDEN_FLAG; + LoOpFlags |= PPCII::MO_NLP_HIDDEN_FLAG; + } + } - HiOpFlags = isPIC ? PPCII::MO_HA16_PIC : PPCII::MO_HA16; - LoOpFlags = isPIC ? PPCII::MO_LO16_PIC : PPCII::MO_LO16; return isPIC; } @@ -1178,8 +1195,6 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op, DebugLoc DL = GSDN->getDebugLoc(); const GlobalValue *GV = GSDN->getGlobal(); - const TargetMachine &TM = DAG.getTarget(); - // 64-bit SVR4 ABI code is always position-independent. // The actual address of the GlobalValue is stored in the TOC. if (PPCSubTarget.isSVR4ABI() && PPCSubTarget.isPPC64()) { @@ -1188,38 +1203,22 @@ SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op, DAG.getRegister(PPC::X2, MVT::i64)); } - SDValue GA = DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset()); + unsigned MOHiFlag, MOLoFlag; + bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag, GV); + SDValue GAHi = + DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset(), MOHiFlag); + SDValue GALo = + DAG.getTargetGlobalAddress(GV, DL, PtrVT, GSDN->getOffset(), MOLoFlag); - SDValue Zero = DAG.getConstant(0, PtrVT); - SDValue Hi = DAG.getNode(PPCISD::Hi, DL, PtrVT, GA, Zero); - SDValue Lo = DAG.getNode(PPCISD::Lo, DL, PtrVT, GA, Zero); + SDValue Ptr = LowerLabelRef(GAHi, GALo, isPIC, DAG); - // If this is a non-darwin platform, we don't support non-static relo models - // yet. - if (TM.getRelocationModel() == Reloc::Static || - !TM.getSubtarget().isDarwin()) { - // Generate non-pic code that has direct accesses to globals. - // The address of the global is just (hi(&g)+lo(&g)). - return DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo); - } - - if (TM.getRelocationModel() == Reloc::PIC_) { - // With PIC, the first instruction is actually "GR+hi(&G)". - Hi = DAG.getNode(ISD::ADD, DL, PtrVT, - DAG.getNode(PPCISD::GlobalBaseReg, - DebugLoc(), PtrVT), Hi); - } - - Lo = DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo); - - if (!TM.getSubtarget().hasLazyResolverStub(GV, TM)) - return Lo; - - // If the global is weak or external, we have to go through the lazy - // resolution stub. - return DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Lo, MachinePointerInfo(), - false, false, 0); + // If the global reference is actually to a non-lazy-pointer, we have to do an + // extra load to get the address of the global. + if (MOHiFlag & PPCII::MO_NLP_FLAG) + Ptr = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo(), + false, false, 0); + return Ptr; } SDValue PPCTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { diff --git a/llvm/lib/Target/PowerPC/PPCMCInstLower.cpp b/llvm/lib/Target/PowerPC/PPCMCInstLower.cpp index ca43ef5be620..6082587b2d3d 100644 --- a/llvm/lib/Target/PowerPC/PPCMCInstLower.cpp +++ b/llvm/lib/Target/PowerPC/PPCMCInstLower.cpp @@ -40,10 +40,7 @@ static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){ const GlobalValue *GV = MO.getGlobal(); bool isImplicitlyPrivate = false; if (MO.getTargetFlags() == PPCII::MO_DARWIN_STUB || - //MO.getTargetFlags() == PPCII::MO_DARWIN_NONLAZY || - //MO.getTargetFlags() == PPCII::MO_DARWIN_NONLAZY_PIC_BASE || - //MO.getTargetFlags() == PPCII::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE - 0) + (MO.getTargetFlags() & PPCII::MO_NLP_FLAG)) isImplicitlyPrivate = true; AP.Mang->getNameWithPrefix(Name, GV, isImplicitlyPrivate); @@ -51,41 +48,7 @@ static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){ // If the target flags on the operand changes the name of the symbol, do that // before we return the symbol. - switch (MO.getTargetFlags()) { - default: break; -#if 0 - case X86II::MO_DARWIN_NONLAZY: - case X86II::MO_DARWIN_NONLAZY_PIC_BASE: { - Name += "$non_lazy_ptr"; - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); - - MachineModuleInfoImpl::StubValueTy &StubSym = - getMachOMMI(AP).getGVStubEntry(Sym); - if (StubSym.getPointer() == 0) { - assert(MO.isGlobal() && "Extern symbol not handled yet"); - StubSym = - MachineModuleInfoImpl:: - StubValueTy(Mang->getSymbol(MO.getGlobal()), - !MO.getGlobal()->hasInternalLinkage()); - } - return Sym; - } - case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: { - Name += "$non_lazy_ptr"; - MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); - MachineModuleInfoImpl::StubValueTy &StubSym = - getMachOMMI(AP).getHiddenGVStubEntry(Sym); - if (StubSym.getPointer() == 0) { - assert(MO.isGlobal() && "Extern symbol not handled yet"); - StubSym = - MachineModuleInfoImpl:: - StubValueTy(Mang->getSymbol(MO.getGlobal()), - !MO.getGlobal()->hasInternalLinkage()); - } - return Sym; - } -#endif - case PPCII::MO_DARWIN_STUB: { + if (MO.getTargetFlags() == PPCII::MO_DARWIN_STUB) { Name += "$stub"; MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); MachineModuleInfoImpl::StubValueTy &StubSym = @@ -106,6 +69,26 @@ static MCSymbol *GetSymbolFromOperand(const MachineOperand &MO, AsmPrinter &AP){ } return Sym; } + + // If the symbol reference is actually to a non_lazy_ptr, not to the symbol, + // then add the suffix. + if (MO.getTargetFlags() & PPCII::MO_NLP_FLAG) { + Name += "$non_lazy_ptr"; + MCSymbol *Sym = Ctx.GetOrCreateSymbol(Name.str()); + + MachineModuleInfoMachO &MachO = getMachOMMI(AP); + + MachineModuleInfoImpl::StubValueTy &StubSym = + (MO.getTargetFlags() & PPCII::MO_NLP_HIDDEN_FLAG) ? + MachO.getHiddenGVStubEntry(Sym) : MachO.getGVStubEntry(Sym); + + if (StubSym.getPointer() == 0) { + assert(MO.isGlobal() && "Extern symbol not handled yet"); + StubSym = MachineModuleInfoImpl:: + StubValueTy(AP.Mang->getSymbol(MO.getGlobal()), + !MO.getGlobal()->hasInternalLinkage()); + } + return Sym; } return Ctx.GetOrCreateSymbol(Name.str()); @@ -116,31 +99,25 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol, MCContext &Ctx = Printer.OutContext; MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None; - const MCExpr *Expr = 0; - switch (MO.getTargetFlags()) { - default: assert(0 && "Unknown target flag on symbol operand"); - case PPCII::MO_NO_FLAG: - // These affect the name of the symbol, not any suffix. - case PPCII::MO_DARWIN_STUB: - break; - - case PPCII::MO_LO16: RefKind = MCSymbolRefExpr::VK_PPC_LO16; break; - case PPCII::MO_HA16: RefKind = MCSymbolRefExpr::VK_PPC_HA16; break; - case PPCII::MO_LO16_PIC: break; - case PPCII::MO_HA16_PIC: break; - } + if (MO.getTargetFlags() & PPCII::MO_LO16) + RefKind = MCSymbolRefExpr::VK_PPC_LO16; + else if (MO.getTargetFlags() & PPCII::MO_HA16) + RefKind = MCSymbolRefExpr::VK_PPC_HA16; - if (Expr == 0) - Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx); + // FIXME: This isn't right, but we don't have a good way to express this in + // the MC Level, see below. + if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) + RefKind = MCSymbolRefExpr::VK_None; + + const MCExpr *Expr = MCSymbolRefExpr::Create(Symbol, RefKind, Ctx); if (!MO.isJTI() && MO.getOffset()) Expr = MCBinaryExpr::CreateAdd(Expr, MCConstantExpr::Create(MO.getOffset(), Ctx), Ctx); - // Subtract off the PIC base. - if (MO.getTargetFlags() == PPCII::MO_LO16_PIC || - MO.getTargetFlags() == PPCII::MO_HA16_PIC) { + // Subtract off the PIC base if required. + if (MO.getTargetFlags() & PPCII::MO_PIC_FLAG) { const MachineFunction *MF = MO.getParent()->getParent()->getParent(); const MCExpr *PB = MCSymbolRefExpr::Create(MF->getPICBaseSymbol(), Ctx);