@@ -64,6 +64,7 @@ class EraVMAsmParser : public MCTargetAsmParser {
6464 bool parseRegOperand (OperandVector &Operands);
6565 ParseStatus tryParseUImm16Operand (OperandVector &Operands);
6666 ParseStatus tryParseJumpTargetOperand (OperandVector &Operands);
67+ bool parseAddend (int &Addend, bool SignRequired);
6768 bool parseRegisterWithAddend (MCRegister &RegNo, MCSymbol *&Symbol,
6869 int &Addend);
6970 bool parseOperand (StringRef Mnemonic, OperandVector &Operands);
@@ -416,6 +417,31 @@ bool EraVMAsmParser::parseRegOperand(OperandVector &Operands) {
416417}
417418
418419ParseStatus EraVMAsmParser::tryParseUImm16Operand (OperandVector &Operands) {
420+ // First check if this is a symbol + addend.
421+ if (getTok ().is (AsmToken::At)) {
422+ MCSymbol *Symbol = nullptr ;
423+ SMLoc StartOfOperand = getLexer ().getLoc ();
424+ int Addend = 0 ;
425+
426+ Lex (); // eat "@" token
427+ Symbol = getContext ().getOrCreateSymbol (getTok ().getString ());
428+ Lex (); // eat symbol name
429+ if (getTok ().is (AsmToken::Plus) || getTok ().is (AsmToken::Minus))
430+ if (parseAddend (Addend, /* SignRequired=*/ true ))
431+ return ParseStatus::Failure;
432+
433+ const MCExpr *Expr = MCSymbolRefExpr::create (Symbol, getContext ());
434+ // FIXME Should we support negative addends?
435+ Addend &= (unsigned )0xffff ;
436+ if (Addend) {
437+ const MCExpr *AddendExpr = createConstant (Addend);
438+ Expr = MCBinaryExpr::createAdd (Expr, AddendExpr, getContext ());
439+ }
440+ Operands.push_back (
441+ EraVMOperand::CreateImm (Expr, StartOfOperand, getTok ().getEndLoc ()));
442+ return ParseStatus::Success;
443+ }
444+
419445 if (getLexer ().is (AsmToken::Minus) &&
420446 getLexer ().peekTok ().is (AsmToken::Integer)) {
421447 TokError (" negative immediate operands are not supported" );
@@ -459,34 +485,33 @@ ParseStatus EraVMAsmParser::tryParseJumpTargetOperand(OperandVector &Operands) {
459485 return ParseStatus::Success;
460486}
461487
462- bool EraVMAsmParser::parseRegisterWithAddend (MCRegister &RegNo,
463- MCSymbol *&Symbol, int &Addend) {
464- auto ParseAddend = [this , &Addend](bool SignRequired) {
465- int Multiplier = 1 ;
466-
467- switch (getTok ().getKind ()) {
468- case AsmToken::Plus:
469- Multiplier = 1 ;
470- Lex (); // eat "+" token
471- break ;
472- case AsmToken::Minus:
473- Multiplier = -1 ;
474- Lex (); // eat "-" token
475- break ;
476- default :
477- if (SignRequired)
478- return TokError (" '+' or '-' expected" );
479- break ;
480- }
488+ bool EraVMAsmParser::parseAddend (int &Addend, bool SignRequired) {
489+ int Multiplier = 1 ;
490+ switch (getTok ().getKind ()) {
491+ case AsmToken::Plus:
492+ Multiplier = 1 ;
493+ Lex (); // eat "+" token
494+ break ;
495+ case AsmToken::Minus:
496+ Multiplier = -1 ;
497+ Lex (); // eat "-" token
498+ break ;
499+ default :
500+ if (SignRequired)
501+ return TokError (" '+' or '-' expected" );
502+ break ;
503+ }
481504
482- if (!getLexer ().is (AsmToken::Integer))
483- return TokError (" integer addend expected" );
484- Addend = Multiplier * getTok ().getIntVal ();
485- Lex (); // eat integer token
505+ if (!getLexer ().is (AsmToken::Integer))
506+ return TokError (" integer addend expected" );
507+ Addend = Multiplier * getTok ().getIntVal ();
508+ Lex (); // eat integer token
486509
487- return false ;
488- };
510+ return false ;
511+ }
489512
513+ bool EraVMAsmParser::parseRegisterWithAddend (MCRegister &RegNo,
514+ MCSymbol *&Symbol, int &Addend) {
490515 auto ParseRegister = [this , &RegNo]() {
491516 SMLoc S, E;
492517 if (tryParseRegister (RegNo, S, E).isNoMatch ())
@@ -526,10 +551,10 @@ bool EraVMAsmParser::parseRegisterWithAddend(MCRegister &RegNo,
526551 return true ;
527552 if (getTok ().is (AsmToken::RBrac))
528553 return false ; // keep "]" token for the caller
529- return ParseAddend ( /* SignRequired=*/ true );
554+ return parseAddend (Addend, /* SignRequired=*/ true );
530555 }
531556
532- if (ParseAddend ( /* SignRequired=*/ false ))
557+ if (parseAddend (Addend, /* SignRequired=*/ false ))
533558 return true ;
534559 if (getTok ().is (AsmToken::RBrac))
535560 return false ; // keep "]" token for the caller
@@ -628,33 +653,18 @@ ParseStatus EraVMAsmParser::tryParseStackOperand(OperandVector &Operands) {
628653
629654ParseStatus EraVMAsmParser::tryParseCodeOperand (OperandVector &Operands) {
630655 SMLoc StartOfOperand = getLexer ().getLoc ();
631- MCSymbol *Symbol = nullptr ;
632656 MCSymbol *SymbolInSubscript = nullptr ;
633657 MCRegister RegNo = 0 ;
634658 int Addend = 0 ;
635659
636- // Decide if this is a code operand
637- SmallVector<AsmToken, 2 > PeekedTokens (2 );
638- getLexer ().peekTokens (PeekedTokens);
639- if (getTok ().is (AsmToken::At)) {
640- // "@symbol_name[...]"
641- if (!PeekedTokens[0 ].is (AsmToken::Identifier) ||
642- !PeekedTokens[1 ].is (AsmToken::LBrac))
643- return ParseStatus::NoMatch;
644-
645- Lex (); // eat "@" token
646- Symbol = getContext ().getOrCreateSymbol (getTok ().getString ());
647- Lex (); // eat constant symbol name
648- Lex (); // eat "[" token
649- } else {
650- // "code[...]"
651- if (!getTok ().is (AsmToken::Identifier) ||
652- !PeekedTokens[0 ].is (AsmToken::LBrac) || getTok ().getString () != " code" )
653- return ParseStatus::NoMatch;
660+ // "code[...]"
661+ if (!getTok ().is (AsmToken::Identifier) ||
662+ !getLexer ().peekTok ().is (AsmToken::LBrac) ||
663+ getTok ().getString () != " code" )
664+ return ParseStatus::NoMatch;
654665
655- Lex (); // eat "code" token
656- Lex (); // eat "[" token
657- }
666+ Lex (); // eat "code" token
667+ Lex (); // eat "[" token
658668
659669 if (parseRegisterWithAddend (RegNo, SymbolInSubscript, Addend))
660670 return ParseStatus::Failure;
@@ -665,21 +675,9 @@ ParseStatus EraVMAsmParser::tryParseCodeOperand(OperandVector &Operands) {
665675 if (parseToken (AsmToken::RBrac, " ']' expected" ))
666676 return ParseStatus::Failure;
667677
668- if (Symbol) {
669- // @symbol_name[reg + imm]
670- if (SymbolInSubscript) {
671- Error (StartOfOperand, " two symbols in a single operand" );
672- return ParseStatus::Failure;
673- }
674- Operands.push_back (EraVMOperand::CreateMem (
675- &getContext (), EraVM::OperandCode, RegNo, Symbol, Addend,
676- StartOfOperand, getTok ().getEndLoc ()));
677- } else {
678- // code[...]
679- Operands.push_back (EraVMOperand::CreateMem (
680- &getContext (), EraVM::OperandCode, RegNo, SymbolInSubscript, Addend,
681- StartOfOperand, getTok ().getEndLoc ()));
682- }
678+ Operands.push_back (EraVMOperand::CreateMem (
679+ &getContext (), EraVM::OperandCode, RegNo, SymbolInSubscript, Addend,
680+ StartOfOperand, getTok ().getEndLoc ()));
683681
684682 return ParseStatus::Success;
685683}
0 commit comments