Newer
Older
break;
case TargetInstrInfo::IMPLICIT_DEF:
case X86::DWARF_LOC:
case X86::FP_REG_KILL:
break;
case X86::MOVPC32r: {
// This emits the "call" portion of this pseudo instruction.
++FinalSize;
FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
break;
}
}
CurOp = NumOps;
break;
case X86II::RawFrm:
++FinalSize;
if (CurOp != NumOps) {
const MachineOperand &MO = MI.getOperand(CurOp++);
if (MO.isMBB()) {
FinalSize += sizePCRelativeBlockAddress();
} else if (MO.isGlobal()) {
FinalSize += sizeGlobalAddress(false);
} else if (MO.isSymbol()) {
FinalSize += sizeExternalSymbolAddress(false);
} else if (MO.isImm()) {
FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
} else {
llvm_unreachable("Unknown RawFrm operand!");
}
}
break;
case X86II::AddRegFrm:
++FinalSize;
Nicolas Geoffray
committed
++CurOp;
if (CurOp != NumOps) {
const MachineOperand &MO1 = MI.getOperand(CurOp++);
unsigned Size = X86InstrInfo::sizeOfImm(Desc);
if (MO1.isImm())
FinalSize += sizeConstant(Size);
else {
bool dword = false;
if (Opcode == X86::MOV64ri)
dword = true;
if (MO1.isGlobal()) {
FinalSize += sizeGlobalAddress(dword);
} else if (MO1.isSymbol())
FinalSize += sizeExternalSymbolAddress(dword);
else if (MO1.isCPI())
FinalSize += sizeConstPoolAddress(dword);
else if (MO1.isJTI())
FinalSize += sizeJumpTableAddress(dword);
}
}
break;
case X86II::MRMDestReg: {
++FinalSize;
FinalSize += sizeRegModRMByte();
CurOp += 2;
Nicolas Geoffray
committed
if (CurOp != NumOps) {
++CurOp;
FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
Nicolas Geoffray
committed
}
break;
}
case X86II::MRMDestMem: {
++FinalSize;
FinalSize += getMemModRMByteSize(MI, CurOp, IsPIC, Is64BitMode);
CurOp += X86AddrNumOperands + 1;
Nicolas Geoffray
committed
if (CurOp != NumOps) {
++CurOp;
FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
Nicolas Geoffray
committed
}
break;
}
case X86II::MRMSrcReg:
++FinalSize;
FinalSize += sizeRegModRMByte();
CurOp += 2;
Nicolas Geoffray
committed
if (CurOp != NumOps) {
++CurOp;
FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
Nicolas Geoffray
committed
}
break;
case X86II::MRMSrcMem: {
int AddrOperands;
if (Opcode == X86::LEA64r || Opcode == X86::LEA64_32r ||
Opcode == X86::LEA16r || Opcode == X86::LEA32r)
AddrOperands = X86AddrNumOperands - 1; // No segment register
else
AddrOperands = X86AddrNumOperands;
++FinalSize;
FinalSize += getMemModRMByteSize(MI, CurOp+1, IsPIC, Is64BitMode);
CurOp += AddrOperands + 1;
Nicolas Geoffray
committed
if (CurOp != NumOps) {
++CurOp;
FinalSize += sizeConstant(X86InstrInfo::sizeOfImm(Desc));
Nicolas Geoffray
committed
}
break;
}
case X86II::MRM0r: case X86II::MRM1r:
case X86II::MRM2r: case X86II::MRM3r:
case X86II::MRM4r: case X86II::MRM5r:
case X86II::MRM6r: case X86II::MRM7r:
++FinalSize;
if (Desc->getOpcode() == X86::LFENCE ||
Desc->getOpcode() == X86::MFENCE) {
// Special handling of lfence and mfence;
FinalSize += sizeRegModRMByte();
} else if (Desc->getOpcode() == X86::MONITOR ||
Desc->getOpcode() == X86::MWAIT) {
// Special handling of monitor and mwait.
FinalSize += sizeRegModRMByte() + 1; // +1 for the opcode.
} else {
++CurOp;
FinalSize += sizeRegModRMByte();
}
if (CurOp != NumOps) {
const MachineOperand &MO1 = MI.getOperand(CurOp++);
unsigned Size = X86InstrInfo::sizeOfImm(Desc);
if (MO1.isImm())
FinalSize += sizeConstant(Size);
else {
bool dword = false;
if (Opcode == X86::MOV64ri32)
dword = true;
if (MO1.isGlobal()) {
FinalSize += sizeGlobalAddress(dword);
} else if (MO1.isSymbol())
FinalSize += sizeExternalSymbolAddress(dword);
else if (MO1.isCPI())
FinalSize += sizeConstPoolAddress(dword);
else if (MO1.isJTI())
FinalSize += sizeJumpTableAddress(dword);
}
}
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 += X86AddrNumOperands;
if (CurOp != NumOps) {
const MachineOperand &MO = MI.getOperand(CurOp++);
unsigned Size = X86InstrInfo::sizeOfImm(Desc);
if (MO.isImm())
FinalSize += sizeConstant(Size);
else {
bool dword = false;
if (Opcode == X86::MOV64mi32)
dword = true;
if (MO.isGlobal()) {
FinalSize += sizeGlobalAddress(dword);
} else if (MO.isSymbol())
FinalSize += sizeExternalSymbolAddress(dword);
else if (MO.isCPI())
FinalSize += sizeConstPoolAddress(dword);
else if (MO.isJTI())
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) {
std::string msg;
raw_string_ostream Msg(msg);
Msg << "Cannot determine size: " << MI;
llvm_report_error(Msg.str());
}
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();
DebugLoc DL = DebugLoc::getUnknownLoc();
if (MBBI != FirstMBB.end()) DL = MBBI->getDebugLoc();
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, DL, 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_OFFSET_TABLE_ external.
if (TM.getSubtarget<X86Subtarget>().isPICStyleGOT()) {
GlobalBaseReg = RegInfo.createVirtualRegister(X86::GR32RegisterClass);
// Generate addl $__GLOBAL_OFFSET_TABLE_ + [.-piclabel], %some_register
BuildMI(FirstMBB, MBBI, DL, TII->get(X86::ADD32ri), GlobalBaseReg)
Daniel Dunbar
committed
.addReg(PC).addExternalSymbol("_GLOBAL_OFFSET_TABLE_",
X86II::MO_GOT_ABSOLUTE_ADDRESS);
} else {
GlobalBaseReg = PC;
X86FI->setGlobalBaseReg(GlobalBaseReg);
return GlobalBaseReg;