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