[AArch64][AsmParser] Unify 'addVectorListOperands' functions.

Summary:
Merged 'addVectorList64Operands' and 'addVectorList128Operands' into a
generic 'addVectorListOperands', which can be easily extended to work
for SVE vectors.

This is patch [4/6] in a series to add assembler/disassembler support for
SVE's contiguous ST1 (scalar+imm) instructions.

Reviewers: fhahn, rengolin, javed.absar, huntergr, SjoerdMeijer, t.p.northover, echristo, evandro

Reviewed By: rengolin

Subscribers: kristof.beyls, llvm-commits

Differential Revision: https://reviews.llvm.org/D45430

llvm-svn: 329909
This commit is contained in:
Sander de Smalen 2018-04-12 13:19:32 +00:00
parent 3c0d61b7c0
commit 525e3225c2
2 changed files with 34 additions and 38 deletions

View File

@ -489,13 +489,13 @@ def V128_lo : RegisterOperand<FPR128_lo, "printVRegOperand"> {
let ParserMatchClass = VectorRegLoAsmOperand;
}
class TypedVecListAsmOperand<int count, int regsize, int lanes, int eltsize>
class TypedVecListAsmOperand<int count, string vecty, int lanes, int eltsize>
: AsmOperandClass {
let Name = "TypedVectorList" # count # "_" # lanes # eltsize;
let PredicateMethod
= "isTypedVectorList<RegKind::NeonVector, " # count # ", " # lanes # ", " # eltsize # ">";
let RenderMethod = "addVectorList" # regsize # "Operands<" # count # ">";
let RenderMethod = "addVectorListOperands<" # vecty # ", " # count # ">";
}
class TypedVecListRegOperand<RegisterClass Reg, int lanes, string eltsize>
@ -507,7 +507,7 @@ multiclass VectorList<int count, RegisterClass Reg64, RegisterClass Reg128> {
def _64AsmOperand : AsmOperandClass {
let Name = NAME # "64";
let PredicateMethod = "isImplicitlyTypedVectorList<RegKind::NeonVector, " # count # ">";
let RenderMethod = "addVectorList64Operands<" # count # ">";
let RenderMethod = "addVectorListOperands<AArch64Operand::VecListIdx_DReg, " # count # ">";
}
def "64" : RegisterOperand<Reg64, "printImplicitlyTypedVectorList"> {
@ -517,7 +517,7 @@ multiclass VectorList<int count, RegisterClass Reg64, RegisterClass Reg128> {
def _128AsmOperand : AsmOperandClass {
let Name = NAME # "128";
let PredicateMethod = "isImplicitlyTypedVectorList<RegKind::NeonVector, " # count # ">";
let RenderMethod = "addVectorList128Operands<" # count # ">";
let RenderMethod = "addVectorListOperands<AArch64Operand::VecListIdx_QReg, " # count # ">";
}
def "128" : RegisterOperand<Reg128, "printImplicitlyTypedVectorList"> {
@ -527,25 +527,25 @@ multiclass VectorList<int count, RegisterClass Reg64, RegisterClass Reg128> {
// 64-bit register lists with explicit type.
// { v0.8b, v1.8b }
def _8bAsmOperand : TypedVecListAsmOperand<count, 64, 8, 8>;
def _8bAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_DReg", 8, 8>;
def "8b" : TypedVecListRegOperand<Reg64, 8, "b"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_8bAsmOperand");
}
// { v0.4h, v1.4h }
def _4hAsmOperand : TypedVecListAsmOperand<count, 64, 4, 16>;
def _4hAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_DReg", 4, 16>;
def "4h" : TypedVecListRegOperand<Reg64, 4, "h"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_4hAsmOperand");
}
// { v0.2s, v1.2s }
def _2sAsmOperand : TypedVecListAsmOperand<count, 64, 2, 32>;
def _2sAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_DReg", 2, 32>;
def "2s" : TypedVecListRegOperand<Reg64, 2, "s"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_2sAsmOperand");
}
// { v0.1d, v1.1d }
def _1dAsmOperand : TypedVecListAsmOperand<count, 64, 1, 64>;
def _1dAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_DReg", 1, 64>;
def "1d" : TypedVecListRegOperand<Reg64, 1, "d"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_1dAsmOperand");
}
@ -553,49 +553,49 @@ multiclass VectorList<int count, RegisterClass Reg64, RegisterClass Reg128> {
// 128-bit register lists with explicit type
// { v0.16b, v1.16b }
def _16bAsmOperand : TypedVecListAsmOperand<count, 128, 16, 8>;
def _16bAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_QReg", 16, 8>;
def "16b" : TypedVecListRegOperand<Reg128, 16, "b"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_16bAsmOperand");
}
// { v0.8h, v1.8h }
def _8hAsmOperand : TypedVecListAsmOperand<count, 128, 8, 16>;
def _8hAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_QReg", 8, 16>;
def "8h" : TypedVecListRegOperand<Reg128, 8, "h"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_8hAsmOperand");
}
// { v0.4s, v1.4s }
def _4sAsmOperand : TypedVecListAsmOperand<count, 128, 4, 32>;
def _4sAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_QReg", 4, 32>;
def "4s" : TypedVecListRegOperand<Reg128, 4, "s"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_4sAsmOperand");
}
// { v0.2d, v1.2d }
def _2dAsmOperand : TypedVecListAsmOperand<count, 128, 2, 64>;
def _2dAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_QReg", 2, 64>;
def "2d" : TypedVecListRegOperand<Reg128, 2, "d"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_2dAsmOperand");
}
// { v0.b, v1.b }
def _bAsmOperand : TypedVecListAsmOperand<count, 128, 0, 8>;
def _bAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_QReg", 0, 8>;
def "b" : TypedVecListRegOperand<Reg128, 0, "b"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_bAsmOperand");
}
// { v0.h, v1.h }
def _hAsmOperand : TypedVecListAsmOperand<count, 128, 0, 16>;
def _hAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_QReg", 0, 16>;
def "h" : TypedVecListRegOperand<Reg128, 0, "h"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_hAsmOperand");
}
// { v0.s, v1.s }
def _sAsmOperand : TypedVecListAsmOperand<count, 128, 0, 32>;
def _sAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_QReg", 0, 32>;
def "s" : TypedVecListRegOperand<Reg128, 0, "s"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_sAsmOperand");
}
// { v0.d, v1.d }
def _dAsmOperand : TypedVecListAsmOperand<count, 128, 0, 64>;
def _dAsmOperand : TypedVecListAsmOperand<count, "AArch64Operand::VecListIdx_QReg", 0, 64>;
def "d" : TypedVecListRegOperand<Reg128, 0, "d"> {
let ParserMatchClass = !cast<AsmOperandClass>(NAME # "_dAsmOperand");
}

View File

@ -1136,30 +1136,26 @@ public:
Inst.addOperand(MCOperand::createReg(getReg()));
}
template <unsigned NumRegs>
void addVectorList64Operands(MCInst &Inst, unsigned N) const {
enum VecListIndexType {
VecListIdx_DReg = 0,
VecListIdx_QReg = 1,
};
template <VecListIndexType RegTy, unsigned NumRegs>
void addVectorListOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
static const unsigned FirstRegs[] = { AArch64::D0,
AArch64::D0_D1,
AArch64::D0_D1_D2,
AArch64::D0_D1_D2_D3 };
unsigned FirstReg = FirstRegs[NumRegs - 1];
static const unsigned FirstRegs[][5] = {
/* DReg */ { AArch64::Q0,
AArch64::D0, AArch64::D0_D1,
AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
/* QReg */ { AArch64::Q0,
AArch64::Q0, AArch64::Q0_Q1,
AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 }
};
Inst.addOperand(
MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0));
}
template <unsigned NumRegs>
void addVectorList128Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
static const unsigned FirstRegs[] = { AArch64::Q0,
AArch64::Q0_Q1,
AArch64::Q0_Q1_Q2,
AArch64::Q0_Q1_Q2_Q3 };
unsigned FirstReg = FirstRegs[NumRegs - 1];
Inst.addOperand(
MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0));
unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
Inst.addOperand(MCOperand::createReg(FirstReg + getVectorListStart() -
FirstRegs[(unsigned)RegTy][0]));
}
void addVectorIndex1Operands(MCInst &Inst, unsigned N) const {