diff options
| author | Sander de Smalen <sander.desmalen@arm.com> | 2018-06-04 07:07:35 +0000 |
|---|---|---|
| committer | Sander de Smalen <sander.desmalen@arm.com> | 2018-06-04 07:07:35 +0000 |
| commit | fd54a781f6f62adf5c65644333d3753c2d708fbe (patch) | |
| tree | 0360457fff6a834668076d16943c738ebee57fda /llvm/lib/Target | |
| parent | c33d668ab7ed26bfaa3b040c8a59c80c70d0fec1 (diff) | |
| download | bcm5719-llvm-fd54a781f6f62adf5c65644333d3753c2d708fbe.tar.gz bcm5719-llvm-fd54a781f6f62adf5c65644333d3753c2d708fbe.zip | |
[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
Diffstat (limited to 'llvm/lib/Target')
5 files changed, 67 insertions, 0 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index 7acdb69ffb0..182451ceeb0 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -859,6 +859,22 @@ def ZPR32 : ZPRRegOp<"s", ZPRAsmOp32, ZPR>; 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 cf22a1cbadc..b6dd39c2a5d 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -934,6 +934,11 @@ public: 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 @@ public: 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 67584d1cbfe..3d52fa142ec 100644 --- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -1499,3 +1499,21 @@ void AArch64InstPrinter::printSVELogicalImm(const MCInst *MI, unsigned OpNum, 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 ca108308c71..446a065bdda 100644 --- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h @@ -180,6 +180,9 @@ protected: 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 757bb6f91dd..93824732cc5 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -334,6 +334,16 @@ multiclass sve_int_perm_dup_i<string asm> { (!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>; } //===----------------------------------------------------------------------===// |

