aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen/X86RecognizableInstr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/X86RecognizableInstr.cpp')
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp128
1 files changed, 90 insertions, 38 deletions
diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp
index 2f9b428b8cfe..ab8a8855c478 100644
--- a/utils/TableGen/X86RecognizableInstr.cpp
+++ b/utils/TableGen/X86RecognizableInstr.cpp
@@ -1,9 +1,8 @@
//===- X86RecognizableInstr.cpp - Disassembler instruction spec --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -84,7 +83,8 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
AdSize = byteFromRec(Rec, "AdSizeBits");
HasREX_WPrefix = Rec->getValueAsBit("hasREX_WPrefix");
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");
HasEVEX_L2Prefix = Rec->getValueAsBit("hasEVEX_L2");
HasEVEX_K = Rec->getValueAsBit("hasEVEX_K");
@@ -110,7 +110,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables,
std::vector<Record*> Predicates = Rec->getValueAsListOfDefs("Predicates");
for (unsigned i = 0, e = Predicates.size(); i != e; ++i) {
if (Predicates[i]->getName().find("Not64Bit") != Name.npos ||
- Predicates[i]->getName().find("In32Bit") != Name.npos) {
+ Predicates[i]->getName().find("In32Bit") != Name.npos) {
Is32Bit = true;
break;
}
@@ -164,8 +164,7 @@ InstructionContext RecognizableInstr::insnContext() const {
llvm_unreachable("Don't support VEX.L if EVEX_L2 is enabled");
}
// VEX_L & VEX_W
- if (!EncodeRC && HasVEX_LPrefix && (VEX_WPrefix == X86Local::VEX_W1 ||
- VEX_WPrefix == X86Local::VEX_W1X)) {
+ if (!EncodeRC && HasVEX_LPrefix && HasVEX_W) {
if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_L_W_OPSIZE);
else if (OpPrefix == X86Local::XS)
@@ -192,9 +191,7 @@ InstructionContext RecognizableInstr::insnContext() const {
errs() << "Instruction does not use a prefix: " << Name << "\n";
llvm_unreachable("Invalid prefix");
}
- } else if (!EncodeRC && HasEVEX_L2Prefix &&
- (VEX_WPrefix == X86Local::VEX_W1 ||
- VEX_WPrefix == X86Local::VEX_W1X)) {
+ } else if (!EncodeRC && HasEVEX_L2Prefix && HasVEX_W) {
// EVEX_L2 & VEX_W
if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_L2_W_OPSIZE);
@@ -223,8 +220,7 @@ InstructionContext RecognizableInstr::insnContext() const {
llvm_unreachable("Invalid prefix");
}
}
- else if (VEX_WPrefix == X86Local::VEX_W1 ||
- VEX_WPrefix == X86Local::VEX_W1X) {
+ else if (HasVEX_W) {
// VEX_W
if (OpPrefix == X86Local::PD)
insnContext = EVEX_KB(IC_EVEX_W_OPSIZE);
@@ -254,8 +250,7 @@ InstructionContext RecognizableInstr::insnContext() const {
}
/// eof EVEX
} else if (Encoding == X86Local::VEX || Encoding == X86Local::XOP) {
- if (HasVEX_LPrefix && (VEX_WPrefix == X86Local::VEX_W1 ||
- VEX_WPrefix == X86Local::VEX_W1X)) {
+ if (HasVEX_LPrefix && HasVEX_W) {
if (OpPrefix == X86Local::PD)
insnContext = IC_VEX_L_W_OPSIZE;
else if (OpPrefix == X86Local::XS)
@@ -270,8 +265,7 @@ InstructionContext RecognizableInstr::insnContext() const {
}
} else if (OpPrefix == X86Local::PD && HasVEX_LPrefix)
insnContext = IC_VEX_L_OPSIZE;
- else if (OpPrefix == X86Local::PD && (VEX_WPrefix == X86Local::VEX_W1 ||
- VEX_WPrefix == X86Local::VEX_W1X))
+ else if (OpPrefix == X86Local::PD && HasVEX_W)
insnContext = IC_VEX_W_OPSIZE;
else if (OpPrefix == X86Local::PD)
insnContext = IC_VEX_OPSIZE;
@@ -279,14 +273,11 @@ InstructionContext RecognizableInstr::insnContext() const {
insnContext = IC_VEX_L_XS;
else if (HasVEX_LPrefix && OpPrefix == X86Local::XD)
insnContext = IC_VEX_L_XD;
- else if ((VEX_WPrefix == X86Local::VEX_W1 ||
- VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::XS)
+ else if (HasVEX_W && OpPrefix == X86Local::XS)
insnContext = IC_VEX_W_XS;
- else if ((VEX_WPrefix == X86Local::VEX_W1 ||
- VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::XD)
+ else if (HasVEX_W && OpPrefix == X86Local::XD)
insnContext = IC_VEX_W_XD;
- else if ((VEX_WPrefix == X86Local::VEX_W1 ||
- VEX_WPrefix == X86Local::VEX_W1X) && OpPrefix == X86Local::PS)
+ else if (HasVEX_W && OpPrefix == X86Local::PS)
insnContext = IC_VEX_W;
else if (HasVEX_LPrefix && OpPrefix == X86Local::PS)
insnContext = IC_VEX_L;
@@ -496,6 +487,13 @@ void RecognizableInstr::emitInstructionSpecifier() {
HANDLE_OPERAND(opcodeModifier)
HANDLE_OPTIONAL(relocation)
break;
+ case X86Local::AddCCFrm:
+ // Operand 1 (optional) is an address or immediate.
+ assert(numPhysicalOperands == 2 &&
+ "Unexpected number of operands for AddCCFrm");
+ HANDLE_OPERAND(relocation)
+ HANDLE_OPERAND(opcodeModifier)
+ break;
case X86Local::MRMDestReg:
// Operand 1 is a register operand in the R/M field.
// - In AVX512 there may be a mask operand here -
@@ -581,6 +579,13 @@ void RecognizableInstr::emitInstructionSpecifier() {
HANDLE_OPERAND(rmRegister)
HANDLE_OPTIONAL(immediate)
break;
+ case X86Local::MRMSrcRegCC:
+ assert(numPhysicalOperands == 3 &&
+ "Unexpected number of operands for MRMSrcRegCC");
+ HANDLE_OPERAND(roRegister)
+ HANDLE_OPERAND(rmRegister)
+ HANDLE_OPERAND(opcodeModifier)
+ break;
case X86Local::MRMSrcMem:
// Operand 1 is a register operand in the Reg/Opcode field.
// Operand 2 is a memory operand (possibly SIB-extended)
@@ -621,6 +626,19 @@ void RecognizableInstr::emitInstructionSpecifier() {
HANDLE_OPERAND(memory)
HANDLE_OPTIONAL(immediate)
break;
+ case X86Local::MRMSrcMemCC:
+ assert(numPhysicalOperands == 3 &&
+ "Unexpected number of operands for MRMSrcMemCC");
+ HANDLE_OPERAND(roRegister)
+ HANDLE_OPERAND(memory)
+ HANDLE_OPERAND(opcodeModifier)
+ break;
+ case X86Local::MRMXrCC:
+ assert(numPhysicalOperands == 2 &&
+ "Unexpected number of operands for MRMXrCC");
+ HANDLE_OPERAND(rmRegister)
+ HANDLE_OPERAND(opcodeModifier)
+ break;
case X86Local::MRMXr:
case X86Local::MRM0r:
case X86Local::MRM1r:
@@ -646,6 +664,12 @@ void RecognizableInstr::emitInstructionSpecifier() {
HANDLE_OPTIONAL(relocation)
HANDLE_OPTIONAL(immediate)
break;
+ case X86Local::MRMXmCC:
+ assert(numPhysicalOperands == 2 &&
+ "Unexpected number of operands for MRMXm");
+ HANDLE_OPERAND(memory)
+ HANDLE_OPERAND(opcodeModifier)
+ break;
case X86Local::MRMXm:
case X86Local::MRM0m:
case X86Local::MRM1m:
@@ -724,12 +748,15 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
case X86Local::RawFrmDstSrc:
case X86Local::RawFrmImm8:
case X86Local::RawFrmImm16:
+ case X86Local::AddCCFrm:
filter = llvm::make_unique<DumbFilter>();
break;
case X86Local::MRMDestReg:
case X86Local::MRMSrcReg:
case X86Local::MRMSrcReg4VOp3:
case X86Local::MRMSrcRegOp4:
+ case X86Local::MRMSrcRegCC:
+ case X86Local::MRMXrCC:
case X86Local::MRMXr:
filter = llvm::make_unique<ModFilter>(true);
break;
@@ -737,6 +764,8 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
case X86Local::MRMSrcMem:
case X86Local::MRMSrcMem4VOp3:
case X86Local::MRMSrcMemOp4:
+ case X86Local::MRMSrcMemCC:
+ case X86Local::MRMXmCC:
case X86Local::MRMXm:
filter = llvm::make_unique<ModFilter>(false);
break;
@@ -769,23 +798,24 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const {
assert(opcodeType && "Opcode type not set");
assert(filter && "Filter not set");
- if (Form == X86Local::AddRegFrm) {
- assert(((opcodeToSet & 7) == 0) &&
- "ADDREG_FRM opcode not aligned");
+ if (Form == X86Local::AddRegFrm || Form == X86Local::MRMSrcRegCC ||
+ Form == X86Local::MRMSrcMemCC || Form == X86Local::MRMXrCC ||
+ Form == X86Local::MRMXmCC || Form == X86Local::AddCCFrm) {
+ unsigned Count = Form == X86Local::AddRegFrm ? 8 : 16;
+ assert(((opcodeToSet % Count) == 0) && "ADDREG_FRM opcode not aligned");
uint8_t currentOpcode;
- for (currentOpcode = opcodeToSet;
- currentOpcode < opcodeToSet + 8;
+ for (currentOpcode = opcodeToSet; currentOpcode < opcodeToSet + Count;
++currentOpcode)
tables.setTableFields(*opcodeType, insnContext(), currentOpcode, *filter,
UID, Is32Bit, OpPrefix == 0,
IgnoresVEX_L || EncodeRC,
- VEX_WPrefix == X86Local::VEX_WIG, AddressSize);
+ IgnoresVEX_W, AddressSize);
} else {
tables.setTableFields(*opcodeType, insnContext(), opcodeToSet, *filter, UID,
Is32Bit, OpPrefix == 0, IgnoresVEX_L || EncodeRC,
- VEX_WPrefix == X86Local::VEX_WIG, AddressSize);
+ IgnoresVEX_W, AddressSize);
}
#undef MAP
@@ -825,7 +855,9 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("i8mem", TYPE_M)
TYPE("i8imm", TYPE_IMM)
TYPE("u8imm", TYPE_UIMM8)
+ TYPE("i16u8imm", TYPE_UIMM8)
TYPE("i32u8imm", TYPE_UIMM8)
+ TYPE("i64u8imm", TYPE_UIMM8)
TYPE("GR8", TYPE_R8)
TYPE("VR128", TYPE_XMM)
TYPE("VR128X", TYPE_XMM)
@@ -842,16 +874,14 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("f32mem", TYPE_M)
TYPE("ssmem", TYPE_M)
TYPE("RST", TYPE_ST)
+ TYPE("RSTi", TYPE_ST)
TYPE("i128mem", TYPE_M)
TYPE("i256mem", TYPE_M)
TYPE("i512mem", TYPE_M)
TYPE("i64i32imm_pcrel", TYPE_REL)
TYPE("i16imm_pcrel", TYPE_REL)
TYPE("i32imm_pcrel", TYPE_REL)
- TYPE("SSECC", TYPE_IMM3)
- TYPE("XOPCC", TYPE_IMM3)
- TYPE("AVXCC", TYPE_IMM5)
- TYPE("AVX512ICC", TYPE_AVX512ICC)
+ TYPE("ccode", TYPE_IMM)
TYPE("AVX512RC", TYPE_IMM)
TYPE("brtarget32", TYPE_REL)
TYPE("brtarget16", TYPE_REL)
@@ -902,6 +932,11 @@ OperandType RecognizableInstr::typeFromString(const std::string &s,
TYPE("VK32WM", TYPE_VK)
TYPE("VK64", TYPE_VK)
TYPE("VK64WM", TYPE_VK)
+ TYPE("VK1Pair", TYPE_VK_PAIR)
+ TYPE("VK2Pair", TYPE_VK_PAIR)
+ TYPE("VK4Pair", TYPE_VK_PAIR)
+ TYPE("VK8Pair", TYPE_VK_PAIR)
+ TYPE("VK16Pair", TYPE_VK_PAIR)
TYPE("vx64mem", TYPE_MVSIBX)
TYPE("vx128mem", TYPE_MVSIBX)
TYPE("vx256mem", TYPE_MVSIBX)
@@ -931,10 +966,6 @@ RecognizableInstr::immediateEncodingFromString(const std::string &s,
ENCODING("i16imm", ENCODING_IW)
}
ENCODING("i32i8imm", ENCODING_IB)
- ENCODING("SSECC", ENCODING_IB)
- ENCODING("XOPCC", ENCODING_IB)
- ENCODING("AVXCC", ENCODING_IB)
- ENCODING("AVX512ICC", ENCODING_IB)
ENCODING("AVX512RC", ENCODING_IRC)
ENCODING("i16imm", ENCODING_Iv)
ENCODING("i16i8imm", ENCODING_IB)
@@ -943,7 +974,9 @@ RecognizableInstr::immediateEncodingFromString(const std::string &s,
ENCODING("i64i8imm", ENCODING_IB)
ENCODING("i8imm", ENCODING_IB)
ENCODING("u8imm", ENCODING_IB)
+ ENCODING("i16u8imm", ENCODING_IB)
ENCODING("i32u8imm", ENCODING_IB)
+ ENCODING("i64u8imm", ENCODING_IB)
// This is not a typo. Instructions like BLENDVPD put
// register IDs in 8-bit immediates nowadays.
ENCODING("FR32", ENCODING_IB)
@@ -964,6 +997,7 @@ OperandEncoding
RecognizableInstr::rmRegisterEncodingFromString(const std::string &s,
uint8_t OpSize) {
ENCODING("RST", ENCODING_FP)
+ ENCODING("RSTi", ENCODING_FP)
ENCODING("GR16", ENCODING_RM)
ENCODING("GR32", ENCODING_RM)
ENCODING("GR32orGR64", ENCODING_RM)
@@ -987,6 +1021,11 @@ RecognizableInstr::rmRegisterEncodingFromString(const std::string &s,
ENCODING("VK16", ENCODING_RM)
ENCODING("VK32", ENCODING_RM)
ENCODING("VK64", ENCODING_RM)
+ ENCODING("VK1PAIR", ENCODING_RM)
+ ENCODING("VK2PAIR", ENCODING_RM)
+ ENCODING("VK4PAIR", ENCODING_RM)
+ ENCODING("VK8PAIR", ENCODING_RM)
+ ENCODING("VK16PAIR", ENCODING_RM)
ENCODING("BNDR", ENCODING_RM)
errs() << "Unhandled R/M register encoding " << s << "\n";
llvm_unreachable("Unhandled R/M register encoding");
@@ -1021,6 +1060,11 @@ RecognizableInstr::roRegisterEncodingFromString(const std::string &s,
ENCODING("VK16", ENCODING_REG)
ENCODING("VK32", ENCODING_REG)
ENCODING("VK64", ENCODING_REG)
+ ENCODING("VK1Pair", ENCODING_REG)
+ ENCODING("VK2Pair", ENCODING_REG)
+ ENCODING("VK4Pair", ENCODING_REG)
+ ENCODING("VK8Pair", ENCODING_REG)
+ ENCODING("VK16Pair", ENCODING_REG)
ENCODING("VK1WM", ENCODING_REG)
ENCODING("VK2WM", ENCODING_REG)
ENCODING("VK4WM", ENCODING_REG)
@@ -1055,6 +1099,11 @@ RecognizableInstr::vvvvRegisterEncodingFromString(const std::string &s,
ENCODING("VK16", ENCODING_VVVV)
ENCODING("VK32", ENCODING_VVVV)
ENCODING("VK64", ENCODING_VVVV)
+ ENCODING("VK1PAIR", ENCODING_VVVV)
+ ENCODING("VK2PAIR", ENCODING_VVVV)
+ ENCODING("VK4PAIR", ENCODING_VVVV)
+ ENCODING("VK8PAIR", ENCODING_VVVV)
+ ENCODING("VK16PAIR", ENCODING_VVVV)
errs() << "Unhandled VEX.vvvv register encoding " << s << "\n";
llvm_unreachable("Unhandled VEX.vvvv register encoding");
}
@@ -1128,7 +1177,9 @@ RecognizableInstr::relocationEncodingFromString(const std::string &s,
ENCODING("i64i8imm", ENCODING_IB)
ENCODING("i8imm", ENCODING_IB)
ENCODING("u8imm", ENCODING_IB)
+ ENCODING("i16u8imm", ENCODING_IB)
ENCODING("i32u8imm", ENCODING_IB)
+ ENCODING("i64u8imm", ENCODING_IB)
ENCODING("i64i32imm_pcrel", ENCODING_ID)
ENCODING("i16imm_pcrel", ENCODING_IW)
ENCODING("i32imm_pcrel", ENCODING_ID)
@@ -1166,6 +1217,7 @@ RecognizableInstr::opcodeModifierEncodingFromString(const std::string &s,
ENCODING("GR64", ENCODING_RO)
ENCODING("GR16", ENCODING_Rv)
ENCODING("GR8", ENCODING_RB)
+ ENCODING("ccode", ENCODING_CC)
errs() << "Unhandled opcode modifier encoding " << s << "\n";
llvm_unreachable("Unhandled opcode modifier encoding");
}