Index: lib/Target/AArch64/AArch64RegisterInfo.td =================================================================== --- lib/Target/AArch64/AArch64RegisterInfo.td +++ lib/Target/AArch64/AArch64RegisterInfo.td @@ -933,3 +933,28 @@ def ZZZZ_d : RegisterOperand"> { let ParserMatchClass = ZPRVectorList<64, 4>; } + + +class GPR64ShiftExtendAsmOperand : AsmOperandClass { + let Name = AsmOperandName # Size; + let PredicateMethod = "isGPR64WithShiftExtend"; + let DiagnosticType = "Invalid" # AsmOperandName # Size; + let RenderMethod = "addRegOperands"; + let ParserMethod = "tryParseGPROperand"; +} + +class GPR64ExtendRegisterOperand : RegisterOperand{ + let ParserMatchClass = !cast(Name); + let PrintMethod = "printRegWithShiftExtend"; +} + +foreach Size = [8, 16, 32, 64] in { + def GPR64shiftedAsmOpnd # Size : GPR64ShiftExtendAsmOperand<"GPR64shifted", Size, "GPR64">; + def GPR64shifted # Size : GPR64ExtendRegisterOperand<"GPR64shiftedAsmOpnd" # Size, Size, GPR64>; + + def GPR64NoXZRshiftedAsmOpnd # Size : GPR64ShiftExtendAsmOperand<"GPR64NoXZRshifted", Size, "GPR64common">; + def GPR64NoXZRshifted # Size : GPR64ExtendRegisterOperand<"GPR64NoXZRshiftedAsmOpnd" # Size, Size, GPR64common>; +} \ No newline at end of file Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -3823,6 +3823,22 @@ ComputeAvailableFeatures(STI->getFeatureBits())); return Error(Loc, "unrecognized instruction mnemonic" + Suggestion); } + case Match_InvalidGPR64shifted8: + return Error(Loc, "register must be x0..x31"); + case Match_InvalidGPR64shifted16: + return Error(Loc, "register must be x0..x31 with required shift 'lsl #1'"); + case Match_InvalidGPR64shifted32: + return Error(Loc, "register must be x0..x31 with required shift 'lsl #2'"); + case Match_InvalidGPR64shifted64: + return Error(Loc, "register must be x0..x31 with required shift 'lsl #3'"); + case Match_InvalidGPR64NoXZRshifted8: + return Error(Loc, "register must be x0..x30"); + case Match_InvalidGPR64NoXZRshifted16: + return Error(Loc, "register must be x0..x30 with required shift 'lsl #1'"); + case Match_InvalidGPR64NoXZRshifted32: + return Error(Loc, "register must be x0..x30 with required shift 'lsl #2'"); + case Match_InvalidGPR64NoXZRshifted64: + return Error(Loc, "register must be x0..x30 with required shift 'lsl #3'"); case Match_InvalidSVEPattern: return Error(Loc, "invalid predicate pattern"); case Match_InvalidSVEPredicateAnyReg: @@ -4268,6 +4284,14 @@ case Match_InvalidLabel: case Match_InvalidComplexRotationEven: case Match_InvalidComplexRotationOdd: + case Match_InvalidGPR64shifted8: + case Match_InvalidGPR64shifted16: + case Match_InvalidGPR64shifted32: + case Match_InvalidGPR64shifted64: + case Match_InvalidGPR64NoXZRshifted8: + case Match_InvalidGPR64NoXZRshifted16: + case Match_InvalidGPR64NoXZRshifted32: + case Match_InvalidGPR64NoXZRshifted64: case Match_InvalidSVEPredicateAnyReg: case Match_InvalidSVEPattern: case Match_InvalidSVEPredicateBReg: Index: lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp =================================================================== --- lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -55,6 +55,9 @@ static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); @@ -402,6 +405,17 @@ AArch64::LR, AArch64::XZR }; +static DecodeStatus DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Addr, + const void *Decoder) { + if (RegNo > 30) + return Fail; + + unsigned Register = GPR64DecoderTable[RegNo]; + Inst.addOperand(MCOperand::createReg(Register)); + return Success; +} + static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, const void *Decoder) { Index: lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h =================================================================== --- lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h @@ -90,7 +90,9 @@ const MCSubtargetInfo &STI, raw_ostream &O) { printMemExtend(MI, OpNum, O, SrcRegKind, Width); } - + template + void printRegWithShiftExtend(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); void printCondCode(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); void printInverseCondCode(const MCInst *MI, unsigned OpNum, Index: lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp =================================================================== --- lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -969,12 +969,9 @@ O << " #" << ShiftVal; } -void AArch64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum, - raw_ostream &O, char SrcRegKind, - unsigned Width) { - unsigned SignExtend = MI->getOperand(OpNum).getImm(); - unsigned DoShift = MI->getOperand(OpNum + 1).getImm(); - +static void printMemExtendImpl(unsigned SignExtend, unsigned DoShift, + unsigned Width, char SrcRegKind, + raw_ostream &O) { // sxtw, sxtx, uxtw or lsl (== uxtx) bool IsLSL = !SignExtend && SrcRegKind == 'x'; if (IsLSL) @@ -986,6 +983,26 @@ O << " #" << Log2_32(Width / 8); } +void AArch64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum, + raw_ostream &O, char SrcRegKind, + unsigned Width) { + unsigned SignExtend = MI->getOperand(OpNum).getImm(); + unsigned DoShift = MI->getOperand(OpNum + 1).getImm(); + printMemExtendImpl(SignExtend, DoShift, Width, SrcRegKind, O); +} + +template +void AArch64InstPrinter::printRegWithShiftExtend(const MCInst *MI, + unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + printOperand(MI, OpNum, STI, O); + if (SignExtend || DoShift || SrcRegKind == 'w') { + O << ", "; + printMemExtendImpl(SignExtend, DoShift, ExtWidth, SrcRegKind, O); + } +} + void AArch64InstPrinter::printCondCode(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) {