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,
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,
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 
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 &&
473  SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO);
474 #endif
475  Inst.addOperand(MCOperand::createExpr(getImm()));
476  } else if (isa<MCBinaryExpr>(getImm())) {
477 #ifndef NDEBUG
478  const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
479  assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
480  cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
482 #endif
483  Inst.addOperand(MCOperand::createExpr(getImm()));
484  } else
485  assert(false && "Operand type not supported.");
486  }
487 
488  void addLoImm16AndOperands(MCInst &Inst, unsigned N) const {
489  assert(N == 1 && "Invalid number of operands!");
490  if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
491  Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0xffff));
492  else
493  assert(false && "Operand type not supported.");
494  }
495 
496  void addHiImm16Operands(MCInst &Inst, unsigned N) const {
497  assert(N == 1 && "Invalid number of operands!");
498  if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
499  Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
500  else if (isa<LanaiMCExpr>(getImm())) {
501 #ifndef NDEBUG
502  const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
503  assert(SymbolRefExpr &&
504  SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI);
505 #endif
506  Inst.addOperand(MCOperand::createExpr(getImm()));
507  } else if (isa<MCBinaryExpr>(getImm())) {
508 #ifndef NDEBUG
509  const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
510  assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
511  cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
513 #endif
514  Inst.addOperand(MCOperand::createExpr(getImm()));
515  } else
516  assert(false && "Operand type not supported.");
517  }
518 
519  void addHiImm16AndOperands(MCInst &Inst, unsigned N) const {
520  assert(N == 1 && "Invalid number of operands!");
521  if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
522  Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
523  else
524  assert(false && "Operand type not supported.");
525  }
526 
527  void addLoImm21Operands(MCInst &Inst, unsigned N) const {
528  assert(N == 1 && "Invalid number of operands!");
529  if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
530  Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
531  else if (isa<LanaiMCExpr>(getImm())) {
532 #ifndef NDEBUG
533  const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
534  assert(SymbolRefExpr &&
535  SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
536 #endif
537  Inst.addOperand(MCOperand::createExpr(getImm()));
538  } else if (isa<MCSymbolRefExpr>(getImm())) {
539 #ifndef NDEBUG
540  const MCSymbolRefExpr *SymbolRefExpr =
541  dyn_cast<MCSymbolRefExpr>(getImm());
542  assert(SymbolRefExpr &&
543  SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None);
544 #endif
545  Inst.addOperand(MCOperand::createExpr(getImm()));
546  } else if (isa<MCBinaryExpr>(getImm())) {
547 #ifndef NDEBUG
548  const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
549  assert(BinaryExpr && isa<LanaiMCExpr>(BinaryExpr->getLHS()) &&
550  cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
552 #endif
553  Inst.addOperand(MCOperand::createExpr(getImm()));
554  } else
555  assert(false && "Operand type not supported.");
556  }
557 
558  void print(raw_ostream &OS) const override {
559  switch (Kind) {
560  case IMMEDIATE:
561  OS << "Imm: " << getImm() << "\n";
562  break;
563  case TOKEN:
564  OS << "Token: " << getToken() << "\n";
565  break;
566  case REGISTER:
567  OS << "Reg: %r" << getReg() << "\n";
568  break;
569  case MEMORY_IMM:
570  OS << "MemImm: " << *getMemOffset() << "\n";
571  break;
572  case MEMORY_REG_IMM:
573  OS << "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
574  break;
575  case MEMORY_REG_REG:
576  assert(getMemOffset() == nullptr);
577  OS << "MemRegReg: " << getMemBaseReg() << "+"
578  << "%r" << getMemOffsetReg() << "\n";
579  break;
580  }
581  }
582 
583  static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
584  auto Op = std::make_unique<LanaiOperand>(TOKEN);
585  Op->Tok.Data = Str.data();
586  Op->Tok.Length = Str.size();
587  Op->StartLoc = Start;
588  Op->EndLoc = Start;
589  return Op;
590  }
591 
592  static std::unique_ptr<LanaiOperand> createReg(unsigned RegNum, SMLoc Start,
593  SMLoc End) {
594  auto Op = std::make_unique<LanaiOperand>(REGISTER);
595  Op->Reg.RegNum = RegNum;
596  Op->StartLoc = Start;
597  Op->EndLoc = End;
598  return Op;
599  }
600 
601  static std::unique_ptr<LanaiOperand> createImm(const MCExpr *Value,
602  SMLoc Start, SMLoc End) {
603  auto Op = std::make_unique<LanaiOperand>(IMMEDIATE);
604  Op->Imm.Value = Value;
605  Op->StartLoc = Start;
606  Op->EndLoc = End;
607  return Op;
608  }
609 
610  static std::unique_ptr<LanaiOperand>
611  MorphToMemImm(std::unique_ptr<LanaiOperand> Op) {
612  const MCExpr *Imm = Op->getImm();
613  Op->Kind = MEMORY_IMM;
614  Op->Mem.BaseReg = 0;
615  Op->Mem.AluOp = LPAC::ADD;
616  Op->Mem.OffsetReg = 0;
617  Op->Mem.Offset = Imm;
618  return Op;
619  }
620 
621  static std::unique_ptr<LanaiOperand>
622  MorphToMemRegReg(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
623  unsigned AluOp) {
624  unsigned OffsetReg = Op->getReg();
625  Op->Kind = MEMORY_REG_REG;
626  Op->Mem.BaseReg = BaseReg;
627  Op->Mem.AluOp = AluOp;
628  Op->Mem.OffsetReg = OffsetReg;
629  Op->Mem.Offset = nullptr;
630  return Op;
631  }
632 
633  static std::unique_ptr<LanaiOperand>
634  MorphToMemRegImm(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
635  unsigned AluOp) {
636  const MCExpr *Imm = Op->getImm();
637  Op->Kind = MEMORY_REG_IMM;
638  Op->Mem.BaseReg = BaseReg;
639  Op->Mem.AluOp = AluOp;
640  Op->Mem.OffsetReg = 0;
641  Op->Mem.Offset = Imm;
642  return Op;
643  }
644 };
645 
646 } // end anonymous namespace
647 
648 bool LanaiAsmParser::ParseDirective(AsmToken /*DirectiveId*/) { return true; }
649 
650 bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
652  MCStreamer &Out,
653  uint64_t &ErrorInfo,
654  bool MatchingInlineAsm) {
655  MCInst Inst;
656  SMLoc ErrorLoc;
657 
658  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
659  case Match_Success:
660  Out.EmitInstruction(Inst, SubtargetInfo);
661  Opcode = Inst.getOpcode();
662  return false;
663  case Match_MissingFeature:
664  return Error(IdLoc, "Instruction use requires option to be enabled");
665  case Match_MnemonicFail:
666  return Error(IdLoc, "Unrecognized instruction mnemonic");
667  case Match_InvalidOperand: {
668  ErrorLoc = IdLoc;
669  if (ErrorInfo != ~0U) {
670  if (ErrorInfo >= Operands.size())
671  return Error(IdLoc, "Too few operands for instruction");
672 
673  ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
674  if (ErrorLoc == SMLoc())
675  ErrorLoc = IdLoc;
676  }
677  return Error(ErrorLoc, "Invalid operand for instruction");
678  }
679  default:
680  break;
681  }
682 
683  llvm_unreachable("Unknown match type detected!");
684 }
685 
686 // Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
687 // backwards compatible with GCC and the different ways inline assembly is
688 // handled.
689 // TODO: see if there isn't a better way to do this.
690 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseRegister() {
691  SMLoc Start = Parser.getTok().getLoc();
692  SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
693 
694  unsigned RegNum;
695  // Eat the '%'.
696  if (Lexer.getKind() == AsmToken::Percent)
697  Parser.Lex();
698  if (Lexer.getKind() == AsmToken::Identifier) {
699  RegNum = MatchRegisterName(Lexer.getTok().getIdentifier());
700  if (RegNum == 0)
701  return nullptr;
702  Parser.Lex(); // Eat identifier token
703  return LanaiOperand::createReg(RegNum, Start, End);
704  }
705  return nullptr;
706 }
707 
708 bool LanaiAsmParser::ParseRegister(unsigned &RegNum, SMLoc &StartLoc,
709  SMLoc &EndLoc) {
710  const AsmToken &Tok = getParser().getTok();
711  StartLoc = Tok.getLoc();
712  EndLoc = Tok.getEndLoc();
713  std::unique_ptr<LanaiOperand> Op = parseRegister();
714  if (Op != nullptr)
715  RegNum = Op->getReg();
716  return (Op == nullptr);
717 }
718 
719 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
720  SMLoc Start = Parser.getTok().getLoc();
721  SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
722  const MCExpr *Res, *RHS = nullptr;
724 
725  if (Lexer.getKind() != AsmToken::Identifier)
726  return nullptr;
727 
729  if (Parser.parseIdentifier(Identifier))
730  return nullptr;
731 
732  // Check if identifier has a modifier
733  if (Identifier.equals_lower("hi"))
735  else if (Identifier.equals_lower("lo"))
737 
738  // If the identifier corresponds to a variant then extract the real
739  // identifier.
740  if (Kind != LanaiMCExpr::VK_Lanai_None) {
741  if (Lexer.getKind() != AsmToken::LParen) {
742  Error(Lexer.getLoc(), "Expected '('");
743  return nullptr;
744  }
745  Lexer.Lex(); // lex '('
746 
747  // Parse identifier
748  if (Parser.parseIdentifier(Identifier))
749  return nullptr;
750  }
751 
752  // If addition parse the RHS.
753  if (Lexer.getKind() == AsmToken::Plus && Parser.parseExpression(RHS))
754  return nullptr;
755 
756  // For variants parse the final ')'
757  if (Kind != LanaiMCExpr::VK_Lanai_None) {
758  if (Lexer.getKind() != AsmToken::RParen) {
759  Error(Lexer.getLoc(), "Expected ')'");
760  return nullptr;
761  }
762  Lexer.Lex(); // lex ')'
763  }
764 
765  End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
766  MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
767  const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
768  Res = LanaiMCExpr::create(Kind, Expr, getContext());
769 
770  // Nest if this was an addition
771  if (RHS)
772  Res = MCBinaryExpr::createAdd(Res, RHS, getContext());
773 
774  return LanaiOperand::createImm(Res, Start, End);
775 }
776 
777 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
778  SMLoc Start = Parser.getTok().getLoc();
779  SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
780 
781  const MCExpr *ExprVal;
782  switch (Lexer.getKind()) {
784  return parseIdentifier();
785  case AsmToken::Plus:
786  case AsmToken::Minus:
787  case AsmToken::Integer:
788  case AsmToken::Dot:
789  if (!Parser.parseExpression(ExprVal))
790  return LanaiOperand::createImm(ExprVal, Start, End);
792  default:
793  return nullptr;
794  }
795 }
796 
797 static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) {
798  if (PreOp)
799  return LPAC::makePreOp(AluCode);
800  if (PostOp)
801  return LPAC::makePostOp(AluCode);
802  return AluCode;
803 }
804 
805 unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) {
806  StringRef IdString;
807  Parser.parseIdentifier(IdString);
808  unsigned AluCode = LPAC::stringToLanaiAluCode(IdString);
809  if (AluCode == LPAC::UNKNOWN) {
810  Error(Parser.getTok().getLoc(), "Can't parse ALU operator");
811  return 0;
812  }
813  return AluCode;
814 }
815 
816 static int SizeForSuffix(StringRef T) {
817  return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
818 }
819 
820 bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) {
821  bool PreOrPost = false;
822  if (Lexer.getKind() == Lexer.peekTok(true).getKind()) {
823  PreOrPost = true;
824  if (Lexer.is(AsmToken::Minus))
825  *OffsetValue = -SizeForSuffix(Type);
826  else if (Lexer.is(AsmToken::Plus))
827  *OffsetValue = SizeForSuffix(Type);
828  else
829  return false;
830 
831  // Eat the '-' '-' or '+' '+'
832  Parser.Lex();
833  Parser.Lex();
834  } else if (Lexer.is(AsmToken::Star)) {
835  Parser.Lex(); // Eat the '*'
836  PreOrPost = true;
837  }
838 
839  return PreOrPost;
840 }
841 
842 bool shouldBeSls(const LanaiOperand &Op) {
843  // The instruction should be encoded as an SLS if the constant is word
844  // aligned and will fit in 21 bits
845  if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
846  int64_t Value = ConstExpr->getValue();
847  return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff);
848  }
849  // The instruction should be encoded as an SLS if the operand is a symbolic
850  // reference with no variant.
851  if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
852  return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
853  // The instruction should be encoded as an SLS if the operand is a binary
854  // expression with the left-hand side being a symbolic reference with no
855  // variant.
856  if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
857  const LanaiMCExpr *LHSSymbolRefExpr =
858  dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
859  return (LHSSymbolRefExpr &&
860  LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
861  }
862  return false;
863 }
864 
865 // Matches memory operand. Returns true if error encountered.
867 LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) {
868  // Try to match a memory operand.
869  // The memory operands are of the form:
870  // (1) Register|Immediate|'' '[' '*'? Register '*'? ']' or
871  // ^
872  // (2) '[' '*'? Register '*'? AluOperator Register ']'
873  // ^
874  // (3) '[' '--'|'++' Register '--'|'++' ']'
875  //
876  // (4) '[' Immediate ']' (for SLS)
877 
878  // Store the type for use in parsing pre/post increment/decrement operators
879  StringRef Type;
880  if (Operands[0]->isToken())
881  Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken();
882 
883  // Use 0 if no offset given
884  int OffsetValue = 0;
885  unsigned BaseReg = 0;
886  unsigned AluOp = LPAC::ADD;
887  bool PostOp = false, PreOp = false;
888 
889  // Try to parse the offset
890  std::unique_ptr<LanaiOperand> Op = parseRegister();
891  if (!Op)
892  Op = parseImmediate();
893 
894  // Only continue if next token is '['
895  if (Lexer.isNot(AsmToken::LBrac)) {
896  if (!Op)
897  return MatchOperand_NoMatch;
898 
899  // The start of this custom parsing overlaps with register/immediate so
900  // consider this as a successful match of an operand of that type as the
901  // token stream can't be rewound to allow them to match separately.
902  Operands.push_back(std::move(Op));
903  return MatchOperand_Success;
904  }
905 
906  Parser.Lex(); // Eat the '['.
907  std::unique_ptr<LanaiOperand> Offset = nullptr;
908  if (Op)
909  Offset.swap(Op);
910 
911  // Determine if a pre operation
912  PreOp = parsePrePost(Type, &OffsetValue);
913 
914  Op = parseRegister();
915  if (!Op) {
916  if (!Offset) {
917  if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) {
918  Parser.Lex(); // Eat the ']'
919 
920  // Memory address operations aligned to word boundary are encoded as
921  // SLS, the rest as RM.
922  if (shouldBeSls(*Op)) {
923  Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
924  } else {
925  if (!Op->isLoImm16Signed()) {
926  Error(Parser.getTok().getLoc(),
927  "Memory address is not word "
928  "aligned and larger than class RM can handle");
929  return MatchOperand_ParseFail;
930  }
931  Operands.push_back(LanaiOperand::MorphToMemRegImm(
932  Lanai::R0, std::move(Op), LPAC::ADD));
933  }
934  return MatchOperand_Success;
935  }
936  }
937 
938  Error(Parser.getTok().getLoc(),
939  "Unknown operand, expected register or immediate");
940  return MatchOperand_ParseFail;
941  }
942  BaseReg = Op->getReg();
943 
944  // Determine if a post operation
945  if (!PreOp)
946  PostOp = parsePrePost(Type, &OffsetValue);
947 
948  // If ] match form (1) else match form (2)
949  if (Lexer.is(AsmToken::RBrac)) {
950  Parser.Lex(); // Eat the ']'.
951  if (!Offset) {
952  SMLoc Start = Parser.getTok().getLoc();
953  SMLoc End =
954  SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
955  const MCConstantExpr *OffsetConstExpr =
956  MCConstantExpr::create(OffsetValue, getContext());
957  Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
958  }
959  } else {
960  if (Offset || OffsetValue != 0) {
961  Error(Parser.getTok().getLoc(), "Expected ']'");
962  return MatchOperand_ParseFail;
963  }
964 
965  // Parse operator
966  AluOp = parseAluOperator(PreOp, PostOp);
967 
968  // Second form requires offset register
969  Offset = parseRegister();
970  if (!BaseReg || Lexer.isNot(AsmToken::RBrac)) {
971  Error(Parser.getTok().getLoc(), "Expected ']'");
972  return MatchOperand_ParseFail;
973  }
974  Parser.Lex(); // Eat the ']'.
975  }
976 
977  // First form has addition as operator. Add pre- or post-op indicator as
978  // needed.
979  AluOp = AluWithPrePost(AluOp, PreOp, PostOp);
980 
981  // Ensure immediate offset is not too large
982  if (Offset->isImm() && !Offset->isLoImm16Signed()) {
983  Error(Parser.getTok().getLoc(),
984  "Memory address is not word "
985  "aligned and larger than class RM can handle");
986  return MatchOperand_ParseFail;
987  }
988 
989  Operands.push_back(
990  Offset->isImm()
991  ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)
992  : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp));
993 
994  return MatchOperand_Success;
995 }
996 
997 // Looks at a token type and creates the relevant operand from this
998 // information, adding to operands.
999 // If operand was parsed, returns false, else true.
1001 LanaiAsmParser::parseOperand(OperandVector *Operands, StringRef Mnemonic) {
1002  // Check if the current operand has a custom associated parser, if so, try to
1003  // custom parse the operand, or fallback to the general approach.
1004  OperandMatchResultTy Result = MatchOperandParserImpl(*Operands, Mnemonic);
1005 
1006  if (Result == MatchOperand_Success)
1007  return Result;
1008  if (Result == MatchOperand_ParseFail) {
1009  Parser.eatToEndOfStatement();
1010  return Result;
1011  }
1012 
1013  // Attempt to parse token as register
1014  std::unique_ptr<LanaiOperand> Op = parseRegister();
1015 
1016  // Attempt to parse token as immediate
1017  if (!Op)
1018  Op = parseImmediate();
1019 
1020  // If the token could not be parsed then fail
1021  if (!Op) {
1022  Error(Parser.getTok().getLoc(), "Unknown operand");
1023  Parser.eatToEndOfStatement();
1024  return MatchOperand_ParseFail;
1025  }
1026 
1027  // Push back parsed operand into list of operands
1028  Operands->push_back(std::move(Op));
1029 
1030  return MatchOperand_Success;
1031 }
1032 
1033 // Split the mnemonic into ASM operand, conditional code and instruction
1034 // qualifier (half-word, byte).
1035 StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
1036  OperandVector *Operands) {
1037  size_t Next = Name.find('.');
1038 
1039  StringRef Mnemonic = Name;
1040 
1041  bool IsBRR = false;
1042  if (Name.endswith(".r")) {
1043  Mnemonic = Name.substr(0, Name.size() - 2);
1044  IsBRR = true;
1045  }
1046 
1047  // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1048  if (Mnemonic[0] == 'b' ||
1049  (Mnemonic[0] == 's' && !Mnemonic.startswith("sel") &&
1050  !Mnemonic.startswith("st"))) {
1051  // Parse instructions with a conditional code. For example, 'bne' is
1052  // converted into two operands 'b' and 'ne'.
1054  LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next));
1055  if (CondCode != LPCC::UNKNOWN) {
1056  Mnemonic = Mnemonic.slice(0, 1);
1057  Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1058  Operands->push_back(LanaiOperand::createImm(
1059  MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1060  if (IsBRR) {
1061  Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1062  }
1063  return Mnemonic;
1064  }
1065  }
1066 
1067  // Parse other instructions with condition codes (RR instructions).
1068  // We ignore .f here and assume they are flag-setting operations, not
1069  // conditional codes (except for select instructions where flag-setting
1070  // variants are not yet implemented).
1071  if (Mnemonic.startswith("sel") ||
1072  (!Mnemonic.endswith(".f") && !Mnemonic.startswith("st"))) {
1074  if (CondCode != LPCC::UNKNOWN) {
1075  size_t Next = Mnemonic.rfind('.', Name.size());
1076  // 'sel' doesn't use a predicate operand whose printer adds the period,
1077  // but instead has the period as part of the identifier (i.e., 'sel.' is
1078  // expected by the generated matcher). If the mnemonic starts with 'sel'
1079  // then include the period as part of the mnemonic, else don't include it
1080  // as part of the mnemonic.
1081  if (Mnemonic.startswith("sel")) {
1082  Mnemonic = Mnemonic.substr(0, Next + 1);
1083  } else {
1084  Mnemonic = Mnemonic.substr(0, Next);
1085  }
1086  Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1087  Operands->push_back(LanaiOperand::createImm(
1088  MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1089  return Mnemonic;
1090  }
1091  }
1092 
1093  Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1094  if (IsBRR) {
1095  Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1096  }
1097 
1098  return Mnemonic;
1099 }
1100 
1101 static bool IsMemoryAssignmentError(const OperandVector &Operands) {
1102  // Detects if a memory operation has an erroneous base register modification.
1103  // Memory operations are detected by matching the types of operands.
1104  //
1105  // TODO: This test is focussed on one specific instance (ld/st).
1106  // Extend it to handle more cases or be more robust.
1107  bool Modifies = false;
1108 
1109  int Offset = 0;
1110 
1111  if (Operands.size() < 5)
1112  return false;
1113  else if (Operands[0]->isToken() && Operands[1]->isReg() &&
1114  Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg())
1115  Offset = 0;
1116  else if (Operands[0]->isToken() && Operands[1]->isToken() &&
1117  Operands[2]->isReg() && Operands[3]->isImm() &&
1118  Operands[4]->isImm() && Operands[5]->isReg())
1119  Offset = 1;
1120  else
1121  return false;
1122 
1123  int PossibleAluOpIdx = Offset + 3;
1124  int PossibleBaseIdx = Offset + 1;
1125  int PossibleDestIdx = Offset + 4;
1126  if (LanaiOperand *PossibleAluOp =
1127  static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get()))
1128  if (PossibleAluOp->isImm())
1129  if (const MCConstantExpr *ConstExpr =
1130  dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
1131  Modifies = LPAC::modifiesOp(ConstExpr->getValue());
1132  return Modifies && Operands[PossibleBaseIdx]->isReg() &&
1133  Operands[PossibleDestIdx]->isReg() &&
1134  Operands[PossibleBaseIdx]->getReg() ==
1135  Operands[PossibleDestIdx]->getReg();
1136 }
1137 
1138 static bool IsRegister(const MCParsedAsmOperand &op) {
1139  return static_cast<const LanaiOperand &>(op).isReg();
1140 }
1141 
1142 static bool MaybePredicatedInst(const OperandVector &Operands) {
1143  if (Operands.size() < 4 || !IsRegister(*Operands[1]) ||
1144  !IsRegister(*Operands[2]))
1145  return false;
1146  return StringSwitch<bool>(
1147  static_cast<const LanaiOperand &>(*Operands[0]).getToken())
1148  .StartsWith("addc", true)
1149  .StartsWith("add", true)
1150  .StartsWith("and", true)
1151  .StartsWith("sh", true)
1152  .StartsWith("subb", true)
1153  .StartsWith("sub", true)
1154  .StartsWith("or", true)
1155  .StartsWith("xor", true)
1156  .Default(false);
1157 }
1158 
1159 bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo & /*Info*/,
1160  StringRef Name, SMLoc NameLoc,
1161  OperandVector &Operands) {
1162  // First operand is token for instruction
1163  StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
1164 
1165  // If there are no more operands, then finish
1166  if (Lexer.is(AsmToken::EndOfStatement))
1167  return false;
1168 
1169  // Parse first operand
1170  if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1171  return true;
1172 
1173  // If it is a st instruction with one 1 operand then it is a "store true".
1174  // Transform <"st"> to <"s">, <LPCC:ICC_T>
1175  if (Lexer.is(AsmToken::EndOfStatement) && Name == "st" &&
1176  Operands.size() == 2) {
1177  Operands.erase(Operands.begin(), Operands.begin() + 1);
1178  Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc));
1179  Operands.insert(Operands.begin() + 1,
1180  LanaiOperand::createImm(
1181  MCConstantExpr::create(LPCC::ICC_T, getContext()),
1182  NameLoc, NameLoc));
1183  }
1184 
1185  // If the instruction is a bt instruction with 1 operand (in assembly) then it
1186  // is an unconditional branch instruction and the first two elements of
1187  // operands need to be merged.
1188  if (Lexer.is(AsmToken::EndOfStatement) && Name.startswith("bt") &&
1189  Operands.size() == 3) {
1190  Operands.erase(Operands.begin(), Operands.begin() + 2);
1191  Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc));
1192  }
1193 
1194  // Parse until end of statement, consuming commas between operands
1195  while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.is(AsmToken::Comma)) {
1196  // Consume comma token
1197  Lex();
1198 
1199  // Parse next operand
1200  if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1201  return true;
1202  }
1203 
1204  if (IsMemoryAssignmentError(Operands)) {
1205  Error(Parser.getTok().getLoc(),
1206  "the destination register can't equal the base register in an "
1207  "instruction that modifies the base register.");
1208  return true;
1209  }
1210 
1211  // Insert always true operand for instruction that may be predicated but
1212  // are not. Currently the autogenerated parser always expects a predicate.
1213  if (MaybePredicatedInst(Operands)) {
1214  Operands.insert(Operands.begin() + 1,
1215  LanaiOperand::createImm(
1216  MCConstantExpr::create(LPCC::ICC_T, getContext()),
1217  NameLoc, NameLoc));
1218  }
1219 
1220  return false;
1221 }
1222 
1223 #define GET_REGISTER_MATCHER
1224 #define GET_MATCHER_IMPLEMENTATION
1225 #include "LanaiGenAsmMatcher.inc"
1226 
1227 extern "C" void LLVMInitializeLanaiAsmParser() {
1229 }
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)
LLVM_NODISCARD bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition: StringRef.h:281
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:329
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:344
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:181
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:270
LLVM_NODISCARD size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
Definition: StringRef.h:359
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:570
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:342
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.
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:169
LLVM_NODISCARD StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition: StringRef.h:693
mir Rename Register Operands
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:592
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:125
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:144
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:1020
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:467
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:153
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:42
Streaming machine code generation interface.
Definition: MCStreamer.h:196
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:46
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:299
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:423
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:382
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:136
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:74
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:273
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)