xref: /freebsd/contrib/llvm-project/llvm/lib/Target/VE/AsmParser/VEAsmParser.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15ffd83dbSDimitry Andric //===-- VEAsmParser.cpp - Parse VE assembly to MCInst instructions --------===//
25ffd83dbSDimitry Andric //
35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65ffd83dbSDimitry Andric //
75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
85ffd83dbSDimitry Andric 
95ffd83dbSDimitry Andric #include "MCTargetDesc/VEMCExpr.h"
105ffd83dbSDimitry Andric #include "MCTargetDesc/VEMCTargetDesc.h"
115ffd83dbSDimitry Andric #include "TargetInfo/VETargetInfo.h"
125ffd83dbSDimitry Andric #include "VE.h"
135ffd83dbSDimitry Andric #include "llvm/ADT/STLExtras.h"
145ffd83dbSDimitry Andric #include "llvm/ADT/SmallVector.h"
155ffd83dbSDimitry Andric #include "llvm/ADT/StringRef.h"
165ffd83dbSDimitry Andric #include "llvm/ADT/Twine.h"
175ffd83dbSDimitry Andric #include "llvm/MC/MCContext.h"
185ffd83dbSDimitry Andric #include "llvm/MC/MCExpr.h"
195ffd83dbSDimitry Andric #include "llvm/MC/MCInst.h"
2081ad6265SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
215ffd83dbSDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h"
225ffd83dbSDimitry Andric #include "llvm/MC/MCParser/MCAsmParser.h"
235ffd83dbSDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
245ffd83dbSDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h"
255ffd83dbSDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
265ffd83dbSDimitry Andric #include "llvm/MC/MCStreamer.h"
275ffd83dbSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
285ffd83dbSDimitry Andric #include "llvm/MC/MCSymbol.h"
29349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
305ffd83dbSDimitry Andric #include "llvm/Support/raw_ostream.h"
315ffd83dbSDimitry Andric #include <algorithm>
325ffd83dbSDimitry Andric #include <memory>
335ffd83dbSDimitry Andric 
345ffd83dbSDimitry Andric using namespace llvm;
355ffd83dbSDimitry Andric 
365ffd83dbSDimitry Andric #define DEBUG_TYPE "ve-asmparser"
375ffd83dbSDimitry Andric 
385ffd83dbSDimitry Andric namespace {
395ffd83dbSDimitry Andric 
405ffd83dbSDimitry Andric class VEOperand;
415ffd83dbSDimitry Andric 
425ffd83dbSDimitry Andric class VEAsmParser : public MCTargetAsmParser {
435ffd83dbSDimitry Andric   MCAsmParser &Parser;
445ffd83dbSDimitry Andric 
455ffd83dbSDimitry Andric   /// @name Auto-generated Match Functions
465ffd83dbSDimitry Andric   /// {
475ffd83dbSDimitry Andric 
485ffd83dbSDimitry Andric #define GET_ASSEMBLER_HEADER
495ffd83dbSDimitry Andric #include "VEGenAsmMatcher.inc"
505ffd83dbSDimitry Andric 
515ffd83dbSDimitry Andric   /// }
525ffd83dbSDimitry Andric 
535ffd83dbSDimitry Andric   // public interface of the MCTargetAsmParser.
545ffd83dbSDimitry Andric   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
555ffd83dbSDimitry Andric                                OperandVector &Operands, MCStreamer &Out,
565ffd83dbSDimitry Andric                                uint64_t &ErrorInfo,
575ffd83dbSDimitry Andric                                bool MatchingInlineAsm) override;
585f757f3fSDimitry Andric   bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
59*0fca6ea1SDimitry Andric   int parseRegisterName(MCRegister (*matchFn)(StringRef));
605f757f3fSDimitry Andric   ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
615ffd83dbSDimitry Andric                                SMLoc &EndLoc) override;
625ffd83dbSDimitry Andric   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
635ffd83dbSDimitry Andric                         SMLoc NameLoc, OperandVector &Operands) override;
6406c3fb27SDimitry Andric   ParseStatus parseDirective(AsmToken DirectiveID) override;
655ffd83dbSDimitry Andric 
665ffd83dbSDimitry Andric   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
675ffd83dbSDimitry Andric                                       unsigned Kind) override;
685ffd83dbSDimitry Andric 
695ffd83dbSDimitry Andric   // Custom parse functions for VE specific operands.
705f757f3fSDimitry Andric   ParseStatus parseMEMOperand(OperandVector &Operands);
715f757f3fSDimitry Andric   ParseStatus parseMEMAsOperand(OperandVector &Operands);
725f757f3fSDimitry Andric   ParseStatus parseCCOpOperand(OperandVector &Operands);
735f757f3fSDimitry Andric   ParseStatus parseRDOpOperand(OperandVector &Operands);
745f757f3fSDimitry Andric   ParseStatus parseMImmOperand(OperandVector &Operands);
755f757f3fSDimitry Andric   ParseStatus parseOperand(OperandVector &Operands, StringRef Name);
765f757f3fSDimitry Andric   ParseStatus parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand);
775ffd83dbSDimitry Andric 
785ffd83dbSDimitry Andric   // Helper function to parse expression with a symbol.
795ffd83dbSDimitry Andric   const MCExpr *extractModifierFromExpr(const MCExpr *E,
805ffd83dbSDimitry Andric                                         VEMCExpr::VariantKind &Variant);
815ffd83dbSDimitry Andric   const MCExpr *fixupVariantKind(const MCExpr *E);
825ffd83dbSDimitry Andric   bool parseExpression(const MCExpr *&EVal);
835ffd83dbSDimitry Andric 
845ffd83dbSDimitry Andric   // Split the mnemonic stripping conditional code and quantifiers
855ffd83dbSDimitry Andric   StringRef splitMnemonic(StringRef Name, SMLoc NameLoc,
865ffd83dbSDimitry Andric                           OperandVector *Operands);
875ffd83dbSDimitry Andric 
880eae32dcSDimitry Andric   bool parseLiteralValues(unsigned Size, SMLoc L);
890eae32dcSDimitry Andric 
905ffd83dbSDimitry Andric public:
VEAsmParser(const MCSubtargetInfo & sti,MCAsmParser & parser,const MCInstrInfo & MII,const MCTargetOptions & Options)915ffd83dbSDimitry Andric   VEAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
925ffd83dbSDimitry Andric               const MCInstrInfo &MII, const MCTargetOptions &Options)
935ffd83dbSDimitry Andric       : MCTargetAsmParser(Options, sti, MII), Parser(parser) {
945ffd83dbSDimitry Andric     // Initialize the set of available features.
955ffd83dbSDimitry Andric     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
965ffd83dbSDimitry Andric   }
975ffd83dbSDimitry Andric };
985ffd83dbSDimitry Andric 
995ffd83dbSDimitry Andric } // end anonymous namespace
1005ffd83dbSDimitry Andric 
1015ffd83dbSDimitry Andric static const MCPhysReg I32Regs[64] = {
1025ffd83dbSDimitry Andric     VE::SW0,  VE::SW1,  VE::SW2,  VE::SW3,  VE::SW4,  VE::SW5,  VE::SW6,
1035ffd83dbSDimitry Andric     VE::SW7,  VE::SW8,  VE::SW9,  VE::SW10, VE::SW11, VE::SW12, VE::SW13,
1045ffd83dbSDimitry Andric     VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20,
1055ffd83dbSDimitry Andric     VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27,
1065ffd83dbSDimitry Andric     VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34,
1075ffd83dbSDimitry Andric     VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41,
1085ffd83dbSDimitry Andric     VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48,
1095ffd83dbSDimitry Andric     VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55,
1105ffd83dbSDimitry Andric     VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62,
1115ffd83dbSDimitry Andric     VE::SW63};
1125ffd83dbSDimitry Andric 
1135ffd83dbSDimitry Andric static const MCPhysReg F32Regs[64] = {
1145ffd83dbSDimitry Andric     VE::SF0,  VE::SF1,  VE::SF2,  VE::SF3,  VE::SF4,  VE::SF5,  VE::SF6,
1155ffd83dbSDimitry Andric     VE::SF7,  VE::SF8,  VE::SF9,  VE::SF10, VE::SF11, VE::SF12, VE::SF13,
1165ffd83dbSDimitry Andric     VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20,
1175ffd83dbSDimitry Andric     VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27,
1185ffd83dbSDimitry Andric     VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34,
1195ffd83dbSDimitry Andric     VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41,
1205ffd83dbSDimitry Andric     VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48,
1215ffd83dbSDimitry Andric     VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55,
1225ffd83dbSDimitry Andric     VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62,
1235ffd83dbSDimitry Andric     VE::SF63};
1245ffd83dbSDimitry Andric 
1255ffd83dbSDimitry Andric static const MCPhysReg F128Regs[32] = {
1265ffd83dbSDimitry Andric     VE::Q0,  VE::Q1,  VE::Q2,  VE::Q3,  VE::Q4,  VE::Q5,  VE::Q6,  VE::Q7,
1275ffd83dbSDimitry Andric     VE::Q8,  VE::Q9,  VE::Q10, VE::Q11, VE::Q12, VE::Q13, VE::Q14, VE::Q15,
1285ffd83dbSDimitry Andric     VE::Q16, VE::Q17, VE::Q18, VE::Q19, VE::Q20, VE::Q21, VE::Q22, VE::Q23,
1295ffd83dbSDimitry Andric     VE::Q24, VE::Q25, VE::Q26, VE::Q27, VE::Q28, VE::Q29, VE::Q30, VE::Q31};
1305ffd83dbSDimitry Andric 
131e8d8bef9SDimitry Andric static const MCPhysReg VM512Regs[8] = {VE::VMP0, VE::VMP1, VE::VMP2, VE::VMP3,
132e8d8bef9SDimitry Andric                                        VE::VMP4, VE::VMP5, VE::VMP6, VE::VMP7};
133e8d8bef9SDimitry Andric 
1345ffd83dbSDimitry Andric static const MCPhysReg MISCRegs[31] = {
1355ffd83dbSDimitry Andric     VE::USRCC,      VE::PSW,        VE::SAR,        VE::NoRegister,
1365ffd83dbSDimitry Andric     VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::PMMR,
1375ffd83dbSDimitry Andric     VE::PMCR0,      VE::PMCR1,      VE::PMCR2,      VE::PMCR3,
1385ffd83dbSDimitry Andric     VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::NoRegister,
1395ffd83dbSDimitry Andric     VE::PMC0,       VE::PMC1,       VE::PMC2,       VE::PMC3,
1405ffd83dbSDimitry Andric     VE::PMC4,       VE::PMC5,       VE::PMC6,       VE::PMC7,
1415ffd83dbSDimitry Andric     VE::PMC8,       VE::PMC9,       VE::PMC10,      VE::PMC11,
1425ffd83dbSDimitry Andric     VE::PMC12,      VE::PMC13,      VE::PMC14};
1435ffd83dbSDimitry Andric 
1445ffd83dbSDimitry Andric namespace {
1455ffd83dbSDimitry Andric 
1465ffd83dbSDimitry Andric /// VEOperand - Instances of this class represent a parsed VE machine
1475ffd83dbSDimitry Andric /// instruction.
1485ffd83dbSDimitry Andric class VEOperand : public MCParsedAsmOperand {
1495ffd83dbSDimitry Andric private:
1505ffd83dbSDimitry Andric   enum KindTy {
1515ffd83dbSDimitry Andric     k_Token,
1525ffd83dbSDimitry Andric     k_Register,
1535ffd83dbSDimitry Andric     k_Immediate,
1545ffd83dbSDimitry Andric     // SX-Aurora ASX form is disp(index, base).
1555ffd83dbSDimitry Andric     k_MemoryRegRegImm,  // base=reg, index=reg, disp=imm
1565ffd83dbSDimitry Andric     k_MemoryRegImmImm,  // base=reg, index=imm, disp=imm
1575ffd83dbSDimitry Andric     k_MemoryZeroRegImm, // base=0, index=reg, disp=imm
1585ffd83dbSDimitry Andric     k_MemoryZeroImmImm, // base=0, index=imm, disp=imm
1595ffd83dbSDimitry Andric     // SX-Aurora AS form is disp(base).
1605ffd83dbSDimitry Andric     k_MemoryRegImm,  // base=reg, disp=imm
1615ffd83dbSDimitry Andric     k_MemoryZeroImm, // base=0, disp=imm
1625ffd83dbSDimitry Andric     // Other special cases for Aurora VE
1635ffd83dbSDimitry Andric     k_CCOp,   // condition code
1645ffd83dbSDimitry Andric     k_RDOp,   // rounding mode
1655ffd83dbSDimitry Andric     k_MImmOp, // Special immediate value of sequential bit stream of 0 or 1.
1665ffd83dbSDimitry Andric   } Kind;
1675ffd83dbSDimitry Andric 
1685ffd83dbSDimitry Andric   SMLoc StartLoc, EndLoc;
1695ffd83dbSDimitry Andric 
1705ffd83dbSDimitry Andric   struct Token {
1715ffd83dbSDimitry Andric     const char *Data;
1725ffd83dbSDimitry Andric     unsigned Length;
1735ffd83dbSDimitry Andric   };
1745ffd83dbSDimitry Andric 
1755ffd83dbSDimitry Andric   struct RegOp {
1765ffd83dbSDimitry Andric     unsigned RegNum;
1775ffd83dbSDimitry Andric   };
1785ffd83dbSDimitry Andric 
1795ffd83dbSDimitry Andric   struct ImmOp {
1805ffd83dbSDimitry Andric     const MCExpr *Val;
1815ffd83dbSDimitry Andric   };
1825ffd83dbSDimitry Andric 
1835ffd83dbSDimitry Andric   struct MemOp {
1845ffd83dbSDimitry Andric     unsigned Base;
1855ffd83dbSDimitry Andric     unsigned IndexReg;
1865ffd83dbSDimitry Andric     const MCExpr *Index;
1875ffd83dbSDimitry Andric     const MCExpr *Offset;
1885ffd83dbSDimitry Andric   };
1895ffd83dbSDimitry Andric 
1905ffd83dbSDimitry Andric   struct CCOp {
1915ffd83dbSDimitry Andric     unsigned CCVal;
1925ffd83dbSDimitry Andric   };
1935ffd83dbSDimitry Andric 
1945ffd83dbSDimitry Andric   struct RDOp {
1955ffd83dbSDimitry Andric     unsigned RDVal;
1965ffd83dbSDimitry Andric   };
1975ffd83dbSDimitry Andric 
1985ffd83dbSDimitry Andric   struct MImmOp {
1995ffd83dbSDimitry Andric     const MCExpr *Val;
2005ffd83dbSDimitry Andric     bool M0Flag;
2015ffd83dbSDimitry Andric   };
2025ffd83dbSDimitry Andric 
2035ffd83dbSDimitry Andric   union {
2045ffd83dbSDimitry Andric     struct Token Tok;
2055ffd83dbSDimitry Andric     struct RegOp Reg;
2065ffd83dbSDimitry Andric     struct ImmOp Imm;
2075ffd83dbSDimitry Andric     struct MemOp Mem;
2085ffd83dbSDimitry Andric     struct CCOp CC;
2095ffd83dbSDimitry Andric     struct RDOp RD;
2105ffd83dbSDimitry Andric     struct MImmOp MImm;
2115ffd83dbSDimitry Andric   };
2125ffd83dbSDimitry Andric 
2135ffd83dbSDimitry Andric public:
VEOperand(KindTy K)21404eeddc0SDimitry Andric   VEOperand(KindTy K) : Kind(K) {}
2155ffd83dbSDimitry Andric 
isToken() const2165ffd83dbSDimitry Andric   bool isToken() const override { return Kind == k_Token; }
isReg() const2175ffd83dbSDimitry Andric   bool isReg() const override { return Kind == k_Register; }
isImm() const2185ffd83dbSDimitry Andric   bool isImm() const override { return Kind == k_Immediate; }
isMem() const2195ffd83dbSDimitry Andric   bool isMem() const override {
2205ffd83dbSDimitry Andric     return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() ||
2215ffd83dbSDimitry Andric            isMEMzi();
2225ffd83dbSDimitry Andric   }
isMEMrri() const2235ffd83dbSDimitry Andric   bool isMEMrri() const { return Kind == k_MemoryRegRegImm; }
isMEMrii() const2245ffd83dbSDimitry Andric   bool isMEMrii() const { return Kind == k_MemoryRegImmImm; }
isMEMzri() const2255ffd83dbSDimitry Andric   bool isMEMzri() const { return Kind == k_MemoryZeroRegImm; }
isMEMzii() const2265ffd83dbSDimitry Andric   bool isMEMzii() const { return Kind == k_MemoryZeroImmImm; }
isMEMri() const2275ffd83dbSDimitry Andric   bool isMEMri() const { return Kind == k_MemoryRegImm; }
isMEMzi() const2285ffd83dbSDimitry Andric   bool isMEMzi() const { return Kind == k_MemoryZeroImm; }
isCCOp() const2295ffd83dbSDimitry Andric   bool isCCOp() const { return Kind == k_CCOp; }
isRDOp() const2305ffd83dbSDimitry Andric   bool isRDOp() const { return Kind == k_RDOp; }
isZero()2315ffd83dbSDimitry Andric   bool isZero() {
2325ffd83dbSDimitry Andric     if (!isImm())
2335ffd83dbSDimitry Andric       return false;
2345ffd83dbSDimitry Andric 
2355ffd83dbSDimitry Andric     // Constant case
2365ffd83dbSDimitry Andric     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
2375ffd83dbSDimitry Andric       int64_t Value = ConstExpr->getValue();
2385ffd83dbSDimitry Andric       return Value == 0;
2395ffd83dbSDimitry Andric     }
2405ffd83dbSDimitry Andric     return false;
2415ffd83dbSDimitry Andric   }
isUImm0to2()2425ffd83dbSDimitry Andric   bool isUImm0to2() {
2435ffd83dbSDimitry Andric     if (!isImm())
2445ffd83dbSDimitry Andric       return false;
2455ffd83dbSDimitry Andric 
2465ffd83dbSDimitry Andric     // Constant case
2475ffd83dbSDimitry Andric     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
2485ffd83dbSDimitry Andric       int64_t Value = ConstExpr->getValue();
2495ffd83dbSDimitry Andric       return Value >= 0 && Value < 3;
2505ffd83dbSDimitry Andric     }
2515ffd83dbSDimitry Andric     return false;
2525ffd83dbSDimitry Andric   }
isUImm1()2535ffd83dbSDimitry Andric   bool isUImm1() {
2545ffd83dbSDimitry Andric     if (!isImm())
2555ffd83dbSDimitry Andric       return false;
2565ffd83dbSDimitry Andric 
2575ffd83dbSDimitry Andric     // Constant case
2585ffd83dbSDimitry Andric     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
2595ffd83dbSDimitry Andric       int64_t Value = ConstExpr->getValue();
2605ffd83dbSDimitry Andric       return isUInt<1>(Value);
2615ffd83dbSDimitry Andric     }
2625ffd83dbSDimitry Andric     return false;
2635ffd83dbSDimitry Andric   }
isUImm2()2645ffd83dbSDimitry Andric   bool isUImm2() {
2655ffd83dbSDimitry Andric     if (!isImm())
2665ffd83dbSDimitry Andric       return false;
2675ffd83dbSDimitry Andric 
2685ffd83dbSDimitry Andric     // Constant case
2695ffd83dbSDimitry Andric     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
2705ffd83dbSDimitry Andric       int64_t Value = ConstExpr->getValue();
2715ffd83dbSDimitry Andric       return isUInt<2>(Value);
2725ffd83dbSDimitry Andric     }
2735ffd83dbSDimitry Andric     return false;
2745ffd83dbSDimitry Andric   }
isUImm3()2755ffd83dbSDimitry Andric   bool isUImm3() {
2765ffd83dbSDimitry Andric     if (!isImm())
2775ffd83dbSDimitry Andric       return false;
2785ffd83dbSDimitry Andric 
2795ffd83dbSDimitry Andric     // Constant case
2805ffd83dbSDimitry Andric     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
2815ffd83dbSDimitry Andric       int64_t Value = ConstExpr->getValue();
2825ffd83dbSDimitry Andric       return isUInt<3>(Value);
2835ffd83dbSDimitry Andric     }
2845ffd83dbSDimitry Andric     return false;
2855ffd83dbSDimitry Andric   }
isUImm4()286e8d8bef9SDimitry Andric   bool isUImm4() {
287e8d8bef9SDimitry Andric     if (!isImm())
288e8d8bef9SDimitry Andric       return false;
289e8d8bef9SDimitry Andric 
290e8d8bef9SDimitry Andric     // Constant case
291e8d8bef9SDimitry Andric     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
292e8d8bef9SDimitry Andric       int64_t Value = ConstExpr->getValue();
293e8d8bef9SDimitry Andric       return isUInt<4>(Value);
294e8d8bef9SDimitry Andric     }
295e8d8bef9SDimitry Andric     return false;
296e8d8bef9SDimitry Andric   }
isUImm6()2975ffd83dbSDimitry Andric   bool isUImm6() {
2985ffd83dbSDimitry Andric     if (!isImm())
2995ffd83dbSDimitry Andric       return false;
3005ffd83dbSDimitry Andric 
3015ffd83dbSDimitry Andric     // Constant case
3025ffd83dbSDimitry Andric     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
3035ffd83dbSDimitry Andric       int64_t Value = ConstExpr->getValue();
3045ffd83dbSDimitry Andric       return isUInt<6>(Value);
3055ffd83dbSDimitry Andric     }
3065ffd83dbSDimitry Andric     return false;
3075ffd83dbSDimitry Andric   }
isUImm7()3085ffd83dbSDimitry Andric   bool isUImm7() {
3095ffd83dbSDimitry Andric     if (!isImm())
3105ffd83dbSDimitry Andric       return false;
3115ffd83dbSDimitry Andric 
3125ffd83dbSDimitry Andric     // Constant case
3135ffd83dbSDimitry Andric     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
3145ffd83dbSDimitry Andric       int64_t Value = ConstExpr->getValue();
3155ffd83dbSDimitry Andric       return isUInt<7>(Value);
3165ffd83dbSDimitry Andric     }
3175ffd83dbSDimitry Andric     return false;
3185ffd83dbSDimitry Andric   }
isSImm7()3195ffd83dbSDimitry Andric   bool isSImm7() {
3205ffd83dbSDimitry Andric     if (!isImm())
3215ffd83dbSDimitry Andric       return false;
3225ffd83dbSDimitry Andric 
3235ffd83dbSDimitry Andric     // Constant case
3245ffd83dbSDimitry Andric     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Val)) {
3255ffd83dbSDimitry Andric       int64_t Value = ConstExpr->getValue();
3265ffd83dbSDimitry Andric       return isInt<7>(Value);
3275ffd83dbSDimitry Andric     }
3285ffd83dbSDimitry Andric     return false;
3295ffd83dbSDimitry Andric   }
isMImm() const3305ffd83dbSDimitry Andric   bool isMImm() const {
3315ffd83dbSDimitry Andric     if (Kind != k_MImmOp)
3325ffd83dbSDimitry Andric       return false;
3335ffd83dbSDimitry Andric 
3345ffd83dbSDimitry Andric     // Constant case
3355ffd83dbSDimitry Andric     if (const auto *ConstExpr = dyn_cast<MCConstantExpr>(MImm.Val)) {
3365ffd83dbSDimitry Andric       int64_t Value = ConstExpr->getValue();
3375ffd83dbSDimitry Andric       return isUInt<6>(Value);
3385ffd83dbSDimitry Andric     }
3395ffd83dbSDimitry Andric     return false;
3405ffd83dbSDimitry Andric   }
3415ffd83dbSDimitry Andric 
getToken() const3425ffd83dbSDimitry Andric   StringRef getToken() const {
3435ffd83dbSDimitry Andric     assert(Kind == k_Token && "Invalid access!");
3445ffd83dbSDimitry Andric     return StringRef(Tok.Data, Tok.Length);
3455ffd83dbSDimitry Andric   }
3465ffd83dbSDimitry Andric 
getReg() const347*0fca6ea1SDimitry Andric   MCRegister getReg() const override {
3485ffd83dbSDimitry Andric     assert((Kind == k_Register) && "Invalid access!");
3495ffd83dbSDimitry Andric     return Reg.RegNum;
3505ffd83dbSDimitry Andric   }
3515ffd83dbSDimitry Andric 
getImm() const3525ffd83dbSDimitry Andric   const MCExpr *getImm() const {
3535ffd83dbSDimitry Andric     assert((Kind == k_Immediate) && "Invalid access!");
3545ffd83dbSDimitry Andric     return Imm.Val;
3555ffd83dbSDimitry Andric   }
3565ffd83dbSDimitry Andric 
getMemBase() const3575ffd83dbSDimitry Andric   unsigned getMemBase() const {
3585ffd83dbSDimitry Andric     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
3595ffd83dbSDimitry Andric             Kind == k_MemoryRegImm) &&
3605ffd83dbSDimitry Andric            "Invalid access!");
3615ffd83dbSDimitry Andric     return Mem.Base;
3625ffd83dbSDimitry Andric   }
3635ffd83dbSDimitry Andric 
getMemIndexReg() const3645ffd83dbSDimitry Andric   unsigned getMemIndexReg() const {
3655ffd83dbSDimitry Andric     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) &&
3665ffd83dbSDimitry Andric            "Invalid access!");
3675ffd83dbSDimitry Andric     return Mem.IndexReg;
3685ffd83dbSDimitry Andric   }
3695ffd83dbSDimitry Andric 
getMemIndex() const3705ffd83dbSDimitry Andric   const MCExpr *getMemIndex() const {
3715ffd83dbSDimitry Andric     assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) &&
3725ffd83dbSDimitry Andric            "Invalid access!");
3735ffd83dbSDimitry Andric     return Mem.Index;
3745ffd83dbSDimitry Andric   }
3755ffd83dbSDimitry Andric 
getMemOffset() const3765ffd83dbSDimitry Andric   const MCExpr *getMemOffset() const {
3775ffd83dbSDimitry Andric     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
3785ffd83dbSDimitry Andric             Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
3795ffd83dbSDimitry Andric             Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
3805ffd83dbSDimitry Andric            "Invalid access!");
3815ffd83dbSDimitry Andric     return Mem.Offset;
3825ffd83dbSDimitry Andric   }
3835ffd83dbSDimitry Andric 
setMemOffset(const MCExpr * off)3845ffd83dbSDimitry Andric   void setMemOffset(const MCExpr *off) {
3855ffd83dbSDimitry Andric     assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
3865ffd83dbSDimitry Andric             Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
3875ffd83dbSDimitry Andric             Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
3885ffd83dbSDimitry Andric            "Invalid access!");
3895ffd83dbSDimitry Andric     Mem.Offset = off;
3905ffd83dbSDimitry Andric   }
3915ffd83dbSDimitry Andric 
getCCVal() const3925ffd83dbSDimitry Andric   unsigned getCCVal() const {
3935ffd83dbSDimitry Andric     assert((Kind == k_CCOp) && "Invalid access!");
3945ffd83dbSDimitry Andric     return CC.CCVal;
3955ffd83dbSDimitry Andric   }
3965ffd83dbSDimitry Andric 
getRDVal() const3975ffd83dbSDimitry Andric   unsigned getRDVal() const {
3985ffd83dbSDimitry Andric     assert((Kind == k_RDOp) && "Invalid access!");
3995ffd83dbSDimitry Andric     return RD.RDVal;
4005ffd83dbSDimitry Andric   }
4015ffd83dbSDimitry Andric 
getMImmVal() const4025ffd83dbSDimitry Andric   const MCExpr *getMImmVal() const {
4035ffd83dbSDimitry Andric     assert((Kind == k_MImmOp) && "Invalid access!");
4045ffd83dbSDimitry Andric     return MImm.Val;
4055ffd83dbSDimitry Andric   }
getM0Flag() const4065ffd83dbSDimitry Andric   bool getM0Flag() const {
4075ffd83dbSDimitry Andric     assert((Kind == k_MImmOp) && "Invalid access!");
4085ffd83dbSDimitry Andric     return MImm.M0Flag;
4095ffd83dbSDimitry Andric   }
4105ffd83dbSDimitry Andric 
4115ffd83dbSDimitry Andric   /// getStartLoc - Get the location of the first token of this operand.
getStartLoc() const4125ffd83dbSDimitry Andric   SMLoc getStartLoc() const override { return StartLoc; }
4135ffd83dbSDimitry Andric   /// getEndLoc - Get the location of the last token of this operand.
getEndLoc() const4145ffd83dbSDimitry Andric   SMLoc getEndLoc() const override { return EndLoc; }
4155ffd83dbSDimitry Andric 
print(raw_ostream & OS) const4165ffd83dbSDimitry Andric   void print(raw_ostream &OS) const override {
4175ffd83dbSDimitry Andric     switch (Kind) {
4185ffd83dbSDimitry Andric     case k_Token:
4195ffd83dbSDimitry Andric       OS << "Token: " << getToken() << "\n";
4205ffd83dbSDimitry Andric       break;
4215ffd83dbSDimitry Andric     case k_Register:
4225ffd83dbSDimitry Andric       OS << "Reg: #" << getReg() << "\n";
4235ffd83dbSDimitry Andric       break;
4245ffd83dbSDimitry Andric     case k_Immediate:
4255ffd83dbSDimitry Andric       OS << "Imm: " << getImm() << "\n";
4265ffd83dbSDimitry Andric       break;
4275ffd83dbSDimitry Andric     case k_MemoryRegRegImm:
4285ffd83dbSDimitry Andric       assert(getMemOffset() != nullptr);
4295ffd83dbSDimitry Andric       OS << "Mem: #" << getMemBase() << "+#" << getMemIndexReg() << "+"
4305ffd83dbSDimitry Andric          << *getMemOffset() << "\n";
4315ffd83dbSDimitry Andric       break;
4325ffd83dbSDimitry Andric     case k_MemoryRegImmImm:
4335ffd83dbSDimitry Andric       assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
4345ffd83dbSDimitry Andric       OS << "Mem: #" << getMemBase() << "+" << *getMemIndex() << "+"
4355ffd83dbSDimitry Andric          << *getMemOffset() << "\n";
4365ffd83dbSDimitry Andric       break;
4375ffd83dbSDimitry Andric     case k_MemoryZeroRegImm:
4385ffd83dbSDimitry Andric       assert(getMemOffset() != nullptr);
4395ffd83dbSDimitry Andric       OS << "Mem: 0+#" << getMemIndexReg() << "+" << *getMemOffset() << "\n";
4405ffd83dbSDimitry Andric       break;
4415ffd83dbSDimitry Andric     case k_MemoryZeroImmImm:
4425ffd83dbSDimitry Andric       assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
4435ffd83dbSDimitry Andric       OS << "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n";
4445ffd83dbSDimitry Andric       break;
4455ffd83dbSDimitry Andric     case k_MemoryRegImm:
4465ffd83dbSDimitry Andric       assert(getMemOffset() != nullptr);
4475ffd83dbSDimitry Andric       OS << "Mem: #" << getMemBase() << "+" << *getMemOffset() << "\n";
4485ffd83dbSDimitry Andric       break;
4495ffd83dbSDimitry Andric     case k_MemoryZeroImm:
4505ffd83dbSDimitry Andric       assert(getMemOffset() != nullptr);
4515ffd83dbSDimitry Andric       OS << "Mem: 0+" << *getMemOffset() << "\n";
4525ffd83dbSDimitry Andric       break;
4535ffd83dbSDimitry Andric     case k_CCOp:
4545ffd83dbSDimitry Andric       OS << "CCOp: " << getCCVal() << "\n";
4555ffd83dbSDimitry Andric       break;
4565ffd83dbSDimitry Andric     case k_RDOp:
4575ffd83dbSDimitry Andric       OS << "RDOp: " << getRDVal() << "\n";
4585ffd83dbSDimitry Andric       break;
4595ffd83dbSDimitry Andric     case k_MImmOp:
4605ffd83dbSDimitry Andric       OS << "MImm: (" << getMImmVal() << (getM0Flag() ? ")0" : ")1") << "\n";
4615ffd83dbSDimitry Andric       break;
4625ffd83dbSDimitry Andric     }
4635ffd83dbSDimitry Andric   }
4645ffd83dbSDimitry Andric 
addRegOperands(MCInst & Inst,unsigned N) const4655ffd83dbSDimitry Andric   void addRegOperands(MCInst &Inst, unsigned N) const {
4665ffd83dbSDimitry Andric     assert(N == 1 && "Invalid number of operands!");
4675ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createReg(getReg()));
4685ffd83dbSDimitry Andric   }
4695ffd83dbSDimitry Andric 
addImmOperands(MCInst & Inst,unsigned N) const4705ffd83dbSDimitry Andric   void addImmOperands(MCInst &Inst, unsigned N) const {
4715ffd83dbSDimitry Andric     assert(N == 1 && "Invalid number of operands!");
4725ffd83dbSDimitry Andric     const MCExpr *Expr = getImm();
4735ffd83dbSDimitry Andric     addExpr(Inst, Expr);
4745ffd83dbSDimitry Andric   }
4755ffd83dbSDimitry Andric 
addZeroOperands(MCInst & Inst,unsigned N) const4765ffd83dbSDimitry Andric   void addZeroOperands(MCInst &Inst, unsigned N) const {
4775ffd83dbSDimitry Andric     addImmOperands(Inst, N);
4785ffd83dbSDimitry Andric   }
4795ffd83dbSDimitry Andric 
addUImm0to2Operands(MCInst & Inst,unsigned N) const4805ffd83dbSDimitry Andric   void addUImm0to2Operands(MCInst &Inst, unsigned N) const {
4815ffd83dbSDimitry Andric     addImmOperands(Inst, N);
4825ffd83dbSDimitry Andric   }
4835ffd83dbSDimitry Andric 
addUImm1Operands(MCInst & Inst,unsigned N) const4845ffd83dbSDimitry Andric   void addUImm1Operands(MCInst &Inst, unsigned N) const {
4855ffd83dbSDimitry Andric     addImmOperands(Inst, N);
4865ffd83dbSDimitry Andric   }
4875ffd83dbSDimitry Andric 
addUImm2Operands(MCInst & Inst,unsigned N) const4885ffd83dbSDimitry Andric   void addUImm2Operands(MCInst &Inst, unsigned N) const {
4895ffd83dbSDimitry Andric     addImmOperands(Inst, N);
4905ffd83dbSDimitry Andric   }
4915ffd83dbSDimitry Andric 
addUImm3Operands(MCInst & Inst,unsigned N) const4925ffd83dbSDimitry Andric   void addUImm3Operands(MCInst &Inst, unsigned N) const {
4935ffd83dbSDimitry Andric     addImmOperands(Inst, N);
4945ffd83dbSDimitry Andric   }
4955ffd83dbSDimitry Andric 
addUImm4Operands(MCInst & Inst,unsigned N) const496e8d8bef9SDimitry Andric   void addUImm4Operands(MCInst &Inst, unsigned N) const {
497e8d8bef9SDimitry Andric     addImmOperands(Inst, N);
498e8d8bef9SDimitry Andric   }
499e8d8bef9SDimitry Andric 
addUImm6Operands(MCInst & Inst,unsigned N) const5005ffd83dbSDimitry Andric   void addUImm6Operands(MCInst &Inst, unsigned N) const {
5015ffd83dbSDimitry Andric     addImmOperands(Inst, N);
5025ffd83dbSDimitry Andric   }
5035ffd83dbSDimitry Andric 
addUImm7Operands(MCInst & Inst,unsigned N) const5045ffd83dbSDimitry Andric   void addUImm7Operands(MCInst &Inst, unsigned N) const {
5055ffd83dbSDimitry Andric     addImmOperands(Inst, N);
5065ffd83dbSDimitry Andric   }
5075ffd83dbSDimitry Andric 
addSImm7Operands(MCInst & Inst,unsigned N) const5085ffd83dbSDimitry Andric   void addSImm7Operands(MCInst &Inst, unsigned N) const {
5095ffd83dbSDimitry Andric     addImmOperands(Inst, N);
5105ffd83dbSDimitry Andric   }
5115ffd83dbSDimitry Andric 
addExpr(MCInst & Inst,const MCExpr * Expr) const5125ffd83dbSDimitry Andric   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
5135ffd83dbSDimitry Andric     // Add as immediate when possible.  Null MCExpr = 0.
5145ffd83dbSDimitry Andric     if (!Expr)
5155ffd83dbSDimitry Andric       Inst.addOperand(MCOperand::createImm(0));
5165ffd83dbSDimitry Andric     else if (const auto *CE = dyn_cast<MCConstantExpr>(Expr))
5175ffd83dbSDimitry Andric       Inst.addOperand(MCOperand::createImm(CE->getValue()));
5185ffd83dbSDimitry Andric     else
5195ffd83dbSDimitry Andric       Inst.addOperand(MCOperand::createExpr(Expr));
5205ffd83dbSDimitry Andric   }
5215ffd83dbSDimitry Andric 
addMEMrriOperands(MCInst & Inst,unsigned N) const5225ffd83dbSDimitry Andric   void addMEMrriOperands(MCInst &Inst, unsigned N) const {
5235ffd83dbSDimitry Andric     assert(N == 3 && "Invalid number of operands!");
5245ffd83dbSDimitry Andric 
5255ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemBase()));
5265ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
5275ffd83dbSDimitry Andric     addExpr(Inst, getMemOffset());
5285ffd83dbSDimitry Andric   }
5295ffd83dbSDimitry Andric 
addMEMriiOperands(MCInst & Inst,unsigned N) const5305ffd83dbSDimitry Andric   void addMEMriiOperands(MCInst &Inst, unsigned N) const {
5315ffd83dbSDimitry Andric     assert(N == 3 && "Invalid number of operands!");
5325ffd83dbSDimitry Andric 
5335ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemBase()));
5345ffd83dbSDimitry Andric     addExpr(Inst, getMemIndex());
5355ffd83dbSDimitry Andric     addExpr(Inst, getMemOffset());
5365ffd83dbSDimitry Andric   }
5375ffd83dbSDimitry Andric 
addMEMzriOperands(MCInst & Inst,unsigned N) const5385ffd83dbSDimitry Andric   void addMEMzriOperands(MCInst &Inst, unsigned N) const {
5395ffd83dbSDimitry Andric     assert(N == 3 && "Invalid number of operands!");
5405ffd83dbSDimitry Andric 
5415ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
5425ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemIndexReg()));
5435ffd83dbSDimitry Andric     addExpr(Inst, getMemOffset());
5445ffd83dbSDimitry Andric   }
5455ffd83dbSDimitry Andric 
addMEMziiOperands(MCInst & Inst,unsigned N) const5465ffd83dbSDimitry Andric   void addMEMziiOperands(MCInst &Inst, unsigned N) const {
5475ffd83dbSDimitry Andric     assert(N == 3 && "Invalid number of operands!");
5485ffd83dbSDimitry Andric 
5495ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
5505ffd83dbSDimitry Andric     addExpr(Inst, getMemIndex());
5515ffd83dbSDimitry Andric     addExpr(Inst, getMemOffset());
5525ffd83dbSDimitry Andric   }
5535ffd83dbSDimitry Andric 
addMEMriOperands(MCInst & Inst,unsigned N) const5545ffd83dbSDimitry Andric   void addMEMriOperands(MCInst &Inst, unsigned N) const {
5555ffd83dbSDimitry Andric     assert(N == 2 && "Invalid number of operands!");
5565ffd83dbSDimitry Andric 
5575ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createReg(getMemBase()));
5585ffd83dbSDimitry Andric     addExpr(Inst, getMemOffset());
5595ffd83dbSDimitry Andric   }
5605ffd83dbSDimitry Andric 
addMEMziOperands(MCInst & Inst,unsigned N) const5615ffd83dbSDimitry Andric   void addMEMziOperands(MCInst &Inst, unsigned N) const {
5625ffd83dbSDimitry Andric     assert(N == 2 && "Invalid number of operands!");
5635ffd83dbSDimitry Andric 
5645ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createImm(0));
5655ffd83dbSDimitry Andric     addExpr(Inst, getMemOffset());
5665ffd83dbSDimitry Andric   }
5675ffd83dbSDimitry Andric 
addCCOpOperands(MCInst & Inst,unsigned N) const5685ffd83dbSDimitry Andric   void addCCOpOperands(MCInst &Inst, unsigned N) const {
5695ffd83dbSDimitry Andric     assert(N == 1 && "Invalid number of operands!");
5705ffd83dbSDimitry Andric 
5715ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createImm(getCCVal()));
5725ffd83dbSDimitry Andric   }
5735ffd83dbSDimitry Andric 
addRDOpOperands(MCInst & Inst,unsigned N) const5745ffd83dbSDimitry Andric   void addRDOpOperands(MCInst &Inst, unsigned N) const {
5755ffd83dbSDimitry Andric     assert(N == 1 && "Invalid number of operands!");
5765ffd83dbSDimitry Andric 
5775ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createImm(getRDVal()));
5785ffd83dbSDimitry Andric   }
5795ffd83dbSDimitry Andric 
addMImmOperands(MCInst & Inst,unsigned N) const5805ffd83dbSDimitry Andric   void addMImmOperands(MCInst &Inst, unsigned N) const {
5815ffd83dbSDimitry Andric     assert(N == 1 && "Invalid number of operands!");
5825ffd83dbSDimitry Andric     const auto *ConstExpr = dyn_cast<MCConstantExpr>(getMImmVal());
5835ffd83dbSDimitry Andric     assert(ConstExpr && "Null operands!");
5845ffd83dbSDimitry Andric     int64_t Value = ConstExpr->getValue();
5855ffd83dbSDimitry Andric     if (getM0Flag())
5865ffd83dbSDimitry Andric       Value += 64;
5875ffd83dbSDimitry Andric     Inst.addOperand(MCOperand::createImm(Value));
5885ffd83dbSDimitry Andric   }
5895ffd83dbSDimitry Andric 
CreateToken(StringRef Str,SMLoc S)5905ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand> CreateToken(StringRef Str, SMLoc S) {
5915ffd83dbSDimitry Andric     auto Op = std::make_unique<VEOperand>(k_Token);
5925ffd83dbSDimitry Andric     Op->Tok.Data = Str.data();
5935ffd83dbSDimitry Andric     Op->Tok.Length = Str.size();
5945ffd83dbSDimitry Andric     Op->StartLoc = S;
5955ffd83dbSDimitry Andric     Op->EndLoc = S;
5965ffd83dbSDimitry Andric     return Op;
5975ffd83dbSDimitry Andric   }
5985ffd83dbSDimitry Andric 
CreateReg(unsigned RegNum,SMLoc S,SMLoc E)5995ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand> CreateReg(unsigned RegNum, SMLoc S,
6005ffd83dbSDimitry Andric                                               SMLoc E) {
6015ffd83dbSDimitry Andric     auto Op = std::make_unique<VEOperand>(k_Register);
6025ffd83dbSDimitry Andric     Op->Reg.RegNum = RegNum;
6035ffd83dbSDimitry Andric     Op->StartLoc = S;
6045ffd83dbSDimitry Andric     Op->EndLoc = E;
6055ffd83dbSDimitry Andric     return Op;
6065ffd83dbSDimitry Andric   }
6075ffd83dbSDimitry Andric 
CreateImm(const MCExpr * Val,SMLoc S,SMLoc E)6085ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand> CreateImm(const MCExpr *Val, SMLoc S,
6095ffd83dbSDimitry Andric                                               SMLoc E) {
6105ffd83dbSDimitry Andric     auto Op = std::make_unique<VEOperand>(k_Immediate);
6115ffd83dbSDimitry Andric     Op->Imm.Val = Val;
6125ffd83dbSDimitry Andric     Op->StartLoc = S;
6135ffd83dbSDimitry Andric     Op->EndLoc = E;
6145ffd83dbSDimitry Andric     return Op;
6155ffd83dbSDimitry Andric   }
6165ffd83dbSDimitry Andric 
CreateCCOp(unsigned CCVal,SMLoc S,SMLoc E)6175ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand> CreateCCOp(unsigned CCVal, SMLoc S,
6185ffd83dbSDimitry Andric                                                SMLoc E) {
6195ffd83dbSDimitry Andric     auto Op = std::make_unique<VEOperand>(k_CCOp);
6205ffd83dbSDimitry Andric     Op->CC.CCVal = CCVal;
6215ffd83dbSDimitry Andric     Op->StartLoc = S;
6225ffd83dbSDimitry Andric     Op->EndLoc = E;
6235ffd83dbSDimitry Andric     return Op;
6245ffd83dbSDimitry Andric   }
6255ffd83dbSDimitry Andric 
CreateRDOp(unsigned RDVal,SMLoc S,SMLoc E)6265ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand> CreateRDOp(unsigned RDVal, SMLoc S,
6275ffd83dbSDimitry Andric                                                SMLoc E) {
6285ffd83dbSDimitry Andric     auto Op = std::make_unique<VEOperand>(k_RDOp);
6295ffd83dbSDimitry Andric     Op->RD.RDVal = RDVal;
6305ffd83dbSDimitry Andric     Op->StartLoc = S;
6315ffd83dbSDimitry Andric     Op->EndLoc = E;
6325ffd83dbSDimitry Andric     return Op;
6335ffd83dbSDimitry Andric   }
6345ffd83dbSDimitry Andric 
CreateMImm(const MCExpr * Val,bool Flag,SMLoc S,SMLoc E)6355ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand> CreateMImm(const MCExpr *Val, bool Flag,
6365ffd83dbSDimitry Andric                                                SMLoc S, SMLoc E) {
6375ffd83dbSDimitry Andric     auto Op = std::make_unique<VEOperand>(k_MImmOp);
6385ffd83dbSDimitry Andric     Op->MImm.Val = Val;
6395ffd83dbSDimitry Andric     Op->MImm.M0Flag = Flag;
6405ffd83dbSDimitry Andric     Op->StartLoc = S;
6415ffd83dbSDimitry Andric     Op->EndLoc = E;
6425ffd83dbSDimitry Andric     return Op;
6435ffd83dbSDimitry Andric   }
6445ffd83dbSDimitry Andric 
MorphToI32Reg(VEOperand & Op)6455ffd83dbSDimitry Andric   static bool MorphToI32Reg(VEOperand &Op) {
6465ffd83dbSDimitry Andric     unsigned Reg = Op.getReg();
6475ffd83dbSDimitry Andric     unsigned regIdx = Reg - VE::SX0;
6485ffd83dbSDimitry Andric     if (regIdx > 63)
6495ffd83dbSDimitry Andric       return false;
6505ffd83dbSDimitry Andric     Op.Reg.RegNum = I32Regs[regIdx];
6515ffd83dbSDimitry Andric     return true;
6525ffd83dbSDimitry Andric   }
6535ffd83dbSDimitry Andric 
MorphToF32Reg(VEOperand & Op)6545ffd83dbSDimitry Andric   static bool MorphToF32Reg(VEOperand &Op) {
6555ffd83dbSDimitry Andric     unsigned Reg = Op.getReg();
6565ffd83dbSDimitry Andric     unsigned regIdx = Reg - VE::SX0;
6575ffd83dbSDimitry Andric     if (regIdx > 63)
6585ffd83dbSDimitry Andric       return false;
6595ffd83dbSDimitry Andric     Op.Reg.RegNum = F32Regs[regIdx];
6605ffd83dbSDimitry Andric     return true;
6615ffd83dbSDimitry Andric   }
6625ffd83dbSDimitry Andric 
MorphToF128Reg(VEOperand & Op)6635ffd83dbSDimitry Andric   static bool MorphToF128Reg(VEOperand &Op) {
6645ffd83dbSDimitry Andric     unsigned Reg = Op.getReg();
6655ffd83dbSDimitry Andric     unsigned regIdx = Reg - VE::SX0;
6665ffd83dbSDimitry Andric     if (regIdx % 2 || regIdx > 63)
6675ffd83dbSDimitry Andric       return false;
6685ffd83dbSDimitry Andric     Op.Reg.RegNum = F128Regs[regIdx / 2];
6695ffd83dbSDimitry Andric     return true;
6705ffd83dbSDimitry Andric   }
6715ffd83dbSDimitry Andric 
MorphToVM512Reg(VEOperand & Op)672e8d8bef9SDimitry Andric   static bool MorphToVM512Reg(VEOperand &Op) {
673e8d8bef9SDimitry Andric     unsigned Reg = Op.getReg();
674e8d8bef9SDimitry Andric     unsigned regIdx = Reg - VE::VM0;
675e8d8bef9SDimitry Andric     if (regIdx % 2 || regIdx > 15)
676e8d8bef9SDimitry Andric       return false;
677e8d8bef9SDimitry Andric     Op.Reg.RegNum = VM512Regs[regIdx / 2];
678e8d8bef9SDimitry Andric     return true;
679e8d8bef9SDimitry Andric   }
680e8d8bef9SDimitry Andric 
MorphToMISCReg(VEOperand & Op)6815ffd83dbSDimitry Andric   static bool MorphToMISCReg(VEOperand &Op) {
6825ffd83dbSDimitry Andric     const auto *ConstExpr = dyn_cast<MCConstantExpr>(Op.getImm());
6835ffd83dbSDimitry Andric     if (!ConstExpr)
6845ffd83dbSDimitry Andric       return false;
6855ffd83dbSDimitry Andric     unsigned regIdx = ConstExpr->getValue();
6865ffd83dbSDimitry Andric     if (regIdx > 31 || MISCRegs[regIdx] == VE::NoRegister)
6875ffd83dbSDimitry Andric       return false;
6885ffd83dbSDimitry Andric     Op.Kind = k_Register;
6895ffd83dbSDimitry Andric     Op.Reg.RegNum = MISCRegs[regIdx];
6905ffd83dbSDimitry Andric     return true;
6915ffd83dbSDimitry Andric   }
6925ffd83dbSDimitry Andric 
6935ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand>
MorphToMEMri(unsigned Base,std::unique_ptr<VEOperand> Op)6945ffd83dbSDimitry Andric   MorphToMEMri(unsigned Base, std::unique_ptr<VEOperand> Op) {
6955ffd83dbSDimitry Andric     const MCExpr *Imm = Op->getImm();
6965ffd83dbSDimitry Andric     Op->Kind = k_MemoryRegImm;
6975ffd83dbSDimitry Andric     Op->Mem.Base = Base;
6985ffd83dbSDimitry Andric     Op->Mem.IndexReg = 0;
6995ffd83dbSDimitry Andric     Op->Mem.Index = nullptr;
7005ffd83dbSDimitry Andric     Op->Mem.Offset = Imm;
7015ffd83dbSDimitry Andric     return Op;
7025ffd83dbSDimitry Andric   }
7035ffd83dbSDimitry Andric 
7045ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand>
MorphToMEMzi(std::unique_ptr<VEOperand> Op)7055ffd83dbSDimitry Andric   MorphToMEMzi(std::unique_ptr<VEOperand> Op) {
7065ffd83dbSDimitry Andric     const MCExpr *Imm = Op->getImm();
7075ffd83dbSDimitry Andric     Op->Kind = k_MemoryZeroImm;
7085ffd83dbSDimitry Andric     Op->Mem.Base = 0;
7095ffd83dbSDimitry Andric     Op->Mem.IndexReg = 0;
7105ffd83dbSDimitry Andric     Op->Mem.Index = nullptr;
7115ffd83dbSDimitry Andric     Op->Mem.Offset = Imm;
7125ffd83dbSDimitry Andric     return Op;
7135ffd83dbSDimitry Andric   }
7145ffd83dbSDimitry Andric 
7155ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand>
MorphToMEMrri(unsigned Base,unsigned Index,std::unique_ptr<VEOperand> Op)7165ffd83dbSDimitry Andric   MorphToMEMrri(unsigned Base, unsigned Index, std::unique_ptr<VEOperand> Op) {
7175ffd83dbSDimitry Andric     const MCExpr *Imm = Op->getImm();
7185ffd83dbSDimitry Andric     Op->Kind = k_MemoryRegRegImm;
7195ffd83dbSDimitry Andric     Op->Mem.Base = Base;
7205ffd83dbSDimitry Andric     Op->Mem.IndexReg = Index;
7215ffd83dbSDimitry Andric     Op->Mem.Index = nullptr;
7225ffd83dbSDimitry Andric     Op->Mem.Offset = Imm;
7235ffd83dbSDimitry Andric     return Op;
7245ffd83dbSDimitry Andric   }
7255ffd83dbSDimitry Andric 
7265ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand>
MorphToMEMrii(unsigned Base,const MCExpr * Index,std::unique_ptr<VEOperand> Op)7275ffd83dbSDimitry Andric   MorphToMEMrii(unsigned Base, const MCExpr *Index,
7285ffd83dbSDimitry Andric                 std::unique_ptr<VEOperand> Op) {
7295ffd83dbSDimitry Andric     const MCExpr *Imm = Op->getImm();
7305ffd83dbSDimitry Andric     Op->Kind = k_MemoryRegImmImm;
7315ffd83dbSDimitry Andric     Op->Mem.Base = Base;
7325ffd83dbSDimitry Andric     Op->Mem.IndexReg = 0;
7335ffd83dbSDimitry Andric     Op->Mem.Index = Index;
7345ffd83dbSDimitry Andric     Op->Mem.Offset = Imm;
7355ffd83dbSDimitry Andric     return Op;
7365ffd83dbSDimitry Andric   }
7375ffd83dbSDimitry Andric 
7385ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand>
MorphToMEMzri(unsigned Index,std::unique_ptr<VEOperand> Op)7395ffd83dbSDimitry Andric   MorphToMEMzri(unsigned Index, std::unique_ptr<VEOperand> Op) {
7405ffd83dbSDimitry Andric     const MCExpr *Imm = Op->getImm();
7415ffd83dbSDimitry Andric     Op->Kind = k_MemoryZeroRegImm;
7425ffd83dbSDimitry Andric     Op->Mem.Base = 0;
7435ffd83dbSDimitry Andric     Op->Mem.IndexReg = Index;
7445ffd83dbSDimitry Andric     Op->Mem.Index = nullptr;
7455ffd83dbSDimitry Andric     Op->Mem.Offset = Imm;
7465ffd83dbSDimitry Andric     return Op;
7475ffd83dbSDimitry Andric   }
7485ffd83dbSDimitry Andric 
7495ffd83dbSDimitry Andric   static std::unique_ptr<VEOperand>
MorphToMEMzii(const MCExpr * Index,std::unique_ptr<VEOperand> Op)7505ffd83dbSDimitry Andric   MorphToMEMzii(const MCExpr *Index, std::unique_ptr<VEOperand> Op) {
7515ffd83dbSDimitry Andric     const MCExpr *Imm = Op->getImm();
7525ffd83dbSDimitry Andric     Op->Kind = k_MemoryZeroImmImm;
7535ffd83dbSDimitry Andric     Op->Mem.Base = 0;
7545ffd83dbSDimitry Andric     Op->Mem.IndexReg = 0;
7555ffd83dbSDimitry Andric     Op->Mem.Index = Index;
7565ffd83dbSDimitry Andric     Op->Mem.Offset = Imm;
7575ffd83dbSDimitry Andric     return Op;
7585ffd83dbSDimitry Andric   }
7595ffd83dbSDimitry Andric };
7605ffd83dbSDimitry Andric 
7615ffd83dbSDimitry Andric } // end anonymous namespace
7625ffd83dbSDimitry Andric 
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)7635ffd83dbSDimitry Andric bool VEAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
7645ffd83dbSDimitry Andric                                           OperandVector &Operands,
7655ffd83dbSDimitry Andric                                           MCStreamer &Out, uint64_t &ErrorInfo,
7665ffd83dbSDimitry Andric                                           bool MatchingInlineAsm) {
7675ffd83dbSDimitry Andric   MCInst Inst;
7685ffd83dbSDimitry Andric   unsigned MatchResult =
7695ffd83dbSDimitry Andric       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
7705ffd83dbSDimitry Andric   switch (MatchResult) {
7715ffd83dbSDimitry Andric   case Match_Success:
7725ffd83dbSDimitry Andric     Inst.setLoc(IDLoc);
7735ffd83dbSDimitry Andric     Out.emitInstruction(Inst, getSTI());
7745ffd83dbSDimitry Andric     return false;
7755ffd83dbSDimitry Andric 
7765ffd83dbSDimitry Andric   case Match_MissingFeature:
7775ffd83dbSDimitry Andric     return Error(IDLoc,
7785ffd83dbSDimitry Andric                  "instruction requires a CPU feature not currently enabled");
7795ffd83dbSDimitry Andric 
7805ffd83dbSDimitry Andric   case Match_InvalidOperand: {
7815ffd83dbSDimitry Andric     SMLoc ErrorLoc = IDLoc;
7825ffd83dbSDimitry Andric     if (ErrorInfo != ~0ULL) {
7835ffd83dbSDimitry Andric       if (ErrorInfo >= Operands.size())
7845ffd83dbSDimitry Andric         return Error(IDLoc, "too few operands for instruction");
7855ffd83dbSDimitry Andric 
7865ffd83dbSDimitry Andric       ErrorLoc = ((VEOperand &)*Operands[ErrorInfo]).getStartLoc();
7875ffd83dbSDimitry Andric       if (ErrorLoc == SMLoc())
7885ffd83dbSDimitry Andric         ErrorLoc = IDLoc;
7895ffd83dbSDimitry Andric     }
7905ffd83dbSDimitry Andric 
7915ffd83dbSDimitry Andric     return Error(ErrorLoc, "invalid operand for instruction");
7925ffd83dbSDimitry Andric   }
7935ffd83dbSDimitry Andric   case Match_MnemonicFail:
7945ffd83dbSDimitry Andric     return Error(IDLoc, "invalid instruction mnemonic");
7955ffd83dbSDimitry Andric   }
7965ffd83dbSDimitry Andric   llvm_unreachable("Implement any new match types added!");
7975ffd83dbSDimitry Andric }
7985ffd83dbSDimitry Andric 
parseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)7995f757f3fSDimitry Andric bool VEAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
8005ffd83dbSDimitry Andric                                 SMLoc &EndLoc) {
8015f757f3fSDimitry Andric   if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
8025ffd83dbSDimitry Andric     return Error(StartLoc, "invalid register name");
8035ffd83dbSDimitry Andric   return false;
8045ffd83dbSDimitry Andric }
8055ffd83dbSDimitry Andric 
8065ffd83dbSDimitry Andric /// Parses a register name using a given matching function.
8075ffd83dbSDimitry Andric /// Checks for lowercase or uppercase if necessary.
parseRegisterName(MCRegister (* matchFn)(StringRef))808*0fca6ea1SDimitry Andric int VEAsmParser::parseRegisterName(MCRegister (*matchFn)(StringRef)) {
8095ffd83dbSDimitry Andric   StringRef Name = Parser.getTok().getString();
8105ffd83dbSDimitry Andric 
8115ffd83dbSDimitry Andric   int RegNum = matchFn(Name);
8125ffd83dbSDimitry Andric 
8135ffd83dbSDimitry Andric   // GCC supports case insensitive register names. All of the VE registers
8145ffd83dbSDimitry Andric   // are all lower case.
8155ffd83dbSDimitry Andric   if (RegNum == VE::NoRegister) {
8165ffd83dbSDimitry Andric     RegNum = matchFn(Name.lower());
8175ffd83dbSDimitry Andric   }
8185ffd83dbSDimitry Andric 
8195ffd83dbSDimitry Andric   return RegNum;
8205ffd83dbSDimitry Andric }
8215ffd83dbSDimitry Andric 
8225ffd83dbSDimitry Andric /// Maps from the set of all register names to a register number.
8235ffd83dbSDimitry Andric /// \note Generated by TableGen.
824*0fca6ea1SDimitry Andric static MCRegister MatchRegisterName(StringRef Name);
8255ffd83dbSDimitry Andric 
8265ffd83dbSDimitry Andric /// Maps from the set of all alternative registernames to a register number.
8275ffd83dbSDimitry Andric /// \note Generated by TableGen.
828*0fca6ea1SDimitry Andric static MCRegister MatchRegisterAltName(StringRef Name);
8295ffd83dbSDimitry Andric 
tryParseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)8305f757f3fSDimitry Andric ParseStatus VEAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
831bdd1243dSDimitry Andric                                           SMLoc &EndLoc) {
8325ffd83dbSDimitry Andric   const AsmToken Tok = Parser.getTok();
8335ffd83dbSDimitry Andric   StartLoc = Tok.getLoc();
8345ffd83dbSDimitry Andric   EndLoc = Tok.getEndLoc();
8355f757f3fSDimitry Andric   Reg = VE::NoRegister;
8365ffd83dbSDimitry Andric   if (getLexer().getKind() != AsmToken::Percent)
8375f757f3fSDimitry Andric     return ParseStatus::NoMatch;
8385ffd83dbSDimitry Andric   Parser.Lex();
8395ffd83dbSDimitry Andric 
8405f757f3fSDimitry Andric   Reg = parseRegisterName(&MatchRegisterName);
8415f757f3fSDimitry Andric   if (Reg == VE::NoRegister)
8425f757f3fSDimitry Andric     Reg = parseRegisterName(&MatchRegisterAltName);
8435ffd83dbSDimitry Andric 
8445f757f3fSDimitry Andric   if (Reg != VE::NoRegister) {
8455ffd83dbSDimitry Andric     Parser.Lex();
8465f757f3fSDimitry Andric     return ParseStatus::Success;
8475ffd83dbSDimitry Andric   }
8485ffd83dbSDimitry Andric 
8495ffd83dbSDimitry Andric   getLexer().UnLex(Tok);
8505f757f3fSDimitry Andric   return ParseStatus::NoMatch;
8515ffd83dbSDimitry Andric }
8525ffd83dbSDimitry Andric 
parseCC(StringRef Name,unsigned Prefix,unsigned Suffix,bool IntegerCC,bool OmitCC,SMLoc NameLoc,OperandVector * Operands)8535ffd83dbSDimitry Andric static StringRef parseCC(StringRef Name, unsigned Prefix, unsigned Suffix,
8545ffd83dbSDimitry Andric                          bool IntegerCC, bool OmitCC, SMLoc NameLoc,
8555ffd83dbSDimitry Andric                          OperandVector *Operands) {
8565ffd83dbSDimitry Andric   // Parse instructions with a conditional code. For example, 'bne' is
8575ffd83dbSDimitry Andric   // converted into two operands 'b' and 'ne'.
8585ffd83dbSDimitry Andric   StringRef Cond = Name.slice(Prefix, Suffix);
8595ffd83dbSDimitry Andric   VECC::CondCode CondCode =
8605ffd83dbSDimitry Andric       IntegerCC ? stringToVEICondCode(Cond) : stringToVEFCondCode(Cond);
8615ffd83dbSDimitry Andric 
8625ffd83dbSDimitry Andric   // If OmitCC is enabled, CC_AT and CC_AF is treated as a part of mnemonic.
8635ffd83dbSDimitry Andric   if (CondCode != VECC::UNKNOWN &&
8645ffd83dbSDimitry Andric       (!OmitCC || (CondCode != VECC::CC_AT && CondCode != VECC::CC_AF))) {
8655ffd83dbSDimitry Andric     StringRef SuffixStr = Name.substr(Suffix);
8665ffd83dbSDimitry Andric     // Push "b".
8675ffd83dbSDimitry Andric     Name = Name.slice(0, Prefix);
8685ffd83dbSDimitry Andric     Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
8695ffd83dbSDimitry Andric     // Push $cond part.
8705ffd83dbSDimitry Andric     SMLoc CondLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Prefix);
8715ffd83dbSDimitry Andric     SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Suffix);
8725ffd83dbSDimitry Andric     Operands->push_back(VEOperand::CreateCCOp(CondCode, CondLoc, SuffixLoc));
8735ffd83dbSDimitry Andric     // push suffix like ".l.t"
8745ffd83dbSDimitry Andric     if (!SuffixStr.empty())
8755ffd83dbSDimitry Andric       Operands->push_back(VEOperand::CreateToken(SuffixStr, SuffixLoc));
8765ffd83dbSDimitry Andric   } else {
8775ffd83dbSDimitry Andric     Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
8785ffd83dbSDimitry Andric   }
8795ffd83dbSDimitry Andric   return Name;
8805ffd83dbSDimitry Andric }
8815ffd83dbSDimitry Andric 
parseRD(StringRef Name,unsigned Prefix,SMLoc NameLoc,OperandVector * Operands)8825ffd83dbSDimitry Andric static StringRef parseRD(StringRef Name, unsigned Prefix, SMLoc NameLoc,
8835ffd83dbSDimitry Andric                          OperandVector *Operands) {
8845ffd83dbSDimitry Andric   // Parse instructions with a conditional code. For example, 'cvt.w.d.sx.rz'
8855ffd83dbSDimitry Andric   // is converted into two operands 'cvt.w.d.sx' and '.rz'.
8865ffd83dbSDimitry Andric   StringRef RD = Name.substr(Prefix);
8875ffd83dbSDimitry Andric   VERD::RoundingMode RoundingMode = stringToVERD(RD);
8885ffd83dbSDimitry Andric 
8895ffd83dbSDimitry Andric   if (RoundingMode != VERD::UNKNOWN) {
8905ffd83dbSDimitry Andric     Name = Name.slice(0, Prefix);
8915ffd83dbSDimitry Andric     // push 1st like `cvt.w.d.sx`
8925ffd83dbSDimitry Andric     Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
8935ffd83dbSDimitry Andric     SMLoc SuffixLoc =
8945ffd83dbSDimitry Andric         SMLoc::getFromPointer(NameLoc.getPointer() + (RD.data() - Name.data()));
8955ffd83dbSDimitry Andric     SMLoc SuffixEnd =
8965ffd83dbSDimitry Andric         SMLoc::getFromPointer(NameLoc.getPointer() + (RD.end() - Name.data()));
8975ffd83dbSDimitry Andric     // push $round if it has rounding mode
8985ffd83dbSDimitry Andric     Operands->push_back(
8995ffd83dbSDimitry Andric         VEOperand::CreateRDOp(RoundingMode, SuffixLoc, SuffixEnd));
9005ffd83dbSDimitry Andric   } else {
9015ffd83dbSDimitry Andric     Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
9025ffd83dbSDimitry Andric   }
9035ffd83dbSDimitry Andric   return Name;
9045ffd83dbSDimitry Andric }
9055ffd83dbSDimitry Andric 
9065ffd83dbSDimitry Andric // Split the mnemonic into ASM operand, conditional code and instruction
9075ffd83dbSDimitry Andric // qualifier (half-word, byte).
splitMnemonic(StringRef Name,SMLoc NameLoc,OperandVector * Operands)9085ffd83dbSDimitry Andric StringRef VEAsmParser::splitMnemonic(StringRef Name, SMLoc NameLoc,
9095ffd83dbSDimitry Andric                                      OperandVector *Operands) {
9105ffd83dbSDimitry Andric   // Create the leading tokens for the mnemonic
9115ffd83dbSDimitry Andric   StringRef Mnemonic = Name;
9125ffd83dbSDimitry Andric 
9135ffd83dbSDimitry Andric   if (Name[0] == 'b') {
9145ffd83dbSDimitry Andric     // Match b?? or br??.
9155ffd83dbSDimitry Andric     size_t Start = 1;
9165ffd83dbSDimitry Andric     size_t Next = Name.find('.');
9175ffd83dbSDimitry Andric     // Adjust position of CondCode.
9185ffd83dbSDimitry Andric     if (Name.size() > 1 && Name[1] == 'r')
9195ffd83dbSDimitry Andric       Start = 2;
9205ffd83dbSDimitry Andric     // Check suffix.
9215ffd83dbSDimitry Andric     bool ICC = true;
9225ffd83dbSDimitry Andric     if (Next + 1 < Name.size() &&
9235ffd83dbSDimitry Andric         (Name[Next + 1] == 'd' || Name[Next + 1] == 's'))
9245ffd83dbSDimitry Andric       ICC = false;
9255ffd83dbSDimitry Andric     Mnemonic = parseCC(Name, Start, Next, ICC, true, NameLoc, Operands);
9265f757f3fSDimitry Andric   } else if (Name.starts_with("cmov.l.") || Name.starts_with("cmov.w.") ||
9275f757f3fSDimitry Andric              Name.starts_with("cmov.d.") || Name.starts_with("cmov.s.")) {
9285ffd83dbSDimitry Andric     bool ICC = Name[5] == 'l' || Name[5] == 'w';
9295ffd83dbSDimitry Andric     Mnemonic = parseCC(Name, 7, Name.size(), ICC, false, NameLoc, Operands);
9305f757f3fSDimitry Andric   } else if (Name.starts_with("cvt.w.d.sx") || Name.starts_with("cvt.w.d.zx") ||
9315f757f3fSDimitry Andric              Name.starts_with("cvt.w.s.sx") || Name.starts_with("cvt.w.s.zx")) {
9325ffd83dbSDimitry Andric     Mnemonic = parseRD(Name, 10, NameLoc, Operands);
9335f757f3fSDimitry Andric   } else if (Name.starts_with("cvt.l.d")) {
9345ffd83dbSDimitry Andric     Mnemonic = parseRD(Name, 7, NameLoc, Operands);
9355f757f3fSDimitry Andric   } else if (Name.starts_with("vcvt.w.d.sx") ||
9365f757f3fSDimitry Andric              Name.starts_with("vcvt.w.d.zx") ||
9375f757f3fSDimitry Andric              Name.starts_with("vcvt.w.s.sx") ||
9385f757f3fSDimitry Andric              Name.starts_with("vcvt.w.s.zx")) {
939e8d8bef9SDimitry Andric     Mnemonic = parseRD(Name, 11, NameLoc, Operands);
9405f757f3fSDimitry Andric   } else if (Name.starts_with("vcvt.l.d")) {
941e8d8bef9SDimitry Andric     Mnemonic = parseRD(Name, 8, NameLoc, Operands);
9425f757f3fSDimitry Andric   } else if (Name.starts_with("pvcvt.w.s.lo") ||
9435f757f3fSDimitry Andric              Name.starts_with("pvcvt.w.s.up")) {
944e8d8bef9SDimitry Andric     Mnemonic = parseRD(Name, 12, NameLoc, Operands);
9455f757f3fSDimitry Andric   } else if (Name.starts_with("pvcvt.w.s")) {
946e8d8bef9SDimitry Andric     Mnemonic = parseRD(Name, 9, NameLoc, Operands);
9475f757f3fSDimitry Andric   } else if (Name.starts_with("vfmk.l.") || Name.starts_with("vfmk.w.") ||
9485f757f3fSDimitry Andric              Name.starts_with("vfmk.d.") || Name.starts_with("vfmk.s.")) {
949e8d8bef9SDimitry Andric     bool ICC = Name[5] == 'l' || Name[5] == 'w' ? true : false;
950e8d8bef9SDimitry Andric     Mnemonic = parseCC(Name, 7, Name.size(), ICC, true, NameLoc, Operands);
9515f757f3fSDimitry Andric   } else if (Name.starts_with("pvfmk.w.lo.") ||
9525f757f3fSDimitry Andric              Name.starts_with("pvfmk.w.up.") ||
9535f757f3fSDimitry Andric              Name.starts_with("pvfmk.s.lo.") ||
9545f757f3fSDimitry Andric              Name.starts_with("pvfmk.s.up.")) {
955e8d8bef9SDimitry Andric     bool ICC = Name[6] == 'l' || Name[6] == 'w' ? true : false;
956e8d8bef9SDimitry Andric     Mnemonic = parseCC(Name, 11, Name.size(), ICC, true, NameLoc, Operands);
9575ffd83dbSDimitry Andric   } else {
9585ffd83dbSDimitry Andric     Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc));
9595ffd83dbSDimitry Andric   }
9605ffd83dbSDimitry Andric 
9615ffd83dbSDimitry Andric   return Mnemonic;
9625ffd83dbSDimitry Andric }
9635ffd83dbSDimitry Andric 
9645ffd83dbSDimitry Andric static void applyMnemonicAliases(StringRef &Mnemonic,
9655ffd83dbSDimitry Andric                                  const FeatureBitset &Features,
9665ffd83dbSDimitry Andric                                  unsigned VariantID);
9675ffd83dbSDimitry Andric 
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)9685ffd83dbSDimitry Andric bool VEAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
9695ffd83dbSDimitry Andric                                    SMLoc NameLoc, OperandVector &Operands) {
9705ffd83dbSDimitry Andric   // If the target architecture uses MnemonicAlias, call it here to parse
9715ffd83dbSDimitry Andric   // operands correctly.
9725ffd83dbSDimitry Andric   applyMnemonicAliases(Name, getAvailableFeatures(), 0);
9735ffd83dbSDimitry Andric 
9745ffd83dbSDimitry Andric   // Split name to first token and the rest, e.g. "bgt.l.t" to "b", "gt", and
9755ffd83dbSDimitry Andric   // ".l.t".  We treat "b" as a mnemonic, "gt" as first operand, and ".l.t"
9765ffd83dbSDimitry Andric   // as second operand.
9775ffd83dbSDimitry Andric   StringRef Mnemonic = splitMnemonic(Name, NameLoc, &Operands);
9785ffd83dbSDimitry Andric 
9795ffd83dbSDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement)) {
9805ffd83dbSDimitry Andric     // Read the first operand.
9815f757f3fSDimitry Andric     if (!parseOperand(Operands, Mnemonic).isSuccess()) {
9825ffd83dbSDimitry Andric       SMLoc Loc = getLexer().getLoc();
9835ffd83dbSDimitry Andric       return Error(Loc, "unexpected token");
9845ffd83dbSDimitry Andric     }
9855ffd83dbSDimitry Andric 
9865ffd83dbSDimitry Andric     while (getLexer().is(AsmToken::Comma)) {
9875ffd83dbSDimitry Andric       Parser.Lex(); // Eat the comma.
9885ffd83dbSDimitry Andric       // Parse and remember the operand.
9895f757f3fSDimitry Andric       if (!parseOperand(Operands, Mnemonic).isSuccess()) {
9905ffd83dbSDimitry Andric         SMLoc Loc = getLexer().getLoc();
9915ffd83dbSDimitry Andric         return Error(Loc, "unexpected token");
9925ffd83dbSDimitry Andric       }
9935ffd83dbSDimitry Andric     }
9945ffd83dbSDimitry Andric   }
9955ffd83dbSDimitry Andric   if (getLexer().isNot(AsmToken::EndOfStatement)) {
9965ffd83dbSDimitry Andric     SMLoc Loc = getLexer().getLoc();
9975ffd83dbSDimitry Andric     return Error(Loc, "unexpected token");
9985ffd83dbSDimitry Andric   }
9995ffd83dbSDimitry Andric   Parser.Lex(); // Consume the EndOfStatement.
10005ffd83dbSDimitry Andric   return false;
10015ffd83dbSDimitry Andric }
10025ffd83dbSDimitry Andric 
parseDirective(AsmToken DirectiveID)100306c3fb27SDimitry Andric ParseStatus VEAsmParser::parseDirective(AsmToken DirectiveID) {
10040eae32dcSDimitry Andric   std::string IDVal = DirectiveID.getIdentifier().lower();
10050eae32dcSDimitry Andric 
10060eae32dcSDimitry Andric   // Defines VE specific directives.  Reference is "Vector Engine Assembly
10070eae32dcSDimitry Andric   // Language Reference Manual":
10080eae32dcSDimitry Andric   // https://www.hpc.nec/documents/sdk/pdfs/VectorEngine-as-manual-v1.3.pdf
10090eae32dcSDimitry Andric 
10100eae32dcSDimitry Andric   // The .word is 4 bytes long on VE.
10110eae32dcSDimitry Andric   if (IDVal == ".word")
10120eae32dcSDimitry Andric     return parseLiteralValues(4, DirectiveID.getLoc());
10130eae32dcSDimitry Andric 
10140eae32dcSDimitry Andric   // The .long is 8 bytes long on VE.
10150eae32dcSDimitry Andric   if (IDVal == ".long")
10160eae32dcSDimitry Andric     return parseLiteralValues(8, DirectiveID.getLoc());
10170eae32dcSDimitry Andric 
10180eae32dcSDimitry Andric   // The .llong is 8 bytes long on VE.
10190eae32dcSDimitry Andric   if (IDVal == ".llong")
10200eae32dcSDimitry Andric     return parseLiteralValues(8, DirectiveID.getLoc());
10210eae32dcSDimitry Andric 
10225ffd83dbSDimitry Andric   // Let the MC layer to handle other directives.
102306c3fb27SDimitry Andric   return ParseStatus::NoMatch;
10245ffd83dbSDimitry Andric }
10255ffd83dbSDimitry Andric 
10260eae32dcSDimitry Andric /// parseLiteralValues
10270eae32dcSDimitry Andric ///  ::= .word expression [, expression]*
10280eae32dcSDimitry Andric ///  ::= .long expression [, expression]*
10290eae32dcSDimitry Andric ///  ::= .llong expression [, expression]*
parseLiteralValues(unsigned Size,SMLoc L)10300eae32dcSDimitry Andric bool VEAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
10310eae32dcSDimitry Andric   auto parseOne = [&]() -> bool {
10320eae32dcSDimitry Andric     const MCExpr *Value;
10330eae32dcSDimitry Andric     if (getParser().parseExpression(Value))
10340eae32dcSDimitry Andric       return true;
10350eae32dcSDimitry Andric     getParser().getStreamer().emitValue(Value, Size, L);
10360eae32dcSDimitry Andric     return false;
10370eae32dcSDimitry Andric   };
10380eae32dcSDimitry Andric   return (parseMany(parseOne));
10390eae32dcSDimitry Andric }
10400eae32dcSDimitry Andric 
10415ffd83dbSDimitry Andric /// Extract \code @lo32/@hi32/etc \endcode modifier from expression.
10425ffd83dbSDimitry Andric /// Recursively scan the expression and check for VK_VE_HI32/LO32/etc
10435ffd83dbSDimitry Andric /// symbol variants.  If all symbols with modifier use the same
10445ffd83dbSDimitry Andric /// variant, return the corresponding VEMCExpr::VariantKind,
10455ffd83dbSDimitry Andric /// and a modified expression using the default symbol variant.
10465ffd83dbSDimitry Andric /// Otherwise, return NULL.
10475ffd83dbSDimitry Andric const MCExpr *
extractModifierFromExpr(const MCExpr * E,VEMCExpr::VariantKind & Variant)10485ffd83dbSDimitry Andric VEAsmParser::extractModifierFromExpr(const MCExpr *E,
10495ffd83dbSDimitry Andric                                      VEMCExpr::VariantKind &Variant) {
10505ffd83dbSDimitry Andric   MCContext &Context = getParser().getContext();
10515ffd83dbSDimitry Andric   Variant = VEMCExpr::VK_VE_None;
10525ffd83dbSDimitry Andric 
10535ffd83dbSDimitry Andric   switch (E->getKind()) {
10545ffd83dbSDimitry Andric   case MCExpr::Target:
10555ffd83dbSDimitry Andric   case MCExpr::Constant:
10565ffd83dbSDimitry Andric     return nullptr;
10575ffd83dbSDimitry Andric 
10585ffd83dbSDimitry Andric   case MCExpr::SymbolRef: {
10595ffd83dbSDimitry Andric     const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
10605ffd83dbSDimitry Andric 
10615ffd83dbSDimitry Andric     switch (SRE->getKind()) {
10625ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_None:
10635ffd83dbSDimitry Andric       // Use VK_VE_REFLONG to a symbol without modifiers.
10645ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_REFLONG;
10655ffd83dbSDimitry Andric       break;
10665ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_HI32:
10675ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_HI32;
10685ffd83dbSDimitry Andric       break;
10695ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_LO32:
10705ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_LO32;
10715ffd83dbSDimitry Andric       break;
10725ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_PC_HI32:
10735ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_PC_HI32;
10745ffd83dbSDimitry Andric       break;
10755ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_PC_LO32:
10765ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_PC_LO32;
10775ffd83dbSDimitry Andric       break;
10785ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_GOT_HI32:
10795ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_GOT_HI32;
10805ffd83dbSDimitry Andric       break;
10815ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_GOT_LO32:
10825ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_GOT_LO32;
10835ffd83dbSDimitry Andric       break;
10845ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_GOTOFF_HI32:
10855ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_GOTOFF_HI32;
10865ffd83dbSDimitry Andric       break;
10875ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_GOTOFF_LO32:
10885ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_GOTOFF_LO32;
10895ffd83dbSDimitry Andric       break;
10905ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_PLT_HI32:
10915ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_PLT_HI32;
10925ffd83dbSDimitry Andric       break;
10935ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_PLT_LO32:
10945ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_PLT_LO32;
10955ffd83dbSDimitry Andric       break;
10965ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_TLS_GD_HI32:
10975ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_TLS_GD_HI32;
10985ffd83dbSDimitry Andric       break;
10995ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_TLS_GD_LO32:
11005ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_TLS_GD_LO32;
11015ffd83dbSDimitry Andric       break;
11025ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_TPOFF_HI32:
11035ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_TPOFF_HI32;
11045ffd83dbSDimitry Andric       break;
11055ffd83dbSDimitry Andric     case MCSymbolRefExpr::VK_VE_TPOFF_LO32:
11065ffd83dbSDimitry Andric       Variant = VEMCExpr::VK_VE_TPOFF_LO32;
11075ffd83dbSDimitry Andric       break;
11085ffd83dbSDimitry Andric     default:
11095ffd83dbSDimitry Andric       return nullptr;
11105ffd83dbSDimitry Andric     }
11115ffd83dbSDimitry Andric 
11125ffd83dbSDimitry Andric     return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);
11135ffd83dbSDimitry Andric   }
11145ffd83dbSDimitry Andric 
11155ffd83dbSDimitry Andric   case MCExpr::Unary: {
11165ffd83dbSDimitry Andric     const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
11175ffd83dbSDimitry Andric     const MCExpr *Sub = extractModifierFromExpr(UE->getSubExpr(), Variant);
11185ffd83dbSDimitry Andric     if (!Sub)
11195ffd83dbSDimitry Andric       return nullptr;
11205ffd83dbSDimitry Andric     return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
11215ffd83dbSDimitry Andric   }
11225ffd83dbSDimitry Andric 
11235ffd83dbSDimitry Andric   case MCExpr::Binary: {
11245ffd83dbSDimitry Andric     const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
11255ffd83dbSDimitry Andric     VEMCExpr::VariantKind LHSVariant, RHSVariant;
11265ffd83dbSDimitry Andric     const MCExpr *LHS = extractModifierFromExpr(BE->getLHS(), LHSVariant);
11275ffd83dbSDimitry Andric     const MCExpr *RHS = extractModifierFromExpr(BE->getRHS(), RHSVariant);
11285ffd83dbSDimitry Andric 
11295ffd83dbSDimitry Andric     if (!LHS && !RHS)
11305ffd83dbSDimitry Andric       return nullptr;
11315ffd83dbSDimitry Andric 
11325ffd83dbSDimitry Andric     if (!LHS)
11335ffd83dbSDimitry Andric       LHS = BE->getLHS();
11345ffd83dbSDimitry Andric     if (!RHS)
11355ffd83dbSDimitry Andric       RHS = BE->getRHS();
11365ffd83dbSDimitry Andric 
11375ffd83dbSDimitry Andric     if (LHSVariant == VEMCExpr::VK_VE_None)
11385ffd83dbSDimitry Andric       Variant = RHSVariant;
11395ffd83dbSDimitry Andric     else if (RHSVariant == VEMCExpr::VK_VE_None)
11405ffd83dbSDimitry Andric       Variant = LHSVariant;
11415ffd83dbSDimitry Andric     else if (LHSVariant == RHSVariant)
11425ffd83dbSDimitry Andric       Variant = LHSVariant;
11435ffd83dbSDimitry Andric     else
11445ffd83dbSDimitry Andric       return nullptr;
11455ffd83dbSDimitry Andric 
11465ffd83dbSDimitry Andric     return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
11475ffd83dbSDimitry Andric   }
11485ffd83dbSDimitry Andric   }
11495ffd83dbSDimitry Andric 
11505ffd83dbSDimitry Andric   llvm_unreachable("Invalid expression kind!");
11515ffd83dbSDimitry Andric }
11525ffd83dbSDimitry Andric 
fixupVariantKind(const MCExpr * E)11535ffd83dbSDimitry Andric const MCExpr *VEAsmParser::fixupVariantKind(const MCExpr *E) {
11545ffd83dbSDimitry Andric   MCContext &Context = getParser().getContext();
11555ffd83dbSDimitry Andric 
11565ffd83dbSDimitry Andric   switch (E->getKind()) {
11575ffd83dbSDimitry Andric   case MCExpr::Target:
11585ffd83dbSDimitry Andric   case MCExpr::Constant:
11595ffd83dbSDimitry Andric   case MCExpr::SymbolRef:
11605ffd83dbSDimitry Andric     return E;
11615ffd83dbSDimitry Andric 
11625ffd83dbSDimitry Andric   case MCExpr::Unary: {
11635ffd83dbSDimitry Andric     const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
11645ffd83dbSDimitry Andric     const MCExpr *Sub = fixupVariantKind(UE->getSubExpr());
11655ffd83dbSDimitry Andric     if (Sub == UE->getSubExpr())
11665ffd83dbSDimitry Andric       return E;
11675ffd83dbSDimitry Andric     return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
11685ffd83dbSDimitry Andric   }
11695ffd83dbSDimitry Andric 
11705ffd83dbSDimitry Andric   case MCExpr::Binary: {
11715ffd83dbSDimitry Andric     const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
11725ffd83dbSDimitry Andric     const MCExpr *LHS = fixupVariantKind(BE->getLHS());
11735ffd83dbSDimitry Andric     const MCExpr *RHS = fixupVariantKind(BE->getRHS());
11745ffd83dbSDimitry Andric     if (LHS == BE->getLHS() && RHS == BE->getRHS())
11755ffd83dbSDimitry Andric       return E;
11765ffd83dbSDimitry Andric     return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
11775ffd83dbSDimitry Andric   }
11785ffd83dbSDimitry Andric   }
11795ffd83dbSDimitry Andric 
11805ffd83dbSDimitry Andric   llvm_unreachable("Invalid expression kind!");
11815ffd83dbSDimitry Andric }
11825ffd83dbSDimitry Andric 
11835ffd83dbSDimitry Andric /// ParseExpression.  This differs from the default "parseExpression" in that
11845ffd83dbSDimitry Andric /// it handles modifiers.
parseExpression(const MCExpr * & EVal)11855ffd83dbSDimitry Andric bool VEAsmParser::parseExpression(const MCExpr *&EVal) {
11865ffd83dbSDimitry Andric   // Handle \code symbol @lo32/@hi32/etc \endcode.
11875ffd83dbSDimitry Andric   if (getParser().parseExpression(EVal))
11885ffd83dbSDimitry Andric     return true;
11895ffd83dbSDimitry Andric 
11905ffd83dbSDimitry Andric   // Convert MCSymbolRefExpr with VK_* to MCExpr with VK_*.
11915ffd83dbSDimitry Andric   EVal = fixupVariantKind(EVal);
11925ffd83dbSDimitry Andric   VEMCExpr::VariantKind Variant;
11935ffd83dbSDimitry Andric   const MCExpr *E = extractModifierFromExpr(EVal, Variant);
11945ffd83dbSDimitry Andric   if (E)
11955ffd83dbSDimitry Andric     EVal = VEMCExpr::create(Variant, E, getParser().getContext());
11965ffd83dbSDimitry Andric 
11975ffd83dbSDimitry Andric   return false;
11985ffd83dbSDimitry Andric }
11995ffd83dbSDimitry Andric 
parseMEMOperand(OperandVector & Operands)12005f757f3fSDimitry Andric ParseStatus VEAsmParser::parseMEMOperand(OperandVector &Operands) {
12015ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "parseMEMOperand\n");
12025ffd83dbSDimitry Andric   const AsmToken &Tok = Parser.getTok();
12035ffd83dbSDimitry Andric   SMLoc S = Tok.getLoc();
12045ffd83dbSDimitry Andric   SMLoc E = Tok.getEndLoc();
12055ffd83dbSDimitry Andric   // Parse ASX format
12065ffd83dbSDimitry Andric   //   disp
12075ffd83dbSDimitry Andric   //   disp(, base)
12085ffd83dbSDimitry Andric   //   disp(index)
12095ffd83dbSDimitry Andric   //   disp(index, base)
12105ffd83dbSDimitry Andric   //   (, base)
12115ffd83dbSDimitry Andric   //   (index)
12125ffd83dbSDimitry Andric   //   (index, base)
12135ffd83dbSDimitry Andric 
12145ffd83dbSDimitry Andric   std::unique_ptr<VEOperand> Offset;
12155ffd83dbSDimitry Andric   switch (getLexer().getKind()) {
12165ffd83dbSDimitry Andric   default:
12175f757f3fSDimitry Andric     return ParseStatus::NoMatch;
12185ffd83dbSDimitry Andric 
12195ffd83dbSDimitry Andric   case AsmToken::Minus:
12205ffd83dbSDimitry Andric   case AsmToken::Integer:
12215ffd83dbSDimitry Andric   case AsmToken::Dot:
12225ffd83dbSDimitry Andric   case AsmToken::Identifier: {
12235ffd83dbSDimitry Andric     const MCExpr *EVal;
12245ffd83dbSDimitry Andric     if (!parseExpression(EVal))
12255ffd83dbSDimitry Andric       Offset = VEOperand::CreateImm(EVal, S, E);
12265ffd83dbSDimitry Andric     else
12275f757f3fSDimitry Andric       return ParseStatus::NoMatch;
12285ffd83dbSDimitry Andric     break;
12295ffd83dbSDimitry Andric   }
12305ffd83dbSDimitry Andric 
12315ffd83dbSDimitry Andric   case AsmToken::LParen:
12325ffd83dbSDimitry Andric     // empty disp (= 0)
12335ffd83dbSDimitry Andric     Offset =
12345ffd83dbSDimitry Andric         VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E);
12355ffd83dbSDimitry Andric     break;
12365ffd83dbSDimitry Andric   }
12375ffd83dbSDimitry Andric 
12385ffd83dbSDimitry Andric   switch (getLexer().getKind()) {
12395ffd83dbSDimitry Andric   default:
12405f757f3fSDimitry Andric     return ParseStatus::Failure;
12415ffd83dbSDimitry Andric 
12425ffd83dbSDimitry Andric   case AsmToken::EndOfStatement:
12435ffd83dbSDimitry Andric     Operands.push_back(VEOperand::MorphToMEMzii(
12445ffd83dbSDimitry Andric         MCConstantExpr::create(0, getContext()), std::move(Offset)));
12455f757f3fSDimitry Andric     return ParseStatus::Success;
12465ffd83dbSDimitry Andric 
12475ffd83dbSDimitry Andric   case AsmToken::LParen:
12485ffd83dbSDimitry Andric     Parser.Lex(); // Eat the (
12495ffd83dbSDimitry Andric     break;
12505ffd83dbSDimitry Andric   }
12515ffd83dbSDimitry Andric 
12525ffd83dbSDimitry Andric   const MCExpr *IndexValue = nullptr;
1253bdd1243dSDimitry Andric   MCRegister IndexReg;
12545ffd83dbSDimitry Andric 
12555ffd83dbSDimitry Andric   switch (getLexer().getKind()) {
12565ffd83dbSDimitry Andric   default:
1257bdd1243dSDimitry Andric     if (parseRegister(IndexReg, S, E))
12585f757f3fSDimitry Andric       return ParseStatus::Failure;
12595ffd83dbSDimitry Andric     break;
12605ffd83dbSDimitry Andric 
12615ffd83dbSDimitry Andric   case AsmToken::Minus:
12625ffd83dbSDimitry Andric   case AsmToken::Integer:
12635ffd83dbSDimitry Andric   case AsmToken::Dot:
12645ffd83dbSDimitry Andric     if (getParser().parseExpression(IndexValue, E))
12655f757f3fSDimitry Andric       return ParseStatus::Failure;
12665ffd83dbSDimitry Andric     break;
12675ffd83dbSDimitry Andric 
12685ffd83dbSDimitry Andric   case AsmToken::Comma:
12695ffd83dbSDimitry Andric     // empty index
12705ffd83dbSDimitry Andric     IndexValue = MCConstantExpr::create(0, getContext());
12715ffd83dbSDimitry Andric     break;
12725ffd83dbSDimitry Andric   }
12735ffd83dbSDimitry Andric 
12745ffd83dbSDimitry Andric   switch (getLexer().getKind()) {
12755ffd83dbSDimitry Andric   default:
12765f757f3fSDimitry Andric     return ParseStatus::Failure;
12775ffd83dbSDimitry Andric 
12785ffd83dbSDimitry Andric   case AsmToken::RParen:
12795ffd83dbSDimitry Andric     Parser.Lex(); // Eat the )
12805ffd83dbSDimitry Andric     Operands.push_back(
12815ffd83dbSDimitry Andric         IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(Offset))
12825ffd83dbSDimitry Andric                    : VEOperand::MorphToMEMzri(IndexReg, std::move(Offset)));
12835f757f3fSDimitry Andric     return ParseStatus::Success;
12845ffd83dbSDimitry Andric 
12855ffd83dbSDimitry Andric   case AsmToken::Comma:
12865ffd83dbSDimitry Andric     Parser.Lex(); // Eat the ,
12875ffd83dbSDimitry Andric     break;
12885ffd83dbSDimitry Andric   }
12895ffd83dbSDimitry Andric 
1290bdd1243dSDimitry Andric   MCRegister BaseReg;
1291bdd1243dSDimitry Andric   if (parseRegister(BaseReg, S, E))
12925f757f3fSDimitry Andric     return ParseStatus::Failure;
12935ffd83dbSDimitry Andric 
12945ffd83dbSDimitry Andric   if (!Parser.getTok().is(AsmToken::RParen))
12955f757f3fSDimitry Andric     return ParseStatus::Failure;
12965ffd83dbSDimitry Andric 
12975ffd83dbSDimitry Andric   Parser.Lex(); // Eat the )
12985ffd83dbSDimitry Andric   Operands.push_back(
12995ffd83dbSDimitry Andric       IndexValue
13005ffd83dbSDimitry Andric           ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(Offset))
13015ffd83dbSDimitry Andric           : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(Offset)));
13025ffd83dbSDimitry Andric 
13035f757f3fSDimitry Andric   return ParseStatus::Success;
13045ffd83dbSDimitry Andric }
13055ffd83dbSDimitry Andric 
parseMEMAsOperand(OperandVector & Operands)13065f757f3fSDimitry Andric ParseStatus VEAsmParser::parseMEMAsOperand(OperandVector &Operands) {
13075ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "parseMEMAsOperand\n");
13085ffd83dbSDimitry Andric   const AsmToken &Tok = Parser.getTok();
13095ffd83dbSDimitry Andric   SMLoc S = Tok.getLoc();
13105ffd83dbSDimitry Andric   SMLoc E = Tok.getEndLoc();
13115ffd83dbSDimitry Andric   // Parse AS format
13125ffd83dbSDimitry Andric   //   disp
13135ffd83dbSDimitry Andric   //   disp(, base)
13145ffd83dbSDimitry Andric   //   disp(base)
13155ffd83dbSDimitry Andric   //   disp()
13165ffd83dbSDimitry Andric   //   (, base)
13175ffd83dbSDimitry Andric   //   (base)
13185ffd83dbSDimitry Andric   //   base
13195ffd83dbSDimitry Andric 
1320bdd1243dSDimitry Andric   MCRegister BaseReg;
13215ffd83dbSDimitry Andric   std::unique_ptr<VEOperand> Offset;
13225ffd83dbSDimitry Andric   switch (getLexer().getKind()) {
13235ffd83dbSDimitry Andric   default:
13245f757f3fSDimitry Andric     return ParseStatus::NoMatch;
13255ffd83dbSDimitry Andric 
13265ffd83dbSDimitry Andric   case AsmToken::Minus:
13275ffd83dbSDimitry Andric   case AsmToken::Integer:
13285ffd83dbSDimitry Andric   case AsmToken::Dot:
13295ffd83dbSDimitry Andric   case AsmToken::Identifier: {
13305ffd83dbSDimitry Andric     const MCExpr *EVal;
13315ffd83dbSDimitry Andric     if (!parseExpression(EVal))
13325ffd83dbSDimitry Andric       Offset = VEOperand::CreateImm(EVal, S, E);
13335ffd83dbSDimitry Andric     else
13345f757f3fSDimitry Andric       return ParseStatus::NoMatch;
13355ffd83dbSDimitry Andric     break;
13365ffd83dbSDimitry Andric   }
13375ffd83dbSDimitry Andric 
13385ffd83dbSDimitry Andric   case AsmToken::Percent:
1339bdd1243dSDimitry Andric     if (parseRegister(BaseReg, S, E))
13405f757f3fSDimitry Andric       return ParseStatus::NoMatch;
13415ffd83dbSDimitry Andric     Offset =
13425ffd83dbSDimitry Andric         VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E);
13435ffd83dbSDimitry Andric     break;
13445ffd83dbSDimitry Andric 
13455ffd83dbSDimitry Andric   case AsmToken::LParen:
13465ffd83dbSDimitry Andric     // empty disp (= 0)
13475ffd83dbSDimitry Andric     Offset =
13485ffd83dbSDimitry Andric         VEOperand::CreateImm(MCConstantExpr::create(0, getContext()), S, E);
13495ffd83dbSDimitry Andric     break;
13505ffd83dbSDimitry Andric   }
13515ffd83dbSDimitry Andric 
13525ffd83dbSDimitry Andric   switch (getLexer().getKind()) {
13535ffd83dbSDimitry Andric   default:
13545f757f3fSDimitry Andric     return ParseStatus::Failure;
13555ffd83dbSDimitry Andric 
13565ffd83dbSDimitry Andric   case AsmToken::EndOfStatement:
13575ffd83dbSDimitry Andric   case AsmToken::Comma:
13585ffd83dbSDimitry Andric     Operands.push_back(BaseReg != VE::NoRegister
13595ffd83dbSDimitry Andric                            ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset))
13605ffd83dbSDimitry Andric                            : VEOperand::MorphToMEMzi(std::move(Offset)));
13615f757f3fSDimitry Andric     return ParseStatus::Success;
13625ffd83dbSDimitry Andric 
13635ffd83dbSDimitry Andric   case AsmToken::LParen:
13645ffd83dbSDimitry Andric     if (BaseReg != VE::NoRegister)
13655f757f3fSDimitry Andric       return ParseStatus::Failure;
13665ffd83dbSDimitry Andric     Parser.Lex(); // Eat the (
13675ffd83dbSDimitry Andric     break;
13685ffd83dbSDimitry Andric   }
13695ffd83dbSDimitry Andric 
13705ffd83dbSDimitry Andric   switch (getLexer().getKind()) {
13715ffd83dbSDimitry Andric   default:
1372bdd1243dSDimitry Andric     if (parseRegister(BaseReg, S, E))
13735f757f3fSDimitry Andric       return ParseStatus::Failure;
13745ffd83dbSDimitry Andric     break;
13755ffd83dbSDimitry Andric 
13765ffd83dbSDimitry Andric   case AsmToken::Comma:
13775ffd83dbSDimitry Andric     Parser.Lex(); // Eat the ,
1378bdd1243dSDimitry Andric     if (parseRegister(BaseReg, S, E))
13795f757f3fSDimitry Andric       return ParseStatus::Failure;
13805ffd83dbSDimitry Andric     break;
13815ffd83dbSDimitry Andric 
13825ffd83dbSDimitry Andric   case AsmToken::RParen:
13835ffd83dbSDimitry Andric     break;
13845ffd83dbSDimitry Andric   }
13855ffd83dbSDimitry Andric 
13865ffd83dbSDimitry Andric   if (!Parser.getTok().is(AsmToken::RParen))
13875f757f3fSDimitry Andric     return ParseStatus::Failure;
13885ffd83dbSDimitry Andric 
13895ffd83dbSDimitry Andric   Parser.Lex(); // Eat the )
13905ffd83dbSDimitry Andric   Operands.push_back(BaseReg != VE::NoRegister
13915ffd83dbSDimitry Andric                          ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset))
13925ffd83dbSDimitry Andric                          : VEOperand::MorphToMEMzi(std::move(Offset)));
13935ffd83dbSDimitry Andric 
13945f757f3fSDimitry Andric   return ParseStatus::Success;
13955ffd83dbSDimitry Andric }
13965ffd83dbSDimitry Andric 
parseMImmOperand(OperandVector & Operands)13975f757f3fSDimitry Andric ParseStatus VEAsmParser::parseMImmOperand(OperandVector &Operands) {
13985ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "parseMImmOperand\n");
13995ffd83dbSDimitry Andric 
14005ffd83dbSDimitry Andric   // Parsing "(" + number + ")0/1"
14015ffd83dbSDimitry Andric   const AsmToken Tok1 = Parser.getTok();
14025ffd83dbSDimitry Andric   if (!Tok1.is(AsmToken::LParen))
14035f757f3fSDimitry Andric     return ParseStatus::NoMatch;
14045ffd83dbSDimitry Andric 
14055ffd83dbSDimitry Andric   Parser.Lex(); // Eat the '('.
14065ffd83dbSDimitry Andric 
14075ffd83dbSDimitry Andric   const AsmToken Tok2 = Parser.getTok();
14085ffd83dbSDimitry Andric   SMLoc E;
14095ffd83dbSDimitry Andric   const MCExpr *EVal;
14105ffd83dbSDimitry Andric   if (!Tok2.is(AsmToken::Integer) || getParser().parseExpression(EVal, E)) {
14115ffd83dbSDimitry Andric     getLexer().UnLex(Tok1);
14125f757f3fSDimitry Andric     return ParseStatus::NoMatch;
14135ffd83dbSDimitry Andric   }
14145ffd83dbSDimitry Andric 
14155ffd83dbSDimitry Andric   const AsmToken Tok3 = Parser.getTok();
14165ffd83dbSDimitry Andric   if (!Tok3.is(AsmToken::RParen)) {
14175ffd83dbSDimitry Andric     getLexer().UnLex(Tok2);
14185ffd83dbSDimitry Andric     getLexer().UnLex(Tok1);
14195f757f3fSDimitry Andric     return ParseStatus::NoMatch;
14205ffd83dbSDimitry Andric   }
14215ffd83dbSDimitry Andric   Parser.Lex(); // Eat the ')'.
14225ffd83dbSDimitry Andric 
14235ffd83dbSDimitry Andric   const AsmToken &Tok4 = Parser.getTok();
14245ffd83dbSDimitry Andric   StringRef Suffix = Tok4.getString();
14255ffd83dbSDimitry Andric   if (Suffix != "1" && Suffix != "0") {
14265ffd83dbSDimitry Andric     getLexer().UnLex(Tok3);
14275ffd83dbSDimitry Andric     getLexer().UnLex(Tok2);
14285ffd83dbSDimitry Andric     getLexer().UnLex(Tok1);
14295f757f3fSDimitry Andric     return ParseStatus::NoMatch;
14305ffd83dbSDimitry Andric   }
14315ffd83dbSDimitry Andric   Parser.Lex(); // Eat the value.
14325ffd83dbSDimitry Andric   SMLoc EndLoc = SMLoc::getFromPointer(Suffix.end());
14335ffd83dbSDimitry Andric   Operands.push_back(
14345ffd83dbSDimitry Andric       VEOperand::CreateMImm(EVal, Suffix == "0", Tok1.getLoc(), EndLoc));
14355f757f3fSDimitry Andric   return ParseStatus::Success;
14365ffd83dbSDimitry Andric }
14375ffd83dbSDimitry Andric 
parseOperand(OperandVector & Operands,StringRef Mnemonic)14385f757f3fSDimitry Andric ParseStatus VEAsmParser::parseOperand(OperandVector &Operands,
14395ffd83dbSDimitry Andric                                       StringRef Mnemonic) {
14405ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "parseOperand\n");
14415f757f3fSDimitry Andric   ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
14425ffd83dbSDimitry Andric 
14435ffd83dbSDimitry Andric   // If there wasn't a custom match, try the generic matcher below. Otherwise,
14445ffd83dbSDimitry Andric   // there was a match, but an error occurred, in which case, just return that
14455ffd83dbSDimitry Andric   // the operand parsing failed.
14465f757f3fSDimitry Andric   if (Res.isSuccess() || Res.isFailure())
14475f757f3fSDimitry Andric     return Res;
14485ffd83dbSDimitry Andric 
14495ffd83dbSDimitry Andric   switch (getLexer().getKind()) {
1450e8d8bef9SDimitry Andric   case AsmToken::LParen: {
1451e8d8bef9SDimitry Andric     // Parsing "(" + %vreg + ", " + %vreg + ")"
1452e8d8bef9SDimitry Andric     const AsmToken Tok1 = Parser.getTok();
1453e8d8bef9SDimitry Andric     Parser.Lex(); // Eat the '('.
1454e8d8bef9SDimitry Andric 
14555f757f3fSDimitry Andric     MCRegister Reg1;
1456e8d8bef9SDimitry Andric     SMLoc S1, E1;
14575f757f3fSDimitry Andric     if (!tryParseRegister(Reg1, S1, E1).isSuccess()) {
1458e8d8bef9SDimitry Andric       getLexer().UnLex(Tok1);
14595f757f3fSDimitry Andric       return ParseStatus::NoMatch;
1460e8d8bef9SDimitry Andric     }
1461e8d8bef9SDimitry Andric 
1462e8d8bef9SDimitry Andric     if (!Parser.getTok().is(AsmToken::Comma))
14635f757f3fSDimitry Andric       return ParseStatus::Failure;
1464e8d8bef9SDimitry Andric     Parser.Lex(); // Eat the ','.
1465e8d8bef9SDimitry Andric 
14665f757f3fSDimitry Andric     MCRegister Reg2;
1467e8d8bef9SDimitry Andric     SMLoc S2, E2;
14685f757f3fSDimitry Andric     if (!tryParseRegister(Reg2, S2, E2).isSuccess())
14695f757f3fSDimitry Andric       return ParseStatus::Failure;
1470e8d8bef9SDimitry Andric 
1471e8d8bef9SDimitry Andric     if (!Parser.getTok().is(AsmToken::RParen))
14725f757f3fSDimitry Andric       return ParseStatus::Failure;
1473e8d8bef9SDimitry Andric 
1474e8d8bef9SDimitry Andric     Operands.push_back(VEOperand::CreateToken(Tok1.getString(), Tok1.getLoc()));
14755f757f3fSDimitry Andric     Operands.push_back(VEOperand::CreateReg(Reg1, S1, E1));
14765f757f3fSDimitry Andric     Operands.push_back(VEOperand::CreateReg(Reg2, S2, E2));
1477e8d8bef9SDimitry Andric     Operands.push_back(VEOperand::CreateToken(Parser.getTok().getString(),
1478e8d8bef9SDimitry Andric                                               Parser.getTok().getLoc()));
1479e8d8bef9SDimitry Andric     Parser.Lex(); // Eat the ')'.
1480e8d8bef9SDimitry Andric     break;
1481e8d8bef9SDimitry Andric   }
14825ffd83dbSDimitry Andric   default: {
14835ffd83dbSDimitry Andric     std::unique_ptr<VEOperand> Op;
14845f757f3fSDimitry Andric     Res = parseVEAsmOperand(Op);
14855f757f3fSDimitry Andric     if (!Res.isSuccess() || !Op)
14865f757f3fSDimitry Andric       return ParseStatus::Failure;
14875ffd83dbSDimitry Andric 
14885ffd83dbSDimitry Andric     // Push the parsed operand into the list of operands
14895ffd83dbSDimitry Andric     Operands.push_back(std::move(Op));
14905ffd83dbSDimitry Andric 
14915ffd83dbSDimitry Andric     if (!Parser.getTok().is(AsmToken::LParen))
14925ffd83dbSDimitry Andric       break;
14935ffd83dbSDimitry Andric 
1494e8d8bef9SDimitry Andric     // Parsing %vec-reg + "(" + %sclar-reg/number + ")"
1495e8d8bef9SDimitry Andric     std::unique_ptr<VEOperand> Op1 = VEOperand::CreateToken(
1496e8d8bef9SDimitry Andric         Parser.getTok().getString(), Parser.getTok().getLoc());
1497e8d8bef9SDimitry Andric     Parser.Lex(); // Eat the '('.
1498e8d8bef9SDimitry Andric 
1499e8d8bef9SDimitry Andric     std::unique_ptr<VEOperand> Op2;
15005f757f3fSDimitry Andric     Res = parseVEAsmOperand(Op2);
15015f757f3fSDimitry Andric     if (!Res.isSuccess() || !Op2)
15025f757f3fSDimitry Andric       return ParseStatus::Failure;
1503e8d8bef9SDimitry Andric 
1504e8d8bef9SDimitry Andric     if (!Parser.getTok().is(AsmToken::RParen))
15055f757f3fSDimitry Andric       return ParseStatus::Failure;
1506e8d8bef9SDimitry Andric 
1507e8d8bef9SDimitry Andric     Operands.push_back(std::move(Op1));
1508e8d8bef9SDimitry Andric     Operands.push_back(std::move(Op2));
1509e8d8bef9SDimitry Andric     Operands.push_back(VEOperand::CreateToken(Parser.getTok().getString(),
1510e8d8bef9SDimitry Andric                                               Parser.getTok().getLoc()));
1511e8d8bef9SDimitry Andric     Parser.Lex(); // Eat the ')'.
15125ffd83dbSDimitry Andric     break;
15135ffd83dbSDimitry Andric   }
15145ffd83dbSDimitry Andric   }
15155ffd83dbSDimitry Andric 
15165f757f3fSDimitry Andric   return ParseStatus::Success;
15175ffd83dbSDimitry Andric }
15185ffd83dbSDimitry Andric 
parseVEAsmOperand(std::unique_ptr<VEOperand> & Op)15195f757f3fSDimitry Andric ParseStatus VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &Op) {
15205ffd83dbSDimitry Andric   LLVM_DEBUG(dbgs() << "parseVEAsmOperand\n");
15215ffd83dbSDimitry Andric   SMLoc S = Parser.getTok().getLoc();
15225ffd83dbSDimitry Andric   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
15235ffd83dbSDimitry Andric   const MCExpr *EVal;
15245ffd83dbSDimitry Andric 
15255ffd83dbSDimitry Andric   Op = nullptr;
15265ffd83dbSDimitry Andric   switch (getLexer().getKind()) {
15275ffd83dbSDimitry Andric   default:
15285ffd83dbSDimitry Andric     break;
15295ffd83dbSDimitry Andric 
1530bdd1243dSDimitry Andric   case AsmToken::Percent: {
15315f757f3fSDimitry Andric     MCRegister Reg;
15325f757f3fSDimitry Andric     if (tryParseRegister(Reg, S, E).isSuccess())
15335f757f3fSDimitry Andric       Op = VEOperand::CreateReg(Reg, S, E);
15345ffd83dbSDimitry Andric     break;
1535bdd1243dSDimitry Andric   }
15365ffd83dbSDimitry Andric   case AsmToken::Minus:
15375ffd83dbSDimitry Andric   case AsmToken::Integer:
15385ffd83dbSDimitry Andric   case AsmToken::Dot:
15395ffd83dbSDimitry Andric   case AsmToken::Identifier:
15405ffd83dbSDimitry Andric     if (!parseExpression(EVal))
15415ffd83dbSDimitry Andric       Op = VEOperand::CreateImm(EVal, S, E);
15425ffd83dbSDimitry Andric     break;
15435ffd83dbSDimitry Andric   }
15445f757f3fSDimitry Andric   return Op ? ParseStatus::Success : ParseStatus::Failure;
15455ffd83dbSDimitry Andric }
15465ffd83dbSDimitry Andric 
15475ffd83dbSDimitry Andric // Force static initialization.
LLVMInitializeVEAsmParser()15485ffd83dbSDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser() {
15495ffd83dbSDimitry Andric   RegisterMCAsmParser<VEAsmParser> A(getTheVETarget());
15505ffd83dbSDimitry Andric }
15515ffd83dbSDimitry Andric 
15525ffd83dbSDimitry Andric #define GET_REGISTER_MATCHER
15535ffd83dbSDimitry Andric #define GET_MATCHER_IMPLEMENTATION
15545ffd83dbSDimitry Andric #include "VEGenAsmMatcher.inc"
15555ffd83dbSDimitry Andric 
validateTargetOperandClass(MCParsedAsmOperand & GOp,unsigned Kind)15565ffd83dbSDimitry Andric unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
15575ffd83dbSDimitry Andric                                                  unsigned Kind) {
15585ffd83dbSDimitry Andric   VEOperand &Op = (VEOperand &)GOp;
15595ffd83dbSDimitry Andric 
15605ffd83dbSDimitry Andric   // VE uses identical register name for all registers like both
15615ffd83dbSDimitry Andric   // F32 and I32 uses "%s23".  Need to convert the name of them
15625ffd83dbSDimitry Andric   // for validation.
15635ffd83dbSDimitry Andric   switch (Kind) {
15645ffd83dbSDimitry Andric   default:
15655ffd83dbSDimitry Andric     break;
15665ffd83dbSDimitry Andric   case MCK_F32:
15675ffd83dbSDimitry Andric     if (Op.isReg() && VEOperand::MorphToF32Reg(Op))
15685ffd83dbSDimitry Andric       return MCTargetAsmParser::Match_Success;
15695ffd83dbSDimitry Andric     break;
15705ffd83dbSDimitry Andric   case MCK_I32:
15715ffd83dbSDimitry Andric     if (Op.isReg() && VEOperand::MorphToI32Reg(Op))
15725ffd83dbSDimitry Andric       return MCTargetAsmParser::Match_Success;
15735ffd83dbSDimitry Andric     break;
15745ffd83dbSDimitry Andric   case MCK_F128:
15755ffd83dbSDimitry Andric     if (Op.isReg() && VEOperand::MorphToF128Reg(Op))
15765ffd83dbSDimitry Andric       return MCTargetAsmParser::Match_Success;
15775ffd83dbSDimitry Andric     break;
1578e8d8bef9SDimitry Andric   case MCK_VM512:
1579e8d8bef9SDimitry Andric     if (Op.isReg() && VEOperand::MorphToVM512Reg(Op))
1580e8d8bef9SDimitry Andric       return MCTargetAsmParser::Match_Success;
1581e8d8bef9SDimitry Andric     break;
15825ffd83dbSDimitry Andric   case MCK_MISC:
15835ffd83dbSDimitry Andric     if (Op.isImm() && VEOperand::MorphToMISCReg(Op))
15845ffd83dbSDimitry Andric       return MCTargetAsmParser::Match_Success;
15855ffd83dbSDimitry Andric     break;
15865ffd83dbSDimitry Andric   }
15875ffd83dbSDimitry Andric   return Match_InvalidOperand;
15885ffd83dbSDimitry Andric }
1589