xref: /freebsd/contrib/llvm-project/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- VEAsmParser.cpp - Parse VE assembly to MCInst instructions --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "MCTargetDesc/VEMCAsmInfo.h"
10 #include "MCTargetDesc/VEMCTargetDesc.h"
11 #include "TargetInfo/VETargetInfo.h"
12 #include "VE.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCParser/AsmLexer.h"
21 #include "llvm/MC/MCParser/MCAsmParser.h"
22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/TargetRegistry.h"
28 #include "llvm/Support/Compiler.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <memory>
31 
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "ve-asmparser"
35 
36 namespace {
37 
38 class VEOperand;
39 
40 class VEAsmParser : public MCTargetAsmParser {
41   MCAsmParser &Parser;
42 
43   /// @name Auto-generated Match Functions
44   /// {
45 
46 #define GET_ASSEMBLER_HEADER
47 #include "VEGenAsmMatcher.inc"
48 
49   /// }
50 
51   // public interface of the MCTargetAsmParser.
52   bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
53                                OperandVector &Operands, MCStreamer &Out,
54                                uint64_t &ErrorInfo,
55                                bool MatchingInlineAsm) override;
56   bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
57   int parseRegisterName(MCRegister (*matchFn)(StringRef));
58   ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
59                                SMLoc &EndLoc) override;
60   bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
61                         SMLoc NameLoc, OperandVector &Operands) override;
62   ParseStatus parseDirective(AsmToken DirectiveID) override;
63 
64   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
65                                       unsigned Kind) override;
66 
67   // Custom parse functions for VE specific operands.
68   ParseStatus parseMEMOperand(OperandVector &Operands);
69   ParseStatus parseMEMAsOperand(OperandVector &Operands);
70   ParseStatus parseCCOpOperand(OperandVector &Operands);
71   ParseStatus parseRDOpOperand(OperandVector &Operands);
72   ParseStatus parseMImmOperand(OperandVector &Operands);
73   ParseStatus parseOperand(OperandVector &Operands, StringRef Name);
74   ParseStatus parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand);
75 
76   // Helper function to parse expression with a symbol.
77   const MCExpr *extractSpecifier(const MCExpr *E, VE::Specifier &Variant);
78   bool parseExpression(const MCExpr *&EVal);
79 
80   // Split the mnemonic stripping conditional code and quantifiers
81   StringRef splitMnemonic(StringRef Name, SMLoc NameLoc,
82                           OperandVector *Operands);
83 
84   bool parseLiteralValues(unsigned Size, SMLoc L);
85 
86 public:
VEAsmParser(const MCSubtargetInfo & sti,MCAsmParser & parser,const MCInstrInfo & MII,const MCTargetOptions & Options)87   VEAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
88               const MCInstrInfo &MII, const MCTargetOptions &Options)
89       : MCTargetAsmParser(Options, sti, MII), Parser(parser) {
90     // Initialize the set of available features.
91     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
92   }
93 };
94 
95 } // end anonymous namespace
96 
97 static const MCPhysReg I32Regs[64] = {
98     VE::SW0,  VE::SW1,  VE::SW2,  VE::SW3,  VE::SW4,  VE::SW5,  VE::SW6,
99     VE::SW7,  VE::SW8,  VE::SW9,  VE::SW10, VE::SW11, VE::SW12, VE::SW13,
100     VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20,
101     VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27,
102     VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34,
103     VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41,
104     VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48,
105     VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55,
106     VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62,
107     VE::SW63};
108 
109 static const MCPhysReg F32Regs[64] = {
110     VE::SF0,  VE::SF1,  VE::SF2,  VE::SF3,  VE::SF4,  VE::SF5,  VE::SF6,
111     VE::SF7,  VE::SF8,  VE::SF9,  VE::SF10, VE::SF11, VE::SF12, VE::SF13,
112     VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20,
113     VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27,
114     VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34,
115     VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41,
116     VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48,
117     VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55,
118     VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62,
119     VE::SF63};
120 
121 static const MCPhysReg F128Regs[32] = {
122     VE::Q0,  VE::Q1,  VE::Q2,  VE::Q3,  VE::Q4,  VE::Q5,  VE::Q6,  VE::Q7,
123     VE::Q8,  VE::Q9,  VE::Q10, VE::Q11, VE::Q12, VE::Q13, VE::Q14, VE::Q15,
124     VE::Q16, VE::Q17, VE::Q18, VE::Q19, VE::Q20, VE::Q21, VE::Q22, VE::Q23,
125     VE::Q24, VE::Q25, VE::Q26, VE::Q27, VE::Q28, VE::Q29, VE::Q30, VE::Q31};
126 
127 static const MCPhysReg VM512Regs[8] = {VE::VMP0, VE::VMP1, VE::VMP2, VE::VMP3,
128                                        VE::VMP4, VE::VMP5, VE::VMP6, VE::VMP7};
129 
130 static const MCPhysReg MISCRegs[31] = {
131     VE::USRCC,      VE::PSW,        VE::SAR,        VE::NoRegister,
132     VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::PMMR,
133     VE::PMCR0,      VE::PMCR1,      VE::PMCR2,      VE::PMCR3,
134     VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::NoRegister,
135     VE::PMC0,       VE::PMC1,       VE::PMC2,       VE::PMC3,
136     VE::PMC4,       VE::PMC5,       VE::PMC6,       VE::PMC7,
137     VE::PMC8,       VE::PMC9,       VE::PMC10,      VE::PMC11,
138     VE::PMC12,      VE::PMC13,      VE::PMC14};
139 
140 namespace {
141 
142 /// VEOperand - Instances of this class represent a parsed VE machine
143 /// instruction.
144 class VEOperand : public MCParsedAsmOperand {
145 private:
146   enum KindTy {
147     k_Token,
148     k_Register,
149     k_Immediate,
150     // SX-Aurora ASX form is disp(index, base).
151     k_MemoryRegRegImm,  // base=reg, index=reg, disp=imm
152     k_MemoryRegImmImm,  // base=reg, index=imm, disp=imm
153     k_MemoryZeroRegImm, // base=0, index=reg, disp=imm
154     k_MemoryZeroImmImm, // base=0, index=imm, disp=imm
155     // SX-Aurora AS form is disp(base).
156     k_MemoryRegImm,  // base=reg, disp=imm
157     k_MemoryZeroImm, // base=0, disp=imm
158     // Other special cases for Aurora VE
159     k_CCOp,   // condition code
160     k_RDOp,   // rounding mode
161     k_MImmOp, // Special immediate value of sequential bit stream of 0 or 1.
162   } Kind;
163 
164   SMLoc StartLoc, EndLoc;
165 
166   struct Token {
167     const char *Data;
168     unsigned Length;
169   };
170 
171   struct RegOp {
172     unsigned RegNum;
173   };
174 
175   struct ImmOp {
176     const MCExpr *Val;
177   };
178 
179   struct MemOp {
180     unsigned Base;
181     unsigned IndexReg;
182     const MCExpr *Index;
183     const MCExpr *Offset;
184   };
185 
186   struct CCOp {
187     unsigned CCVal;
188   };
189 
190   struct RDOp {
191     unsigned RDVal;
192   };
193 
194   struct MImmOp {
195     const MCExpr *Val;
196     bool M0Flag;
197   };
198 
199   union {
200     struct Token Tok;
201     struct RegOp Reg;
202     struct ImmOp Imm;
203     struct MemOp Mem;
204     struct CCOp CC;
205     struct RDOp RD;
206     struct MImmOp MImm;
207   };
208 
209 public:
VEOperand(KindTy K)210   VEOperand(KindTy K) : Kind(K) {}
211 
isToken() const212   bool isToken() const override { return Kind == k_Token; }
isReg() const213   bool isReg() const override { return Kind == k_Register; }
isImm() const214   bool isImm() const override { return Kind == k_Immediate; }
isMem() const215   bool isMem() const override {
216     return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() ||
217            isMEMzi();
218   }
isMEMrri() const219   bool isMEMrri() const { return Kind == k_MemoryRegRegImm; }
isMEMrii() const220   bool isMEMrii() const { return Kind == k_MemoryRegImmImm; }
isMEMzri() const221   bool isMEMzri() const { return Kind == k_MemoryZeroRegImm; }
isMEMzii() const222   bool isMEMzii() const { return Kind == k_MemoryZeroImmImm; }
isMEMri() const223   bool isMEMri() const { return Kind == k_MemoryRegImm; }
isMEMzi() const224   bool isMEMzi() const { return Kind == k_MemoryZeroImm; }
isCCOp() const225   bool isCCOp() const { return Kind == k_CCOp; }
isRDOp() const226   bool isRDOp() const { return Kind == k_RDOp; }
isZero()227   bool isZero() {
228     if (!isImm())
229       return false;
230 
231     // Constant case
232     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
233       int64_t Value = ConstExpr->getValue();
234       return Value == 0;
235     }
236     return false;
237   }
isUImm0to2()238   bool isUImm0to2() {
239     if (!isImm())
240       return false;
241 
242     // Constant case
243     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
244       int64_t Value = ConstExpr->getValue();
245       return Value >= 0 && Value < 3;
246     }
247     return false;
248   }
isUImm1()249   bool isUImm1() {
250     if (!isImm())
251       return false;
252 
253     // Constant case
254     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
255       int64_t Value = ConstExpr->getValue();
256       return isUInt<1>(Value);
257     }
258     return false;
259   }
isUImm2()260   bool isUImm2() {
261     if (!isImm())
262       return false;
263 
264     // Constant case
265     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
266       int64_t Value = ConstExpr->getValue();
267       return isUInt<2>(Value);
268     }
269     return false;
270   }
isUImm3()271   bool isUImm3() {
272     if (!isImm())
273       return false;
274 
275     // Constant case
276     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
277       int64_t Value = ConstExpr->getValue();
278       return isUInt<3>(Value);
279     }
280     return false;
281   }
isUImm4()282   bool isUImm4() {
283     if (!isImm())
284       return false;
285 
286     // Constant case
287     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
288       int64_t Value = ConstExpr->getValue();
289       return isUInt<4>(Value);
290     }
291     return false;
292   }
isUImm6()293   bool isUImm6() {
294     if (!isImm())
295       return false;
296 
297     // Constant case
298     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
299       int64_t Value = ConstExpr->getValue();
300       return isUInt<6>(Value);
301     }
302     return false;
303   }
isUImm7()304   bool isUImm7() {
305     if (!isImm())
306       return false;
307 
308     // Constant case
309     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
310       int64_t Value = ConstExpr->getValue();
311       return isUInt<7>(Value);
312     }
313     return false;
314   }
isSImm7()315   bool isSImm7() {
316     if (!isImm())
317       return false;
318 
319     // Constant case
320     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
321       int64_t Value = ConstExpr->getValue();
322       return isInt<7>(Value);
323     }
324     return false;
325   }
isMImm() const326   bool isMImm() const {
327     if (Kind != k_MImmOp)
328       return false;
329 
330     // Constant case
331     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(MImm.Val)) {
332       int64_t Value = ConstExpr->getValue();
333       return isUInt<6>(Value);
334     }
335     return false;
336   }
337 
getToken() const338   StringRef getToken() const {
339     assert(Kind == k_Token && "Invalid access!");
340     return StringRef(Tok.Data, Tok.Length);
341   }
342 
getReg() const343   MCRegister getReg() const override {
344     assert((Kind == k_Register) && "Invalid access!");
345     return Reg.RegNum;
346   }
347 
getImm() const348   const MCExpr *getImm() const {
349     assert((Kind == k_Immediate) && "Invalid access!");
350     return Imm.Val;
351   }
352 
getMemBase() const353   unsigned getMemBase() const {
354     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
355             Kind == k_MemoryRegImm) &&
356            "Invalid access!");
357     return Mem.Base;
358   }
359 
getMemIndexReg() const360   unsigned getMemIndexReg() const {
361     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) &&
362            "Invalid access!");
363     return Mem.IndexReg;
364   }
365 
getMemIndex() const366   const MCExpr *getMemIndex() const {
367     assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) &&
368            "Invalid access!");
369     return Mem.Index;
370   }
371 
getMemOffset() const372   const MCExpr *getMemOffset() const {
373     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
374             Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
375             Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
376            "Invalid access!");
377     return Mem.Offset;
378   }
379 
setMemOffset(const MCExpr * off)380   void setMemOffset(const MCExpr *off) {
381     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
382             Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
383             Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
384            "Invalid access!");
385     Mem.Offset = off;
386   }
387 
getCCVal() const388   unsigned getCCVal() const {
389     assert((Kind == k_CCOp) && "Invalid access!");
390     return CC.CCVal;
391   }
392 
getRDVal() const393   unsigned getRDVal() const {
394     assert((Kind == k_RDOp) && "Invalid access!");
395     return RD.RDVal;
396   }
397 
getMImmVal() const398   const MCExpr *getMImmVal() const {
399     assert((Kind == k_MImmOp) && "Invalid access!");
400     return MImm.Val;
401   }
getM0Flag() const402   bool getM0Flag() const {
403     assert((Kind == k_MImmOp) && "Invalid access!");
404     return MImm.M0Flag;
405   }
406 
407   /// getStartLoc - Get the location of the first token of this operand.
getStartLoc() const408   SMLoc getStartLoc() const override { return StartLoc; }
409   /// getEndLoc - Get the location of the last token of this operand.
getEndLoc() const410   SMLoc getEndLoc() const override { return EndLoc; }
411 
print(raw_ostream & OS,const MCAsmInfo & MAI) const412   void print(raw_ostream &OS, const MCAsmInfo &MAI) const override {
413     switch (Kind) {
414     case k_Token:
415       OS << "Token: " << getToken() << "\n";
416       break;
417     case k_Register:
418       OS << "Reg: #" << getReg() << "\n";
419       break;
420     case k_Immediate:
421       OS << "Imm: " << getImm() << "\n";
422       break;
423     case k_MemoryRegRegImm:
424       assert(getMemOffset() != nullptr);
425       OS << "Mem: #" << getMemBase() << "+#" << getMemIndexReg() << "+";
426       MAI.printExpr(OS, *getMemOffset());
427       OS << "\n";
428       break;
429     case k_MemoryRegImmImm:
430       assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
431       OS << "Mem: #" << getMemBase() << "+";
432       MAI.printExpr(OS, *getMemIndex());
433       OS << "+";
434       MAI.printExpr(OS, *getMemOffset());
435       OS << "\n";
436       break;
437     case k_MemoryZeroRegImm:
438       assert(getMemOffset() != nullptr);
439       OS << "Mem: 0+#" << getMemIndexReg() << "+";
440       MAI.printExpr(OS, *getMemOffset());
441       OS << "\n";
442       break;
443     case k_MemoryZeroImmImm:
444       assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
445       OS << "Mem: 0+";
446       MAI.printExpr(OS, *getMemIndex());
447       OS << "+";
448       MAI.printExpr(OS, *getMemOffset());
449       OS << "\n";
450       break;
451     case k_MemoryRegImm:
452       assert(getMemOffset() != nullptr);
453       OS << "Mem: #" << getMemBase() << "+";
454       MAI.printExpr(OS, *getMemOffset());
455       OS << "\n";
456       break;
457     case k_MemoryZeroImm:
458       assert(getMemOffset() != nullptr);
459       OS << "Mem: 0+";
460       MAI.printExpr(OS, *getMemOffset());
461       OS << "\n";
462       break;
463     case k_CCOp:
464       OS << "CCOp: " << getCCVal() << "\n";
465       break;
466     case k_RDOp:
467       OS << "RDOp: " << getRDVal() << "\n";
468       break;
469     case k_MImmOp:
470       OS << "MImm: (" << getMImmVal() << (getM0Flag() ? ")0" : ")1") << "\n";
471       break;
472     }
473   }
474 
addRegOperands(MCInst & Inst,unsigned N) const475   void addRegOperands(MCInst &Inst, unsigned N) const {
476     assert(N == 1 && "Invalid number of operands!");
477     Inst.addOperand(MCOperand::createReg(getReg()));
478   }
479 
addImmOperands(MCInst & Inst,unsigned N) const480   void addImmOperands(MCInst &Inst, unsigned N) const {
481     assert(N == 1 && "Invalid number of operands!");
482     const MCExpr *Expr = getImm();
483     addExpr(Inst, Expr);
484   }
485 
addZeroOperands(MCInst & Inst,unsigned N) const486   void addZeroOperands(MCInst &Inst, unsigned N) const {
487     addImmOperands(Inst, N);
488   }
489 
addUImm0to2Operands(MCInst & Inst,unsigned N) const490   void addUImm0to2Operands(MCInst &Inst, unsigned N) const {
491     addImmOperands(Inst, N);
492   }
493 
addUImm1Operands(MCInst & Inst,unsigned N) const494   void addUImm1Operands(MCInst &Inst, unsigned N) const {
495     addImmOperands(Inst, N);
496   }
497 
addUImm2Operands(MCInst & Inst,unsigned N) const498   void addUImm2Operands(MCInst &Inst, unsigned N) const {
499     addImmOperands(Inst, N);
500   }
501 
addUImm3Operands(MCInst & Inst,unsigned N) const502   void addUImm3Operands(MCInst &Inst, unsigned N) const {
503     addImmOperands(Inst, N);
504   }
505 
addUImm4Operands(MCInst & Inst,unsigned N) const506   void addUImm4Operands(MCInst &Inst, unsigned N) const {
507     addImmOperands(Inst, N);
508   }
509 
addUImm6Operands(MCInst & Inst,unsigned N) const510   void addUImm6Operands(MCInst &Inst, unsigned N) const {
511     addImmOperands(Inst, N);
512   }
513 
addUImm7Operands(MCInst & Inst,unsigned N) const514   void addUImm7Operands(MCInst &Inst, unsigned N) const {
515     addImmOperands(Inst, N);
516   }
517 
addSImm7Operands(MCInst & Inst,unsigned N) const518   void addSImm7Operands(MCInst &Inst, unsigned N) const {
519     addImmOperands(Inst, N);
520   }
521 
addExpr(MCInst & Inst,const MCExpr * Expr) const522   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
523     // Add as immediate when possible.  Null MCExpr = 0.
524     if (!Expr)
525       Inst.addOperand(MCOperand::createImm(0));
526     else if (const auto *CE = dyn_cast<MCConstantExpr>(Expr))
527       Inst.addOperand(MCOperand::createImm(CE->getValue()));
528     else
529       Inst.addOperand(MCOperand::createExpr(Expr));
530   }
531 
addMEMrriOperands(MCInst & Inst,unsigned N) const532   void addMEMrriOperands(MCInst &Inst, unsigned N) const {
533     assert(N == 3 && "Invalid number of operands!");
534 
535     Inst.addOperand(MCOperand::createReg(getMemBase()));
536     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
537     addExpr(Inst, getMemOffset());
538   }
539 
addMEMriiOperands(MCInst & Inst,unsigned N) const540   void addMEMriiOperands(MCInst &Inst, unsigned N) const {
541     assert(N == 3 && "Invalid number of operands!");
542 
543     Inst.addOperand(MCOperand::createReg(getMemBase()));
544     addExpr(Inst, getMemIndex());
545     addExpr(Inst, getMemOffset());
546   }
547 
addMEMzriOperands(MCInst & Inst,unsigned N) const548   void addMEMzriOperands(MCInst &Inst, unsigned N) const {
549     assert(N == 3 && "Invalid number of operands!");
550 
551     Inst.addOperand(MCOperand::createImm(0));
552     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
553     addExpr(Inst, getMemOffset());
554   }
555 
addMEMziiOperands(MCInst & Inst,unsigned N) const556   void addMEMziiOperands(MCInst &Inst, unsigned N) const {
557     assert(N == 3 && "Invalid number of operands!");
558 
559     Inst.addOperand(MCOperand::createImm(0));
560     addExpr(Inst, getMemIndex());
561     addExpr(Inst, getMemOffset());
562   }
563 
addMEMriOperands(MCInst & Inst,unsigned N) const564   void addMEMriOperands(MCInst &Inst, unsigned N) const {
565     assert(N == 2 && "Invalid number of operands!");
566 
567     Inst.addOperand(MCOperand::createReg(getMemBase()));
568     addExpr(Inst, getMemOffset());
569   }
570 
addMEMziOperands(MCInst & Inst,unsigned N) const571   void addMEMziOperands(MCInst &Inst, unsigned N) const {
572     assert(N == 2 && "Invalid number of operands!");
573 
574     Inst.addOperand(MCOperand::createImm(0));
575     addExpr(Inst, getMemOffset());
576   }
577 
addCCOpOperands(MCInst & Inst,unsigned N) const578   void addCCOpOperands(MCInst &Inst, unsigned N) const {
579     assert(N == 1 && "Invalid number of operands!");
580 
581     Inst.addOperand(MCOperand::createImm(getCCVal()));
582   }
583 
addRDOpOperands(MCInst & Inst,unsigned N) const584   void addRDOpOperands(MCInst &Inst, unsigned N) const {
585     assert(N == 1 && "Invalid number of operands!");
586 
587     Inst.addOperand(MCOperand::createImm(getRDVal()));
588   }
589 
addMImmOperands(MCInst & Inst,unsigned N) const590   void addMImmOperands(MCInst &Inst, unsigned N) const {
591     assert(N == 1 && "Invalid number of operands!");
592     const auto *ConstExpr = dyn_cast<MCConstantExpr>(getMImmVal());
593     assert(ConstExpr && "Null operands!");
594     int64_t Value = ConstExpr->getValue();
595     if (getM0Flag())
596       Value += 64;
597     Inst.addOperand(MCOperand::createImm(Value));
598   }
599 
CreateToken(StringRef Str,SMLoc S)600   static std::unique_ptr<VEOperand> CreateToken(StringRef Str, SMLoc S) {
601     auto Op = std::make_unique<VEOperand>(k_Token);
602     Op->Tok.Data = Str.data();
603     Op->Tok.Length = Str.size();
604     Op->StartLoc = S;
605     Op->EndLoc = S;
606     return Op;
607   }
608 
CreateReg(unsigned RegNum,SMLoc S,SMLoc E)609   static std::unique_ptr<VEOperand> CreateReg(unsigned RegNum, SMLoc S,
610                                               SMLoc E) {
611     auto Op = std::make_unique<VEOperand>(k_Register);
612     Op->Reg.RegNum = RegNum;
613     Op->StartLoc = S;
614     Op->EndLoc = E;
615     return Op;
616   }
617 
CreateImm(const MCExpr * Val,SMLoc S,SMLoc E)618   static std::unique_ptr<VEOperand> CreateImm(const MCExpr *Val, SMLoc S,
619                                               SMLoc E) {
620     auto Op = std::make_unique<VEOperand>(k_Immediate);
621     Op->Imm.Val = Val;
622     Op->StartLoc = S;
623     Op->EndLoc = E;
624     return Op;
625   }
626 
CreateCCOp(unsigned CCVal,SMLoc S,SMLoc E)627   static std::unique_ptr<VEOperand> CreateCCOp(unsigned CCVal, SMLoc S,
628                                                SMLoc E) {
629     auto Op = std::make_unique<VEOperand>(k_CCOp);
630     Op->CC.CCVal = CCVal;
631     Op->StartLoc = S;
632     Op->EndLoc = E;
633     return Op;
634   }
635 
CreateRDOp(unsigned RDVal,SMLoc S,SMLoc E)636   static std::unique_ptr<VEOperand> CreateRDOp(unsigned RDVal, SMLoc S,
637                                                SMLoc E) {
638     auto Op = std::make_unique<VEOperand>(k_RDOp);
639     Op->RD.RDVal = RDVal;
640     Op->StartLoc = S;
641     Op->EndLoc = E;
642     return Op;
643   }
644 
CreateMImm(const MCExpr * Val,bool Flag,SMLoc S,SMLoc E)645   static std::unique_ptr<VEOperand> CreateMImm(const MCExpr *Val, bool Flag,
646                                                SMLoc S, SMLoc E) {
647     auto Op = std::make_unique<VEOperand>(k_MImmOp);
648     Op->MImm.Val = Val;
649     Op->MImm.M0Flag = Flag;
650     Op->StartLoc = S;
651     Op->EndLoc = E;
652     return Op;
653   }
654 
MorphToI32Reg(VEOperand & Op)655   static bool MorphToI32Reg(VEOperand &Op) {
656     unsigned Reg = Op.getReg();
657     unsigned regIdx = Reg - VE::SX0;
658     if (regIdx > 63)
659       return false;
660     Op.Reg.RegNum = I32Regs[regIdx];
661     return true;
662   }
663 
MorphToF32Reg(VEOperand & Op)664   static bool MorphToF32Reg(VEOperand &Op) {
665     unsigned Reg = Op.getReg();
666     unsigned regIdx = Reg - VE::SX0;
667     if (regIdx > 63)
668       return false;
669     Op.Reg.RegNum = F32Regs[regIdx];
670     return true;
671   }
672 
MorphToF128Reg(VEOperand & Op)673   static bool MorphToF128Reg(VEOperand &Op) {
674     unsigned Reg = Op.getReg();
675     unsigned regIdx = Reg - VE::SX0;
676     if (regIdx % 2 || regIdx > 63)
677       return false;
678     Op.Reg.RegNum = F128Regs[regIdx / 2];
679     return true;
680   }
681 
MorphToVM512Reg(VEOperand & Op)682   static bool MorphToVM512Reg(VEOperand &Op) {
683     unsigned Reg = Op.getReg();
684     unsigned regIdx = Reg - VE::VM0;
685     if (regIdx % 2 || regIdx > 15)
686       return false;
687     Op.Reg.RegNum = VM512Regs[regIdx / 2];
688     return true;
689   }
690 
MorphToMISCReg(VEOperand & Op)691   static bool MorphToMISCReg(VEOperand &Op) {
692     const auto *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm());
693     if (!ConstExpr)
694       return false;
695     unsigned regIdx = ConstExpr->getValue();
696     if (regIdx > 31 || MISCRegs[regIdx] == VE::NoRegister)
697       return false;
698     Op.Kind = k_Register;
699     Op.Reg.RegNum = MISCRegs[regIdx];
700     return true;
701   }
702 
703   static std::unique_ptr<VEOperand>
MorphToMEMri(unsigned Base,std::unique_ptr<VEOperand> Op)704   MorphToMEMri(unsigned Base, std::unique_ptr<VEOperand> Op) {
705     const MCExpr *Imm = Op->getImm();
706     Op->Kind = k_MemoryRegImm;
707     Op->Mem.Base = Base;
708     Op->Mem.IndexReg = 0;
709     Op->Mem.Index = nullptr;
710     Op->Mem.Offset = Imm;
711     return Op;
712   }
713 
714   static std::unique_ptr<VEOperand>
MorphToMEMzi(std::unique_ptr<VEOperand> Op)715   MorphToMEMzi(std::unique_ptr<VEOperand> Op) {
716     const MCExpr *Imm = Op->getImm();
717     Op->Kind = k_MemoryZeroImm;
718     Op->Mem.Base = 0;
719     Op->Mem.IndexReg = 0;
720     Op->Mem.Index = nullptr;
721     Op->Mem.Offset = Imm;
722     return Op;
723   }
724 
725   static std::unique_ptr<VEOperand>
MorphToMEMrri(unsigned Base,unsigned Index,std::unique_ptr<VEOperand> Op)726   MorphToMEMrri(unsigned Base, unsigned Index, std::unique_ptr<VEOperand> Op) {
727     const MCExpr *Imm = Op->getImm();
728     Op->Kind = k_MemoryRegRegImm;
729     Op->Mem.Base = Base;
730     Op->Mem.IndexReg = Index;
731     Op->Mem.Index = nullptr;
732     Op->Mem.Offset = Imm;
733     return Op;
734   }
735 
736   static std::unique_ptr<VEOperand>
MorphToMEMrii(unsigned Base,const MCExpr * Index,std::unique_ptr<VEOperand> Op)737   MorphToMEMrii(unsigned Base, const MCExpr *Index,
738                 std::unique_ptr<VEOperand> Op) {
739     const MCExpr *Imm = Op->getImm();
740     Op->Kind = k_MemoryRegImmImm;
741     Op->Mem.Base = Base;
742     Op->Mem.IndexReg = 0;
743     Op->Mem.Index = Index;
744     Op->Mem.Offset = Imm;
745     return Op;
746   }
747 
748   static std::unique_ptr<VEOperand>
MorphToMEMzri(unsigned Index,std::unique_ptr<VEOperand> Op)749   MorphToMEMzri(unsigned Index, std::unique_ptr<VEOperand> Op) {
750     const MCExpr *Imm = Op->getImm();
751     Op->Kind = k_MemoryZeroRegImm;
752     Op->Mem.Base = 0;
753     Op->Mem.IndexReg = Index;
754     Op->Mem.Index = nullptr;
755     Op->Mem.Offset = Imm;
756     return Op;
757   }
758 
759   static std::unique_ptr<VEOperand>
MorphToMEMzii(const MCExpr * Index,std::unique_ptr<VEOperand> Op)760   MorphToMEMzii(const MCExpr *Index, std::unique_ptr<VEOperand> Op) {
761     const MCExpr *Imm = Op->getImm();
762     Op->Kind = k_MemoryZeroImmImm;
763     Op->Mem.Base = 0;
764     Op->Mem.IndexReg = 0;
765     Op->Mem.Index = Index;
766     Op->Mem.Offset = Imm;
767     return Op;
768   }
769 };
770 
771 } // end anonymous namespace
772 
matchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)773 bool VEAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
774                                           OperandVector &Operands,
775                                           MCStreamer &Out, uint64_t &ErrorInfo,
776                                           bool MatchingInlineAsm) {
777   MCInst Inst;
778   unsigned MatchResult =
779       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
780   switch (MatchResult) {
781   case Match_Success:
782     Inst.setLoc(IDLoc);
783     Out.emitInstruction(Inst, getSTI());
784     return false;
785 
786   case Match_MissingFeature:
787     return Error(IDLoc,
788                  "instruction requires a CPU feature not currently enabled");
789 
790   case Match_InvalidOperand: {
791     SMLoc ErrorLoc = IDLoc;
792     if (ErrorInfo != ~0ULL) {
793       if (ErrorInfo >= Operands.size())
794         return Error(IDLoc, "too few operands for instruction");
795 
796       ErrorLoc = ((VEOperand &)*Operands[ErrorInfo]).getStartLoc();
797       if (ErrorLoc == SMLoc())
798         ErrorLoc = IDLoc;
799     }
800 
801     return Error(ErrorLoc, "invalid operand for instruction");
802   }
803   case Match_MnemonicFail:
804     return Error(IDLoc, "invalid instruction mnemonic");
805   }
806   llvm_unreachable("Implement any new match types added!");
807 }
808 
parseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)809 bool VEAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
810                                 SMLoc &EndLoc) {
811   if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
812     return Error(StartLoc, "invalid register name");
813   return false;
814 }
815 
816 /// Parses a register name using a given matching function.
817 /// Checks for lowercase or uppercase if necessary.
parseRegisterName(MCRegister (* matchFn)(StringRef))818 int VEAsmParser::parseRegisterName(MCRegister (*matchFn)(StringRef)) {
819   StringRef Name = Parser.getTok().getString();
820 
821   int RegNum = matchFn(Name);
822 
823   // GCC supports case insensitive register names. All of the VE registers
824   // are all lower case.
825   if (RegNum == VE::NoRegister) {
826     RegNum = matchFn(Name.lower());
827   }
828 
829   return RegNum;
830 }
831 
832 /// Maps from the set of all register names to a register number.
833 /// \note Generated by TableGen.
834 static MCRegister MatchRegisterName(StringRef Name);
835 
836 /// Maps from the set of all alternative registernames to a register number.
837 /// \note Generated by TableGen.
838 static MCRegister MatchRegisterAltName(StringRef Name);
839 
tryParseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)840 ParseStatus VEAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
841                                           SMLoc &EndLoc) {
842   const AsmToken Tok = Parser.getTok();
843   StartLoc = Tok.getLoc();
844   EndLoc = Tok.getEndLoc();
845   Reg = VE::NoRegister;
846   if (getLexer().getKind() != AsmToken::Percent)
847     return ParseStatus::NoMatch;
848   Parser.Lex();
849 
850   Reg = parseRegisterName(&MatchRegisterName);
851   if (Reg == VE::NoRegister)
852     Reg = parseRegisterName(&MatchRegisterAltName);
853 
854   if (Reg != VE::NoRegister) {
855     Parser.Lex();
856     return ParseStatus::Success;
857   }
858 
859   getLexer().UnLex(Tok);
860   return ParseStatus::NoMatch;
861 }
862 
parseCC(StringRef Name,unsigned Prefix,unsigned Suffix,bool IntegerCC,bool OmitCC,SMLoc NameLoc,OperandVector * Operands)863 static StringRef parseCC(StringRef Name, unsigned Prefix, unsigned Suffix,
864                          bool IntegerCC, bool OmitCC, SMLoc NameLoc,
865                          OperandVector *Operands) {
866   // Parse instructions with a conditional code. For example, 'bne' is
867   // converted into two operands 'b' and 'ne'.
868   StringRef Cond = Name.slice(Prefix, Suffix);
869   VECC::CondCode CondCode =
870       IntegerCC ? stringToVEICondCode(Cond) : stringToVEFCondCode(Cond);
871 
872   // If OmitCC is enabled, CC_AT and CC_AF is treated as a part of mnemonic.
873   if (CondCode != VECC::UNKNOWN &&
874       (!OmitCC || (CondCode != VECC::CC_AT && CondCode != VECC::CC_AF))) {
875     StringRef SuffixStr = Name.substr(Suffix);
876     // Push "b".
877     Name = Name.slice(0, Prefix);
878     Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
879     // Push $cond part.
880     SMLoc CondLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Prefix);
881     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Suffix);
882     Operands->push_back(VEOperand::CreateCCOp(CondCode, CondLoc, SuffixLoc));
883     // push suffix like ".l.t"
884     if (!SuffixStr.empty())
885       Operands->push_back(VEOperand::CreateToken(SuffixStr, SuffixLoc));
886   } else {
887     Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
888   }
889   return Name;
890 }
891 
parseRD(StringRef Name,unsigned Prefix,SMLoc NameLoc,OperandVector * Operands)892 static StringRef parseRD(StringRef Name, unsigned Prefix, SMLoc NameLoc,
893                          OperandVector *Operands) {
894   // Parse instructions with a conditional code. For example, 'cvt.w.d.sx.rz'
895   // is converted into two operands 'cvt.w.d.sx' and '.rz'.
896   StringRef RD = Name.substr(Prefix);
897   VERD::RoundingMode RoundingMode = stringToVERD(RD);
898 
899   if (RoundingMode != VERD::UNKNOWN) {
900     Name = Name.slice(0, Prefix);
901     // push 1st like `cvt.w.d.sx`
902     Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
903     SMLoc SuffixLoc =
904         SMLoc::getFromPointer(NameLoc.getPointer() + (RD.data() - Name.data()));
905     SMLoc SuffixEnd =
906         SMLoc::getFromPointer(NameLoc.getPointer() + (RD.end() - Name.data()));
907     // push $round if it has rounding mode
908     Operands->push_back(
909         VEOperand::CreateRDOp(RoundingMode, SuffixLoc, SuffixEnd));
910   } else {
911     Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
912   }
913   return Name;
914 }
915 
916 // Split the mnemonic into ASM operand, conditional code and instruction
917 // qualifier (half-word, byte).
splitMnemonic(StringRef Name,SMLoc NameLoc,OperandVector * Operands)918 StringRef VEAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
919                                      OperandVector *Operands) {
920   // Create the leading tokens for the mnemonic
921   StringRef Mnemonic = Name;
922 
923   if (Name[0] == 'b') {
924     // Match b?? or br??.
925     size_t Start = 1;
926     size_t Next = Name.find('.');
927     // Adjust position of CondCode.
928     if (Name.size() > 1 && Name[1] == 'r')
929       Start = 2;
930     // Check suffix.
931     bool ICC = true;
932     if (Next + 1 < Name.size() &&
933         (Name[Next + 1] == 'd' || Name[Next + 1] == 's'))
934       ICC = false;
935     Mnemonic = parseCC(Name, Start, Next, ICC, true, NameLoc, Operands);
936   } else if (Name.starts_with("cmov.l.") || Name.starts_with("cmov.w.") ||
937              Name.starts_with("cmov.d.") || Name.starts_with("cmov.s.")) {
938     bool ICC = Name[5] == 'l' || Name[5] == 'w';
939     Mnemonic = parseCC(Name, 7, Name.size(), ICC, false, NameLoc, Operands);
940   } else if (Name.starts_with("cvt.w.d.sx") || Name.starts_with("cvt.w.d.zx") ||
941              Name.starts_with("cvt.w.s.sx") || Name.starts_with("cvt.w.s.zx")) {
942     Mnemonic = parseRD(Name, 10, NameLoc, Operands);
943   } else if (Name.starts_with("cvt.l.d")) {
944     Mnemonic = parseRD(Name, 7, NameLoc, Operands);
945   } else if (Name.starts_with("vcvt.w.d.sx") ||
946              Name.starts_with("vcvt.w.d.zx") ||
947              Name.starts_with("vcvt.w.s.sx") ||
948              Name.starts_with("vcvt.w.s.zx")) {
949     Mnemonic = parseRD(Name, 11, NameLoc, Operands);
950   } else if (Name.starts_with("vcvt.l.d")) {
951     Mnemonic = parseRD(Name, 8, NameLoc, Operands);
952   } else if (Name.starts_with("pvcvt.w.s.lo") ||
953              Name.starts_with("pvcvt.w.s.up")) {
954     Mnemonic = parseRD(Name, 12, NameLoc, Operands);
955   } else if (Name.starts_with("pvcvt.w.s")) {
956     Mnemonic = parseRD(Name, 9, NameLoc, Operands);
957   } else if (Name.starts_with("vfmk.l.") || Name.starts_with("vfmk.w.") ||
958              Name.starts_with("vfmk.d.") || Name.starts_with("vfmk.s.")) {
959     bool ICC = Name[5] == 'l' || Name[5] == 'w' ? true : false;
960     Mnemonic = parseCC(Name, 7, Name.size(), ICC, true, NameLoc, Operands);
961   } else if (Name.starts_with("pvfmk.w.lo.") ||
962              Name.starts_with("pvfmk.w.up.") ||
963              Name.starts_with("pvfmk.s.lo.") ||
964              Name.starts_with("pvfmk.s.up.")) {
965     bool ICC = Name[6] == 'l' || Name[6] == 'w' ? true : false;
966     Mnemonic = parseCC(Name, 11, Name.size(), ICC, true, NameLoc, Operands);
967   } else {
968     Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc));
969   }
970 
971   return Mnemonic;
972 }
973 
974 static void applyMnemonicAliases(StringRef &Mnemonic,
975                                  const FeatureBitset &Features,
976                                  unsigned VariantID);
977 
parseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)978 bool VEAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
979                                    SMLoc NameLoc, OperandVector &Operands) {
980   // If the target architecture uses MnemonicAlias, call it here to parse
981   // operands correctly.
982   applyMnemonicAliases(Name, getAvailableFeatures(), 0);
983 
984   // Split name to first token and the rest, e.g. "bgt.l.t" to "b", "gt", and
985   // ".l.t".  We treat "b" as a mnemonic, "gt" as first operand, and ".l.t"
986   // as second operand.
987   StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
988 
989   if (getLexer().isNot(AsmToken::EndOfStatement)) {
990     // Read the first operand.
991     if (!parseOperand(Operands, Mnemonic).isSuccess()) {
992       SMLoc Loc = getLexer().getLoc();
993       return Error(Loc, "unexpected token");
994     }
995 
996     while (getLexer().is(AsmToken::Comma)) {
997       Parser.Lex(); // Eat the comma.
998       // Parse and remember the operand.
999       if (!parseOperand(Operands, Mnemonic).isSuccess()) {
1000         SMLoc Loc = getLexer().getLoc();
1001         return Error(Loc, "unexpected token");
1002       }
1003     }
1004   }
1005   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1006     SMLoc Loc = getLexer().getLoc();
1007     return Error(Loc, "unexpected token");
1008   }
1009   Parser.Lex(); // Consume the EndOfStatement.
1010   return false;
1011 }
1012 
parseDirective(AsmToken DirectiveID)1013 ParseStatus VEAsmParser::parseDirective(AsmToken DirectiveID) {
1014   std::string IDVal = DirectiveID.getIdentifier().lower();
1015 
1016   // Defines VE specific directives.  Reference is "Vector Engine Assembly
1017   // Language Reference Manual":
1018   // https://www.hpc.nec/documents/sdk/pdfs/VectorEngine-as-manual-v1.3.pdf
1019 
1020   // The .word is 4 bytes long on VE.
1021   if (IDVal == ".word")
1022     return parseLiteralValues(4, DirectiveID.getLoc());
1023 
1024   // The .long is 8 bytes long on VE.
1025   if (IDVal == ".long")
1026     return parseLiteralValues(8, DirectiveID.getLoc());
1027 
1028   // The .llong is 8 bytes long on VE.
1029   if (IDVal == ".llong")
1030     return parseLiteralValues(8, DirectiveID.getLoc());
1031 
1032   // Let the MC layer to handle other directives.
1033   return ParseStatus::NoMatch;
1034 }
1035 
1036 /// parseLiteralValues
1037 ///  ::= .word expression [, expression]*
1038 ///  ::= .long expression [, expression]*
1039 ///  ::= .llong expression [, expression]*
parseLiteralValues(unsigned Size,SMLoc L)1040 bool VEAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
1041   auto parseOne = [&]() -> bool {
1042     const MCExpr *Value;
1043     if (getParser().parseExpression(Value))
1044       return true;
1045     getParser().getStreamer().emitValue(Value, Size, L);
1046     return false;
1047   };
1048   return (parseMany(parseOne));
1049 }
1050 
1051 /// Extract \code @lo32/@hi32/etc \endcode specifier from expression.
1052 /// Recursively scan the expression and check for VK_HI32/LO32/etc
1053 /// symbol variants.  If all symbols with modifier use the same
1054 /// variant, return the corresponding VE::Specifier,
1055 /// and a modified expression using the default symbol variant.
1056 /// Otherwise, return NULL.
extractSpecifier(const MCExpr * E,VE::Specifier & Variant)1057 const MCExpr *VEAsmParser::extractSpecifier(const MCExpr *E,
1058                                             VE::Specifier &Variant) {
1059   MCContext &Context = getParser().getContext();
1060   Variant = VE::S_None;
1061 
1062   switch (E->getKind()) {
1063   case MCExpr::Target:
1064   case MCExpr::Constant:
1065     return nullptr;
1066   case MCExpr::Specifier:
1067     llvm_unreachable("unused by this backend");
1068 
1069   case MCExpr::SymbolRef: {
1070     const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1071 
1072     switch (SRE->getSpecifier()) {
1073     case VE::S_None:
1074       // Use VK_REFLONG to a symbol without modifiers.
1075       Variant = VE::S_REFLONG;
1076       break;
1077     case VE::S_HI32:
1078       Variant = VE::S_HI32;
1079       break;
1080     case VE::S_LO32:
1081       Variant = VE::S_LO32;
1082       break;
1083     case VE::S_PC_HI32:
1084       Variant = VE::S_PC_HI32;
1085       break;
1086     case VE::S_PC_LO32:
1087       Variant = VE::S_PC_LO32;
1088       break;
1089     case VE::S_GOT_HI32:
1090       Variant = VE::S_GOT_HI32;
1091       break;
1092     case VE::S_GOT_LO32:
1093       Variant = VE::S_GOT_LO32;
1094       break;
1095     case VE::S_GOTOFF_HI32:
1096       Variant = VE::S_GOTOFF_HI32;
1097       break;
1098     case VE::S_GOTOFF_LO32:
1099       Variant = VE::S_GOTOFF_LO32;
1100       break;
1101     case VE::S_PLT_HI32:
1102       Variant = VE::S_PLT_HI32;
1103       break;
1104     case VE::S_PLT_LO32:
1105       Variant = VE::S_PLT_LO32;
1106       break;
1107     case VE::S_TLS_GD_HI32:
1108       Variant = VE::S_TLS_GD_HI32;
1109       break;
1110     case VE::S_TLS_GD_LO32:
1111       Variant = VE::S_TLS_GD_LO32;
1112       break;
1113     case VE::S_TPOFF_HI32:
1114       Variant = VE::S_TPOFF_HI32;
1115       break;
1116     case VE::S_TPOFF_LO32:
1117       Variant = VE::S_TPOFF_LO32;
1118       break;
1119     default:
1120       return nullptr;
1121     }
1122 
1123     return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);
1124   }
1125 
1126   case MCExpr::Unary: {
1127     const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1128     const MCExpr *Sub = extractSpecifier(UE->getSubExpr(), Variant);
1129     if (!Sub)
1130       return nullptr;
1131     return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
1132   }
1133 
1134   case MCExpr::Binary: {
1135     const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1136     VE::Specifier LHSVariant, RHSVariant;
1137     const MCExpr *LHS = extractSpecifier(BE->getLHS(), LHSVariant);
1138     const MCExpr *RHS = extractSpecifier(BE->getRHS(), RHSVariant);
1139 
1140     if (!LHS && !RHS)
1141       return nullptr;
1142 
1143     if (!LHS)
1144       LHS = BE->getLHS();
1145     if (!RHS)
1146       RHS = BE->getRHS();
1147 
1148     if (LHSVariant == VE::S_None)
1149       Variant = RHSVariant;
1150     else if (RHSVariant == VE::S_None)
1151       Variant = LHSVariant;
1152     else if (LHSVariant == RHSVariant)
1153       Variant = LHSVariant;
1154     else
1155       return nullptr;
1156 
1157     return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
1158   }
1159   }
1160 
1161   llvm_unreachable("Invalid expression kind!");
1162 }
1163 
1164 /// This differs from the default "parseExpression" in that it handles
1165 /// relocation specifiers.
parseExpression(const MCExpr * & EVal)1166 bool VEAsmParser::parseExpression(const MCExpr *&EVal) {
1167   // Handle \code symbol @lo32/@hi32/etc \endcode.
1168   if (getParser().parseExpression(EVal))
1169     return true;
1170 
1171   // Convert MCSymbolRefExpr with specifier to MCSpecifierExpr.
1172   VE::Specifier Specifier;
1173   const MCExpr *E = extractSpecifier(EVal, Specifier);
1174   if (E)
1175     EVal = MCSpecifierExpr::create(E, Specifier, getParser().getContext());
1176 
1177   return false;
1178 }
1179 
parseMEMOperand(OperandVector & Operands)1180 ParseStatus VEAsmParser::parseMEMOperand(OperandVector &Operands) {
1181   LLVM_DEBUG(dbgs() << "parseMEMOperand\n");
1182   const AsmToken &Tok = Parser.getTok();
1183   SMLoc S = Tok.getLoc();
1184   SMLoc E = Tok.getEndLoc();
1185   // Parse ASX format
1186   //   disp
1187   //   disp(, base)
1188   //   disp(index)
1189   //   disp(index, base)
1190   //   (, base)
1191   //   (index)
1192   //   (index, base)
1193 
1194   std::unique_ptr<VEOperand> Offset;
1195   switch (getLexer().getKind()) {
1196   default:
1197     return ParseStatus::NoMatch;
1198 
1199   case AsmToken::Minus:
1200   case AsmToken::Integer:
1201   case AsmToken::Dot:
1202   case AsmToken::Identifier: {
1203     const MCExpr *EVal;
1204     if (!parseExpression(EVal))
1205       Offset = VEOperand::CreateImm(EVal, S, E);
1206     else
1207       return ParseStatus::NoMatch;
1208     break;
1209   }
1210 
1211   case AsmToken::LParen:
1212     // empty disp (= 0)
1213     Offset =
1214         VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E);
1215     break;
1216   }
1217 
1218   switch (getLexer().getKind()) {
1219   default:
1220     return ParseStatus::Failure;
1221 
1222   case AsmToken::EndOfStatement:
1223     Operands.push_back(VEOperand::MorphToMEMzii(
1224         MCConstantExpr::create(0, getContext()), std::move(Offset)));
1225     return ParseStatus::Success;
1226 
1227   case AsmToken::LParen:
1228     Parser.Lex(); // Eat the (
1229     break;
1230   }
1231 
1232   const MCExpr *IndexValue = nullptr;
1233   MCRegister IndexReg;
1234 
1235   switch (getLexer().getKind()) {
1236   default:
1237     if (parseRegister(IndexReg, S, E))
1238       return ParseStatus::Failure;
1239     break;
1240 
1241   case AsmToken::Minus:
1242   case AsmToken::Integer:
1243   case AsmToken::Dot:
1244     if (getParser().parseExpression(IndexValue, E))
1245       return ParseStatus::Failure;
1246     break;
1247 
1248   case AsmToken::Comma:
1249     // empty index
1250     IndexValue = MCConstantExpr::create(0, getContext());
1251     break;
1252   }
1253 
1254   switch (getLexer().getKind()) {
1255   default:
1256     return ParseStatus::Failure;
1257 
1258   case AsmToken::RParen:
1259     Parser.Lex(); // Eat the )
1260     Operands.push_back(
1261         IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(Offset))
1262                    : VEOperand::MorphToMEMzri(IndexReg, std::move(Offset)));
1263     return ParseStatus::Success;
1264 
1265   case AsmToken::Comma:
1266     Parser.Lex(); // Eat the ,
1267     break;
1268   }
1269 
1270   MCRegister BaseReg;
1271   if (parseRegister(BaseReg, S, E))
1272     return ParseStatus::Failure;
1273 
1274   if (!Parser.getTok().is(AsmToken::RParen))
1275     return ParseStatus::Failure;
1276 
1277   Parser.Lex(); // Eat the )
1278   Operands.push_back(
1279       IndexValue
1280           ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(Offset))
1281           : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(Offset)));
1282 
1283   return ParseStatus::Success;
1284 }
1285 
parseMEMAsOperand(OperandVector & Operands)1286 ParseStatus VEAsmParser::parseMEMAsOperand(OperandVector &Operands) {
1287   LLVM_DEBUG(dbgs() << "parseMEMAsOperand\n");
1288   const AsmToken &Tok = Parser.getTok();
1289   SMLoc S = Tok.getLoc();
1290   SMLoc E = Tok.getEndLoc();
1291   // Parse AS format
1292   //   disp
1293   //   disp(, base)
1294   //   disp(base)
1295   //   disp()
1296   //   (, base)
1297   //   (base)
1298   //   base
1299 
1300   MCRegister BaseReg;
1301   std::unique_ptr<VEOperand> Offset;
1302   switch (getLexer().getKind()) {
1303   default:
1304     return ParseStatus::NoMatch;
1305 
1306   case AsmToken::Minus:
1307   case AsmToken::Integer:
1308   case AsmToken::Dot:
1309   case AsmToken::Identifier: {
1310     const MCExpr *EVal;
1311     if (!parseExpression(EVal))
1312       Offset = VEOperand::CreateImm(EVal, S, E);
1313     else
1314       return ParseStatus::NoMatch;
1315     break;
1316   }
1317 
1318   case AsmToken::Percent:
1319     if (parseRegister(BaseReg, S, E))
1320       return ParseStatus::NoMatch;
1321     Offset =
1322         VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E);
1323     break;
1324 
1325   case AsmToken::LParen:
1326     // empty disp (= 0)
1327     Offset =
1328         VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E);
1329     break;
1330   }
1331 
1332   switch (getLexer().getKind()) {
1333   default:
1334     return ParseStatus::Failure;
1335 
1336   case AsmToken::EndOfStatement:
1337   case AsmToken::Comma:
1338     Operands.push_back(BaseReg != VE::NoRegister
1339                            ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset))
1340                            : VEOperand::MorphToMEMzi(std::move(Offset)));
1341     return ParseStatus::Success;
1342 
1343   case AsmToken::LParen:
1344     if (BaseReg != VE::NoRegister)
1345       return ParseStatus::Failure;
1346     Parser.Lex(); // Eat the (
1347     break;
1348   }
1349 
1350   switch (getLexer().getKind()) {
1351   default:
1352     if (parseRegister(BaseReg, S, E))
1353       return ParseStatus::Failure;
1354     break;
1355 
1356   case AsmToken::Comma:
1357     Parser.Lex(); // Eat the ,
1358     if (parseRegister(BaseReg, S, E))
1359       return ParseStatus::Failure;
1360     break;
1361 
1362   case AsmToken::RParen:
1363     break;
1364   }
1365 
1366   if (!Parser.getTok().is(AsmToken::RParen))
1367     return ParseStatus::Failure;
1368 
1369   Parser.Lex(); // Eat the )
1370   Operands.push_back(BaseReg != VE::NoRegister
1371                          ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset))
1372                          : VEOperand::MorphToMEMzi(std::move(Offset)));
1373 
1374   return ParseStatus::Success;
1375 }
1376 
parseMImmOperand(OperandVector & Operands)1377 ParseStatus VEAsmParser::parseMImmOperand(OperandVector &Operands) {
1378   LLVM_DEBUG(dbgs() << "parseMImmOperand\n");
1379 
1380   // Parsing "(" + number + ")0/1"
1381   const AsmToken Tok1 = Parser.getTok();
1382   if (!Tok1.is(AsmToken::LParen))
1383     return ParseStatus::NoMatch;
1384 
1385   Parser.Lex(); // Eat the '('.
1386 
1387   const AsmToken Tok2 = Parser.getTok();
1388   SMLoc E;
1389   const MCExpr *EVal;
1390   if (!Tok2.is(AsmToken::Integer) || getParser().parseExpression(EVal, E)) {
1391     getLexer().UnLex(Tok1);
1392     return ParseStatus::NoMatch;
1393   }
1394 
1395   const AsmToken Tok3 = Parser.getTok();
1396   if (!Tok3.is(AsmToken::RParen)) {
1397     getLexer().UnLex(Tok2);
1398     getLexer().UnLex(Tok1);
1399     return ParseStatus::NoMatch;
1400   }
1401   Parser.Lex(); // Eat the ')'.
1402 
1403   const AsmToken &Tok4 = Parser.getTok();
1404   StringRef Suffix = Tok4.getString();
1405   if (Suffix != "1" && Suffix != "0") {
1406     getLexer().UnLex(Tok3);
1407     getLexer().UnLex(Tok2);
1408     getLexer().UnLex(Tok1);
1409     return ParseStatus::NoMatch;
1410   }
1411   Parser.Lex(); // Eat the value.
1412   SMLoc EndLoc = SMLoc::getFromPointer(Suffix.end());
1413   Operands.push_back(
1414       VEOperand::CreateMImm(EVal, Suffix == "0", Tok1.getLoc(), EndLoc));
1415   return ParseStatus::Success;
1416 }
1417 
parseOperand(OperandVector & Operands,StringRef Mnemonic)1418 ParseStatus VEAsmParser::parseOperand(OperandVector &Operands,
1419                                       StringRef Mnemonic) {
1420   LLVM_DEBUG(dbgs() << "parseOperand\n");
1421   ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
1422 
1423   // If there wasn't a custom match, try the generic matcher below. Otherwise,
1424   // there was a match, but an error occurred, in which case, just return that
1425   // the operand parsing failed.
1426   if (Res.isSuccess() || Res.isFailure())
1427     return Res;
1428 
1429   switch (getLexer().getKind()) {
1430   case AsmToken::LParen: {
1431     // Parsing "(" + %vreg + ", " + %vreg + ")"
1432     const AsmToken Tok1 = Parser.getTok();
1433     Parser.Lex(); // Eat the '('.
1434 
1435     MCRegister Reg1;
1436     SMLoc S1, E1;
1437     if (!tryParseRegister(Reg1, S1, E1).isSuccess()) {
1438       getLexer().UnLex(Tok1);
1439       return ParseStatus::NoMatch;
1440     }
1441 
1442     if (!Parser.getTok().is(AsmToken::Comma))
1443       return ParseStatus::Failure;
1444     Parser.Lex(); // Eat the ','.
1445 
1446     MCRegister Reg2;
1447     SMLoc S2, E2;
1448     if (!tryParseRegister(Reg2, S2, E2).isSuccess())
1449       return ParseStatus::Failure;
1450 
1451     if (!Parser.getTok().is(AsmToken::RParen))
1452       return ParseStatus::Failure;
1453 
1454     Operands.push_back(VEOperand::CreateToken(Tok1.getString(), Tok1.getLoc()));
1455     Operands.push_back(VEOperand::CreateReg(Reg1, S1, E1));
1456     Operands.push_back(VEOperand::CreateReg(Reg2, S2, E2));
1457     Operands.push_back(VEOperand::CreateToken(Parser.getTok().getString(),
1458                                               Parser.getTok().getLoc()));
1459     Parser.Lex(); // Eat the ')'.
1460     break;
1461   }
1462   default: {
1463     std::unique_ptr<VEOperand> Op;
1464     Res = parseVEAsmOperand(Op);
1465     if (!Res.isSuccess() || !Op)
1466       return ParseStatus::Failure;
1467 
1468     // Push the parsed operand into the list of operands
1469     Operands.push_back(std::move(Op));
1470 
1471     if (!Parser.getTok().is(AsmToken::LParen))
1472       break;
1473 
1474     // Parsing %vec-reg + "(" + %sclar-reg/number + ")"
1475     std::unique_ptr<VEOperand> Op1 = VEOperand::CreateToken(
1476         Parser.getTok().getString(), Parser.getTok().getLoc());
1477     Parser.Lex(); // Eat the '('.
1478 
1479     std::unique_ptr<VEOperand> Op2;
1480     Res = parseVEAsmOperand(Op2);
1481     if (!Res.isSuccess() || !Op2)
1482       return ParseStatus::Failure;
1483 
1484     if (!Parser.getTok().is(AsmToken::RParen))
1485       return ParseStatus::Failure;
1486 
1487     Operands.push_back(std::move(Op1));
1488     Operands.push_back(std::move(Op2));
1489     Operands.push_back(VEOperand::CreateToken(Parser.getTok().getString(),
1490                                               Parser.getTok().getLoc()));
1491     Parser.Lex(); // Eat the ')'.
1492     break;
1493   }
1494   }
1495 
1496   return ParseStatus::Success;
1497 }
1498 
parseVEAsmOperand(std::unique_ptr<VEOperand> & Op)1499 ParseStatus VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &Op) {
1500   LLVM_DEBUG(dbgs() << "parseVEAsmOperand\n");
1501   SMLoc S = Parser.getTok().getLoc();
1502   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1503   const MCExpr *EVal;
1504 
1505   Op = nullptr;
1506   switch (getLexer().getKind()) {
1507   default:
1508     break;
1509 
1510   case AsmToken::Percent: {
1511     MCRegister Reg;
1512     if (tryParseRegister(Reg, S, E).isSuccess())
1513       Op = VEOperand::CreateReg(Reg, S, E);
1514     break;
1515   }
1516   case AsmToken::Minus:
1517   case AsmToken::Integer:
1518   case AsmToken::Dot:
1519   case AsmToken::Identifier:
1520     if (!parseExpression(EVal))
1521       Op = VEOperand::CreateImm(EVal, S, E);
1522     break;
1523   }
1524   return Op ? ParseStatus::Success : ParseStatus::Failure;
1525 }
1526 
1527 // Force static initialization.
LLVMInitializeVEAsmParser()1528 extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser() {
1529   RegisterMCAsmParser<VEAsmParser> A(getTheVETarget());
1530 }
1531 
1532 #define GET_REGISTER_MATCHER
1533 #define GET_MATCHER_IMPLEMENTATION
1534 #include "VEGenAsmMatcher.inc"
1535 
validateTargetOperandClass(MCParsedAsmOperand & GOp,unsigned Kind)1536 unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1537                                                  unsigned Kind) {
1538   VEOperand &Op = (VEOperand &)GOp;
1539 
1540   // VE uses identical register name for all registers like both
1541   // F32 and I32 uses "%s23".  Need to convert the name of them
1542   // for validation.
1543   switch (Kind) {
1544   default:
1545     break;
1546   case MCK_F32:
1547     if (Op.isReg() && VEOperand::MorphToF32Reg(Op))
1548       return MCTargetAsmParser::Match_Success;
1549     break;
1550   case MCK_I32:
1551     if (Op.isReg() && VEOperand::MorphToI32Reg(Op))
1552       return MCTargetAsmParser::Match_Success;
1553     break;
1554   case MCK_F128:
1555     if (Op.isReg() && VEOperand::MorphToF128Reg(Op))
1556       return MCTargetAsmParser::Match_Success;
1557     break;
1558   case MCK_VM512:
1559     if (Op.isReg() && VEOperand::MorphToVM512Reg(Op))
1560       return MCTargetAsmParser::Match_Success;
1561     break;
1562   case MCK_MISC:
1563     if (Op.isImm() && VEOperand::MorphToMISCReg(Op))
1564       return MCTargetAsmParser::Match_Success;
1565     break;
1566   }
1567   return Match_InvalidOperand;
1568 }
1569