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