diff options
| author | Sander de Smalen <sander.desmalen@arm.com> | 2018-07-03 15:31:04 +0000 |
|---|---|---|
| committer | Sander de Smalen <sander.desmalen@arm.com> | 2018-07-03 15:31:04 +0000 |
| commit | 8cd1f533340e1b6f3b93577795e874fea9b6a31e (patch) | |
| tree | a3759ea508cb6bc98c587c24a1dee32aedd0b586 /llvm/lib/Target/AArch64 | |
| parent | cbd224941fb3662f305c24de224ae0003d2a3b2d (diff) | |
| download | bcm5719-llvm-8cd1f533340e1b6f3b93577795e874fea9b6a31e.tar.gz bcm5719-llvm-8cd1f533340e1b6f3b93577795e874fea9b6a31e.zip | |
[AArch64][SVE] Asm: Support for FMUL (indexed)
Unpredicated FP-multiply of SVE vector with a vector-element given by
vector[index], for example:
fmul z0.s, z1.s, z2.s[0]
which performs an unpredicated FP-multiply of all 32-bit elements in
'z1' with the first element from 'z2'.
This patch adds restricted register classes for SVE vectors:
ZPR_3b (only z0..z7 are allowed) - for indexed vector of 16/32-bit elements.
ZPR_4b (only z0..z15 are allowed) - for indexed vector of 64-bit elements.
Reviewers: rengolin, fhahn, SjoerdMeijer, samparker, javed.absar
Reviewed By: fhahn
Differential Revision: https://reviews.llvm.org/D48823
llvm-svn: 336205
Diffstat (limited to 'llvm/lib/Target/AArch64')
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterInfo.td | 44 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 20 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp | 22 | ||||
| -rw-r--r-- | llvm/lib/Target/AArch64/SVEInstrFormats.td | 39 |
5 files changed, 125 insertions, 3 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index 182451ceeb0..b2bc642f864 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -835,12 +835,34 @@ def ZPR : RegisterClass<"AArch64", let Size = 128; } -class ZPRAsmOperand <string name, int Width>: AsmOperandClass { +// SVE restricted 4 bit scalable vector register class +def ZPR_4b : RegisterClass<"AArch64", + [nxv16i8, nxv8i16, nxv4i32, nxv2i64, + nxv2f16, nxv4f16, nxv8f16, + nxv1f32, nxv2f32, nxv4f32, + nxv1f64, nxv2f64], + 128, (sequence "Z%u", 0, 15)> { + let Size = 128; +} + +// SVE restricted 3 bit scalable vector register class +def ZPR_3b : RegisterClass<"AArch64", + [nxv16i8, nxv8i16, nxv4i32, nxv2i64, + nxv2f16, nxv4f16, nxv8f16, + nxv1f32, nxv2f32, nxv4f32, + nxv1f64, nxv2f64], + 128, (sequence "Z%u", 0, 7)> { + let Size = 128; +} + +class ZPRAsmOperand<string name, int Width, string RegClassSuffix = ""> + : AsmOperandClass { let Name = "SVE" # name # "Reg"; let PredicateMethod = "isSVEDataVectorRegOfWidth<" - # Width # ", AArch64::ZPRRegClassID>"; + # Width # ", AArch64::ZPR" + # RegClassSuffix # "RegClassID>"; let RenderMethod = "addRegOperands"; - let DiagnosticType = "InvalidZPR" # Width; + let DiagnosticType = "InvalidZPR" # RegClassSuffix # Width; let ParserMethod = "tryParseSVEDataVector<false, " # !if(!eq(Width, 0), "false", "true") # ">"; } @@ -859,6 +881,22 @@ def ZPR32 : ZPRRegOp<"s", ZPRAsmOp32, ZPR>; def ZPR64 : ZPRRegOp<"d", ZPRAsmOp64, ZPR>; def ZPR128 : ZPRRegOp<"q", ZPRAsmOp128, ZPR>; +def ZPRAsmOp3b8 : ZPRAsmOperand<"Vector3bB", 8, "_3b">; +def ZPRAsmOp3b16 : ZPRAsmOperand<"Vector3bH", 16, "_3b">; +def ZPRAsmOp3b32 : ZPRAsmOperand<"Vector3bS", 32, "_3b">; + +def ZPR3b8 : ZPRRegOp<"b", ZPRAsmOp3b8, ZPR_3b>; +def ZPR3b16 : ZPRRegOp<"h", ZPRAsmOp3b16, ZPR_3b>; +def ZPR3b32 : ZPRRegOp<"s", ZPRAsmOp3b32, ZPR_3b>; + +def ZPRAsmOp4b16 : ZPRAsmOperand<"Vector4bH", 16, "_4b">; +def ZPRAsmOp4b32 : ZPRAsmOperand<"Vector4bS", 32, "_4b">; +def ZPRAsmOp4b64 : ZPRAsmOperand<"Vector4bD", 64, "_4b">; + +def ZPR4b16 : ZPRRegOp<"h", ZPRAsmOp4b16, ZPR_4b>; +def ZPR4b32 : ZPRRegOp<"s", ZPRAsmOp4b32, ZPR_4b>; +def ZPR4b64 : ZPRRegOp<"d", ZPRAsmOp4b64, ZPR_4b>; + class FPRasZPR<int Width> : AsmOperandClass{ let Name = "FPR" # Width # "asZPR"; let PredicateMethod = "isFPRasZPR<AArch64::FPR" # Width # "RegClassID>"; diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 76f114bc820..ee075d0eaa9 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -56,6 +56,9 @@ let Predicates = [HasSVE] in { defm FMUL_ZPmI : sve_fp_2op_i_p_zds<0b010, "fmul", sve_fpimm_half_two>; defm FMAX_ZPmI : sve_fp_2op_i_p_zds<0b110, "fmax", sve_fpimm_zero_one>; + + defm FMUL_ZZZI : sve_fp_fmul_by_indexed_elem<"fmul">; + // Splat immediate (unpredicated) defm DUP_ZI : sve_int_dup_imm<"dup">; defm FDUP_ZI : sve_int_dup_fpimm<"fdup">; diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 37c27fe67eb..61a8205efd5 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -953,6 +953,8 @@ public: RegKind RK; switch (Class) { case AArch64::ZPRRegClassID: + case AArch64::ZPR_3bRegClassID: + case AArch64::ZPR_4bRegClassID: RK = RegKind::SVEDataVector; break; case AArch64::PPRRegClassID: @@ -4093,6 +4095,18 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, case Match_InvalidZPR64: case Match_InvalidZPR128: return Error(Loc, "invalid element width"); + case Match_InvalidZPR_3b8: + return Error(Loc, "Invalid restricted vector register, expected z0.b..z7.b"); + case Match_InvalidZPR_3b16: + return Error(Loc, "Invalid restricted vector register, expected z0.h..z7.h"); + case Match_InvalidZPR_3b32: + return Error(Loc, "Invalid restricted vector register, expected z0.s..z7.s"); + case Match_InvalidZPR_4b16: + return Error(Loc, "Invalid restricted vector register, expected z0.h..z15.h"); + case Match_InvalidZPR_4b32: + return Error(Loc, "Invalid restricted vector register, expected z0.s..z15.s"); + case Match_InvalidZPR_4b64: + return Error(Loc, "Invalid restricted vector register, expected z0.d..z15.d"); case Match_InvalidSVEPattern: return Error(Loc, "invalid predicate pattern"); case Match_InvalidSVEPredicateAnyReg: @@ -4600,6 +4614,12 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidZPR32: case Match_InvalidZPR64: case Match_InvalidZPR128: + case Match_InvalidZPR_3b8: + case Match_InvalidZPR_3b16: + case Match_InvalidZPR_3b32: + case Match_InvalidZPR_4b16: + case Match_InvalidZPR_4b32: + case Match_InvalidZPR_4b64: case Match_InvalidSVEPredicateAnyReg: case Match_InvalidSVEPattern: case Match_InvalidSVEPredicateBReg: diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index 6fb8ba0f3f6..b2b542bc944 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -91,6 +91,12 @@ static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo, static DecodeStatus DecodeZPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decode); +static DecodeStatus DecodeZPR_4bRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decode); +static DecodeStatus DecodeZPR_3bRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decode); static DecodeStatus DecodeZPR2RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decode); @@ -499,6 +505,22 @@ static DecodeStatus DecodeZPRRegisterClass(MCInst &Inst, unsigned RegNo, return Success; } +static DecodeStatus DecodeZPR_4bRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 15) + return Fail; + return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder); +} + +static DecodeStatus DecodeZPR_3bRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 7) + return Fail; + return DecodeZPRRegisterClass(Inst, RegNo, Address, Decoder); +} + static const unsigned ZZDecoderTable[] = { AArch64::Z0_Z1, AArch64::Z1_Z2, AArch64::Z2_Z3, AArch64::Z3_Z4, AArch64::Z4_Z5, AArch64::Z5_Z6, AArch64::Z6_Z7, AArch64::Z7_Z8, diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index f780ef01a9e..27b1885a4a0 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -781,6 +781,45 @@ multiclass sve_fp_2op_i_p_zds<bits<3> opc, string asm, Operand imm_ty> { def _D : sve_fp_2op_i_p_zds<0b11, opc, asm, ZPR64, imm_ty>; } +//===----------------------------------------------------------------------===// +// SVE Floating Point Multiply - Indexed Group +//===----------------------------------------------------------------------===// + +class sve_fp_fmul_by_indexed_elem<bits<2> sz, string asm, ZPRRegOp zprty, + ZPRRegOp zprty2, Operand itype> +: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty2:$Zm, itype:$iop), + asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> { + bits<5> Zd; + bits<5> Zn; + let Inst{31-24} = 0b01100100; + let Inst{23-22} = sz; + let Inst{21} = 0b1; + let Inst{15-10} = 0b001000; + let Inst{9-5} = Zn; + let Inst{4-0} = Zd; +} + +multiclass sve_fp_fmul_by_indexed_elem<string asm> { + def _H : sve_fp_fmul_by_indexed_elem<{0, ?}, asm, ZPR16, ZPR3b16, VectorIndexH> { + bits<3> Zm; + bits<3> iop; + let Inst{22} = iop{2}; + let Inst{20-19} = iop{1-0}; + let Inst{18-16} = Zm; + } + def _S : sve_fp_fmul_by_indexed_elem<0b10, asm, ZPR32, ZPR3b32, VectorIndexS> { + bits<3> Zm; + bits<2> iop; + let Inst{20-19} = iop; + let Inst{18-16} = Zm; + } + def _D : sve_fp_fmul_by_indexed_elem<0b11, asm, ZPR64, ZPR4b64, VectorIndexD> { + bits<4> Zm; + bit iop; + let Inst{20} = iop; + let Inst{19-16} = Zm; + } +} //===----------------------------------------------------------------------===// // SVE Stack Allocation Group |

