aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/ARMAsmPrinter.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2011-01-17 08:03:18 +0000
committerEvan Cheng <evan.cheng@apple.com>2011-01-17 08:03:18 +0000
commit5de5d4b6d0eb3fd379fa571d82f6fa764460b3b8 (patch)
tree3e3003c4648ab61634d5f42fa60ae13332153883 /lib/Target/ARM/ARMAsmPrinter.cpp
parentb1086a9c6d6d5ee3070a68076f38eec841cefd58 (diff)
downloadexternal_llvm-5de5d4b6d0eb3fd379fa571d82f6fa764460b3b8.zip
external_llvm-5de5d4b6d0eb3fd379fa571d82f6fa764460b3b8.tar.gz
external_llvm-5de5d4b6d0eb3fd379fa571d82f6fa764460b3b8.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123619 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMAsmPrinter.cpp')
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp96
1 files changed, 78 insertions, 18 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp
index d1a975d..71a471d 100644
--- a/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -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: