aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp')
-rw-r--r--llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp108
1 files changed, 108 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index dca76f8457fe..1ed8a80a4600 100644
--- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -69,6 +69,10 @@ static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst &Inst,
static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst,
unsigned RegNo, uint64_t Address,
const void *Decoder);
+static DecodeStatus DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
@@ -111,6 +115,13 @@ static DecodeStatus DecodeZPR3RegisterClass(MCInst &Inst, unsigned RegNo,
static DecodeStatus DecodeZPR4RegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
+template <unsigned NumBitsForTile>
+static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
+ uint64_t Address, const void *Decoder);
+static DecodeStatus DecodeMatrixTileListRegisterClass(MCInst &Inst,
+ unsigned RegMask,
+ uint64_t Address,
+ const void *Decoder);
static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decoder);
@@ -226,6 +237,8 @@ static DecodeStatus DecodeImm8OptLsl(MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
uint64_t Addr, const void *Decoder);
+static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
+ const void *Decoder);
static bool Check(DecodeStatus &Out, DecodeStatus In) {
switch (In) {
@@ -276,6 +289,43 @@ DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
for (auto Table : Tables) {
DecodeStatus Result =
decodeInstruction(Table, MI, Insn, Address, this, STI);
+
+ switch (MI.getOpcode()) {
+ default:
+ break;
+ // For Scalable Matrix Extension (SME) instructions that have an implicit
+ // operand for the accumulator (ZA) which isn't encoded, manually insert
+ // operand.
+ case AArch64::LDR_ZA:
+ case AArch64::STR_ZA: {
+ MI.insert(MI.begin(), MCOperand::createReg(AArch64::ZA));
+ // Spill and fill instructions have a single immediate used for both the
+ // vector select offset and optional memory offset. Replicate the decoded
+ // immediate.
+ const MCOperand &Imm4Op = MI.getOperand(2);
+ assert(Imm4Op.isImm() && "Unexpected operand type!");
+ MI.addOperand(Imm4Op);
+ break;
+ }
+ case AArch64::LD1_MXIPXX_H_B:
+ case AArch64::LD1_MXIPXX_V_B:
+ case AArch64::ST1_MXIPXX_H_B:
+ case AArch64::ST1_MXIPXX_V_B:
+ case AArch64::INSERT_MXIPZ_H_B:
+ case AArch64::INSERT_MXIPZ_V_B:
+ // e.g.
+ // MOVA ZA0<HV>.B[<Ws>, <imm>], <Pg>/M, <Zn>.B
+ // ^ insert implicit 8-bit element tile
+ MI.insert(MI.begin(), MCOperand::createReg(AArch64::ZAB0));
+ break;
+ case AArch64::EXTRACT_ZPMXI_H_B:
+ case AArch64::EXTRACT_ZPMXI_V_B:
+ // MOVA <Zd>.B, <Pg>/M, ZA0<HV>.B[<Ws>, <imm>]
+ // ^ insert implicit 8-bit element tile
+ MI.insert(MI.begin()+2, MCOperand::createReg(AArch64::ZAB0));
+ break;
+ }
+
if (Result != MCDisassembler::Fail)
return Result;
}
@@ -502,6 +552,22 @@ static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo,
return Success;
}
+static const unsigned MatrixIndexGPR32_12_15DecoderTable[] = {
+ AArch64::W12, AArch64::W13, AArch64::W14, AArch64::W15
+};
+
+static DecodeStatus DecodeMatrixIndexGPR32_12_15RegisterClass(MCInst &Inst,
+ unsigned RegNo,
+ uint64_t Addr,
+ const void *Decoder) {
+ if (RegNo > 3)
+ return Fail;
+
+ unsigned Register = MatrixIndexGPR32_12_15DecoderTable[RegNo];
+ Inst.addOperand(MCOperand::createReg(Register));
+ return Success;
+}
+
static const unsigned GPR32DecoderTable[] = {
AArch64::W0, AArch64::W1, AArch64::W2, AArch64::W3, AArch64::W4,
AArch64::W5, AArch64::W6, AArch64::W7, AArch64::W8, AArch64::W9,
@@ -642,6 +708,39 @@ static DecodeStatus DecodeZPR4RegisterClass(MCInst &Inst, unsigned RegNo,
return Success;
}
+static DecodeStatus DecodeMatrixTileListRegisterClass(MCInst &Inst,
+ unsigned RegMask,
+ uint64_t Address,
+ const void *Decoder) {
+ if (RegMask > 0xFF)
+ return Fail;
+ Inst.addOperand(MCOperand::createImm(RegMask));
+ return Success;
+}
+
+static const SmallVector<SmallVector<unsigned, 16>, 5>
+ MatrixZATileDecoderTable = {
+ {AArch64::ZAB0},
+ {AArch64::ZAH0, AArch64::ZAH1},
+ {AArch64::ZAS0, AArch64::ZAS1, AArch64::ZAS2, AArch64::ZAS3},
+ {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
+ AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7},
+ {AArch64::ZAQ0, AArch64::ZAQ1, AArch64::ZAQ2, AArch64::ZAQ3,
+ AArch64::ZAQ4, AArch64::ZAQ5, AArch64::ZAQ6, AArch64::ZAQ7,
+ AArch64::ZAQ8, AArch64::ZAQ9, AArch64::ZAQ10, AArch64::ZAQ11,
+ AArch64::ZAQ12, AArch64::ZAQ13, AArch64::ZAQ14, AArch64::ZAQ15}};
+
+template <unsigned NumBitsForTile>
+static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
+ uint64_t Address, const void *Decoder) {
+ unsigned LastReg = (1 << NumBitsForTile) - 1;
+ if (RegNo > LastReg)
+ return Fail;
+ Inst.addOperand(
+ MCOperand::createReg(MatrixZATileDecoderTable[NumBitsForTile][RegNo]));
+ return Success;
+}
+
static const unsigned PPRDecoderTable[] = {
AArch64::P0, AArch64::P1, AArch64::P2, AArch64::P3,
AArch64::P4, AArch64::P5, AArch64::P6, AArch64::P7,
@@ -1931,3 +2030,12 @@ static DecodeStatus DecodeSVEIncDecImm(MCInst &Inst, unsigned Imm,
Inst.addOperand(MCOperand::createImm(Imm + 1));
return Success;
}
+
+static DecodeStatus DecodeSVCROp(MCInst &Inst, unsigned Imm, uint64_t Address,
+ const void *Decoder) {
+ if (AArch64SVCR::lookupSVCRByEncoding(Imm)) {
+ Inst.addOperand(MCOperand::createImm(Imm));
+ return Success;
+ }
+ return Fail;
+}