aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSander de Smalen <sander.desmalen@arm.com>2018-04-13 09:11:53 +0000
committerSander de Smalen <sander.desmalen@arm.com>2018-04-13 09:11:53 +0000
commit15535accd9e1e9d7772202ce51c8428c1994a04b (patch)
treedafd8870e2c10f9ee94f26de2cf02b89e393fc23
parent31add1057f7db6b20fd98ae46accac644d81a3a6 (diff)
[AArch64][SVE] Asm: Add support for parsing and printing SVE vector lists.
Summary: Added Z_(b|h|s|d) vector list RegisterOperands along with support to add/print the vector lists. This is patch [5/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: fhahn Subscribers: tschuett, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D45431 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@330000 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/AArch64/AArch64RegisterInfo.td29
-rw-r--r--lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp8
-rw-r--r--lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp43
3 files changed, 78 insertions, 2 deletions
diff --git a/lib/Target/AArch64/AArch64RegisterInfo.td b/lib/Target/AArch64/AArch64RegisterInfo.td
index 39243b92a44..09d0a753072 100644
--- a/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -834,3 +834,32 @@ def ZPR16 : ZPRRegOp<"h", ZPRAsmOp16, ZPR>;
def ZPR32 : ZPRRegOp<"s", ZPRAsmOp32, ZPR>;
def ZPR64 : ZPRRegOp<"d", ZPRAsmOp64, ZPR>;
def ZPR128 : ZPRRegOp<"q", ZPRAsmOp128, ZPR>;
+
+
+let Namespace = "AArch64" in {
+ def zsub0 : SubRegIndex<128, -1>;
+}
+
+class ZPRVectorList<int ElementWidth, int NumRegs> : AsmOperandClass {
+ let Name = "SVEVectorList" # NumRegs # ElementWidth;
+ let ParserMethod = "tryParseVectorList<RegKind::SVEDataVector>";
+ let PredicateMethod =
+ "isTypedVectorList<RegKind::SVEDataVector, " #NumRegs #", 0, " #ElementWidth #">";
+ let RenderMethod = "addVectorListOperands<AArch64Operand::VecListIdx_ZReg, " # NumRegs # ">";
+}
+
+def Z_b : RegisterOperand<ZPR, "printTypedVectorList<0,'b'>"> {
+ let ParserMatchClass = ZPRVectorList<8, 1>;
+}
+
+def Z_h : RegisterOperand<ZPR, "printTypedVectorList<0,'h'>"> {
+ let ParserMatchClass = ZPRVectorList<16, 1>;
+}
+
+def Z_s : RegisterOperand<ZPR, "printTypedVectorList<0,'s'>"> {
+ let ParserMatchClass = ZPRVectorList<32, 1>;
+}
+
+def Z_d : RegisterOperand<ZPR, "printTypedVectorList<0,'d'>"> {
+ let ParserMatchClass = ZPRVectorList<64, 1>;
+}
diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 17f038e2a65..d21881fd99c 100644
--- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -1139,6 +1139,7 @@ public:
enum VecListIndexType {
VecListIdx_DReg = 0,
VecListIdx_QReg = 1,
+ VecListIdx_ZReg = 2,
};
template <VecListIndexType RegTy, unsigned NumRegs>
@@ -1150,9 +1151,14 @@ public:
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 }
+ AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
+ /* ZReg */ { AArch64::Z0,
+ AArch64::Z0 }
};
+ assert((RegTy != VecListIdx_ZReg || NumRegs <= 1) &&
+ " NumRegs must be 0 or 1 for ZRegs");
+
unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
Inst.addOperand(MCOperand::createReg(FirstReg + getVectorListStart() -
FirstRegs[(unsigned)RegTy][0]));
diff --git a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
index a34864cdad7..4e39b963227 100644
--- a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
+++ b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
@@ -1111,6 +1111,41 @@ static unsigned getNextVectorRegister(unsigned Reg, unsigned Stride = 1) {
case AArch64::Q31:
Reg = AArch64::Q0;
break;
+ case AArch64::Z0: Reg = AArch64::Z1; break;
+ case AArch64::Z1: Reg = AArch64::Z2; break;
+ case AArch64::Z2: Reg = AArch64::Z3; break;
+ case AArch64::Z3: Reg = AArch64::Z4; break;
+ case AArch64::Z4: Reg = AArch64::Z5; break;
+ case AArch64::Z5: Reg = AArch64::Z6; break;
+ case AArch64::Z6: Reg = AArch64::Z7; break;
+ case AArch64::Z7: Reg = AArch64::Z8; break;
+ case AArch64::Z8: Reg = AArch64::Z9; break;
+ case AArch64::Z9: Reg = AArch64::Z10; break;
+ case AArch64::Z10: Reg = AArch64::Z11; break;
+ case AArch64::Z11: Reg = AArch64::Z12; break;
+ case AArch64::Z12: Reg = AArch64::Z13; break;
+ case AArch64::Z13: Reg = AArch64::Z14; break;
+ case AArch64::Z14: Reg = AArch64::Z15; break;
+ case AArch64::Z15: Reg = AArch64::Z16; break;
+ case AArch64::Z16: Reg = AArch64::Z17; break;
+ case AArch64::Z17: Reg = AArch64::Z18; break;
+ case AArch64::Z18: Reg = AArch64::Z19; break;
+ case AArch64::Z19: Reg = AArch64::Z20; break;
+ case AArch64::Z20: Reg = AArch64::Z21; break;
+ case AArch64::Z21: Reg = AArch64::Z22; break;
+ case AArch64::Z22: Reg = AArch64::Z23; break;
+ case AArch64::Z23: Reg = AArch64::Z24; break;
+ case AArch64::Z24: Reg = AArch64::Z25; break;
+ case AArch64::Z25: Reg = AArch64::Z26; break;
+ case AArch64::Z26: Reg = AArch64::Z27; break;
+ case AArch64::Z27: Reg = AArch64::Z28; break;
+ case AArch64::Z28: Reg = AArch64::Z29; break;
+ case AArch64::Z29: Reg = AArch64::Z30; break;
+ case AArch64::Z30: Reg = AArch64::Z31; break;
+ // Vector lists can wrap around.
+ case AArch64::Z31:
+ Reg = AArch64::Z0;
+ break;
}
}
return Reg;
@@ -1159,6 +1194,8 @@ void AArch64InstPrinter::printVectorList(const MCInst *MI, unsigned OpNum,
Reg = FirstReg;
else if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::qsub0))
Reg = FirstReg;
+ else if (unsigned FirstReg = MRI.getSubReg(Reg, AArch64::zsub0))
+ Reg = FirstReg;
// If it's a D-reg, we need to promote it to the equivalent Q-reg before
// printing (otherwise getRegisterName fails).
@@ -1169,7 +1206,11 @@ void AArch64InstPrinter::printVectorList(const MCInst *MI, unsigned OpNum,
}
for (unsigned i = 0; i < NumRegs; ++i, Reg = getNextVectorRegister(Reg)) {
- O << getRegisterName(Reg, AArch64::vreg) << LayoutSuffix;
+ if (MRI.getRegClass(AArch64::ZPRRegClassID).contains(Reg))
+ O << getRegisterName(Reg) << LayoutSuffix;
+ else
+ O << getRegisterName(Reg, AArch64::vreg) << LayoutSuffix;
+
if (i + 1 != NumRegs)
O << ", ";
}