summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64
diff options
context:
space:
mode:
authorSander de Smalen <sander.desmalen@arm.com>2018-07-03 15:31:04 +0000
committerSander de Smalen <sander.desmalen@arm.com>2018-07-03 15:31:04 +0000
commit8cd1f533340e1b6f3b93577795e874fea9b6a31e (patch)
treea3759ea508cb6bc98c587c24a1dee32aedd0b586 /llvm/lib/Target/AArch64
parentcbd224941fb3662f305c24de224ae0003d2a3b2d (diff)
downloadbcm5719-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.td44
-rw-r--r--llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td3
-rw-r--r--llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp20
-rw-r--r--llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp22
-rw-r--r--llvm/lib/Target/AArch64/SVEInstrFormats.td39
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
OpenPOWER on IntegriCloud