[AArch64][SVE] Asm: Support for LD1RQ load-and-replicate quad-word vector instructions.

Reviewers: fhahn, rengolin, samparker, SjoerdMeijer, javed.absar

Reviewed By: SjoerdMeijer

Differential Revision: https://reviews.llvm.org/D46250

llvm-svn: 331339
This commit is contained in:
Sander de Smalen 2018-05-02 08:49:08 +00:00
parent f801205e48
commit c1e44bdfc7
12 changed files with 553 additions and 0 deletions

View File

@ -323,6 +323,7 @@ def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>;
def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>;
def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>;
def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>;
def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>;
def simm4s1 : Operand<i64>, ImmLeaf<i64,
[{ return Imm >=-8 && Imm <= 7; }]> {
@ -350,6 +351,12 @@ def simm4s4 : Operand<i64>, ImmLeaf<i64,
let ParserMatchClass = SImm4s4Operand;
let DecoderMethod = "DecodeSImm<4>";
}
def simm4s16 : Operand<i64>, ImmLeaf<i64,
[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }]> {
let PrintMethod = "printImmScale<16>";
let ParserMatchClass = SImm4s16Operand;
let DecoderMethod = "DecodeSImm<4>";
}
class AsmImmRange<int Low, int High> : AsmOperandClass {
let Name = "Imm" # Low # "_" # High;

View File

@ -38,6 +38,15 @@ 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>;
defm LD1RQ_B_IMM : sve_mem_ldqr_si<0b00, "ld1rqb", Z_b, ZPR8>;
defm LD1RQ_H_IMM : sve_mem_ldqr_si<0b01, "ld1rqh", Z_h, ZPR16>;
defm LD1RQ_W_IMM : sve_mem_ldqr_si<0b10, "ld1rqw", Z_s, ZPR32>;
defm LD1RQ_D_IMM : sve_mem_ldqr_si<0b11, "ld1rqd", Z_d, ZPR64>;
defm LD1RQ_B : sve_mem_ldqr_ss<0b00, "ld1rqb", Z_b, ZPR8, GPR64NoXZRshifted8>;
defm LD1RQ_H : sve_mem_ldqr_ss<0b01, "ld1rqh", Z_h, ZPR16, GPR64NoXZRshifted16>;
defm LD1RQ_W : sve_mem_ldqr_ss<0b10, "ld1rqw", Z_s, ZPR32, GPR64NoXZRshifted32>;
defm LD1RQ_D : sve_mem_ldqr_ss<0b11, "ld1rqd", Z_d, ZPR64, GPR64NoXZRshifted64>;
// continuous load with reg+reg addressing.
defm LD1B : sve_mem_cld_ss<0b0000, "ld1b", Z_b, ZPR8, GPR64NoXZRshifted8>;
defm LD1B_H : sve_mem_cld_ss<0b0001, "ld1b", Z_h, ZPR16, GPR64NoXZRshifted8>;

View File

@ -3628,6 +3628,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
return Error(Loc, "index must be a multiple of 3 in range [-24, 21].");
case Match_InvalidMemoryIndexed4SImm4:
return Error(Loc, "index must be a multiple of 4 in range [-32, 28].");
case Match_InvalidMemoryIndexed16SImm4:
return Error(Loc, "index must be a multiple of 16 in range [-128, 112].");
case Match_InvalidMemoryIndexedSImm9:
return Error(Loc, "index must be an integer in range [-256, 255].");
case Match_InvalidMemoryIndexed8SImm10:
@ -4200,6 +4202,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_InvalidMemoryIndexed2SImm4:
case Match_InvalidMemoryIndexed3SImm4:
case Match_InvalidMemoryIndexed4SImm4:
case Match_InvalidMemoryIndexed16SImm4:
case Match_InvalidMemoryIndexed4SImm7:
case Match_InvalidMemoryIndexed8SImm7:
case Match_InvalidMemoryIndexed16SImm7:

View File

@ -666,6 +666,64 @@ multiclass sve_mem_cld_si<bits<4> dtype, string asm, RegisterOperand listty,
ZPRRegOp zprty>
: sve_mem_cld_si_base<dtype, 0, asm, listty, zprty>;
class sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand VecList>
: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4),
asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
bits<5> Zt;
bits<5> Rn;
bits<3> Pg;
bits<4> imm4;
let Inst{31-25} = 0b1010010;
let Inst{24-23} = sz;
let Inst{22-20} = 0;
let Inst{19-16} = imm4;
let Inst{15-13} = 0b001;
let Inst{12-10} = Pg;
let Inst{9-5} = Rn;
let Inst{4-0} = Zt;
let mayLoad = 1;
}
multiclass sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand listty,
ZPRRegOp zprty> {
def NAME : sve_mem_ldqr_si<sz, asm, listty>;
def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
(!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
(!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
(!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4), 0>;
}
class sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand VecList,
RegisterOperand gprty>
: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
bits<5> Zt;
bits<3> Pg;
bits<5> Rn;
bits<5> Rm;
let Inst{31-25} = 0b1010010;
let Inst{24-23} = sz;
let Inst{22-21} = 0;
let Inst{20-16} = Rm;
let Inst{15-13} = 0;
let Inst{12-10} = Pg;
let Inst{9-5} = Rn;
let Inst{4-0} = Zt;
let mayLoad = 1;
}
multiclass sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand listty,
ZPRRegOp zprty, RegisterOperand gprty> {
def NAME : sve_mem_ldqr_ss<sz, asm, listty, gprty>;
def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
(!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
}
class sve_mem_cld_ss_base<bits<4> dtype, bit ff, dag iops, string asm,
RegisterOperand VecList>
: I<(outs VecList:$Zt), iops,

View File

@ -0,0 +1,81 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
// --------------------------------------------------------------------------//
// Immediate out of lower bound [-128, 112].
ld1rqb z0.b, p0/z, [x0, #-144]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqb z0.b, p0/z, [x0, #-144]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqb z0.b, p0/z, [x0, #-129]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqb z0.b, p0/z, [x0, #-129]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqb z0.b, p0/z, [x0, #113]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqb z0.b, p0/z, [x0, #113]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqb z0.b, p0/z, [x0, #128]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqb z0.b, p0/z, [x0, #128]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqb z0.b, p0/z, [x0, #12]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqb z0.b, p0/z, [x0, #12]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid immediate suffix
ld1rqb z0.b, p0/z, [x0, #16, MUL VL]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqb z0.b, p0/z, [x0, #16, MUL VL]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid destination register width.
ld1rqb z0.h, p0/z, [x0]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqb z0.h, p0/z, [x0]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqb z0.s, p0/z, [x0]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqb z0.s, p0/z, [x0]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqb z0.d, p0/z, [x0]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqb z0.d, p0/z, [x0]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid scalar + scalar addressing modes
ld1rqb z0.b, p0/z, [x0, xzr]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 without shift
// CHECK-NEXT: ld1rqb z0.b, p0/z, [x0, xzr]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqb z0.b, p0/z, [x0, x1, lsl #1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 without shift
// CHECK-NEXT: ld1rqb z0.b, p0/z, [x0, x1, lsl #1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqb z0.b, p0/z, [x0, w1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 without shift
// CHECK-NEXT: ld1rqb z0.b, p0/z, [x0, w1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqb z0.b, p0/z, [x0, w1, uxtw]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 without shift
// CHECK-NEXT: ld1rqb z0.b, p0/z, [x0, w1, uxtw]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

View File

@ -0,0 +1,38 @@
// 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
ld1rqb { z0.b }, p0/z, [x0]
// CHECK-INST: ld1rqb { z0.b }, p0/z, [x0]
// CHECK-ENCODING: [0x00,0x20,0x00,0xa4]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 20 00 a4 <unknown>
ld1rqb { z0.b }, p0/z, [x0, x0]
// CHECK-INST: ld1rqb { z0.b }, p0/z, [x0, x0]
// CHECK-ENCODING: [0x00,0x00,0x00,0xa4]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 00 00 a4 <unknown>
ld1rqb { z31.b }, p7/z, [sp, #-16]
// CHECK-INST: ld1rqb { z31.b }, p7/z, [sp, #-16]
// CHECK-ENCODING: [0xff,0x3f,0x0f,0xa4]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff 3f 0f a4 <unknown>
ld1rqb { z23.b }, p3/z, [x13, #-128]
// CHECK-INST: ld1rqb { z23.b }, p3/z, [x13, #-128]
// CHECK-ENCODING: [0xb7,0x2d,0x08,0xa4]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: b7 2d 08 a4 <unknown>
ld1rqb { z21.b }, p5/z, [x10, #112]
// CHECK-INST: ld1rqb { z21.b }, p5/z, [x10, #112]
// CHECK-ENCODING: [0x55,0x35,0x07,0xa4]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 55 35 07 a4 <unknown>

View File

@ -0,0 +1,81 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
// --------------------------------------------------------------------------//
// Immediate out of lower bound [-128, 112].
ld1rqd z0.d, p0/z, [x0, #-144]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqd z0.d, p0/z, [x0, #-144]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqd z0.d, p0/z, [x0, #-129]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqd z0.d, p0/z, [x0, #-129]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqd z0.d, p0/z, [x0, #113]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqd z0.d, p0/z, [x0, #113]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqd z0.d, p0/z, [x0, #128]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqd z0.d, p0/z, [x0, #128]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqd z0.d, p0/z, [x0, #12]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqd z0.d, p0/z, [x0, #12]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid immediate suffix
ld1rqd z0.d, p0/z, [x0, #16, MUL VL]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqd z0.d, p0/z, [x0, #16, MUL VL]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid destination register width.
ld1rqd z0.b, p0/z, [x0, x1, lsl #3]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqd z0.b, p0/z, [x0, x1, lsl #3]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqd z0.h, p0/z, [x0, x1, lsl #3]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqd z0.h, p0/z, [x0, x1, lsl #3]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqd z0.s, p0/z, [x0, x1, lsl #3]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqd z0.s, p0/z, [x0, x1, lsl #3]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid scalar + scalar addressing modes
ld1rqd z0.d, p0/z, [x0, xzr, lsl #3]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #3'
// CHECK-NEXT: ld1rqd z0.d, p0/z, [x0, xzr, lsl #3]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqd z0.d, p0/z, [x0, x1, lsl #1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #3'
// CHECK-NEXT: ld1rqd z0.d, p0/z, [x0, x1, lsl #1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqd z0.d, p0/z, [x0, w1, lsl #3]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #3'
// CHECK-NEXT: ld1rqd z0.d, p0/z, [x0, w1, lsl #3]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqd z0.d, p0/z, [x0, w1, uxtw #1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #3'
// CHECK-NEXT: ld1rqd z0.d, p0/z, [x0, w1, uxtw #1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

View File

@ -0,0 +1,38 @@
// 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
ld1rqd { z0.d }, p0/z, [x0]
// CHECK-INST: ld1rqd { z0.d }, p0/z, [x0]
// CHECK-ENCODING: [0x00,0x20,0x80,0xa5]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 20 80 a5 <unknown>
ld1rqd { z0.d }, p0/z, [x0, x0, lsl #3]
// CHECK-INST: ld1rqd { z0.d }, p0/z, [x0, x0, lsl #3]
// CHECK-ENCODING: [0x00,0x00,0x80,0xa5]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 00 80 a5 <unknown>
ld1rqd { z31.d }, p7/z, [sp, #-16]
// CHECK-INST: ld1rqd { z31.d }, p7/z, [sp, #-16]
// CHECK-ENCODING: [0xff,0x3f,0x8f,0xa5]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff 3f 8f a5 <unknown>
ld1rqd { z23.d }, p3/z, [x13, #-128]
// CHECK-INST: ld1rqd { z23.d }, p3/z, [x13, #-128]
// CHECK-ENCODING: [0xb7,0x2d,0x88,0xa5]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: b7 2d 88 a5 <unknown>
ld1rqd { z23.d }, p3/z, [x13, #112]
// CHECK-INST: ld1rqd { z23.d }, p3/z, [x13, #112]
// CHECK-ENCODING: [0xb7,0x2d,0x87,0xa5]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: b7 2d 87 a5 <unknown>

View File

@ -0,0 +1,81 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
// --------------------------------------------------------------------------//
// Immediate out of lower bound [-128, 112].
ld1rqh z0.h, p0/z, [x0, #-144]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqh z0.h, p0/z, [x0, #-144]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqh z0.h, p0/z, [x0, #-129]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqh z0.h, p0/z, [x0, #-129]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqh z0.h, p0/z, [x0, #113]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqh z0.h, p0/z, [x0, #113]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqh z0.h, p0/z, [x0, #128]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqh z0.h, p0/z, [x0, #128]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqh z0.h, p0/z, [x0, #12]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqh z0.h, p0/z, [x0, #12]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid immediate suffix
ld1rqh z0.h, p0/z, [x0, #16, MUL VL]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqh z0.h, p0/z, [x0, #16, MUL VL]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid destination register width.
ld1rqh z0.b, p0/z, [x0, x1, lsl #1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqh z0.b, p0/z, [x0, x1, lsl #1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqh z0.s, p0/z, [x0, x1, lsl #1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqh z0.s, p0/z, [x0, x1, lsl #1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqh z0.d, p0/z, [x0, x1, lsl #1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqh z0.d, p0/z, [x0, x1, lsl #1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid scalar + scalar addressing modes
ld1rqh z0.h, p0/z, [x0, xzr, lsl #1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #1'
// CHECK-NEXT: ld1rqh z0.h, p0/z, [x0, xzr, lsl #1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqh z0.h, p0/z, [x0, x1, lsl #2]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #1'
// CHECK-NEXT: ld1rqh z0.h, p0/z, [x0, x1, lsl #2]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqh z0.h, p0/z, [x0, w1, lsl #1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #1'
// CHECK-NEXT: ld1rqh z0.h, p0/z, [x0, w1, lsl #1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqh z0.h, p0/z, [x0, w1, uxtw #1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #1'
// CHECK-NEXT: ld1rqh z0.h, p0/z, [x0, w1, uxtw #1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

View File

@ -0,0 +1,38 @@
// 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
ld1rqh { z0.h }, p0/z, [x0]
// CHECK-INST: ld1rqh { z0.h }, p0/z, [x0]
// CHECK-ENCODING: [0x00,0x20,0x80,0xa4]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 20 80 a4 <unknown>
ld1rqh { z0.h }, p0/z, [x0, x0, lsl #1]
// CHECK-INST: ld1rqh { z0.h }, p0/z, [x0, x0, lsl #1]
// CHECK-ENCODING: [0x00,0x00,0x80,0xa4]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 00 80 a4 <unknown>
ld1rqh { z31.h }, p7/z, [sp, #-16]
// CHECK-INST: ld1rqh { z31.h }, p7/z, [sp, #-16]
// CHECK-ENCODING: [0xff,0x3f,0x8f,0xa4]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff 3f 8f a4 <unknown>
ld1rqh { z23.h }, p3/z, [x13, #-128]
// CHECK-INST: ld1rqh { z23.h }, p3/z, [x13, #-128]
// CHECK-ENCODING: [0xb7,0x2d,0x88,0xa4]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: b7 2d 88 a4 <unknown>
ld1rqh { z23.h }, p3/z, [x13, #112]
// CHECK-INST: ld1rqh { z23.h }, p3/z, [x13, #112]
// CHECK-ENCODING: [0xb7,0x2d,0x87,0xa4]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: b7 2d 87 a4 <unknown>

View File

@ -0,0 +1,81 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s
// --------------------------------------------------------------------------//
// Immediate out of lower bound [-128, 112].
ld1rqw z0.s, p0/z, [x0, #-144]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqw z0.s, p0/z, [x0, #-144]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqw z0.s, p0/z, [x0, #-129]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqw z0.s, p0/z, [x0, #-129]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqw z0.s, p0/z, [x0, #113]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqw z0.s, p0/z, [x0, #113]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqw z0.s, p0/z, [x0, #128]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqw z0.s, p0/z, [x0, #128]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqw z0.s, p0/z, [x0, #12]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 16 in range [-128, 112].
// CHECK-NEXT: ld1rqw z0.s, p0/z, [x0, #12]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid immediate suffix
ld1rqw z0.s, p0/z, [x0, #16, MUL VL]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqw z0.s, p0/z, [x0, #16, MUL VL]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid destination register width.
ld1rqw z0.b, p0/z, [x0, x1, lsl #2]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqw z0.b, p0/z, [x0, x1, lsl #2]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqw z0.h, p0/z, [x0, x1, lsl #2]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqw z0.h, p0/z, [x0, x1, lsl #2]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqw z0.d, p0/z, [x0, x1, lsl #2]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: ld1rqw z0.d, p0/z, [x0, x1, lsl #2]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
// --------------------------------------------------------------------------//
// Invalid scalar + scalar addressing modes
ld1rqw z0.s, p0/z, [x0, xzr, lsl #2]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #2'
// CHECK-NEXT: ld1rqw z0.s, p0/z, [x0, xzr, lsl #2]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqw z0.s, p0/z, [x0, x1, lsl #3]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #2'
// CHECK-NEXT: ld1rqw z0.s, p0/z, [x0, x1, lsl #3]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqw z0.s, p0/z, [x0, w1, lsl #2]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #2'
// CHECK-NEXT: ld1rqw z0.s, p0/z, [x0, w1, lsl #2]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
ld1rqw z0.s, p0/z, [x0, w1, uxtw #1]
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #2'
// CHECK-NEXT: ld1rqw z0.s, p0/z, [x0, w1, uxtw #1]
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

View File

@ -0,0 +1,38 @@
// 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
ld1rqw { z0.s }, p0/z, [x0]
// CHECK-INST: ld1rqw { z0.s }, p0/z, [x0]
// CHECK-ENCODING: [0x00,0x20,0x00,0xa5]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 20 00 a5 <unknown>
ld1rqw { z0.s }, p0/z, [x0, x0, lsl #2]
// CHECK-INST: ld1rqw { z0.s }, p0/z, [x0, x0, lsl #2]
// CHECK-ENCODING: [0x00,0x00,0x00,0xa5]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 00 00 a5 <unknown>
ld1rqw { z31.s }, p7/z, [sp, #-16]
// CHECK-INST: ld1rqw { z31.s }, p7/z, [sp, #-16]
// CHECK-ENCODING: [0xff,0x3f,0x0f,0xa5]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff 3f 0f a5 <unknown>
ld1rqw { z23.s }, p3/z, [x13, #-128]
// CHECK-INST: ld1rqw { z23.s }, p3/z, [x13, #-128]
// CHECK-ENCODING: [0xb7,0x2d,0x08,0xa5]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: b7 2d 08 a5 <unknown>
ld1rqw { z23.s }, p3/z, [x13, #112]
// CHECK-INST: ld1rqw { z23.s }, p3/z, [x13, #112]
// CHECK-ENCODING: [0xb7,0x2d,0x07,0xa5]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: b7 2d 07 a5 <unknown>