diff options
author | Xiang1 Zhang <xiang1.zhang@intel.com> | 2020-07-02 08:36:45 +0800 |
---|---|---|
committer | Xiang1 Zhang <xiang1.zhang@intel.com> | 2020-07-02 08:57:04 +0800 |
commit | aded4f0cc070fcef6763c9a3c2ba764d652b692e (patch) | |
tree | 12be06afe5e1998a21e9be647a144d256341ee35 /llvm/utils | |
parent | 99c4207d428bc1e24fed677c67230e27dd3d508f (diff) | |
download | llvm-aded4f0cc070fcef6763c9a3c2ba764d652b692e.zip llvm-aded4f0cc070fcef6763c9a3c2ba764d652b692e.tar.gz llvm-aded4f0cc070fcef6763c9a3c2ba764d652b692e.tar.bz2 |
[X86-64] Support Intel AMX instructions
Summary:
INTEL ADVANCED MATRIX EXTENSIONS (AMX).
AMX is a new programming paradigm, it has a set of 2-dimensional registers
(TILES) representing sub-arrays from a larger 2-dimensional memory image and
operate on TILES.
Spec can be found in Chapter 3 here https://software.intel.com/content/www/us/en/develop/download/intel-architecture-instruction-set-extensions-programming-reference.html
Reviewers: LuoYuanke, annita.zhang, pengfei, RKSimon, xiangzhangllvm
Reviewed By: xiangzhangllvm
Subscribers: hiraditya, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D82705
Diffstat (limited to 'llvm/utils')
-rw-r--r-- | llvm/utils/TableGen/X86DisassemblerTables.cpp | 15 | ||||
-rw-r--r-- | llvm/utils/TableGen/X86ModRMFilters.cpp | 2 | ||||
-rw-r--r-- | llvm/utils/TableGen/X86ModRMFilters.h | 23 | ||||
-rw-r--r-- | llvm/utils/TableGen/X86RecognizableInstr.cpp | 23 | ||||
-rw-r--r-- | llvm/utils/TableGen/X86RecognizableInstr.h | 3 |
5 files changed, 65 insertions, 1 deletions
diff --git a/llvm/utils/TableGen/X86DisassemblerTables.cpp b/llvm/utils/TableGen/X86DisassemblerTables.cpp index 76e4fd9..3a95df2 100644 --- a/llvm/utils/TableGen/X86DisassemblerTables.cpp +++ b/llvm/utils/TableGen/X86DisassemblerTables.cpp @@ -595,6 +595,7 @@ static ModRMDecisionType getDecisionType(ModRMDecision &decision) { bool satisfiesOneEntry = true; bool satisfiesSplitRM = true; bool satisfiesSplitReg = true; + bool satisfiesSplitRegM = true; bool satisfiesSplitMisc = true; for (unsigned index = 0; index < 256; ++index) { @@ -616,6 +617,10 @@ static ModRMDecisionType getDecisionType(ModRMDecision &decision) { if (((index & 0xc0) != 0xc0) && (decision.instructionIDs[index] != decision.instructionIDs[index&0x38])) satisfiesSplitMisc = false; + + if (((index & 0xc0) == 0xc0) && + (decision.instructionIDs[index] != decision.instructionIDs[index&0xc7])) + satisfiesSplitRegM = false; } if (satisfiesOneEntry) @@ -627,6 +632,9 @@ static ModRMDecisionType getDecisionType(ModRMDecision &decision) { if (satisfiesSplitReg && satisfiesSplitMisc) return MODRM_SPLITREG; + if (satisfiesSplitRegM) + return MODRM_SPLITREGM; + if (satisfiesSplitMisc) return MODRM_SPLITMISC; @@ -691,6 +699,10 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, for (unsigned index = 0xc0; index < 256; index += 8) ModRMDecision.push_back(decision.instructionIDs[index]); break; + case MODRM_SPLITREGM: + for (unsigned index = 0xc0; index < 256; index += 8) + ModRMDecision.push_back(decision.instructionIDs[index]); + break; case MODRM_SPLITMISC: for (unsigned index = 0; index < 64; index += 8) ModRMDecision.push_back(decision.instructionIDs[index]); @@ -732,6 +744,9 @@ void DisassemblerTables::emitModRMDecision(raw_ostream &o1, raw_ostream &o2, case MODRM_SPLITREG: sEntryNumber += 16; break; + case MODRM_SPLITREGM: + sEntryNumber += 8; + break; case MODRM_SPLITMISC: sEntryNumber += 8 + 64; break; diff --git a/llvm/utils/TableGen/X86ModRMFilters.cpp b/llvm/utils/TableGen/X86ModRMFilters.cpp index 98e6fb6..cf75070 100644 --- a/llvm/utils/TableGen/X86ModRMFilters.cpp +++ b/llvm/utils/TableGen/X86ModRMFilters.cpp @@ -18,4 +18,6 @@ void ModFilter::anchor() { } void ExtendedFilter::anchor() { } +void ExtendedRMFilter::anchor() { } + void ExactFilter::anchor() { } diff --git a/llvm/utils/TableGen/X86ModRMFilters.h b/llvm/utils/TableGen/X86ModRMFilters.h index c77b4c2..f0b8af5 100644 --- a/llvm/utils/TableGen/X86ModRMFilters.h +++ b/llvm/utils/TableGen/X86ModRMFilters.h @@ -108,6 +108,29 @@ public: } }; +/// ExtendedRMFilter - Extended opcodes are classified based on the value of the +/// mod field [bits 7-6] and the value of the nnn field [bits 2-0]. +class ExtendedRMFilter : public ModRMFilter { + void anchor() override; + bool R; + uint8_t NNN; +public: + /// Constructor + /// + /// \param r True if the mod field must be set to 11; false otherwise. + /// The name is explained at ModFilter. + /// \param nnn The required value of the nnn field. + ExtendedRMFilter(bool r, uint8_t nnn) : + ModRMFilter(), + R(r), + NNN(nnn) { + } + + bool accepts(uint8_t modRM) const override { + return ((R && ((modRM & 0xc0) == 0xc0)) && + ((modRM & 0x7) == NNN)); + } +}; /// ExactFilter - The occasional extended opcode (such as VMCALL or MONITOR) /// requires the ModR/M byte to have a specific value. class ExactFilter : public ModRMFilter { diff --git a/llvm/utils/TableGen/X86RecognizableInstr.cpp b/llvm/utils/TableGen/X86RecognizableInstr.cpp index f31e43b..84f6d52 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.cpp +++ b/llvm/utils/TableGen/X86RecognizableInstr.cpp @@ -352,10 +352,13 @@ void RecognizableInstr::adjustOperandEncoding(OperandEncoding &encoding) { // The scaling factor for AVX512 compressed displacement encoding is an // instruction attribute. Adjust the ModRM encoding type to include the // scale for compressed displacement. - if ((encoding != ENCODING_RM && encoding != ENCODING_VSIB) ||CD8_Scale == 0) + if ((encoding != ENCODING_RM && + encoding != ENCODING_VSIB && + encoding != ENCODING_SIB) ||CD8_Scale == 0) return; encoding = (OperandEncoding)(encoding + Log2_32(CD8_Scale)); assert(((encoding >= ENCODING_RM && encoding <= ENCODING_RM_CD64) || + (encoding == ENCODING_SIB) || (encoding >= ENCODING_VSIB && encoding <= ENCODING_VSIB_CD64)) && "Invalid CDisp scaling"); } @@ -519,6 +522,7 @@ void RecognizableInstr::emitInstructionSpecifier() { HANDLE_OPTIONAL(immediate) break; case X86Local::MRMDestMem: + case X86Local::MRMDestMemFSIB: // Operand 1 is a memory operand (possibly SIB-extended) // Operand 2 is a register operand in the Reg/Opcode field. // - In AVX, there is a register operand in the VEX.vvvv field here - @@ -589,6 +593,7 @@ void RecognizableInstr::emitInstructionSpecifier() { HANDLE_OPERAND(opcodeModifier) break; case X86Local::MRMSrcMem: + case X86Local::MRMSrcMemFSIB: // Operand 1 is a register operand in the Reg/Opcode field. // Operand 2 is a memory operand (possibly SIB-extended) // - In AVX, there is a register operand in the VEX.vvvv field here - @@ -641,6 +646,10 @@ void RecognizableInstr::emitInstructionSpecifier() { HANDLE_OPERAND(rmRegister) HANDLE_OPERAND(opcodeModifier) break; + case X86Local::MRMr0: + // Operand 1 is a register operand in the R/M field. + HANDLE_OPERAND(roRegister) + break; case X86Local::MRMXr: case X86Local::MRM0r: case X86Local::MRM1r: @@ -772,7 +781,9 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { filter = std::make_unique<ModFilter>(true); break; case X86Local::MRMDestMem: + case X86Local::MRMDestMemFSIB: case X86Local::MRMSrcMem: + case X86Local::MRMSrcMemFSIB: case X86Local::MRMSrcMem4VOp3: case X86Local::MRMSrcMemOp4: case X86Local::MRMSrcMemCC: @@ -792,6 +803,9 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { case X86Local::MRM6X: case X86Local::MRM7X: filter = std::make_unique<ExtendedFilter>(true, Form - X86Local::MRM0X); break; + case X86Local::MRMr0: + filter = std::make_unique<ExtendedRMFilter>(true, Form - X86Local::MRMr0); + break; case X86Local::MRM0m: case X86Local::MRM1m: case X86Local::MRM2m: case X86Local::MRM3m: case X86Local::MRM4m: case X86Local::MRM5m: @@ -911,6 +925,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("i64imm", TYPE_IMM) TYPE("anymem", TYPE_M) TYPE("opaquemem", TYPE_M) + TYPE("sibmem", TYPE_MSIB) TYPE("SEGMENT_REG", TYPE_SEGMENTREG) TYPE("DEBUG_REG", TYPE_DEBUGREG) TYPE("CONTROL_REG", TYPE_CONTROLREG) @@ -969,6 +984,7 @@ OperandType RecognizableInstr::typeFromString(const std::string &s, TYPE("vz256mem", TYPE_MVSIBZ) TYPE("vz512mem", TYPE_MVSIBZ) TYPE("BNDR", TYPE_BNDR) + TYPE("TILE", TYPE_TMM) errs() << "Unhandled type string " << s << "\n"; llvm_unreachable("Unhandled type string"); } @@ -1008,6 +1024,7 @@ RecognizableInstr::immediateEncodingFromString(const std::string &s, ENCODING("VR128X", ENCODING_IB) ENCODING("VR256X", ENCODING_IB) ENCODING("VR512", ENCODING_IB) + ENCODING("TILE", ENCODING_IB) errs() << "Unhandled immediate encoding " << s << "\n"; llvm_unreachable("Unhandled immediate encoding"); } @@ -1046,6 +1063,7 @@ RecognizableInstr::rmRegisterEncodingFromString(const std::string &s, ENCODING("VK8PAIR", ENCODING_RM) ENCODING("VK16PAIR", ENCODING_RM) ENCODING("BNDR", ENCODING_RM) + ENCODING("TILE", ENCODING_RM) errs() << "Unhandled R/M register encoding " << s << "\n"; llvm_unreachable("Unhandled R/M register encoding"); } @@ -1092,6 +1110,7 @@ RecognizableInstr::roRegisterEncodingFromString(const std::string &s, ENCODING("VK32WM", ENCODING_REG) ENCODING("VK64WM", ENCODING_REG) ENCODING("BNDR", ENCODING_REG) + ENCODING("TILE", ENCODING_REG) errs() << "Unhandled reg/opcode register encoding " << s << "\n"; llvm_unreachable("Unhandled reg/opcode register encoding"); } @@ -1123,6 +1142,7 @@ RecognizableInstr::vvvvRegisterEncodingFromString(const std::string &s, ENCODING("VK4PAIR", ENCODING_VVVV) ENCODING("VK8PAIR", ENCODING_VVVV) ENCODING("VK16PAIR", ENCODING_VVVV) + ENCODING("TILE", ENCODING_VVVV) errs() << "Unhandled VEX.vvvv register encoding " << s << "\n"; llvm_unreachable("Unhandled VEX.vvvv register encoding"); } @@ -1163,6 +1183,7 @@ RecognizableInstr::memoryEncodingFromString(const std::string &s, ENCODING("lea64mem", ENCODING_RM) ENCODING("anymem", ENCODING_RM) ENCODING("opaquemem", ENCODING_RM) + ENCODING("sibmem", ENCODING_SIB) ENCODING("vx64mem", ENCODING_VSIB) ENCODING("vx128mem", ENCODING_VSIB) ENCODING("vx256mem", ENCODING_VSIB) diff --git a/llvm/utils/TableGen/X86RecognizableInstr.h b/llvm/utils/TableGen/X86RecognizableInstr.h index 2bf6d1a..a7b88b4d 100644 --- a/llvm/utils/TableGen/X86RecognizableInstr.h +++ b/llvm/utils/TableGen/X86RecognizableInstr.h @@ -103,6 +103,9 @@ namespace X86Local { RawFrmImm16 = 8, AddCCFrm = 9, PrefixByte = 10, + MRMr0 = 21, + MRMSrcMemFSIB = 22, + MRMDestMemFSIB = 23, MRMDestMem = 24, MRMSrcMem = 25, MRMSrcMem4VOp3 = 26, |