Index: lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- lib/Target/AArch64/AArch64InstrFormats.td +++ lib/Target/AArch64/AArch64InstrFormats.td @@ -323,6 +323,7 @@ def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>; def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>; def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>; +def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>; def simm4s1 : Operand, ImmLeaf=-8 && Imm <= 7; }]> { @@ -350,6 +351,12 @@ let ParserMatchClass = SImm4s4Operand; let DecoderMethod = "DecodeSImm<4>"; } +def simm4s16 : Operand, ImmLeaf=-128 && Imm <= 112 && (Imm % 16) == 0x0; }]> { + let PrintMethod = "printImmScale<16>"; + let ParserMatchClass = SImm4s16Operand; + let DecoderMethod = "DecodeSImm<4>"; +} class AsmImmRange : AsmOperandClass { let Name = "Imm" # Low # "_" # High; Index: lib/Target/AArch64/AArch64SVEInstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64SVEInstrInfo.td +++ lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -38,6 +38,15 @@ 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>; Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -3628,6 +3628,8 @@ 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 @@ case Match_InvalidMemoryIndexed2SImm4: case Match_InvalidMemoryIndexed3SImm4: case Match_InvalidMemoryIndexed4SImm4: + case Match_InvalidMemoryIndexed16SImm4: case Match_InvalidMemoryIndexed4SImm7: case Match_InvalidMemoryIndexed8SImm7: case Match_InvalidMemoryIndexed16SImm7: Index: lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- lib/Target/AArch64/SVEInstrFormats.td +++ lib/Target/AArch64/SVEInstrFormats.td @@ -792,6 +792,64 @@ ZPRRegOp zprty> : sve_mem_cld_si_base; +class sve_mem_ldqr_si 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 sz, string asm, RegisterOperand listty, + ZPRRegOp zprty> { + def NAME : sve_mem_ldqr_si; + def : InstAlias(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>; + def : InstAlias(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>; + def : InstAlias(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4), 0>; +} + +class sve_mem_ldqr_ss 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 sz, string asm, RegisterOperand listty, + ZPRRegOp zprty, RegisterOperand gprty> { + def NAME : sve_mem_ldqr_ss; + + def : InstAlias(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>; +} + class sve_mem_cld_ss_base dtype, bit ff, dag iops, string asm, RegisterOperand VecList> : I<(outs VecList:$Zt), iops, Index: test/MC/AArch64/SVE/ld1rqb-diagnostics.s =================================================================== --- /dev/null +++ test/MC/AArch64/SVE/ld1rqb-diagnostics.s @@ -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]+}}: Index: test/MC/AArch64/SVE/ld1rqb.s =================================================================== --- /dev/null +++ test/MC/AArch64/SVE/ld1rqb.s @@ -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 + +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 + +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 + +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 + +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 Index: test/MC/AArch64/SVE/ld1rqd-diagnostics.s =================================================================== --- /dev/null +++ test/MC/AArch64/SVE/ld1rqd-diagnostics.s @@ -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]+}}: Index: test/MC/AArch64/SVE/ld1rqd.s =================================================================== --- /dev/null +++ test/MC/AArch64/SVE/ld1rqd.s @@ -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 + +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 + +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 + +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 + +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 Index: test/MC/AArch64/SVE/ld1rqh-diagnostics.s =================================================================== --- /dev/null +++ test/MC/AArch64/SVE/ld1rqh-diagnostics.s @@ -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]+}}: Index: test/MC/AArch64/SVE/ld1rqh.s =================================================================== --- /dev/null +++ test/MC/AArch64/SVE/ld1rqh.s @@ -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 + +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 + +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 + +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 + +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 Index: test/MC/AArch64/SVE/ld1rqw-diagnostics.s =================================================================== --- /dev/null +++ test/MC/AArch64/SVE/ld1rqw-diagnostics.s @@ -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]+}}: Index: test/MC/AArch64/SVE/ld1rqw.s =================================================================== --- /dev/null +++ test/MC/AArch64/SVE/ld1rqw.s @@ -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 + +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 + +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 + +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 + +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