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