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
This commit is contained in:
Chris Lattner 2010-11-15 03:13:19 +00:00
parent edb9d84dcc
commit dd6df84900
3 changed files with 92 additions and 116 deletions

View File

@ -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

View File

@ -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);
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<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);
}
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 {

View File

@ -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);