def ZZZZ_d : RegisterOperand<ZPR4, "printTypedVectorList<0,'d'>"> {
let ParserMatchClass = ZPRVectorList<64, 4>;
}
+
+class GPR64ShiftExtendAsmOperand <string AsmOperandName, int Scale, string RegClass> : AsmOperandClass {
+ let Name = AsmOperandName # Scale;
+ let PredicateMethod = "isGPR64WithShiftExtend<AArch64::"#RegClass#"RegClassID, " # Scale # ">";
+ let DiagnosticType = "Invalid" # AsmOperandName # Scale;
+ let RenderMethod = "addRegOperands";
+ let ParserMethod = "tryParseGPROperand<true>";
+}
+
+class GPR64ExtendRegisterOperand<string Name, int Scale, RegisterClass RegClass> : RegisterOperand<RegClass>{
+ let ParserMatchClass = !cast<AsmOperandClass>(Name);
+ let PrintMethod = "printRegWithShiftExtend<false, " # Scale # ", 'x'>";
+}
+
+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>;
+}
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:
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:
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);
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) {
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)
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 <bool SignExtend, int ExtWidth, char SrcRegKind>
+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) {
const MCSubtargetInfo &STI, raw_ostream &O) {
printMemExtend(MI, OpNum, O, SrcRegKind, Width);
}
-
+ template <bool SignedExtend, int ExtWidth, char SrcRegKind>
+ 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,