[Darwin][Driver][clang] apple-none-macho orders the resource directory after internal...
[llvm-project.git] / llvm / lib / Target / Xtensa / AsmParser / XtensaAsmParser.cpp
blob731f9535ca251f2aecc971324dfd483ce8593b0b
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 //===----------------------------------------------------------------------===//
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"
31 using namespace llvm;
33 #define DEBUG_TYPE "xtensa-asm-parser"
35 struct XtensaOperand;
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,
52 uint64_t &ErrorInfo,
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,
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 {
74 return ParseStatus::NoMatch;
76 ParseStatus parsePCRelTarget(OperandVector &Operands);
77 bool parseLiteralDirective(SMLoc L);
79 public:
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;
100 return false;
103 struct XtensaOperand : public MCParsedAsmOperand {
105 enum KindTy {
106 Token,
107 Register,
108 Immediate,
109 } Kind;
111 struct RegOp {
112 unsigned RegNum;
115 struct ImmOp {
116 const MCExpr *Val;
119 SMLoc StartLoc, EndLoc;
120 union {
121 StringRef Tok;
122 RegOp Reg;
123 ImmOp Imm;
126 XtensaOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
128 public:
129 XtensaOperand(const XtensaOperand &o) : MCParsedAsmOperand() {
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;
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)
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;
228 return false;
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;
258 return false;
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!");
268 return Reg.RegNum;
271 const MCExpr *getImm() const {
272 assert(Kind == Immediate && "Invalid type access!");
273 return Imm.Val;
276 StringRef getToken() const {
277 assert(Kind == Token && "Invalid type access!");
278 return Tok;
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;
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;
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;
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;
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;
327 if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
328 IsConstant = true;
329 Imm = CE->getValue();
332 if (IsConstant)
333 Inst.addOperand(MCOperand::createImm(Imm));
334 else
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,
355 unsigned Kind) {
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())
364 return Loc;
365 return ErrorLoc;
367 return Loc;
370 bool 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());
379 XtensaMCExpr::VariantKind Kind = XtensaMCExpr::VK_Xtensa_None;
380 const MCExpr *NewOpExpr = XtensaMCExpr::create(OpExpr, Kind, getContext());
381 Inst.getOperand(1).setExpr(NewOpExpr);
382 break;
384 case Xtensa::MOVI: {
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();
393 MCInst TmpInst;
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);
406 Inst = TmpInst;
408 } else {
409 MCInst TmpInst;
410 TmpInst.setLoc(IDLoc);
411 TmpInst.setOpcode(Xtensa::L32R);
412 const MCExpr *Value = Inst.getOperand(1).getExpr();
413 MCSymbol *Sym = getContext().createTempSymbol();
414 const MCExpr *Expr =
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);
421 Inst = TmpInst;
422 TS.emitLiteral(Sym, Value, true, IDLoc);
424 break;
426 default:
427 break;
430 return true;
433 bool XtensaAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
434 OperandVector &Operands,
435 MCStreamer &Out,
436 uint64_t &ErrorInfo,
437 bool MatchingInlineAsm) {
438 MCInst Inst;
439 auto Result =
440 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
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;
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())
462 ErrorLoc = IDLoc;
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 "
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");
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,
545 SMLoc &EndLoc) {
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.
554 return false;
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;
564 AsmToken Buf[2];
565 StringRef RegName;
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;
573 HadParens = true;
574 getParser().Lex(); // Eat '('
578 unsigned RegNo = 0;
580 switch (getLexer().getKind()) {
581 default:
582 return ParseStatus::NoMatch;
583 case AsmToken::Integer:
584 if (!SR)
585 return ParseStatus::NoMatch;
586 RegName = getLexer().getTok().getString();
587 RegNo = MatchRegisterName(RegName);
588 if (RegNo == 0)
589 RegNo = MatchRegisterAltName(RegName);
590 break;
591 case AsmToken::Identifier:
592 RegName = getLexer().getTok().getIdentifier();
593 RegNo = MatchRegisterName(RegName);
594 if (RegNo == 0)
595 RegNo = MatchRegisterAltName(RegName);
596 break;
599 if (RegNo == 0) {
600 if (HadParens)
601 getLexer().UnLex(Buf[0]);
602 return ParseStatus::NoMatch;
604 if (HadParens)
605 Operands.push_back(XtensaOperand::createToken("(", FirstS));
606 SMLoc S = getLoc();
607 SMLoc E = getParser().getTok().getEndLoc();
608 getLexer().Lex();
609 Operands.push_back(XtensaOperand::createReg(RegNo, S, E));
611 if (HadParens) {
612 getParser().Lex(); // Eat ')'
613 Operands.push_back(XtensaOperand::createToken(")", getLoc()));
616 return ParseStatus::Success;
619 ParseStatus XtensaAsmParser::parseImmediate(OperandVector &Operands) {
620 SMLoc S = getLoc();
621 SMLoc E;
622 const MCExpr *Res;
624 switch (getLexer().getKind()) {
625 default:
626 return ParseStatus::NoMatch;
627 case AsmToken::LParen:
628 case AsmToken::Minus:
629 case AsmToken::Plus:
630 case AsmToken::Tilde:
631 case AsmToken::Integer:
632 case AsmToken::String:
633 if (getParser().parseExpression(Res))
634 return ParseStatus::Failure;
635 break;
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());
643 break;
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,
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;
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;
675 // Attempt to parse token as register
676 if (parseRegister(Operands, true, SR).isSuccess())
677 return false;
679 // Attempt to parse token as an immediate
680 if (parseImmediate(Operands).isSuccess())
681 return false;
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.")) &&
692 (Name.size() > 4)) {
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);
702 if (RegNo == 0)
703 RegNo = MatchRegisterAltName(RegName);
705 if (RegNo == 0)
706 return Error(NameLoc, "invalid register name");
708 // Parse operand
709 if (parseOperand(Operands, Name))
710 return true;
712 SMLoc S = getLoc();
713 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
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));
719 // Parse first operand
720 if (parseOperand(Operands, Name))
721 return true;
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))
731 return 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.
741 return false;
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))
757 return false;
759 // Parse first operand
760 if (parseOperand(Operands, Name))
761 return true;
763 // Parse until end of statement, consuming commas between operands
764 while (parseOptionalToken(AsmToken::Comma))
765 if (parseOperand(Operands, Name))
766 return true;
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.
775 return false;
778 bool XtensaAsmParser::parseLiteralDirective(SMLoc L) {
779 MCAsmParser &Parser = getParser();
780 const MCExpr *Value;
781 SMLoc LiteralLoc = getLexer().getLoc();
782 XtensaTargetStreamer &TS = this->getTargetStreamer();
784 if (Parser.parseExpression(Value))
785 return true;
787 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Value);
789 if (!SE)
790 return Error(LiteralLoc, "literal label must be a symbol");
792 if (Parser.parseComma())
793 return true;
795 SMLoc OpcodeLoc = getLexer().getLoc();
796 if (parseOptionalToken(AsmToken::EndOfStatement))
797 return Error(OpcodeLoc, "expected value");
799 if (Parser.parseExpression(Value))
800 return true;
802 if (parseEOL())
803 return true;
805 MCSymbol *Sym = getContext().getOrCreateSymbol(SE->getSymbol().getName());
807 TS.emitLiteral(Sym, Value, true, LiteralLoc);
809 return false;
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();
819 return parseEOL();
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());