xref: /llvm-project/llvm/lib/Target/Lanai/AsmParser/LanaiAsmParser.cpp (revision ed8019d9fbed2e6a6b08f8f73e9fa54a24f3ed52)
1 //===-- LanaiAsmParser.cpp - Parse Lanai assembly to MCInst instructions --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "LanaiAluCode.h"
10 #include "LanaiCondCode.h"
11 #include "LanaiInstrInfo.h"
12 #include "MCTargetDesc/LanaiMCExpr.h"
13 #include "TargetInfo/LanaiTargetInfo.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCParser/MCAsmLexer.h"
20 #include "llvm/MC/MCParser/MCAsmParser.h"
21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/TargetRegistry.h"
27 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SMLoc.h"
31 #include "llvm/Support/raw_ostream.h"
32 #include <cassert>
33 #include <cstddef>
34 #include <cstdint>
35 #include <memory>
36 #include <optional>
37 
38 using namespace llvm;
39 
40 // Auto-generated by TableGen
41 static MCRegister MatchRegisterName(StringRef Name);
42 
43 namespace {
44 
45 struct LanaiOperand;
46 
47 class LanaiAsmParser : public MCTargetAsmParser {
48   // Parse operands
49   std::unique_ptr<LanaiOperand> parseRegister(bool RestoreOnFailure = false);
50 
51   std::unique_ptr<LanaiOperand> parseImmediate();
52 
53   std::unique_ptr<LanaiOperand> parseIdentifier();
54 
55   unsigned parseAluOperator(bool PreOp, bool PostOp);
56 
57   // Split the mnemonic stripping conditional code and quantifiers
58   StringRef splitMnemonic(StringRef Name, SMLoc NameLoc,
59                           OperandVector *Operands);
60 
61   bool parsePrePost(StringRef Type, int *OffsetValue);
62 
63   bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
64                         SMLoc NameLoc, OperandVector &Operands) override;
65 
66   bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
67   ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
68                                SMLoc &EndLoc) override;
69 
70   bool matchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
71                                OperandVector &Operands, MCStreamer &Out,
72                                uint64_t &ErrorInfo,
73                                bool MatchingInlineAsm) override;
74 
75 // Auto-generated instruction matching functions
76 #define GET_ASSEMBLER_HEADER
77 #include "LanaiGenAsmMatcher.inc"
78 
79   ParseStatus parseOperand(OperandVector *Operands, StringRef Mnemonic);
80 
81   ParseStatus parseMemoryOperand(OperandVector &Operands);
82 
83 public:
84   LanaiAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
85                  const MCInstrInfo &MII, const MCTargetOptions &Options)
86       : MCTargetAsmParser(Options, STI, MII), Parser(Parser),
87         Lexer(Parser.getLexer()), SubtargetInfo(STI) {
88     setAvailableFeatures(
89         ComputeAvailableFeatures(SubtargetInfo.getFeatureBits()));
90   }
91 
92 private:
93   MCAsmParser &Parser;
94   MCAsmLexer &Lexer;
95 
96   const MCSubtargetInfo &SubtargetInfo;
97 };
98 
99 // LanaiOperand - Instances of this class represented a parsed machine
100 // instruction
101 struct LanaiOperand : public MCParsedAsmOperand {
102   enum KindTy {
103     TOKEN,
104     REGISTER,
105     IMMEDIATE,
106     MEMORY_IMM,
107     MEMORY_REG_IMM,
108     MEMORY_REG_REG,
109   } Kind;
110 
111   SMLoc StartLoc, EndLoc;
112 
113   struct Token {
114     const char *Data;
115     unsigned Length;
116   };
117 
118   struct RegOp {
119     MCRegister RegNum;
120   };
121 
122   struct ImmOp {
123     const MCExpr *Value;
124   };
125 
126   struct MemOp {
127     MCRegister BaseReg;
128     MCRegister OffsetReg;
129     unsigned AluOp;
130     const MCExpr *Offset;
131   };
132 
133   union {
134     struct Token Tok;
135     struct RegOp Reg;
136     struct ImmOp Imm;
137     struct MemOp Mem;
138   };
139 
140   explicit LanaiOperand(KindTy Kind) : Kind(Kind) {}
141 
142 public:
143   // The functions below are used by the autogenerated ASM matcher and hence to
144   // be of the form expected.
145 
146   // getStartLoc - Gets location of the first token of this operand
147   SMLoc getStartLoc() const override { return StartLoc; }
148 
149   // getEndLoc - Gets location of the last token of this operand
150   SMLoc getEndLoc() const override { return EndLoc; }
151 
152   MCRegister getReg() const override {
153     assert(isReg() && "Invalid type access!");
154     return Reg.RegNum;
155   }
156 
157   const MCExpr *getImm() const {
158     assert(isImm() && "Invalid type access!");
159     return Imm.Value;
160   }
161 
162   StringRef getToken() const {
163     assert(isToken() && "Invalid type access!");
164     return StringRef(Tok.Data, Tok.Length);
165   }
166 
167   MCRegister getMemBaseReg() const {
168     assert(isMem() && "Invalid type access!");
169     return Mem.BaseReg;
170   }
171 
172   MCRegister getMemOffsetReg() const {
173     assert(isMem() && "Invalid type access!");
174     return Mem.OffsetReg;
175   }
176 
177   const MCExpr *getMemOffset() const {
178     assert(isMem() && "Invalid type access!");
179     return Mem.Offset;
180   }
181 
182   unsigned getMemOp() const {
183     assert(isMem() && "Invalid type access!");
184     return Mem.AluOp;
185   }
186 
187   // Functions for testing operand type
188   bool isReg() const override { return Kind == REGISTER; }
189 
190   bool isImm() const override { return Kind == IMMEDIATE; }
191 
192   bool isMem() const override {
193     return isMemImm() || isMemRegImm() || isMemRegReg();
194   }
195 
196   bool isMemImm() const { return Kind == MEMORY_IMM; }
197 
198   bool isMemRegImm() const { return Kind == MEMORY_REG_IMM; }
199 
200   bool isMemRegReg() const { return Kind == MEMORY_REG_REG; }
201 
202   bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); }
203 
204   bool isToken() const override { return Kind == TOKEN; }
205 
206   bool isBrImm() {
207     if (!isImm())
208       return false;
209 
210     // Constant case
211     const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm.Value);
212     if (!MCE)
213       return true;
214     int64_t Value = MCE->getValue();
215     // Check if value fits in 25 bits with 2 least significant bits 0.
216     return isShiftedUInt<23, 2>(static_cast<int32_t>(Value));
217   }
218 
219   bool isBrTarget() { return isBrImm() || isToken(); }
220 
221   bool isCallTarget() { return isImm() || isToken(); }
222 
223   bool isHiImm16() {
224     if (!isImm())
225       return false;
226 
227     // Constant case
228     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
229       int64_t Value = ConstExpr->getValue();
230       return Value != 0 && isShiftedUInt<16, 16>(Value);
231     }
232 
233     // Symbolic reference expression
234     if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
235       return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI;
236 
237     // Binary expression
238     if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
239       if (const LanaiMCExpr *SymbolRefExpr =
240               dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
241         return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI;
242 
243     return false;
244   }
245 
246   bool isHiImm16And() {
247     if (!isImm())
248       return false;
249 
250     const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
251     if (ConstExpr) {
252       int64_t Value = ConstExpr->getValue();
253       // Check if in the form 0xXYZWffff
254       return (Value != 0) && ((Value & ~0xffff0000) == 0xffff);
255     }
256     return false;
257   }
258 
259   bool isLoImm16() {
260     if (!isImm())
261       return false;
262 
263     // Constant case
264     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
265       int64_t Value = ConstExpr->getValue();
266       // Check if value fits in 16 bits
267       return isUInt<16>(static_cast<int32_t>(Value));
268     }
269 
270     // Symbolic reference expression
271     if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
272       return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
273 
274     // Binary expression
275     if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
276       if (const LanaiMCExpr *SymbolRefExpr =
277               dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
278         return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
279 
280     return false;
281   }
282 
283   bool isLoImm16Signed() {
284     if (!isImm())
285       return false;
286 
287     // Constant case
288     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
289       int64_t Value = ConstExpr->getValue();
290       // Check if value fits in 16 bits or value of the form 0xffffxyzw
291       return isInt<16>(static_cast<int32_t>(Value));
292     }
293 
294     // Symbolic reference expression
295     if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
296       return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
297 
298     // Binary expression
299     if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value))
300       if (const LanaiMCExpr *SymbolRefExpr =
301               dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
302         return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO;
303 
304     return false;
305   }
306 
307   bool isLoImm16And() {
308     if (!isImm())
309       return false;
310 
311     const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
312     if (ConstExpr) {
313       int64_t Value = ConstExpr->getValue();
314       // Check if in the form 0xffffXYZW
315       return ((Value & ~0xffff) == 0xffff0000);
316     }
317     return false;
318   }
319 
320   bool isImmShift() {
321     if (!isImm())
322       return false;
323 
324     const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
325     if (!ConstExpr)
326       return false;
327     int64_t Value = ConstExpr->getValue();
328     return (Value >= -31) && (Value <= 31);
329   }
330 
331   bool isLoImm21() {
332     if (!isImm())
333       return false;
334 
335     // Constant case
336     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value)) {
337       int64_t Value = ConstExpr->getValue();
338       return isUInt<21>(Value);
339     }
340 
341     // Symbolic reference expression
342     if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Imm.Value))
343       return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
344     if (const MCSymbolRefExpr *SymbolRefExpr =
345             dyn_cast<MCSymbolRefExpr>(Imm.Value)) {
346       return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
347     }
348 
349     // Binary expression
350     if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Imm.Value)) {
351       if (const LanaiMCExpr *SymbolRefExpr =
352               dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()))
353         return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
354       if (const MCSymbolRefExpr *SymbolRefExpr =
355               dyn_cast<MCSymbolRefExpr>(BinaryExpr->getLHS()))
356         return SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None;
357     }
358 
359     return false;
360   }
361 
362   bool isImm10() {
363     if (!isImm())
364       return false;
365 
366     const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
367     if (!ConstExpr)
368       return false;
369     int64_t Value = ConstExpr->getValue();
370     return isInt<10>(Value);
371   }
372 
373   bool isCondCode() {
374     if (!isImm())
375       return false;
376 
377     const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
378     if (!ConstExpr)
379       return false;
380     uint64_t Value = ConstExpr->getValue();
381     // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
382     // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
383     // value corresponds to a valid condition code.
384     return Value < LPCC::UNKNOWN;
385   }
386 
387   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
388     // Add as immediates where possible. Null MCExpr = 0
389     if (Expr == nullptr)
390       Inst.addOperand(MCOperand::createImm(0));
391     else if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
392       Inst.addOperand(
393           MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
394     else
395       Inst.addOperand(MCOperand::createExpr(Expr));
396   }
397 
398   void addRegOperands(MCInst &Inst, unsigned N) const {
399     assert(N == 1 && "Invalid number of operands!");
400     Inst.addOperand(MCOperand::createReg(getReg()));
401   }
402 
403   void addImmOperands(MCInst &Inst, unsigned N) const {
404     assert(N == 1 && "Invalid number of operands!");
405     addExpr(Inst, getImm());
406   }
407 
408   void addBrTargetOperands(MCInst &Inst, unsigned N) const {
409     assert(N == 1 && "Invalid number of operands!");
410     addExpr(Inst, getImm());
411   }
412 
413   void addCallTargetOperands(MCInst &Inst, unsigned N) const {
414     assert(N == 1 && "Invalid number of operands!");
415     addExpr(Inst, getImm());
416   }
417 
418   void addCondCodeOperands(MCInst &Inst, unsigned N) const {
419     assert(N == 1 && "Invalid number of operands!");
420     addExpr(Inst, getImm());
421   }
422 
423   void addMemImmOperands(MCInst &Inst, unsigned N) const {
424     assert(N == 1 && "Invalid number of operands!");
425     const MCExpr *Expr = getMemOffset();
426     addExpr(Inst, Expr);
427   }
428 
429   void addMemRegImmOperands(MCInst &Inst, unsigned N) const {
430     assert(N == 3 && "Invalid number of operands!");
431     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
432     const MCExpr *Expr = getMemOffset();
433     addExpr(Inst, Expr);
434     Inst.addOperand(MCOperand::createImm(getMemOp()));
435   }
436 
437   void addMemRegRegOperands(MCInst &Inst, unsigned N) const {
438     assert(N == 3 && "Invalid number of operands!");
439     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
440     assert(getMemOffsetReg() && "Invalid offset");
441     Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
442     Inst.addOperand(MCOperand::createImm(getMemOp()));
443   }
444 
445   void addMemSplsOperands(MCInst &Inst, unsigned N) const {
446     if (isMemRegImm())
447       addMemRegImmOperands(Inst, N);
448     if (isMemRegReg())
449       addMemRegRegOperands(Inst, N);
450   }
451 
452   void addImmShiftOperands(MCInst &Inst, unsigned N) const {
453     assert(N == 1 && "Invalid number of operands!");
454     addExpr(Inst, getImm());
455   }
456 
457   void addImm10Operands(MCInst &Inst, unsigned N) const {
458     assert(N == 1 && "Invalid number of operands!");
459     addExpr(Inst, getImm());
460   }
461 
462   void addLoImm16Operands(MCInst &Inst, unsigned N) const {
463     assert(N == 1 && "Invalid number of operands!");
464     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
465       Inst.addOperand(
466           MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
467     else if (isa<LanaiMCExpr>(getImm())) {
468 #ifndef NDEBUG
469       const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
470       assert(SymbolRefExpr &&
471              SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO);
472 #endif
473       Inst.addOperand(MCOperand::createExpr(getImm()));
474     } else if (isa<MCBinaryExpr>(getImm())) {
475 #ifndef NDEBUG
476       const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
477       assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
478              cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
479                  LanaiMCExpr::VK_Lanai_ABS_LO);
480 #endif
481       Inst.addOperand(MCOperand::createExpr(getImm()));
482     } else
483       assert(false && "Operand type not supported.");
484   }
485 
486   void addLoImm16AndOperands(MCInst &Inst, unsigned N) const {
487     assert(N == 1 && "Invalid number of operands!");
488     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
489       Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0xffff));
490     else
491       assert(false && "Operand type not supported.");
492   }
493 
494   void addHiImm16Operands(MCInst &Inst, unsigned N) const {
495     assert(N == 1 && "Invalid number of operands!");
496     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
497       Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
498     else if (isa<LanaiMCExpr>(getImm())) {
499 #ifndef NDEBUG
500       const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
501       assert(SymbolRefExpr &&
502              SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI);
503 #endif
504       Inst.addOperand(MCOperand::createExpr(getImm()));
505     } else if (isa<MCBinaryExpr>(getImm())) {
506 #ifndef NDEBUG
507       const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
508       assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
509              cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
510                  LanaiMCExpr::VK_Lanai_ABS_HI);
511 #endif
512       Inst.addOperand(MCOperand::createExpr(getImm()));
513     } else
514       assert(false && "Operand type not supported.");
515   }
516 
517   void addHiImm16AndOperands(MCInst &Inst, unsigned N) const {
518     assert(N == 1 && "Invalid number of operands!");
519     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
520       Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
521     else
522       assert(false && "Operand type not supported.");
523   }
524 
525   void addLoImm21Operands(MCInst &Inst, unsigned N) const {
526     assert(N == 1 && "Invalid number of operands!");
527     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
528       Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
529     else if (isa<LanaiMCExpr>(getImm())) {
530 #ifndef NDEBUG
531       const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
532       assert(SymbolRefExpr &&
533              SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
534 #endif
535       Inst.addOperand(MCOperand::createExpr(getImm()));
536     } else if (isa<MCSymbolRefExpr>(getImm())) {
537 #ifndef NDEBUG
538       const MCSymbolRefExpr *SymbolRefExpr =
539           dyn_cast<MCSymbolRefExpr>(getImm());
540       assert(SymbolRefExpr &&
541              SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None);
542 #endif
543       Inst.addOperand(MCOperand::createExpr(getImm()));
544     } else if (isa<MCBinaryExpr>(getImm())) {
545 #ifndef NDEBUG
546       const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
547       assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
548              cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
549                  LanaiMCExpr::VK_Lanai_None);
550 #endif
551       Inst.addOperand(MCOperand::createExpr(getImm()));
552     } else
553       assert(false && "Operand type not supported.");
554   }
555 
556   void print(raw_ostream &OS) const override {
557     switch (Kind) {
558     case IMMEDIATE:
559       OS << "Imm: " << getImm() << "\n";
560       break;
561     case TOKEN:
562       OS << "Token: " << getToken() << "\n";
563       break;
564     case REGISTER:
565       OS << "Reg: %r" << getReg() << "\n";
566       break;
567     case MEMORY_IMM:
568       OS << "MemImm: " << *getMemOffset() << "\n";
569       break;
570     case MEMORY_REG_IMM:
571       OS << "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
572       break;
573     case MEMORY_REG_REG:
574       assert(getMemOffset() == nullptr);
575       OS << "MemRegReg: " << getMemBaseReg() << "+"
576          << "%r" << getMemOffsetReg() << "\n";
577       break;
578     }
579   }
580 
581   static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
582     auto Op = std::make_unique<LanaiOperand>(TOKEN);
583     Op->Tok.Data = Str.data();
584     Op->Tok.Length = Str.size();
585     Op->StartLoc = Start;
586     Op->EndLoc = Start;
587     return Op;
588   }
589 
590   static std::unique_ptr<LanaiOperand> createReg(MCRegister Reg, SMLoc Start,
591                                                  SMLoc End) {
592     auto Op = std::make_unique<LanaiOperand>(REGISTER);
593     Op->Reg.RegNum = Reg;
594     Op->StartLoc = Start;
595     Op->EndLoc = End;
596     return Op;
597   }
598 
599   static std::unique_ptr<LanaiOperand> createImm(const MCExpr *Value,
600                                                  SMLoc Start, SMLoc End) {
601     auto Op = std::make_unique<LanaiOperand>(IMMEDIATE);
602     Op->Imm.Value = Value;
603     Op->StartLoc = Start;
604     Op->EndLoc = End;
605     return Op;
606   }
607 
608   static std::unique_ptr<LanaiOperand>
609   MorphToMemImm(std::unique_ptr<LanaiOperand> Op) {
610     const MCExpr *Imm = Op->getImm();
611     Op->Kind = MEMORY_IMM;
612     Op->Mem.BaseReg = MCRegister();
613     Op->Mem.AluOp = LPAC::ADD;
614     Op->Mem.OffsetReg = 0;
615     Op->Mem.Offset = Imm;
616     return Op;
617   }
618 
619   static std::unique_ptr<LanaiOperand>
620   MorphToMemRegReg(MCRegister BaseReg, std::unique_ptr<LanaiOperand> Op,
621                    unsigned AluOp) {
622     MCRegister OffsetReg = Op->getReg();
623     Op->Kind = MEMORY_REG_REG;
624     Op->Mem.BaseReg = BaseReg;
625     Op->Mem.AluOp = AluOp;
626     Op->Mem.OffsetReg = OffsetReg;
627     Op->Mem.Offset = nullptr;
628     return Op;
629   }
630 
631   static std::unique_ptr<LanaiOperand>
632   MorphToMemRegImm(MCRegister BaseReg, std::unique_ptr<LanaiOperand> Op,
633                    unsigned AluOp) {
634     const MCExpr *Imm = Op->getImm();
635     Op->Kind = MEMORY_REG_IMM;
636     Op->Mem.BaseReg = BaseReg;
637     Op->Mem.AluOp = AluOp;
638     Op->Mem.OffsetReg = 0;
639     Op->Mem.Offset = Imm;
640     return Op;
641   }
642 };
643 
644 } // end anonymous namespace
645 
646 bool LanaiAsmParser::matchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
647                                              OperandVector &Operands,
648                                              MCStreamer &Out,
649                                              uint64_t &ErrorInfo,
650                                              bool MatchingInlineAsm) {
651   MCInst Inst;
652   SMLoc ErrorLoc;
653 
654   switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
655   case Match_Success:
656     Out.emitInstruction(Inst, SubtargetInfo);
657     Opcode = Inst.getOpcode();
658     return false;
659   case Match_MissingFeature:
660     return Error(IdLoc, "Instruction use requires option to be enabled");
661   case Match_MnemonicFail:
662     return Error(IdLoc, "Unrecognized instruction mnemonic");
663   case Match_InvalidOperand: {
664     ErrorLoc = IdLoc;
665     if (ErrorInfo != ~0U) {
666       if (ErrorInfo >= Operands.size())
667         return Error(IdLoc, "Too few operands for instruction");
668 
669       ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
670       if (ErrorLoc == SMLoc())
671         ErrorLoc = IdLoc;
672     }
673     return Error(ErrorLoc, "Invalid operand for instruction");
674   }
675   default:
676     break;
677   }
678 
679   llvm_unreachable("Unknown match type detected!");
680 }
681 
682 // Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
683 // backwards compatible with GCC and the different ways inline assembly is
684 // handled.
685 // TODO: see if there isn't a better way to do this.
686 std::unique_ptr<LanaiOperand>
687 LanaiAsmParser::parseRegister(bool RestoreOnFailure) {
688   SMLoc Start = Parser.getTok().getLoc();
689   SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
690   std::optional<AsmToken> PercentTok;
691 
692   MCRegister Reg;
693   // Eat the '%'.
694   if (Lexer.getKind() == AsmToken::Percent) {
695     PercentTok = Parser.getTok();
696     Parser.Lex();
697   }
698   if (Lexer.getKind() == AsmToken::Identifier) {
699     Reg = MatchRegisterName(Lexer.getTok().getIdentifier());
700     if (!Reg) {
701       if (PercentTok && RestoreOnFailure)
702         Lexer.UnLex(*PercentTok);
703       return nullptr;
704     }
705     Parser.Lex(); // Eat identifier token
706     return LanaiOperand::createReg(Reg, Start, End);
707   }
708   if (PercentTok && RestoreOnFailure)
709     Lexer.UnLex(*PercentTok);
710   return nullptr;
711 }
712 
713 bool LanaiAsmParser::parseRegister(MCRegister &RegNum, SMLoc &StartLoc,
714                                    SMLoc &EndLoc) {
715   const AsmToken &Tok = getParser().getTok();
716   StartLoc = Tok.getLoc();
717   EndLoc = Tok.getEndLoc();
718   std::unique_ptr<LanaiOperand> Op = parseRegister(/*RestoreOnFailure=*/false);
719   if (Op != nullptr)
720     RegNum = Op->getReg();
721   return (Op == nullptr);
722 }
723 
724 ParseStatus LanaiAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
725                                              SMLoc &EndLoc) {
726   const AsmToken &Tok = getParser().getTok();
727   StartLoc = Tok.getLoc();
728   EndLoc = Tok.getEndLoc();
729   std::unique_ptr<LanaiOperand> Op = parseRegister(/*RestoreOnFailure=*/true);
730   if (Op == nullptr)
731     return ParseStatus::NoMatch;
732   Reg = Op->getReg();
733   return ParseStatus::Success;
734 }
735 
736 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
737   SMLoc Start = Parser.getTok().getLoc();
738   SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
739   const MCExpr *Res, *RHS = nullptr;
740   LanaiMCExpr::VariantKind Kind = LanaiMCExpr::VK_Lanai_None;
741 
742   if (Lexer.getKind() != AsmToken::Identifier)
743     return nullptr;
744 
745   StringRef Identifier;
746   if (Parser.parseIdentifier(Identifier))
747     return nullptr;
748 
749   // Check if identifier has a modifier
750   if (Identifier.equals_insensitive("hi"))
751     Kind = LanaiMCExpr::VK_Lanai_ABS_HI;
752   else if (Identifier.equals_insensitive("lo"))
753     Kind = LanaiMCExpr::VK_Lanai_ABS_LO;
754 
755   // If the identifier corresponds to a variant then extract the real
756   // identifier.
757   if (Kind != LanaiMCExpr::VK_Lanai_None) {
758     if (Lexer.getKind() != AsmToken::LParen) {
759       Error(Lexer.getLoc(), "Expected '('");
760       return nullptr;
761     }
762     Lexer.Lex(); // lex '('
763 
764     // Parse identifier
765     if (Parser.parseIdentifier(Identifier))
766       return nullptr;
767   }
768 
769   // If addition parse the RHS.
770   if (Lexer.getKind() == AsmToken::Plus && Parser.parseExpression(RHS))
771     return nullptr;
772 
773   // For variants parse the final ')'
774   if (Kind != LanaiMCExpr::VK_Lanai_None) {
775     if (Lexer.getKind() != AsmToken::RParen) {
776       Error(Lexer.getLoc(), "Expected ')'");
777       return nullptr;
778     }
779     Lexer.Lex(); // lex ')'
780   }
781 
782   End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
783   MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
784   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
785   Res = LanaiMCExpr::create(Kind, Expr, getContext());
786 
787   // Nest if this was an addition
788   if (RHS)
789     Res = MCBinaryExpr::createAdd(Res, RHS, getContext());
790 
791   return LanaiOperand::createImm(Res, Start, End);
792 }
793 
794 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
795   SMLoc Start = Parser.getTok().getLoc();
796   SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
797 
798   const MCExpr *ExprVal;
799   switch (Lexer.getKind()) {
800   case AsmToken::Identifier:
801     return parseIdentifier();
802   case AsmToken::Plus:
803   case AsmToken::Minus:
804   case AsmToken::Integer:
805   case AsmToken::Dot:
806     if (!Parser.parseExpression(ExprVal))
807       return LanaiOperand::createImm(ExprVal, Start, End);
808     [[fallthrough]];
809   default:
810     return nullptr;
811   }
812 }
813 
814 static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) {
815   if (PreOp)
816     return LPAC::makePreOp(AluCode);
817   if (PostOp)
818     return LPAC::makePostOp(AluCode);
819   return AluCode;
820 }
821 
822 unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) {
823   StringRef IdString;
824   Parser.parseIdentifier(IdString);
825   unsigned AluCode = LPAC::stringToLanaiAluCode(IdString);
826   if (AluCode == LPAC::UNKNOWN) {
827     Error(Parser.getTok().getLoc(), "Can't parse ALU operator");
828     return 0;
829   }
830   return AluCode;
831 }
832 
833 static int SizeForSuffix(StringRef T) {
834   return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
835 }
836 
837 bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) {
838   bool PreOrPost = false;
839   if (Lexer.getKind() == Lexer.peekTok(true).getKind()) {
840     PreOrPost = true;
841     if (Lexer.is(AsmToken::Minus))
842       *OffsetValue = -SizeForSuffix(Type);
843     else if (Lexer.is(AsmToken::Plus))
844       *OffsetValue = SizeForSuffix(Type);
845     else
846       return false;
847 
848     // Eat the '-' '-' or '+' '+'
849     Parser.Lex();
850     Parser.Lex();
851   } else if (Lexer.is(AsmToken::Star)) {
852     Parser.Lex(); // Eat the '*'
853     PreOrPost = true;
854   }
855 
856   return PreOrPost;
857 }
858 
859 bool shouldBeSls(const LanaiOperand &Op) {
860   // The instruction should be encoded as an SLS if the constant is word
861   // aligned and will fit in 21 bits
862   if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
863     int64_t Value = ConstExpr->getValue();
864     return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff);
865   }
866   // The instruction should be encoded as an SLS if the operand is a symbolic
867   // reference with no variant.
868   if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
869     return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
870   // The instruction should be encoded as an SLS if the operand is a binary
871   // expression with the left-hand side being a symbolic reference with no
872   // variant.
873   if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
874     const LanaiMCExpr *LHSSymbolRefExpr =
875         dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
876     return (LHSSymbolRefExpr &&
877             LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
878   }
879   return false;
880 }
881 
882 // Matches memory operand. Returns true if error encountered.
883 ParseStatus LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) {
884   // Try to match a memory operand.
885   // The memory operands are of the form:
886   //  (1)  Register|Immediate|'' '[' '*'? Register '*'? ']' or
887   //                            ^
888   //  (2)  '[' '*'? Register '*'? AluOperator Register ']'
889   //      ^
890   //  (3)  '[' '--'|'++' Register '--'|'++' ']'
891   //
892   //  (4) '[' Immediate ']' (for SLS)
893 
894   // Store the type for use in parsing pre/post increment/decrement operators
895   StringRef Type;
896   if (Operands[0]->isToken())
897     Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken();
898 
899   // Use 0 if no offset given
900   int OffsetValue = 0;
901   MCRegister BaseReg;
902   unsigned AluOp = LPAC::ADD;
903   bool PostOp = false, PreOp = false;
904 
905   // Try to parse the offset
906   std::unique_ptr<LanaiOperand> Op = parseRegister();
907   if (!Op)
908     Op = parseImmediate();
909 
910   // Only continue if next token is '['
911   if (Lexer.isNot(AsmToken::LBrac)) {
912     if (!Op)
913       return ParseStatus::NoMatch;
914 
915     // The start of this custom parsing overlaps with register/immediate so
916     // consider this as a successful match of an operand of that type as the
917     // token stream can't be rewound to allow them to match separately.
918     Operands.push_back(std::move(Op));
919     return ParseStatus::Success;
920   }
921 
922   Parser.Lex(); // Eat the '['.
923   std::unique_ptr<LanaiOperand> Offset = nullptr;
924   if (Op)
925     Offset.swap(Op);
926 
927   // Determine if a pre operation
928   PreOp = parsePrePost(Type, &OffsetValue);
929 
930   Op = parseRegister();
931   if (!Op) {
932     if (!Offset) {
933       if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) {
934         Parser.Lex(); // Eat the ']'
935 
936         // Memory address operations aligned to word boundary are encoded as
937         // SLS, the rest as RM.
938         if (shouldBeSls(*Op)) {
939           Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
940         } else {
941           if (!Op->isLoImm16Signed())
942             return Error(Parser.getTok().getLoc(),
943                          "Memory address is not word aligned and larger than "
944                          "class RM can handle");
945           Operands.push_back(LanaiOperand::MorphToMemRegImm(
946               Lanai::R0, std::move(Op), LPAC::ADD));
947         }
948         return ParseStatus::Success;
949       }
950     }
951 
952     return Error(Parser.getTok().getLoc(),
953                  "Unknown operand, expected register or immediate");
954   }
955   BaseReg = Op->getReg();
956 
957   // Determine if a post operation
958   if (!PreOp)
959     PostOp = parsePrePost(Type, &OffsetValue);
960 
961   // If ] match form (1) else match form (2)
962   if (Lexer.is(AsmToken::RBrac)) {
963     Parser.Lex(); // Eat the ']'.
964     if (!Offset) {
965       SMLoc Start = Parser.getTok().getLoc();
966       SMLoc End =
967           SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
968       const MCConstantExpr *OffsetConstExpr =
969           MCConstantExpr::create(OffsetValue, getContext());
970       Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
971     }
972   } else {
973     if (Offset || OffsetValue != 0)
974       return Error(Parser.getTok().getLoc(), "Expected ']'");
975 
976     // Parse operator
977     AluOp = parseAluOperator(PreOp, PostOp);
978 
979     // Second form requires offset register
980     Offset = parseRegister();
981     if (!BaseReg || Lexer.isNot(AsmToken::RBrac))
982       return Error(Parser.getTok().getLoc(), "Expected ']'");
983     Parser.Lex(); // Eat the ']'.
984   }
985 
986   // First form has addition as operator. Add pre- or post-op indicator as
987   // needed.
988   AluOp = AluWithPrePost(AluOp, PreOp, PostOp);
989 
990   // Ensure immediate offset is not too large
991   if (Offset->isImm() && !Offset->isLoImm16Signed())
992     return Error(Parser.getTok().getLoc(),
993                  "Memory address is not word aligned and larger than class RM "
994                  "can handle");
995 
996   Operands.push_back(
997       Offset->isImm()
998           ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)
999           : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp));
1000 
1001   return ParseStatus::Success;
1002 }
1003 
1004 // Looks at a token type and creates the relevant operand from this
1005 // information, adding to operands.
1006 // If operand was parsed, returns false, else true.
1007 ParseStatus LanaiAsmParser::parseOperand(OperandVector *Operands,
1008                                          StringRef Mnemonic) {
1009   // Check if the current operand has a custom associated parser, if so, try to
1010   // custom parse the operand, or fallback to the general approach.
1011   ParseStatus Result = MatchOperandParserImpl(*Operands, Mnemonic);
1012 
1013   if (Result.isSuccess())
1014     return Result;
1015   if (Result.isFailure()) {
1016     Parser.eatToEndOfStatement();
1017     return Result;
1018   }
1019 
1020   // Attempt to parse token as register
1021   std::unique_ptr<LanaiOperand> Op = parseRegister();
1022 
1023   // Attempt to parse token as immediate
1024   if (!Op)
1025     Op = parseImmediate();
1026 
1027   // If the token could not be parsed then fail
1028   if (!Op) {
1029     Error(Parser.getTok().getLoc(), "Unknown operand");
1030     Parser.eatToEndOfStatement();
1031     return ParseStatus::Failure;
1032   }
1033 
1034   // Push back parsed operand into list of operands
1035   Operands->push_back(std::move(Op));
1036 
1037   return ParseStatus::Success;
1038 }
1039 
1040 // Split the mnemonic into ASM operand, conditional code and instruction
1041 // qualifier (half-word, byte).
1042 StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
1043                                         OperandVector *Operands) {
1044   size_t Next = Name.find('.');
1045 
1046   StringRef Mnemonic = Name;
1047 
1048   bool IsBRR = Mnemonic.consume_back(".r");
1049 
1050   // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1051   if (Mnemonic[0] == 'b' ||
1052       (Mnemonic[0] == 's' && !Mnemonic.starts_with("sel") &&
1053        !Mnemonic.starts_with("st"))) {
1054     // Parse instructions with a conditional code. For example, 'bne' is
1055     // converted into two operands 'b' and 'ne'.
1056     LPCC::CondCode CondCode =
1057         LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next));
1058     if (CondCode != LPCC::UNKNOWN) {
1059       Mnemonic = Mnemonic.slice(0, 1);
1060       Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1061       Operands->push_back(LanaiOperand::createImm(
1062           MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1063       if (IsBRR) {
1064         Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1065       }
1066       return Mnemonic;
1067     }
1068   }
1069 
1070   // Parse other instructions with condition codes (RR instructions).
1071   // We ignore .f here and assume they are flag-setting operations, not
1072   // conditional codes (except for select instructions where flag-setting
1073   // variants are not yet implemented).
1074   if (Mnemonic.starts_with("sel") ||
1075       (!Mnemonic.ends_with(".f") && !Mnemonic.starts_with("st"))) {
1076     LPCC::CondCode CondCode = LPCC::suffixToLanaiCondCode(Mnemonic);
1077     if (CondCode != LPCC::UNKNOWN) {
1078       size_t Next = Mnemonic.rfind('.', Name.size());
1079       // 'sel' doesn't use a predicate operand whose printer adds the period,
1080       // but instead has the period as part of the identifier (i.e., 'sel.' is
1081       // expected by the generated matcher). If the mnemonic starts with 'sel'
1082       // then include the period as part of the mnemonic, else don't include it
1083       // as part of the mnemonic.
1084       if (Mnemonic.starts_with("sel")) {
1085         Mnemonic = Mnemonic.substr(0, Next + 1);
1086       } else {
1087         Mnemonic = Mnemonic.substr(0, Next);
1088       }
1089       Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1090       Operands->push_back(LanaiOperand::createImm(
1091           MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1092       return Mnemonic;
1093     }
1094   }
1095 
1096   Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1097   if (IsBRR) {
1098     Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1099   }
1100 
1101   return Mnemonic;
1102 }
1103 
1104 static bool IsMemoryAssignmentError(const OperandVector &Operands) {
1105   // Detects if a memory operation has an erroneous base register modification.
1106   // Memory operations are detected by matching the types of operands.
1107   //
1108   // TODO: This test is focussed on one specific instance (ld/st).
1109   // Extend it to handle more cases or be more robust.
1110   bool Modifies = false;
1111 
1112   int Offset = 0;
1113 
1114   if (Operands.size() < 5)
1115     return false;
1116   else if (Operands[0]->isToken() && Operands[1]->isReg() &&
1117            Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg())
1118     Offset = 0;
1119   else if (Operands[0]->isToken() && Operands[1]->isToken() &&
1120            Operands[2]->isReg() && Operands[3]->isImm() &&
1121            Operands[4]->isImm() && Operands[5]->isReg())
1122     Offset = 1;
1123   else
1124     return false;
1125 
1126   int PossibleAluOpIdx = Offset + 3;
1127   int PossibleBaseIdx = Offset + 1;
1128   int PossibleDestIdx = Offset + 4;
1129   if (LanaiOperand *PossibleAluOp =
1130           static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get()))
1131     if (PossibleAluOp->isImm())
1132       if (const MCConstantExpr *ConstExpr =
1133               dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
1134         Modifies = LPAC::modifiesOp(ConstExpr->getValue());
1135   return Modifies && Operands[PossibleBaseIdx]->isReg() &&
1136          Operands[PossibleDestIdx]->isReg() &&
1137          Operands[PossibleBaseIdx]->getReg() ==
1138              Operands[PossibleDestIdx]->getReg();
1139 }
1140 
1141 static bool IsRegister(const MCParsedAsmOperand &op) {
1142   return static_cast<const LanaiOperand &>(op).isReg();
1143 }
1144 
1145 static bool MaybePredicatedInst(const OperandVector &Operands) {
1146   if (Operands.size() < 4 || !IsRegister(*Operands[1]) ||
1147       !IsRegister(*Operands[2]))
1148     return false;
1149   return StringSwitch<bool>(
1150              static_cast<const LanaiOperand &>(*Operands[0]).getToken())
1151       .StartsWith("addc", true)
1152       .StartsWith("add", true)
1153       .StartsWith("and", true)
1154       .StartsWith("sh", true)
1155       .StartsWith("subb", true)
1156       .StartsWith("sub", true)
1157       .StartsWith("or", true)
1158       .StartsWith("xor", true)
1159       .Default(false);
1160 }
1161 
1162 bool LanaiAsmParser::parseInstruction(ParseInstructionInfo & /*Info*/,
1163                                       StringRef Name, SMLoc NameLoc,
1164                                       OperandVector &Operands) {
1165   // First operand is token for instruction
1166   StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
1167 
1168   // If there are no more operands, then finish
1169   if (Lexer.is(AsmToken::EndOfStatement))
1170     return false;
1171 
1172   // Parse first operand
1173   if (!parseOperand(&Operands, Mnemonic).isSuccess())
1174     return true;
1175 
1176   // If it is a st instruction with one 1 operand then it is a "store true".
1177   // Transform <"st"> to <"s">, <LPCC:ICC_T>
1178   if (Lexer.is(AsmToken::EndOfStatement) && Name == "st" &&
1179       Operands.size() == 2) {
1180     Operands.erase(Operands.begin(), Operands.begin() + 1);
1181     Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc));
1182     Operands.insert(Operands.begin() + 1,
1183                     LanaiOperand::createImm(
1184                         MCConstantExpr::create(LPCC::ICC_T, getContext()),
1185                         NameLoc, NameLoc));
1186   }
1187 
1188   // If the instruction is a bt instruction with 1 operand (in assembly) then it
1189   // is an unconditional branch instruction and the first two elements of
1190   // operands need to be merged.
1191   if (Lexer.is(AsmToken::EndOfStatement) && Name.starts_with("bt") &&
1192       Operands.size() == 3) {
1193     Operands.erase(Operands.begin(), Operands.begin() + 2);
1194     Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc));
1195   }
1196 
1197   // Parse until end of statement, consuming commas between operands
1198   while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.is(AsmToken::Comma)) {
1199     // Consume comma token
1200     Lex();
1201 
1202     // Parse next operand
1203     if (!parseOperand(&Operands, Mnemonic).isSuccess())
1204       return true;
1205   }
1206 
1207   if (IsMemoryAssignmentError(Operands)) {
1208     Error(Parser.getTok().getLoc(),
1209           "the destination register can't equal the base register in an "
1210           "instruction that modifies the base register.");
1211     return true;
1212   }
1213 
1214   // Insert always true operand for instruction that may be predicated but
1215   // are not. Currently the autogenerated parser always expects a predicate.
1216   if (MaybePredicatedInst(Operands)) {
1217     Operands.insert(Operands.begin() + 1,
1218                     LanaiOperand::createImm(
1219                         MCConstantExpr::create(LPCC::ICC_T, getContext()),
1220                         NameLoc, NameLoc));
1221   }
1222 
1223   return false;
1224 }
1225 
1226 #define GET_REGISTER_MATCHER
1227 #define GET_MATCHER_IMPLEMENTATION
1228 #include "LanaiGenAsmMatcher.inc"
1229 
1230 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiAsmParser() {
1231   RegisterMCAsmParser<LanaiAsmParser> x(getTheLanaiTarget());
1232 }
1233