LLVM 20.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 // Check that value is either equals (-1) or from [1,15] range.
197 bool isImm1n_15() const { return isImm(1, 15) || isImm(-1, -1); }
198
199 bool isImm32n_95() const { return isImm(-32, 95); }
200
201 bool isB4const() const {
202 if (Kind != Immediate)
203 return false;
204 if (auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
205 int64_t Value = CE->getValue();
206 switch (Value) {
207 case -1:
208 case 1:
209 case 2:
210 case 3:
211 case 4:
212 case 5:
213 case 6:
214 case 7:
215 case 8:
216 case 10:
217 case 12:
218 case 16:
219 case 32:
220 case 64:
221 case 128:
222 case 256:
223 return true;
224 default:
225 return false;
226 }
227 }
228 return false;
229 }
230
231 bool isB4constu() const {
232 if (Kind != Immediate)
233 return false;
234 if (auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
235 int64_t Value = CE->getValue();
236 switch (Value) {
237 case 32768:
238 case 65536:
239 case 2:
240 case 3:
241 case 4:
242 case 5:
243 case 6:
244 case 7:
245 case 8:
246 case 10:
247 case 12:
248 case 16:
249 case 32:
250 case 64:
251 case 128:
252 case 256:
253 return true;
254 default:
255 return false;
256 }
257 }
258 return false;
259 }
260
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; }
265
266 MCRegister getReg() const override {
267 assert(Kind == Register && "Invalid type access!");
268 return Reg.RegNum;
269 }
270
271 const MCExpr *getImm() const {
272 assert(Kind == Immediate && "Invalid type access!");
273 return Imm.Val;
274 }
275
277 assert(Kind == Token && "Invalid type access!");
278 return Tok;
279 }
280
281 void print(raw_ostream &OS) const override {
282 switch (Kind) {
283 case Immediate:
284 OS << *getImm();
285 break;
286 case Register:
287 OS << "<register x";
288 OS << getReg() << ">";
289 break;
290 case Token:
291 OS << "'" << getToken() << "'";
292 break;
293 }
294 }
295
296 static std::unique_ptr<XtensaOperand> createToken(StringRef Str, SMLoc S) {
297 auto Op = std::make_unique<XtensaOperand>(Token);
298 Op->Tok = Str;
299 Op->StartLoc = S;
300 Op->EndLoc = S;
301 return Op;
302 }
303
304 static std::unique_ptr<XtensaOperand> createReg(unsigned RegNo, SMLoc S,
305 SMLoc E) {
306 auto Op = std::make_unique<XtensaOperand>(Register);
307 Op->Reg.RegNum = RegNo;
308 Op->StartLoc = S;
309 Op->EndLoc = E;
310 return Op;
311 }
312
313 static std::unique_ptr<XtensaOperand> createImm(const MCExpr *Val, SMLoc S,
314 SMLoc E) {
315 auto Op = std::make_unique<XtensaOperand>(Immediate);
316 Op->Imm.Val = Val;
317 Op->StartLoc = S;
318 Op->EndLoc = E;
319 return Op;
320 }
321
322 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
323 assert(Expr && "Expr shouldn't be null!");
324 int64_t Imm = 0;
325 bool IsConstant = false;
326
327 if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
328 IsConstant = true;
329 Imm = CE->getValue();
330 }
331
332 if (IsConstant)
334 else
336 }
337
338 // Used by the TableGen Code
339 void addRegOperands(MCInst &Inst, unsigned N) const {
340 assert(N == 1 && "Invalid number of operands!");
342 }
343
344 void addImmOperands(MCInst &Inst, unsigned N) const {
345 assert(N == 1 && "Invalid number of operands!");
346 addExpr(Inst, getImm());
347 }
348};
349
350#define GET_REGISTER_MATCHER
351#define GET_MATCHER_IMPLEMENTATION
352#include "XtensaGenAsmMatcher.inc"
353
354unsigned XtensaAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
355 unsigned Kind) {
357}
358
361 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
362 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
363 if (ErrorLoc == SMLoc())
364 return Loc;
365 return ErrorLoc;
366 }
367 return Loc;
368}
369
370bool XtensaAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
371 MCStreamer &Out,
372 const MCSubtargetInfo *STI) {
373 Inst.setLoc(IDLoc);
374 const unsigned Opcode = Inst.getOpcode();
375 switch (Opcode) {
376 case Xtensa::L32R: {
377 const MCSymbolRefExpr *OpExpr =
378 static_cast<const MCSymbolRefExpr *>(Inst.getOperand(1).getExpr());
380 const MCExpr *NewOpExpr = XtensaMCExpr::create(OpExpr, Kind, getContext());
381 Inst.getOperand(1).setExpr(NewOpExpr);
382 break;
383 }
384 case Xtensa::MOVI: {
385 XtensaTargetStreamer &TS = this->getTargetStreamer();
386
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();
393 MCInst TmpInst;
394 TmpInst.setLoc(IDLoc);
395 TmpInst.setOpcode(Xtensa::L32R);
396 const MCExpr *Value = MCConstantExpr::create(ImmOp64, getContext());
398 const MCExpr *Expr = MCSymbolRefExpr::create(
400 const MCExpr *OpExpr = XtensaMCExpr::create(
402 TmpInst.addOperand(Inst.getOperand(0));
403 MCOperand Op1 = MCOperand::createExpr(OpExpr);
404 TmpInst.addOperand(Op1);
405 TS.emitLiteral(Sym, Value, true, IDLoc);
406 Inst = TmpInst;
407 }
408 } else {
409 MCInst TmpInst;
410 TmpInst.setLoc(IDLoc);
411 TmpInst.setOpcode(Xtensa::L32R);
412 const MCExpr *Value = Inst.getOperand(1).getExpr();
414 const MCExpr *Expr =
416 const MCExpr *OpExpr = XtensaMCExpr::create(
418 TmpInst.addOperand(Inst.getOperand(0));
419 MCOperand Op1 = MCOperand::createExpr(OpExpr);
420 TmpInst.addOperand(Op1);
421 Inst = TmpInst;
422 TS.emitLiteral(Sym, Value, true, IDLoc);
423 }
424 break;
425 }
426 default:
427 break;
428 }
429
430 return true;
431}
432
433bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
435 MCStreamer &Out,
437 bool MatchingInlineAsm) {
438 MCInst Inst;
439 auto Result =
440 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
441
442 switch (Result) {
443 default:
444 break;
445 case Match_Success:
446 processInstruction(Inst, IDLoc, Out, STI);
447 Inst.setLoc(IDLoc);
448 Out.emitInstruction(Inst, getSTI());
449 return false;
451 return Error(IDLoc, "instruction use requires an option to be enabled");
453 return Error(IDLoc, "unrecognized instruction mnemonic");
455 SMLoc ErrorLoc = IDLoc;
456 if (ErrorInfo != ~0U) {
457 if (ErrorInfo >= Operands.size())
458 return Error(ErrorLoc, "too few operands for instruction");
459
460 ErrorLoc = ((XtensaOperand &)*Operands[ErrorInfo]).getStartLoc();
461 if (ErrorLoc == SMLoc())
462 ErrorLoc = IDLoc;
463 }
464 return Error(ErrorLoc, "invalid operand for instruction");
465 }
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 "
472 "should be zero");
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 "
509 "should be zero");
510 case Match_InvalidOffset8m32:
511 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
512 "expected immediate in range [0, 1020], first 2 bits "
513 "should be zero");
514 case Match_InvalidOffset4m32:
515 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
516 "expected immediate in range [0, 60], first 2 bits "
517 "should be zero");
518 }
519
520 report_fatal_error("Unknown match type detected!");
521}
522
523ParseStatus XtensaAsmParser::parsePCRelTarget(OperandVector &Operands) {
524 MCAsmParser &Parser = getParser();
525 LLVM_DEBUG(dbgs() << "parsePCRelTarget\n");
526
527 SMLoc S = getLexer().getLoc();
528
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
534 }
535
536 // Currently not support constants
537 if (Expr->getKind() == MCExpr::ExprKind::Constant)
538 return Error(getLoc(), "unknown operand");
539
540 Operands.push_back(XtensaOperand::createImm(Expr, S, getLexer().getLoc()));
542}
543
544bool XtensaAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
545 SMLoc &EndLoc) {
546 const AsmToken &Tok = getParser().getTok();
547 StartLoc = Tok.getLoc();
548 EndLoc = Tok.getEndLoc();
549 Reg = Xtensa::NoRegister;
551
553 getParser().Lex(); // Eat identifier token.
554 return false;
555 }
556
557 return Error(StartLoc, "invalid register name");
558}
559
560ParseStatus XtensaAsmParser::parseRegister(OperandVector &Operands,
561 bool AllowParens, bool SR) {
562 SMLoc FirstS = getLoc();
563 bool HadParens = false;
564 AsmToken Buf[2];
566
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))
573 HadParens = true;
574 getParser().Lex(); // Eat '('
575 }
576 }
577
578 unsigned RegNo = 0;
579
580 switch (getLexer().getKind()) {
581 default:
584 if (!SR)
587 RegNo = MatchRegisterName(RegName);
588 if (RegNo == 0)
590 break;
593 RegNo = MatchRegisterName(RegName);
594 if (RegNo == 0)
596 break;
597 }
598
599 if (RegNo == 0) {
600 if (HadParens)
601 getLexer().UnLex(Buf[0]);
603 }
604 if (HadParens)
605 Operands.push_back(XtensaOperand::createToken("(", FirstS));
606 SMLoc S = getLoc();
608 getLexer().Lex();
609 Operands.push_back(XtensaOperand::createReg(RegNo, S, E));
610
611 if (HadParens) {
612 getParser().Lex(); // Eat ')'
613 Operands.push_back(XtensaOperand::createToken(")", getLoc()));
614 }
615
617}
618
619ParseStatus XtensaAsmParser::parseImmediate(OperandVector &Operands) {
620 SMLoc S = getLoc();
621 SMLoc E;
622 const MCExpr *Res;
623
624 switch (getLexer().getKind()) {
625 default:
627 case AsmToken::LParen:
628 case AsmToken::Minus:
629 case AsmToken::Plus:
630 case AsmToken::Tilde:
632 case AsmToken::String:
633 if (getParser().parseExpression(Res))
635 break;
638 if (getParser().parseIdentifier(Identifier))
640
641 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
643 break;
644 }
646 return parseOperandWithModifier(Operands);
647 }
648
650 Operands.push_back(XtensaOperand::createImm(Res, S, E));
652}
653
654ParseStatus XtensaAsmParser::parseOperandWithModifier(OperandVector &Operands) {
656}
657
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.
661bool XtensaAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic,
662 bool SR) {
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);
666 if (Res.isSuccess())
667 return false;
668
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.
672 if (Res.isFailure())
673 return true;
674
675 // Attempt to parse token as register
676 if (parseRegister(Operands, true, SR).isSuccess())
677 return false;
678
679 // Attempt to parse token as an immediate
680 if (parseImmediate(Operands).isSuccess())
681 return false;
682
683 // Finally we have exhausted all options and must declare defeat.
684 return Error(getLoc(), "unknown operand");
685}
686
687bool XtensaAsmParser::ParseInstructionWithSR(ParseInstructionInfo &Info,
688 StringRef Name, SMLoc NameLoc,
690 if ((Name.starts_with("wsr.") || Name.starts_with("rsr.") ||
691 Name.starts_with("xsr.")) &&
692 (Name.size() > 4)) {
693 // Parse case when instruction name is concatenated with SR register
694 // name, like "wsr.sar a1"
695
696 // First operand is token for instruction
697 Operands.push_back(XtensaOperand::createToken(Name.take_front(3), NameLoc));
698
699 StringRef RegName = Name.drop_front(4);
700 unsigned RegNo = MatchRegisterName(RegName);
701
702 if (RegNo == 0)
704
705 if (RegNo == 0)
706 return Error(NameLoc, "invalid register name");
707
708 // Parse operand
709 if (parseOperand(Operands, Name))
710 return true;
711
712 SMLoc S = getLoc();
714 Operands.push_back(XtensaOperand::createReg(RegNo, S, E));
715 } else {
716 // First operand is token for instruction
717 Operands.push_back(XtensaOperand::createToken(Name, NameLoc));
718
719 // Parse first operand
720 if (parseOperand(Operands, Name))
721 return true;
722
724 SMLoc Loc = getLexer().getLoc();
726 return Error(Loc, "unexpected token");
727 }
728
729 // Parse second operand
730 if (parseOperand(Operands, Name, true))
731 return true;
732 }
733
735 SMLoc Loc = getLexer().getLoc();
737 return Error(Loc, "unexpected token");
738 }
739
740 getParser().Lex(); // Consume the EndOfStatement.
741 return false;
742}
743
744bool XtensaAsmParser::parseInstruction(ParseInstructionInfo &Info,
745 StringRef Name, SMLoc NameLoc,
747 if (Name.starts_with("wsr") || Name.starts_with("rsr") ||
748 Name.starts_with("xsr")) {
749 return ParseInstructionWithSR(Info, Name, NameLoc, Operands);
750 }
751
752 // First operand is token for instruction
753 Operands.push_back(XtensaOperand::createToken(Name, NameLoc));
754
755 // If there are no more operands, then finish
757 return false;
758
759 // Parse first operand
760 if (parseOperand(Operands, Name))
761 return true;
762
763 // Parse until end of statement, consuming commas between operands
765 if (parseOperand(Operands, Name))
766 return true;
767
769 SMLoc Loc = getLexer().getLoc();
771 return Error(Loc, "unexpected token");
772 }
773
774 getParser().Lex(); // Consume the EndOfStatement.
775 return false;
776}
777
778bool XtensaAsmParser::parseLiteralDirective(SMLoc L) {
779 MCAsmParser &Parser = getParser();
780 const MCExpr *Value;
781 SMLoc LiteralLoc = getLexer().getLoc();
782 XtensaTargetStreamer &TS = this->getTargetStreamer();
783
784 if (Parser.parseExpression(Value))
785 return true;
786
787 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Value);
788
789 if (!SE)
790 return Error(LiteralLoc, "literal label must be a symbol");
791
792 if (Parser.parseComma())
793 return true;
794
795 SMLoc OpcodeLoc = getLexer().getLoc();
797 return Error(OpcodeLoc, "expected value");
798
799 if (Parser.parseExpression(Value))
800 return true;
801
802 if (parseEOL())
803 return true;
804
806
807 TS.emitLiteral(Sym, Value, true, LiteralLoc);
808
809 return false;
810}
811
812ParseStatus XtensaAsmParser::parseDirective(AsmToken DirectiveID) {
813 StringRef IDVal = DirectiveID.getString();
814 SMLoc Loc = getLexer().getLoc();
815
816 if (IDVal == ".literal_position") {
817 XtensaTargetStreamer &TS = this->getTargetStreamer();
819 return parseEOL();
820 }
821
822 if (IDVal == ".literal") {
823 return parseLiteralDirective(Loc);
824 }
825
827}
828
829// Force static initialization.
832}
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:128
#define LLVM_DEBUG(...)
Definition: Debug.h:106
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:355
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:222
MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
Definition: MCContext.cpp:345
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:212
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
ExprKind getKind() const
Definition: MCExpr.h:78
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
void setLoc(SMLoc loc)
Definition: MCInst.h:204
unsigned getOpcode() const
Definition: MCInst.h:199
void addOperand(const MCOperand Op)
Definition: MCInst.h:211
void setOpcode(unsigned Op)
Definition: MCInst.h:198
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:207
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:37
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:163
void setExpr(const MCExpr *Val)
Definition: MCInst.h:120
int64_t getImm() const
Definition: MCInst.h:81
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:135
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:142
const MCExpr * getExpr() const
Definition: MCInst.h:115
bool isExpr() const
Definition: MCInst.h:66
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:213
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:309
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:411
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:398
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
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:94
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:573
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
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:167
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?
bool isImm1n_15() const
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
bool isImm32n_95() const
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,...