mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-02 05:12:20 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119106 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1e61e69d40
commit
6d2ff122af
@ -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
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user