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:
LanaiAsmParser(const MCSubtargetInfo & STI,MCAsmParser & Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)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 
LanaiOperandllvm::__anon737eca8c0111::LanaiOperand127   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
getStartLocllvm::__anon737eca8c0111::LanaiOperand134   SMLoc getStartLoc() const override { return StartLoc; }
135 
136   // getEndLoc - Gets location of the last token of this operand
getEndLocllvm::__anon737eca8c0111::LanaiOperand137   SMLoc getEndLoc() const override { return EndLoc; }
138 
getRegllvm::__anon737eca8c0111::LanaiOperand139   unsigned getReg() const override {
140     assert(isReg() && "Invalid type access!");
141     return Reg.RegNum;
142   }
143 
getImmllvm::__anon737eca8c0111::LanaiOperand144   const MCExpr *getImm() const {
145     assert(isImm() && "Invalid type access!");
146     return Imm.Value;
147   }
148 
getTokenllvm::__anon737eca8c0111::LanaiOperand149   StringRef getToken() const {
150     assert(isToken() && "Invalid type access!");
151     return StringRef(Tok.Data, Tok.Length);
152   }
153 
getMemBaseRegllvm::__anon737eca8c0111::LanaiOperand154   unsigned getMemBaseReg() const {
155     assert(isMem() && "Invalid type access!");
156     return Mem.BaseReg;
157   }
158 
getMemOffsetRegllvm::__anon737eca8c0111::LanaiOperand159   unsigned getMemOffsetReg() const {
160     assert(isMem() && "Invalid type access!");
161     return Mem.OffsetReg;
162   }
163 
getMemOffsetllvm::__anon737eca8c0111::LanaiOperand164   const MCExpr *getMemOffset() const {
165     assert(isMem() && "Invalid type access!");
166     return Mem.Offset;
167   }
168 
getMemOpllvm::__anon737eca8c0111::LanaiOperand169   unsigned getMemOp() const {
170     assert(isMem() && "Invalid type access!");
171     return Mem.AluOp;
172   }
173 
174   // Functions for testing operand type
isRegllvm::__anon737eca8c0111::LanaiOperand175   bool isReg() const override { return Kind == REGISTER; }
176 
isImmllvm::__anon737eca8c0111::LanaiOperand177   bool isImm() const override { return Kind == IMMEDIATE; }
178 
isMemllvm::__anon737eca8c0111::LanaiOperand179   bool isMem() const override {
180     return isMemImm() || isMemRegImm() || isMemRegReg();
181   }
182 
isMemImmllvm::__anon737eca8c0111::LanaiOperand183   bool isMemImm() const { return Kind == MEMORY_IMM; }
184 
isMemRegImmllvm::__anon737eca8c0111::LanaiOperand185   bool isMemRegImm() const { return Kind == MEMORY_REG_IMM; }
186 
isMemRegRegllvm::__anon737eca8c0111::LanaiOperand187   bool isMemRegReg() const { return Kind == MEMORY_REG_REG; }
188 
isMemSplsllvm::__anon737eca8c0111::LanaiOperand189   bool isMemSpls() const { return isMemRegImm() || isMemRegReg(); }
190 
isTokenllvm::__anon737eca8c0111::LanaiOperand191   bool isToken() const override { return Kind == TOKEN; }
192 
isBrImmllvm::__anon737eca8c0111::LanaiOperand193   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 
isBrTargetllvm::__anon737eca8c0111::LanaiOperand206   bool isBrTarget() { return isBrImm() || isToken(); }
207 
isCallTargetllvm::__anon737eca8c0111::LanaiOperand208   bool isCallTarget() { return isImm() || isToken(); }
209 
isHiImm16llvm::__anon737eca8c0111::LanaiOperand210   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 
isHiImm16Andllvm::__anon737eca8c0111::LanaiOperand233   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 
isLoImm16llvm::__anon737eca8c0111::LanaiOperand246   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 
isLoImm16Signedllvm::__anon737eca8c0111::LanaiOperand270   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 
isLoImm16Andllvm::__anon737eca8c0111::LanaiOperand294   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 
isImmShiftllvm::__anon737eca8c0111::LanaiOperand307   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 
isLoImm21llvm::__anon737eca8c0111::LanaiOperand318   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 
isImm10llvm::__anon737eca8c0111::LanaiOperand349   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 
isCondCodellvm::__anon737eca8c0111::LanaiOperand360   bool isCondCode() {
361     if (!isImm())
362       return false;
363 
364     const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
365     if (!ConstExpr)
366       return false;
367     uint64_t Value = ConstExpr->getValue();
368     // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
369     // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
370     // value corresponds to a valid condition code.
371     return Value < LPCC::UNKNOWN;
372   }
373 
addExprllvm::__anon737eca8c0111::LanaiOperand374   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
375     // Add as immediates where possible. Null MCExpr = 0
376     if (Expr == nullptr)
377       Inst.addOperand(MCOperand::createImm(0));
378     else if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Expr))
379       Inst.addOperand(
380           MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
381     else
382       Inst.addOperand(MCOperand::createExpr(Expr));
383   }
384 
addRegOperandsllvm::__anon737eca8c0111::LanaiOperand385   void addRegOperands(MCInst &Inst, unsigned N) const {
386     assert(N == 1 && "Invalid number of operands!");
387     Inst.addOperand(MCOperand::createReg(getReg()));
388   }
389 
addImmOperandsllvm::__anon737eca8c0111::LanaiOperand390   void addImmOperands(MCInst &Inst, unsigned N) const {
391     assert(N == 1 && "Invalid number of operands!");
392     addExpr(Inst, getImm());
393   }
394 
addBrTargetOperandsllvm::__anon737eca8c0111::LanaiOperand395   void addBrTargetOperands(MCInst &Inst, unsigned N) const {
396     assert(N == 1 && "Invalid number of operands!");
397     addExpr(Inst, getImm());
398   }
399 
addCallTargetOperandsllvm::__anon737eca8c0111::LanaiOperand400   void addCallTargetOperands(MCInst &Inst, unsigned N) const {
401     assert(N == 1 && "Invalid number of operands!");
402     addExpr(Inst, getImm());
403   }
404 
addCondCodeOperandsllvm::__anon737eca8c0111::LanaiOperand405   void addCondCodeOperands(MCInst &Inst, unsigned N) const {
406     assert(N == 1 && "Invalid number of operands!");
407     addExpr(Inst, getImm());
408   }
409 
addMemImmOperandsllvm::__anon737eca8c0111::LanaiOperand410   void addMemImmOperands(MCInst &Inst, unsigned N) const {
411     assert(N == 1 && "Invalid number of operands!");
412     const MCExpr *Expr = getMemOffset();
413     addExpr(Inst, Expr);
414   }
415 
addMemRegImmOperandsllvm::__anon737eca8c0111::LanaiOperand416   void addMemRegImmOperands(MCInst &Inst, unsigned N) const {
417     assert(N == 3 && "Invalid number of operands!");
418     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
419     const MCExpr *Expr = getMemOffset();
420     addExpr(Inst, Expr);
421     Inst.addOperand(MCOperand::createImm(getMemOp()));
422   }
423 
addMemRegRegOperandsllvm::__anon737eca8c0111::LanaiOperand424   void addMemRegRegOperands(MCInst &Inst, unsigned N) const {
425     assert(N == 3 && "Invalid number of operands!");
426     Inst.addOperand(MCOperand::createReg(getMemBaseReg()));
427     assert(getMemOffsetReg() != 0 && "Invalid offset");
428     Inst.addOperand(MCOperand::createReg(getMemOffsetReg()));
429     Inst.addOperand(MCOperand::createImm(getMemOp()));
430   }
431 
addMemSplsOperandsllvm::__anon737eca8c0111::LanaiOperand432   void addMemSplsOperands(MCInst &Inst, unsigned N) const {
433     if (isMemRegImm())
434       addMemRegImmOperands(Inst, N);
435     if (isMemRegReg())
436       addMemRegRegOperands(Inst, N);
437   }
438 
addImmShiftOperandsllvm::__anon737eca8c0111::LanaiOperand439   void addImmShiftOperands(MCInst &Inst, unsigned N) const {
440     assert(N == 1 && "Invalid number of operands!");
441     addExpr(Inst, getImm());
442   }
443 
addImm10Operandsllvm::__anon737eca8c0111::LanaiOperand444   void addImm10Operands(MCInst &Inst, unsigned N) const {
445     assert(N == 1 && "Invalid number of operands!");
446     addExpr(Inst, getImm());
447   }
448 
addLoImm16Operandsllvm::__anon737eca8c0111::LanaiOperand449   void addLoImm16Operands(MCInst &Inst, unsigned N) const {
450     assert(N == 1 && "Invalid number of operands!");
451     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
452       Inst.addOperand(
453           MCOperand::createImm(static_cast<int32_t>(ConstExpr->getValue())));
454     else if (isa<LanaiMCExpr>(getImm())) {
455 #ifndef NDEBUG
456       const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
457       assert(SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_LO);
458 #endif
459       Inst.addOperand(MCOperand::createExpr(getImm()));
460     } else if (isa<MCBinaryExpr>(getImm())) {
461 #ifndef NDEBUG
462       const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
463       assert(dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()) &&
464              dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
465                  LanaiMCExpr::VK_Lanai_ABS_LO);
466 #endif
467       Inst.addOperand(MCOperand::createExpr(getImm()));
468     } else
469       assert(false && "Operand type not supported.");
470   }
471 
addLoImm16AndOperandsllvm::__anon737eca8c0111::LanaiOperand472   void addLoImm16AndOperands(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() & 0xffff));
476     else
477       assert(false && "Operand type not supported.");
478   }
479 
addHiImm16Operandsllvm::__anon737eca8c0111::LanaiOperand480   void addHiImm16Operands(MCInst &Inst, unsigned N) const {
481     assert(N == 1 && "Invalid number of operands!");
482     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
483       Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() >> 16));
484     else if (isa<LanaiMCExpr>(getImm())) {
485 #ifndef NDEBUG
486       const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
487       assert(SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_ABS_HI);
488 #endif
489       Inst.addOperand(MCOperand::createExpr(getImm()));
490     } else if (isa<MCBinaryExpr>(getImm())) {
491 #ifndef NDEBUG
492       const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
493       assert(dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS()) &&
494              dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS())->getKind() ==
495                  LanaiMCExpr::VK_Lanai_ABS_HI);
496 #endif
497       Inst.addOperand(MCOperand::createExpr(getImm()));
498     } else
499       assert(false && "Operand type not supported.");
500   }
501 
addHiImm16AndOperandsllvm::__anon737eca8c0111::LanaiOperand502   void addHiImm16AndOperands(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() >> 16));
506     else
507       assert(false && "Operand type not supported.");
508   }
509 
addLoImm21Operandsllvm::__anon737eca8c0111::LanaiOperand510   void addLoImm21Operands(MCInst &Inst, unsigned N) const {
511     assert(N == 1 && "Invalid number of operands!");
512     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(getImm()))
513       Inst.addOperand(MCOperand::createImm(ConstExpr->getValue() & 0x1fffff));
514     else if (isa<LanaiMCExpr>(getImm())) {
515 #ifndef NDEBUG
516       const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(getImm());
517       assert(SymbolRefExpr &&
518              SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
519 #endif
520       Inst.addOperand(MCOperand::createExpr(getImm()));
521     } else if (isa<MCSymbolRefExpr>(getImm())) {
522 #ifndef NDEBUG
523       const MCSymbolRefExpr *SymbolRefExpr =
524           dyn_cast<MCSymbolRefExpr>(getImm());
525       assert(SymbolRefExpr &&
526              SymbolRefExpr->getKind() == MCSymbolRefExpr::VK_None);
527 #endif
528       Inst.addOperand(MCOperand::createExpr(getImm()));
529     } else if (isa<MCBinaryExpr>(getImm())) {
530 #ifndef NDEBUG
531       const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(getImm());
532       const LanaiMCExpr *SymbolRefExpr =
533           dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
534       assert(SymbolRefExpr &&
535              SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
536 #endif
537       Inst.addOperand(MCOperand::createExpr(getImm()));
538     } else
539       assert(false && "Operand type not supported.");
540   }
541 
printllvm::__anon737eca8c0111::LanaiOperand542   void print(raw_ostream &OS) const override {
543     switch (Kind) {
544     case IMMEDIATE:
545       OS << "Imm: " << getImm() << "\n";
546       break;
547     case TOKEN:
548       OS << "Token: " << getToken() << "\n";
549       break;
550     case REGISTER:
551       OS << "Reg: %r" << getReg() << "\n";
552       break;
553     case MEMORY_IMM:
554       OS << "MemImm: " << *getMemOffset() << "\n";
555       break;
556     case MEMORY_REG_IMM:
557       OS << "MemRegImm: " << getMemBaseReg() << "+" << *getMemOffset() << "\n";
558       break;
559     case MEMORY_REG_REG:
560       assert(getMemOffset() == nullptr);
561       OS << "MemRegReg: " << getMemBaseReg() << "+"
562          << "%r" << getMemOffsetReg() << "\n";
563       break;
564     }
565   }
566 
CreateTokenllvm::__anon737eca8c0111::LanaiOperand567   static std::unique_ptr<LanaiOperand> CreateToken(StringRef Str, SMLoc Start) {
568     auto Op = make_unique<LanaiOperand>(TOKEN);
569     Op->Tok.Data = Str.data();
570     Op->Tok.Length = Str.size();
571     Op->StartLoc = Start;
572     Op->EndLoc = Start;
573     return Op;
574   }
575 
createRegllvm::__anon737eca8c0111::LanaiOperand576   static std::unique_ptr<LanaiOperand> createReg(unsigned RegNum, SMLoc Start,
577                                                  SMLoc End) {
578     auto Op = make_unique<LanaiOperand>(REGISTER);
579     Op->Reg.RegNum = RegNum;
580     Op->StartLoc = Start;
581     Op->EndLoc = End;
582     return Op;
583   }
584 
createImmllvm::__anon737eca8c0111::LanaiOperand585   static std::unique_ptr<LanaiOperand> createImm(const MCExpr *Value,
586                                                  SMLoc Start, SMLoc End) {
587     auto Op = make_unique<LanaiOperand>(IMMEDIATE);
588     Op->Imm.Value = Value;
589     Op->StartLoc = Start;
590     Op->EndLoc = End;
591     return Op;
592   }
593 
594   static std::unique_ptr<LanaiOperand>
MorphToMemImmllvm::__anon737eca8c0111::LanaiOperand595   MorphToMemImm(std::unique_ptr<LanaiOperand> Op) {
596     const MCExpr *Imm = Op->getImm();
597     Op->Kind = MEMORY_IMM;
598     Op->Mem.BaseReg = 0;
599     Op->Mem.AluOp = LPAC::ADD;
600     Op->Mem.OffsetReg = 0;
601     Op->Mem.Offset = Imm;
602     return Op;
603   }
604 
605   static std::unique_ptr<LanaiOperand>
MorphToMemRegRegllvm::__anon737eca8c0111::LanaiOperand606   MorphToMemRegReg(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
607                    unsigned AluOp) {
608     unsigned OffsetReg = Op->getReg();
609     Op->Kind = MEMORY_REG_REG;
610     Op->Mem.BaseReg = BaseReg;
611     Op->Mem.AluOp = AluOp;
612     Op->Mem.OffsetReg = OffsetReg;
613     Op->Mem.Offset = nullptr;
614     return Op;
615   }
616 
617   static std::unique_ptr<LanaiOperand>
MorphToMemRegImmllvm::__anon737eca8c0111::LanaiOperand618   MorphToMemRegImm(unsigned BaseReg, std::unique_ptr<LanaiOperand> Op,
619                    unsigned AluOp) {
620     const MCExpr *Imm = Op->getImm();
621     Op->Kind = MEMORY_REG_IMM;
622     Op->Mem.BaseReg = BaseReg;
623     Op->Mem.AluOp = AluOp;
624     Op->Mem.OffsetReg = 0;
625     Op->Mem.Offset = Imm;
626     return Op;
627   }
628 };
629 
ParseDirective(AsmToken DirectiveId)630 bool LanaiAsmParser::ParseDirective(AsmToken DirectiveId) { return true; }
631 
MatchAndEmitInstruction(SMLoc IdLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)632 bool LanaiAsmParser::MatchAndEmitInstruction(SMLoc IdLoc, unsigned &Opcode,
633                                              OperandVector &Operands,
634                                              MCStreamer &Out,
635                                              uint64_t &ErrorInfo,
636                                              bool MatchingInlineAsm) {
637   MCInst Inst;
638   SMLoc ErrorLoc;
639 
640   switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
641   case Match_Success:
642     Out.EmitInstruction(Inst, SubtargetInfo);
643     return false;
644   case Match_MissingFeature:
645     return Error(IdLoc, "Instruction use requires option to be enabled");
646   case Match_MnemonicFail:
647     return Error(IdLoc, "Unrecognized instruction mnemonic");
648   case Match_InvalidOperand: {
649     ErrorLoc = IdLoc;
650     if (ErrorInfo != ~0U) {
651       if (ErrorInfo >= Operands.size())
652         return Error(IdLoc, "Too few operands for instruction");
653 
654       ErrorLoc = ((LanaiOperand &)*Operands[ErrorInfo]).getStartLoc();
655       if (ErrorLoc == SMLoc())
656         ErrorLoc = IdLoc;
657     }
658     return Error(ErrorLoc, "Invalid operand for instruction");
659   }
660   default:
661     break;
662   }
663 
664   llvm_unreachable("Unknown match type detected!");
665 }
666 
667 // Both '%rN' and 'rN' are parsed as valid registers. This was done to remain
668 // backwards compatible with GCC and the different ways inline assembly is
669 // handled.
670 // TODO: see if there isn't a better way to do this.
parseRegister()671 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseRegister() {
672   SMLoc Start = Parser.getTok().getLoc();
673   SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
674 
675   unsigned RegNum;
676   // Eat the '%'.
677   if (Lexer.getKind() == AsmToken::Percent)
678     Parser.Lex();
679   if (Lexer.getKind() == AsmToken::Identifier) {
680     RegNum = MatchRegisterName(Lexer.getTok().getIdentifier());
681     if (RegNum == 0)
682       return 0;
683     Parser.Lex(); // Eat identifier token
684     return LanaiOperand::createReg(RegNum, Start, End);
685   }
686   return 0;
687 }
688 
ParseRegister(unsigned & RegNum,SMLoc & StartLoc,SMLoc & EndLoc)689 bool LanaiAsmParser::ParseRegister(unsigned &RegNum, SMLoc &StartLoc,
690                                    SMLoc &EndLoc) {
691   std::unique_ptr<LanaiOperand> Op = parseRegister();
692   if (Op != 0)
693     RegNum = Op->getReg();
694   return (Op == 0);
695 }
696 
parseIdentifier()697 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseIdentifier() {
698   SMLoc Start = Parser.getTok().getLoc();
699   SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
700   const MCExpr *Res, *RHS = 0;
701   LanaiMCExpr::VariantKind Kind = LanaiMCExpr::VK_Lanai_None;
702 
703   if (Lexer.getKind() != AsmToken::Identifier)
704     return 0;
705 
706   StringRef Identifier;
707   if (Parser.parseIdentifier(Identifier))
708     return 0;
709 
710   // Check if identifier has a modifier
711   if (Identifier.equals_lower("hi"))
712     Kind = LanaiMCExpr::VK_Lanai_ABS_HI;
713   else if (Identifier.equals_lower("lo"))
714     Kind = LanaiMCExpr::VK_Lanai_ABS_LO;
715 
716   // If the identifier corresponds to a variant then extract the real
717   // identifier.
718   if (Kind != LanaiMCExpr::VK_Lanai_None) {
719     if (Lexer.getKind() != AsmToken::LParen) {
720       Error(Lexer.getLoc(), "Expected '('");
721       return 0;
722     }
723     Lexer.Lex(); // lex '('
724 
725     // Parse identifier
726     if (Parser.parseIdentifier(Identifier))
727       return 0;
728   }
729 
730   // If addition parse the RHS.
731   if (Lexer.getKind() == AsmToken::Plus && Parser.parseExpression(RHS))
732     return 0;
733 
734   // For variants parse the final ')'
735   if (Kind != LanaiMCExpr::VK_Lanai_None) {
736     if (Lexer.getKind() != AsmToken::RParen) {
737       Error(Lexer.getLoc(), "Expected ')'");
738       return 0;
739     }
740     Lexer.Lex(); // lex ')'
741   }
742 
743   End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
744   MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
745   const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
746   Res = LanaiMCExpr::create(Kind, Expr, getContext());
747 
748   // Nest if this was an addition
749   if (RHS)
750     Res = MCBinaryExpr::createAdd(Res, RHS, getContext());
751 
752   return LanaiOperand::createImm(Res, Start, End);
753 }
754 
parseImmediate()755 std::unique_ptr<LanaiOperand> LanaiAsmParser::parseImmediate() {
756   SMLoc Start = Parser.getTok().getLoc();
757   SMLoc End = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
758 
759   const MCExpr *ExprVal;
760   switch (Lexer.getKind()) {
761   case AsmToken::Identifier:
762     return parseIdentifier();
763   case AsmToken::Plus:
764   case AsmToken::Minus:
765   case AsmToken::Integer:
766   case AsmToken::Dot:
767     if (!Parser.parseExpression(ExprVal))
768       return LanaiOperand::createImm(ExprVal, Start, End);
769   default:
770     return 0;
771   }
772 }
773 
AluWithPrePost(unsigned AluCode,bool PreOp,bool PostOp)774 static unsigned AluWithPrePost(unsigned AluCode, bool PreOp, bool PostOp) {
775   if (PreOp)
776     return LPAC::makePreOp(AluCode);
777   if (PostOp)
778     return LPAC::makePostOp(AluCode);
779   return AluCode;
780 }
781 
parseAluOperator(bool PreOp,bool PostOp)782 unsigned LanaiAsmParser::parseAluOperator(bool PreOp, bool PostOp) {
783   StringRef IdString;
784   Parser.parseIdentifier(IdString);
785   unsigned AluCode = LPAC::stringToLanaiAluCode(IdString);
786   if (AluCode == LPAC::UNKNOWN) {
787     Error(Parser.getTok().getLoc(), "Can't parse ALU operator");
788     return 0;
789   }
790   return AluCode;
791 }
792 
SizeForSuffix(StringRef T)793 static int SizeForSuffix(StringRef T) {
794   return StringSwitch<int>(T).EndsWith(".h", 2).EndsWith(".b", 1).Default(4);
795 }
796 
parsePrePost(StringRef Type,int * OffsetValue)797 bool LanaiAsmParser::parsePrePost(StringRef Type, int *OffsetValue) {
798   bool PreOrPost = false;
799   if (Lexer.getKind() == Lexer.peekTok(true).getKind()) {
800     PreOrPost = true;
801     if (Lexer.is(AsmToken::Minus))
802       *OffsetValue = -SizeForSuffix(Type);
803     else if (Lexer.is(AsmToken::Plus))
804       *OffsetValue = SizeForSuffix(Type);
805     else
806       return false;
807 
808     // Eat the '-' '-' or '+' '+'
809     Parser.Lex();
810     Parser.Lex();
811   } else if (Lexer.is(AsmToken::Star)) {
812     Parser.Lex(); // Eat the '*'
813     PreOrPost = true;
814   }
815 
816   return PreOrPost;
817 }
818 
shouldBeSls(const LanaiOperand & Op)819 bool shouldBeSls(const LanaiOperand &Op) {
820   // The instruction should be encoded as an SLS if the constant is word
821   // aligned and will fit in 21 bits
822   if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm())) {
823     int64_t Value = ConstExpr->getValue();
824     return (Value % 4 == 0) && (Value >= 0) && (Value <= 0x1fffff);
825   }
826   // The instruction should be encoded as an SLS if the operand is a symbolic
827   // reference with no variant.
828   if (const LanaiMCExpr *SymbolRefExpr = dyn_cast<LanaiMCExpr>(Op.getImm()))
829     return SymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None;
830   // The instruction should be encoded as an SLS if the operand is a binary
831   // expression with the left-hand side being a symbolic reference with no
832   // variant.
833   if (const MCBinaryExpr *BinaryExpr = dyn_cast<MCBinaryExpr>(Op.getImm())) {
834     const LanaiMCExpr *LHSSymbolRefExpr =
835         dyn_cast<LanaiMCExpr>(BinaryExpr->getLHS());
836     return (LHSSymbolRefExpr &&
837             LHSSymbolRefExpr->getKind() == LanaiMCExpr::VK_Lanai_None);
838   }
839   return false;
840 }
841 
842 // Matches memory operand. Returns true if error encountered.
843 LanaiAsmParser::OperandMatchResultTy
parseMemoryOperand(OperandVector & Operands)844 LanaiAsmParser::parseMemoryOperand(OperandVector &Operands) {
845   // Try to match a memory operand.
846   // The memory operands are of the form:
847   //  (1)  Register|Immediate|'' '[' '*'? Register '*'? ']' or
848   //                            ^
849   //  (2)  '[' '*'? Register '*'? AluOperator Register ']'
850   //      ^
851   //  (3)  '[' '--'|'++' Register '--'|'++' ']'
852   //
853   //  (4) '[' Immediate ']' (for SLS)
854 
855   // Store the type for use in parsing pre/post increment/decrement operators
856   StringRef Type;
857   if (Operands[0]->isToken())
858     Type = static_cast<LanaiOperand *>(Operands[0].get())->getToken();
859 
860   // Use 0 if no offset given
861   int OffsetValue = 0;
862   unsigned BaseReg = 0;
863   unsigned AluOp = LPAC::ADD;
864   bool PostOp = false, PreOp = false;
865 
866   // Try to parse the offset
867   std::unique_ptr<LanaiOperand> Op = parseRegister();
868   if (!Op)
869     Op = parseImmediate();
870 
871   // Only continue if next token is '['
872   if (Lexer.isNot(AsmToken::LBrac)) {
873     if (!Op)
874       return MatchOperand_NoMatch;
875 
876     // The start of this custom parsing overlaps with register/immediate so
877     // consider this as a successful match of an operand of that type as the
878     // token stream can't be rewound to allow them to match separately.
879     Operands.push_back(std::move(Op));
880     return MatchOperand_Success;
881   }
882 
883   Parser.Lex(); // Eat the '['.
884   std::unique_ptr<LanaiOperand> Offset = nullptr;
885   if (Op)
886     Offset.swap(Op);
887 
888   // Determine if a pre operation
889   PreOp = parsePrePost(Type, &OffsetValue);
890 
891   Op = parseRegister();
892   if (!Op) {
893     if (!Offset) {
894       if ((Op = parseImmediate()) && Lexer.is(AsmToken::RBrac)) {
895         Parser.Lex(); // Eat the ']'
896 
897         // Memory address operations aligned to word boundary are encoded as
898         // SLS, the rest as RM.
899         if (shouldBeSls(*Op)) {
900           Operands.push_back(LanaiOperand::MorphToMemImm(std::move(Op)));
901         } else {
902           if (!Op->isLoImm16Signed()) {
903             Error(Parser.getTok().getLoc(),
904                   "Memory address is not word "
905                   "aligned and larger than class RM can handle");
906             return MatchOperand_ParseFail;
907           }
908           Operands.push_back(LanaiOperand::MorphToMemRegImm(
909               Lanai::R0, std::move(Op), LPAC::ADD));
910         }
911         return MatchOperand_Success;
912       }
913     }
914 
915     Error(Parser.getTok().getLoc(),
916           "Unknown operand, expected register or immediate");
917     return MatchOperand_ParseFail;
918   }
919   BaseReg = Op->getReg();
920 
921   // Determine if a post operation
922   if (!PreOp)
923     PostOp = parsePrePost(Type, &OffsetValue);
924 
925   // If ] match form (1) else match form (2)
926   if (Lexer.is(AsmToken::RBrac)) {
927     Parser.Lex(); // Eat the ']'.
928     if (!Offset) {
929       SMLoc Start = Parser.getTok().getLoc();
930       SMLoc End =
931           SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
932       const MCConstantExpr *OffsetConstExpr =
933           MCConstantExpr::create(OffsetValue, getContext());
934       Offset = LanaiOperand::createImm(OffsetConstExpr, Start, End);
935     }
936   } else {
937     if (Offset || OffsetValue != 0) {
938       Error(Parser.getTok().getLoc(), "Expected ']'");
939       return MatchOperand_ParseFail;
940     }
941 
942     // Parse operator
943     AluOp = parseAluOperator(PreOp, PostOp);
944 
945     // Second form requires offset register
946     Offset = parseRegister();
947     if (!BaseReg || Lexer.isNot(AsmToken::RBrac)) {
948       Error(Parser.getTok().getLoc(), "Expected ']'");
949       return MatchOperand_ParseFail;
950     }
951     Parser.Lex(); // Eat the ']'.
952   }
953 
954   // First form has addition as operator. Add pre- or post-op indicator as
955   // needed.
956   AluOp = AluWithPrePost(AluOp, PreOp, PostOp);
957 
958   // Ensure immediate offset is not too large
959   if (Offset->isImm() && !Offset->isLoImm16Signed()) {
960     Error(Parser.getTok().getLoc(),
961           "Memory address is not word "
962           "aligned and larger than class RM can handle");
963     return MatchOperand_ParseFail;
964   }
965 
966   Operands.push_back(
967       Offset->isImm()
968           ? LanaiOperand::MorphToMemRegImm(BaseReg, std::move(Offset), AluOp)
969           : LanaiOperand::MorphToMemRegReg(BaseReg, std::move(Offset), AluOp));
970 
971   return MatchOperand_Success;
972 }
973 
974 // Looks at a token type and creates the relevant operand from this
975 // information, adding to operands.
976 // If operand was parsed, returns false, else true.
977 LanaiAsmParser::OperandMatchResultTy
parseOperand(OperandVector * Operands,StringRef Mnemonic)978 LanaiAsmParser::parseOperand(OperandVector *Operands, StringRef Mnemonic) {
979   // Check if the current operand has a custom associated parser, if so, try to
980   // custom parse the operand, or fallback to the general approach.
981   OperandMatchResultTy Result = MatchOperandParserImpl(*Operands, Mnemonic);
982 
983   if (Result == MatchOperand_Success)
984     return Result;
985   if (Result == MatchOperand_ParseFail) {
986     Parser.eatToEndOfStatement();
987     return Result;
988   }
989 
990   // Attempt to parse token as register
991   std::unique_ptr<LanaiOperand> Op = parseRegister();
992 
993   // Attempt to parse token as immediate
994   if (!Op)
995     Op = parseImmediate();
996 
997   // If the token could not be parsed then fail
998   if (!Op) {
999     Error(Parser.getTok().getLoc(), "Unknown operand");
1000     Parser.eatToEndOfStatement();
1001     return MatchOperand_ParseFail;
1002   }
1003 
1004   // Push back parsed operand into list of operands
1005   Operands->push_back(std::move(Op));
1006 
1007   return MatchOperand_Success;
1008 }
1009 
1010 // Split the mnemonic into ASM operand, conditional code and instruction
1011 // qualifier (half-word, byte).
splitMnemonic(StringRef Name,SMLoc NameLoc,OperandVector * Operands)1012 StringRef LanaiAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
1013                                         OperandVector *Operands) {
1014   size_t Next = Name.find('.');
1015 
1016   StringRef Mnemonic = Name;
1017 
1018   bool IsBRR = false;
1019   if (Name.endswith(".r")) {
1020     Mnemonic = Name.substr(0, Name.size() - 2);
1021     IsBRR = true;
1022   }
1023 
1024   // Match b?? and s?? (BR, BRR, and SCC instruction classes).
1025   if (Mnemonic[0] == 'b' ||
1026       (Mnemonic[0] == 's' && !Mnemonic.startswith("sel") &&
1027        !Mnemonic.startswith("st"))) {
1028     // Parse instructions with a conditional code. For example, 'bne' is
1029     // converted into two operands 'b' and 'ne'.
1030     LPCC::CondCode CondCode =
1031         LPCC::suffixToLanaiCondCode(Mnemonic.substr(1, Next));
1032     if (CondCode != LPCC::UNKNOWN) {
1033       Mnemonic = Mnemonic.slice(0, 1);
1034       Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1035       Operands->push_back(LanaiOperand::createImm(
1036           MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1037       if (IsBRR) {
1038         Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1039       }
1040       return Mnemonic;
1041     }
1042   }
1043 
1044   // Parse other instructions with condition codes (RR instructions).
1045   // We ignore .f here and assume they are flag-setting operations, not
1046   // conditional codes (except for select instructions where flag-setting
1047   // variants are not yet implemented).
1048   if (Mnemonic.startswith("sel") ||
1049       (!Mnemonic.endswith(".f") && !Mnemonic.startswith("st"))) {
1050     LPCC::CondCode CondCode = LPCC::suffixToLanaiCondCode(Mnemonic);
1051     if (CondCode != LPCC::UNKNOWN) {
1052       size_t Next = Mnemonic.rfind('.', Name.size());
1053       // 'sel' doesn't use a predicate operand whose printer adds the period,
1054       // but instead has the period as part of the identifier (i.e., 'sel.' is
1055       // expected by the generated matcher). If the mnemonic starts with 'sel'
1056       // then include the period as part of the mnemonic, else don't include it
1057       // as part of the mnemonic.
1058       if (Mnemonic.startswith("sel")) {
1059         Mnemonic = Mnemonic.substr(0, Next + 1);
1060       } else {
1061         Mnemonic = Mnemonic.substr(0, Next);
1062       }
1063       Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1064       Operands->push_back(LanaiOperand::createImm(
1065           MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
1066       return Mnemonic;
1067     }
1068   }
1069 
1070   Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
1071   if (IsBRR) {
1072     Operands->push_back(LanaiOperand::CreateToken(".r", NameLoc));
1073   }
1074 
1075   return Mnemonic;
1076 }
1077 
IsMemoryAssignmentError(const OperandVector & Operands)1078 bool IsMemoryAssignmentError(const OperandVector &Operands) {
1079   // Detects if a memory operation has an erroneous base register modification.
1080   // Memory operations are detected by matching the types of operands.
1081   //
1082   // TODO: This test is focussed on one specific instance (ld/st).
1083   // Extend it to handle more cases or be more robust.
1084   bool Modifies = false;
1085 
1086   int Offset = 0;
1087 
1088   if (Operands.size() < 5)
1089     return false;
1090   else if (Operands[0]->isToken() && Operands[1]->isReg() &&
1091            Operands[2]->isImm() && Operands[3]->isImm() && Operands[4]->isReg())
1092     Offset = 0;
1093   else if (Operands[0]->isToken() && Operands[1]->isToken() &&
1094            Operands[2]->isReg() && Operands[3]->isImm() &&
1095            Operands[4]->isImm() && Operands[5]->isReg())
1096     Offset = 1;
1097   else
1098     return false;
1099 
1100   int PossibleAluOpIdx = Offset + 3;
1101   int PossibleBaseIdx = Offset + 1;
1102   int PossibleDestIdx = Offset + 4;
1103   if (LanaiOperand *PossibleAluOp =
1104           static_cast<LanaiOperand *>(Operands[PossibleAluOpIdx].get()))
1105     if (PossibleAluOp->isImm())
1106       if (const MCConstantExpr *ConstExpr =
1107               dyn_cast<MCConstantExpr>(PossibleAluOp->getImm()))
1108         Modifies = LPAC::modifiesOp(ConstExpr->getValue());
1109   return Modifies && Operands[PossibleBaseIdx]->isReg() &&
1110          Operands[PossibleDestIdx]->isReg() &&
1111          Operands[PossibleBaseIdx]->getReg() ==
1112              Operands[PossibleDestIdx]->getReg();
1113 }
1114 
IsRegister(const MCParsedAsmOperand & op)1115 static bool IsRegister(const MCParsedAsmOperand &op) {
1116   return static_cast<const LanaiOperand &>(op).isReg();
1117 }
1118 
MaybePredicatedInst(const OperandVector & Operands)1119 static bool MaybePredicatedInst(const OperandVector &Operands) {
1120   if (Operands.size() < 4 || !IsRegister(*Operands[1]) ||
1121       !IsRegister(*Operands[2]))
1122     return false;
1123   return StringSwitch<bool>(
1124              static_cast<const LanaiOperand &>(*Operands[0]).getToken())
1125       .StartsWith("addc", true)
1126       .StartsWith("add", true)
1127       .StartsWith("and", true)
1128       .StartsWith("sh", true)
1129       .StartsWith("subb", true)
1130       .StartsWith("sub", true)
1131       .StartsWith("or", true)
1132       .StartsWith("xor", true)
1133       .Default(false);
1134 }
1135 
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)1136 bool LanaiAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1137                                       StringRef Name, SMLoc NameLoc,
1138                                       OperandVector &Operands) {
1139   // First operand is token for instruction
1140   StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
1141 
1142   // If there are no more operands, then finish
1143   if (Lexer.is(AsmToken::EndOfStatement))
1144     return false;
1145 
1146   // Parse first operand
1147   if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1148     return true;
1149 
1150   // If it is a st instruction with one 1 operand then it is a "store true".
1151   // Transform <"st"> to <"s">, <LPCC:ICC_T>
1152   if (Lexer.is(AsmToken::EndOfStatement) && Name == "st" &&
1153       Operands.size() == 2) {
1154     Operands.erase(Operands.begin(), Operands.begin() + 1);
1155     Operands.insert(Operands.begin(), LanaiOperand::CreateToken("s", NameLoc));
1156     Operands.insert(Operands.begin() + 1,
1157                     LanaiOperand::createImm(
1158                         MCConstantExpr::create(LPCC::ICC_T, getContext()),
1159                         NameLoc, NameLoc));
1160   }
1161 
1162   // If the instruction is a bt instruction with 1 operand (in assembly) then it
1163   // is an unconditional branch instruction and the first two elements of
1164   // operands need to be merged.
1165   if (Lexer.is(AsmToken::EndOfStatement) && Name.startswith("bt") &&
1166       Operands.size() == 3) {
1167     Operands.erase(Operands.begin(), Operands.begin() + 2);
1168     Operands.insert(Operands.begin(), LanaiOperand::CreateToken("bt", NameLoc));
1169   }
1170 
1171   // Parse until end of statement, consuming commas between operands
1172   while (Lexer.isNot(AsmToken::EndOfStatement) && Lexer.is(AsmToken::Comma)) {
1173     // Consume comma token
1174     Lex();
1175 
1176     // Parse next operand
1177     if (parseOperand(&Operands, Mnemonic) != MatchOperand_Success)
1178       return true;
1179   }
1180 
1181   if (IsMemoryAssignmentError(Operands)) {
1182     Error(Parser.getTok().getLoc(),
1183           "the destination register can't equal the base register in an "
1184           "instruction that modifies the base register.");
1185     return true;
1186   }
1187 
1188   // Insert always true operand for instruction that may be predicated but
1189   // are not. Currently the autogenerated parser always expects a predicate.
1190   if (MaybePredicatedInst(Operands)) {
1191     Operands.insert(Operands.begin() + 1,
1192                     LanaiOperand::createImm(
1193                         MCConstantExpr::create(LPCC::ICC_T, getContext()),
1194                         NameLoc, NameLoc));
1195   }
1196 
1197   return false;
1198 }
1199 
1200 #define GET_REGISTER_MATCHER
1201 #define GET_MATCHER_IMPLEMENTATION
1202 #include "LanaiGenAsmMatcher.inc"
1203 } // namespace
1204 
LLVMInitializeLanaiAsmParser()1205 extern "C" void LLVMInitializeLanaiAsmParser() {
1206   RegisterMCAsmParser<LanaiAsmParser> x(TheLanaiTarget);
1207 }
1208 
1209 } // namespace llvm
1210