[AArch64][SVE] Asm: Print indexed element 0 as FPR.
Print the first indexed element as a FP register, for example:
mov z0.d, z1.d[0]
Is now printed as:
mov z0.d, d1
Next to printing, this patch also adds aliases to parse 'mov z0.d, d1'.
Reviewers: rengolin, fhahn, samparker, SjoerdMeijer, javed.absar
Reviewed By: fhahn
Differential Revision: https://reviews.llvm.org/D47571
llvm-svn: 333872
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index 7acdb69..182451c 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -859,6 +859,22 @@
def ZPR64 : ZPRRegOp<"d", ZPRAsmOp64, ZPR>;
def ZPR128 : ZPRRegOp<"q", ZPRAsmOp128, ZPR>;
+class FPRasZPR<int Width> : AsmOperandClass{
+ let Name = "FPR" # Width # "asZPR";
+ let PredicateMethod = "isFPRasZPR<AArch64::FPR" # Width # "RegClassID>";
+ let RenderMethod = "addFPRasZPRRegOperands<" # Width # ">";
+}
+
+class FPRasZPROperand<int Width> : RegisterOperand<ZPR> {
+ let ParserMatchClass = FPRasZPR<Width>;
+ let PrintMethod = "printZPRasFPR<" # Width # ">";
+}
+
+def FPR8asZPR : FPRasZPROperand<8>;
+def FPR16asZPR : FPRasZPROperand<16>;
+def FPR32asZPR : FPRasZPROperand<32>;
+def FPR64asZPR : FPRasZPROperand<64>;
+def FPR128asZPR : FPRasZPROperand<128>;
let Namespace = "AArch64" in {
def zsub0 : SubRegIndex<128, -1>;
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index cf22a1c..b6dd39c 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -934,6 +934,11 @@
AArch64MCRegisterClasses[Class].contains(getReg());
}
+ template <unsigned Class> bool isFPRasZPR() const {
+ return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
+ AArch64MCRegisterClasses[Class].contains(getReg());
+ }
+
template <int ElementWidth, unsigned Class>
DiagnosticPredicate isSVEPredicateVectorRegOfWidth() const {
if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateVector)
@@ -1269,6 +1274,21 @@
Inst.addOperand(MCOperand::createReg(Reg));
}
+ template <int Width>
+ void addFPRasZPRRegOperands(MCInst &Inst, unsigned N) const {
+ unsigned Base;
+ switch (Width) {
+ case 8: Base = AArch64::B0; break;
+ case 16: Base = AArch64::H0; break;
+ case 32: Base = AArch64::S0; break;
+ case 64: Base = AArch64::D0; break;
+ case 128: Base = AArch64::Q0; break;
+ default:
+ llvm_unreachable("Unsupported width");
+ }
+ Inst.addOperand(MCOperand::createReg(AArch64::Z0 + getReg() - Base));
+ }
+
void addVectorReg64Operands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
assert(
diff --git a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
index 67584d1..3d52fa1 100644
--- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
@@ -1499,3 +1499,21 @@
else
O << '#' << formatHex((uint64_t)PrintVal);
}
+
+template <int Width>
+void AArch64InstPrinter::printZPRasFPR(const MCInst *MI, unsigned OpNum,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ unsigned Base;
+ switch (Width) {
+ case 8: Base = AArch64::B0; break;
+ case 16: Base = AArch64::H0; break;
+ case 32: Base = AArch64::S0; break;
+ case 64: Base = AArch64::D0; break;
+ case 128: Base = AArch64::Q0; break;
+ default:
+ llvm_unreachable("Unsupported width");
+ }
+ unsigned Reg = MI->getOperand(OpNum).getReg();
+ O << getRegisterName(Reg - AArch64::Z0 + Base);
+}
diff --git a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
index ca10830..446a065 100644
--- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
+++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h
@@ -180,6 +180,9 @@
template <char = 0>
void printSVERegOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
+ template <int Width>
+ void printZPRasFPR(const MCInst *MI, unsigned OpNum,
+ const MCSubtargetInfo &STI, raw_ostream &O);
};
class AArch64AppleInstPrinter : public AArch64InstPrinter {
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 757bb6f..9382473 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -334,6 +334,16 @@
(!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, sve_elm_idx_extdup_d:$idx), 1>;
def : InstAlias<"mov $Zd, $Zn$idx",
(!cast<Instruction>(NAME # _Q) ZPR128:$Zd, ZPR128:$Zn, sve_elm_idx_extdup_q:$idx), 1>;
+ def : InstAlias<"mov $Zd, $Bn",
+ (!cast<Instruction>(NAME # _B) ZPR8:$Zd, FPR8asZPR:$Bn, 0), 2>;
+ def : InstAlias<"mov $Zd, $Hn",
+ (!cast<Instruction>(NAME # _H) ZPR16:$Zd, FPR16asZPR:$Hn, 0), 2>;
+ def : InstAlias<"mov $Zd, $Sn",
+ (!cast<Instruction>(NAME # _S) ZPR32:$Zd, FPR32asZPR:$Sn, 0), 2>;
+ def : InstAlias<"mov $Zd, $Dn",
+ (!cast<Instruction>(NAME # _D) ZPR64:$Zd, FPR64asZPR:$Dn, 0), 2>;
+ def : InstAlias<"mov $Zd, $Qn",
+ (!cast<Instruction>(NAME # _Q) ZPR128:$Zd, FPR128asZPR:$Qn, 0), 2>;
}
//===----------------------------------------------------------------------===//