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