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