mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[X86] Add a new format type for instructions that represent named prefix bytes like data16 and rep. Use it to make a simpler version of isPrefix.
isPrefix was added to support the patches to align branches. it relies on a switch over instruction names. This moves those opcodes to a new format so the information is tablegen and we can just check for a specific value in some bits in TSFlags instead. I've left the other function in place for now so that the existing patches in phabricator will still work. I'll work with the owner to get them migrated.
This commit is contained in:
parent
9dbb4c30c4
commit
604077c19d
@ -608,6 +608,10 @@ namespace X86II {
|
||||
/// in the lower 4 bits of the opcode.
|
||||
AddCCFrm = 9,
|
||||
|
||||
/// PrefixByte - This form is used for instructions that represent a prefix
|
||||
/// byte like data16 or rep.
|
||||
PrefixByte = 10,
|
||||
|
||||
/// MRM[0-7][rm] - These forms are used to represent instructions that use
|
||||
/// a Mod/RM byte, and use the middle field to hold extended opcode
|
||||
/// information. In the intel manual these are represented as /0, /1, ...
|
||||
@ -927,6 +931,11 @@ namespace X86II {
|
||||
NOTRACK = 1ULL << NoTrackShift
|
||||
};
|
||||
|
||||
/// \returns true if the instruction with given opcode is a prefix.
|
||||
inline bool isPrefix(uint64_t TSFlags) {
|
||||
return (TSFlags & X86II::FormMask) == PrefixByte;
|
||||
}
|
||||
|
||||
/// \returns the "base" X86 opcode for the specified machine
|
||||
/// instruction.
|
||||
inline uint8_t getBaseOpcodeFor(uint64_t TSFlags) {
|
||||
@ -1055,6 +1064,7 @@ namespace X86II {
|
||||
case X86II::RawFrmDst:
|
||||
case X86II::RawFrmDstSrc:
|
||||
case X86II::AddCCFrm:
|
||||
case X86II::PrefixByte:
|
||||
return -1;
|
||||
case X86II::MRMDestMem:
|
||||
return 0;
|
||||
|
@ -870,6 +870,7 @@ void X86MCCodeEmitter::emitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
|
||||
default:
|
||||
llvm_unreachable("Unexpected form in emitVEXOpcodePrefix!");
|
||||
case X86II::RawFrm:
|
||||
case X86II::PrefixByte:
|
||||
break;
|
||||
case X86II::MRMDestMem: {
|
||||
// MRMDestMem instructions forms:
|
||||
@ -1423,6 +1424,7 @@ void X86MCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
case X86II::RawFrmDstSrc:
|
||||
case X86II::RawFrmSrc:
|
||||
case X86II::RawFrmDst:
|
||||
case X86II::PrefixByte:
|
||||
emitByte(BaseOpcode, CurByte, OS);
|
||||
break;
|
||||
case X86II::AddCCFrm: {
|
||||
|
@ -27,6 +27,7 @@ def RawFrmDstSrc : Format<6>;
|
||||
def RawFrmImm8 : Format<7>;
|
||||
def RawFrmImm16 : Format<8>;
|
||||
def AddCCFrm : Format<9>;
|
||||
def PrefixByte : Format<10>;
|
||||
def MRMDestMem : Format<32>;
|
||||
def MRMSrcMem : Format<33>;
|
||||
def MRMSrcMem4VOp3 : Format<34>;
|
||||
|
@ -2169,24 +2169,24 @@ def CMPXCHG16B : RI<0xC7, MRM1m, (outs), (ins i128mem:$dst),
|
||||
|
||||
// Lock instruction prefix
|
||||
let SchedRW = [WriteMicrocoded] in
|
||||
def LOCK_PREFIX : I<0xF0, RawFrm, (outs), (ins), "lock", []>;
|
||||
def LOCK_PREFIX : I<0xF0, PrefixByte, (outs), (ins), "lock", []>;
|
||||
|
||||
let SchedRW = [WriteNop] in {
|
||||
|
||||
// Rex64 instruction prefix
|
||||
def REX64_PREFIX : I<0x48, RawFrm, (outs), (ins), "rex64", []>,
|
||||
def REX64_PREFIX : I<0x48, PrefixByte, (outs), (ins), "rex64", []>,
|
||||
Requires<[In64BitMode]>;
|
||||
|
||||
// Data16 instruction prefix
|
||||
def DATA16_PREFIX : I<0x66, RawFrm, (outs), (ins), "data16", []>;
|
||||
def DATA16_PREFIX : I<0x66, PrefixByte, (outs), (ins), "data16", []>;
|
||||
} // SchedRW
|
||||
|
||||
// Repeat string operation instruction prefixes
|
||||
let Defs = [ECX], Uses = [ECX,DF], SchedRW = [WriteMicrocoded] in {
|
||||
// Repeat (used with INS, OUTS, MOVS, LODS and STOS)
|
||||
def REP_PREFIX : I<0xF3, RawFrm, (outs), (ins), "rep", []>;
|
||||
def REP_PREFIX : I<0xF3, PrefixByte, (outs), (ins), "rep", []>;
|
||||
// Repeat while not equal (used with CMPS and SCAS)
|
||||
def REPNE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "repne", []>;
|
||||
def REPNE_PREFIX : I<0xF2, PrefixByte, (outs), (ins), "repne", []>;
|
||||
}
|
||||
|
||||
// String manipulation instructions
|
||||
|
@ -149,12 +149,12 @@ def MOV64cr : I<0x22, MRMSrcReg, (outs CONTROL_REG:$dst), (ins GR64:$src),
|
||||
// Segment override instruction prefixes
|
||||
|
||||
let SchedRW = [WriteNop] in {
|
||||
def CS_PREFIX : I<0x2E, RawFrm, (outs), (ins), "cs", []>;
|
||||
def SS_PREFIX : I<0x36, RawFrm, (outs), (ins), "ss", []>;
|
||||
def DS_PREFIX : I<0x3E, RawFrm, (outs), (ins), "ds", []>;
|
||||
def ES_PREFIX : I<0x26, RawFrm, (outs), (ins), "es", []>;
|
||||
def FS_PREFIX : I<0x64, RawFrm, (outs), (ins), "fs", []>;
|
||||
def GS_PREFIX : I<0x65, RawFrm, (outs), (ins), "gs", []>;
|
||||
def CS_PREFIX : I<0x2E, PrefixByte, (outs), (ins), "cs", []>;
|
||||
def SS_PREFIX : I<0x36, PrefixByte, (outs), (ins), "ss", []>;
|
||||
def DS_PREFIX : I<0x3E, PrefixByte, (outs), (ins), "ds", []>;
|
||||
def ES_PREFIX : I<0x26, PrefixByte, (outs), (ins), "es", []>;
|
||||
def FS_PREFIX : I<0x64, PrefixByte, (outs), (ins), "fs", []>;
|
||||
def GS_PREFIX : I<0x65, PrefixByte, (outs), (ins), "gs", []>;
|
||||
} // SchedRW
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -52,8 +52,8 @@ def XABORT : Ii8<0xc6, MRM_F8, (outs), (ins i8imm:$imm),
|
||||
let SchedRW = [WriteSystem] in {
|
||||
|
||||
let isAsmParserOnly = 1 in {
|
||||
def XACQUIRE_PREFIX : I<0xF2, RawFrm, (outs), (ins), "xacquire", []>;
|
||||
def XRELEASE_PREFIX : I<0xF3, RawFrm, (outs), (ins), "xrelease", []>;
|
||||
def XACQUIRE_PREFIX : I<0xF2, PrefixByte, (outs), (ins), "xacquire", []>;
|
||||
def XRELEASE_PREFIX : I<0xF3, PrefixByte, (outs), (ins), "xrelease", []>;
|
||||
}
|
||||
|
||||
} // SchedRW
|
||||
|
@ -33,6 +33,7 @@ static const char *isInvalidMemoryInstr(const Instruction &Instr) {
|
||||
case X86II::Pseudo:
|
||||
case X86II::RawFrm:
|
||||
case X86II::AddCCFrm:
|
||||
case X86II::PrefixByte:
|
||||
case X86II::MRMDestReg:
|
||||
case X86II::MRMSrcReg:
|
||||
case X86II::MRMSrcReg4VOp3:
|
||||
|
@ -459,6 +459,8 @@ void RecognizableInstr::emitInstructionSpecifier() {
|
||||
|
||||
switch (Form) {
|
||||
default: llvm_unreachable("Unhandled form");
|
||||
case X86Local::PrefixByte:
|
||||
return;
|
||||
case X86Local::RawFrmSrc:
|
||||
HANDLE_OPERAND(relocation);
|
||||
return;
|
||||
@ -749,6 +751,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
|
||||
case X86Local::RawFrmImm8:
|
||||
case X86Local::RawFrmImm16:
|
||||
case X86Local::AddCCFrm:
|
||||
case X86Local::PrefixByte:
|
||||
filter = std::make_unique<DumbFilter>();
|
||||
break;
|
||||
case X86Local::MRMDestReg:
|
||||
|
@ -102,6 +102,7 @@ namespace X86Local {
|
||||
RawFrmImm8 = 7,
|
||||
RawFrmImm16 = 8,
|
||||
AddCCFrm = 9,
|
||||
PrefixByte = 10,
|
||||
MRMDestMem = 32,
|
||||
MRMSrcMem = 33,
|
||||
MRMSrcMem4VOp3 = 34,
|
||||
|
Loading…
Reference in New Issue
Block a user