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