@@ -446,8 +446,8 @@ class ARMAsmParser : public MCTargetAsmParser {
446446 int tryParseShiftRegister (OperandVector &);
447447 std::optional<ARM_AM::ShiftOpc> tryParseShiftToken ();
448448 bool parseRegisterList (OperandVector &, bool EnforceOrder = true ,
449- bool AllowRAAC = false ,
450- bool AllowOutOfBoundReg = false );
449+ bool AllowRAAC = false , bool IsLazyLoadStore = false ,
450+ bool IsVSCCLRM = false );
451451 bool parseMemory (OperandVector &);
452452 bool parseOperand (OperandVector &, StringRef Mnemonic);
453453 bool parseImmExpr (int64_t &Out);
@@ -3811,6 +3811,10 @@ class ARMOperand : public MCParsedAsmOperand {
38113811 Kind = k_FPSRegisterListWithVPR;
38123812 else
38133813 Kind = k_SPRRegisterList;
3814+ } else if (Regs.front ().second == ARM::VPR) {
3815+ assert (Regs.size () == 1 &&
3816+ " Register list starting with VPR expected to only contain VPR" );
3817+ Kind = k_FPSRegisterListWithVPR;
38143818 }
38153819
38163820 if (Kind == k_RegisterList && Regs.back ().second == ARM::APSR)
@@ -4608,7 +4612,8 @@ insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
46084612
46094613// / Parse a register list.
46104614bool ARMAsmParser::parseRegisterList (OperandVector &Operands, bool EnforceOrder,
4611- bool AllowRAAC, bool AllowOutOfBoundReg) {
4615+ bool AllowRAAC, bool IsLazyLoadStore,
4616+ bool IsVSCCLRM) {
46124617 MCAsmParser &Parser = getParser ();
46134618 if (Parser.getTok ().isNot (AsmToken::LCurly))
46144619 return TokError (" Token is not a Left Curly Brace" );
@@ -4618,15 +4623,23 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
46184623
46194624 // Check the first register in the list to see what register class
46204625 // this is a list of.
4621- MCRegister Reg = tryParseRegister ();
4626+ bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
4627+ MCRegister Reg = tryParseRegister (AllowOutOfBoundReg);
46224628 if (!Reg)
46234629 return Error (RegLoc, " register expected" );
46244630 if (!AllowRAAC && Reg == ARM::RA_AUTH_CODE)
46254631 return Error (RegLoc, " pseudo-register not allowed" );
4626- // The reglist instructions have at most 16 registers, so reserve
4632+ // The reglist instructions have at most 32 registers, so reserve
46274633 // space for that many.
46284634 int EReg = 0 ;
4629- SmallVector<std::pair<unsigned , MCRegister>, 16 > Registers;
4635+ SmallVector<std::pair<unsigned , MCRegister>, 32 > Registers;
4636+
4637+ // Single-precision VSCCLRM can have double-precision registers in the
4638+ // register list. When VSCCLRMAdjustEncoding is true then we've switched from
4639+ // single-precision to double-precision and we pretend that these registers
4640+ // are encoded as S32 onwards, which we can do by adding 16 to the encoding
4641+ // value.
4642+ bool VSCCLRMAdjustEncoding = false ;
46304643
46314644 // Allow Q regs and just interpret them as the two D sub-registers.
46324645 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains (Reg)) {
@@ -4645,6 +4658,8 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
46454658 RC = &ARMMCRegisterClasses[ARM::SPRRegClassID];
46464659 else if (ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains (Reg))
46474660 RC = &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID];
4661+ else if (Reg == ARM::VPR)
4662+ RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
46484663 else
46494664 return Error (RegLoc, " invalid register in register list" );
46504665
@@ -4685,6 +4700,8 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
46854700 while (Reg != EndReg) {
46864701 Reg = getNextRegister (Reg);
46874702 EReg = MRI->getEncodingValue (Reg);
4703+ if (VSCCLRMAdjustEncoding)
4704+ EReg += 16 ;
46884705 if (!insertNoDuplicates (Registers, EReg, Reg)) {
46894706 Warning (AfterMinusLoc, StringRef (" duplicated register (" ) +
46904707 ARMInstPrinter::getRegisterName (Reg) +
@@ -4696,6 +4713,7 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
46964713 Parser.Lex (); // Eat the comma.
46974714 RegLoc = Parser.getTok ().getLoc ();
46984715 MCRegister OldReg = Reg;
4716+ int EOldReg = EReg;
46994717 const AsmToken RegTok = Parser.getTok ();
47004718 Reg = tryParseRegister (AllowOutOfBoundReg);
47014719 if (!Reg)
@@ -4727,6 +4745,12 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
47274745 }
47284746 continue ;
47294747 }
4748+ // VSCCLRM can switch from single-precision to double-precision only when
4749+ // S31 is followed by D16.
4750+ if (IsVSCCLRM && OldReg == ARM::S31 && Reg == ARM::D16) {
4751+ VSCCLRMAdjustEncoding = true ;
4752+ RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4753+ }
47304754 // The register must be in the same register class as the first.
47314755 if ((Reg == ARM::RA_AUTH_CODE &&
47324756 RC != &ARMMCRegisterClasses[ARM::GPRRegClassID]) ||
@@ -4736,8 +4760,10 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
47364760 // exception is CLRM, which is order-independent anyway, so
47374761 // there's no potential for confusion if you write clrm {r2,r1}
47384762 // instead of clrm {r1,r2}.
4739- if (EnforceOrder &&
4740- MRI->getEncodingValue (Reg) < MRI->getEncodingValue (OldReg)) {
4763+ EReg = MRI->getEncodingValue (Reg);
4764+ if (VSCCLRMAdjustEncoding)
4765+ EReg += 16 ;
4766+ if (EnforceOrder && EReg < EOldReg) {
47414767 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains (Reg))
47424768 Warning (RegLoc, " register list not in ascending order" );
47434769 else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains (Reg))
@@ -4746,9 +4772,9 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
47464772 // VFP register lists must also be contiguous.
47474773 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
47484774 RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] &&
4749- Reg != OldReg + 1 )
4775+ EReg != EOldReg + 1 )
47504776 return Error (RegLoc, " non-contiguous register range" );
4751- EReg = MRI-> getEncodingValue (Reg);
4777+
47524778 if (!insertNoDuplicates (Registers, EReg, Reg)) {
47534779 Warning (RegLoc, " duplicated register (" + RegTok.getString () +
47544780 " ) in register list" );
@@ -6336,9 +6362,10 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
63366362 case AsmToken::LBrac:
63376363 return parseMemory (Operands);
63386364 case AsmToken::LCurly: {
6339- bool AllowOutOfBoundReg = Mnemonic == " vlldm" || Mnemonic == " vlstm" ;
6365+ bool IsLazyLoadStore = Mnemonic == " vlldm" || Mnemonic == " vlstm" ;
6366+ bool IsVSCCLRM = Mnemonic == " vscclrm" ;
63406367 return parseRegisterList (Operands, !Mnemonic.starts_with (" clr" ), false ,
6341- AllowOutOfBoundReg );
6368+ IsLazyLoadStore, IsVSCCLRM );
63426369 }
63436370 case AsmToken::Dollar:
63446371 case AsmToken::Hash: {
0 commit comments