}
// Shifter operand for arithmetic register shifted encodings.
-def ArithmeticShifterOperand : AsmOperandClass {
+class ArithmeticShifterOperand<int width> : AsmOperandClass {
let SuperClasses = [ShifterOperand];
- let Name = "ArithmeticShifter";
+ let Name = "ArithmeticShifter" # width;
+ let PredicateMethod = "isArithmeticShifter";
+ let RenderMethod = "addArithmeticShifterOperands";
+ let DiagnosticType = "AddSubRegShift" # width;
}
+def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
+def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
+
// Shifter operand for logical vector 128/64-bit shifted encodings.
def LogicalVecShifterOperand : AsmOperandClass {
let SuperClasses = [ShifterOperand];
// An arithmetic shifter operand:
// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
// {5-0} - imm6
-def arith_shift : Operand<i32> {
+class arith_shift<ValueType Ty, int width> : Operand<Ty> {
let PrintMethod = "printShifter";
- let ParserMatchClass = ArithmeticShifterOperand;
+ let ParserMatchClass = !cast<AsmOperandClass>(
+ "ArithmeticShifterOperand" # width);
}
-class arith_shifted_reg<ValueType Ty, RegisterClass regclass>
+def arith_shift32 : arith_shift<i32, 32>;
+def arith_shift64 : arith_shift<i64, 64>;
+
+class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
: Operand<Ty>,
ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
let PrintMethod = "printShiftedRegister";
- let MIOperandInfo = (ops regclass, arith_shift);
+ let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
}
-def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32>;
-def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64>;
+def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
+def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
// An arithmetic shifter operand:
// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
def : InstAlias<cmp#" $src1, $src2, $sh", (!cast<Instruction>(NAME#"Xrx64")
XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh)>;
def : InstAlias<cmp#" $src1, $src2, $sh", (!cast<Instruction>(NAME#"Wrs")
- WZR, GPR32:$src1, GPR32:$src2, arith_shift:$sh)>;
+ WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh)>;
def : InstAlias<cmp#" $src1, $src2, $sh", (!cast<Instruction>(NAME#"Xrs")
- XZR, GPR64:$src1, GPR64:$src2, arith_shift:$sh)>;
+ XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh)>;
// Compare shorthands
def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Wrs")
def : InstAlias<"neg $dst, $src", (SUBWrs GPR32:$dst, WZR, GPR32:$src, 0)>;
def : InstAlias<"neg $dst, $src", (SUBXrs GPR64:$dst, XZR, GPR64:$src, 0)>;
def : InstAlias<"neg $dst, $src, $shift",
- (SUBWrs GPR32:$dst, WZR, GPR32:$src, arith_shift:$shift)>;
+ (SUBWrs GPR32:$dst, WZR, GPR32:$src, arith_shift32:$shift)>;
def : InstAlias<"neg $dst, $src, $shift",
- (SUBXrs GPR64:$dst, XZR, GPR64:$src, arith_shift:$shift)>;
+ (SUBXrs GPR64:$dst, XZR, GPR64:$src, arith_shift64:$shift)>;
// Because of the immediate format for add/sub-imm instructions, the
// expression (add x, -1) must be transformed to (SUB{W,X}ri x, 1).
def : InstAlias<"negs $dst, $src", (SUBSWrs GPR32:$dst, WZR, GPR32:$src, 0)>;
def : InstAlias<"negs $dst, $src", (SUBSXrs GPR64:$dst, XZR, GPR64:$src, 0)>;
def : InstAlias<"negs $dst, $src, $shift",
- (SUBSWrs GPR32:$dst, WZR, GPR32:$src, arith_shift:$shift)>;
+ (SUBSWrs GPR32:$dst, WZR, GPR32:$src, arith_shift32:$shift)>;
def : InstAlias<"negs $dst, $src, $shift",
- (SUBSXrs GPR64:$dst, XZR, GPR64:$src, arith_shift:$shift)>;
+ (SUBSXrs GPR64:$dst, XZR, GPR64:$src, arith_shift64:$shift)>;
// Unsigned/Signed divide
defm UDIV : Div<0, "udiv", udiv>;
case Match_AddSubSecondSource:
return Error(Loc,
"expected compatible register, symbol or integer in range [0, 4095]");
+ case Match_AddSubRegShift32:
+ return Error(Loc,
+ "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
+ case Match_AddSubRegShift64:
+ return Error(Loc,
+ "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
case Match_InvalidMemoryIndexedSImm9:
return Error(Loc, "index must be an integer in range [-256, 255].");
case Match_InvalidMemoryIndexed32SImm7:
case Match_AddSubRegExtendSmall:
case Match_AddSubRegExtendLarge:
case Match_AddSubSecondSource:
+ case Match_AddSubRegShift32:
+ case Match_AddSubRegShift64:
case Match_InvalidMemoryIndexed8:
case Match_InvalidMemoryIndexed16:
case Match_InvalidMemoryIndexed32SImm7: