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