forked from OSchip/llvm-project
[X86] Split the VEX_WPrefix in X86Inst tablegen class into 3 separate fields with clear meanings.
llvm-svn: 357970
This commit is contained in:
parent
6e9157d588
commit
2f9c1732b8
|
@ -210,13 +210,10 @@ class TAPS : TA { Prefix OpPrefix = PS; }
|
||||||
class TAPD : TA { Prefix OpPrefix = PD; }
|
class TAPD : TA { Prefix OpPrefix = PD; }
|
||||||
class TAXD : TA { Prefix OpPrefix = XD; }
|
class TAXD : TA { Prefix OpPrefix = XD; }
|
||||||
class VEX { Encoding OpEnc = EncVEX; }
|
class VEX { Encoding OpEnc = EncVEX; }
|
||||||
class VEX_W { bits<2> VEX_WPrefix = 1; }
|
class VEX_W { bit HasVEX_W = 1; }
|
||||||
class VEX_WIG { bits<2> VEX_WPrefix = 2; }
|
class VEX_WIG { bit IgnoresVEX_W = 1; }
|
||||||
// Special version of VEX_W that can be changed to VEX.W==0 for EVEX2VEX.
|
// Special version of VEX_W that can be changed to VEX.W==0 for EVEX2VEX.
|
||||||
// FIXME: We should consider adding separate bits for VEX_WIG and the extra
|
class VEX_W1X { bit HasVEX_W = 1; bit EVEX_W1_VEX_W0 = 1; }
|
||||||
// part of W1X. This would probably simplify the tablegen emitters and
|
|
||||||
// the TSFlags creation below.
|
|
||||||
class VEX_W1X { bits<2> VEX_WPrefix = 3; }
|
|
||||||
class VEX_4V : VEX { bit hasVEX_4V = 1; }
|
class VEX_4V : VEX { bit hasVEX_4V = 1; }
|
||||||
class VEX_L { bit hasVEX_L = 1; }
|
class VEX_L { bit hasVEX_L = 1; }
|
||||||
class VEX_LIG { bit ignoresVEX_L = 1; }
|
class VEX_LIG { bit ignoresVEX_L = 1; }
|
||||||
|
@ -300,7 +297,10 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
|
||||||
bit hasREPPrefix = 0; // Does this inst have a REP prefix?
|
bit hasREPPrefix = 0; // Does this inst have a REP prefix?
|
||||||
Encoding OpEnc = EncNormal; // Encoding used by this instruction
|
Encoding OpEnc = EncNormal; // Encoding used by this instruction
|
||||||
bits<2> OpEncBits = OpEnc.Value;
|
bits<2> OpEncBits = OpEnc.Value;
|
||||||
bits<2> VEX_WPrefix = 0; // Does this inst set the VEX_W field?
|
bit HasVEX_W = 0; // Does this inst set the VEX_W field?
|
||||||
|
bit IgnoresVEX_W = 0; // Does this inst ignore VEX_W field?
|
||||||
|
bit EVEX_W1_VEX_W0 = 0; // This EVEX inst with VEX.W==1 can become a VEX
|
||||||
|
// instruction with VEX.W == 0.
|
||||||
bit hasVEX_4V = 0; // Does this inst require the VEX.VVVV field?
|
bit hasVEX_4V = 0; // Does this inst require the VEX.VVVV field?
|
||||||
bit hasVEX_L = 0; // Does this inst use large (256-bit) registers?
|
bit hasVEX_L = 0; // Does this inst use large (256-bit) registers?
|
||||||
bit ignoresVEX_L = 0; // Does this instruction ignore the L-bit
|
bit ignoresVEX_L = 0; // Does this instruction ignore the L-bit
|
||||||
|
@ -359,7 +359,7 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins,
|
||||||
let TSFlags{29-28} = OpEncBits;
|
let TSFlags{29-28} = OpEncBits;
|
||||||
let TSFlags{37-30} = Opcode;
|
let TSFlags{37-30} = Opcode;
|
||||||
// Currently no need for second bit in TSFlags - W Ignore is equivalent to 0.
|
// Currently no need for second bit in TSFlags - W Ignore is equivalent to 0.
|
||||||
let TSFlags{38} = VEX_WPrefix{0};
|
let TSFlags{38} = HasVEX_W;
|
||||||
let TSFlags{39} = hasVEX_4V;
|
let TSFlags{39} = hasVEX_4V;
|
||||||
let TSFlags{40} = hasVEX_L;
|
let TSFlags{40} = hasVEX_L;
|
||||||
let TSFlags{41} = hasEVEX_K;
|
let TSFlags{41} = hasEVEX_K;
|
||||||
|
|
|
@ -108,10 +108,11 @@ public:
|
||||||
bool operator()(const CodeGenInstruction *VEXInst) {
|
bool operator()(const CodeGenInstruction *VEXInst) {
|
||||||
Record *RecE = EVEXInst->TheDef;
|
Record *RecE = EVEXInst->TheDef;
|
||||||
Record *RecV = VEXInst->TheDef;
|
Record *RecV = VEXInst->TheDef;
|
||||||
uint64_t EVEX_W =
|
bool EVEX_W = RecE->getValueAsBit("HasVEX_W");
|
||||||
getValueFromBitsInit(RecE->getValueAsBitsInit("VEX_WPrefix"));
|
bool VEX_W = RecV->getValueAsBit("HasVEX_W");
|
||||||
uint64_t VEX_W =
|
bool VEX_WIG = RecV->getValueAsBit("IgnoresVEX_W");
|
||||||
getValueFromBitsInit(RecV->getValueAsBitsInit("VEX_WPrefix"));
|
bool EVEX_WIG = RecE->getValueAsBit("IgnoresVEX_W");
|
||||||
|
bool EVEX_W1_VEX_W0 = RecE->getValueAsBit("EVEX_W1_VEX_W0");
|
||||||
|
|
||||||
if (RecV->getValueAsDef("OpEnc")->getName().str() != "EncVEX" ||
|
if (RecV->getValueAsDef("OpEnc")->getName().str() != "EncVEX" ||
|
||||||
// VEX/EVEX fields
|
// VEX/EVEX fields
|
||||||
|
@ -122,8 +123,8 @@ public:
|
||||||
RecE->getValueAsBitsInit("EVEX_LL")) ||
|
RecE->getValueAsBitsInit("EVEX_LL")) ||
|
||||||
// Match is allowed if either is VEX_WIG, or they match, or EVEX
|
// Match is allowed if either is VEX_WIG, or they match, or EVEX
|
||||||
// is VEX_W1X and VEX is VEX_W0.
|
// is VEX_W1X and VEX is VEX_W0.
|
||||||
(!(EVEX_W == 2 || VEX_W == 2 || EVEX_W == VEX_W ||
|
(!(VEX_WIG || EVEX_WIG || EVEX_W == VEX_W ||
|
||||||
(EVEX_W == 3 && VEX_W == 0))) ||
|
(EVEX_W1_VEX_W0 && EVEX_W && !VEX_W))) ||
|
||||||
// Instruction's format
|
// Instruction's format
|
||||||
RecV->getValueAsDef("Form") != RecE->getValueAsDef("Form") ||
|
RecV->getValueAsDef("Form") != RecE->getValueAsDef("Form") ||
|
||||||
RecV->getValueAsBit("isAsmParserOnly") !=
|
RecV->getValueAsBit("isAsmParserOnly") !=
|
||||||
|
|
|
@ -83,7 +83,8 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
|
||||||
AdSize = byteFromRec(Rec, "AdSizeBits");
|
AdSize = byteFromRec(Rec, "AdSizeBits");
|
||||||
HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix");
|
HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix");
|
||||||
HasVEX_4V = Rec->getValueAsBit("hasVEX_4V");
|
HasVEX_4V = Rec->getValueAsBit("hasVEX_4V");
|
||||||
VEX_WPrefix = byteFromRec(Rec,"VEX_WPrefix");
|
HasVEX_W = Rec->getValueAsBit("HasVEX_W");
|
||||||
|
IgnoresVEX_W = Rec->getValueAsBit("IgnoresVEX_W");
|
||||||
IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L");
|
IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L");
|
||||||
HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2");
|
HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2");
|
||||||
HasEVEX_K = Rec->getValueAsBit("hasEVEX_K");
|
HasEVEX_K = Rec->getValueAsBit("hasEVEX_K");
|
||||||
|
@ -163,8 +164,7 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||||
llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled");
|
llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled");
|
||||||
}
|
}
|
||||||
// VEX_L & VEX_W
|
// VEX_L & VEX_W
|
||||||
if (!EncodeRC && HasVEX_LPrefix && (VEX_WPrefix == X86Local::VEX_W1 ||
|
if (!EncodeRC && HasVEX_LPrefix && HasVEX_W) {
|
||||||
VEX_WPrefix == X86Local::VEX_W1X)) {
|
|
||||||
if (OpPrefix == X86Local::PD)
|
if (OpPrefix == X86Local::PD)
|
||||||
insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE);
|
insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE);
|
||||||
else if (OpPrefix == X86Local::XS)
|
else if (OpPrefix == X86Local::XS)
|
||||||
|
@ -191,9 +191,7 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||||
errs() << "Instruction does not use a prefix: " << Name << "\n";
|
errs() << "Instruction does not use a prefix: " << Name << "\n";
|
||||||
llvm_unreachable("Invalid prefix");
|
llvm_unreachable("Invalid prefix");
|
||||||
}
|
}
|
||||||
} else if (!EncodeRC && HasEVEX_L2Prefix &&
|
} else if (!EncodeRC && HasEVEX_L2Prefix && HasVEX_W) {
|
||||||
(VEX_WPrefix == X86Local::VEX_W1 ||
|
|
||||||
VEX_WPrefix == X86Local::VEX_W1X)) {
|
|
||||||
// EVEX_L2 & VEX_W
|
// EVEX_L2 & VEX_W
|
||||||
if (OpPrefix == X86Local::PD)
|
if (OpPrefix == X86Local::PD)
|
||||||
insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE);
|
insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE);
|
||||||
|
@ -222,8 +220,7 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||||
llvm_unreachable("Invalid prefix");
|
llvm_unreachable("Invalid prefix");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (VEX_WPrefix == X86Local::VEX_W1 ||
|
else if (HasVEX_W) {
|
||||||
VEX_WPrefix == X86Local::VEX_W1X) {
|
|
||||||
// VEX_W
|
// VEX_W
|
||||||
if (OpPrefix == X86Local::PD)
|
if (OpPrefix == X86Local::PD)
|
||||||
insnContext = EVEX_KB(IC_EVEX_W_OPSIZE);
|
insnContext = EVEX_KB(IC_EVEX_W_OPSIZE);
|
||||||
|
@ -253,8 +250,7 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||||
}
|
}
|
||||||
/// eof EVEX
|
/// eof EVEX
|
||||||
} else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) {
|
} else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) {
|
||||||
if (HasVEX_LPrefix && (VEX_WPrefix == X86Local::VEX_W1 ||
|
if (HasVEX_LPrefix && HasVEX_W) {
|
||||||
VEX_WPrefix == X86Local::VEX_W1X)) {
|
|
||||||
if (OpPrefix == X86Local::PD)
|
if (OpPrefix == X86Local::PD)
|
||||||
insnContext = IC_VEX_L_W_OPSIZE;
|
insnContext = IC_VEX_L_W_OPSIZE;
|
||||||
else if (OpPrefix == X86Local::XS)
|
else if (OpPrefix == X86Local::XS)
|
||||||
|
@ -269,8 +265,7 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||||
}
|
}
|
||||||
} else if (OpPrefix == X86Local::PD && HasVEX_LPrefix)
|
} else if (OpPrefix == X86Local::PD && HasVEX_LPrefix)
|
||||||
insnContext = IC_VEX_L_OPSIZE;
|
insnContext = IC_VEX_L_OPSIZE;
|
||||||
else if (OpPrefix == X86Local::PD && (VEX_WPrefix == X86Local::VEX_W1 ||
|
else if (OpPrefix == X86Local::PD && HasVEX_W)
|
||||||
VEX_WPrefix == X86Local::VEX_W1X))
|
|
||||||
insnContext = IC_VEX_W_OPSIZE;
|
insnContext = IC_VEX_W_OPSIZE;
|
||||||
else if (OpPrefix == X86Local::PD)
|
else if (OpPrefix == X86Local::PD)
|
||||||
insnContext = IC_VEX_OPSIZE;
|
insnContext = IC_VEX_OPSIZE;
|
||||||
|
@ -278,14 +273,11 @@ InstructionContext RecognizableInstr::insnContext() const {
|
||||||
insnContext = IC_VEX_L_XS;
|
insnContext = IC_VEX_L_XS;
|
||||||
else if (HasVEX_LPrefix && OpPrefix == X86Local::XD)
|
else if (HasVEX_LPrefix && OpPrefix == X86Local::XD)
|
||||||
insnContext = IC_VEX_L_XD;
|
insnContext = IC_VEX_L_XD;
|
||||||
else if ((VEX_WPrefix == X86Local::VEX_W1 ||
|
else if (HasVEX_W && OpPrefix == X86Local::XS)
|
||||||
VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::XS)
|
|
||||||
insnContext = IC_VEX_W_XS;
|
insnContext = IC_VEX_W_XS;
|
||||||
else if ((VEX_WPrefix == X86Local::VEX_W1 ||
|
else if (HasVEX_W && OpPrefix == X86Local::XD)
|
||||||
VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::XD)
|
|
||||||
insnContext = IC_VEX_W_XD;
|
insnContext = IC_VEX_W_XD;
|
||||||
else if ((VEX_WPrefix == X86Local::VEX_W1 ||
|
else if (HasVEX_W && OpPrefix == X86Local::PS)
|
||||||
VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::PS)
|
|
||||||
insnContext = IC_VEX_W;
|
insnContext = IC_VEX_W;
|
||||||
else if (HasVEX_LPrefix && OpPrefix == X86Local::PS)
|
else if (HasVEX_LPrefix && OpPrefix == X86Local::PS)
|
||||||
insnContext = IC_VEX_L;
|
insnContext = IC_VEX_L;
|
||||||
|
@ -819,11 +811,11 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
|
||||||
tables.setTableFields(*opcodeType, insnContext(), currentOpcode, *filter,
|
tables.setTableFields(*opcodeType, insnContext(), currentOpcode, *filter,
|
||||||
UID, Is32Bit, OpPrefix == 0,
|
UID, Is32Bit, OpPrefix == 0,
|
||||||
IgnoresVEX_L || EncodeRC,
|
IgnoresVEX_L || EncodeRC,
|
||||||
VEX_WPrefix == X86Local::VEX_WIG, AddressSize);
|
IgnoresVEX_W, AddressSize);
|
||||||
} else {
|
} else {
|
||||||
tables.setTableFields(*opcodeType, insnContext(), opcodeToSet, *filter, UID,
|
tables.setTableFields(*opcodeType, insnContext(), opcodeToSet, *filter, UID,
|
||||||
Is32Bit, OpPrefix == 0, IgnoresVEX_L || EncodeRC,
|
Is32Bit, OpPrefix == 0, IgnoresVEX_L || EncodeRC,
|
||||||
VEX_WPrefix == X86Local::VEX_WIG, AddressSize);
|
IgnoresVEX_W, AddressSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef MAP
|
#undef MAP
|
||||||
|
|
|
@ -142,10 +142,6 @@ namespace X86Local {
|
||||||
enum {
|
enum {
|
||||||
AdSize16 = 1, AdSize32 = 2, AdSize64 = 3
|
AdSize16 = 1, AdSize32 = 2, AdSize64 = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
VEX_W0 = 0, VEX_W1 = 1, VEX_WIG = 2, VEX_W1X = 3
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace X86Disassembler {
|
namespace X86Disassembler {
|
||||||
|
@ -179,8 +175,10 @@ private:
|
||||||
bool HasREX_WPrefix;
|
bool HasREX_WPrefix;
|
||||||
/// The hasVEX_4V field from the record
|
/// The hasVEX_4V field from the record
|
||||||
bool HasVEX_4V;
|
bool HasVEX_4V;
|
||||||
/// The VEX_WPrefix field from the record
|
/// The HasVEX_WPrefix field from the record
|
||||||
uint8_t VEX_WPrefix;
|
bool HasVEX_W;
|
||||||
|
/// The IgnoresVEX_W field from the record
|
||||||
|
bool IgnoresVEX_W;
|
||||||
/// Inferred from the operands; indicates whether the L bit in the VEX prefix is set
|
/// Inferred from the operands; indicates whether the L bit in the VEX prefix is set
|
||||||
bool HasVEX_LPrefix;
|
bool HasVEX_LPrefix;
|
||||||
/// The ignoreVEX_L field from the record
|
/// The ignoreVEX_L field from the record
|
||||||
|
|
Loading…
Reference in New Issue