summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AArch64/AArch64RegisterInfo.td24
-rw-r--r--llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td6
-rw-r--r--llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp9
-rw-r--r--llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp24
-rw-r--r--llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp1
-rw-r--r--llvm/lib/Target/AArch64/SVEInstrFormats.td42
6 files changed, 102 insertions, 4 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index a4e9b4426d6..1e320be16d4 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -841,6 +841,14 @@ def ZPR128 : ZPRRegOp<"q", ZPRAsmOp128, ZPR>;
let Namespace = "AArch64" in {
def zsub0 : SubRegIndex<128, -1>;
+ def zsub1 : SubRegIndex<128, -1>;
+}
+
+// Pairs, triples, and quads of SVE vector registers.
+def ZSeqPairs : RegisterTuples<[zsub0, zsub1], [(rotl ZPR, 0), (rotl ZPR, 1)]>;
+
+def ZPR2 : RegisterClass<"AArch64", [untyped], 128, (add ZSeqPairs)> {
+ let Size = 256;
}
class ZPRVectorList<int ElementWidth, int NumRegs> : AsmOperandClass {
@@ -866,3 +874,19 @@ def Z_s : RegisterOperand<ZPR, "printTypedVectorList<0,'s'>"> {
def Z_d : RegisterOperand<ZPR, "printTypedVectorList<0,'d'>"> {
let ParserMatchClass = ZPRVectorList<64, 1>;
}
+
+def ZZ_b : RegisterOperand<ZPR2, "printTypedVectorList<0,'b'>"> {
+ let ParserMatchClass = ZPRVectorList<8, 2>;
+}
+
+def ZZ_h : RegisterOperand<ZPR2, "printTypedVectorList<0,'h'>"> {
+ let ParserMatchClass = ZPRVectorList<16, 2>;
+}
+
+def ZZ_s : RegisterOperand<ZPR2, "printTypedVectorList<0,'s'>"> {
+ let ParserMatchClass = ZPRVectorList<32, 2>;
+}
+
+def ZZ_d : RegisterOperand<ZPR2, "printTypedVectorList<0,'d'>"> {
+ let ParserMatchClass = ZPRVectorList<64, 2>;
+}
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index b3bed53762d..0406c52e872 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -38,6 +38,12 @@ let Predicates = [HasSVE] in {
defm LD1SB_H_IMM : sve_mem_cld_si<0b1110, "ld1sb", Z_h, ZPR16>;
defm LD1D_IMM : sve_mem_cld_si<0b1111, "ld1d", Z_d, ZPR64>;
+ // LD(2|3|4) structured loads with reg+immediate
+ defm LD2B_IMM : sve_mem_eld_si<0b00, 0b01, ZZ_b, "ld2b", simm4Scale2MulVl>;
+ defm LD2H_IMM : sve_mem_eld_si<0b01, 0b01, ZZ_h, "ld2h", simm4Scale2MulVl>;
+ defm LD2W_IMM : sve_mem_eld_si<0b10, 0b01, ZZ_s, "ld2w", simm4Scale2MulVl>;
+ defm LD2D_IMM : sve_mem_eld_si<0b11, 0b01, ZZ_d, "ld2d", simm4Scale2MulVl>;
+
// continuous store with immediates
defm ST1B_IMM : sve_mem_cst_si<0b00, 0b00, "st1b", Z_b, ZPR8>;
defm ST1B_H_IMM : sve_mem_cst_si<0b00, 0b01, "st1b", Z_h, ZPR16>;
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 787c035df10..b3b3f0672bf 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -1154,11 +1154,11 @@ public:
AArch64::Q0, AArch64::Q0_Q1,
AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
/* ZReg */ { AArch64::Z0,
- AArch64::Z0 }
+ AArch64::Z0, AArch64::Z0_Z1 }
};
- assert((RegTy != VecListIdx_ZReg || NumRegs <= 1) &&
- " NumRegs must be 0 or 1 for ZRegs");
+ assert((RegTy != VecListIdx_ZReg || NumRegs <= 2) &&
+ " NumRegs must be <= 2 for ZRegs");
unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
Inst.addOperand(MCOperand::createReg(FirstReg + getVectorListStart() -
@@ -3647,6 +3647,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
return Error(Loc, "index must be an integer in range [-16, 15].");
case Match_InvalidMemoryIndexed1SImm4:
return Error(Loc, "index must be an integer in range [-8, 7].");
+ case Match_InvalidMemoryIndexed2SImm4:
+ return Error(Loc, "index must be a multiple of 2 in range [-16, 14].");
case Match_InvalidMemoryIndexedSImm9:
return Error(Loc, "index must be an integer in range [-256, 255].");
case Match_InvalidMemoryIndexedSImm10:
@@ -4162,6 +4164,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidMemoryXExtend64:
case Match_InvalidMemoryXExtend128:
case Match_InvalidMemoryIndexed1SImm4:
+ case Match_InvalidMemoryIndexed2SImm4:
case Match_InvalidMemoryIndexed4SImm7:
case Match_InvalidMemoryIndexed8SImm7:
case Match_InvalidMemoryIndexed16SImm7:
diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index b4a554e0658..19783d3f9d3 100644
--- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -88,6 +88,9 @@ static DecodeStatus DecodeDDDDRegisterClass(MCInst &Inst, unsigned RegNo,
static DecodeStatus DecodeZPRRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decode);
+static DecodeStatus DecodeZPR2RegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t Address,
+ const void *Decode);
static DecodeStatus DecodePPRRegisterClass(MCInst &Inst, unsigned RegNo,
uint64_t Address,
const void *Decode);
@@ -471,6 +474,27 @@ static DecodeStatus DecodeZPRRegisterClass(MCInst &Inst, unsigned RegNo,
return Success;
}
+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,
+ AArch64::Z8_Z9, AArch64::Z9_Z10, AArch64::Z10_Z11, AArch64::Z11_Z12,
+ AArch64::Z12_Z13, AArch64::Z13_Z14, AArch64::Z14_Z15, AArch64::Z15_Z16,
+ AArch64::Z16_Z17, AArch64::Z17_Z18, AArch64::Z18_Z19, AArch64::Z19_Z20,
+ AArch64::Z20_Z21, AArch64::Z21_Z22, AArch64::Z22_Z23, AArch64::Z23_Z24,
+ AArch64::Z24_Z25, AArch64::Z25_Z26, AArch64::Z26_Z27, AArch64::Z27_Z28,
+ AArch64::Z28_Z29, AArch64::Z29_Z30, AArch64::Z30_Z31, AArch64::Z31_Z0
+};
+
+static DecodeStatus DecodeZPR2RegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t Address,
+ const void* Decoder) {
+ if (RegNo > 31)
+ return Fail;
+ unsigned Register = ZZDecoderTable[RegNo];
+ Inst.addOperand(MCOperand::createReg(Register));
+ return Success;
+}
+
static const unsigned PPRDecoderTable[] = {
AArch64::P0, AArch64::P1, AArch64::P2, AArch64::P3,
AArch64::P4, AArch64::P5, AArch64::P6, AArch64::P7,
diff --git a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
index 4e39b963227..b36ce3ad2e9 100644
--- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
+++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp
@@ -1180,6 +1180,7 @@ void AArch64InstPrinter::printVectorList(const MCInst *MI, unsigned OpNum,
// list).
unsigned NumRegs = 1;
if (MRI.getRegClass(AArch64::DDRegClassID).contains(Reg) ||
+ MRI.getRegClass(AArch64::ZPR2RegClassID).contains(Reg) ||
MRI.getRegClass(AArch64::QQRegClassID).contains(Reg))
NumRegs = 2;
else if (MRI.getRegClass(AArch64::DDDRegClassID).contains(Reg) ||
diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index 95af6682941..a21a7dc090c 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -36,12 +36,21 @@ class SImmMulVlOperand<int Bits, int Scale> : AsmOperandClass {
}
def SImm4MulVlOperand : SImmMulVlOperand<4,1>;
+def SImm4Scale2MulVlOperand : SImmMulVlOperand<4,2>;
def simm4MulVl : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -8 && Imm < 8; }]> {
let DecoderMethod = "DecodeSImm<4>";
let ParserMatchClass = SImm4MulVlOperand;
}
+def simm4Scale2MulVl : Operand<i64>, ImmLeaf<i64, [{
+ return (Imm >= -16 && Imm <= 14) && ((Imm % 2) == 0x0);
+ }]> {
+ let DecoderMethod = "DecodeSImm<4>";
+ let PrintMethod = "printImmScale<2>";
+ let ParserMatchClass = SImm4Scale2MulVlOperand;
+}
+
class SVELogicalImmOperand<int Width> : AsmOperandClass {
let Name = "SVELogicalImm" # Width;
let DiagnosticType = "LogicalSecondSource";
@@ -618,4 +627,35 @@ multiclass sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
multiclass sve_mem_cld_si<bits<4> dtype, string asm, RegisterOperand listty,
ZPRRegOp zprty>
-: sve_mem_cld_si_base<dtype, 0, asm, listty, zprty>; \ No newline at end of file
+: sve_mem_cld_si_base<dtype, 0, asm, listty, zprty>;
+
+class sve_mem_eld_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
+ string asm, Operand immtype>
+: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
+ asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
+ "",
+ []>, Sched<[]> {
+ bits<5> Zt;
+ bits<3> Pg;
+ bits<5> Rn;
+ bits<4> imm4;
+ let Inst{31-25} = 0b1010010;
+ let Inst{24-23} = sz;
+ let Inst{22-21} = nregs;
+ let Inst{20} = 0;
+ let Inst{19-16} = imm4;
+ let Inst{15-13} = 0b111;
+ let Inst{12-10} = Pg;
+ let Inst{9-5} = Rn;
+ let Inst{4-0} = Zt;
+
+ let mayLoad = 1;
+}
+
+multiclass sve_mem_eld_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
+ string asm, Operand immtype> {
+ def NAME : sve_mem_eld_si<sz, nregs, VecList, asm, immtype>;
+
+ def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
+ (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
+}
OpenPOWER on IntegriCloud