Newer
Older
}
}
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 {
assert(0 && "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())
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
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();
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_ADDRESS_TABLE_ external
if (TM.getRelocationModel() == Reloc::PIC_ &&
TM.getSubtarget<X86Subtarget>().isPICStyleGOT()) {
RegInfo.createVirtualRegister(X86::GR32RegisterClass);
BuildMI(FirstMBB, MBBI, DL, TII->get(X86::ADD32ri), GlobalBaseReg)
.addReg(PC).addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
} else {
GlobalBaseReg = PC;
X86FI->setGlobalBaseReg(GlobalBaseReg);
return GlobalBaseReg;