summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/PowerPC/PPC.h50
-rw-r--r--lib/Target/PowerPC/PPCISelLowering.cpp67
-rw-r--r--lib/Target/PowerPC/PPCMCInstLower.cpp91
3 files changed, 92 insertions, 116 deletions
diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h
index 6fe5cef771..460d8e1744 100644
--- a/lib/Target/PowerPC/PPC.h
+++ b/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_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_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_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/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp
index e31cefd6be..7649088f04 100644
--- a/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/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<PPCSubtarget>().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<PPCSubtarget>().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);
-
- // If this is a non-darwin platform, we don't support non-static relo models
- // yet.
- if (TM.getRelocationModel() == Reloc::Static ||
- !TM.getSubtarget<PPCSubtarget>().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);
- }
+ SDValue Ptr = LowerLabelRef(GAHi, GALo, isPIC, DAG);
- Lo = DAG.getNode(ISD::ADD, DL, PtrVT, Hi, Lo);
-
- if (!TM.getSubtarget<PPCSubtarget>().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/lib/Target/PowerPC/PPCMCInstLower.cpp b/lib/Target/PowerPC/PPCMCInstLower.cpp
index ca43ef5be6..6082587b2d 100644
--- a/lib/Target/PowerPC/PPCMCInstLower.cpp
+++ b/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);