diff options
Diffstat (limited to 'llvm/utils/TableGen')
-rw-r--r-- | llvm/utils/TableGen/X86DisassemblerTables.cpp | 21 | ||||
-rw-r--r-- | llvm/utils/TableGen/X86FoldTablesEmitter.cpp | 18 | ||||
-rw-r--r-- | llvm/utils/TableGen/X86RecognizableInstr.cpp | 37 | ||||
-rw-r--r-- | llvm/utils/TableGen/X86RecognizableInstr.h | 4 |
4 files changed, 69 insertions, 11 deletions
diff --git a/llvm/utils/TableGen/X86DisassemblerTables.cpp b/llvm/utils/TableGen/X86DisassemblerTables.cpp index 06e7ec3..9ee1472 100644 --- a/llvm/utils/TableGen/X86DisassemblerTables.cpp +++ b/llvm/utils/TableGen/X86DisassemblerTables.cpp @@ -563,6 +563,13 @@ static inline bool inheritsFrom(InstructionContext child, case IC_EVEX_L2_W_XD_KZ_B: case IC_EVEX_L2_W_OPSIZE_KZ_B: return false; + case IC_EVEX_NF: + case IC_EVEX_B_NF: + case IC_EVEX_OPSIZE_NF: + case IC_EVEX_OPSIZE_B_NF: + case IC_EVEX_W_NF: + case IC_EVEX_W_B_NF: + return false; default: errs() << "Unknown instruction class: " << stringForContext((InstructionContext)parent) << "\n"; @@ -889,7 +896,19 @@ void DisassemblerTables::emitContextTable(raw_ostream &o, unsigned &i) const { if ((index & ATTR_EVEX) && (index & ATTR_OPSIZE) && (index & ATTR_ADSIZE)) o << "IC_EVEX_OPSIZE_ADSIZE"; - else if ((index & ATTR_EVEX) || (index & ATTR_VEX) || (index & ATTR_VEXL)) { + else if (index & ATTR_EVEXNF) { + o << "IC_EVEX"; + if (index & ATTR_REXW) + o << "_W"; + else if (index & ATTR_OPSIZE) + o << "_OPSIZE"; + + if (index & ATTR_EVEXB) + o << "_B"; + + o << "_NF"; + } else if ((index & ATTR_EVEX) || (index & ATTR_VEX) || + (index & ATTR_VEXL)) { if (index & ATTR_EVEX) o << "IC_EVEX"; else diff --git a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp index d3299e2..101b75e 100644 --- a/llvm/utils/TableGen/X86FoldTablesEmitter.cpp +++ b/llvm/utils/TableGen/X86FoldTablesEmitter.cpp @@ -348,7 +348,9 @@ public: // memory form: broadcast if (IsBroadcast && (RegRI.HasEVEX_B || !MemRI.HasEVEX_B)) return false; - if (!IsBroadcast && (RegRI.HasEVEX_B || MemRI.HasEVEX_B)) + // EVEX_B indicates NDD for MAP4 instructions + if (!IsBroadcast && (RegRI.HasEVEX_B || MemRI.HasEVEX_B) && + RegRI.OpMap != X86Local::T_MAP4) return false; if (!mayFoldFromLeftToRight(RegRI.Form, MemRI.Form)) @@ -369,7 +371,8 @@ public: RegRI.OpMap, RegRI.OpSize, RegRI.AdSize, RegRI.HasREX_W, RegRI.HasVEX_4V, RegRI.HasVEX_L, RegRI.IgnoresVEX_L, RegRI.IgnoresW, RegRI.HasEVEX_K, RegRI.HasEVEX_KZ, - RegRI.HasEVEX_L2, RegRec->getValueAsBit("hasEVEX_RC"), + RegRI.HasEVEX_L2, RegRI.HasEVEX_NF, + RegRec->getValueAsBit("hasEVEX_RC"), RegRec->getValueAsBit("hasLockPrefix"), RegRec->getValueAsBit("hasNoTrackPrefix"), RegRec->getValueAsBit("EVEX_W1_VEX_W0")) != @@ -377,7 +380,8 @@ public: MemRI.OpMap, MemRI.OpSize, MemRI.AdSize, MemRI.HasREX_W, MemRI.HasVEX_4V, MemRI.HasVEX_L, MemRI.IgnoresVEX_L, MemRI.IgnoresW, MemRI.HasEVEX_K, MemRI.HasEVEX_KZ, - MemRI.HasEVEX_L2, MemRec->getValueAsBit("hasEVEX_RC"), + MemRI.HasEVEX_L2, MemRI.HasEVEX_NF, + MemRec->getValueAsBit("hasEVEX_RC"), MemRec->getValueAsBit("hasLockPrefix"), MemRec->getValueAsBit("hasNoTrackPrefix"), MemRec->getValueAsBit("EVEX_W1_VEX_W0"))) @@ -668,6 +672,14 @@ void X86FoldTablesEmitter::run(raw_ostream &O) { if (NoFoldSet.find(Rec->getName()) != NoFoldSet.end()) continue; + // Promoted legacy instruction is in EVEX space, and has REX2-encoding + // alternative. It's added due to HW design and never emitted by compiler. + if (byteFromBitsInit(Rec->getValueAsBitsInit("OpMapBits")) == + X86Local::T_MAP4 && + byteFromBitsInit(Rec->getValueAsBitsInit("explicitOpPrefixBits")) == + X86Local::ExplicitEVEX) + continue; + // - Instructions including RST register class operands are not relevant // for memory folding (for further details check the explanation in // lib/Target/X86/X86InstrFPStack.td file). diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp index 47ee954..fb43067 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -125,6 +125,7 @@ RecognizableInstrBase::RecognizableInstrBase(const CodeGenInstruction &insn) { HasEVEX_K = Rec->getValueAsBit("hasEVEX_K"); HasEVEX_KZ = Rec->getValueAsBit("hasEVEX_Z"); HasEVEX_B = Rec->getValueAsBit("hasEVEX_B"); + HasEVEX_NF = Rec->getValueAsBit("hasEVEX_NF"); IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); IsAsmParserOnly = Rec->getValueAsBit("isAsmParserOnly"); ForceDisassemble = Rec->getValueAsBit("ForceDisassemble"); @@ -185,6 +186,9 @@ void RecognizableInstr::processInstr(DisassemblerTables &tables, : (HasEVEX_KZ ? n##_KZ \ : (HasEVEX_K ? n##_K : (HasEVEX_B ? n##_B : n))))) +#define EVEX_NF(n) (HasEVEX_NF ? n##_NF : n) +#define EVEX_B_NF(n) (HasEVEX_B ? EVEX_NF(n##_B) : EVEX_NF(n)) + InstructionContext RecognizableInstr::insnContext() const { InstructionContext insnContext; @@ -193,8 +197,15 @@ InstructionContext RecognizableInstr::insnContext() const { errs() << "Don't support VEX.L if EVEX_L2 is enabled: " << Name << "\n"; llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled"); } - // VEX_L & VEX_W - if (!EncodeRC && HasVEX_L && HasREX_W) { + if (HasEVEX_NF) { + if (OpPrefix == X86Local::PD) + insnContext = EVEX_B_NF(IC_EVEX_OPSIZE); + else if (HasREX_W) + insnContext = EVEX_B_NF(IC_EVEX_W); + else + insnContext = EVEX_B_NF(IC_EVEX); + } else if (!EncodeRC && HasVEX_L && HasREX_W) { + // VEX_L & VEX_W if (OpPrefix == X86Local::PD) insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE); else if (OpPrefix == X86Local::XS) @@ -486,6 +497,7 @@ void RecognizableInstr::emitInstructionSpecifier() { ++additionalOperands; #endif + bool IsND = OpMap == X86Local::T_MAP4 && HasEVEX_B && HasVEX_4V; switch (Form) { default: llvm_unreachable("Unhandled form"); @@ -536,11 +548,14 @@ void RecognizableInstr::emitInstructionSpecifier() { numPhysicalOperands <= 3 + additionalOperands && "Unexpected number of operands for MRMDestReg"); + if (IsND) + HANDLE_OPERAND(vvvvRegister) + HANDLE_OPERAND(rmRegister) if (HasEVEX_K) HANDLE_OPERAND(writemaskRegister) - if (HasVEX_4V) + if (!IsND && HasVEX_4V) // FIXME: In AVX, the register below becomes the one encoded // in ModRMVEX and the one above the one in the VEX.VVVV field HANDLE_OPERAND(vvvvRegister) @@ -570,12 +585,15 @@ void RecognizableInstr::emitInstructionSpecifier() { numPhysicalOperands <= 3 + additionalOperands && "Unexpected number of operands for MRMDestMemFrm with VEX_4V"); + if (IsND) + HANDLE_OPERAND(vvvvRegister) + HANDLE_OPERAND(memory) if (HasEVEX_K) HANDLE_OPERAND(writemaskRegister) - if (HasVEX_4V) + if (!IsND && HasVEX_4V) // FIXME: In AVX, the register below becomes the one encoded // in ModRMVEX and the one above the one in the VEX.VVVV field HANDLE_OPERAND(vvvvRegister) @@ -594,12 +612,15 @@ void RecognizableInstr::emitInstructionSpecifier() { numPhysicalOperands <= 4 + additionalOperands && "Unexpected number of operands for MRMSrcRegFrm"); + if (IsND) + HANDLE_OPERAND(vvvvRegister) + HANDLE_OPERAND(roRegister) if (HasEVEX_K) HANDLE_OPERAND(writemaskRegister) - if (HasVEX_4V) + if (!IsND && HasVEX_4V) // FIXME: In AVX, the register below becomes the one encoded // in ModRMVEX and the one above the one in the VEX.VVVV field HANDLE_OPERAND(vvvvRegister) @@ -641,13 +662,15 @@ void RecognizableInstr::emitInstructionSpecifier() { assert(numPhysicalOperands >= 2 + additionalOperands && numPhysicalOperands <= 4 + additionalOperands && "Unexpected number of operands for MRMSrcMemFrm"); + if (IsND) + HANDLE_OPERAND(vvvvRegister) HANDLE_OPERAND(roRegister) if (HasEVEX_K) HANDLE_OPERAND(writemaskRegister) - if (HasVEX_4V) + if (!IsND && HasVEX_4V) // FIXME: In AVX, the register below becomes the one encoded // in ModRMVEX and the one above the one in the VEX.VVVV field HANDLE_OPERAND(vvvvRegister) @@ -1216,6 +1239,8 @@ RecognizableInstr::roRegisterEncodingFromString(const std::string &s, OperandEncoding RecognizableInstr::vvvvRegisterEncodingFromString(const std::string &s, uint8_t OpSize) { + ENCODING("GR8", ENCODING_VVVV) + ENCODING("GR16", ENCODING_VVVV) ENCODING("GR32", ENCODING_VVVV) ENCODING("GR64", ENCODING_VVVV) ENCODING("FR32", ENCODING_VVVV) diff --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h index 61ad5e3..007c700 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.h +++ b/llvm/utils/TableGen/X86RecognizableInstr.h @@ -172,7 +172,7 @@ enum { PD = 1, XS = 2, XD = 3, PS = 4 }; enum { VEX = 1, XOP = 2, EVEX = 3 }; enum { OpSize16 = 1, OpSize32 = 2 }; enum { AdSize16 = 1, AdSize32 = 2, AdSize64 = 3 }; -enum { ExplicitREX2 = 1 }; +enum { ExplicitREX2 = 1, ExplicitEVEX = 3 }; } // namespace X86Local namespace X86Disassembler { @@ -212,6 +212,8 @@ struct RecognizableInstrBase { bool HasEVEX_KZ; /// The hasEVEX_B field from the record bool HasEVEX_B; + /// The hasEVEX_NF field from the record + bool HasEVEX_NF; /// Indicates that the instruction uses the L and L' fields for RC. bool EncodeRC; /// The isCodeGenOnly field from the record |