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