Skip to content
X86InstrInfo.cpp 107 KiB
Newer Older
    Size += GetInstSizeWithDesc(*MI, &get(X86::POP32r), IsPIC, Is64BitMode);
  }
  return Size;
}
/// getGlobalBaseReg - Return a virtual register initialized with the
/// the global base register value. Output instructions required to
/// initialize the register in the function entry block, if necessary.
unsigned X86InstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
  assert(!TM.getSubtarget<X86Subtarget>().is64Bit() &&
         "X86-64 PIC uses RIP relative addressing");

  X86MachineFunctionInfo *X86FI = MF->getInfo<X86MachineFunctionInfo>();
  unsigned GlobalBaseReg = X86FI->getGlobalBaseReg();
  if (GlobalBaseReg != 0)
    return GlobalBaseReg;

  // Insert the set of GlobalBaseReg into the first MBB of the function
  MachineBasicBlock &FirstMBB = MF->front();
  MachineBasicBlock::iterator MBBI = FirstMBB.begin();
  MachineRegisterInfo &RegInfo = MF->getRegInfo();
  unsigned PC = RegInfo.createVirtualRegister(X86::GR32RegisterClass);
  
  const TargetInstrInfo *TII = TM.getInstrInfo();
  // Operand of MovePCtoStack is completely ignored by asm printer. It's
  // only used in JIT code emission as displacement to pc.
  BuildMI(FirstMBB, MBBI, TII->get(X86::MOVPC32r), PC).addImm(0);
  
  // If we're using vanilla 'GOT' PIC style, we should use relative addressing
  // not to pc, but to _GLOBAL_ADDRESS_TABLE_ external
  if (TM.getRelocationModel() == Reloc::PIC_ &&
      TM.getSubtarget<X86Subtarget>().isPICStyleGOT()) {
      RegInfo.createVirtualRegister(X86::GR32RegisterClass);
    BuildMI(FirstMBB, MBBI, TII->get(X86::ADD32ri), GlobalBaseReg)
      .addReg(PC).addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
  } else {
    GlobalBaseReg = PC;
  X86FI->setGlobalBaseReg(GlobalBaseReg);
  return GlobalBaseReg;