Index: lib/Target/AArch64/AArch64SVEInstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64SVEInstrInfo.td +++ lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -20,6 +20,9 @@ defm ADD_ZPmZ : sve_int_bin_pred_arit_0<0b000, "add">; defm SUB_ZPmZ : sve_int_bin_pred_arit_0<0b001, "sub">; + defm ADD_ZI : sve_int_arith_imm0<0b000, "add">; + defm SUB_ZI : sve_int_arith_imm0<0b001, "sub">; + // Splat immediate (unpredicated) defm DUP_ZI : sve_int_dup_imm<"dup">; Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -687,7 +687,7 @@ || ELFRefKind == AArch64MCExpr::VK_SECREL_LO12; } - // If it's a constant, it should be a real immediate in range: + // If it's a constant, it should be a real immediate in range. if (auto ShiftedVal = getShiftedVal<12>()) return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff; @@ -700,20 +700,11 @@ if (!isShiftedImm() && !isImm()) return false; - const MCExpr *Expr; - - // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'. - if (isShiftedImm()) { - unsigned Shift = ShiftedImm.ShiftAmount; - Expr = ShiftedImm.Val; - if (Shift != 0 && Shift != 12) - return false; - } else - Expr = getImm(); + // Otherwise it should be a real negative immediate in range. + if (auto ShiftedVal = getShiftedVal<12>()) + return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff; - // Otherwise it should be a real negative immediate in range: - const MCConstantExpr *CE = dyn_cast(Expr); - return CE != nullptr && CE->getValue() < 0 && -CE->getValue() <= 0xfff; + return false; } // Signed value in the range -128 to +127. For element widths of @@ -736,6 +727,24 @@ return DiagnosticPredicateTy::NearMatch; } + // Unsigned value in the range 0 to 255. For element widths of + // 16 bits or higher it may also be a signed multiple of 256 in the + // range 0 to 65280. + template DiagnosticPredicate isSVEAddSubImm() const { + if (!isShiftedImm() && (!isImm() || !isa(getImm()))) + return DiagnosticPredicateTy::NoMatch; + + bool IsByte = + std::is_same::type>::value; + if (auto ShiftedImm = getShiftedVal<8>()) + if (!(IsByte && ShiftedImm->second) && + AArch64_AM::isSVEAddSubImm(ShiftedImm->first + << ShiftedImm->second)) + return DiagnosticPredicateTy::Match; + + return DiagnosticPredicateTy::NearMatch; + } + bool isCondCode() const { return Kind == k_CondCode; } bool isSIMDImmType10() const { @@ -3801,6 +3810,14 @@ return Error(Loc, "immediate must be an integer in range [1, 32]."); case Match_InvalidImm1_64: return Error(Loc, "immediate must be an integer in range [1, 64]."); + case Match_InvalidSVEAddSubImm8: + return Error(Loc, "immediate must be an integer in range [0, 255]" + " with a shift amount of 0"); + case Match_InvalidSVEAddSubImm16: + case Match_InvalidSVEAddSubImm32: + case Match_InvalidSVEAddSubImm64: + return Error(Loc, "immediate must be an integer in range [0, 255] or a " + "multiple of 256 in range [256, 65280]"); case Match_InvalidSVECpyImm8: return Error(Loc, "immediate must be an integer in range [-128, 255]" " with a shift amount of 0"); @@ -4337,6 +4354,10 @@ case Match_InvalidImm1_16: case Match_InvalidImm1_32: case Match_InvalidImm1_64: + case Match_InvalidSVEAddSubImm8: + case Match_InvalidSVEAddSubImm16: + case Match_InvalidSVEAddSubImm32: + case Match_InvalidSVEAddSubImm64: case Match_InvalidSVECpyImm8: case Match_InvalidSVECpyImm16: case Match_InvalidSVECpyImm32: Index: lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h +++ lib/Target/AArch64/MCTargetDesc/AArch64AddressingModes.h @@ -772,8 +772,14 @@ return uint8_t(Imm) == Imm || int8_t(Imm) == Imm; else return int8_t(Imm) == Imm || int16_t(Imm & ~0xff) == Imm; +} - llvm_unreachable("Unsupported element width"); +/// Returns true if Imm is valid for ADD/SUB. +template +static inline bool isSVEAddSubImm(int64_t Imm) { + bool IsInt8t = + std::is_same::type>::value; + return uint8_t(Imm) == Imm || (!IsInt8t && uint16_t(Imm & ~0xff) == Imm); } inline static bool isAnyMOVZMovAlias(uint64_t Value, int RegWidth) { Index: lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- lib/Target/AArch64/SVEInstrFormats.td +++ lib/Target/AArch64/SVEInstrFormats.td @@ -117,6 +117,11 @@ def SVECpyImmOperand32 : SVEShiftedImmOperand<32, "Cpy", "isSVECpyImm">; def SVECpyImmOperand64 : SVEShiftedImmOperand<64, "Cpy", "isSVECpyImm">; +def SVEAddSubImmOperand8 : SVEShiftedImmOperand<8, "AddSub", "isSVEAddSubImm">; +def SVEAddSubImmOperand16 : SVEShiftedImmOperand<16, "AddSub", "isSVEAddSubImm">; +def SVEAddSubImmOperand32 : SVEShiftedImmOperand<32, "AddSub", "isSVEAddSubImm">; +def SVEAddSubImmOperand64 : SVEShiftedImmOperand<64, "AddSub", "isSVEAddSubImm">; + class imm8_opt_lsl : Operand, ImmLeaf { @@ -140,6 +145,19 @@ return AArch64_AM::isSVECpyImm(Imm); }]>; +def addsub_imm8_opt_lsl_i8 : imm8_opt_lsl<8, "uint8_t", SVEAddSubImmOperand8, [{ + return AArch64_AM::isSVEAddSubImm(Imm); +}]>; +def addsub_imm8_opt_lsl_i16 : imm8_opt_lsl<16, "uint16_t", SVEAddSubImmOperand16, [{ + return AArch64_AM::isSVEAddSubImm(Imm); +}]>; +def addsub_imm8_opt_lsl_i32 : imm8_opt_lsl<32, "uint32_t", SVEAddSubImmOperand32, [{ + return AArch64_AM::isSVEAddSubImm(Imm); +}]>; +def addsub_imm8_opt_lsl_i64 : imm8_opt_lsl<64, "uint64_t", SVEAddSubImmOperand64, [{ + return AArch64_AM::isSVEAddSubImm(Imm); +}]>; + //===----------------------------------------------------------------------===// // SVE PTrue - These are used extensively throughout the pattern matching so // it's important we define them first. @@ -425,6 +443,33 @@ (!cast(NAME # _D) ZPR64:$Zd, cpy_imm8_opt_lsl_i64:$imm), 1>; } +class sve_int_arith_imm0 sz8_64, bits<3> opc, string asm, + ZPRRegOp zprty, Operand immtype> +: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm), + asm, "\t$Zdn, $_Zdn, $imm", + "", + []>, Sched<[]> { + bits<5> Zdn; + bits<9> imm; + let Inst{31-24} = 0b00100101; + let Inst{23-22} = sz8_64; + let Inst{21-19} = 0b100; + let Inst{18-16} = opc; + let Inst{15-14} = 0b11; + let Inst{13} = imm{8}; // sh + let Inst{12-5} = imm{7-0}; // imm8 + let Inst{4-0} = Zdn; + + let Constraints = "$Zdn = $_Zdn"; +} + +multiclass sve_int_arith_imm0 opc, string asm> { + def _B : sve_int_arith_imm0<0b00, opc, asm, ZPR8, addsub_imm8_opt_lsl_i8>; + def _H : sve_int_arith_imm0<0b01, opc, asm, ZPR16, addsub_imm8_opt_lsl_i16>; + def _S : sve_int_arith_imm0<0b10, opc, asm, ZPR32, addsub_imm8_opt_lsl_i32>; + def _D : sve_int_arith_imm0<0b11, opc, asm, ZPR64, addsub_imm8_opt_lsl_i64>; +} + //===----------------------------------------------------------------------===// //SVE Index Generation Group //===----------------------------------------------------------------------===// Index: test/MC/AArch64/SVE/add-diagnostics.s =================================================================== --- test/MC/AArch64/SVE/add-diagnostics.s +++ test/MC/AArch64/SVE/add-diagnostics.s @@ -75,3 +75,72 @@ // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register // CHECK-NEXT: add z9.d, p4/m, z10.d, z7.d // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// --------------------------------------------------------------------------// +// Invalid immediates + +add z0.b, z0.b, #0, lsl #8 // #0, lsl #8 is not valid for .b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0 +// CHECK-NEXT: add z0.b, z0.b, #0, lsl #8 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.b, z0.b, #-1 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0 +// CHECK-NEXT: add z0.b, z0.b, #-1 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.b, z0.b, #1, lsl #8 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0 +// CHECK-NEXT: add z0.b, z0.b, #1, lsl #8 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.b, z0.b, #256 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0 +// CHECK-NEXT: add z0.b, z0.b, #256 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.h, z0.h, #-1 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: add z0.h, z0.h, #-1 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.h, z0.h, #256, lsl #8 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: add z0.h, z0.h, #256, lsl #8 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.h, z0.h, #65536 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: add z0.h, z0.h, #65536 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.s, z0.s, #-1 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: add z0.s, z0.s, #-1 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.s, z0.s, #256, lsl #8 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: add z0.s, z0.s, #256, lsl #8 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.s, z0.s, #65536 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: add z0.s, z0.s, #65536 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.d, z0.d, #-1 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: add z0.d, z0.d, #-1 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.d, z0.d, #256, lsl #8 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: add z0.d, z0.d, #256, lsl #8 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +add z0.d, z0.d, #65536 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: add z0.d, z0.d, #65536 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: Index: test/MC/AArch64/SVE/add.s =================================================================== --- test/MC/AArch64/SVE/add.s +++ test/MC/AArch64/SVE/add.s @@ -198,3 +198,88 @@ // CHECK-ENCODING: [0xb7,0x01,0xa8,0x04] // CHECK-ERROR: instruction requires: sve // CHECK-UNKNOWN: b7 01 a8 04 + +add z0.b, z0.b, #0 +// CHECK-INST: add z0.b, z0.b, #0 +// CHECK-ENCODING: [0x00,0xc0,0x20,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 c0 20 25 + +add z31.b, z31.b, #255 +// CHECK-INST: add z31.b, z31.b, #255 +// CHECK-ENCODING: [0xff,0xdf,0x20,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff df 20 25 + +add z0.h, z0.h, #0 +// CHECK-INST: add z0.h, z0.h, #0 +// CHECK-ENCODING: [0x00,0xc0,0x60,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 c0 60 25 + +add z0.h, z0.h, #0, lsl #8 +// CHECK-INST: add z0.h, z0.h, #0, lsl #8 +// CHECK-ENCODING: [0x00,0xe0,0x60,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 60 25 + +add z31.h, z31.h, #255, lsl #8 +// CHECK-INST: add z31.h, z31.h, #65280 +// CHECK-ENCODING: [0xff,0xff,0x60,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff 60 25 + +add z31.h, z31.h, #65280 +// CHECK-INST: add z31.h, z31.h, #65280 +// CHECK-ENCODING: [0xff,0xff,0x60,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff 60 25 + +add z0.s, z0.s, #0 +// CHECK-INST: add z0.s, z0.s, #0 +// CHECK-ENCODING: [0x00,0xc0,0xa0,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 c0 a0 25 + +add z0.s, z0.s, #0, lsl #8 +// CHECK-INST: add z0.s, z0.s, #0, lsl #8 +// CHECK-ENCODING: [0x00,0xe0,0xa0,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 a0 25 + +add z31.s, z31.s, #255, lsl #8 +// CHECK-INST: add z31.s, z31.s, #65280 +// CHECK-ENCODING: [0xff,0xff,0xa0,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff a0 25 + +add z31.s, z31.s, #65280 +// CHECK-INST: add z31.s, z31.s, #65280 +// CHECK-ENCODING: [0xff,0xff,0xa0,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff a0 25 + +add z0.d, z0.d, #0 +// CHECK-INST: add z0.d, z0.d, #0 +// CHECK-ENCODING: [0x00,0xc0,0xe0,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 c0 e0 25 + +add z0.d, z0.d, #0, lsl #8 +// CHECK-INST: add z0.d, z0.d, #0, lsl #8 +// CHECK-ENCODING: [0x00,0xe0,0xe0,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 e0 25 + +add z31.d, z31.d, #255, lsl #8 +// CHECK-INST: add z31.d, z31.d, #65280 +// CHECK-ENCODING: [0xff,0xff,0xe0,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff e0 25 + +add z31.d, z31.d, #65280 +// CHECK-INST: add z31.d, z31.d, #65280 +// CHECK-ENCODING: [0xff,0xff,0xe0,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff e0 25 + Index: test/MC/AArch64/SVE/sub-diagnostics.s =================================================================== --- test/MC/AArch64/SVE/sub-diagnostics.s +++ test/MC/AArch64/SVE/sub-diagnostics.s @@ -75,3 +75,72 @@ // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register // CHECK-NEXT: sub z2.d, p5/m, z3.d, z11.d // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// --------------------------------------------------------------------------// +// Invalid immediates + +sub z0.b, z0.b, #0, lsl #8 // #0, lsl #8 is not valid for .b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0 +// CHECK-NEXT: sub z0.b, z0.b, #0, lsl #8 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.b, z0.b, #-1 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0 +// CHECK-NEXT: sub z0.b, z0.b, #-1 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.b, z0.b, #1, lsl #8 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0 +// CHECK-NEXT: sub z0.b, z0.b, #1, lsl #8 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.b, z0.b, #256 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0 +// CHECK-NEXT: sub z0.b, z0.b, #256 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.h, z0.h, #-1 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: sub z0.h, z0.h, #-1 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.h, z0.h, #256, lsl #8 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: sub z0.h, z0.h, #256, lsl #8 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.h, z0.h, #65536 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: sub z0.h, z0.h, #65536 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.s, z0.s, #-1 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: sub z0.s, z0.s, #-1 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.s, z0.s, #256, lsl #8 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: sub z0.s, z0.s, #256, lsl #8 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.s, z0.s, #65536 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: sub z0.s, z0.s, #65536 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.d, z0.d, #-1 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: sub z0.d, z0.d, #-1 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.d, z0.d, #256, lsl #8 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: sub z0.d, z0.d, #256, lsl #8 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sub z0.d, z0.d, #65536 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280] +// CHECK-NEXT: sub z0.d, z0.d, #65536 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: Index: test/MC/AArch64/SVE/sub.s =================================================================== --- test/MC/AArch64/SVE/sub.s +++ test/MC/AArch64/SVE/sub.s @@ -198,3 +198,91 @@ // CHECK-ENCODING: [0xb7,0x0d,0x01,0x04] // CHECK-ERROR: instruction requires: sve // CHECK-UNKNOWN: b7 0d 01 04 + +// ----------------------- +// + +sub z0.b, z0.b, #0 +// CHECK-INST: sub z0.b, z0.b, #0 +// CHECK-ENCODING: [0x00,0xc0,0x21,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 c0 21 25 + +sub z31.b, z31.b, #255 +// CHECK-INST: sub z31.b, z31.b, #255 +// CHECK-ENCODING: [0xff,0xdf,0x21,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff df 21 25 + +sub z0.h, z0.h, #0 +// CHECK-INST: sub z0.h, z0.h, #0 +// CHECK-ENCODING: [0x00,0xc0,0x61,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 c0 61 25 + +sub z0.h, z0.h, #0, lsl #8 +// CHECK-INST: sub z0.h, z0.h, #0, lsl #8 +// CHECK-ENCODING: [0x00,0xe0,0x61,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 61 25 + +sub z31.h, z31.h, #255, lsl #8 +// CHECK-INST: sub z31.h, z31.h, #65280 +// CHECK-ENCODING: [0xff,0xff,0x61,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff 61 25 + +sub z31.h, z31.h, #65280 +// CHECK-INST: sub z31.h, z31.h, #65280 +// CHECK-ENCODING: [0xff,0xff,0x61,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff 61 25 + +sub z0.s, z0.s, #0 +// CHECK-INST: sub z0.s, z0.s, #0 +// CHECK-ENCODING: [0x00,0xc0,0xa1,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 c0 a1 25 + +sub z0.s, z0.s, #0, lsl #8 +// CHECK-INST: sub z0.s, z0.s, #0, lsl #8 +// CHECK-ENCODING: [0x00,0xe0,0xa1,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 a1 25 + +sub z31.s, z31.s, #255, lsl #8 +// CHECK-INST: sub z31.s, z31.s, #65280 +// CHECK-ENCODING: [0xff,0xff,0xa1,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff a1 25 + +sub z31.s, z31.s, #65280 +// CHECK-INST: sub z31.s, z31.s, #65280 +// CHECK-ENCODING: [0xff,0xff,0xa1,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff a1 25 + +sub z0.d, z0.d, #0 +// CHECK-INST: sub z0.d, z0.d, #0 +// CHECK-ENCODING: [0x00,0xc0,0xe1,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 c0 e1 25 + +sub z0.d, z0.d, #0, lsl #8 +// CHECK-INST: sub z0.d, z0.d, #0, lsl #8 +// CHECK-ENCODING: [0x00,0xe0,0xe1,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 00 e0 e1 25 + +sub z31.d, z31.d, #255, lsl #8 +// CHECK-INST: sub z31.d, z31.d, #65280 +// CHECK-ENCODING: [0xff,0xff,0xe1,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff e1 25 + +sub z31.d, z31.d, #65280 +// CHECK-INST: sub z31.d, z31.d, #65280 +// CHECK-ENCODING: [0xff,0xff,0xe1,0x25] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: ff ff e1 25 + Index: test/MC/AArch64/alias-addsubimm.s =================================================================== --- test/MC/AArch64/alias-addsubimm.s +++ test/MC/AArch64/alias-addsubimm.s @@ -1,6 +1,16 @@ // RUN: llvm-mc -triple=aarch64-none-linux-gnu < %s | FileCheck %s // RUN: not llvm-mc -mattr=+no-neg-immediates -triple=aarch64-none-linux-gnu < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-NEG-IMM + add w0, w2, #4096 + sub w0, w2, #4096 +// CHECK: add w0, w2, #1, lsl #12 +// CHECK: sub w0, w2, #1, lsl #12 + + add w0, w2, #-4096 + sub w0, w2, #-4096 +// CHECK: sub w0, w2, #1, lsl #12 +// CHECK: add w0, w2, #1, lsl #12 + // CHECK: sub w0, w2, #2, lsl #12 // CHECK: sub w0, w2, #2, lsl #12 // CHECK-NO-NEG-IMM: instruction requires: NegativeImmediates Index: test/MC/AArch64/basic-a64-diagnostics.s =================================================================== --- test/MC/AArch64/basic-a64-diagnostics.s +++ test/MC/AArch64/basic-a64-diagnostics.s @@ -76,12 +76,12 @@ //------------------------------------------------------------------------------ // Out of range immediates: more than 12 bits - add w4, w5, #-4096 + add w4, w5, #-4097 add w5, w6, #0x1000 add w4, w5, #-4096, lsl #12 add w5, w6, #0x1000, lsl #12 // CHECK-ERROR: error: expected compatible register, symbol or integer in range [0, 4095] -// CHECK-ERROR-NEXT: add w4, w5, #-4096 +// CHECK-ERROR-NEXT: add w4, w5, #-4097 // CHECK-ERROR-NEXT: ^ // CHECK-ERROR-AARCH64-NEXT: error: expected compatible register, symbol or integer in range [0, 4095] // CHECK-ERROR-AARCH64-NEXT: add w5, w6, #0x1000