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/VEMCExpr.h"
10 #include "MCTargetDesc/VEMCTargetDesc.h"
11 #include "TargetInfo/VETargetInfo.h"
12 #include "VE.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ADT/Twine.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCParser/MCAsmLexer.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/MCRegisterInfo.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/Support/TargetRegistry.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include <algorithm>
31 #include <memory>
32 
33 using namespace llvm;
34 
35 #define DEBUG_TYPE "ve-asmparser"
36 
37 namespace {
38 
39 class VEOperand;
40 
41 class VEAsmParser : public MCTargetAsmParser {
42   MCAsmParser &Parser;
43 
44   /// @name Auto-generated Match Functions
45   /// {
46 
47 #define GET_ASSEMBLER_HEADER
48 #include "VEGenAsmMatcher.inc"
49 
50   /// }
51 
52   // public interface of the MCTargetAsmParser.
53   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
54                                OperandVector &Operands, MCStreamer &Out,
55                                uint64_t &ErrorInfo,
56                                bool MatchingInlineAsm) override;
57   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
58   int parseRegisterName(unsigned (*matchFn)(StringRef));
59   OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
60                                         SMLoc &EndLoc) override;
61   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
62                         SMLoc NameLoc, OperandVector &Operands) override;
63   bool ParseDirective(AsmToken DirectiveID) override;
64 
65   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
66                                       unsigned Kind) override;
67 
68   // Custom parse functions for VE specific operands.
69   OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
70   OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
71   OperandMatchResultTy parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand);
72 
73 public:
74   VEAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
75               const MCInstrInfo &MII, const MCTargetOptions &Options)
76       : MCTargetAsmParser(Options, sti, MII), Parser(parser) {
77     // Initialize the set of available features.
78     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
79   }
80 };
81 
82 } // end anonymous namespace
83 
84 static const MCPhysReg I32Regs[64] = {
85     VE::SW0,  VE::SW1,  VE::SW2,  VE::SW3,  VE::SW4,  VE::SW5,  VE::SW6,
86     VE::SW7,  VE::SW8,  VE::SW9,  VE::SW10, VE::SW11, VE::SW12, VE::SW13,
87     VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20,
88     VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27,
89     VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34,
90     VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41,
91     VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48,
92     VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55,
93     VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62,
94     VE::SW63};
95 
96 static const MCPhysReg F32Regs[64] = {
97     VE::SF0,  VE::SF1,  VE::SF2,  VE::SF3,  VE::SF4,  VE::SF5,  VE::SF6,
98     VE::SF7,  VE::SF8,  VE::SF9,  VE::SF10, VE::SF11, VE::SF12, VE::SF13,
99     VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20,
100     VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27,
101     VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34,
102     VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41,
103     VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48,
104     VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55,
105     VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62,
106     VE::SF63};
107 
108 namespace {
109 
110 /// VEOperand - Instances of this class represent a parsed VE machine
111 /// instruction.
112 class VEOperand : public MCParsedAsmOperand {
113 private:
114   enum KindTy {
115     k_Token,
116     k_Register,
117     k_Immediate,
118     // SX-Aurora ASX form is disp(index, base).
119     k_MemoryRegRegImm,  // base=reg, index=reg, disp=imm
120     k_MemoryRegImmImm,  // base=reg, index=imm, disp=imm
121     k_MemoryZeroRegImm, // base=0, index=reg, disp=imm
122     k_MemoryZeroImmImm, // base=0, index=imm, disp=imm
123   } Kind;
124 
125   SMLoc StartLoc, EndLoc;
126 
127   struct Token {
128     const char *Data;
129     unsigned Length;
130   };
131 
132   struct RegOp {
133     unsigned RegNum;
134   };
135 
136   struct ImmOp {
137     const MCExpr *Val;
138   };
139 
140   struct MemOp {
141     unsigned Base;
142     unsigned IndexReg;
143     const MCExpr *Index;
144     const MCExpr *Offset;
145   };
146 
147   union {
148     struct Token Tok;
149     struct RegOp Reg;
150     struct ImmOp Imm;
151     struct MemOp Mem;
152   };
153 
154 public:
155   VEOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
156 
157   bool isToken() const override { return Kind == k_Token; }
158   bool isReg() const override { return Kind == k_Register; }
159   bool isImm() const override { return Kind == k_Immediate; }
160   bool isMem() const override {
161     return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() ||
162            isMEMzi();
163   }
164   bool isMEMrri() const { return Kind == k_MemoryRegRegImm; }
165   bool isMEMrii() const { return Kind == k_MemoryRegImmImm; }
166   bool isMEMzri() const { return Kind == k_MemoryZeroRegImm; }
167   bool isMEMzii() const { return Kind == k_MemoryZeroImmImm; }
168   // isMEMri and isMEMzi will be implemented later.
169   bool isMEMri() const { return false; }
170   bool isMEMzi() const { return false; }
171   bool isSImm7() {
172     if (!isImm())
173       return false;
174 
175     // Constant case
176     if (const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
177       int64_t Value = ConstExpr->getValue();
178       return isInt<7>(Value);
179     }
180     return false;
181   }
182 
183   StringRef getToken() const {
184     assert(Kind == k_Token && "Invalid access!");
185     return StringRef(Tok.Data, Tok.Length);
186   }
187 
188   unsigned getReg() const override {
189     assert((Kind == k_Register) && "Invalid access!");
190     return Reg.RegNum;
191   }
192 
193   const MCExpr *getImm() const {
194     assert((Kind == k_Immediate) && "Invalid access!");
195     return Imm.Val;
196   }
197 
198   unsigned getMemBase() const {
199     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm) &&
200            "Invalid access!");
201     return Mem.Base;
202   }
203 
204   unsigned getMemIndexReg() const {
205     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) &&
206            "Invalid access!");
207     return Mem.IndexReg;
208   }
209 
210   const MCExpr *getMemIndex() const {
211     assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) &&
212            "Invalid access!");
213     return Mem.Index;
214   }
215 
216   const MCExpr *getMemOffset() const {
217     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
218             Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm) &&
219            "Invalid access!");
220     return Mem.Offset;
221   }
222 
223   void setMemOffset(const MCExpr *off) {
224     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
225             Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm) &&
226            "Invalid access!");
227     Mem.Offset = off;
228   }
229 
230   /// getStartLoc - Get the location of the first token of this operand.
231   SMLoc getStartLoc() const override { return StartLoc; }
232   /// getEndLoc - Get the location of the last token of this operand.
233   SMLoc getEndLoc() const override { return EndLoc; }
234 
235   void print(raw_ostream &OS) const override {
236     switch (Kind) {
237     case k_Token:
238       OS << "Token: " << getToken() << "\n";
239       break;
240     case k_Register:
241       OS << "Reg: #" << getReg() << "\n";
242       break;
243     case k_Immediate:
244       OS << "Imm: " << getImm() << "\n";
245       break;
246     case k_MemoryRegRegImm:
247       assert(getMemOffset() != nullptr);
248       OS << "Mem: #" << getMemBase() << "+#" << getMemIndexReg() << "+"
249          << *getMemOffset() << "\n";
250       break;
251     case k_MemoryRegImmImm:
252       assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
253       OS << "Mem: #" << getMemBase() << "+" << *getMemIndex() << "+"
254          << *getMemOffset() << "\n";
255       break;
256     case k_MemoryZeroRegImm:
257       assert(getMemOffset() != nullptr);
258       OS << "Mem: 0+#" << getMemIndexReg() << "+" << *getMemOffset() << "\n";
259       break;
260     case k_MemoryZeroImmImm:
261       assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
262       OS << "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n";
263       break;
264     }
265   }
266 
267   void addRegOperands(MCInst &Inst, unsigned N) const {
268     assert(N == 1 && "Invalid number of operands!");
269     Inst.addOperand(MCOperand::createReg(getReg()));
270   }
271 
272   void addImmOperands(MCInst &Inst, unsigned N) const {
273     assert(N == 1 && "Invalid number of operands!");
274     const MCExpr *Expr = getImm();
275     addExpr(Inst, Expr);
276   }
277 
278   void addSImm7Operands(MCInst &Inst, unsigned N) const {
279     addImmOperands(Inst, N);
280   }
281 
282   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
283     // Add as immediate when possible.  Null MCExpr = 0.
284     if (!Expr)
285       Inst.addOperand(MCOperand::createImm(0));
286     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
287       Inst.addOperand(MCOperand::createImm(CE->getValue()));
288     else
289       Inst.addOperand(MCOperand::createExpr(Expr));
290   }
291 
292   void addMEMrriOperands(MCInst &Inst, unsigned N) const {
293     assert(N == 3 && "Invalid number of operands!");
294 
295     Inst.addOperand(MCOperand::createReg(getMemBase()));
296     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
297     addExpr(Inst, getMemOffset());
298   }
299 
300   void addMEMriiOperands(MCInst &Inst, unsigned N) const {
301     assert(N == 3 && "Invalid number of operands!");
302 
303     Inst.addOperand(MCOperand::createReg(getMemBase()));
304     addExpr(Inst, getMemIndex());
305     addExpr(Inst, getMemOffset());
306   }
307 
308   void addMEMzriOperands(MCInst &Inst, unsigned N) const {
309     assert(N == 3 && "Invalid number of operands!");
310 
311     Inst.addOperand(MCOperand::createImm(0));
312     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
313     addExpr(Inst, getMemOffset());
314   }
315 
316   void addMEMziiOperands(MCInst &Inst, unsigned N) const {
317     assert(N == 3 && "Invalid number of operands!");
318 
319     Inst.addOperand(MCOperand::createImm(0));
320     addExpr(Inst, getMemIndex());
321     addExpr(Inst, getMemOffset());
322   }
323 
324   void addMEMriOperands(MCInst &Inst, unsigned N) const {
325     // FIXME: implement
326   }
327 
328   void addMEMziOperands(MCInst &Inst, unsigned N) const {
329     // FIXME: implement
330   }
331 
332   static std::unique_ptr<VEOperand> CreateToken(StringRef Str, SMLoc S) {
333     auto Op = std::make_unique<VEOperand>(k_Token);
334     Op->Tok.Data = Str.data();
335     Op->Tok.Length = Str.size();
336     Op->StartLoc = S;
337     Op->EndLoc = S;
338     return Op;
339   }
340 
341   static std::unique_ptr<VEOperand> CreateReg(unsigned RegNum, SMLoc S,
342                                               SMLoc E) {
343     auto Op = std::make_unique<VEOperand>(k_Register);
344     Op->Reg.RegNum = RegNum;
345     Op->StartLoc = S;
346     Op->EndLoc = E;
347     return Op;
348   }
349 
350   static std::unique_ptr<VEOperand> CreateImm(const MCExpr *Val, SMLoc S,
351                                               SMLoc E) {
352     auto Op = std::make_unique<VEOperand>(k_Immediate);
353     Op->Imm.Val = Val;
354     Op->StartLoc = S;
355     Op->EndLoc = E;
356     return Op;
357   }
358 
359   static bool MorphToI32Reg(VEOperand &Op) {
360     unsigned Reg = Op.getReg();
361     unsigned regIdx = Reg - VE::SX0;
362     if (regIdx > 63)
363       return false;
364     Op.Reg.RegNum = I32Regs[regIdx];
365     return true;
366   }
367 
368   static bool MorphToF32Reg(VEOperand &Op) {
369     unsigned Reg = Op.getReg();
370     unsigned regIdx = Reg - VE::SX0;
371     if (regIdx > 63)
372       return false;
373     Op.Reg.RegNum = F32Regs[regIdx];
374     return true;
375   }
376 
377   static std::unique_ptr<VEOperand>
378   MorphToMEMrri(unsigned Base, unsigned Index, std::unique_ptr<VEOperand> Op) {
379     const MCExpr *Imm = Op->getImm();
380     Op->Kind = k_MemoryRegRegImm;
381     Op->Mem.Base = Base;
382     Op->Mem.IndexReg = Index;
383     Op->Mem.Index = nullptr;
384     Op->Mem.Offset = Imm;
385     return Op;
386   }
387 
388   static std::unique_ptr<VEOperand>
389   MorphToMEMrii(unsigned Base, const MCExpr *Index,
390                 std::unique_ptr<VEOperand> Op) {
391     const MCExpr *Imm = Op->getImm();
392     Op->Kind = k_MemoryRegImmImm;
393     Op->Mem.Base = Base;
394     Op->Mem.IndexReg = 0;
395     Op->Mem.Index = Index;
396     Op->Mem.Offset = Imm;
397     return Op;
398   }
399 
400   static std::unique_ptr<VEOperand>
401   MorphToMEMzri(unsigned Index, std::unique_ptr<VEOperand> Op) {
402     const MCExpr *Imm = Op->getImm();
403     Op->Kind = k_MemoryZeroRegImm;
404     Op->Mem.Base = 0;
405     Op->Mem.IndexReg = Index;
406     Op->Mem.Index = nullptr;
407     Op->Mem.Offset = Imm;
408     return Op;
409   }
410 
411   static std::unique_ptr<VEOperand>
412   MorphToMEMzii(const MCExpr *Index, std::unique_ptr<VEOperand> Op) {
413     const MCExpr *Imm = Op->getImm();
414     Op->Kind = k_MemoryZeroImmImm;
415     Op->Mem.Base = 0;
416     Op->Mem.IndexReg = 0;
417     Op->Mem.Index = Index;
418     Op->Mem.Offset = Imm;
419     return Op;
420   }
421 };
422 
423 } // end anonymous namespace
424 
425 bool VEAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
426                                           OperandVector &Operands,
427                                           MCStreamer &Out, uint64_t &ErrorInfo,
428                                           bool MatchingInlineAsm) {
429   MCInst Inst;
430   unsigned MatchResult =
431       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
432   switch (MatchResult) {
433   case Match_Success:
434     Inst.setLoc(IDLoc);
435     Out.emitInstruction(Inst, getSTI());
436     return false;
437 
438   case Match_MissingFeature:
439     return Error(IDLoc,
440                  "instruction requires a CPU feature not currently enabled");
441 
442   case Match_InvalidOperand: {
443     SMLoc ErrorLoc = IDLoc;
444     if (ErrorInfo != ~0ULL) {
445       if (ErrorInfo >= Operands.size())
446         return Error(IDLoc, "too few operands for instruction");
447 
448       ErrorLoc = ((VEOperand &)*Operands[ErrorInfo]).getStartLoc();
449       if (ErrorLoc == SMLoc())
450         ErrorLoc = IDLoc;
451     }
452 
453     return Error(ErrorLoc, "invalid operand for instruction");
454   }
455   case Match_MnemonicFail:
456     return Error(IDLoc, "invalid instruction mnemonic");
457   }
458   llvm_unreachable("Implement any new match types added!");
459 }
460 
461 bool VEAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
462                                 SMLoc &EndLoc) {
463   if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success)
464     return Error(StartLoc, "invalid register name");
465   return false;
466 }
467 
468 /// Parses a register name using a given matching function.
469 /// Checks for lowercase or uppercase if necessary.
470 int VEAsmParser::parseRegisterName(unsigned (*matchFn)(StringRef)) {
471   StringRef Name = Parser.getTok().getString();
472 
473   int RegNum = matchFn(Name);
474 
475   // GCC supports case insensitive register names. All of the VE registers
476   // are all lower case.
477   if (RegNum == VE::NoRegister) {
478     RegNum = matchFn(Name.lower());
479   }
480 
481   return RegNum;
482 }
483 
484 /// Maps from the set of all register names to a register number.
485 /// \note Generated by TableGen.
486 static unsigned MatchRegisterName(StringRef Name);
487 
488 /// Maps from the set of all alternative registernames to a register number.
489 /// \note Generated by TableGen.
490 static unsigned MatchRegisterAltName(StringRef Name);
491 
492 OperandMatchResultTy
493 VEAsmParser::tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
494   const AsmToken Tok = Parser.getTok();
495   StartLoc = Tok.getLoc();
496   EndLoc = Tok.getEndLoc();
497   RegNo = 0;
498   if (getLexer().getKind() != AsmToken::Percent)
499     return MatchOperand_NoMatch;
500   Parser.Lex();
501 
502   RegNo = parseRegisterName(&MatchRegisterName);
503   if (RegNo == VE::NoRegister)
504     RegNo = parseRegisterName(&MatchRegisterAltName);
505 
506   if (RegNo != VE::NoRegister) {
507     Parser.Lex();
508     return MatchOperand_Success;
509   }
510 
511   getLexer().UnLex(Tok);
512   return MatchOperand_NoMatch;
513 }
514 
515 bool VEAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
516                                    SMLoc NameLoc, OperandVector &Operands) {
517 
518   // First operand in MCInst is instruction mnemonic.
519   Operands.push_back(VEOperand::CreateToken(Name, NameLoc));
520 
521   if (getLexer().isNot(AsmToken::EndOfStatement)) {
522     // Read the first operand.
523     if (parseOperand(Operands, Name) != MatchOperand_Success) {
524       SMLoc Loc = getLexer().getLoc();
525       return Error(Loc, "unexpected token");
526     }
527 
528     while (getLexer().is(AsmToken::Comma)) {
529       Parser.Lex(); // Eat the comma.
530       // Parse and remember the operand.
531       if (parseOperand(Operands, Name) != MatchOperand_Success) {
532         SMLoc Loc = getLexer().getLoc();
533         return Error(Loc, "unexpected token");
534       }
535     }
536   }
537   if (getLexer().isNot(AsmToken::EndOfStatement)) {
538     SMLoc Loc = getLexer().getLoc();
539     return Error(Loc, "unexpected token");
540   }
541   Parser.Lex(); // Consume the EndOfStatement.
542   return false;
543 }
544 
545 bool VEAsmParser::ParseDirective(AsmToken DirectiveID) {
546   // Let the MC layer to handle other directives.
547   return true;
548 }
549 
550 OperandMatchResultTy VEAsmParser::parseMEMOperand(OperandVector &Operands) {
551   LLVM_DEBUG(dbgs() << "parseMEMOperand\n");
552   const AsmToken &Tok = Parser.getTok();
553   SMLoc S = Tok.getLoc();
554   SMLoc E = Tok.getEndLoc();
555   // Parse ASX format
556   //   disp
557   //   disp(, base)
558   //   disp(index)
559   //   disp(index, base)
560   //   (, base)
561   //   (index)
562   //   (index, base)
563 
564   std::unique_ptr<VEOperand> Offset;
565   switch (getLexer().getKind()) {
566   default:
567     return MatchOperand_NoMatch;
568 
569   case AsmToken::Minus:
570   case AsmToken::Integer:
571   case AsmToken::Dot: {
572     const MCExpr *EVal;
573     if (!getParser().parseExpression(EVal, E))
574       Offset = VEOperand::CreateImm(EVal, S, E);
575     else
576       return MatchOperand_NoMatch;
577     break;
578   }
579   case AsmToken::LParen:
580     // empty disp (= 0)
581     Offset =
582         VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E);
583     break;
584   }
585 
586   switch (getLexer().getKind()) {
587   default:
588     return MatchOperand_ParseFail;
589 
590   case AsmToken::EndOfStatement:
591     Operands.push_back(VEOperand::MorphToMEMzii(
592         MCConstantExpr::create(0, getContext()), std::move(Offset)));
593     return MatchOperand_Success;
594 
595   case AsmToken::LParen:
596     Parser.Lex(); // Eat the (
597     break;
598   }
599 
600   const MCExpr *IndexValue = nullptr;
601   unsigned IndexReg = 0;
602 
603   switch (getLexer().getKind()) {
604   default:
605     if (ParseRegister(IndexReg, S, E))
606       return MatchOperand_ParseFail;
607     break;
608 
609   case AsmToken::Minus:
610   case AsmToken::Integer:
611   case AsmToken::Dot:
612     if (getParser().parseExpression(IndexValue, E))
613       return MatchOperand_ParseFail;
614     break;
615 
616   case AsmToken::Comma:
617     // empty index
618     IndexValue = MCConstantExpr::create(0, getContext());
619     break;
620   }
621 
622   switch (getLexer().getKind()) {
623   default:
624     return MatchOperand_ParseFail;
625 
626   case AsmToken::RParen:
627     Parser.Lex(); // Eat the )
628     Operands.push_back(
629         IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(Offset))
630                    : VEOperand::MorphToMEMzri(IndexReg, std::move(Offset)));
631     return MatchOperand_Success;
632 
633   case AsmToken::Comma:
634     Parser.Lex(); // Eat the ,
635     break;
636   }
637 
638   unsigned BaseReg = 0;
639   if (ParseRegister(BaseReg, S, E))
640     return MatchOperand_ParseFail;
641 
642   if (!Parser.getTok().is(AsmToken::RParen))
643     return MatchOperand_ParseFail;
644 
645   Parser.Lex(); // Eat the )
646   Operands.push_back(
647       IndexValue
648           ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(Offset))
649           : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(Offset)));
650 
651   return MatchOperand_Success;
652 }
653 
654 OperandMatchResultTy VEAsmParser::parseOperand(OperandVector &Operands,
655                                                StringRef Mnemonic) {
656   LLVM_DEBUG(dbgs() << "parseOperand\n");
657   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
658 
659   // If there wasn't a custom match, try the generic matcher below. Otherwise,
660   // there was a match, but an error occurred, in which case, just return that
661   // the operand parsing failed.
662   if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail)
663     return ResTy;
664 
665   switch (getLexer().getKind()) {
666   case AsmToken::LParen:
667     // FIXME: Parsing "(" + %vreg + ", " + %vreg + ")"
668     // FALLTHROUGH
669   default: {
670     std::unique_ptr<VEOperand> Op;
671     ResTy = parseVEAsmOperand(Op);
672     if (ResTy != MatchOperand_Success || !Op)
673       return MatchOperand_ParseFail;
674 
675     // Push the parsed operand into the list of operands
676     Operands.push_back(std::move(Op));
677 
678     if (!Parser.getTok().is(AsmToken::LParen))
679       break;
680 
681     // FIXME: Parsing %vec-reg + "(" + %sclar-reg/number + ")"
682     break;
683   }
684   }
685 
686   return MatchOperand_Success;
687 }
688 
689 OperandMatchResultTy
690 VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &Op) {
691   LLVM_DEBUG(dbgs() << "parseVEAsmOperand\n");
692   SMLoc S = Parser.getTok().getLoc();
693   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
694   const MCExpr *EVal;
695 
696   Op = nullptr;
697   switch (getLexer().getKind()) {
698   default:
699     break;
700 
701   case AsmToken::Percent:
702     unsigned RegNo;
703     if (tryParseRegister(RegNo, S, E) == MatchOperand_Success)
704       Op = VEOperand::CreateReg(RegNo, S, E);
705     break;
706 
707   case AsmToken::Minus:
708   case AsmToken::Integer:
709   case AsmToken::Dot:
710     if (!getParser().parseExpression(EVal, E))
711       Op = VEOperand::CreateImm(EVal, S, E);
712     break;
713 
714   case AsmToken::Identifier: {
715     StringRef Identifier;
716     if (!getParser().parseIdentifier(Identifier)) {
717       E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
718       MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
719 
720       const MCExpr *Res =
721           MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
722       Op = VEOperand::CreateImm(Res, S, E);
723     }
724     break;
725   }
726   }
727   return (Op) ? MatchOperand_Success : MatchOperand_ParseFail;
728 }
729 
730 // Force static initialization.
731 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser() {
732   RegisterMCAsmParser<VEAsmParser> A(getTheVETarget());
733 }
734 
735 #define GET_REGISTER_MATCHER
736 #define GET_MATCHER_IMPLEMENTATION
737 #include "VEGenAsmMatcher.inc"
738 
739 unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
740                                                  unsigned Kind) {
741   VEOperand &Op = (VEOperand &)GOp;
742 
743   // VE uses identical register name for all registers like both
744   // F32 and I32 uses "%s23".  Need to convert the name of them
745   // for validation.
746   switch (Kind) {
747   default:
748     break;
749   case MCK_F32:
750     if (Op.isReg() && VEOperand::MorphToF32Reg(Op))
751       return MCTargetAsmParser::Match_Success;
752     break;
753   case MCK_I32:
754     if (Op.isReg() && VEOperand::MorphToI32Reg(Op))
755       return MCTargetAsmParser::Match_Success;
756     break;
757   }
758   return Match_InvalidOperand;
759 }
760