def SImm10s8Operand : AsmOperandClass {
let Name = "SImm10s8";
let DiagnosticType = "InvalidMemoryIndexedSImm10";
+ let PredicateMethod = "isSImmScaled<10, 8>";
}
//===----------------------------------------------------------------------===//
let ParserMatchClass = AdrOperand;
}
+class SImmOperand<int width> : AsmOperandClass {
+ let Name = "SImm" # width;
+ let DiagnosticType = "InvalidMemoryIndexedSImm" # width;
+ let RenderMethod = "addImmOperands";
+ let PredicateMethod = "isSImm<" # width # ">";
+}
+
def simm10Scaled : Operand<i64> {
let ParserMatchClass = SImm10s8Operand;
let DecoderMethod = "DecodeSImm<10>";
let PrintMethod = "printImmScale<8>";
}
-// simm9 predicate - True if the immediate is in the range [-256, 255].
-def SImm9Operand : AsmOperandClass {
- let Name = "SImm9";
- let DiagnosticType = "InvalidMemoryIndexedSImm9";
-}
+def SImm9Operand : SImmOperand<9>;
def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
let ParserMatchClass = SImm9Operand;
+ let DecoderMethod = "DecodeSImm<9>";
}
// simm7sN predicate - True if the immediate is a multiple of N in the range
class SImm7Scaled<int Scale> : AsmOperandClass {
let Name = "SImm7s" # Scale;
let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7";
+ let PredicateMethod = "isSImmScaled<7, " # Scale # ">";
}
def SImm7s4Operand : SImm7Scaled<4>;
bool isImm() const override { return Kind == k_Immediate; }
bool isMem() const override { return false; }
- bool isSImm9() const {
- if (!isImm())
- return false;
- const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
- if (!MCE)
- return false;
- int64_t Val = MCE->getValue();
- return (Val >= -256 && Val < 256);
- }
- bool isSImm10s8() const {
- if (!isImm())
- return false;
- const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
- if (!MCE)
- return false;
- int64_t Val = MCE->getValue();
- return (Val >= -4096 && Val < 4089 && (Val & 7) == 0);
- }
- bool isSImm7s4() const {
- if (!isImm())
- return false;
- const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
- if (!MCE)
- return false;
- int64_t Val = MCE->getValue();
- return (Val >= -256 && Val <= 252 && (Val & 3) == 0);
- }
- bool isSImm7s8() const {
- if (!isImm())
- return false;
- const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
- if (!MCE)
- return false;
- int64_t Val = MCE->getValue();
- return (Val >= -512 && Val <= 504 && (Val & 7) == 0);
- }
- bool isSImm7s16() const {
+
+ template <int Width> bool isSImm() const { return isSImmScaled<Width, 1>(); }
+
+ template <int Bits, int Scale> bool isSImmScaled() const {
if (!isImm())
return false;
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
return false;
+
+ int64_t Shift = Bits - 1;
+ int64_t MinVal = (int64_t(1) << Shift) * -Scale;
+ int64_t MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
+
int64_t Val = MCE->getValue();
- return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0);
+ return Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0;
}
bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const {
// ambiguity in the matcher.
template<int Width>
bool isSImm9OffsetFB() const {
- return isSImm9() && !isUImm12Offset<Width / 8>();
+ return isSImm<9>() && !isUImm12Offset<Width / 8>();
}
bool isAdrpLabel() const {