@@ -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);
@@ -4611,7 +4611,8 @@ insertNoDuplicates(SmallVectorImpl<std::pair<unsigned, MCRegister>> &Regs,
46114611
46124612// / Parse a register list.
46134613bool ARMAsmParser::parseRegisterList (OperandVector &Operands, bool EnforceOrder,
4614- bool AllowRAAC, bool AllowOutOfBoundReg) {
4614+ bool AllowRAAC, bool IsLazyLoadStore,
4615+ bool IsVSCCLRM) {
46154616 MCAsmParser &Parser = getParser ();
46164617 if (Parser.getTok ().isNot (AsmToken::LCurly))
46174618 return TokError (" Token is not a Left Curly Brace" );
@@ -4621,6 +4622,7 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
46214622
46224623 // Check the first register in the list to see what register class
46234624 // this is a list of.
4625+ bool AllowOutOfBoundReg = IsLazyLoadStore || IsVSCCLRM;
46244626 MCRegister Reg = tryParseRegister (AllowOutOfBoundReg);
46254627 if (!Reg)
46264628 return Error (RegLoc, " register expected" );
@@ -4631,6 +4633,13 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
46314633 int EReg = 0 ;
46324634 SmallVector<std::pair<unsigned , MCRegister>, 32 > Registers;
46334635
4636+ // Single-precision VSCCLRM can have double-precision registers in the
4637+ // register list. When VSCCLRMAdjustEncoding is true then we've switched from
4638+ // single-precision to double-precision and we pretend that these registers
4639+ // are encoded as S32 onwards, which we can do by adding 16 to the encoding
4640+ // value.
4641+ bool VSCCLRMAdjustEncoding = false ;
4642+
46344643 // Allow Q regs and just interpret them as the two D sub-registers.
46354644 if (ARMMCRegisterClasses[ARM::QPRRegClassID].contains (Reg)) {
46364645 Reg = getDRegFromQReg (Reg);
@@ -4690,6 +4699,8 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
46904699 while (Reg != EndReg) {
46914700 Reg = getNextRegister (Reg);
46924701 EReg = MRI->getEncodingValue (Reg);
4702+ if (VSCCLRMAdjustEncoding)
4703+ EReg += 16 ;
46934704 if (!insertNoDuplicates (Registers, EReg, Reg)) {
46944705 Warning (AfterMinusLoc, StringRef (" duplicated register (" ) +
46954706 ARMInstPrinter::getRegisterName (Reg) +
@@ -4701,6 +4712,7 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
47014712 Parser.Lex (); // Eat the comma.
47024713 RegLoc = Parser.getTok ().getLoc ();
47034714 MCRegister OldReg = Reg;
4715+ int EOldReg = EReg;
47044716 const AsmToken RegTok = Parser.getTok ();
47054717 Reg = tryParseRegister (AllowOutOfBoundReg);
47064718 if (!Reg)
@@ -4732,6 +4744,12 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
47324744 }
47334745 continue ;
47344746 }
4747+ // VSCCLRM can switch from single-precision to double-precision only when
4748+ // S31 is followed by D16.
4749+ if (IsVSCCLRM && OldReg == ARM::S31 && Reg == ARM::D16) {
4750+ VSCCLRMAdjustEncoding = true ;
4751+ RC = &ARMMCRegisterClasses[ARM::FPWithVPRRegClassID];
4752+ }
47354753 // The register must be in the same register class as the first.
47364754 if ((Reg == ARM::RA_AUTH_CODE &&
47374755 RC != &ARMMCRegisterClasses[ARM::GPRRegClassID]) ||
@@ -4741,8 +4759,10 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
47414759 // exception is CLRM, which is order-independent anyway, so
47424760 // there's no potential for confusion if you write clrm {r2,r1}
47434761 // instead of clrm {r1,r2}.
4744- if (EnforceOrder &&
4745- MRI->getEncodingValue (Reg) < MRI->getEncodingValue (OldReg)) {
4762+ EReg = MRI->getEncodingValue (Reg);
4763+ if (VSCCLRMAdjustEncoding)
4764+ EReg += 16 ;
4765+ if (EnforceOrder && EReg < EOldReg) {
47464766 if (ARMMCRegisterClasses[ARM::GPRRegClassID].contains (Reg))
47474767 Warning (RegLoc, " register list not in ascending order" );
47484768 else if (!ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID].contains (Reg))
@@ -4751,9 +4771,9 @@ bool ARMAsmParser::parseRegisterList(OperandVector &Operands, bool EnforceOrder,
47514771 // VFP register lists must also be contiguous.
47524772 if (RC != &ARMMCRegisterClasses[ARM::GPRRegClassID] &&
47534773 RC != &ARMMCRegisterClasses[ARM::GPRwithAPSRnospRegClassID] &&
4754- Reg != OldReg + 1 )
4774+ EReg != EOldReg + 1 )
47554775 return Error (RegLoc, " non-contiguous register range" );
4756- EReg = MRI-> getEncodingValue (Reg);
4776+
47574777 if (!insertNoDuplicates (Registers, EReg, Reg)) {
47584778 Warning (RegLoc, " duplicated register (" + RegTok.getString () +
47594779 " ) in register list" );
@@ -6341,10 +6361,10 @@ bool ARMAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
63416361 case AsmToken::LBrac:
63426362 return parseMemory (Operands);
63436363 case AsmToken::LCurly: {
6344- bool AllowOutOfBoundReg =
6345- Mnemonic == " vlldm " || Mnemonic == " vlstm " || Mnemonic == " vscclrm" ;
6364+ bool IsLazyLoadStore = Mnemonic == " vlldm " || Mnemonic == " vlstm " ;
6365+ bool IsVSCCLRM = Mnemonic == " vscclrm" ;
63466366 return parseRegisterList (Operands, !Mnemonic.starts_with (" clr" ), false ,
6347- AllowOutOfBoundReg );
6367+ IsLazyLoadStore, IsVSCCLRM );
63486368 }
63496369 case AsmToken::Dollar:
63506370 case AsmToken::Hash: {
0 commit comments