Skip to content
X86InstrInfo.cpp 110 KiB
Newer Older
    break;

  case X86II::MRM0m: case X86II::MRM1m:
  case X86II::MRM2m: case X86II::MRM3m:
  case X86II::MRM4m: case X86II::MRM5m:
  case X86II::MRM6m: case X86II::MRM7m: {
    
    ++FinalSize;
    FinalSize += getMemModRMByteSize(MI, CurOp, IsPIC, Is64BitMode);
    CurOp += 4;

    if (CurOp != NumOps) {
      const MachineOperand &MO = MI.getOperand(CurOp++);
      unsigned Size = X86InstrInfo::sizeOfImm(Desc);
        FinalSize += sizeConstant(Size);
      else {
        bool dword = false;
        if (Opcode == X86::MOV64mi32)
          dword = true;
          FinalSize += sizeGlobalAddress(dword);
          FinalSize += sizeExternalSymbolAddress(dword);
          FinalSize += sizeConstPoolAddress(dword);
          FinalSize += sizeJumpTableAddress(dword);
      }
    }
    break;
  }

  case X86II::MRMInitReg:
    ++FinalSize;
    // Duplicate register, used by things like MOV8r0 (aka xor reg,reg).
    FinalSize += sizeRegModRMByte();
    ++CurOp;
    break;
  }

  if (!Desc->isVariadic() && CurOp != NumOps) {
    cerr << "Cannot determine size: ";
    MI.dump();
    cerr << '\n';
    abort();
  }
  

  return FinalSize;
}


unsigned X86InstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
  const TargetInstrDesc &Desc = MI->getDesc();
  bool IsPIC = (TM.getRelocationModel() == Reloc::PIC_);
  bool Is64BitMode = TM.getSubtargetImpl()->is64Bit();
  unsigned Size = GetInstSizeWithDesc(*MI, &Desc, IsPIC, Is64BitMode);
  if (Desc.getOpcode() == X86::MOVPC32r) {
    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;