forked from OSchip/llvm-project
[X86] Add a private member function determinePaddingPrefix for X86AsmBackend
Summary: X86 can reduce the bytes of NOP by padding instructions with prefixes to get a better peformance in some cases. So a private member function `determinePaddingPrefix` is added to determine which prefix is the most suitable. Reviewers: annita.zhang, reames, MaskRay, craig.topper, LuoYuanke, jyknight Reviewed By: reames Subscribers: llvm-commits, dexonsmith, hiraditya Tags: #llvm Differential Revision: https://reviews.llvm.org/D75357
This commit is contained in:
parent
755c050200
commit
b3722dea3b
|
@ -126,6 +126,8 @@ class X86AsmBackend : public MCAsmBackend {
|
|||
X86AlignBranchKind AlignBranchType;
|
||||
Align AlignBoundary;
|
||||
|
||||
uint8_t determinePaddingPrefix(const MCInst &Inst) const;
|
||||
|
||||
bool isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const;
|
||||
|
||||
bool needAlign(MCObjectStreamer &OS) const;
|
||||
|
@ -340,6 +342,83 @@ static bool isFirstMacroFusibleInst(const MCInst &Inst,
|
|||
return FIK != X86::FirstMacroFusionInstKind::Invalid;
|
||||
}
|
||||
|
||||
/// X86 can reduce the bytes of NOP by padding instructions with prefixes to
|
||||
/// get a better peformance in some cases. Here, we determine which prefix is
|
||||
/// the most suitable.
|
||||
///
|
||||
/// If the instruction has a segment override prefix, use the existing one.
|
||||
/// If the target is 64-bit, use the CS.
|
||||
/// If the target is 32-bit,
|
||||
/// - If the instruction has a ESP/EBP base register, use SS.
|
||||
/// - Otherwise use DS.
|
||||
uint8_t X86AsmBackend::determinePaddingPrefix(const MCInst &Inst) const {
|
||||
assert((STI.hasFeature(X86::Mode32Bit) || STI.hasFeature(X86::Mode64Bit)) &&
|
||||
"Prefixes can be added only in 32-bit or 64-bit mode.");
|
||||
const MCInstrDesc &Desc = MCII->get(Inst.getOpcode());
|
||||
uint64_t TSFlags = Desc.TSFlags;
|
||||
|
||||
// Determine where the memory operand starts, if present.
|
||||
int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
|
||||
if (MemoryOperand != -1)
|
||||
MemoryOperand += X86II::getOperandBias(Desc);
|
||||
|
||||
unsigned SegmentReg = 0;
|
||||
if (MemoryOperand >= 0) {
|
||||
// Check for explicit segment override on memory operand.
|
||||
SegmentReg = Inst.getOperand(MemoryOperand + X86::AddrSegmentReg).getReg();
|
||||
}
|
||||
|
||||
switch (TSFlags & X86II::FormMask) {
|
||||
default:
|
||||
break;
|
||||
case X86II::RawFrmDstSrc: {
|
||||
// Check segment override opcode prefix as needed (not for %ds).
|
||||
if (Inst.getOperand(2).getReg() != X86::DS)
|
||||
SegmentReg = Inst.getOperand(2).getReg();
|
||||
break;
|
||||
}
|
||||
case X86II::RawFrmSrc: {
|
||||
// Check segment override opcode prefix as needed (not for %ds).
|
||||
if (Inst.getOperand(1).getReg() != X86::DS)
|
||||
SegmentReg = Inst.getOperand(1).getReg();
|
||||
break;
|
||||
}
|
||||
case X86II::RawFrmMemOffs: {
|
||||
// Check segment override opcode prefix as needed.
|
||||
SegmentReg = Inst.getOperand(1).getReg();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (SegmentReg) {
|
||||
case 0:
|
||||
break;
|
||||
case X86::CS:
|
||||
return X86::CS_Encoding;
|
||||
case X86::DS:
|
||||
return X86::DS_Encoding;
|
||||
case X86::ES:
|
||||
return X86::ES_Encoding;
|
||||
case X86::FS:
|
||||
return X86::FS_Encoding;
|
||||
case X86::GS:
|
||||
return X86::GS_Encoding;
|
||||
case X86::SS:
|
||||
return X86::SS_Encoding;
|
||||
}
|
||||
|
||||
if (STI.hasFeature(X86::Mode64Bit))
|
||||
return X86::CS_Encoding;
|
||||
|
||||
if (MemoryOperand >= 0) {
|
||||
unsigned BaseRegNum = MemoryOperand + X86::AddrBaseReg;
|
||||
unsigned BaseReg = Inst.getOperand(BaseRegNum).getReg();
|
||||
if (BaseReg == X86::ESP || BaseReg == X86::EBP)
|
||||
return X86::SS_Encoding;
|
||||
}
|
||||
return X86::DS_Encoding;
|
||||
}
|
||||
|
||||
/// Check if the two instructions will be macro-fused on the target cpu.
|
||||
bool X86AsmBackend::isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const {
|
||||
const MCInstrDesc &InstDesc = MCII->get(Jcc.getOpcode());
|
||||
|
|
|
@ -383,6 +383,16 @@ namespace X86 {
|
|||
AlignBranchRet = 1U << 4,
|
||||
AlignBranchIndirect = 1U << 5
|
||||
};
|
||||
|
||||
/// Defines the encoding values for segment override prefix.
|
||||
enum EncodingOfSegmentOverridePrefix : uint8_t {
|
||||
CS_Encoding = 0x2E,
|
||||
DS_Encoding = 0x3E,
|
||||
ES_Encoding = 0x26,
|
||||
FS_Encoding = 0x64,
|
||||
GS_Encoding = 0x65,
|
||||
SS_Encoding = 0x36
|
||||
};
|
||||
} // end namespace X86;
|
||||
|
||||
/// X86II - This namespace holds all of the target specific flags that
|
||||
|
|
Loading…
Reference in New Issue