Index: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td @@ -257,6 +257,7 @@ 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 @@ } // imm0_255 predicate - True if the immediate is in the range [0,255]. -def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; } +def Imm0_255Operand : AsmImmRange<0,255>; + def imm0_255 : Operand, ImmLeaf { @@ -1166,11 +1168,12 @@ // 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"; } Index: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -537,154 +537,15 @@ 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 @@ 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 @@ 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: Index: llvm/trunk/test/MC/AArch64/neon-diagnostics.s =================================================================== --- llvm/trunk/test/MC/AArch64/neon-diagnostics.s +++ llvm/trunk/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: ^