LLVM  10.0.0svn
LanaiAsmParser.cpp
Go to the documentation of this file.
1 //===-- LanaiAsmParser.cpp - Parse Lanai assembly to MCInst instructions --===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "LanaiAluCode.h"
10 #include "LanaiCondCode.h"
11 #include "LanaiInstrInfo.h"
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 using namespace llvm;
40 
41 // Auto-generated by TableGen
42 static unsigned MatchRegisterName(StringRef Name);
43 
44 namespace {
45 
46 struct LanaiOperand;
47 
48 class LanaiAsmParser : public MCTargetAsmParser {
49  // Parse operands
50  std::unique_ptr<LanaiOperand> parseRegister();
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, MII), 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)
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!");
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(isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
479  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(isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
509  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 
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);
791  default:
792  return nullptr;
793  }
794 }
795 
796 static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) {
797  if (PreOp)
798  return LPAC::makePreOp(AluCode);
799  if (PostOp)
800  return LPAC::makePostOp(AluCode);
801  return AluCode;
802 }
803 
804 unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) {
805  StringRef IdString;
806  Parser.parseIdentifier(IdString);
807  unsigned AluCode = LPAC::stringToLanaiAluCode(IdString);
808  if (AluCode == LPAC::UNKNOWN) {
809  Error(Parser.getTok().getLoc(), "Can't parse ALU operator");
810  return 0;
811  }
812  return AluCode;
813 }
814 
815 static int SizeForSuffix(StringRef T) {
816  return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
817 }
818 
819 bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) {
820  bool PreOrPost = false;
821  if (Lexer.getKind() == Lexer.peekTok(true).getKind()) {
822  PreOrPost = true;
823  if (Lexer.is(AsmToken::Minus))
824  *OffsetValue = -SizeForSuffix(Type);
825  else if (Lexer.is(AsmToken::Plus))
826  *OffsetValue = SizeForSuffix(Type);
827  else
828  return false;
829 
830  // Eat the '-' '-' or '+' '+'
831  Parser.Lex();
832  Parser.Lex();
833  } else if (Lexer.is(AsmToken::Star)) {
834  Parser.Lex(); // Eat the '*'
835  PreOrPost = true;
836  }
837 
838  return PreOrPost;
839 }
840 
841 bool shouldBeSls(const LanaiOperand &Op) {
842  // The instruction should be encoded as an SLS if the constant is word
843  // aligned and will fit in 21 bits
844  if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
845  int64_t Value = ConstExpr->getValue();
846  return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff);
847  }
848  // The instruction should be encoded as an SLS if the operand is a symbolic
849  // reference with no variant.
850  if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
851  return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
852  // The instruction should be encoded as an SLS if the operand is a binary
853  // expression with the left-hand side being a symbolic reference with no
854  // variant.
855  if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
856  const LanaiMCExpr *LHSSymbolRefExpr =
857  dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
858  return (LHSSymbolRefExpr &&
859  LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
860  }
861  return false;
862 }
863 
864 // Matches memory operand. Returns true if error encountered.
866 LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) {
867  // Try to match a memory operand.
868  // The memory operands are of the form:
869  // (1) Register|Immediate|'' '[' '*'? Register '*'? ']' or
870  // ^
871  // (2) '[' '*'? Register '*'? AluOperator Register ']'
872  // ^
873  // (3) '[' '--'|'++' Register '--'|'++' ']'
874  //
875  // (4) '[' Immediate ']' (for SLS)
876 
877  // Store the type for use in parsing pre/post increment/decrement operators
878  StringRef Type;
879  if (Operands[0]->isToken())
880  Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken();
881 
882  // Use 0 if no offset given
883  int OffsetValue = 0;
884  unsigned BaseReg = 0;
885  unsigned AluOp = LPAC::ADD;
886  bool PostOp = false, PreOp = false;
887 
888  // Try to parse the offset
889  std::unique_ptr<LanaiOperand> Op = parseRegister();
890  if (!Op)
891  Op = parseImmediate();
892 
893  // Only continue if next token is '['
894  if (Lexer.isNot(AsmToken::LBrac)) {
895  if (!Op)
896  return MatchOperand_NoMatch;
897 
898  // The start of this custom parsing overlaps with register/immediate so
899  // consider this as a successful match of an operand of that type as the
900  // token stream can't be rewound to allow them to match separately.
901  Operands.push_back(std::move(Op));
902  return MatchOperand_Success;
903  }
904 
905  Parser.Lex(); // Eat the '['.
906  std::unique_ptr<LanaiOperand> Offset = nullptr;
907  if (Op)
908  Offset.swap(Op);
909 
910  // Determine if a pre operation
911  PreOp = parsePrePost(Type, &OffsetValue);
912 
913  Op = parseRegister();
914  if (!Op) {
915  if (!Offset) {
916  if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) {
917  Parser.Lex(); // Eat the ']'
918 
919  // Memory address operations aligned to word boundary are encoded as
920  // SLS, the rest as RM.
921  if (shouldBeSls(*Op)) {
922  Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
923  } else {
924  if (!Op->isLoImm16Signed()) {
925  Error(Parser.getTok().getLoc(),
926  "Memory address is not word "
927  "aligned and larger than class RM can handle");
928  return MatchOperand_ParseFail;
929  }
930  Operands.push_back(LanaiOperand::MorphToMemRegImm(
931  Lanai::R0, std::move(Op), LPAC::ADD));
932  }
933  return MatchOperand_Success;
934  }
935  }
936 
937  Error(Parser.getTok().getLoc(),
938  "Unknown operand, expected register or immediate");
939  return MatchOperand_ParseFail;
940  }
941  BaseReg = Op->getReg();
942 
943  // Determine if a post operation
944  if (!PreOp)
945  PostOp = parsePrePost(Type, &OffsetValue);
946 
947  // If ] match form (1) else match form (2)
948  if (Lexer.is(AsmToken::RBrac)) {
949  Parser.Lex(); // Eat the ']'.
950  if (!Offset) {
951  SMLoc Start = Parser.getTok().getLoc();
952  SMLoc End =
953  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
954  const MCConstantExpr *OffsetConstExpr =
955  MCConstantExpr::create(OffsetValue, getContext());
956  Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
957  }
958  } else {
959  if (Offset || OffsetValue != 0) {
960  Error(Parser.getTok().getLoc(), "Expected ']'");
961  return MatchOperand_ParseFail;
962  }
963 
964  // Parse operator
965  AluOp = parseAluOperator(PreOp, PostOp);
966 
967  // Second form requires offset register
968  Offset = parseRegister();
969  if (!BaseReg || Lexer.isNot(AsmToken::RBrac)) {
970  Error(Parser.getTok().getLoc(), "Expected ']'");
971  return MatchOperand_ParseFail;
972  }
973  Parser.Lex(); // Eat the ']'.
974  }
975 
976  // First form has addition as operator. Add pre- or post-op indicator as
977  // needed.
978  AluOp = AluWithPrePost(AluOp, PreOp, PostOp);
979 
980  // Ensure immediate offset is not too large
981  if (Offset->isImm() && !Offset->isLoImm16Signed()) {
982  Error(Parser.getTok().getLoc(),
983  "Memory address is not word "
984  "aligned and larger than class RM can handle");
985  return MatchOperand_ParseFail;
986  }
987 
988  Operands.push_back(
989  Offset->isImm()
990  ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)
991  : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp));
992 
993  return MatchOperand_Success;
994 }
995 
996 // Looks at a token type and creates the relevant operand from this
997 // information, adding to operands.
998 // If operand was parsed, returns false, else true.
1000 LanaiAsmParser::parseOperand(OperandVector *Operands, StringRef Mnemonic) {
1001  // Check if the current operand has a custom associated parser, if so, try to
1002  // custom parse the operand, or fallback to the general approach.
1003  OperandMatchResultTy Result = MatchOperandParserImpl(*Operands, Mnemonic);
1004 
1005  if (Result == MatchOperand_Success)
1006  return Result;
1007  if (Result == MatchOperand_ParseFail) {
1008  Parser.eatToEndOfStatement();
1009  return Result;
1010  }
1011 
1012  // Attempt to parse token as register
1013  std::unique_ptr<LanaiOperand> Op = parseRegister();
1014 
1015  // Attempt to parse token as immediate
1016  if (!Op)
1017  Op = parseImmediate();
1018 
1019  // If the token could not be parsed then fail
1020  if (!Op) {
1021  Error(Parser.getTok().getLoc(), "Unknown operand");
1022  Parser.eatToEndOfStatement();
1023  return MatchOperand_ParseFail;
1024  }
1025 
1026  // Push back parsed operand into list of operands
1027  Operands->push_back(std::move(Op));
1028 
1029  return MatchOperand_Success;
1030 }
1031 
1032 // Split the mnemonic into ASM operand, conditional code and instruction
1033 // qualifier (half-word, byte).
1034 StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
1035  OperandVector *Operands) {
1036  size_t Next = Name.find('.');
1037 
1038  StringRef Mnemonic = Name;
1039 
1040  bool IsBRR = false;
1041  if (Name.endswith(".r")) {
1042  Mnemonic = Name.substr(0, Name.size() - 2);
1043  IsBRR = true;
1044  }
1045 
1046  // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1047  if (Mnemonic[0] == 'b' ||
1048  (Mnemonic[0] == 's' && !Mnemonic.startswith("sel") &&
1049  !Mnemonic.startswith("st"))) {
1050  // Parse instructions with a conditional code. For example, 'bne' is
1051  // converted into two operands 'b' and 'ne'.
1053  LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next));
1054  if (CondCode != LPCC::UNKNOWN) {
1055  Mnemonic = Mnemonic.slice(0, 1);
1056  Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1057  Operands->push_back(LanaiOperand::createImm(
1058  MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1059  if (IsBRR) {
1060  Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1061  }
1062  return Mnemonic;
1063  }
1064  }
1065 
1066  // Parse other instructions with condition codes (RR instructions).
1067  // We ignore .f here and assume they are flag-setting operations, not
1068  // conditional codes (except for select instructions where flag-setting
1069  // variants are not yet implemented).
1070  if (Mnemonic.startswith("sel") ||
1071  (!Mnemonic.endswith(".f") && !Mnemonic.startswith("st"))) {
1073  if (CondCode != LPCC::UNKNOWN) {
1074  size_t Next = Mnemonic.rfind('.', Name.size());
1075  // 'sel' doesn't use a predicate operand whose printer adds the period,
1076  // but instead has the period as part of the identifier (i.e., 'sel.' is
1077  // expected by the generated matcher). If the mnemonic starts with 'sel'
1078  // then include the period as part of the mnemonic, else don't include it
1079  // as part of the mnemonic.
1080  if (Mnemonic.startswith("sel")) {
1081  Mnemonic = Mnemonic.substr(0, Next + 1);
1082  } else {
1083  Mnemonic = Mnemonic.substr(0, Next);
1084  }
1085  Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1086  Operands->push_back(LanaiOperand::createImm(
1087  MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1088  return Mnemonic;
1089  }
1090  }
1091 
1092  Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1093  if (IsBRR) {
1094  Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1095  }
1096 
1097  return Mnemonic;
1098 }
1099 
1100 static bool IsMemoryAssignmentError(const OperandVector &Operands) {
1101  // Detects if a memory operation has an erroneous base register modification.
1102  // Memory operations are detected by matching the types of operands.
1103  //
1104  // TODO: This test is focussed on one specific instance (ld/st).
1105  // Extend it to handle more cases or be more robust.
1106  bool Modifies = false;
1107 
1108  int Offset = 0;
1109 
1110  if (Operands.size() < 5)
1111  return false;
1112  else if (Operands[0]->isToken() && Operands[1]->isReg() &&
1113  Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg())
1114  Offset = 0;
1115  else if (Operands[0]->isToken() && Operands[1]->isToken() &&
1116  Operands[2]->isReg() && Operands[3]->isImm() &&
1117  Operands[4]->isImm() && Operands[5]->isReg())
1118  Offset = 1;
1119  else
1120  return false;
1121 
1122  int PossibleAluOpIdx = Offset + 3;
1123  int PossibleBaseIdx = Offset + 1;
1124  int PossibleDestIdx = Offset + 4;
1125  if (LanaiOperand *PossibleAluOp =
1126  static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get()))
1127  if (PossibleAluOp->isImm())
1128  if (const MCConstantExpr *ConstExpr =
1129  dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
1130  Modifies = LPAC::modifiesOp(ConstExpr->getValue());
1131  return Modifies && Operands[PossibleBaseIdx]->isReg() &&
1132  Operands[PossibleDestIdx]->isReg() &&
1133  Operands[PossibleBaseIdx]->getReg() ==
1134  Operands[PossibleDestIdx]->getReg();
1135 }
1136 
1137 static bool IsRegister(const MCParsedAsmOperand &op) {
1138  return static_cast<const LanaiOperand &>(op).isReg();
1139 }
1140 
1141 static bool MaybePredicatedInst(const OperandVector &Operands) {
1142  if (Operands.size() < 4 || !IsRegister(*Operands[1]) ||
1143  !IsRegister(*Operands[2]))
1144  return false;
1145  return StringSwitch<bool>(
1146  static_cast<const LanaiOperand &>(*Operands[0]).getToken())
1147  .StartsWith("addc", true)
1148  .StartsWith("add", true)
1149  .StartsWith("and", true)
1150  .StartsWith("sh", true)
1151  .StartsWith("subb", true)
1152  .StartsWith("sub", true)
1153  .StartsWith("or", true)
1154  .StartsWith("xor", true)
1155  .Default(false);
1156 }
1157 
1158 bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo & /*Info*/,
1159  StringRef Name, SMLoc NameLoc,
1160  OperandVector &Operands) {
1161  // First operand is token for instruction
1162  StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
1163 
1164  // If there are no more operands, then finish
1165  if (Lexer.is(AsmToken::EndOfStatement))
1166  return false;
1167 
1168  // Parse first operand
1169  if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1170  return true;
1171 
1172  // If it is a st instruction with one 1 operand then it is a "store true".
1173  // Transform <"st"> to <"s">, <LPCC:ICC_T>
1174  if (Lexer.is(AsmToken::EndOfStatement) && Name == "st" &&
1175  Operands.size() == 2) {
1176  Operands.erase(Operands.begin(), Operands.begin() + 1);
1177  Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc));
1178  Operands.insert(Operands.begin() + 1,
1179  LanaiOperand::createImm(
1180  MCConstantExpr::create(LPCC::ICC_T, getContext()),
1181  NameLoc, NameLoc));
1182  }
1183 
1184  // If the instruction is a bt instruction with 1 operand (in assembly) then it
1185  // is an unconditional branch instruction and the first two elements of
1186  // operands need to be merged.
1187  if (Lexer.is(AsmToken::EndOfStatement) && Name.startswith("bt") &&
1188  Operands.size() == 3) {
1189  Operands.erase(Operands.begin(), Operands.begin() + 2);
1190  Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc));
1191  }
1192 
1193  // Parse until end of statement, consuming commas between operands
1194  while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.is(AsmToken::Comma)) {
1195  // Consume comma token
1196  Lex();
1197 
1198  // Parse next operand
1199  if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1200  return true;
1201  }
1202 
1203  if (IsMemoryAssignmentError(Operands)) {
1204  Error(Parser.getTok().getLoc(),
1205  "the destination register can't equal the base register in an "
1206  "instruction that modifies the base register.");
1207  return true;
1208  }
1209 
1210  // Insert always true operand for instruction that may be predicated but
1211  // are not. Currently the autogenerated parser always expects a predicate.
1212  if (MaybePredicatedInst(Operands)) {
1213  Operands.insert(Operands.begin() + 1,
1214  LanaiOperand::createImm(
1215  MCConstantExpr::create(LPCC::ICC_T, getContext()),
1216  NameLoc, NameLoc));
1217  }
1218 
1219  return false;
1220 }
1221 
1222 #define GET_REGISTER_MATCHER
1223 #define GET_MATCHER_IMPLEMENTATION
1224 #include "LanaiGenAsmMatcher.inc"
1225 
1226 extern "C" void LLVMInitializeLanaiAsmParser() {
1228 }
static bool isReg(const MCInst &MI, unsigned OpNo)
static CondCode suffixToLanaiCondCode(StringRef S)
Definition: LanaiCondCode.h:73
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
Definition: MsgPackReader.h:48
static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp)
LLVM_NODISCARD bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:267
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:331
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Target & getTheLanaiTarget()
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
VariantKind getKind() const
Definition: MCExpr.h:346
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:167
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:109
static bool modifiesOp(unsigned AluOp)
Definition: LanaiAluCode.h:72
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:136
MCTargetAsmParser - Generic interface to target specific assembly parsers.
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:256
LLVM_NODISCARD size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
Definition: StringRef.h:345
void push_back(const T &Elt)
Definition: SmallVector.h:211
static int SizeForSuffix(StringRef T)
unsigned Reg
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:572
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:305
StringSwitch & StartsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:81
TOKEN(Invalid) TOKEN(Int) TOKEN(String) TOKEN(Identifier) SHORT_TOKEN(BlockBegin
static bool IsMemoryAssignmentError(const OperandVector &Operands)
#define op(i)
void LLVMInitializeLanaiAsmParser()
static const LanaiMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: LanaiMCExpr.cpp:17
static unsigned makePostOp(unsigned AluOp)
Definition: LanaiAluCode.h:67
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:960
static bool MaybePredicatedInst(const OperandVector &Operands)
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:115
Generic assembler lexer interface, for use by target specific assembly lexers.
Definition: MCAsmLexer.h:39
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
LLVM_NODISCARD R Default(T Value)
Definition: StringSwitch.h:181
static bool IsRegister(const MCParsedAsmOperand &op)
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:21
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:173
LLVM_NODISCARD StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:679
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:578
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:122
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \\\)
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:130
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:27
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
Definition: ISDOpcodes.h:995
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:469
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
Analysis containing CSE Info
Definition: CSEInfo.cpp:20
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false)
Definition: MCExpr.cpp:169
int64_t getValue() const
Definition: MCExpr.h:157
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
Streaming machine code generation interface.
Definition: MCStreamer.h:188
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:31
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
StringSwitch & EndsWith(StringLiteral S, T Value)
Definition: StringSwitch.h:74
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:23
LLVM_NODISCARD size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:285
bool shouldBeSls(const LanaiOperand &Op)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
iterator erase(const_iterator CI)
Definition: SmallVector.h:434
Binary assembler expressions.
Definition: MCExpr.h:425
size_t size() const
Definition: SmallVector.h:52
#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:62
Base class for user error types.
Definition: Error.h:344
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:467
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
static AluCode stringToLanaiAluCode(StringRef S)
Definition: LanaiAluCode.h:103
#define N
Generic base class for all target subtargets.
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:332
VariantKind getKind() const
Definition: LanaiMCExpr.h:33
constexpr bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:345
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:122
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:72
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:250
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
void addOperand(const MCOperand &Op)
Definition: MCInst.h:183
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
Represents a location in source code.
Definition: SMLoc.h:23
unsigned getOpcode() const
Definition: MCInst.h:171
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:122
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
static unsigned MatchRegisterName(StringRef Name)