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(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
87public:
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
96private:
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
105struct 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
146public:
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
650bool LanaiAsmParser::ParseDirective(AsmToken /*DirectiveId*/) { return true; }
651
652bool 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.
692std::unique_ptr<LanaiOperand>
693LanaiAsmParser::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
719bool 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
730OperandMatchResultTy 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
743std::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
801std::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
821static 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
829unsigned 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
840static int SizeForSuffix(StringRef T) {
841  return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
842}
843
844bool 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
866bool 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.
890OperandMatchResultTy
891LanaiAsmParser::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.
1024OperandMatchResultTy
1025LanaiAsmParser::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).
1059StringRef 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
1125static 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
1162static bool IsRegister(const MCParsedAsmOperand &op) {
1163  return static_cast<const LanaiOperand &>(op).isReg();
1164}
1165
1166static 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
1183bool 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
1251extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeLanaiAsmParser() {
1252  RegisterMCAsmParser<LanaiAsmParser> x(getTheLanaiTarget());
1253}
1254