@@ -35,7 +35,9 @@ using namespace llvm;
3535struct XtensaOperand ;
3636
3737class XtensaAsmParser : public MCTargetAsmParser {
38+ const MCRegisterInfo &MRI;
3839
40+ enum XtensaRegisterType { Xtensa_Generic, Xtensa_SR, Xtensa_UR };
3941 SMLoc getLoc () const { return getParser ().getTok ().getLoc (); }
4042
4143 XtensaTargetStreamer &getTargetStreamer () {
@@ -64,11 +66,12 @@ class XtensaAsmParser : public MCTargetAsmParser {
6466 ParseStatus parseImmediate (OperandVector &Operands);
6567 ParseStatus
6668 parseRegister (OperandVector &Operands, bool AllowParens = false ,
67- bool SR = false ,
69+ XtensaRegisterType SR = Xtensa_Generic ,
6870 Xtensa::RegisterAccessType RAType = Xtensa::REGISTER_EXCHANGE);
6971 ParseStatus parseOperandWithModifier (OperandVector &Operands);
7072 bool
71- parseOperand (OperandVector &Operands, StringRef Mnemonic, bool SR = false ,
73+ parseOperand (OperandVector &Operands, StringRef Mnemonic,
74+ XtensaRegisterType SR = Xtensa_Generic,
7275 Xtensa::RegisterAccessType RAType = Xtensa::REGISTER_EXCHANGE);
7376 bool ParseInstructionWithSR (ParseInstructionInfo &Info, StringRef Name,
7477 SMLoc NameLoc, OperandVector &Operands);
@@ -90,7 +93,8 @@ class XtensaAsmParser : public MCTargetAsmParser {
9093
9194 XtensaAsmParser (const MCSubtargetInfo &STI, MCAsmParser &Parser,
9295 const MCInstrInfo &MII, const MCTargetOptions &Options)
93- : MCTargetAsmParser(Options, STI, MII) {
96+ : MCTargetAsmParser(Options, STI, MII),
97+ MRI (*Parser.getContext().getRegisterInfo()) {
9498 setAvailableFeatures (ComputeAvailableFeatures (STI.getFeatureBits ()));
9599 }
96100
@@ -583,7 +587,8 @@ bool XtensaAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
583587}
584588
585589ParseStatus XtensaAsmParser::parseRegister (OperandVector &Operands,
586- bool AllowParens, bool SR,
590+ bool AllowParens,
591+ XtensaRegisterType RegType,
587592 Xtensa::RegisterAccessType RAType) {
588593 SMLoc FirstS = getLoc ();
589594 bool HadParens = false ;
@@ -594,25 +599,32 @@ ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
594599 if (AllowParens && getLexer ().is (AsmToken::LParen)) {
595600 size_t ReadCount = getLexer ().peekTokens (Buf);
596601 if (ReadCount == 2 && Buf[1 ].getKind () == AsmToken::RParen) {
597- if (( Buf[0 ].getKind () == AsmToken::Integer) && (!SR) )
602+ if (Buf[0 ].getKind () == AsmToken::Integer && RegType == Xtensa_Generic )
598603 return ParseStatus::NoMatch;
599604 HadParens = true ;
600605 getParser ().Lex (); // Eat '('
601606 }
602607 }
603608
604- unsigned RegNo = 0 ;
609+ MCRegister RegNo = 0 ;
605610
606611 switch (getLexer ().getKind ()) {
607612 default :
608613 return ParseStatus::NoMatch;
609614 case AsmToken::Integer:
610- if (!SR )
615+ if (RegType == Xtensa_Generic )
611616 return ParseStatus::NoMatch;
612- RegName = getLexer ().getTok ().getString ();
613- RegNo = MatchRegisterName (RegName);
614- if (RegNo == 0 )
617+
618+ // Parse case when we expect UR register code as special case,
619+ // because SR and UR registers may have the same number
620+ // and such situation may lead to confilct
621+ if (RegType == Xtensa_UR) {
622+ int64_t RegCode = getLexer ().getTok ().getIntVal ();
623+ RegNo = Xtensa::getUserRegister (RegCode, MRI);
624+ } else {
625+ RegName = getLexer ().getTok ().getString ();
615626 RegNo = MatchRegisterAltName (RegName);
627+ }
616628 break ;
617629 case AsmToken::Identifier:
618630 RegName = getLexer ().getTok ().getIdentifier ();
@@ -689,7 +701,8 @@ ParseStatus XtensaAsmParser::parseOperandWithModifier(OperandVector &Operands) {
689701// / from this information, adding to Operands.
690702// / If operand was parsed, returns false, else true.
691703bool XtensaAsmParser::parseOperand (OperandVector &Operands, StringRef Mnemonic,
692- bool SR, Xtensa::RegisterAccessType RAType) {
704+ XtensaRegisterType RegType,
705+ Xtensa::RegisterAccessType RAType) {
693706 // Check if the current operand has a custom associated parser, if so, try to
694707 // custom parse the operand, or fallback to the general approach.
695708 ParseStatus Res = MatchOperandParserImpl (Operands, Mnemonic);
@@ -703,7 +716,7 @@ bool XtensaAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic,
703716 return true ;
704717
705718 // Attempt to parse token as register
706- if (parseRegister (Operands, true , SR , RAType).isSuccess ())
719+ if (parseRegister (Operands, true , RegType , RAType).isSuccess ())
707720 return false ;
708721
709722 // Attempt to parse token as an immediate
@@ -722,11 +735,9 @@ bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
722735 : (Name[0 ] == ' r' ? Xtensa::REGISTER_READ
723736 : Xtensa::REGISTER_EXCHANGE);
724737
725- if ((Name.starts_with (" wsr." ) || Name.starts_with (" rsr." ) ||
726- Name.starts_with (" xsr." )) &&
727- (Name.size () > 4 )) {
728- // Parse case when instruction name is concatenated with SR register
729- // name, like "wsr.sar a1"
738+ if ((Name.size () > 4 ) && Name[3 ] == ' .' ) {
739+ // Parse case when instruction name is concatenated with SR/UR register
740+ // name, like "wsr.sar a1" or "wur.fcr a1"
730741
731742 // First operand is token for instruction
732743 Operands.push_back (XtensaOperand::createToken (Name.take_front (3 ), NameLoc));
@@ -762,7 +773,8 @@ bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
762773 }
763774
764775 // Parse second operand
765- if (parseOperand (Operands, Name, true , RAType))
776+ if (parseOperand (Operands, Name, Name[1 ] == ' s' ? Xtensa_SR : Xtensa_UR,
777+ RAType))
766778 return true ;
767779 }
768780
@@ -780,7 +792,8 @@ bool XtensaAsmParser::parseInstruction(ParseInstructionInfo &Info,
780792 StringRef Name, SMLoc NameLoc,
781793 OperandVector &Operands) {
782794 if (Name.starts_with (" wsr" ) || Name.starts_with (" rsr" ) ||
783- Name.starts_with (" xsr" )) {
795+ Name.starts_with (" xsr" ) || Name.starts_with (" rur" ) ||
796+ Name.starts_with (" wur" )) {
784797 return ParseInstructionWithSR (Info, Name, NameLoc, Operands);
785798 }
786799
0 commit comments