@@ -5851,7 +5851,9 @@ isSafeToMoveRegClassDefs(const TargetRegisterClass *RC) const {
5851
5851
// / TODO: Eliminate this and move the code to X86MachineFunctionInfo.
5852
5852
// /
5853
5853
unsigned X86InstrInfo::getGlobalBaseReg (MachineFunction *MF) const {
5854
- assert (!Subtarget.is64Bit () &&
5854
+ assert ((!Subtarget.is64Bit () ||
5855
+ MF->getTarget ().getCodeModel () == CodeModel::Medium ||
5856
+ MF->getTarget ().getCodeModel () == CodeModel::Large) &&
5855
5857
" X86-64 PIC uses RIP relative addressing" );
5856
5858
5857
5859
X86MachineFunctionInfo *X86FI = MF->getInfo <X86MachineFunctionInfo>();
@@ -5862,7 +5864,8 @@ unsigned X86InstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
5862
5864
// Create the register. The code to initialize it is inserted
5863
5865
// later, by the CGBR pass (below).
5864
5866
MachineRegisterInfo &RegInfo = MF->getRegInfo ();
5865
- GlobalBaseReg = RegInfo.createVirtualRegister (&X86::GR32_NOSPRegClass);
5867
+ GlobalBaseReg = RegInfo.createVirtualRegister (
5868
+ Subtarget.is64Bit () ? &X86::GR64_NOSPRegClass : &X86::GR32_NOSPRegClass);
5866
5869
X86FI->setGlobalBaseReg (GlobalBaseReg);
5867
5870
return GlobalBaseReg;
5868
5871
}
@@ -7321,9 +7324,10 @@ namespace {
7321
7324
static_cast <const X86TargetMachine *>(&MF.getTarget ());
7322
7325
const X86Subtarget &STI = MF.getSubtarget <X86Subtarget>();
7323
7326
7324
- // Don't do anything if this is 64-bit as 64-bit PIC
7325
- // uses RIP relative addressing.
7326
- if (STI.is64Bit ())
7327
+ // Don't do anything in the 64-bit small and kernel code models. They use
7328
+ // RIP-relative addressing for everything.
7329
+ if (STI.is64Bit () && (TM->getCodeModel () == CodeModel::Small ||
7330
+ TM->getCodeModel () == CodeModel::Kernel))
7327
7331
return false ;
7328
7332
7329
7333
// Only emit a global base reg in PIC mode.
@@ -7350,17 +7354,41 @@ namespace {
7350
7354
else
7351
7355
PC = GlobalBaseReg;
7352
7356
7353
- // Operand of MovePCtoStack is completely ignored by asm printer. It's
7354
- // only used in JIT code emission as displacement to pc.
7355
- BuildMI (FirstMBB, MBBI, DL, TII->get (X86::MOVPC32r), PC).addImm (0 );
7356
-
7357
- // If we're using vanilla 'GOT' PIC style, we should use relative addressing
7358
- // not to pc, but to _GLOBAL_OFFSET_TABLE_ external.
7359
- if (STI.isPICStyleGOT ()) {
7360
- // Generate addl $__GLOBAL_OFFSET_TABLE_ + [.-piclabel], %some_register
7361
- BuildMI (FirstMBB, MBBI, DL, TII->get (X86::ADD32ri), GlobalBaseReg)
7362
- .addReg (PC).addExternalSymbol (" _GLOBAL_OFFSET_TABLE_" ,
7363
- X86II::MO_GOT_ABSOLUTE_ADDRESS);
7357
+ if (STI.is64Bit ()) {
7358
+ if (TM->getCodeModel () == CodeModel::Medium) {
7359
+ // In the medium code model, use a RIP-relative LEA to materialize the
7360
+ // GOT.
7361
+ BuildMI (FirstMBB, MBBI, DL, TII->get (X86::LEA64r), PC)
7362
+ .addReg (X86::RIP)
7363
+ .addImm (0 )
7364
+ .addReg (0 )
7365
+ .addExternalSymbol (" _GLOBAL_OFFSET_TABLE_" )
7366
+ .addReg (0 );
7367
+ } else if (TM->getCodeModel () == CodeModel::Large) {
7368
+ // Loading the GOT in the large code model requires math with labels,
7369
+ // so we use a pseudo instruction and expand it during MC emission.
7370
+ unsigned Scratch = RegInfo.createVirtualRegister (&X86::GR64RegClass);
7371
+ BuildMI (FirstMBB, MBBI, DL, TII->get (X86::MOVGOT64r), PC)
7372
+ .addReg (Scratch, RegState::Undef | RegState::Define)
7373
+ .addExternalSymbol (" _GLOBAL_OFFSET_TABLE_" );
7374
+ } else {
7375
+ llvm_unreachable (" unexpected code model" );
7376
+ }
7377
+ } else {
7378
+ // Operand of MovePCtoStack is completely ignored by asm printer. It's
7379
+ // only used in JIT code emission as displacement to pc.
7380
+ BuildMI (FirstMBB, MBBI, DL, TII->get (X86::MOVPC32r), PC).addImm (0 );
7381
+
7382
+ // If we're using vanilla 'GOT' PIC style, we should use relative
7383
+ // addressing not to pc, but to _GLOBAL_OFFSET_TABLE_ external.
7384
+ if (STI.isPICStyleGOT ()) {
7385
+ // Generate addl $__GLOBAL_OFFSET_TABLE_ + [.-piclabel],
7386
+ // %some_register
7387
+ BuildMI (FirstMBB, MBBI, DL, TII->get (X86::ADD32ri), GlobalBaseReg)
7388
+ .addReg (PC)
7389
+ .addExternalSymbol (" _GLOBAL_OFFSET_TABLE_" ,
7390
+ X86II::MO_GOT_ABSOLUTE_ADDRESS);
7391
+ }
7364
7392
}
7365
7393
7366
7394
return true ;
0 commit comments