Index: lib/Target/ARM64/ARM64InstrFormats.td =================================================================== --- lib/Target/ARM64/ARM64InstrFormats.td +++ lib/Target/ARM64/ARM64InstrFormats.td @@ -97,11 +97,17 @@ } // Shifter operand for arithmetic register shifted encodings. -def ArithmeticShifterOperand : AsmOperandClass { +class ArithmeticShifterOperand : 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]; @@ -491,20 +497,24 @@ // An arithmetic shifter operand: // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr // {5-0} - imm6 -def arith_shift : Operand { +class arith_shift : Operand { let PrintMethod = "printShifter"; - let ParserMatchClass = ArithmeticShifterOperand; + let ParserMatchClass = !cast( + "ArithmeticShifterOperand" # width); } -class arith_shifted_reg +def arith_shift32 : arith_shift; +def arith_shift64 : arith_shift; + +class arith_shifted_reg : Operand, ComplexPattern { let PrintMethod = "printShiftedRegister"; - let MIOperandInfo = (ops regclass, arith_shift); + let MIOperandInfo = (ops regclass, !cast("arith_shift" # width)); } -def arith_shifted_reg32 : arith_shifted_reg; -def arith_shifted_reg64 : arith_shifted_reg; +def arith_shifted_reg32 : arith_shifted_reg; +def arith_shifted_reg64 : arith_shifted_reg; // An arithmetic shifter operand: // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror @@ -1578,9 +1588,9 @@ def : InstAlias(NAME#"Xrx64") XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh)>; def : InstAlias(NAME#"Wrs") - WZR, GPR32:$src1, GPR32:$src2, arith_shift:$sh)>; + WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh)>; def : InstAlias(NAME#"Xrs") - XZR, GPR64:$src1, GPR64:$src2, arith_shift:$sh)>; + XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh)>; // Compare shorthands def : InstAlias(NAME#"Wrs") Index: lib/Target/ARM64/ARM64InstrInfo.td =================================================================== --- lib/Target/ARM64/ARM64InstrInfo.td +++ lib/Target/ARM64/ARM64InstrInfo.td @@ -512,9 +512,9 @@ 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). @@ -533,9 +533,9 @@ 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>; Index: lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp =================================================================== --- lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp +++ lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp @@ -3992,6 +3992,12 @@ 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: @@ -4510,6 +4516,8 @@ case Match_AddSubRegExtendSmall: case Match_AddSubRegExtendLarge: case Match_AddSubSecondSource: + case Match_AddSubRegShift32: + case Match_AddSubRegShift64: case Match_InvalidMemoryIndexed8: case Match_InvalidMemoryIndexed16: case Match_InvalidMemoryIndexed32SImm7: