aboutsummaryrefslogtreecommitdiff
path: root/llvm/utils
diff options
context:
space:
mode:
authorXiang1 Zhang <xiang1.zhang@intel.com>2020-07-02 08:36:45 +0800
committerXiang1 Zhang <xiang1.zhang@intel.com>2020-07-02 08:57:04 +0800
commitaded4f0cc070fcef6763c9a3c2ba764d652b692e (patch)
tree12be06afe5e1998a21e9be647a144d256341ee35 /llvm/utils
parent99c4207d428bc1e24fed677c67230e27dd3d508f (diff)
downloadllvm-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.cpp15
-rw-r--r--llvm/utils/TableGen/X86ModRMFilters.cpp2
-rw-r--r--llvm/utils/TableGen/X86ModRMFilters.h23
-rw-r--r--llvm/utils/TableGen/X86RecognizableInstr.cpp23
-rw-r--r--llvm/utils/TableGen/X86RecognizableInstr.h3
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,