LLVM 19.0.0git
XtensaAsmParser.cpp
Go to the documentation of this file.
1//===- XtensaAsmParser.cpp - Parse Xtensa assembly to MCInst instructions -===//
2//
3// The LLVM Compiler Infrastructure
4//
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
8//
9//===----------------------------------------------------------------------===//
10
15#include "llvm/ADT/STLExtras.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"
25#include "llvm/MC/MCStreamer.h"
27#include "llvm/MC/MCSymbol.h"
30
31using namespace llvm;
32
33#define DEBUG_TYPE "xtensa-asm-parser"
34
35struct XtensaOperand;
36
38
39 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
40
41 XtensaTargetStreamer &getTargetStreamer() {
43 return static_cast<XtensaTargetStreamer &>(TS);
44 }
45
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,
53 bool MatchingInlineAsm) override;
54 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
55 unsigned Kind) override;
56
57 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
58 const MCSubtargetInfo *STI);
59
60// Auto-generated instruction matching functions
61#define GET_ASSEMBLER_HEADER
62#include "XtensaGenAsmMatcher.inc"
63
64 ParseStatus parseImmediate(OperandVector &Operands);
65 ParseStatus parseRegister(OperandVector &Operands, bool AllowParens = false,
66 bool SR = false);
67 ParseStatus parseOperandWithModifier(OperandVector &Operands);
68 bool parseOperand(OperandVector &Operands, StringRef Mnemonic,
69 bool SR = false);
70 bool ParseInstructionWithSR(ParseInstructionInfo &Info, StringRef Name,
71 SMLoc NameLoc, OperandVector &Operands);
72 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
73 SMLoc &EndLoc) override {
75 }
76 ParseStatus parsePCRelTarget(OperandVector &Operands);
77 bool parseLiteralDirective(SMLoc L);
78
79public:
82#define GET_OPERAND_DIAGNOSTIC_TYPES
83#include "XtensaGenAsmMatcher.inc"
84#undef GET_OPERAND_DIAGNOSTIC_TYPES
85 };
86
90 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
91 }
92};
93
94// Return true if Expr is in the range [MinValue, MaxValue].
95static 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;
99 }
100 return false;
101}
102
104
105 enum KindTy {
110
111 struct RegOp {
112 unsigned RegNum;
113 };
114
115 struct ImmOp {
116 const MCExpr *Val;
117 };
118
120 union {
124 };
125
127
128public:
130 Kind = o.Kind;
131 StartLoc = o.StartLoc;
132 EndLoc = o.EndLoc;
133 switch (Kind) {
134 case Register:
135 Reg = o.Reg;
136 break;
137 case Immediate:
138 Imm = o.Imm;
139 break;
140 case Token:
141 Tok = o.Tok;
142 break;
143 }
144 }
145
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; }
150
151 bool isImm(int64_t MinValue, int64_t MaxValue) const {
152 return Kind == Immediate && inRange(getImm(), MinValue, MaxValue);
153 }
154
155 bool isImm8() const { return isImm(-128, 127); }
156
157 bool isImm8_sh8() const {
158 return isImm(-32768, 32512) &&
159 ((cast<MCConstantExpr>(getImm())->getValue() & 0xFF) == 0);
160 }
161
162 bool isImm12() const { return isImm(-2048, 2047); }
163
164 // Convert MOVI to literal load, when immediate is not in range (-2048, 2047)
165 bool isImm12m() const { return Kind == Immediate; }
166
167 bool isOffset4m32() const {
168 return isImm(0, 60) &&
169 ((cast<MCConstantExpr>(getImm())->getValue() & 0x3) == 0);
170 }
171
172 bool isOffset8m8() const { return isImm(0, 255); }
173
174 bool isOffset8m16() const {
175 return isImm(0, 510) &&
176 ((cast<MCConstantExpr>(getImm())->getValue() & 0x1) == 0);
177 }
178
179 bool isOffset8m32() const {
180 return isImm(0, 1020) &&
181 ((cast<MCConstantExpr>(getImm())->getValue() & 0x3) == 0);
182 }
183
184 bool isUimm4() const { return isImm(0, 15); }
185
186 bool isUimm5() const { return isImm(0, 31); }
187
188 bool isImm8n_7() const { return isImm(-8, 7); }
189
190 bool isShimm1_31() const { return isImm(1, 31); }
191
192 bool isImm16_31() const { return isImm(16, 31); }
193
194 bool isImm1_16() const { return isImm(1, 16); }
195
196 bool isB4const() const {
197 if (Kind != Immediate)
198 return false;
199 if (auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
200 int64_t Value = CE->getValue();
201 switch (Value) {
202 case -1:
203 case 1:
204 case 2:
205 case 3:
206 case 4:
207 case 5:
208 case 6:
209 case 7:
210 case 8:
211 case 10:
212 case 12:
213 case 16:
214 case 32:
215 case 64:
216 case 128:
217 case 256:
218 return true;
219 default:
220 return false;
221 }
222 }
223 return false;
224 }
225
226 bool isB4constu() const {
227 if (Kind != Immediate)
228 return false;
229 if (auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
230 int64_t Value = CE->getValue();
231 switch (Value) {
232 case 32768:
233 case 65536:
234 case 2:
235 case 3:
236 case 4:
237 case 5:
238 case 6:
239 case 7:
240 case 8:
241 case 10:
242 case 12:
243 case 16:
244 case 32:
245 case 64:
246 case 128:
247 case 256:
248 return true;
249 default:
250 return false;
251 }
252 }
253 return false;
254 }
255
256 /// getStartLoc - Gets location of the first token of this operand
257 SMLoc getStartLoc() const override { return StartLoc; }
258 /// getEndLoc - Gets location of the last token of this operand
259 SMLoc getEndLoc() const override { return EndLoc; }
260
261 MCRegister getReg() const override {
262 assert(Kind == Register && "Invalid type access!");
263 return Reg.RegNum;
264 }
265
266 const MCExpr *getImm() const {
267 assert(Kind == Immediate && "Invalid type access!");
268 return Imm.Val;
269 }
270
272 assert(Kind == Token && "Invalid type access!");
273 return Tok;
274 }
275
276 void print(raw_ostream &OS) const override {
277 switch (Kind) {
278 case Immediate:
279 OS << *getImm();
280 break;
281 case Register:
282 OS << "<register x";
283 OS << getReg() << ">";
284 break;
285 case Token:
286 OS << "'" << getToken() << "'";
287 break;
288 }
289 }
290
291 static std::unique_ptr<XtensaOperand> createToken(StringRef Str, SMLoc S) {
292 auto Op = std::make_unique<XtensaOperand>(Token);
293 Op->Tok = Str;
294 Op->StartLoc = S;
295 Op->EndLoc = S;
296 return Op;
297 }
298
299 static std::unique_ptr<XtensaOperand> createReg(unsigned RegNo, SMLoc S,
300 SMLoc E) {
301 auto Op = std::make_unique<XtensaOperand>(Register);
302 Op->Reg.RegNum = RegNo;
303 Op->StartLoc = S;
304 Op->EndLoc = E;
305 return Op;
306 }
307
308 static std::unique_ptr<XtensaOperand> createImm(const MCExpr *Val, SMLoc S,
309 SMLoc E) {
310 auto Op = std::make_unique<XtensaOperand>(Immediate);
311 Op->Imm.Val = Val;
312 Op->StartLoc = S;
313 Op->EndLoc = E;
314 return Op;
315 }
316
317 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
318 assert(Expr && "Expr shouldn't be null!");
319 int64_t Imm = 0;
320 bool IsConstant = false;
321
322 if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
323 IsConstant = true;
324 Imm = CE->getValue();
325 }
326
327 if (IsConstant)
329 else
331 }
332
333 // Used by the TableGen Code
334 void addRegOperands(MCInst &Inst, unsigned N) const {
335 assert(N == 1 && "Invalid number of operands!");
337 }
338
339 void addImmOperands(MCInst &Inst, unsigned N) const {
340 assert(N == 1 && "Invalid number of operands!");
341 addExpr(Inst, getImm());
342 }
343};
344
345#define GET_REGISTER_MATCHER
346#define GET_MATCHER_IMPLEMENTATION
347#include "XtensaGenAsmMatcher.inc"
348
349unsigned XtensaAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
350 unsigned Kind) {
352}
353
356 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
357 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
358 if (ErrorLoc == SMLoc())
359 return Loc;
360 return ErrorLoc;
361 }
362 return Loc;
363}
364
365bool XtensaAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
366 MCStreamer &Out,
367 const MCSubtargetInfo *STI) {
368 Inst.setLoc(IDLoc);
369 const unsigned Opcode = Inst.getOpcode();
370 switch (Opcode) {
371 case Xtensa::L32R: {
372 const MCSymbolRefExpr *OpExpr =
373 static_cast<const MCSymbolRefExpr *>(Inst.getOperand(1).getExpr());
375 const MCExpr *NewOpExpr = XtensaMCExpr::create(OpExpr, Kind, getContext());
376 Inst.getOperand(1).setExpr(NewOpExpr);
377 break;
378 }
379 case Xtensa::MOVI: {
380 XtensaTargetStreamer &TS = this->getTargetStreamer();
381
382 // Expand MOVI operand
383 if (!Inst.getOperand(1).isExpr()) {
384 uint64_t ImmOp64 = Inst.getOperand(1).getImm();
385 int32_t Imm = ImmOp64;
386 if (!isInt<12>(Imm)) {
387 XtensaTargetStreamer &TS = this->getTargetStreamer();
388 MCInst TmpInst;
389 TmpInst.setLoc(IDLoc);
390 TmpInst.setOpcode(Xtensa::L32R);
391 const MCExpr *Value = MCConstantExpr::create(ImmOp64, getContext());
393 const MCExpr *Expr = MCSymbolRefExpr::create(
395 const MCExpr *OpExpr = XtensaMCExpr::create(
397 TmpInst.addOperand(Inst.getOperand(0));
398 MCOperand Op1 = MCOperand::createExpr(OpExpr);
399 TmpInst.addOperand(Op1);
400 TS.emitLiteral(Sym, Value, true, IDLoc);
401 Inst = TmpInst;
402 }
403 } else {
404 MCInst TmpInst;
405 TmpInst.setLoc(IDLoc);
406 TmpInst.setOpcode(Xtensa::L32R);
407 const MCExpr *Value = Inst.getOperand(1).getExpr();
409 const MCExpr *Expr =
411 const MCExpr *OpExpr = XtensaMCExpr::create(
413 TmpInst.addOperand(Inst.getOperand(0));
414 MCOperand Op1 = MCOperand::createExpr(OpExpr);
415 TmpInst.addOperand(Op1);
416 Inst = TmpInst;
417 TS.emitLiteral(Sym, Value, true, IDLoc);
418 }
419 break;
420 }
421 default:
422 break;
423 }
424
425 return true;
426}
427
428bool XtensaAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
430 MCStreamer &Out,
432 bool MatchingInlineAsm) {
433 MCInst Inst;
434 auto Result =
435 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
436
437 switch (Result) {
438 default:
439 break;
440 case Match_Success:
441 processInstruction(Inst, IDLoc, Out, STI);
442 Inst.setLoc(IDLoc);
443 Out.emitInstruction(Inst, getSTI());
444 return false;
446 return Error(IDLoc, "instruction use requires an option to be enabled");
448 return Error(IDLoc, "unrecognized instruction mnemonic");
450 SMLoc ErrorLoc = IDLoc;
451 if (ErrorInfo != ~0U) {
452 if (ErrorInfo >= Operands.size())
453 return Error(ErrorLoc, "too few operands for instruction");
454
455 ErrorLoc = ((XtensaOperand &)*Operands[ErrorInfo]).getStartLoc();
456 if (ErrorLoc == SMLoc())
457 ErrorLoc = IDLoc;
458 }
459 return Error(ErrorLoc, "invalid operand for instruction");
460 }
461 case Match_InvalidImm8:
462 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
463 "expected immediate in range [-128, 127]");
464 case Match_InvalidImm8_sh8:
465 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
466 "expected immediate in range [-32768, 32512], first 8 bits "
467 "should be zero");
468 case Match_InvalidB4const:
469 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
470 "expected b4const immediate");
471 case Match_InvalidB4constu:
472 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
473 "expected b4constu immediate");
474 case Match_InvalidImm12:
475 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
476 "expected immediate in range [-2048, 2047]");
477 case Match_InvalidImm12m:
478 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
479 "expected immediate in range [-2048, 2047]");
480 case Match_InvalidImm1_16:
481 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
482 "expected immediate in range [1, 16]");
483 case Match_InvalidShimm1_31:
484 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
485 "expected immediate in range [1, 31]");
486 case Match_InvalidUimm4:
487 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
488 "expected immediate in range [0, 15]");
489 case Match_InvalidUimm5:
490 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
491 "expected immediate in range [0, 31]");
492 case Match_InvalidOffset8m8:
493 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
494 "expected immediate in range [0, 255]");
495 case Match_InvalidOffset8m16:
496 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
497 "expected immediate in range [0, 510], first bit "
498 "should be zero");
499 case Match_InvalidOffset8m32:
500 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
501 "expected immediate in range [0, 1020], first 2 bits "
502 "should be zero");
503 case Match_InvalidOffset4m32:
504 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
505 "expected immediate in range [0, 60], first 2 bits "
506 "should be zero");
507 }
508
509 report_fatal_error("Unknown match type detected!");
510}
511
512ParseStatus XtensaAsmParser::parsePCRelTarget(OperandVector &Operands) {
513 MCAsmParser &Parser = getParser();
514 LLVM_DEBUG(dbgs() << "parsePCRelTarget\n");
515
516 SMLoc S = getLexer().getLoc();
517
518 // Expressions are acceptable
519 const MCExpr *Expr = nullptr;
520 if (Parser.parseExpression(Expr)) {
521 // We have no way of knowing if a symbol was consumed so we must ParseFail
523 }
524
525 // Currently not support constants
526 if (Expr->getKind() == MCExpr::ExprKind::Constant)
527 return Error(getLoc(), "unknown operand");
528
529 Operands.push_back(XtensaOperand::createImm(Expr, S, getLexer().getLoc()));
531}
532
533bool XtensaAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
534 SMLoc &EndLoc) {
535 const AsmToken &Tok = getParser().getTok();
536 StartLoc = Tok.getLoc();
537 EndLoc = Tok.getEndLoc();
538 Reg = Xtensa::NoRegister;
540
542 getParser().Lex(); // Eat identifier token.
543 return false;
544 }
545
546 return Error(StartLoc, "invalid register name");
547}
548
549ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
550 bool AllowParens, bool SR) {
551 SMLoc FirstS = getLoc();
552 bool HadParens = false;
553 AsmToken Buf[2];
555
556 // If this a parenthesised register name is allowed, parse it atomically
557 if (AllowParens && getLexer().is(AsmToken::LParen)) {
558 size_t ReadCount = getLexer().peekTokens(Buf);
559 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
560 if ((Buf[0].getKind() == AsmToken::Integer) && (!SR))
562 HadParens = true;
563 getParser().Lex(); // Eat '('
564 }
565 }
566
567 unsigned RegNo = 0;
568
569 switch (getLexer().getKind()) {
570 default:
573 if (!SR)
575 RegName = StringRef(std::to_string(getLexer().getTok().getIntVal()));
576 RegNo = MatchRegisterName(RegName);
577 if (RegNo == 0)
579 break;
582 RegNo = MatchRegisterName(RegName);
583 if (RegNo == 0)
585 break;
586 }
587
588 if (RegNo == 0) {
589 if (HadParens)
590 getLexer().UnLex(Buf[0]);
592 }
593 if (HadParens)
594 Operands.push_back(XtensaOperand::createToken("(", FirstS));
595 SMLoc S = getLoc();
597 getLexer().Lex();
598 Operands.push_back(XtensaOperand::createReg(RegNo, S, E));
599
600 if (HadParens) {
601 getParser().Lex(); // Eat ')'
602 Operands.push_back(XtensaOperand::createToken(")", getLoc()));
603 }
604
606}
607
608ParseStatus XtensaAsmParser::parseImmediate(OperandVector &Operands) {
609 SMLoc S = getLoc();
610 SMLoc E;
611 const MCExpr *Res;
612
613 switch (getLexer().getKind()) {
614 default:
616 case AsmToken::LParen:
617 case AsmToken::Minus:
618 case AsmToken::Plus:
619 case AsmToken::Tilde:
621 case AsmToken::String:
622 if (getParser().parseExpression(Res))
624 break;
627 if (getParser().parseIdentifier(Identifier))
629
630 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
632 break;
633 }
635 return parseOperandWithModifier(Operands);
636 }
637
639 Operands.push_back(XtensaOperand::createImm(Res, S, E));
641}
642
643ParseStatus XtensaAsmParser::parseOperandWithModifier(OperandVector &Operands) {
645}
646
647/// Looks at a token type and creates the relevant operand
648/// from this information, adding to Operands.
649/// If operand was parsed, returns false, else true.
650bool XtensaAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic,
651 bool SR) {
652 // Check if the current operand has a custom associated parser, if so, try to
653 // custom parse the operand, or fallback to the general approach.
654 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
655 if (Res.isSuccess())
656 return false;
657
658 // If there wasn't a custom match, try the generic matcher below. Otherwise,
659 // there was a match, but an error occurred, in which case, just return that
660 // the operand parsing failed.
661 if (Res.isFailure())
662 return true;
663
664 // Attempt to parse token as register
665 if (parseRegister(Operands, true, SR).isSuccess())
666 return false;
667
668 // Attempt to parse token as an immediate
669 if (parseImmediate(Operands).isSuccess())
670 return false;
671
672 // Finally we have exhausted all options and must declare defeat.
673 return Error(getLoc(), "unknown operand");
674}
675
676bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
677 StringRef Name, SMLoc NameLoc,
679 if ((Name.starts_with("wsr.") || Name.starts_with("rsr.") ||
680 Name.starts_with("xsr.")) &&
681 (Name.size() > 4)) {
682 // Parse case when instruction name is concatenated with SR register
683 // name, like "wsr.sar a1"
684
685 // First operand is token for instruction
686 Operands.push_back(XtensaOperand::createToken(Name.take_front(3), NameLoc));
687
688 StringRef RegName = Name.drop_front(4);
689 unsigned RegNo = MatchRegisterName(RegName);
690
691 if (RegNo == 0)
693
694 if (RegNo == 0)
695 return Error(NameLoc, "invalid register name");
696
697 // Parse operand
698 if (parseOperand(Operands, Name))
699 return true;
700
701 SMLoc S = getLoc();
703 Operands.push_back(XtensaOperand::createReg(RegNo, S, E));
704 } else {
705 // First operand is token for instruction
706 Operands.push_back(XtensaOperand::createToken(Name, NameLoc));
707
708 // Parse first operand
709 if (parseOperand(Operands, Name))
710 return true;
711
713 SMLoc Loc = getLexer().getLoc();
715 return Error(Loc, "unexpected token");
716 }
717
718 // Parse second operand
719 if (parseOperand(Operands, Name, true))
720 return true;
721 }
722
724 SMLoc Loc = getLexer().getLoc();
726 return Error(Loc, "unexpected token");
727 }
728
729 getParser().Lex(); // Consume the EndOfStatement.
730 return false;
731}
732
733bool XtensaAsmParser::ParseInstruction(ParseInstructionInfo &Info,
734 StringRef Name, SMLoc NameLoc,
736 if (Name.starts_with("wsr") || Name.starts_with("rsr") ||
737 Name.starts_with("xsr")) {
738 return ParseInstructionWithSR(Info, Name, NameLoc, Operands);
739 }
740
741 // First operand is token for instruction
742 Operands.push_back(XtensaOperand::createToken(Name, NameLoc));
743
744 // If there are no more operands, then finish
746 return false;
747
748 // Parse first operand
749 if (parseOperand(Operands, Name))
750 return true;
751
752 // Parse until end of statement, consuming commas between operands
754 if (parseOperand(Operands, Name))
755 return true;
756
758 SMLoc Loc = getLexer().getLoc();
760 return Error(Loc, "unexpected token");
761 }
762
763 getParser().Lex(); // Consume the EndOfStatement.
764 return false;
765}
766
767bool XtensaAsmParser::parseLiteralDirective(SMLoc L) {
768 MCAsmParser &Parser = getParser();
769 const MCExpr *Value;
770 SMLoc LiteralLoc = getLexer().getLoc();
771 XtensaTargetStreamer &TS = this->getTargetStreamer();
772
773 if (Parser.parseExpression(Value))
774 return true;
775
776 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Value);
777
778 if (!SE)
779 return Error(LiteralLoc, "literal label must be a symbol");
780
781 if (Parser.parseComma())
782 return true;
783
784 SMLoc OpcodeLoc = getLexer().getLoc();
786 return Error(OpcodeLoc, "expected value");
787
788 if (Parser.parseExpression(Value))
789 return true;
790
791 if (parseEOL())
792 return true;
793
795
796 TS.emitLiteral(Sym, Value, true, LiteralLoc);
797
798 return false;
799}
800
801ParseStatus XtensaAsmParser::parseDirective(AsmToken DirectiveID) {
802 StringRef IDVal = DirectiveID.getString();
803 SMLoc Loc = getLexer().getLoc();
804
805 if (IDVal == ".literal_position") {
806 XtensaTargetStreamer &TS = this->getTargetStreamer();
808 return parseEOL();
809 }
810
811 if (IDVal == ".literal") {
812 return parseLiteralDirective(Loc);
813 }
814
816}
817
818// Force static initialization.
821}
static MCRegister MatchRegisterName(StringRef Name)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:135
#define LLVM_DEBUG(X)
Definition: Debug.h:101
std::string Name
Symbol * Sym
Definition: ELF_riscv.cpp:479
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
#define RegName(no)
static LVOptions Options
Definition: LVOptions.cpp:25
mir Rename Register Operands
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
raw_pwrite_stream & OS
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeXtensaAsmParser()
static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands, uint64_t ErrorInfo)
XtensaAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, const MCInstrInfo &MII, const MCTargetOptions &Options)
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:21
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:26
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:110
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:30
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Definition: MCAsmMacro.h:99
This class represents an Operation in the Expression.
Base class for user error types.
Definition: Error.h:352
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
void UnLex(AsmToken const &Token)
Definition: MCAsmLexer.h:93
SMLoc getLoc() const
Get the current source location.
Definition: MCAsmLexer.cpp:22
const AsmToken & getTok() const
Get the current (last) lexed token.
Definition: MCAsmLexer.h:106
const AsmToken & Lex()
Consume the next token from the input stream and return it.
Definition: MCAsmLexer.h:79
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
bool parseOptionalToken(AsmToken::TokenKind T)
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:123
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:40
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:322
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:201
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
ExprKind getKind() const
Definition: MCExpr.h:81
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
void setLoc(SMLoc loc)
Definition: MCInst.h:203
unsigned getOpcode() const
Definition: MCInst.h:198
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
void setOpcode(unsigned Op)
Definition: MCInst.h:197
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
void setExpr(const MCExpr *Val)
Definition: MCInst.h:119
int64_t getImm() const
Definition: MCInst.h:80
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
const MCExpr * getExpr() const
Definition: MCInst.h:114
bool isExpr() const
Definition: MCInst.h:65
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
Streaming machine code generation interface.
Definition: MCStreamer.h:212
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:304
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:410
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:397
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCInstrInfo & MII
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
const MCSubtargetInfo * STI
Current STI.
Target specific streamer interface.
Definition: MCStreamer.h:93
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
Represents a location in source code.
Definition: SMLoc.h:23
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
constexpr const char * getPointer() const
Definition: SMLoc.h:34
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
LLVM Value Representation.
Definition: Value.h:74
static const XtensaMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
virtual void emitLiteralPosition()=0
virtual void emitLiteral(MCSymbol *LblSym, const MCExpr *Value, bool SwitchLiteralSection, SMLoc L=SMLoc())=0
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
Target & getTheXtensaTarget()
DWARFExpression::Operation Op
#define N
bool isImm12() const
bool isOffset4m32() const
bool isOffset8m16() const
static std::unique_ptr< XtensaOperand > createToken(StringRef Str, SMLoc S)
bool isImm8_sh8() const
void addRegOperands(MCInst &Inst, unsigned N) const
void addExpr(MCInst &Inst, const MCExpr *Expr) const
void addImmOperands(MCInst &Inst, unsigned N) const
StringRef getToken() const
enum XtensaOperand::KindTy Kind
bool isMem() const override
isMem - Is this a memory operand?
bool isImm16_31() const
bool isImm8n_7() const
bool isToken() const override
isToken - Is this a token operand?
MCRegister getReg() const override
SMLoc getStartLoc() const override
getStartLoc - Gets location of the first token of this operand
bool isImm8() const
bool isImm(int64_t MinValue, int64_t MaxValue) const
void print(raw_ostream &OS) const override
print - Print a debug representation of the operand to the given stream.
bool isImm12m() const
bool isReg() const override
isReg - Is this a register operand?
XtensaOperand(KindTy K)
bool isB4constu() const
bool isImm() const override
isImm - Is this an immediate operand?
bool isUimm4() const
static std::unique_ptr< XtensaOperand > createReg(unsigned RegNo, SMLoc S, SMLoc E)
SMLoc getEndLoc() const override
getEndLoc - Gets location of the last token of this operand
const MCExpr * getImm() const
bool isUimm5() const
bool isOffset8m8() const
XtensaOperand(const XtensaOperand &o)
bool isImm1_16() const
bool isB4const() const
static std::unique_ptr< XtensaOperand > createImm(const MCExpr *Val, SMLoc S, SMLoc E)
bool isOffset8m32() const
bool isShimm1_31() const
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...