Index: llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td +++ llvm/trunk/lib/Target/AArch64/AArch64RegisterInfo.td @@ -933,3 +933,24 @@ def ZZZZ_d : RegisterOperand"> { let ParserMatchClass = ZPRVectorList<64, 4>; } + +class GPR64ShiftExtendAsmOperand : AsmOperandClass { + let Name = AsmOperandName # Scale; + let PredicateMethod = "isGPR64WithShiftExtend"; + let DiagnosticType = "Invalid" # AsmOperandName # Scale; + let RenderMethod = "addRegOperands"; + let ParserMethod = "tryParseGPROperand"; +} + +class GPR64ExtendRegisterOperand : RegisterOperand{ + let ParserMatchClass = !cast(Name); + let PrintMethod = "printRegWithShiftExtend"; +} + +foreach Scale = [8, 16, 32, 64] in { + def GPR64shiftedAsmOpnd # Scale : GPR64ShiftExtendAsmOperand<"GPR64shifted", Scale, "GPR64">; + def GPR64shifted # Scale : GPR64ExtendRegisterOperand<"GPR64shiftedAsmOpnd" # Scale, Scale, GPR64>; + + def GPR64NoXZRshiftedAsmOpnd # Scale : GPR64ShiftExtendAsmOperand<"GPR64NoXZRshifted", Scale, "GPR64common">; + def GPR64NoXZRshifted # Scale : GPR64ExtendRegisterOperand<"GPR64NoXZRshiftedAsmOpnd" # Scale, Scale, GPR64common>; +} 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 @@ -3823,6 +3823,22 @@ ComputeAvailableFeatures(STI->getFeatureBits())); return Error(Loc, "unrecognized instruction mnemonic" + Suggestion); } + case Match_InvalidGPR64shifted8: + return Error(Loc, "register must be x0..x30 or xzr, without shift"); + case Match_InvalidGPR64shifted16: + return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #1'"); + case Match_InvalidGPR64shifted32: + return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #2'"); + case Match_InvalidGPR64shifted64: + return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #3'"); + case Match_InvalidGPR64NoXZRshifted8: + return Error(Loc, "register must be x0..x30 without shift"); + 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: llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ llvm/trunk/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -55,6 +55,10 @@ static DecodeStatus DecodeFPR8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +LLVM_ATTRIBUTE_UNUSED +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 +406,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: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h =================================================================== --- llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ llvm/trunk/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: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ llvm/trunk/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(bool SignExtend, bool DoShift, + unsigned Width, char SrcRegKind, + raw_ostream &O) { // sxtw, sxtx, uxtw or lsl (== uxtx) bool IsLSL = !SignExtend && SrcRegKind == 'x'; if (IsLSL) @@ -986,6 +983,28 @@ O << " #" << Log2_32(Width / 8); } +void AArch64InstPrinter::printMemExtend(const MCInst *MI, unsigned OpNum, + raw_ostream &O, char SrcRegKind, + unsigned Width) { + bool SignExtend = MI->getOperand(OpNum).getImm(); + bool 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); + + bool DoShift = ExtWidth != 8; + 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) {