1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

Materialize GA addresses with movw + movt pairs for Darwin in PIC mode. e.g.

movw    r0, :lower16:(L_foo$non_lazy_ptr-(LPC0_0+4))
        movt    r0, :upper16:(L_foo$non_lazy_ptr-(LPC0_0+4))
LPC0_0:
        add     r0, pc, r0

It's not yet enabled by default as some tests are failing. I suspect bugs in
down stream tools.

llvm-svn: 123619
This commit is contained in:
Evan Cheng 2011-01-17 08:03:18 +00:00
parent 77e381e302
commit 53ec6fc591
18 changed files with 248 additions and 85 deletions

View File

@ -20,6 +20,7 @@
#include "ARMBaseRegisterInfo.h"
#include "ARMConstantPoolValue.h"
#include "ARMMachineFunctionInfo.h"
#include "ARMMCExpr.h"
#include "ARMTargetMachine.h"
#include "ARMTargetObjectFile.h"
#include "InstPrinter/ARMInstPrinter.h"
@ -537,6 +538,25 @@ getModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
return MCSymbolRefExpr::VK_None;
}
MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV) {
bool isIndirect = Subtarget->isTargetDarwin() &&
Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
if (!isIndirect)
return Mang->getSymbol(GV);
// FIXME: Remove this when Darwin transition to @GOT like syntax.
MCSymbol *MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
MachineModuleInfoMachO &MMIMachO =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
MachineModuleInfoImpl::StubValueTy &StubSym =
GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) :
MMIMachO.getGVStubEntry(MCSym);
if (StubSym.getPointer() == 0)
StubSym = MachineModuleInfoImpl::
StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
return MCSym;
}
void ARMAsmPrinter::
EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
int Size = TM.getTargetData()->getTypeAllocSize(MCPV->getType());
@ -553,23 +573,7 @@ EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
MCSym = GetBlockAddressSymbol(ACPV->getBlockAddress());
} else if (ACPV->isGlobalValue()) {
const GlobalValue *GV = ACPV->getGV();
bool isIndirect = Subtarget->isTargetDarwin() &&
Subtarget->GVIsIndirectSymbol(GV, TM.getRelocationModel());
if (!isIndirect)
MCSym = Mang->getSymbol(GV);
else {
// FIXME: Remove this when Darwin transition to @GOT like syntax.
MCSym = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
MachineModuleInfoMachO &MMIMachO =
MMI->getObjFileInfo<MachineModuleInfoMachO>();
MachineModuleInfoImpl::StubValueTy &StubSym =
GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) :
MMIMachO.getGVStubEntry(MCSym);
if (StubSym.getPointer() == 0)
StubSym = MachineModuleInfoImpl::
StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage());
}
MCSym = GetARMGVSymbol(GV);
} else {
assert(ACPV->isExtSymbol() && "unrecognized constant pool value");
MCSym = GetExternalSymbolSymbol(ACPV->getSymbol());
@ -737,7 +741,8 @@ void ARMAsmPrinter::EmitPatchedInstruction(const MachineInstr *MI,
}
void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
switch (MI->getOpcode()) {
unsigned Opc = MI->getOpcode();
switch (Opc) {
default: break;
case ARM::t2ADDrSPi:
case ARM::t2ADDrSPi12:
@ -858,6 +863,61 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
return;
}
case ARM::MOVi16_pic_ga:
case ARM::t2MOVi16_pic_ga: {
MCInst TmpInst;
TmpInst.setOpcode(Opc == ARM::MOVi16_pic_ga ? ARM::MOVi16 : ARM::t2MOVi16);
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
const GlobalValue *GV = MI->getOperand(1).getGlobal();
MCSymbol *GVSym = GetARMGVSymbol(GV);
const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
getFunctionNumber(), MI->getOperand(2).getImm(),
OutContext);
const MCExpr *LabelSymExpr = MCSymbolRefExpr::Create(LabelSym, OutContext);
const MCExpr *PCRelExpr =
ARMMCExpr::CreateLower16(MCBinaryExpr::CreateSub(GVSymExpr,
MCBinaryExpr::CreateAdd(LabelSymExpr,
MCConstantExpr::Create(4, OutContext),
OutContext), OutContext), OutContext);
TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
// Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
TmpInst.addOperand(MCOperand::CreateReg(0));
// Add 's' bit operand (always reg0 for this)
TmpInst.addOperand(MCOperand::CreateReg(0));
OutStreamer.EmitInstruction(TmpInst);
return;
}
case ARM::MOVTi16_pic_ga:
case ARM::t2MOVTi16_pic_ga: {
MCInst TmpInst;
TmpInst.setOpcode(Opc==ARM::MOVTi16_pic_ga ? ARM::MOVTi16 : ARM::t2MOVTi16);
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(1).getReg()));
const GlobalValue *GV = MI->getOperand(2).getGlobal();
MCSymbol *GVSym = GetARMGVSymbol(GV);
const MCExpr *GVSymExpr = MCSymbolRefExpr::Create(GVSym, OutContext);
MCSymbol *LabelSym = getPICLabel(MAI->getPrivateGlobalPrefix(),
getFunctionNumber(), MI->getOperand(3).getImm(),
OutContext);
const MCExpr *LabelSymExpr = MCSymbolRefExpr::Create(LabelSym, OutContext);
const MCExpr *PCRelExpr =
ARMMCExpr::CreateUpper16(MCBinaryExpr::CreateSub(GVSymExpr,
MCBinaryExpr::CreateAdd(LabelSymExpr,
MCConstantExpr::Create(4, OutContext),
OutContext), OutContext), OutContext);
TmpInst.addOperand(MCOperand::CreateExpr(PCRelExpr));
// Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
TmpInst.addOperand(MCOperand::CreateReg(0));
// Add 's' bit operand (always reg0 for this)
TmpInst.addOperand(MCOperand::CreateReg(0));
OutStreamer.EmitInstruction(TmpInst);
return;
}
case ARM::tPICADD: {
// This is a pseudo op for a label + instruction sequence, which looks like:
// LPC0:

View File

@ -101,6 +101,8 @@ public:
MCSymbol *GetARMSJLJEHLabel(void) const;
MCSymbol *GetARMGVSymbol(const GlobalValue *GV);
/// EmitMachineConstantPoolValue - Print a machine constantpool value to
/// the .s file.
virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);

View File

@ -185,6 +185,18 @@ namespace ARMII {
/// higher 16 bit of the address. Used only via movt instruction.
MO_HI16,
/// MO_LO16_NONLAZY_PIC - On a symbol operand "FOO", this represents a
/// relocation containing lower 16 bit of the PC relative address of the
/// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".
/// Used only via movw instruction.
MO_LO16_NONLAZY_PIC,
/// MO_HI16_NONLAZY_PIC - On a symbol operand "FOO", this represents a
/// relocation containing lower 16 bit of the PC relative address of the
/// non-lazy-ptr indirect symbol, i.e. "FOO$non_lazy_ptr - LABEL".
/// Used only via movt instruction.
MO_HI16_NONLAZY_PIC,
/// MO_PLT - On a symbol operand, this represents an ELF PLT reference on a
/// call operand.
MO_PLT

View File

@ -561,8 +561,14 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
case ARMII::Size2Bytes: return 2; // Thumb1 instruction.
case ARMII::SizeSpecial: {
switch (Opc) {
case ARM::MOVi16_pic_ga:
case ARM::MOVTi16_pic_ga:
case ARM::t2MOVi16_pic_ga:
case ARM::t2MOVTi16_pic_ga:
return 4;
case ARM::MOVi32imm:
case ARM::t2MOVi32imm:
case ARM::MOV_pic_ga:
return 8;
case ARM::CONSTPOOL_ENTRY:
// If this machine instr is a constant pool entry, its size is recorded as
@ -977,7 +983,7 @@ static unsigned duplicateCPV(MachineFunction &MF, unsigned &CPI) {
ARMConstantPoolValue *ACPV =
static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal);
unsigned PCLabelId = AFI->createConstPoolEntryUId();
unsigned PCLabelId = AFI->createPICLabelUId();
ARMConstantPoolValue *NewCPV = 0;
// FIXME: The below assumes PIC relocation model and that the function
// is Thumb mode (t1 or t2). PCAdjustment would be 8 for ARM mode PIC, and

View File

@ -316,7 +316,7 @@ bool ARMConstantIslands::runOnMachineFunction(MachineFunction &MF) {
}
/// The next UID to take is the first unused one.
AFI->initConstPoolEntryUId(CPEMIs.size());
AFI->initPICLabelUId(CPEMIs.size());
// Do the initial scan of the function, building up information about the
// sizes of each block, the location of all the water, and finding all of the
@ -1245,7 +1245,7 @@ bool ARMConstantIslands::HandleConstantPoolUser(MachineFunction &MF,
// No existing clone of this CPE is within range.
// We will be generating a new clone. Get a UID for it.
unsigned ID = AFI->createConstPoolEntryUId();
unsigned ID = AFI->createPICLabelUId();
// Look for water where we can place this CPE.
MachineBasicBlock *NewIsland = MF.CreateMachineBasicBlock();

View File

@ -765,13 +765,16 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
case ARM::MOVi32imm:
case ARM::MOVCCi32imm:
case ARM::MOV_pic_ga:
case ARM::t2MOVi32imm:
case ARM::t2MOVCCi32imm: {
case ARM::t2MOVCCi32imm:
case ARM::t2MOV_pic_ga: {
unsigned PredReg = 0;
ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
unsigned DstReg = MI.getOperand(0).getReg();
bool DstIsDead = MI.getOperand(0).isDead();
bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
bool isPIC_GA = (Opcode == ARM::t2MOV_pic_ga || Opcode == ARM::MOV_pic_ga);
const MachineOperand &MO = MI.getOperand(isCC ? 2 : 1);
MachineInstrBuilder LO16, HI16;
@ -798,14 +801,24 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
break;
}
bool isThumb =
(Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm);
unsigned LO16Opc = 0;
unsigned HI16Opc = 0;
if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) {
LO16Opc = ARM::t2MOVi16;
HI16Opc = ARM::t2MOVTi16;
} else if (Opcode == ARM::MOV_pic_ga) {
LO16Opc = ARM::MOVi16_pic_ga;
HI16Opc = ARM::MOVTi16_pic_ga;
} else if (Opcode == ARM::t2MOV_pic_ga) {
LO16Opc = ARM::t2MOVi16_pic_ga;
HI16Opc = ARM::t2MOVTi16_pic_ga;
} else {
LO16Opc = ARM::MOVi16;
HI16Opc = ARM::MOVTi16;
}
LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
TII->get(isThumb ? ARM::t2MOVi16 : ARM::MOVi16),
DstReg);
HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
TII->get(isThumb ? ARM::t2MOVTi16 : ARM::MOVTi16))
LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg);
HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc))
.addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
.addReg(DstReg);
@ -815,16 +828,30 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
unsigned Hi16 = (Imm >> 16) & 0xffff;
LO16 = LO16.addImm(Lo16);
HI16 = HI16.addImm(Hi16);
} else if (isPIC_GA) {
unsigned LabelId = MI.getOperand(2).getImm();
const GlobalValue *GV = MO.getGlobal();
unsigned TF = MO.getTargetFlags();
LO16 = LO16.addGlobalAddress(GV, MO.getOffset(),
TF | ARMII::MO_LO16_NONLAZY_PIC)
.addImm(LabelId);
HI16 = HI16.addGlobalAddress(GV, MO.getOffset(),
TF | ARMII::MO_HI16_NONLAZY_PIC)
.addImm(LabelId);
} else {
const GlobalValue *GV = MO.getGlobal();
unsigned TF = MO.getTargetFlags();
LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
}
(*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
(*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
if (!isPIC_GA) {
LO16.addImm(Pred).addReg(PredReg);
HI16.addImm(Pred).addReg(PredReg);
}
TransferImpOps(MI, LO16, HI16);
MI.eraseFromParent();
break;

View File

@ -517,7 +517,7 @@ unsigned ARMFastISel::ARMMaterializeGV(const GlobalValue *GV, EVT VT) {
// Grab index.
unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 : (Subtarget->isThumb() ? 4 : 8);
unsigned Id = AFI->createConstPoolEntryUId();
unsigned Id = AFI->createPICLabelUId();
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV, Id,
ARMCP::CPValue, PCAdj);
unsigned Idx = MCP.getConstantPoolIndex(CPV, Align);

View File

@ -127,8 +127,7 @@ public:
SDValue &Offset);
bool SelectAddrMode6(SDNode *Parent, SDValue N, SDValue &Addr,SDValue &Align);
bool SelectAddrModePC(SDValue N, SDValue &Offset,
SDValue &Label);
bool SelectAddrModePC(SDValue N, SDValue &Offset, SDValue &Label);
// Thumb Addressing Modes:
bool SelectThumbAddrModeRR(SDValue N, SDValue &Base, SDValue &Offset);

View File

@ -734,6 +734,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
switch (Opcode) {
default: return 0;
case ARMISD::Wrapper: return "ARMISD::Wrapper";
case ARMISD::WrapperPIC: return "ARMISD::WrapperPIC";
case ARMISD::WrapperJT: return "ARMISD::WrapperJT";
case ARMISD::CALL: return "ARMISD::CALL";
case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED";
@ -1315,7 +1316,7 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
const GlobalValue *GV = G->getGlobal();
// Create a constant pool entry for the callee address
unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV,
ARMPCLabelIndex,
ARMCP::CPValue, 0);
@ -1330,7 +1331,7 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
const char *Sym = S->getSymbol();
// Create a constant pool entry for the callee address
unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(*DAG.getContext(),
Sym, ARMPCLabelIndex, 0);
// Get the address of the callee into a register
@ -1352,7 +1353,7 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
isLocalARMFunc = !Subtarget->isThumb() && (!isExt || !ARMInterworking);
// tBX takes a register source operand.
if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(GV,
ARMPCLabelIndex,
ARMCP::CPValue, 4);
@ -1381,7 +1382,7 @@ ARMTargetLowering::LowerCall(SDValue Chain, SDValue Callee,
// tBX takes a register source operand.
const char *Sym = S->getSymbol();
if (isARMFunc && Subtarget->isThumb1Only() && !Subtarget->hasV5TOps()) {
unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(*DAG.getContext(),
Sym, ARMPCLabelIndex, 4);
SDValue CPAddr = DAG.getTargetConstantPool(CPV, getPointerTy(), 4);
@ -1808,7 +1809,7 @@ SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op,
CPAddr = DAG.getTargetConstantPool(BA, PtrVT, 4);
} else {
unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
ARMPCLabelIndex = AFI->createConstPoolEntryUId();
ARMPCLabelIndex = AFI->createPICLabelUId();
ARMConstantPoolValue *CPV = new ARMConstantPoolValue(BA, ARMPCLabelIndex,
ARMCP::CPBlockAddress,
PCAdj);
@ -1833,7 +1834,7 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
MachineFunction &MF = DAG.getMachineFunction();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
ARMConstantPoolValue *CPV =
new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex,
ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true);
@ -1878,7 +1879,7 @@ ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
if (GV->isDeclaration()) {
MachineFunction &MF = DAG.getMachineFunction();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
// Initial exec model.
unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
ARMConstantPoolValue *CPV =
@ -1949,10 +1950,13 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
Result = DAG.getLoad(PtrVT, dl, Chain, Result,
MachinePointerInfo::getGOT(), false, false, 0);
return Result;
} else {
}
// If we have T2 ops, we can materialize the address directly via movt/movw
// pair. This is always cheaper.
if (Subtarget->useMovt()) {
// FIXME: Once remat is capable of dealing with instructions with register
// operands, expand this into two nodes.
return DAG.getNode(ARMISD::Wrapper, dl, PtrVT,
DAG.getTargetGlobalAddress(GV, dl, PtrVT));
} else {
@ -1962,23 +1966,39 @@ SDValue ARMTargetLowering::LowerGlobalAddressELF(SDValue Op,
MachinePointerInfo::getConstantPool(),
false, false, 0);
}
}
}
SDValue ARMTargetLowering::LowerGlobalAddressDarwin(SDValue Op,
SelectionDAG &DAG) const {
MachineFunction &MF = DAG.getMachineFunction();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned ARMPCLabelIndex = 0;
EVT PtrVT = getPointerTy();
DebugLoc dl = Op.getDebugLoc();
const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
Reloc::Model RelocM = getTargetMachine().getRelocationModel();
MachineFunction &MF = DAG.getMachineFunction();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
if (Subtarget->useMovt()) {
// FIXME: Once remat is capable of dealing with instructions with register
// operands, expand this into two nodes.
if (RelocM != Reloc::PIC_)
return DAG.getNode(ARMISD::Wrapper, dl, PtrVT,
DAG.getTargetGlobalAddress(GV, dl, PtrVT));
// FIXME: Not a constant pool!
unsigned PICLabelIndex = AFI->createPICLabelUId();
SDValue PICLabel = DAG.getConstant(PICLabelIndex, MVT::i32);
SDValue Result = DAG.getNode(ARMISD::WrapperPIC, dl, PtrVT,
DAG.getTargetGlobalAddress(GV, dl, PtrVT),
PICLabel);
return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel);
}
unsigned ARMPCLabelIndex = 0;
SDValue CPAddr;
if (RelocM == Reloc::Static)
if (RelocM == Reloc::Static) {
CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 4);
else {
ARMPCLabelIndex = AFI->createConstPoolEntryUId();
} else {
ARMPCLabelIndex = AFI->createPICLabelUId();
unsigned PCAdj = (RelocM != Reloc::PIC_) ? 0 : (Subtarget->isThumb()?4:8);
ARMConstantPoolValue *CPV =
new ARMConstantPoolValue(GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj);
@ -2009,7 +2029,7 @@ SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op,
"GLOBAL OFFSET TABLE not implemented for non-ELF targets");
MachineFunction &MF = DAG.getMachineFunction();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
EVT PtrVT = getPointerTy();
DebugLoc dl = Op.getDebugLoc();
unsigned PCAdj = Subtarget->isThumb() ? 4 : 8;
@ -2062,7 +2082,7 @@ ARMTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG,
case Intrinsic::eh_sjlj_lsda: {
MachineFunction &MF = DAG.getMachineFunction();
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
unsigned ARMPCLabelIndex = AFI->createConstPoolEntryUId();
unsigned ARMPCLabelIndex = AFI->createPICLabelUId();
EVT PtrVT = getPointerTy();
DebugLoc dl = Op.getDebugLoc();
Reloc::Model RelocM = getTargetMachine().getRelocationModel();

View File

@ -34,6 +34,8 @@ namespace llvm {
Wrapper, // Wrapper - A wrapper node for TargetConstantPool,
// TargetExternalSymbol, and TargetGlobalAddress.
WrapperPIC, // WrapperPIC - A wrapper node for TargetGlobalAddress in
// PIC mode.
WrapperJT, // WrapperJT - A wrapper node for TargetJumpTable
CALL, // Function call.

View File

@ -70,6 +70,7 @@ def SDT_ARMBFI : SDTypeProfile<1, 3, [SDTCisVT<0, i32>, SDTCisVT<1, i32>,
// Node definitions.
def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
def ARMWrapperPIC : SDNode<"ARMISD::WrapperPIC", SDTIntBinOp>;
def ARMcallseq_start : SDNode<"ISD::CALLSEQ_START", SDT_ARMCallSeqStart,
[SDNPHasChain, SDNPOutGlue]>;
@ -1930,7 +1931,10 @@ def MOVi16 : AI1<0b1000, (outs GPR:$Rd), (ins i32imm_hilo16:$imm),
let Inst{25} = 1;
}
let Constraints = "$src = $Rd" in
def MOVi16_pic_ga : PseudoInst<(outs GPR:$Rd),
(ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
let Constraints = "$src = $Rd" in {
def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm),
DPFrm, IIC_iMOVi,
"movt", "\t$Rd, $imm",
@ -1947,6 +1951,11 @@ def MOVTi16 : AI1<0b1010, (outs GPR:$Rd), (ins GPR:$src, i32imm_hilo16:$imm),
let Inst{25} = 1;
}
def MOVTi16_pic_ga : PseudoInst<(outs GPR:$Rd),
(ins GPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
} // Constraints
def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
Requires<[IsARM, HasV6T2]>;
@ -3363,11 +3372,17 @@ def Int_eh_sjlj_dispatchsetup :
// This is a single pseudo instruction, the benefit is that it can be remat'd
// as a single unit instead of having to handle reg inputs.
// FIXME: Remove this when we can do generalized remat.
let isReMaterializable = 1, isMoveImm = 1 in
let isReMaterializable = 1, isMoveImm = 1 in {
def MOVi32imm : PseudoInst<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
[(set GPR:$dst, (arm_i32imm:$src))]>,
Requires<[IsARM]>;
def MOV_pic_ga : PseudoInst<(outs GPR:$dst),
(ins i32imm:$addr, pclabel:$id), IIC_iMOVix2,
[(set GPR:$dst, (ARMWrapperPIC tglobaladdr:$addr, imm:$id))]>,
Requires<[IsARM, UseMovt]>;
} // isReMaterializable = 1, isMoveImm = 1 in
// ConstantPool, GlobalAddress, and JumpTable
def : ARMPat<(ARMWrapper tglobaladdr :$dst), (LEApcrel tglobaladdr :$dst)>,
Requires<[IsARM, DontUseMovt]>;

View File

@ -1696,7 +1696,10 @@ def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins i32imm_hilo16:$imm), IIC_iMOVi,
let Inst{7-0} = imm{7-0};
}
let Constraints = "$src = $Rd" in
def t2MOVi16_pic_ga : PseudoInst<(outs rGPR:$Rd),
(ins i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
let Constraints = "$src = $Rd" in {
def t2MOVTi16 : T2I<(outs rGPR:$Rd),
(ins rGPR:$src, i32imm_hilo16:$imm), IIC_iMOVi,
"movt", "\t$Rd, $imm",
@ -1718,6 +1721,10 @@ def t2MOVTi16 : T2I<(outs rGPR:$Rd),
let Inst{7-0} = imm{7-0};
}
def t2MOVTi16_pic_ga : PseudoInst<(outs rGPR:$Rd),
(ins rGPR:$src, i32imm:$addr, pclabel:$id), IIC_iMOVi, []>;
} // Constraints
def : T2Pat<(or rGPR:$src, 0xffff0000), (t2MOVTi16 rGPR:$src, 0xffff)>;
//===----------------------------------------------------------------------===//
@ -3209,11 +3216,17 @@ def t2RFEIA : T2RFE<0b111010011001,
// 32-bit immediate using movw + movt.
// This is a single pseudo instruction to make it re-materializable.
// FIXME: Remove this when we can do generalized remat.
let isReMaterializable = 1, isMoveImm = 1 in
let isReMaterializable = 1, isMoveImm = 1 in {
def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
[(set rGPR:$dst, (i32 imm:$src))]>,
Requires<[IsThumb, HasV6T2]>;
def t2MOV_pic_ga : PseudoInst<(outs rGPR:$dst),
(ins i32imm:$addr, pclabel:$id), IIC_iMOVix2,
[(set rGPR:$dst, (ARMWrapperPIC tglobaladdr:$addr, imm:$id))]>,
Requires<[IsThumb2, UseMovt]>;
} // isReMaterializable = 1, isMoveImm = 1 in
// ConstantPool, GlobalAddress, and JumpTable
def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
Requires<[IsThumb2, DontUseMovt]>;

View File

@ -105,7 +105,7 @@ namespace llvm {
/// model is PIC.
void Initialize(const MachineFunction &MF, bool isPIC) {
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
ConstPoolId2AddrMap.resize(AFI->getNumConstPoolEntries());
ConstPoolId2AddrMap.resize(AFI->getNumPICLabels());
JumpTableId2AddrMap.resize(AFI->getNumJumpTables());
IsPIC = isPIC;
}

View File

@ -87,7 +87,7 @@ class ARMFunctionInfo : public MachineFunctionInfo {
///
unsigned JumpTableUId;
unsigned ConstPoolEntryUId;
unsigned PICLabelUId;
/// VarArgsFrameIndex - FrameIndex for start of varargs area.
int VarArgsFrameIndex;
@ -104,8 +104,8 @@ public:
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0),
JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0),
HasITBlocks(false) {}
JumpTableUId(0), PICLabelUId(0),
VarArgsFrameIndex(0), HasITBlocks(false) {}
explicit ARMFunctionInfo(MachineFunction &MF) :
isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
@ -116,8 +116,8 @@ public:
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32),
SpilledCSRegs(MF.getTarget().getRegisterInfo()->getNumRegs()),
JumpTableUId(0), ConstPoolEntryUId(0), VarArgsFrameIndex(0),
HasITBlocks(false) {}
JumpTableUId(0), PICLabelUId(0),
VarArgsFrameIndex(0), HasITBlocks(false) {}
bool isThumbFunction() const { return isThumb; }
bool isThumb1OnlyFunction() const { return isThumb && !hasThumb2; }
@ -227,16 +227,16 @@ public:
return JumpTableUId;
}
void initConstPoolEntryUId(unsigned UId) {
ConstPoolEntryUId = UId;
void initPICLabelUId(unsigned UId) {
PICLabelUId = UId;
}
unsigned getNumConstPoolEntries() const {
return ConstPoolEntryUId;
unsigned getNumPICLabels() const {
return PICLabelUId;
}
unsigned createConstPoolEntryUId() {
return ConstPoolEntryUId++;
unsigned createPICLabelUId() {
return PICLabelUId++;
}
int getVarArgsFrameIndex() const { return VarArgsFrameIndex; }

View File

@ -25,8 +25,7 @@ ReserveR9("arm-reserve-r9", cl::Hidden,
cl::desc("Reserve R9, making it unavailable as GPR"));
static cl::opt<bool>
UseMOVT("arm-use-movt",
cl::init(true), cl::Hidden);
UseMOVT("arm-darwin-use-movt", cl::init(false), cl::Hidden);
static cl::opt<bool>
StrictAlign("arm-strict-align", cl::Hidden,
@ -45,7 +44,7 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
, NoARM(false)
, PostRAScheduler(false)
, IsR9Reserved(ReserveR9)
, UseMovt(UseMOVT)
, UseMovt(false)
, HasFP16(false)
, HasD16(false)
, HasHardwareDivide(false)
@ -147,8 +146,16 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &FS,
if (isAAPCS_ABI())
stackAlignment = 8;
if (isTargetDarwin())
if (!isTargetDarwin())
UseMovt = hasV6T2Ops();
else {
IsR9Reserved = ReserveR9 | (ARMArchVersion < V6);
if (UseMOVT && hasV6T2Ops()) {
unsigned Maj, Min, Rev;
TargetTriple.getDarwinNumber(Maj, Min, Rev);
UseMovt = (Maj > 4 || Min > 2);
}
}
if (!isThumb() || hasThumb2())
PostRAScheduler = true;

View File

@ -1,4 +1,4 @@
; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -filetype=obj -o - | \
; RUN: llc %s -mtriple=armv7-linux-gnueabi -filetype=obj -o - | \
; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=OBJ %s
target triple = "armv7-none-linux-gnueabi"

View File

@ -1,4 +1,4 @@
; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -relocation-model=pic -filetype=obj -o - | \
; RUN: llc %s -mtriple=armv7-linux-gnueabi -relocation-model=pic -filetype=obj -o - | \
; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=PIC01 %s
;; FIXME: Reduce this test further, or even better,

View File

@ -1,6 +1,6 @@
; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -filetype=obj -o - | \
; RUN: llc %s -mtriple=armv7-linux-gnueabi -filetype=obj -o - | \
; RUN: elf-dump --dump-section-data | FileCheck -check-prefix=OBJ %s
; RUN: llc %s -mtriple=armv7-linux-gnueabi -arm-use-movt -o - | \
; RUN: llc %s -mtriple=armv7-linux-gnueabi -o - | \
; RUN: FileCheck -check-prefix=ASM %s