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