1 //===- XtensaAsmParser.cpp - Parse Xtensa assembly to MCInst instructions -===//
3 // The LLVM Compiler Infrastructure
5 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6 // See https://llvm.org/LICENSE.txt for license information.
7 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
9 //===----------------------------------------------------------------------===//
11 #include "MCTargetDesc/XtensaMCExpr.h"
12 #include "MCTargetDesc/XtensaMCTargetDesc.h"
13 #include "MCTargetDesc/XtensaTargetStreamer.h"
14 #include "TargetInfo/XtensaTargetInfo.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCParser/MCAsmLexer.h"
22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
24 #include "llvm/MC/MCRegisterInfo.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/TargetRegistry.h"
29 #include "llvm/Support/Casting.h"
33 #define DEBUG_TYPE "xtensa-asm-parser"
37 class XtensaAsmParser
: public MCTargetAsmParser
{
39 SMLoc
getLoc() const { return getParser().getTok().getLoc(); }
41 XtensaTargetStreamer
&getTargetStreamer() {
42 MCTargetStreamer
&TS
= *getParser().getStreamer().getTargetStreamer();
43 return static_cast<XtensaTargetStreamer
&>(TS
);
46 ParseStatus
parseDirective(AsmToken DirectiveID
) override
;
47 bool parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
48 bool parseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
49 SMLoc NameLoc
, OperandVector
&Operands
) override
;
50 bool matchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
51 OperandVector
&Operands
, MCStreamer
&Out
,
53 bool MatchingInlineAsm
) override
;
54 unsigned validateTargetOperandClass(MCParsedAsmOperand
&Op
,
55 unsigned Kind
) override
;
57 bool processInstruction(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
,
58 const MCSubtargetInfo
*STI
);
60 // Auto-generated instruction matching functions
61 #define GET_ASSEMBLER_HEADER
62 #include "XtensaGenAsmMatcher.inc"
64 ParseStatus
parseImmediate(OperandVector
&Operands
);
65 ParseStatus
parseRegister(OperandVector
&Operands
, bool AllowParens
= false,
67 ParseStatus
parseOperandWithModifier(OperandVector
&Operands
);
68 bool parseOperand(OperandVector
&Operands
, StringRef Mnemonic
,
70 bool ParseInstructionWithSR(ParseInstructionInfo
&Info
, StringRef Name
,
71 SMLoc NameLoc
, OperandVector
&Operands
);
72 ParseStatus
tryParseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
73 SMLoc
&EndLoc
) override
{
74 return ParseStatus::NoMatch
;
76 ParseStatus
parsePCRelTarget(OperandVector
&Operands
);
77 bool parseLiteralDirective(SMLoc L
);
80 enum XtensaMatchResultTy
{
81 Match_Dummy
= FIRST_TARGET_MATCH_RESULT_TY
,
82 #define GET_OPERAND_DIAGNOSTIC_TYPES
83 #include "XtensaGenAsmMatcher.inc"
84 #undef GET_OPERAND_DIAGNOSTIC_TYPES
87 XtensaAsmParser(const MCSubtargetInfo
&STI
, MCAsmParser
&Parser
,
88 const MCInstrInfo
&MII
, const MCTargetOptions
&Options
)
89 : MCTargetAsmParser(Options
, STI
, MII
) {
90 setAvailableFeatures(ComputeAvailableFeatures(STI
.getFeatureBits()));
94 // Return true if Expr is in the range [MinValue, MaxValue].
95 static bool inRange(const MCExpr
*Expr
, int64_t MinValue
, int64_t MaxValue
) {
96 if (auto *CE
= dyn_cast
<MCConstantExpr
>(Expr
)) {
97 int64_t Value
= CE
->getValue();
98 return Value
>= MinValue
&& Value
<= MaxValue
;
103 struct XtensaOperand
: public MCParsedAsmOperand
{
119 SMLoc StartLoc
, EndLoc
;
126 XtensaOperand(KindTy K
) : MCParsedAsmOperand(), Kind(K
) {}
129 XtensaOperand(const XtensaOperand
&o
) : MCParsedAsmOperand() {
131 StartLoc
= o
.StartLoc
;
146 bool isToken() const override
{ return Kind
== Token
; }
147 bool isReg() const override
{ return Kind
== Register
; }
148 bool isImm() const override
{ return Kind
== Immediate
; }
149 bool isMem() const override
{ return false; }
151 bool isImm(int64_t MinValue
, int64_t MaxValue
) const {
152 return Kind
== Immediate
&& inRange(getImm(), MinValue
, MaxValue
);
155 bool isImm8() const { return isImm(-128, 127); }
157 bool isImm8_sh8() const {
158 return isImm(-32768, 32512) &&
159 ((cast
<MCConstantExpr
>(getImm())->getValue() & 0xFF) == 0);
162 bool isImm12() const { return isImm(-2048, 2047); }
164 // Convert MOVI to literal load, when immediate is not in range (-2048, 2047)
165 bool isImm12m() const { return Kind
== Immediate
; }
167 bool isOffset4m32() const {
168 return isImm(0, 60) &&
169 ((cast
<MCConstantExpr
>(getImm())->getValue() & 0x3) == 0);
172 bool isOffset8m8() const { return isImm(0, 255); }
174 bool isOffset8m16() const {
175 return isImm(0, 510) &&
176 ((cast
<MCConstantExpr
>(getImm())->getValue() & 0x1) == 0);
179 bool isOffset8m32() const {
180 return isImm(0, 1020) &&
181 ((cast
<MCConstantExpr
>(getImm())->getValue() & 0x3) == 0);
184 bool isUimm4() const { return isImm(0, 15); }
186 bool isUimm5() const { return isImm(0, 31); }
188 bool isImm8n_7() const { return isImm(-8, 7); }
190 bool isShimm1_31() const { return isImm(1, 31); }
192 bool isImm16_31() const { return isImm(16, 31); }
194 bool isImm1_16() const { return isImm(1, 16); }
196 // Check that value is either equals (-1) or from [1,15] range.
197 bool isImm1n_15() const { return isImm(1, 15) || isImm(-1, -1); }
199 bool isImm32n_95() const { return isImm(-32, 95); }
201 bool isB4const() const {
202 if (Kind
!= Immediate
)
204 if (auto *CE
= dyn_cast
<MCConstantExpr
>(getImm())) {
205 int64_t Value
= CE
->getValue();
231 bool isB4constu() const {
232 if (Kind
!= Immediate
)
234 if (auto *CE
= dyn_cast
<MCConstantExpr
>(getImm())) {
235 int64_t Value
= CE
->getValue();
261 /// getStartLoc - Gets location of the first token of this operand
262 SMLoc
getStartLoc() const override
{ return StartLoc
; }
263 /// getEndLoc - Gets location of the last token of this operand
264 SMLoc
getEndLoc() const override
{ return EndLoc
; }
266 MCRegister
getReg() const override
{
267 assert(Kind
== Register
&& "Invalid type access!");
271 const MCExpr
*getImm() const {
272 assert(Kind
== Immediate
&& "Invalid type access!");
276 StringRef
getToken() const {
277 assert(Kind
== Token
&& "Invalid type access!");
281 void print(raw_ostream
&OS
) const override
{
288 OS
<< getReg() << ">";
291 OS
<< "'" << getToken() << "'";
296 static std::unique_ptr
<XtensaOperand
> createToken(StringRef Str
, SMLoc S
) {
297 auto Op
= std::make_unique
<XtensaOperand
>(Token
);
304 static std::unique_ptr
<XtensaOperand
> createReg(unsigned RegNo
, SMLoc S
,
306 auto Op
= std::make_unique
<XtensaOperand
>(Register
);
307 Op
->Reg
.RegNum
= RegNo
;
313 static std::unique_ptr
<XtensaOperand
> createImm(const MCExpr
*Val
, SMLoc S
,
315 auto Op
= std::make_unique
<XtensaOperand
>(Immediate
);
322 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const {
323 assert(Expr
&& "Expr shouldn't be null!");
325 bool IsConstant
= false;
327 if (auto *CE
= dyn_cast
<MCConstantExpr
>(Expr
)) {
329 Imm
= CE
->getValue();
333 Inst
.addOperand(MCOperand::createImm(Imm
));
335 Inst
.addOperand(MCOperand::createExpr(Expr
));
338 // Used by the TableGen Code
339 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
340 assert(N
== 1 && "Invalid number of operands!");
341 Inst
.addOperand(MCOperand::createReg(getReg()));
344 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
345 assert(N
== 1 && "Invalid number of operands!");
346 addExpr(Inst
, getImm());
350 #define GET_REGISTER_MATCHER
351 #define GET_MATCHER_IMPLEMENTATION
352 #include "XtensaGenAsmMatcher.inc"
354 unsigned XtensaAsmParser::validateTargetOperandClass(MCParsedAsmOperand
&AsmOp
,
356 return Match_InvalidOperand
;
359 static SMLoc
RefineErrorLoc(const SMLoc Loc
, const OperandVector
&Operands
,
360 uint64_t ErrorInfo
) {
361 if (ErrorInfo
!= ~0ULL && ErrorInfo
< Operands
.size()) {
362 SMLoc ErrorLoc
= Operands
[ErrorInfo
]->getStartLoc();
363 if (ErrorLoc
== SMLoc())
370 bool XtensaAsmParser::processInstruction(MCInst
&Inst
, SMLoc IDLoc
,
372 const MCSubtargetInfo
*STI
) {
374 const unsigned Opcode
= Inst
.getOpcode();
377 const MCSymbolRefExpr
*OpExpr
=
378 static_cast<const MCSymbolRefExpr
*>(Inst
.getOperand(1).getExpr());
379 XtensaMCExpr::VariantKind Kind
= XtensaMCExpr::VK_Xtensa_None
;
380 const MCExpr
*NewOpExpr
= XtensaMCExpr::create(OpExpr
, Kind
, getContext());
381 Inst
.getOperand(1).setExpr(NewOpExpr
);
385 XtensaTargetStreamer
&TS
= this->getTargetStreamer();
387 // Expand MOVI operand
388 if (!Inst
.getOperand(1).isExpr()) {
389 uint64_t ImmOp64
= Inst
.getOperand(1).getImm();
390 int32_t Imm
= ImmOp64
;
391 if (!isInt
<12>(Imm
)) {
392 XtensaTargetStreamer
&TS
= this->getTargetStreamer();
394 TmpInst
.setLoc(IDLoc
);
395 TmpInst
.setOpcode(Xtensa::L32R
);
396 const MCExpr
*Value
= MCConstantExpr::create(ImmOp64
, getContext());
397 MCSymbol
*Sym
= getContext().createTempSymbol();
398 const MCExpr
*Expr
= MCSymbolRefExpr::create(
399 Sym
, MCSymbolRefExpr::VK_None
, getContext());
400 const MCExpr
*OpExpr
= XtensaMCExpr::create(
401 Expr
, XtensaMCExpr::VK_Xtensa_None
, getContext());
402 TmpInst
.addOperand(Inst
.getOperand(0));
403 MCOperand Op1
= MCOperand::createExpr(OpExpr
);
404 TmpInst
.addOperand(Op1
);
405 TS
.emitLiteral(Sym
, Value
, true, IDLoc
);
410 TmpInst
.setLoc(IDLoc
);
411 TmpInst
.setOpcode(Xtensa::L32R
);
412 const MCExpr
*Value
= Inst
.getOperand(1).getExpr();
413 MCSymbol
*Sym
= getContext().createTempSymbol();
415 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
416 const MCExpr
*OpExpr
= XtensaMCExpr::create(
417 Expr
, XtensaMCExpr::VK_Xtensa_None
, getContext());
418 TmpInst
.addOperand(Inst
.getOperand(0));
419 MCOperand Op1
= MCOperand::createExpr(OpExpr
);
420 TmpInst
.addOperand(Op1
);
422 TS
.emitLiteral(Sym
, Value
, true, IDLoc
);
433 bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
434 OperandVector
&Operands
,
437 bool MatchingInlineAsm
) {
440 MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MatchingInlineAsm
);
446 processInstruction(Inst
, IDLoc
, Out
, STI
);
448 Out
.emitInstruction(Inst
, getSTI());
450 case Match_MissingFeature
:
451 return Error(IDLoc
, "instruction use requires an option to be enabled");
452 case Match_MnemonicFail
:
453 return Error(IDLoc
, "unrecognized instruction mnemonic");
454 case Match_InvalidOperand
: {
455 SMLoc ErrorLoc
= IDLoc
;
456 if (ErrorInfo
!= ~0U) {
457 if (ErrorInfo
>= Operands
.size())
458 return Error(ErrorLoc
, "too few operands for instruction");
460 ErrorLoc
= ((XtensaOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
461 if (ErrorLoc
== SMLoc())
464 return Error(ErrorLoc
, "invalid operand for instruction");
466 case Match_InvalidImm8
:
467 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
468 "expected immediate in range [-128, 127]");
469 case Match_InvalidImm8_sh8
:
470 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
471 "expected immediate in range [-32768, 32512], first 8 bits "
473 case Match_InvalidB4const
:
474 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
475 "expected b4const immediate");
476 case Match_InvalidB4constu
:
477 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
478 "expected b4constu immediate");
479 case Match_InvalidImm12
:
480 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
481 "expected immediate in range [-2048, 2047]");
482 case Match_InvalidImm12m
:
483 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
484 "expected immediate in range [-2048, 2047]");
485 case Match_InvalidImm1_16
:
486 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
487 "expected immediate in range [1, 16]");
488 case Match_InvalidImm1n_15
:
489 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
490 "expected immediate in range [-1, 15] except 0");
491 case Match_InvalidImm32n_95
:
492 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
493 "expected immediate in range [-32, 95]");
494 case Match_InvalidShimm1_31
:
495 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
496 "expected immediate in range [1, 31]");
497 case Match_InvalidUimm4
:
498 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
499 "expected immediate in range [0, 15]");
500 case Match_InvalidUimm5
:
501 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
502 "expected immediate in range [0, 31]");
503 case Match_InvalidOffset8m8
:
504 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
505 "expected immediate in range [0, 255]");
506 case Match_InvalidOffset8m16
:
507 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
508 "expected immediate in range [0, 510], first bit "
510 case Match_InvalidOffset8m32
:
511 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
512 "expected immediate in range [0, 1020], first 2 bits "
514 case Match_InvalidOffset4m32
:
515 return Error(RefineErrorLoc(IDLoc
, Operands
, ErrorInfo
),
516 "expected immediate in range [0, 60], first 2 bits "
520 report_fatal_error("Unknown match type detected!");
523 ParseStatus
XtensaAsmParser::parsePCRelTarget(OperandVector
&Operands
) {
524 MCAsmParser
&Parser
= getParser();
525 LLVM_DEBUG(dbgs() << "parsePCRelTarget\n");
527 SMLoc S
= getLexer().getLoc();
529 // Expressions are acceptable
530 const MCExpr
*Expr
= nullptr;
531 if (Parser
.parseExpression(Expr
)) {
532 // We have no way of knowing if a symbol was consumed so we must ParseFail
533 return ParseStatus::Failure
;
536 // Currently not support constants
537 if (Expr
->getKind() == MCExpr::ExprKind::Constant
)
538 return Error(getLoc(), "unknown operand");
540 Operands
.push_back(XtensaOperand::createImm(Expr
, S
, getLexer().getLoc()));
541 return ParseStatus::Success
;
544 bool XtensaAsmParser::parseRegister(MCRegister
&Reg
, SMLoc
&StartLoc
,
546 const AsmToken
&Tok
= getParser().getTok();
547 StartLoc
= Tok
.getLoc();
548 EndLoc
= Tok
.getEndLoc();
549 Reg
= Xtensa::NoRegister
;
550 StringRef Name
= getLexer().getTok().getIdentifier();
552 if (!MatchRegisterName(Name
) && !MatchRegisterAltName(Name
)) {
553 getParser().Lex(); // Eat identifier token.
557 return Error(StartLoc
, "invalid register name");
560 ParseStatus
XtensaAsmParser::parseRegister(OperandVector
&Operands
,
561 bool AllowParens
, bool SR
) {
562 SMLoc FirstS
= getLoc();
563 bool HadParens
= false;
567 // If this a parenthesised register name is allowed, parse it atomically
568 if (AllowParens
&& getLexer().is(AsmToken::LParen
)) {
569 size_t ReadCount
= getLexer().peekTokens(Buf
);
570 if (ReadCount
== 2 && Buf
[1].getKind() == AsmToken::RParen
) {
571 if ((Buf
[0].getKind() == AsmToken::Integer
) && (!SR
))
572 return ParseStatus::NoMatch
;
574 getParser().Lex(); // Eat '('
580 switch (getLexer().getKind()) {
582 return ParseStatus::NoMatch
;
583 case AsmToken::Integer
:
585 return ParseStatus::NoMatch
;
586 RegName
= getLexer().getTok().getString();
587 RegNo
= MatchRegisterName(RegName
);
589 RegNo
= MatchRegisterAltName(RegName
);
591 case AsmToken::Identifier
:
592 RegName
= getLexer().getTok().getIdentifier();
593 RegNo
= MatchRegisterName(RegName
);
595 RegNo
= MatchRegisterAltName(RegName
);
601 getLexer().UnLex(Buf
[0]);
602 return ParseStatus::NoMatch
;
605 Operands
.push_back(XtensaOperand::createToken("(", FirstS
));
607 SMLoc E
= getParser().getTok().getEndLoc();
609 Operands
.push_back(XtensaOperand::createReg(RegNo
, S
, E
));
612 getParser().Lex(); // Eat ')'
613 Operands
.push_back(XtensaOperand::createToken(")", getLoc()));
616 return ParseStatus::Success
;
619 ParseStatus
XtensaAsmParser::parseImmediate(OperandVector
&Operands
) {
624 switch (getLexer().getKind()) {
626 return ParseStatus::NoMatch
;
627 case AsmToken::LParen
:
628 case AsmToken::Minus
:
630 case AsmToken::Tilde
:
631 case AsmToken::Integer
:
632 case AsmToken::String
:
633 if (getParser().parseExpression(Res
))
634 return ParseStatus::Failure
;
636 case AsmToken::Identifier
: {
637 StringRef Identifier
;
638 if (getParser().parseIdentifier(Identifier
))
639 return ParseStatus::Failure
;
641 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Identifier
);
642 Res
= MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
645 case AsmToken::Percent
:
646 return parseOperandWithModifier(Operands
);
649 E
= SMLoc::getFromPointer(S
.getPointer() - 1);
650 Operands
.push_back(XtensaOperand::createImm(Res
, S
, E
));
651 return ParseStatus::Success
;
654 ParseStatus
XtensaAsmParser::parseOperandWithModifier(OperandVector
&Operands
) {
655 return ParseStatus::Failure
;
658 /// Looks at a token type and creates the relevant operand
659 /// from this information, adding to Operands.
660 /// If operand was parsed, returns false, else true.
661 bool XtensaAsmParser::parseOperand(OperandVector
&Operands
, StringRef Mnemonic
,
663 // Check if the current operand has a custom associated parser, if so, try to
664 // custom parse the operand, or fallback to the general approach.
665 ParseStatus Res
= MatchOperandParserImpl(Operands
, Mnemonic
);
669 // If there wasn't a custom match, try the generic matcher below. Otherwise,
670 // there was a match, but an error occurred, in which case, just return that
671 // the operand parsing failed.
675 // Attempt to parse token as register
676 if (parseRegister(Operands
, true, SR
).isSuccess())
679 // Attempt to parse token as an immediate
680 if (parseImmediate(Operands
).isSuccess())
683 // Finally we have exhausted all options and must declare defeat.
684 return Error(getLoc(), "unknown operand");
687 bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo
&Info
,
688 StringRef Name
, SMLoc NameLoc
,
689 OperandVector
&Operands
) {
690 if ((Name
.starts_with("wsr.") || Name
.starts_with("rsr.") ||
691 Name
.starts_with("xsr.")) &&
693 // Parse case when instruction name is concatenated with SR register
694 // name, like "wsr.sar a1"
696 // First operand is token for instruction
697 Operands
.push_back(XtensaOperand::createToken(Name
.take_front(3), NameLoc
));
699 StringRef RegName
= Name
.drop_front(4);
700 unsigned RegNo
= MatchRegisterName(RegName
);
703 RegNo
= MatchRegisterAltName(RegName
);
706 return Error(NameLoc
, "invalid register name");
709 if (parseOperand(Operands
, Name
))
713 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
714 Operands
.push_back(XtensaOperand::createReg(RegNo
, S
, E
));
716 // First operand is token for instruction
717 Operands
.push_back(XtensaOperand::createToken(Name
, NameLoc
));
719 // Parse first operand
720 if (parseOperand(Operands
, Name
))
723 if (!parseOptionalToken(AsmToken::Comma
)) {
724 SMLoc Loc
= getLexer().getLoc();
725 getParser().eatToEndOfStatement();
726 return Error(Loc
, "unexpected token");
729 // Parse second operand
730 if (parseOperand(Operands
, Name
, true))
734 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
735 SMLoc Loc
= getLexer().getLoc();
736 getParser().eatToEndOfStatement();
737 return Error(Loc
, "unexpected token");
740 getParser().Lex(); // Consume the EndOfStatement.
744 bool XtensaAsmParser::parseInstruction(ParseInstructionInfo
&Info
,
745 StringRef Name
, SMLoc NameLoc
,
746 OperandVector
&Operands
) {
747 if (Name
.starts_with("wsr") || Name
.starts_with("rsr") ||
748 Name
.starts_with("xsr")) {
749 return ParseInstructionWithSR(Info
, Name
, NameLoc
, Operands
);
752 // First operand is token for instruction
753 Operands
.push_back(XtensaOperand::createToken(Name
, NameLoc
));
755 // If there are no more operands, then finish
756 if (getLexer().is(AsmToken::EndOfStatement
))
759 // Parse first operand
760 if (parseOperand(Operands
, Name
))
763 // Parse until end of statement, consuming commas between operands
764 while (parseOptionalToken(AsmToken::Comma
))
765 if (parseOperand(Operands
, Name
))
768 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
769 SMLoc Loc
= getLexer().getLoc();
770 getParser().eatToEndOfStatement();
771 return Error(Loc
, "unexpected token");
774 getParser().Lex(); // Consume the EndOfStatement.
778 bool XtensaAsmParser::parseLiteralDirective(SMLoc L
) {
779 MCAsmParser
&Parser
= getParser();
781 SMLoc LiteralLoc
= getLexer().getLoc();
782 XtensaTargetStreamer
&TS
= this->getTargetStreamer();
784 if (Parser
.parseExpression(Value
))
787 const MCSymbolRefExpr
*SE
= dyn_cast
<MCSymbolRefExpr
>(Value
);
790 return Error(LiteralLoc
, "literal label must be a symbol");
792 if (Parser
.parseComma())
795 SMLoc OpcodeLoc
= getLexer().getLoc();
796 if (parseOptionalToken(AsmToken::EndOfStatement
))
797 return Error(OpcodeLoc
, "expected value");
799 if (Parser
.parseExpression(Value
))
805 MCSymbol
*Sym
= getContext().getOrCreateSymbol(SE
->getSymbol().getName());
807 TS
.emitLiteral(Sym
, Value
, true, LiteralLoc
);
812 ParseStatus
XtensaAsmParser::parseDirective(AsmToken DirectiveID
) {
813 StringRef IDVal
= DirectiveID
.getString();
814 SMLoc Loc
= getLexer().getLoc();
816 if (IDVal
== ".literal_position") {
817 XtensaTargetStreamer
&TS
= this->getTargetStreamer();
818 TS
.emitLiteralPosition();
822 if (IDVal
== ".literal") {
823 return parseLiteralDirective(Loc
);
826 return ParseStatus::NoMatch
;
829 // Force static initialization.
830 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeXtensaAsmParser() {
831 RegisterMCAsmParser
<XtensaAsmParser
> X(getTheXtensaTarget());