From 9f0017c23cc174ff81af4205300a5570eb6bb21c Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Fri, 13 Apr 2018 12:56:14 +0000 Subject: [PATCH] [AArch64][SVE] Asm: Support for contiguous ST1 (scalar+imm) store instructions. Summary: Added instructions for contiguous stores, ST1, with scalar+imm addressing modes and corresponding tests. The patch also adds parsing of 'mul vl' as needed for the VL-scaled immediate. This is patch [6/6] in a series to add assembler/disassembler support for SVE's contiguous ST1 (scalar+imm) instructions. Reviewers: fhahn, rengolin, javed.absar, huntergr, SjoerdMeijer, t.p.northover, echristo, evandro Reviewed By: rengolin Subscribers: tschuett, llvm-commits, kristof.beyls Differential Revision: https://reviews.llvm.org/D45432 llvm-svn: 330014 --- lib/Target/AArch64/AArch64SVEInstrInfo.td | 13 +++ .../AArch64/AsmParser/AArch64AsmParser.cpp | 40 ++++++- lib/Target/AArch64/SVEInstrFormats.td | 55 +++++++++ test/MC/AArch64/SVE/st1b-diagnostics.s | 85 ++++++++++++++ test/MC/AArch64/SVE/st1b.s | 104 ++++++++++++++++++ test/MC/AArch64/SVE/st1d-diagnostics.s | 41 +++++++ test/MC/AArch64/SVE/st1d.s | 32 ++++++ test/MC/AArch64/SVE/st1h-diagnostics.s | 70 ++++++++++++ test/MC/AArch64/SVE/st1h.s | 80 ++++++++++++++ test/MC/AArch64/SVE/st1w-diagnostics.s | 58 ++++++++++ test/MC/AArch64/SVE/st1w.s | 56 ++++++++++ 11 files changed, 633 insertions(+), 1 deletion(-) create mode 100644 test/MC/AArch64/SVE/st1b-diagnostics.s create mode 100644 test/MC/AArch64/SVE/st1b.s create mode 100644 test/MC/AArch64/SVE/st1d-diagnostics.s create mode 100644 test/MC/AArch64/SVE/st1d.s create mode 100644 test/MC/AArch64/SVE/st1h-diagnostics.s create mode 100644 test/MC/AArch64/SVE/st1h.s create mode 100644 test/MC/AArch64/SVE/st1w-diagnostics.s create mode 100644 test/MC/AArch64/SVE/st1w.s diff --git a/lib/Target/AArch64/AArch64SVEInstrInfo.td b/lib/Target/AArch64/AArch64SVEInstrInfo.td index 1d60c7bff2f..6a13003ab02 100644 --- a/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -20,6 +20,19 @@ let Predicates = [HasSVE] in { defm ADD_ZPmZ : sve_int_bin_pred_arit_0<0b000, "add">; defm SUB_ZPmZ : sve_int_bin_pred_arit_0<0b001, "sub">; + + // 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>; + defm ST1B_S_IMM : sve_mem_cst_si<0b00, 0b10, "st1b", Z_s, ZPR32>; + defm ST1B_D_IMM : sve_mem_cst_si<0b00, 0b11, "st1b", Z_d, ZPR64>; + defm ST1H_IMM : sve_mem_cst_si<0b01, 0b01, "st1h", Z_h, ZPR16>; + defm ST1H_S_IMM : sve_mem_cst_si<0b01, 0b10, "st1h", Z_s, ZPR32>; + defm ST1H_D_IMM : sve_mem_cst_si<0b01, 0b11, "st1h", Z_d, ZPR64>; + defm ST1W_IMM : sve_mem_cst_si<0b10, 0b10, "st1w", Z_s, ZPR32>; + defm ST1W_D_IMM : sve_mem_cst_si<0b10, 0b11, "st1w", Z_d, ZPR64>; + defm ST1D_IMM : sve_mem_cst_si<0b11, 0b11, "st1d", Z_d, ZPR64>; + defm ZIP1_ZZZ : sve_int_perm_bin_perm_zz<0b000, "zip1">; defm ZIP2_ZZZ : sve_int_perm_bin_perm_zz<0b001, "zip2">; diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index d21881fd99c..787c035df10 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -89,6 +89,7 @@ private: bool parseRegister(OperandVector &Operands); bool parseSymbolicImmVal(const MCExpr *&ImmVal); bool parseNeonVectorList(OperandVector &Operands); + bool parseOptionalMulVl(OperandVector &Operands); bool parseOperand(OperandVector &Operands, bool isCondCode, bool invertCondCode); @@ -1371,6 +1372,13 @@ public: Inst.addOperand(MCOperand::createImm(MCE->getValue())); } + template + void addImmScaledOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + const MCConstantExpr *MCE = cast(getImm()); + Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale)); + } + template void addLogicalImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); @@ -3049,6 +3057,29 @@ AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) { return MatchOperand_Success; } +bool AArch64AsmParser::parseOptionalMulVl(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); + + // Some SVE instructions have a decoration after the immediate, i.e. + // "mul vl". We parse them here and add tokens, which must be present in the + // asm string in the tablegen instruction. + if (!Parser.getTok().getString().equals_lower("mul") || + !Parser.getLexer().peekTok().getString().equals_lower("vl")) + return true; + + SMLoc S = getLoc(); + Operands.push_back( + AArch64Operand::CreateToken("mul", false, S, getContext())); + Parser.Lex(); // Eat the "mul" + + S = getLoc(); + Operands.push_back( + AArch64Operand::CreateToken("vl", false, S, getContext())); + Parser.Lex(); // Eat the "vl" + + return false; +} + /// parseOperand - Parse a arm instruction operand. For now this parses the /// operand regardless of the mnemonic. bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, @@ -3102,6 +3133,10 @@ bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode, if (!parseRegister(Operands)) return false; + // See if this is a "mul vl" decoration used by SVE instructions. + if (!parseOptionalMulVl(Operands)) + return false; + // This could be an optional "shift" or "extend" operand. OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands); // We can only continue if no tokens were eaten. @@ -3610,6 +3645,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, return Error(Loc, "index must be an integer in range [-32, 31]."); case Match_InvalidMemoryIndexedSImm5: 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_InvalidMemoryIndexedSImm9: return Error(Loc, "index must be an integer in range [-256, 255]."); case Match_InvalidMemoryIndexedSImm10: @@ -4124,10 +4161,11 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidMemoryXExtend32: case Match_InvalidMemoryXExtend64: case Match_InvalidMemoryXExtend128: - case Match_InvalidMemoryIndexedSImm6: + case Match_InvalidMemoryIndexed1SImm4: case Match_InvalidMemoryIndexed4SImm7: case Match_InvalidMemoryIndexed8SImm7: case Match_InvalidMemoryIndexed16SImm7: + case Match_InvalidMemoryIndexedSImm6: case Match_InvalidMemoryIndexedSImm5: case Match_InvalidMemoryIndexedSImm9: case Match_InvalidMemoryIndexedSImm10: diff --git a/lib/Target/AArch64/SVEInstrFormats.td b/lib/Target/AArch64/SVEInstrFormats.td index 3b69d3a143c..73e79559e7c 100644 --- a/lib/Target/AArch64/SVEInstrFormats.td +++ b/lib/Target/AArch64/SVEInstrFormats.td @@ -27,6 +27,21 @@ def sve_pred_enum : Operand, ImmLeaf : AsmOperandClass { + let Name = "SImm" # Bits # "Scale" # Scale # "MulVl"; + let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Bits; + let PredicateMethod = "isSImmScaled<" # Bits # ", " # Scale # ">"; + let RenderMethod = "addImmScaledOperands<" # Scale # ">"; +} + +def SImm4MulVlOperand : SImmMulVlOperand<4,1>; + +def simm4MulVl : Operand, ImmLeaf= -8 && Imm < 8; }]> { + let DecoderMethod = "DecodeSImm<4>"; + let ParserMatchClass = SImm4MulVlOperand; +} + class SVELogicalImmOperand : AsmOperandClass { let Name = "SVELogicalImm" # Width; let DiagnosticType = "LogicalSecondSource"; @@ -489,6 +504,46 @@ multiclass sve_int_bin_cons_shift_b_right opc, string asm> { let Inst{20-19} = imm{4-3}; } } +//===----------------------------------------------------------------------===// +// SVE Memory - Store Group +//===----------------------------------------------------------------------===// + +class sve_mem_cst_si msz, bits<2> esz, string asm, + RegisterOperand VecList> +: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4MulVl:$imm4), + asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]", + "", + []>, Sched<[]> { + bits<3> Pg; + bits<5> Rn; + bits<5> Zt; + bits<4> imm4; + let Inst{31-25} = 0b1110010; + let Inst{24-23} = msz; + let Inst{22-21} = esz; + 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 mayStore = 1; +} + +multiclass sve_mem_cst_si msz, bits<2> esz, string asm, + RegisterOperand listty, ZPRRegOp zprty> +{ + def NAME : sve_mem_cst_si; + + def : InstAlias(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4MulVl:$imm4), 0>; + def : InstAlias(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>; + def : InstAlias(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>; +} + //===----------------------------------------------------------------------===// // SVE Permute - Predicates Group //===----------------------------------------------------------------------===// diff --git a/test/MC/AArch64/SVE/st1b-diagnostics.s b/test/MC/AArch64/SVE/st1b-diagnostics.s new file mode 100644 index 00000000000..89964cd245d --- /dev/null +++ b/test/MC/AArch64/SVE/st1b-diagnostics.s @@ -0,0 +1,85 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Immediate out of upper bound [-8, 7]. + +st1b z10.b, p4, [x8, #-9, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1b z10.b, p4, [x8, #-9, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b z18.b, p4, [x24, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1b z18.b, p4, [x24, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b z11.h, p0, [x23, #-9, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1b z11.h, p0, [x23, #-9, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b z24.h, p3, [x1, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1b z24.h, p3, [x1, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b z6.s, p5, [x23, #-9, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1b z6.s, p5, [x23, #-9, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b z16.s, p6, [x14, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1b z16.s, p6, [x14, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b z26.d, p2, [x7, #-9, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1b z26.d, p2, [x7, #-9, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b z27.d, p1, [x12, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1b z27.d, p1, [x12, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Restricted predicate has range [0, 7]. + +st1b z12.b, p8, [x27, #6, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: st1b z12.b, p8, [x27, #6, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b z23.h, p8, [x20, #1, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: st1b z23.h, p8, [x20, #1, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b z6.s, p8, [x0, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: st1b z6.s, p8, [x0, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b z14.d, p8, [x6, #5, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: st1b z14.d, p8, [x6, #5, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector list + +st1b { }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector register expected +// CHECK-NEXT: st1b { }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b { z1.b, z2.b }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand +// CHECK-NEXT: st1b { z1.b, z2.b }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1b { v0.16b }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand +// CHECK-NEXT: st1b { v0.16b }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/st1b.s b/test/MC/AArch64/SVE/st1b.s new file mode 100644 index 00000000000..3d22f673217 --- /dev/null +++ b/test/MC/AArch64/SVE/st1b.s @@ -0,0 +1,104 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +st1b z0.b, p0, [x0] +// CHECK-INST: st1b { z0.b }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x00,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 00 e4 + +st1b z0.h, p0, [x0] +// CHECK-INST: st1b { z0.h }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x20,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 20 e4 + +st1b z0.s, p0, [x0] +// CHECK-INST: st1b { z0.s }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x40,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 40 e4 + +st1b z0.d, p0, [x0] +// CHECK-INST: st1b { z0.d }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x60,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 60 e4 + +st1b { z0.b }, p0, [x0] +// CHECK-INST: st1b { z0.b }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x00,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 00 e4 + +st1b { z0.h }, p0, [x0] +// CHECK-INST: st1b { z0.h }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x20,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 20 e4 + +st1b { z0.s }, p0, [x0] +// CHECK-INST: st1b { z0.s }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x40,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 40 e4 + +st1b { z0.d }, p0, [x0] +// CHECK-INST: st1b { z0.d }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x60,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 60 e4 + +st1b { z31.b }, p7, [sp, #-1, mul vl] +// CHECK-INST: st1b { z31.b }, p7, [sp, #-1, mul vl] +// CHECK-ENCODING: [0xff,0xff,0x0f,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff 0f e4 + +st1b { z21.b }, p5, [x10, #5, mul vl] +// CHECK-INST: st1b { z21.b }, p5, [x10, #5, mul vl] +// CHECK-ENCODING: [0x55,0xf5,0x05,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 55 f5 05 e4 + +st1b { z31.h }, p7, [sp, #-1, mul vl] +// CHECK-INST: st1b { z31.h }, p7, [sp, #-1, mul vl] +// CHECK-ENCODING: [0xff,0xff,0x2f,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff 2f e4 + +st1b { z21.h }, p5, [x10, #5, mul vl] +// CHECK-INST: st1b { z21.h }, p5, [x10, #5, mul vl] +// CHECK-ENCODING: [0x55,0xf5,0x25,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 55 f5 25 e4 + +st1b { z31.s }, p7, [sp, #-1, mul vl] +// CHECK-INST: st1b { z31.s }, p7, [sp, #-1, mul vl] +// CHECK-ENCODING: [0xff,0xff,0x4f,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff 4f e4 + +st1b { z21.s }, p5, [x10, #5, mul vl] +// CHECK-INST: st1b { z21.s }, p5, [x10, #5, mul vl] +// CHECK-ENCODING: [0x55,0xf5,0x45,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 55 f5 45 e4 + +st1b { z31.d }, p7, [sp, #-1, mul vl] +// CHECK-INST: st1b { z31.d }, p7, [sp, #-1, mul vl] +// CHECK-ENCODING: [0xff,0xff,0x6f,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff 6f e4 + +st1b { z21.d }, p5, [x10, #5, mul vl] +// CHECK-INST: st1b { z21.d }, p5, [x10, #5, mul vl] +// CHECK-ENCODING: [0x55,0xf5,0x65,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 55 f5 65 e4 diff --git a/test/MC/AArch64/SVE/st1d-diagnostics.s b/test/MC/AArch64/SVE/st1d-diagnostics.s new file mode 100644 index 00000000000..be4e8ee0558 --- /dev/null +++ b/test/MC/AArch64/SVE/st1d-diagnostics.s @@ -0,0 +1,41 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Immediate out of lower bound [-8, 7]. + +st1d z25.d, p4, [x16, #-9, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1d z25.d, p4, [x16, #-9, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// Immediate out of upper bound [-8, 7]. +st1d z16.d, p4, [x2, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1d z16.d, p4, [x2, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Restricted predicate has range [0, 7]. + +st1d z12.d, p8, [x4, #14, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: st1d z12.d, p8, [x4, #14, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector list + +st1d { }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector register expected +// CHECK-NEXT: st1d { }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1d { z1.d, z2.d }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand +// CHECK-NEXT: st1d { z1.d, z2.d }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1d { v0.2d }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand +// CHECK-NEXT: st1d { v0.2d }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/st1d.s b/test/MC/AArch64/SVE/st1d.s new file mode 100644 index 00000000000..0cc130e70c5 --- /dev/null +++ b/test/MC/AArch64/SVE/st1d.s @@ -0,0 +1,32 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +st1d z0.d, p0, [x0] +// CHECK-INST: st1d { z0.d }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0xe0,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 e0 e5 + +st1d { z0.d }, p0, [x0] +// CHECK-INST: st1d { z0.d }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0xe0,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 e0 e5 + +st1d { z31.d }, p7, [sp, #-1, mul vl] +// CHECK-INST: st1d { z31.d }, p7, [sp, #-1, mul vl] +// CHECK-ENCODING: [0xff,0xff,0xef,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff ef e5 + +st1d { z21.d }, p5, [x10, #5, mul vl] +// CHECK-INST: st1d { z21.d }, p5, [x10, #5, mul vl] +// CHECK-ENCODING: [0x55,0xf5,0xe5,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 55 f5 e5 e5 diff --git a/test/MC/AArch64/SVE/st1h-diagnostics.s b/test/MC/AArch64/SVE/st1h-diagnostics.s new file mode 100644 index 00000000000..63bdd57ce84 --- /dev/null +++ b/test/MC/AArch64/SVE/st1h-diagnostics.s @@ -0,0 +1,70 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Immediate out of upper bound [-8, 7]. + +st1h z29.h, p5, [x7, #-9, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1h z29.h, p5, [x7, #-9, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1h z29.h, p5, [x4, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1h z29.h, p5, [x4, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1h z21.s, p2, [x1, #-9, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1h z21.s, p2, [x1, #-9, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1h z17.s, p5, [x1, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1h z17.s, p5, [x1, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1h z0.d, p1, [x14, #-9, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1h z0.d, p1, [x14, #-9, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1h z24.d, p3, [x16, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1h z24.d, p3, [x16, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Restricted predicate has range [0, 7]. + +st1h z15.h, p8, [x0, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: st1h z15.h, p8, [x0, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1h z17.s, p8, [x20, #2, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: st1h z17.s, p8, [x20, #2, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1h z15.d, p8, [x0, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: st1h z15.d, p8, [x0, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector list + +st1h { }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector register expected +// CHECK-NEXT: st1h { }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1h { z1.h, z2.h }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand +// CHECK-NEXT: st1h { z1.h, z2.h }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1h { v0.8h }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand +// CHECK-NEXT: st1h { v0.8h }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/st1h.s b/test/MC/AArch64/SVE/st1h.s new file mode 100644 index 00000000000..615a3e08da5 --- /dev/null +++ b/test/MC/AArch64/SVE/st1h.s @@ -0,0 +1,80 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +st1h z0.h, p0, [x0] +// CHECK-INST: st1h { z0.h }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0xa0,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 a0 e4 + +st1h z0.s, p0, [x0] +// CHECK-INST: st1h { z0.s }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0xc0,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 c0 e4 + +st1h z0.d, p0, [x0] +// CHECK-INST: st1h { z0.d }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0xe0,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 e0 e4 + +st1h { z0.h }, p0, [x0] +// CHECK-INST: st1h { z0.h }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0xa0,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 a0 e4 + +st1h { z0.s }, p0, [x0] +// CHECK-INST: st1h { z0.s }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0xc0,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 c0 e4 + +st1h { z0.d }, p0, [x0] +// CHECK-INST: st1h { z0.d }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0xe0,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 e0 e4 + +st1h { z31.h }, p7, [sp, #-1, mul vl] +// CHECK-INST: st1h { z31.h }, p7, [sp, #-1, mul vl] +// CHECK-ENCODING: [0xff,0xff,0xaf,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff af e4 + +st1h { z21.h }, p5, [x10, #5, mul vl] +// CHECK-INST: st1h { z21.h }, p5, [x10, #5, mul vl] +// CHECK-ENCODING: [0x55,0xf5,0xa5,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 55 f5 a5 e4 + +st1h { z31.s }, p7, [sp, #-1, mul vl] +// CHECK-INST: st1h { z31.s }, p7, [sp, #-1, mul vl] +// CHECK-ENCODING: [0xff,0xff,0xcf,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff cf e4 + +st1h { z21.s }, p5, [x10, #5, mul vl] +// CHECK-INST: st1h { z21.s }, p5, [x10, #5, mul vl] +// CHECK-ENCODING: [0x55,0xf5,0xc5,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 55 f5 c5 e4 + +st1h { z21.d }, p5, [x10, #5, mul vl] +// CHECK-INST: st1h { z21.d }, p5, [x10, #5, mul vl] +// CHECK-ENCODING: [0x55,0xf5,0xe5,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 55 f5 e5 e4 + +st1h { z31.d }, p7, [sp, #-1, mul vl] +// CHECK-INST: st1h { z31.d }, p7, [sp, #-1, mul vl] +// CHECK-ENCODING: [0xff,0xff,0xef,0xe4] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff ef e4 diff --git a/test/MC/AArch64/SVE/st1w-diagnostics.s b/test/MC/AArch64/SVE/st1w-diagnostics.s new file mode 100644 index 00000000000..a224849144f --- /dev/null +++ b/test/MC/AArch64/SVE/st1w-diagnostics.s @@ -0,0 +1,58 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Immediate out of lower bound [-8, 7]. + +st1w z19.s, p2, [x18, #-9, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1w z19.s, p2, [x18, #-9, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// Immediate out of upper bound [-8, 7]. +st1w z1.s, p5, [x23, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1w z1.s, p5, [x23, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// Immediate out of lower bound [-8, 7]. +st1w z21.d, p2, [x29, #-9, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1w z21.d, p2, [x29, #-9, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// Immediate out of upper bound [-8, 7]. +st1w z10.d, p5, [x26, #8, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be an integer in range [-8, 7]. +// CHECK-NEXT: st1w z10.d, p5, [x26, #8, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Restricted predicate has range [0, 7]. + +st1w z1.s, p8, [x3, #1, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: st1w z1.s, p8, [x3, #1, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1w z12.d, p8, [x26, #3, MUL VL] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: st1w z12.d, p8, [x26, #3, MUL VL] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector list + +st1w { }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector register expected +// CHECK-NEXT: st1w { }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1w { z1.s, z2.s }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand +// CHECK-NEXT: st1w { z1.s, z2.s }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +st1w { v0.4s }, p0, [x0] +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand +// CHECK-NEXT: st1w { v0.4s }, p0, [x0] +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/st1w.s b/test/MC/AArch64/SVE/st1w.s new file mode 100644 index 00000000000..b64ebcf2963 --- /dev/null +++ b/test/MC/AArch64/SVE/st1w.s @@ -0,0 +1,56 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +st1w z0.s, p0, [x0] +// CHECK-INST: st1w { z0.s }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x40,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 40 e5 + +st1w z0.d, p0, [x0] +// CHECK-INST: st1w { z0.d }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x60,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 60 e5 + +st1w { z0.s }, p0, [x0] +// CHECK-INST: st1w { z0.s }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x40,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 40 e5 + +st1w { z0.d }, p0, [x0] +// CHECK-INST: st1w { z0.d }, p0, [x0] +// CHECK-ENCODING: [0x00,0xe0,0x60,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 60 e5 + +st1w { z31.s }, p7, [sp, #-1, mul vl] +// CHECK-INST: st1w { z31.s }, p7, [sp, #-1, mul vl] +// CHECK-ENCODING: [0xff,0xff,0x4f,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff 4f e5 + +st1w { z21.s }, p5, [x10, #5, mul vl] +// CHECK-INST: st1w { z21.s }, p5, [x10, #5, mul vl] +// CHECK-ENCODING: [0x55,0xf5,0x45,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 55 f5 45 e5 + +st1w { z31.d }, p7, [sp, #-1, mul vl] +// CHECK-INST: st1w { z31.d }, p7, [sp, #-1, mul vl] +// CHECK-ENCODING: [0xff,0xff,0x6f,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff 6f e5 + +st1w { z21.d }, p5, [x10, #5, mul vl] +// CHECK-INST: st1w { z21.d }, p5, [x10, #5, mul vl] +// CHECK-ENCODING: [0x55,0xf5,0x65,0xe5] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 55 f5 65 e5