[llvm] r336205 - [AArch64][SVE] Asm: Support for FMUL (indexed)
Sander de Smalen via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 3 08:31:05 PDT 2018
Author: s.desmalen
Date: Tue Jul 3 08:31:04 2018
New Revision: 336205
URL: http://llvm.org/viewvc/llvm-project?rev=336205&view=rev
Log:
[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
Modified:
llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td
llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td
llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td
llvm/trunk/test/MC/AArch64/SVE/fmul-diagnostics.s
llvm/trunk/test/MC/AArch64/SVE/fmul.s
Modified: llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td?rev=336205&r1=336204&r2=336205&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td Tue Jul 3 08:31:04 2018
@@ -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,
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>";
Modified: llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td?rev=336205&r1=336204&r2=336205&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64SVEInstrInfo.td Tue Jul 3 08:31:04 2018
@@ -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">;
Modified: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp?rev=336205&r1=336204&r2=336205&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp Tue Jul 3 08:31:04 2018
@@ -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(SM
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::MatchAndEmitInstr
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:
Modified: llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp?rev=336205&r1=336204&r2=336205&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp Tue Jul 3 08:31:04 2018
@@ -91,6 +91,12 @@ static DecodeStatus DecodeDDDDRegisterCl
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 DecodeZPRRegisterCla
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,
Modified: llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td?rev=336205&r1=336204&r2=336205&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td (original)
+++ llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td Tue Jul 3 08:31:04 2018
@@ -781,6 +781,45 @@ multiclass sve_fp_2op_i_p_zds<bits<3> op
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
Modified: llvm/trunk/test/MC/AArch64/SVE/fmul-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/SVE/fmul-diagnostics.s?rev=336205&r1=336204&r2=336205&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/SVE/fmul-diagnostics.s (original)
+++ llvm/trunk/test/MC/AArch64/SVE/fmul-diagnostics.s Tue Jul 3 08:31:04 2018
@@ -32,3 +32,61 @@ fmul z0.h, p0/m, z0.h, #1.99999999999999
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid floating point constant, expected 0.5 or 2.0.
// CHECK-NEXT: fmul z0.h, p0/m, z0.h, #1.9999999999999999999999999
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+
+// --------------------------------------------------------------------------//
+// Restricted ZPR range
+
+fmul z0.h, z0.h, z8.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z7.h
+// CHECK-NEXT: fmul z0.h, z0.h, z8.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmul z0.h, z0.h, z8.h[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z7.h
+// CHECK-NEXT: fmul z0.h, z0.h, z8.h[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmul z0.s, z0.s, z8.s[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.s..z7.s
+// CHECK-NEXT: fmul z0.s, z0.s, z8.s[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmul z0.d, z0.d, z16.d[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.d..z15.d
+// CHECK-NEXT: fmul z0.d, z0.d, z16.d[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+
+// --------------------------------------------------------------------------//
+// Index out of bounds
+
+fmul z0.h, z0.h, z0.h[-1]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7].
+// CHECK-NEXT: fmul z0.h, z0.h, z0.h[-1]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmul z0.h, z0.h, z0.h[8]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 7].
+// CHECK-NEXT: fmul z0.h, z0.h, z0.h[8]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmul z0.s, z0.s, z0.s[-1]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: fmul z0.s, z0.s, z0.s[-1]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmul z0.s, z0.s, z0.s[4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: fmul z0.s, z0.s, z0.s[4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmul z0.d, z0.d, z0.d[-1]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 1].
+// CHECK-NEXT: fmul z0.d, z0.d, z0.d[-1]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmul z0.d, z0.d, z0.d[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 1].
+// CHECK-NEXT: fmul z0.d, z0.d, z0.d[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
Modified: llvm/trunk/test/MC/AArch64/SVE/fmul.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AArch64/SVE/fmul.s?rev=336205&r1=336204&r2=336205&view=diff
==============================================================================
--- llvm/trunk/test/MC/AArch64/SVE/fmul.s (original)
+++ llvm/trunk/test/MC/AArch64/SVE/fmul.s Tue Jul 3 08:31:04 2018
@@ -48,3 +48,39 @@ fmul z31.d, p7/m, z31.d, #2.0
// CHECK-ENCODING: [0x3f,0x9c,0xda,0x65]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 3f 9c da 65 <unknown>
+
+fmul z0.h, z0.h, z0.h[0]
+// CHECK-INST: fmul z0.h, z0.h, z0.h[0]
+// CHECK-ENCODING: [0x00,0x20,0x20,0x64]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 00 20 20 64 <unknown>
+
+fmul z0.s, z0.s, z0.s[0]
+// CHECK-INST: fmul z0.s, z0.s, z0.s[0]
+// CHECK-ENCODING: [0x00,0x20,0xa0,0x64]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 00 20 a0 64 <unknown>
+
+fmul z0.d, z0.d, z0.d[0]
+// CHECK-INST: fmul z0.d, z0.d, z0.d[0]
+// CHECK-ENCODING: [0x00,0x20,0xe0,0x64]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 00 20 e0 64 <unknown>
+
+fmul z31.h, z31.h, z7.h[7]
+// CHECK-INST: fmul z31.h, z31.h, z7.h[7]
+// CHECK-ENCODING: [0xff,0x23,0x7f,0x64]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: ff 23 7f 64 <unknown>
+
+fmul z31.s, z31.s, z7.s[3]
+// CHECK-INST: fmul z31.s, z31.s, z7.s[3]
+// CHECK-ENCODING: [0xff,0x23,0xbf,0x64]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: ff 23 bf 64 <unknown>
+
+fmul z31.d, z31.d, z15.d[1]
+// CHECK-INST: fmul z31.d, z31.d, z15.d[1]
+// CHECK-ENCODING: [0xff,0x23,0xff,0x64]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: ff 23 ff 64 <unknown>
More information about the llvm-commits
mailing list