Skip to content

Commit bf83516

Browse files
authored
[AArch64] Remove post-decoding instruction mutations (llvm#156364)
Add `bits<0>` fields to instructions using the ZTR/MPR/MPR8 register classes. These register classes contain only one register, and it is not encoded in the instruction. This way, the generated decoder can completely decode instructions without having to perform a post-decoding pass to insert missing operands. Some immediate operands are also not encoded and have only one possible value "zero". Use this trick for them, too. Finally, remove `-ignore-non-decodable-operands` option from `llvm-tblgen` invocation to ensure that non-decodable operands do not appear in the future.
1 parent cac54a8 commit bf83516

File tree

7 files changed

+153
-79
lines changed

7 files changed

+153
-79
lines changed

llvm/lib/Target/AArch64/AArch64InstrFormats.td

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,13 +1561,12 @@ def VectorIndexHOperand : AsmVectorIndex<0, 7>;
15611561
def VectorIndexSOperand : AsmVectorIndex<0, 3>;
15621562
def VectorIndexDOperand : AsmVectorIndex<0, 1>;
15631563

1564-
let OperandNamespace = "AArch64" in {
1565-
let OperandType = "OPERAND_IMPLICIT_IMM_0" in {
1566-
defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand,
1567-
[{ return ((uint64_t)Imm) == 0; }]>;
1568-
defm VectorIndex032b : VectorIndex<i32, VectorIndex0Operand,
1569-
[{ return ((uint32_t)Imm) == 0; }]>;
1570-
}
1564+
let OperandNamespace = "AArch64", OperandType = "OPERAND_IMPLICIT_IMM_0",
1565+
DecoderMethod = "DecodeZeroImm" in {
1566+
defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand,
1567+
[{ return ((uint64_t)Imm) == 0; }]>;
1568+
defm VectorIndex032b : VectorIndex<i32, VectorIndex0Operand,
1569+
[{ return ((uint32_t)Imm) == 0; }]>;
15711570
}
15721571
defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand,
15731572
[{ return ((uint64_t)Imm) == 1; }]>;
@@ -1620,6 +1619,7 @@ def sme_elm_idx0_0 : Operand<i32>, TImmLeaf<i32, [{
16201619
let PrintMethod = "printMatrixIndex";
16211620
let OperandNamespace = "AArch64";
16221621
let OperandType = "OPERAND_IMPLICIT_IMM_0";
1622+
let DecoderMethod = "DecodeZeroImm";
16231623
}
16241624
def sme_elm_idx0_1 : Operand<i32>, TImmLeaf<i32, [{
16251625
return ((uint32_t)Imm) <= 1;
@@ -1683,6 +1683,7 @@ def uimm0s2range : Operand<i64>, ImmLeaf<i64,
16831683
let ParserMatchClass = UImm0s2RangeOperand;
16841684
let OperandNamespace = "AArch64";
16851685
let OperandType = "OPERAND_IMPLICIT_IMM_0";
1686+
let DecoderMethod = "DecodeZeroImm";
16861687
}
16871688

16881689
def uimm0s4range : Operand<i64>, ImmLeaf<i64,
@@ -1691,6 +1692,7 @@ def uimm0s4range : Operand<i64>, ImmLeaf<i64,
16911692
let ParserMatchClass = UImm0s4RangeOperand;
16921693
let OperandNamespace = "AArch64";
16931694
let OperandType = "OPERAND_IMPLICIT_IMM_0";
1695+
let DecoderMethod = "DecodeZeroImm";
16941696
}
16951697

16961698
def uimm1s2range : Operand<i64>, ImmLeaf<i64,
@@ -8220,18 +8222,23 @@ multiclass SMov {
82208222
// streaming mode.
82218223
let Predicates = [HasNEONandIsStreamingSafe] in {
82228224
def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> {
8225+
bits<0> idx;
82238226
let Inst{20-16} = 0b00001;
82248227
}
82258228
def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> {
8229+
bits<0> idx;
82268230
let Inst{20-16} = 0b00001;
82278231
}
82288232
def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> {
8233+
bits<0> idx;
82298234
let Inst{20-16} = 0b00010;
82308235
}
82318236
def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> {
8237+
bits<0> idx;
82328238
let Inst{20-16} = 0b00010;
82338239
}
82348240
def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> {
8241+
bits<0> idx;
82358242
let Inst{20-16} = 0b00100;
82368243
}
82378244
}
@@ -8267,15 +8274,19 @@ multiclass UMov {
82678274
// streaming mode.
82688275
let Predicates = [HasNEONandIsStreamingSafe] in {
82698276
def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> {
8277+
bits<0> idx;
82708278
let Inst{20-16} = 0b00001;
82718279
}
82728280
def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> {
8281+
bits<0> idx;
82738282
let Inst{20-16} = 0b00010;
82748283
}
82758284
def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> {
8285+
bits<0> idx;
82768286
let Inst{20-16} = 0b00100;
82778287
}
82788288
def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> {
8289+
bits<0> idx;
82798290
let Inst{20-16} = 0b01000;
82808291
}
82818292
def : SIMDMovAlias<"mov", ".s",

llvm/lib/Target/AArch64/AArch64RegisterInfo.td

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,16 +1875,15 @@ class MatrixTileAsmOperand<string RC, int EltSize> : AsmOperandClass {
18751875
# EltSize # ", AArch64::" # RC # "RegClassID>";
18761876
}
18771877

1878-
class MatrixTileOperand<int EltSize, int NumBitsForTile, RegisterClass RC>
1878+
class MatrixTileOperand<int EltSize, RegisterClass RC>
18791879
: RegisterOperand<RC> {
18801880
let ParserMatchClass = MatrixTileAsmOperand<!cast<string>(RC), EltSize>;
1881-
let DecoderMethod = "DecodeMatrixTile<" # NumBitsForTile # ">";
18821881
let PrintMethod = "printMatrixTile";
18831882
}
18841883

1885-
def TileOp16 : MatrixTileOperand<16, 1, MPR16>;
1886-
def TileOp32 : MatrixTileOperand<32, 2, MPR32>;
1887-
def TileOp64 : MatrixTileOperand<64, 3, MPR64>;
1884+
def TileOp16 : MatrixTileOperand<16, MPR16>;
1885+
def TileOp32 : MatrixTileOperand<32, MPR32>;
1886+
def TileOp64 : MatrixTileOperand<64, MPR64>;
18881887

18891888
//
18901889
// Tile vectors (horizontal and vertical)
@@ -1902,26 +1901,24 @@ class MatrixTileVectorAsmOperand<string RC, int EltSize, int IsVertical>
19021901
# EltSize # ", AArch64::" # RC # "RegClassID>";
19031902
}
19041903

1905-
class MatrixTileVectorOperand<int EltSize, int NumBitsForTile,
1906-
RegisterClass RC, int IsVertical>
1904+
class MatrixTileVectorOperand<int EltSize, RegisterClass RC, int IsVertical>
19071905
: RegisterOperand<RC> {
19081906
let ParserMatchClass = MatrixTileVectorAsmOperand<!cast<string>(RC), EltSize,
19091907
IsVertical>;
1910-
let DecoderMethod = "DecodeMatrixTile<" # NumBitsForTile # ">";
19111908
let PrintMethod = "printMatrixTileVector<" # IsVertical # ">";
19121909
}
19131910

1914-
def TileVectorOpH8 : MatrixTileVectorOperand< 8, 0, MPR8, 0>;
1915-
def TileVectorOpH16 : MatrixTileVectorOperand< 16, 1, MPR16, 0>;
1916-
def TileVectorOpH32 : MatrixTileVectorOperand< 32, 2, MPR32, 0>;
1917-
def TileVectorOpH64 : MatrixTileVectorOperand< 64, 3, MPR64, 0>;
1918-
def TileVectorOpH128 : MatrixTileVectorOperand<128, 4, MPR128, 0>;
1911+
def TileVectorOpH8 : MatrixTileVectorOperand< 8, MPR8, 0>;
1912+
def TileVectorOpH16 : MatrixTileVectorOperand< 16, MPR16, 0>;
1913+
def TileVectorOpH32 : MatrixTileVectorOperand< 32, MPR32, 0>;
1914+
def TileVectorOpH64 : MatrixTileVectorOperand< 64, MPR64, 0>;
1915+
def TileVectorOpH128 : MatrixTileVectorOperand<128, MPR128, 0>;
19191916

1920-
def TileVectorOpV8 : MatrixTileVectorOperand< 8, 0, MPR8, 1>;
1921-
def TileVectorOpV16 : MatrixTileVectorOperand< 16, 1, MPR16, 1>;
1922-
def TileVectorOpV32 : MatrixTileVectorOperand< 32, 2, MPR32, 1>;
1923-
def TileVectorOpV64 : MatrixTileVectorOperand< 64, 3, MPR64, 1>;
1924-
def TileVectorOpV128 : MatrixTileVectorOperand<128, 4, MPR128, 1>;
1917+
def TileVectorOpV8 : MatrixTileVectorOperand< 8, MPR8, 1>;
1918+
def TileVectorOpV16 : MatrixTileVectorOperand< 16, MPR16, 1>;
1919+
def TileVectorOpV32 : MatrixTileVectorOperand< 32, MPR32, 1>;
1920+
def TileVectorOpV64 : MatrixTileVectorOperand< 64, MPR64, 1>;
1921+
def TileVectorOpV128 : MatrixTileVectorOperand<128, MPR128, 1>;
19251922

19261923
//
19271924
// Accumulator matrix

llvm/lib/Target/AArch64/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ tablegen(LLVM AArch64GenAsmWriter.inc -gen-asm-writer)
77
tablegen(LLVM AArch64GenAsmWriter1.inc -gen-asm-writer -asmwriternum=1)
88
tablegen(LLVM AArch64GenCallingConv.inc -gen-callingconv)
99
tablegen(LLVM AArch64GenDAGISel.inc -gen-dag-isel)
10-
tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler
11-
-ignore-non-decodable-operands)
10+
tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
1211
tablegen(LLVM AArch64GenFastISel.inc -gen-fast-isel)
1312
tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel)
1413
tablegen(LLVM AArch64GenO0PreLegalizeGICombiner.inc -gen-global-isel-combiner

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

Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -130,26 +130,57 @@ DecodeMatrixTileListRegisterClass(MCInst &Inst, unsigned RegMask,
130130
return Success;
131131
}
132132

133-
static const MCPhysReg MatrixZATileDecoderTable[5][16] = {
134-
{AArch64::ZAB0},
135-
{AArch64::ZAH0, AArch64::ZAH1},
136-
{AArch64::ZAS0, AArch64::ZAS1, AArch64::ZAS2, AArch64::ZAS3},
137-
{AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3, AArch64::ZAD4,
138-
AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7},
139-
{AArch64::ZAQ0, AArch64::ZAQ1, AArch64::ZAQ2, AArch64::ZAQ3, AArch64::ZAQ4,
140-
AArch64::ZAQ5, AArch64::ZAQ6, AArch64::ZAQ7, AArch64::ZAQ8, AArch64::ZAQ9,
141-
AArch64::ZAQ10, AArch64::ZAQ11, AArch64::ZAQ12, AArch64::ZAQ13,
142-
AArch64::ZAQ14, AArch64::ZAQ15}};
143-
144-
template <unsigned NumBitsForTile>
145-
static DecodeStatus DecodeMatrixTile(MCInst &Inst, unsigned RegNo,
146-
uint64_t Address,
147-
const MCDisassembler *Decoder) {
148-
unsigned LastReg = (1 << NumBitsForTile) - 1;
149-
if (RegNo > LastReg)
150-
return Fail;
151-
Inst.addOperand(
152-
MCOperand::createReg(MatrixZATileDecoderTable[NumBitsForTile][RegNo]));
133+
static DecodeStatus DecodeZTRRegisterClass(MCInst &Inst,
134+
const MCDisassembler *Decoder) {
135+
Inst.addOperand(MCOperand::createReg(AArch64::ZT0));
136+
return Success;
137+
}
138+
139+
static DecodeStatus DecodeMPRRegisterClass(MCInst &Inst,
140+
const MCDisassembler *Decoder) {
141+
Inst.addOperand(MCOperand::createReg(AArch64::ZA));
142+
return Success;
143+
}
144+
145+
static DecodeStatus DecodeMPR8RegisterClass(MCInst &Inst,
146+
const MCDisassembler *Decoder) {
147+
Inst.addOperand(MCOperand::createReg(AArch64::ZAB0));
148+
return Success;
149+
}
150+
151+
static DecodeStatus DecodeMPR16RegisterClass(MCInst &Inst, unsigned RegNo,
152+
uint64_t Address,
153+
const MCDisassembler *Decoder) {
154+
MCRegister Reg =
155+
AArch64MCRegisterClasses[AArch64::MPR16RegClassID].getRegister(RegNo);
156+
Inst.addOperand(MCOperand::createReg(Reg));
157+
return Success;
158+
}
159+
160+
static DecodeStatus DecodeMPR32RegisterClass(MCInst &Inst, unsigned RegNo,
161+
uint64_t Address,
162+
const MCDisassembler *Decoder) {
163+
MCRegister Reg =
164+
AArch64MCRegisterClasses[AArch64::MPR32RegClassID].getRegister(RegNo);
165+
Inst.addOperand(MCOperand::createReg(Reg));
166+
return Success;
167+
}
168+
169+
static DecodeStatus DecodeMPR64RegisterClass(MCInst &Inst, unsigned RegNo,
170+
uint64_t Address,
171+
const MCDisassembler *Decoder) {
172+
MCRegister Reg =
173+
AArch64MCRegisterClasses[AArch64::MPR64RegClassID].getRegister(RegNo);
174+
Inst.addOperand(MCOperand::createReg(Reg));
175+
return Success;
176+
}
177+
178+
static DecodeStatus DecodeMPR128RegisterClass(MCInst &Inst, unsigned RegNo,
179+
uint64_t Address,
180+
const MCDisassembler *Decoder) {
181+
MCRegister Reg =
182+
AArch64MCRegisterClasses[AArch64::MPR128RegClassID].getRegister(RegNo);
183+
Inst.addOperand(MCOperand::createReg(Reg));
153184
return Success;
154185
}
155186

@@ -1392,6 +1423,11 @@ DecodeSVELogicalImmInstruction(MCInst &Inst, uint32_t insn, uint64_t Addr,
13921423
return Success;
13931424
}
13941425

1426+
static DecodeStatus DecodeZeroImm(MCInst &Inst, const MCDisassembler *Decoder) {
1427+
Inst.addOperand(MCOperand::createImm(0));
1428+
return Success;
1429+
}
1430+
13951431
template <int Bits>
13961432
static DecodeStatus DecodeSImm(MCInst &Inst, uint64_t Imm, uint64_t Address,
13971433
const MCDisassembler *Decoder) {
@@ -1540,6 +1576,7 @@ DecodeSMESpillFillInstruction(MCInst &Inst, uint32_t Bits, uint64_t Addr,
15401576
unsigned RnBits = fieldFromInstruction(Bits, 5, 5);
15411577
unsigned Imm4Bits = fieldFromInstruction(Bits, 0, 4);
15421578

1579+
DecodeMPRRegisterClass(Inst, Decoder);
15431580
DecodeSimpleRegisterClass<AArch64::MatrixIndexGPR32_12_15RegClassID, 0, 4>(
15441581
Inst, RvBits, Addr, Decoder);
15451582
Inst.addOperand(MCOperand::createImm(Imm4Bits));
@@ -1583,33 +1620,6 @@ DecodeStatus AArch64Disassembler::getInstruction(MCInst &MI, uint64_t &Size,
15831620
for (const auto *Table : Tables) {
15841621
DecodeStatus Result =
15851622
decodeInstruction(Table, MI, Insn, Address, this, STI);
1586-
1587-
const MCInstrDesc &Desc = MCII->get(MI.getOpcode());
1588-
1589-
// For Scalable Matrix Extension (SME) instructions that have an implicit
1590-
// operand for the accumulator (ZA) or implicit immediate zero which isn't
1591-
// encoded, manually insert operand.
1592-
for (unsigned i = 0; i < Desc.getNumOperands(); i++) {
1593-
if (Desc.operands()[i].OperandType == MCOI::OPERAND_REGISTER) {
1594-
switch (Desc.operands()[i].RegClass) {
1595-
default:
1596-
break;
1597-
case AArch64::MPRRegClassID:
1598-
MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZA));
1599-
break;
1600-
case AArch64::MPR8RegClassID:
1601-
MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZAB0));
1602-
break;
1603-
case AArch64::ZTRRegClassID:
1604-
MI.insert(MI.begin() + i, MCOperand::createReg(AArch64::ZT0));
1605-
break;
1606-
}
1607-
} else if (Desc.operands()[i].OperandType ==
1608-
AArch64::OPERAND_IMPLICIT_IMM_0) {
1609-
MI.insert(MI.begin() + i, MCOperand::createImm(0));
1610-
}
1611-
}
1612-
16131623
if (Result != MCDisassembler::Fail)
16141624
return Result;
16151625
}

0 commit comments

Comments
 (0)