diff options
Diffstat (limited to 'utils/TableGen/X86RecognizableInstr.cpp')
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.cpp | 128 |
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"); } |