aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86FastISel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/X86FastISel.cpp')
-rw-r--r--lib/Target/X86/X86FastISel.cpp46
1 files changed, 35 insertions, 11 deletions
diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp
index 492ba523aa..2ed68c14a0 100644
--- a/lib/Target/X86/X86FastISel.cpp
+++ b/lib/Target/X86/X86FastISel.cpp
@@ -445,8 +445,10 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) {
if (!isCall &&
TM.getRelocationModel() == Reloc::PIC_ &&
- !Subtarget->is64Bit())
+ !Subtarget->is64Bit()) {
+ // FIXME: How do we know Base.Reg is free??
AM.Base.Reg = getInstrInfo()->getGlobalBaseReg(&MF);
+ }
// If the ABI doesn't require an extra load, return a direct reference to
// the global.
@@ -456,6 +458,11 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) {
// base and index registers are unused.
assert(AM.Base.Reg == 0 && AM.IndexReg == 0);
AM.Base.Reg = X86::RIP;
+ } else if (Subtarget->isPICStyleStub() &&
+ TM.getRelocationModel() == Reloc::PIC_) {
+ AM.GVOpFlags = X86II::MO_PIC_BASE_OFFSET;
+ } else if (Subtarget->isPICStyleGOT()) {
+ AM.GVOpFlags = X86II::MO_GOTOFF;
}
return true;
@@ -473,23 +480,40 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) {
const TargetRegisterClass *RC = NULL;
X86AddressMode StubAM;
StubAM.Base.Reg = AM.Base.Reg;
- StubAM.GV = AM.GV;
+ StubAM.GV = GV;
- if (TLI.getPointerTy() == MVT::i32) {
- Opc = X86::MOV32rm;
- RC = X86::GR32RegisterClass;
-
- if (Subtarget->isPICStyleGOT())
- StubAM.GVOpFlags = X86II::MO_GOT;
-
- } else {
+ if (TLI.getPointerTy() == MVT::i64) {
Opc = X86::MOV64rm;
RC = X86::GR64RegisterClass;
- if (TM.getRelocationModel() != Reloc::Static) {
+ if (Subtarget->isPICStyleRIPRel()) {
StubAM.GVOpFlags = X86II::MO_GOTPCREL;
StubAM.Base.Reg = X86::RIP;
}
+
+ } else {
+ Opc = X86::MOV32rm;
+ RC = X86::GR32RegisterClass;
+
+ if (Subtarget->isPICStyleGOT())
+ StubAM.GVOpFlags = X86II::MO_GOT;
+ else if (Subtarget->isPICStyleStub()) {
+ // In darwin, we have multiple different stub types, and we have both
+ // PIC and -mdynamic-no-pic. Determine whether we have a stub
+ // reference and/or whether the reference is relative to the PIC base
+ // or not.
+ bool IsPIC = TM.getRelocationModel() == Reloc::PIC_;
+
+ if (!GV->hasHiddenVisibility()) {
+ // Non-hidden $non_lazy_ptr reference.
+ StubAM.GVOpFlags = IsPIC ? X86II::MO_DARWIN_NONLAZY_PIC_BASE :
+ X86II::MO_DARWIN_NONLAZY;
+ } else {
+ // Hidden $non_lazy_ptr reference.
+ StubAM.GVOpFlags = IsPIC ? X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
+ X86II::MO_DARWIN_HIDDEN_NONLAZY;
+ }
+ }
}
LoadReg = createResultReg(RC);