diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index e35d49bbd41d..95c01c7198ae 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -257,6 +257,7 @@ def am_indexed7s128 : ComplexPattern; class AsmImmRange : AsmOperandClass { let Name = "Imm" # Low # "_" # High; let DiagnosticType = "InvalidImm" # Low # "_" # High; + let PredicateMethod = "isImmInRange<" # Low # "," # High # ">"; } def Imm1_8Operand : AsmImmRange<1, 8>; @@ -500,7 +501,8 @@ def imm0_65535 : Operand, ImmLeaf; + def imm0_255 : Operand, ImmLeaf { @@ -1166,11 +1168,12 @@ def am_tbrcond : Operand { // AsmOperand classes to emit (or not) special diagnostics def TBZImm0_31Operand : AsmOperandClass { let Name = "TBZImm0_31"; - let PredicateMethod = "isImm0_31"; + let PredicateMethod = "isImmInRange<0,31>"; let RenderMethod = "addImm0_31Operands"; } def TBZImm32_63Operand : AsmOperandClass { let Name = "Imm32_63"; + let PredicateMethod = "isImmInRange<32,63>"; let DiagnosticType = "InvalidImm0_63"; } diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index b86a283b40d4..3ed3c880631d 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -537,154 +537,15 @@ public: return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000; } - bool isImm0_1() const { + template + bool isImmInRange() const { if (!isImm()) return false; const MCConstantExpr *MCE = dyn_cast(getImm()); if (!MCE) return false; int64_t Val = MCE->getValue(); - return (Val >= 0 && Val < 2); - } - - bool isImm0_7() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 0 && Val < 8); - } - - bool isImm1_8() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val > 0 && Val < 9); - } - - bool isImm0_15() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 0 && Val < 16); - } - - bool isImm1_16() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val > 0 && Val < 17); - } - - bool isImm0_31() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 0 && Val < 32); - } - - bool isImm1_31() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 1 && Val < 32); - } - - bool isImm1_32() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 1 && Val < 33); - } - - bool isImm0_63() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 0 && Val < 64); - } - - bool isImm1_63() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 1 && Val < 64); - } - - bool isImm1_64() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 1 && Val < 65); - } - - bool isImm0_127() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 0 && Val < 128); - } - - bool isImm0_255() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 0 && Val < 256); - } - - bool isImm0_65535() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 0 && Val < 65536); - } - - bool isImm32_63() const { - if (!isImm()) - return false; - const MCConstantExpr *MCE = dyn_cast(getImm()); - if (!MCE) - return false; - int64_t Val = MCE->getValue(); - return (Val >= 32 && Val < 64); + return (Val >= N && Val <= M); } bool isLogicalImm32() const { @@ -3696,6 +3557,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode) { return Error(Loc, "immediate must be an integer in range [0, 63]."); case Match_InvalidImm0_127: return Error(Loc, "immediate must be an integer in range [0, 127]."); + case Match_InvalidImm0_255: + return Error(Loc, "immediate must be an integer in range [0, 255]."); case Match_InvalidImm0_65535: return Error(Loc, "immediate must be an integer in range [0, 65535]."); case Match_InvalidImm1_8: @@ -4120,6 +3983,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidImm0_31: case Match_InvalidImm0_63: case Match_InvalidImm0_127: + case Match_InvalidImm0_255: case Match_InvalidImm0_65535: case Match_InvalidImm1_8: case Match_InvalidImm1_16: diff --git a/llvm/test/MC/AArch64/neon-diagnostics.s b/llvm/test/MC/AArch64/neon-diagnostics.s index a51243dfb344..1172903b0342 100644 --- a/llvm/test/MC/AArch64/neon-diagnostics.s +++ b/llvm/test/MC/AArch64/neon-diagnostics.s @@ -81,7 +81,7 @@ // CHECK-ERROR: error: invalid operand for instruction // CHECK-ERROR: and v0.8b, v1.16b, v2.8b // CHECK-ERROR: ^ -// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: error: immediate must be an integer in range [0, 255] // CHECK-ERROR: orr v0.4h, v1.4h, v2.4h // CHECK-ERROR: ^ // CHECK-ERROR: error: invalid operand for instruction @@ -152,10 +152,10 @@ // invalid vector type (2s, 4s, 4h, 8h) movi v5.8b, #1, lsl #8 -// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: error: immediate must be an integer in range [0, 255] // CHECK-ERROR: movi v0.2s, #-1 // CHECK-ERROR: ^ -// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: error: immediate must be an integer in range [0, 255] // CHECK-ERROR: mvni v1.4s, #256 // CHECK-ERROR: ^ // CHECK-ERROR: error: invalid operand for instruction @@ -183,10 +183,10 @@ // invalid vector type (2s, 4s) movi v5.4h, #31, msl #8 -// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: error: immediate must be an integer in range [0, 255] // CHECK-ERROR: movi v0.2s, #-1, msl #8 // CHECK-ERROR: ^ -// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: error: immediate must be an integer in range [0, 255] // CHECK-ERROR: mvni v7.4s, #256, msl #16 // CHECK-ERROR: ^ // CHECK-ERROR: error: invalid operand for instruction @@ -206,10 +206,10 @@ movi v0.8b, #-1 movi v1.16b, #256 -// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: error: immediate must be an integer in range [0, 255] // CHECK-ERROR: movi v0.8b, #-1 // CHECK-ERROR: ^ -// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: error: immediate must be an integer in range [0, 255] // CHECK-ERROR: movi v1.16b, #256 // CHECK-ERROR: ^