Skip to content

Commit 261f86f

Browse files
committed
[AArch64] Provide a custom decoder for LDR_ZA/STR_ZA
These are the only instructions that encode two operands in the same field. Instead of fixing them after they have been incorrectly decoded, provide a custom decoder.
1 parent 8b1424a commit 261f86f

File tree

2 files changed

+24
-10
lines changed

2 files changed

+24
-10
lines changed

llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,6 +1563,26 @@ static DecodeStatus DecodePRFMRegInstruction(MCInst &Inst, uint32_t insn,
15631563
return Success;
15641564
}
15651565

1566+
static DecodeStatus
1567+
DecodeSMESpillFillInstruction(MCInst &Inst, uint32_t Bits, uint64_t Addr,
1568+
const MCDisassembler *Decoder) {
1569+
unsigned RvBits = fieldFromInstruction(Bits, 13, 2);
1570+
unsigned RnBits = fieldFromInstruction(Bits, 5, 5);
1571+
unsigned Imm4Bits = fieldFromInstruction(Bits, 0, 4);
1572+
1573+
Inst.addOperand(MCOperand::createReg(AArch64::ZA));
1574+
DecodeSimpleRegisterClass<AArch64::MatrixIndexGPR32_12_15RegClassID, 0, 4>(
1575+
Inst, RvBits, Addr, Decoder);
1576+
Inst.addOperand(MCOperand::createImm(Imm4Bits));
1577+
DecodeSimpleRegisterClass<AArch64::GPR64spRegClassID, 0, 32>(Inst, RnBits,
1578+
Addr, Decoder);
1579+
// Spill and fill instructions have a single immediate used for both
1580+
// the vector select offset and optional memory offset. Replicate
1581+
// the decoded immediate.
1582+
Inst.addOperand(MCOperand::createImm(Imm4Bits));
1583+
return Success;
1584+
}
1585+
15661586
#include "AArch64GenDisassemblerTables.inc"
15671587
#include "AArch64GenInstrInfo.inc"
15681588

@@ -1621,16 +1641,6 @@ DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
16211641
}
16221642
}
16231643

1624-
if (MI.getOpcode() == AArch64::LDR_ZA ||
1625-
MI.getOpcode() == AArch64::STR_ZA) {
1626-
// Spill and fill instructions have a single immediate used for both
1627-
// the vector select offset and optional memory offset. Replicate
1628-
// the decoded immediate.
1629-
const MCOperand &Imm4Op = MI.getOperand(2);
1630-
assert(Imm4Op.isImm() && "Unexpected operand type!");
1631-
MI.addOperand(Imm4Op);
1632-
}
1633-
16341644
if (Result != MCDisassembler::Fail)
16351645
return Result;
16361646
}

llvm/lib/Target/AArch64/SMEInstrFormats.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,10 @@ class sme_spill_fill_base<bit isStore, dag outs, dag ins, string opcodestr>
11081108
: I<outs, ins, opcodestr, "\t$ZAt[$Rv, $imm4], [$Rn, $offset, mul vl]", "",
11091109
[]>,
11101110
Sched<[]> {
1111+
// 'offset' operand is encoded in the same bits as 'imm4'. There is currently
1112+
// no way to tell TableGen about this.
1113+
let DecoderMethod = "DecodeSMESpillFillInstruction";
1114+
bits<0> ZAt;
11111115
bits<2> Rv;
11121116
bits<5> Rn;
11131117
bits<4> imm4;

0 commit comments

Comments
 (0)