Home | History | Annotate | Line # | Download | only in AsmParser
      1 //===-- HexagonAsmParser.cpp - Parse Hexagon asm to MCInst instructions----===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #define DEBUG_TYPE "mcasmparser"
     10 
     11 #include "HexagonTargetStreamer.h"
     12 #include "MCTargetDesc/HexagonMCChecker.h"
     13 #include "MCTargetDesc/HexagonMCELFStreamer.h"
     14 #include "MCTargetDesc/HexagonMCExpr.h"
     15 #include "MCTargetDesc/HexagonMCInstrInfo.h"
     16 #include "MCTargetDesc/HexagonMCTargetDesc.h"
     17 #include "MCTargetDesc/HexagonShuffler.h"
     18 #include "TargetInfo/HexagonTargetInfo.h"
     19 #include "llvm/ADT/STLExtras.h"
     20 #include "llvm/ADT/SmallVector.h"
     21 #include "llvm/ADT/StringExtras.h"
     22 #include "llvm/ADT/StringRef.h"
     23 #include "llvm/ADT/Twine.h"
     24 #include "llvm/BinaryFormat/ELF.h"
     25 #include "llvm/MC/MCAssembler.h"
     26 #include "llvm/MC/MCContext.h"
     27 #include "llvm/MC/MCDirectives.h"
     28 #include "llvm/MC/MCELFStreamer.h"
     29 #include "llvm/MC/MCExpr.h"
     30 #include "llvm/MC/MCInst.h"
     31 #include "llvm/MC/MCParser/MCAsmLexer.h"
     32 #include "llvm/MC/MCParser/MCAsmParser.h"
     33 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
     34 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
     35 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
     36 #include "llvm/MC/MCRegisterInfo.h"
     37 #include "llvm/MC/MCSectionELF.h"
     38 #include "llvm/MC/MCStreamer.h"
     39 #include "llvm/MC/MCSubtargetInfo.h"
     40 #include "llvm/MC/MCSymbol.h"
     41 #include "llvm/MC/MCValue.h"
     42 #include "llvm/Support/Casting.h"
     43 #include "llvm/Support/CommandLine.h"
     44 #include "llvm/Support/Debug.h"
     45 #include "llvm/Support/ErrorHandling.h"
     46 #include "llvm/Support/Format.h"
     47 #include "llvm/Support/MathExtras.h"
     48 #include "llvm/Support/SMLoc.h"
     49 #include "llvm/Support/SourceMgr.h"
     50 #include "llvm/Support/TargetRegistry.h"
     51 #include "llvm/Support/raw_ostream.h"
     52 #include <algorithm>
     53 #include <cassert>
     54 #include <cctype>
     55 #include <cstddef>
     56 #include <cstdint>
     57 #include <memory>
     58 #include <string>
     59 #include <utility>
     60 
     61 using namespace llvm;
     62 
     63 static cl::opt<bool> WarnMissingParenthesis(
     64     "mwarn-missing-parenthesis",
     65     cl::desc("Warn for missing parenthesis around predicate registers"),
     66     cl::init(true));
     67 static cl::opt<bool> ErrorMissingParenthesis(
     68     "merror-missing-parenthesis",
     69     cl::desc("Error for missing parenthesis around predicate registers"),
     70     cl::init(false));
     71 static cl::opt<bool> WarnSignedMismatch(
     72     "mwarn-sign-mismatch",
     73     cl::desc("Warn for mismatching a signed and unsigned value"),
     74     cl::init(true));
     75 static cl::opt<bool> WarnNoncontigiousRegister(
     76     "mwarn-noncontigious-register",
     77     cl::desc("Warn for register names that arent contigious"), cl::init(true));
     78 static cl::opt<bool> ErrorNoncontigiousRegister(
     79     "merror-noncontigious-register",
     80     cl::desc("Error for register names that aren't contigious"),
     81     cl::init(false));
     82 
     83 namespace {
     84 
     85 struct HexagonOperand;
     86 
     87 class HexagonAsmParser : public MCTargetAsmParser {
     88 
     89   HexagonTargetStreamer &getTargetStreamer() {
     90     MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
     91     return static_cast<HexagonTargetStreamer &>(TS);
     92   }
     93 
     94   MCAsmParser &Parser;
     95   MCInst MCB;
     96   bool InBrackets;
     97 
     98   MCAsmParser &getParser() const { return Parser; }
     99   MCAssembler *getAssembler() const {
    100     MCAssembler *Assembler = nullptr;
    101     // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
    102     if (!Parser.getStreamer().hasRawTextSupport()) {
    103       MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
    104       Assembler = &MES->getAssembler();
    105     }
    106     return Assembler;
    107   }
    108 
    109   MCAsmLexer &getLexer() const { return Parser.getLexer(); }
    110 
    111   bool equalIsAsmAssignment() override { return false; }
    112   bool isLabel(AsmToken &Token) override;
    113 
    114   void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
    115   bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
    116   bool ParseDirectiveFalign(unsigned Size, SMLoc L);
    117 
    118   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
    119   OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
    120                                         SMLoc &EndLoc) override;
    121   bool ParseDirectiveSubsection(SMLoc L);
    122   bool ParseDirectiveComm(bool IsLocal, SMLoc L);
    123   bool RegisterMatchesArch(unsigned MatchNum) const;
    124 
    125   bool matchBundleOptions();
    126   bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);
    127   bool finishBundle(SMLoc IDLoc, MCStreamer &Out);
    128   void canonicalizeImmediates(MCInst &MCI);
    129   bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,
    130                            OperandVector &InstOperands, uint64_t &ErrorInfo,
    131                            bool MatchingInlineAsm);
    132   void eatToEndOfPacket();
    133   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
    134                                OperandVector &Operands, MCStreamer &Out,
    135                                uint64_t &ErrorInfo,
    136                                bool MatchingInlineAsm) override;
    137 
    138   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
    139                                       unsigned Kind) override;
    140   bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
    141   int processInstruction(MCInst &Inst, OperandVector const &Operands,
    142                          SMLoc IDLoc);
    143 
    144   // Check if we have an assembler and, if so, set the ELF e_header flags.
    145   void chksetELFHeaderEFlags(unsigned flags) {
    146     if (getAssembler())
    147       getAssembler()->setELFHeaderEFlags(flags);
    148   }
    149 
    150   unsigned matchRegister(StringRef Name);
    151 
    152 /// @name Auto-generated Match Functions
    153 /// {
    154 
    155 #define GET_ASSEMBLER_HEADER
    156 #include "HexagonGenAsmMatcher.inc"
    157 
    158   /// }
    159 
    160 public:
    161   HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,
    162                    const MCInstrInfo &MII, const MCTargetOptions &Options)
    163     : MCTargetAsmParser(Options, _STI, MII), Parser(_Parser),
    164       InBrackets(false) {
    165     MCB.setOpcode(Hexagon::BUNDLE);
    166     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
    167 
    168     Parser.addAliasForDirective(".half", ".2byte");
    169     Parser.addAliasForDirective(".hword", ".2byte");
    170     Parser.addAliasForDirective(".word", ".4byte");
    171 
    172     MCAsmParserExtension::Initialize(_Parser);
    173   }
    174 
    175   bool splitIdentifier(OperandVector &Operands);
    176   bool parseOperand(OperandVector &Operands);
    177   bool parseInstruction(OperandVector &Operands);
    178   bool implicitExpressionLocation(OperandVector &Operands);
    179   bool parseExpressionOrOperand(OperandVector &Operands);
    180   bool parseExpression(MCExpr const *&Expr);
    181 
    182   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
    183                         SMLoc NameLoc, OperandVector &Operands) override {
    184     llvm_unreachable("Unimplemented");
    185   }
    186 
    187   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
    188                         OperandVector &Operands) override;
    189 
    190   bool ParseDirective(AsmToken DirectiveID) override;
    191 };
    192 
    193 /// HexagonOperand - Instances of this class represent a parsed Hexagon machine
    194 /// instruction.
    195 struct HexagonOperand : public MCParsedAsmOperand {
    196   enum KindTy { Token, Immediate, Register } Kind;
    197   MCContext &Context;
    198 
    199   SMLoc StartLoc, EndLoc;
    200 
    201   struct TokTy {
    202     const char *Data;
    203     unsigned Length;
    204   };
    205 
    206   struct RegTy {
    207     unsigned RegNum;
    208   };
    209 
    210   struct ImmTy {
    211     const MCExpr *Val;
    212   };
    213 
    214   struct InstTy {
    215     OperandVector *SubInsts;
    216   };
    217 
    218   union {
    219     struct TokTy Tok;
    220     struct RegTy Reg;
    221     struct ImmTy Imm;
    222   };
    223 
    224   HexagonOperand(KindTy K, MCContext &Context)
    225       : MCParsedAsmOperand(), Kind(K), Context(Context) {}
    226 
    227 public:
    228   HexagonOperand(const HexagonOperand &o)
    229       : MCParsedAsmOperand(), Context(o.Context) {
    230     Kind = o.Kind;
    231     StartLoc = o.StartLoc;
    232     EndLoc = o.EndLoc;
    233     switch (Kind) {
    234     case Register:
    235       Reg = o.Reg;
    236       break;
    237     case Immediate:
    238       Imm = o.Imm;
    239       break;
    240     case Token:
    241       Tok = o.Tok;
    242       break;
    243     }
    244   }
    245 
    246   /// getStartLoc - Get the location of the first token of this operand.
    247   SMLoc getStartLoc() const override { return StartLoc; }
    248 
    249   /// getEndLoc - Get the location of the last token of this operand.
    250   SMLoc getEndLoc() const override { return EndLoc; }
    251 
    252   unsigned getReg() const override {
    253     assert(Kind == Register && "Invalid access!");
    254     return Reg.RegNum;
    255   }
    256 
    257   const MCExpr *getImm() const {
    258     assert(Kind == Immediate && "Invalid access!");
    259     return Imm.Val;
    260   }
    261 
    262   bool isToken() const override { return Kind == Token; }
    263   bool isImm() const override { return Kind == Immediate; }
    264   bool isMem() const override { llvm_unreachable("No isMem"); }
    265   bool isReg() const override { return Kind == Register; }
    266 
    267   bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
    268                      bool isRelocatable, bool Extendable) const {
    269     if (Kind == Immediate) {
    270       const MCExpr *myMCExpr = &HexagonMCInstrInfo::getExpr(*getImm());
    271       if (HexagonMCInstrInfo::mustExtend(*Imm.Val) && !Extendable)
    272         return false;
    273       int64_t Res;
    274       if (myMCExpr->evaluateAsAbsolute(Res)) {
    275         int bits = immBits + zeroBits;
    276         // Field bit range is zerobits + bits
    277         // zeroBits must be 0
    278         if (Res & ((1 << zeroBits) - 1))
    279           return false;
    280         if (isSigned) {
    281           if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
    282             return true;
    283         } else {
    284           if (bits == 64)
    285             return true;
    286           if (Res >= 0)
    287             return ((uint64_t)Res < (uint64_t)(1ULL << bits));
    288           else {
    289             const int64_t high_bit_set = 1ULL << 63;
    290             const uint64_t mask = (high_bit_set >> (63 - bits));
    291             return (((uint64_t)Res & mask) == mask);
    292           }
    293         }
    294       } else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)
    295         return true;
    296       else if (myMCExpr->getKind() == MCExpr::Binary ||
    297                myMCExpr->getKind() == MCExpr::Unary)
    298         return true;
    299     }
    300     return false;
    301   }
    302 
    303   bool isa30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
    304   bool isb30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
    305   bool isb15_2Imm() const { return CheckImmRange(15, 2, true, true, false); }
    306   bool isb13_2Imm() const { return CheckImmRange(13, 2, true, true, false); }
    307 
    308   bool ism32_0Imm() const { return true; }
    309 
    310   bool isf32Imm() const { return false; }
    311   bool isf64Imm() const { return false; }
    312   bool iss32_0Imm() const { return true; }
    313   bool iss31_1Imm() const { return true; }
    314   bool iss30_2Imm() const { return true; }
    315   bool iss29_3Imm() const { return true; }
    316   bool iss27_2Imm() const { return CheckImmRange(27, 2, true, true, false); }
    317   bool iss10_0Imm() const { return CheckImmRange(10, 0, true, false, false); }
    318   bool iss10_6Imm() const { return CheckImmRange(10, 6, true, false, false); }
    319   bool iss9_0Imm() const { return CheckImmRange(9, 0, true, false, false); }
    320   bool iss8_0Imm() const { return CheckImmRange(8, 0, true, false, false); }
    321   bool iss8_0Imm64() const { return CheckImmRange(8, 0, true, true, false); }
    322   bool iss7_0Imm() const { return CheckImmRange(7, 0, true, false, false); }
    323   bool iss6_0Imm() const { return CheckImmRange(6, 0, true, false, false); }
    324   bool iss6_3Imm() const { return CheckImmRange(6, 3, true, false, false); }
    325   bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }
    326   bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }
    327   bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }
    328   bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }
    329   bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }
    330 
    331   bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }
    332   bool isu32_0Imm() const { return true; }
    333   bool isu31_1Imm() const { return true; }
    334   bool isu30_2Imm() const { return true; }
    335   bool isu29_3Imm() const { return true; }
    336   bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }
    337   bool isu16_0Imm() const { return CheckImmRange(16, 0, false, true, false); }
    338   bool isu16_1Imm() const { return CheckImmRange(16, 1, false, true, false); }
    339   bool isu16_2Imm() const { return CheckImmRange(16, 2, false, true, false); }
    340   bool isu16_3Imm() const { return CheckImmRange(16, 3, false, true, false); }
    341   bool isu11_3Imm() const { return CheckImmRange(11, 3, false, false, false); }
    342   bool isu10_0Imm() const { return CheckImmRange(10, 0, false, false, false); }
    343   bool isu9_0Imm() const { return CheckImmRange(9, 0, false, false, false); }
    344   bool isu8_0Imm() const { return CheckImmRange(8, 0, false, false, false); }
    345   bool isu7_0Imm() const { return CheckImmRange(7, 0, false, false, false); }
    346   bool isu6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }
    347   bool isu6_1Imm() const { return CheckImmRange(6, 1, false, false, false); }
    348   bool isu6_2Imm() const { return CheckImmRange(6, 2, false, false, false); }
    349   bool isu6_3Imm() const { return CheckImmRange(6, 3, false, false, false); }
    350   bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }
    351   bool isu5_2Imm() const { return CheckImmRange(5, 2, false, false, false); }
    352   bool isu5_3Imm() const { return CheckImmRange(5, 3, false, false, false); }
    353   bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }
    354   bool isu4_2Imm() const { return CheckImmRange(4, 2, false, false, false); }
    355   bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }
    356   bool isu3_1Imm() const { return CheckImmRange(3, 1, false, false, false); }
    357   bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }
    358   bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }
    359 
    360   bool isn1Const() const {
    361     if (!isImm())
    362       return false;
    363     int64_t Value;
    364     if (!getImm()->evaluateAsAbsolute(Value))
    365       return false;
    366     return Value == -1;
    367   }
    368   bool iss11_0Imm() const {
    369     return CheckImmRange(11 + 26, 0, true, true, true);
    370   }
    371   bool iss11_1Imm() const {
    372     return CheckImmRange(11 + 26, 1, true, true, true);
    373   }
    374   bool iss11_2Imm() const {
    375     return CheckImmRange(11 + 26, 2, true, true, true);
    376   }
    377   bool iss11_3Imm() const {
    378     return CheckImmRange(11 + 26, 3, true, true, true);
    379   }
    380   bool isu32_0MustExt() const { return isImm(); }
    381 
    382   void addRegOperands(MCInst &Inst, unsigned N) const {
    383     assert(N == 1 && "Invalid number of operands!");
    384     Inst.addOperand(MCOperand::createReg(getReg()));
    385   }
    386 
    387   void addImmOperands(MCInst &Inst, unsigned N) const {
    388     assert(N == 1 && "Invalid number of operands!");
    389     Inst.addOperand(MCOperand::createExpr(getImm()));
    390   }
    391 
    392   void addSignedImmOperands(MCInst &Inst, unsigned N) const {
    393     assert(N == 1 && "Invalid number of operands!");
    394     HexagonMCExpr *Expr =
    395         const_cast<HexagonMCExpr *>(cast<HexagonMCExpr>(getImm()));
    396     int64_t Value;
    397     if (!Expr->evaluateAsAbsolute(Value)) {
    398       Inst.addOperand(MCOperand::createExpr(Expr));
    399       return;
    400     }
    401     int64_t Extended = SignExtend64(Value, 32);
    402     HexagonMCExpr *NewExpr = HexagonMCExpr::create(
    403         MCConstantExpr::create(Extended, Context), Context);
    404     if ((Extended < 0) != (Value < 0))
    405       NewExpr->setSignMismatch();
    406     NewExpr->setMustExtend(Expr->mustExtend());
    407     NewExpr->setMustNotExtend(Expr->mustNotExtend());
    408     Inst.addOperand(MCOperand::createExpr(NewExpr));
    409   }
    410 
    411   void addn1ConstOperands(MCInst &Inst, unsigned N) const {
    412     addImmOperands(Inst, N);
    413   }
    414 
    415   StringRef getToken() const {
    416     assert(Kind == Token && "Invalid access!");
    417     return StringRef(Tok.Data, Tok.Length);
    418   }
    419 
    420   void print(raw_ostream &OS) const override;
    421 
    422   static std::unique_ptr<HexagonOperand> CreateToken(MCContext &Context,
    423                                                      StringRef Str, SMLoc S) {
    424     HexagonOperand *Op = new HexagonOperand(Token, Context);
    425     Op->Tok.Data = Str.data();
    426     Op->Tok.Length = Str.size();
    427     Op->StartLoc = S;
    428     Op->EndLoc = S;
    429     return std::unique_ptr<HexagonOperand>(Op);
    430   }
    431 
    432   static std::unique_ptr<HexagonOperand>
    433   CreateReg(MCContext &Context, unsigned RegNum, SMLoc S, SMLoc E) {
    434     HexagonOperand *Op = new HexagonOperand(Register, Context);
    435     Op->Reg.RegNum = RegNum;
    436     Op->StartLoc = S;
    437     Op->EndLoc = E;
    438     return std::unique_ptr<HexagonOperand>(Op);
    439   }
    440 
    441   static std::unique_ptr<HexagonOperand>
    442   CreateImm(MCContext &Context, const MCExpr *Val, SMLoc S, SMLoc E) {
    443     HexagonOperand *Op = new HexagonOperand(Immediate, Context);
    444     Op->Imm.Val = Val;
    445     Op->StartLoc = S;
    446     Op->EndLoc = E;
    447     return std::unique_ptr<HexagonOperand>(Op);
    448   }
    449 };
    450 
    451 } // end anonymous namespace
    452 
    453 void HexagonOperand::print(raw_ostream &OS) const {
    454   switch (Kind) {
    455   case Immediate:
    456     getImm()->print(OS, nullptr);
    457     break;
    458   case Register:
    459     OS << "<register R";
    460     OS << getReg() << ">";
    461     break;
    462   case Token:
    463     OS << "'" << getToken() << "'";
    464     break;
    465   }
    466 }
    467 
    468 bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
    469   LLVM_DEBUG(dbgs() << "Bundle:");
    470   LLVM_DEBUG(MCB.dump_pretty(dbgs()));
    471   LLVM_DEBUG(dbgs() << "--\n");
    472 
    473   MCB.setLoc(IDLoc);
    474 
    475   // Check the bundle for errors.
    476   const MCRegisterInfo *RI = getContext().getRegisterInfo();
    477   MCSubtargetInfo const &STI = getSTI();
    478 
    479   MCInst OrigBundle = MCB;
    480   HexagonMCChecker Check(getContext(), MII, STI, MCB, *RI, true);
    481 
    482   bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(
    483       MII, STI, getContext(), MCB, &Check, true);
    484 
    485   if (CheckOk) {
    486     if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
    487       assert(!HexagonMCInstrInfo::isInnerLoop(MCB));
    488       assert(!HexagonMCInstrInfo::isOuterLoop(MCB));
    489       // Empty packets are valid yet aren't emitted
    490       return false;
    491     }
    492 
    493     assert(HexagonMCInstrInfo::isBundle(MCB));
    494 
    495     Out.emitInstruction(MCB, STI);
    496   } else
    497     return true; // Error
    498 
    499   return false; // No error
    500 }
    501 
    502 bool HexagonAsmParser::matchBundleOptions() {
    503   MCAsmParser &Parser = getParser();
    504   while (true) {
    505     if (!Parser.getTok().is(AsmToken::Colon))
    506       return false;
    507     Lex();
    508     char const *MemNoShuffMsg =
    509         "invalid instruction packet: mem_noshuf specifier not "
    510         "supported with this architecture";
    511     StringRef Option = Parser.getTok().getString();
    512     auto IDLoc = Parser.getTok().getLoc();
    513     if (Option.compare_lower("endloop01") == 0) {
    514       HexagonMCInstrInfo::setInnerLoop(MCB);
    515       HexagonMCInstrInfo::setOuterLoop(MCB);
    516     } else if (Option.compare_lower("endloop0") == 0) {
    517       HexagonMCInstrInfo::setInnerLoop(MCB);
    518     } else if (Option.compare_lower("endloop1") == 0) {
    519       HexagonMCInstrInfo::setOuterLoop(MCB);
    520     } else if (Option.compare_lower("mem_noshuf") == 0) {
    521       if (getSTI().getFeatureBits()[Hexagon::FeatureMemNoShuf])
    522         HexagonMCInstrInfo::setMemReorderDisabled(MCB);
    523       else
    524         return getParser().Error(IDLoc, MemNoShuffMsg);
    525     } else if (Option.compare_lower("mem_no_order") == 0) {
    526       // Nothing.
    527     } else
    528       return getParser().Error(IDLoc, llvm::Twine("'") + Option +
    529                                           "' is not a valid bundle option");
    530     Lex();
    531   }
    532 }
    533 
    534 // For instruction aliases, immediates are generated rather than
    535 // MCConstantExpr.  Convert them for uniform MCExpr.
    536 // Also check for signed/unsigned mismatches and warn
    537 void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
    538   MCInst NewInst;
    539   NewInst.setOpcode(MCI.getOpcode());
    540   for (MCOperand &I : MCI)
    541     if (I.isImm()) {
    542       int64_t Value(I.getImm());
    543       NewInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
    544           MCConstantExpr::create(Value, getContext()), getContext())));
    545     } else {
    546       if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&
    547           WarnSignedMismatch)
    548         Warning(MCI.getLoc(), "Signed/Unsigned mismatch");
    549       NewInst.addOperand(I);
    550     }
    551   MCI = NewInst;
    552 }
    553 
    554 bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
    555                                            OperandVector &InstOperands,
    556                                            uint64_t &ErrorInfo,
    557                                            bool MatchingInlineAsm) {
    558   // Perform matching with tablegen asmmatcher generated function
    559   int result =
    560       MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
    561   if (result == Match_Success) {
    562     MCI.setLoc(IDLoc);
    563     canonicalizeImmediates(MCI);
    564     result = processInstruction(MCI, InstOperands, IDLoc);
    565 
    566     LLVM_DEBUG(dbgs() << "Insn:");
    567     LLVM_DEBUG(MCI.dump_pretty(dbgs()));
    568     LLVM_DEBUG(dbgs() << "\n\n");
    569 
    570     MCI.setLoc(IDLoc);
    571   }
    572 
    573   // Create instruction operand for bundle instruction
    574   //   Break this into a separate function Code here is less readable
    575   //   Think about how to get an instruction error to report correctly.
    576   //   SMLoc will return the "{"
    577   switch (result) {
    578   default:
    579     break;
    580   case Match_Success:
    581     return false;
    582   case Match_MissingFeature:
    583     return Error(IDLoc, "invalid instruction");
    584   case Match_MnemonicFail:
    585     return Error(IDLoc, "unrecognized instruction");
    586   case Match_InvalidOperand:
    587     LLVM_FALLTHROUGH;
    588   case Match_InvalidTiedOperand:
    589     SMLoc ErrorLoc = IDLoc;
    590     if (ErrorInfo != ~0U) {
    591       if (ErrorInfo >= InstOperands.size())
    592         return Error(IDLoc, "too few operands for instruction");
    593 
    594       ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
    595                      ->getStartLoc();
    596       if (ErrorLoc == SMLoc())
    597         ErrorLoc = IDLoc;
    598     }
    599     return Error(ErrorLoc, "invalid operand for instruction");
    600   }
    601   llvm_unreachable("Implement any new match types added!");
    602 }
    603 
    604 void HexagonAsmParser::eatToEndOfPacket() {
    605   assert(InBrackets);
    606   MCAsmLexer &Lexer = getLexer();
    607   while (!Lexer.is(AsmToken::RCurly))
    608     Lexer.Lex();
    609   Lexer.Lex();
    610   InBrackets = false;
    611 }
    612 
    613 bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
    614                                                OperandVector &Operands,
    615                                                MCStreamer &Out,
    616                                                uint64_t &ErrorInfo,
    617                                                bool MatchingInlineAsm) {
    618   if (!InBrackets) {
    619     MCB.clear();
    620     MCB.addOperand(MCOperand::createImm(0));
    621   }
    622   HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
    623   if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
    624     assert(Operands.size() == 1 && "Brackets should be by themselves");
    625     if (InBrackets) {
    626       getParser().Error(IDLoc, "Already in a packet");
    627       InBrackets = false;
    628       return true;
    629     }
    630     InBrackets = true;
    631     return false;
    632   }
    633   if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
    634     assert(Operands.size() == 1 && "Brackets should be by themselves");
    635     if (!InBrackets) {
    636       getParser().Error(IDLoc, "Not in a packet");
    637       return true;
    638     }
    639     InBrackets = false;
    640     if (matchBundleOptions())
    641       return true;
    642     return finishBundle(IDLoc, Out);
    643   }
    644   MCInst *SubInst = getParser().getContext().createMCInst();
    645   if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
    646                           MatchingInlineAsm)) {
    647     if (InBrackets)
    648       eatToEndOfPacket();
    649     return true;
    650   }
    651   HexagonMCInstrInfo::extendIfNeeded(
    652       getParser().getContext(), MII, MCB, *SubInst);
    653   MCB.addOperand(MCOperand::createInst(SubInst));
    654   if (!InBrackets)
    655     return finishBundle(IDLoc, Out);
    656   return false;
    657 }
    658 
    659 /// ParseDirective parses the Hexagon specific directives
    660 bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
    661   StringRef IDVal = DirectiveID.getIdentifier();
    662   if (IDVal.lower() == ".falign")
    663     return ParseDirectiveFalign(256, DirectiveID.getLoc());
    664   if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
    665     return ParseDirectiveComm(true, DirectiveID.getLoc());
    666   if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
    667     return ParseDirectiveComm(false, DirectiveID.getLoc());
    668   if (IDVal.lower() == ".subsection")
    669     return ParseDirectiveSubsection(DirectiveID.getLoc());
    670 
    671   return true;
    672 }
    673 bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
    674   const MCExpr *Subsection = nullptr;
    675   int64_t Res;
    676 
    677   assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
    678          "Invalid subsection directive");
    679   getParser().parseExpression(Subsection);
    680 
    681   if (!Subsection->evaluateAsAbsolute(Res))
    682     return Error(L, "Cannot evaluate subsection number");
    683 
    684   if (getLexer().isNot(AsmToken::EndOfStatement))
    685     return TokError("unexpected token in directive");
    686 
    687   // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
    688   // negative subsections together and in the same order but at the opposite
    689   // end of the section.  Only legacy hexagon-gcc created assembly code
    690   // used negative subsections.
    691   if ((Res < 0) && (Res > -8193))
    692     Subsection = HexagonMCExpr::create(
    693         MCConstantExpr::create(8192 + Res, getContext()), getContext());
    694 
    695   getStreamer().SubSection(Subsection);
    696   return false;
    697 }
    698 
    699 ///  ::= .falign [expression]
    700 bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
    701 
    702   int64_t MaxBytesToFill = 15;
    703 
    704   // if there is an argument
    705   if (getLexer().isNot(AsmToken::EndOfStatement)) {
    706     const MCExpr *Value;
    707     SMLoc ExprLoc = L;
    708 
    709     // Make sure we have a number (false is returned if expression is a number)
    710     if (!getParser().parseExpression(Value)) {
    711       // Make sure this is a number that is in range
    712       auto *MCE = cast<MCConstantExpr>(Value);
    713       uint64_t IntValue = MCE->getValue();
    714       if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
    715         return Error(ExprLoc, "literal value out of range (256) for falign");
    716       MaxBytesToFill = IntValue;
    717       Lex();
    718     } else {
    719       return Error(ExprLoc, "not a valid expression for falign directive");
    720     }
    721   }
    722 
    723   getTargetStreamer().emitFAlign(16, MaxBytesToFill);
    724   Lex();
    725 
    726   return false;
    727 }
    728 
    729 // This is largely a copy of AsmParser's ParseDirectiveComm extended to
    730 // accept a 3rd argument, AccessAlignment which indicates the smallest
    731 // memory access made to the symbol, expressed in bytes.  If no
    732 // AccessAlignment is specified it defaults to the Alignment Value.
    733 // Hexagon's .lcomm:
    734 //   .lcomm Symbol, Length, Alignment, AccessAlignment
    735 bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
    736   // FIXME: need better way to detect if AsmStreamer (upstream removed
    737   // getKind())
    738   if (getStreamer().hasRawTextSupport())
    739     return true; // Only object file output requires special treatment.
    740 
    741   StringRef Name;
    742   if (getParser().parseIdentifier(Name))
    743     return TokError("expected identifier in directive");
    744   // Handle the identifier as the key symbol.
    745   MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
    746 
    747   if (getLexer().isNot(AsmToken::Comma))
    748     return TokError("unexpected token in directive");
    749   Lex();
    750 
    751   int64_t Size;
    752   SMLoc SizeLoc = getLexer().getLoc();
    753   if (getParser().parseAbsoluteExpression(Size))
    754     return true;
    755 
    756   int64_t ByteAlignment = 1;
    757   SMLoc ByteAlignmentLoc;
    758   if (getLexer().is(AsmToken::Comma)) {
    759     Lex();
    760     ByteAlignmentLoc = getLexer().getLoc();
    761     if (getParser().parseAbsoluteExpression(ByteAlignment))
    762       return true;
    763     if (!isPowerOf2_64(ByteAlignment))
    764       return Error(ByteAlignmentLoc, "alignment must be a power of 2");
    765   }
    766 
    767   int64_t AccessAlignment = 0;
    768   if (getLexer().is(AsmToken::Comma)) {
    769     // The optional access argument specifies the size of the smallest memory
    770     //   access to be made to the symbol, expressed in bytes.
    771     SMLoc AccessAlignmentLoc;
    772     Lex();
    773     AccessAlignmentLoc = getLexer().getLoc();
    774     if (getParser().parseAbsoluteExpression(AccessAlignment))
    775       return true;
    776 
    777     if (!isPowerOf2_64(AccessAlignment))
    778       return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
    779   }
    780 
    781   if (getLexer().isNot(AsmToken::EndOfStatement))
    782     return TokError("unexpected token in '.comm' or '.lcomm' directive");
    783 
    784   Lex();
    785 
    786   // NOTE: a size of zero for a .comm should create a undefined symbol
    787   // but a size of .lcomm creates a bss symbol of size zero.
    788   if (Size < 0)
    789     return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
    790                           "be less than zero");
    791 
    792   // NOTE: The alignment in the directive is a power of 2 value, the assembler
    793   // may internally end up wanting an alignment in bytes.
    794   // FIXME: Diagnose overflow.
    795   if (ByteAlignment < 0)
    796     return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
    797                                    "alignment, can't be less than zero");
    798 
    799   if (!Sym->isUndefined())
    800     return Error(Loc, "invalid symbol redefinition");
    801 
    802   HexagonMCELFStreamer &HexagonELFStreamer =
    803       static_cast<HexagonMCELFStreamer &>(getStreamer());
    804   if (IsLocal) {
    805     HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(Sym, Size, ByteAlignment,
    806                                                       AccessAlignment);
    807     return false;
    808   }
    809 
    810   HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, ByteAlignment,
    811                                                AccessAlignment);
    812   return false;
    813 }
    814 
    815 // validate register against architecture
    816 bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
    817   if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))
    818     if (!getSTI().getFeatureBits()[Hexagon::ArchV62])
    819       return false;
    820   return true;
    821 }
    822 
    823 // extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonAsmLexer();
    824 
    825 /// Force static initialization.
    826 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonAsmParser() {
    827   RegisterMCAsmParser<HexagonAsmParser> X(getTheHexagonTarget());
    828 }
    829 
    830 #define GET_MATCHER_IMPLEMENTATION
    831 #define GET_REGISTER_MATCHER
    832 #include "HexagonGenAsmMatcher.inc"
    833 
    834 static bool previousEqual(OperandVector &Operands, size_t Index,
    835                           StringRef String) {
    836   if (Index >= Operands.size())
    837     return false;
    838   MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
    839   if (!Operand.isToken())
    840     return false;
    841   return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
    842 }
    843 
    844 static bool previousIsLoop(OperandVector &Operands, size_t Index) {
    845   return previousEqual(Operands, Index, "loop0") ||
    846          previousEqual(Operands, Index, "loop1") ||
    847          previousEqual(Operands, Index, "sp1loop0") ||
    848          previousEqual(Operands, Index, "sp2loop0") ||
    849          previousEqual(Operands, Index, "sp3loop0");
    850 }
    851 
    852 bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
    853   AsmToken const &Token = getParser().getTok();
    854   StringRef String = Token.getString();
    855   SMLoc Loc = Token.getLoc();
    856   Lex();
    857   do {
    858     std::pair<StringRef, StringRef> HeadTail = String.split('.');
    859     if (!HeadTail.first.empty())
    860       Operands.push_back(
    861           HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
    862     if (!HeadTail.second.empty())
    863       Operands.push_back(HexagonOperand::CreateToken(
    864           getContext(), String.substr(HeadTail.first.size(), 1), Loc));
    865     String = HeadTail.second;
    866   } while (!String.empty());
    867   return false;
    868 }
    869 
    870 bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
    871   unsigned Register;
    872   SMLoc Begin;
    873   SMLoc End;
    874   MCAsmLexer &Lexer = getLexer();
    875   if (!ParseRegister(Register, Begin, End)) {
    876     if (!ErrorMissingParenthesis)
    877       switch (Register) {
    878       default:
    879         break;
    880       case Hexagon::P0:
    881       case Hexagon::P1:
    882       case Hexagon::P2:
    883       case Hexagon::P3:
    884         if (previousEqual(Operands, 0, "if")) {
    885           if (WarnMissingParenthesis)
    886             Warning(Begin, "Missing parenthesis around predicate register");
    887           static char const *LParen = "(";
    888           static char const *RParen = ")";
    889           Operands.push_back(
    890               HexagonOperand::CreateToken(getContext(), LParen, Begin));
    891           Operands.push_back(
    892               HexagonOperand::CreateReg(getContext(), Register, Begin, End));
    893           const AsmToken &MaybeDotNew = Lexer.getTok();
    894           if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
    895               MaybeDotNew.getString().equals_lower(".new"))
    896             splitIdentifier(Operands);
    897           Operands.push_back(
    898               HexagonOperand::CreateToken(getContext(), RParen, Begin));
    899           return false;
    900         }
    901         if (previousEqual(Operands, 0, "!") &&
    902             previousEqual(Operands, 1, "if")) {
    903           if (WarnMissingParenthesis)
    904             Warning(Begin, "Missing parenthesis around predicate register");
    905           static char const *LParen = "(";
    906           static char const *RParen = ")";
    907           Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(
    908                                                   getContext(), LParen, Begin));
    909           Operands.push_back(
    910               HexagonOperand::CreateReg(getContext(), Register, Begin, End));
    911           const AsmToken &MaybeDotNew = Lexer.getTok();
    912           if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
    913               MaybeDotNew.getString().equals_lower(".new"))
    914             splitIdentifier(Operands);
    915           Operands.push_back(
    916               HexagonOperand::CreateToken(getContext(), RParen, Begin));
    917           return false;
    918         }
    919         break;
    920       }
    921     Operands.push_back(
    922         HexagonOperand::CreateReg(getContext(), Register, Begin, End));
    923     return false;
    924   }
    925   return splitIdentifier(Operands);
    926 }
    927 
    928 bool HexagonAsmParser::isLabel(AsmToken &Token) {
    929   MCAsmLexer &Lexer = getLexer();
    930   AsmToken const &Second = Lexer.getTok();
    931   AsmToken Third = Lexer.peekTok();
    932   StringRef String = Token.getString();
    933   if (Token.is(AsmToken::TokenKind::LCurly) ||
    934       Token.is(AsmToken::TokenKind::RCurly))
    935     return false;
    936   // special case for parsing vwhist256:sat
    937   if (String.lower() == "vwhist256" && Second.is(AsmToken::Colon) &&
    938       Third.getString().lower() == "sat")
    939     return false;
    940   if (!Token.is(AsmToken::TokenKind::Identifier))
    941     return true;
    942   if (!matchRegister(String.lower()))
    943     return true;
    944   assert(Second.is(AsmToken::Colon));
    945   StringRef Raw(String.data(), Third.getString().data() - String.data() +
    946                                    Third.getString().size());
    947   std::string Collapsed = std::string(Raw);
    948   llvm::erase_if(Collapsed, isSpace);
    949   StringRef Whole = Collapsed;
    950   std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
    951   if (!matchRegister(DotSplit.first.lower()))
    952     return true;
    953   return false;
    954 }
    955 
    956 bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,
    957                                                    SMLoc &Loc) {
    958   if (!Contigious && ErrorNoncontigiousRegister) {
    959     Error(Loc, "Register name is not contigious");
    960     return true;
    961   }
    962   if (!Contigious && WarnNoncontigiousRegister)
    963     Warning(Loc, "Register name is not contigious");
    964   return false;
    965 }
    966 
    967 bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
    968                                      SMLoc &EndLoc) {
    969   return tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success;
    970 }
    971 
    972 OperandMatchResultTy HexagonAsmParser::tryParseRegister(unsigned &RegNo,
    973                                                         SMLoc &StartLoc,
    974                                                         SMLoc &EndLoc) {
    975   MCAsmLexer &Lexer = getLexer();
    976   StartLoc = getLexer().getLoc();
    977   SmallVector<AsmToken, 5> Lookahead;
    978   StringRef RawString(Lexer.getTok().getString().data(), 0);
    979   bool Again = Lexer.is(AsmToken::Identifier);
    980   bool NeededWorkaround = false;
    981   while (Again) {
    982     AsmToken const &Token = Lexer.getTok();
    983     RawString = StringRef(RawString.data(), Token.getString().data() -
    984                                                 RawString.data() +
    985                                                 Token.getString().size());
    986     Lookahead.push_back(Token);
    987     Lexer.Lex();
    988     bool Contigious = Lexer.getTok().getString().data() ==
    989                       Lookahead.back().getString().data() +
    990                           Lookahead.back().getString().size();
    991     bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
    992                 Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
    993                 Lexer.is(AsmToken::Colon);
    994     bool Workaround =
    995         Lexer.is(AsmToken::Colon) || Lookahead.back().is(AsmToken::Colon);
    996     Again = (Contigious && Type) || (Workaround && Type);
    997     NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
    998   }
    999   std::string Collapsed = std::string(RawString);
   1000   llvm::erase_if(Collapsed, isSpace);
   1001   StringRef FullString = Collapsed;
   1002   std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
   1003   unsigned DotReg = matchRegister(DotSplit.first.lower());
   1004   if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
   1005     if (DotSplit.second.empty()) {
   1006       RegNo = DotReg;
   1007       EndLoc = Lexer.getLoc();
   1008       if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
   1009         return MatchOperand_NoMatch;
   1010       return MatchOperand_Success;
   1011     } else {
   1012       RegNo = DotReg;
   1013       size_t First = RawString.find('.');
   1014       StringRef DotString (RawString.data() + First, RawString.size() - First);
   1015       Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
   1016       EndLoc = Lexer.getLoc();
   1017       if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
   1018         return MatchOperand_NoMatch;
   1019       return MatchOperand_Success;
   1020     }
   1021   }
   1022   std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
   1023   unsigned ColonReg = matchRegister(ColonSplit.first.lower());
   1024   if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
   1025     do {
   1026       Lexer.UnLex(Lookahead.pop_back_val());
   1027     } while (!Lookahead.empty() && !Lexer.is(AsmToken::Colon));
   1028     RegNo = ColonReg;
   1029     EndLoc = Lexer.getLoc();
   1030     if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
   1031       return MatchOperand_NoMatch;
   1032     return MatchOperand_Success;
   1033   }
   1034   while (!Lookahead.empty()) {
   1035     Lexer.UnLex(Lookahead.pop_back_val());
   1036   }
   1037   return MatchOperand_NoMatch;
   1038 }
   1039 
   1040 bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
   1041   if (previousEqual(Operands, 0, "call"))
   1042     return true;
   1043   if (previousEqual(Operands, 0, "jump"))
   1044     if (!getLexer().getTok().is(AsmToken::Colon))
   1045       return true;
   1046   if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
   1047     return true;
   1048   if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
   1049       (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
   1050     return true;
   1051   return false;
   1052 }
   1053 
   1054 bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {
   1055   SmallVector<AsmToken, 4> Tokens;
   1056   MCAsmLexer &Lexer = getLexer();
   1057   bool Done = false;
   1058   static char const *Comma = ",";
   1059   do {
   1060     Tokens.emplace_back(Lexer.getTok());
   1061     Lex();
   1062     switch (Tokens.back().getKind()) {
   1063     case AsmToken::TokenKind::Hash:
   1064       if (Tokens.size() > 1)
   1065         if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
   1066           Tokens.insert(Tokens.end() - 2,
   1067                         AsmToken(AsmToken::TokenKind::Comma, Comma));
   1068           Done = true;
   1069         }
   1070       break;
   1071     case AsmToken::TokenKind::RCurly:
   1072     case AsmToken::TokenKind::EndOfStatement:
   1073     case AsmToken::TokenKind::Eof:
   1074       Done = true;
   1075       break;
   1076     default:
   1077       break;
   1078     }
   1079   } while (!Done);
   1080   while (!Tokens.empty()) {
   1081     Lexer.UnLex(Tokens.back());
   1082     Tokens.pop_back();
   1083   }
   1084   SMLoc Loc = Lexer.getLoc();
   1085   return getParser().parseExpression(Expr, Loc);
   1086 }
   1087 
   1088 bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
   1089   if (implicitExpressionLocation(Operands)) {
   1090     MCAsmParser &Parser = getParser();
   1091     SMLoc Loc = Parser.getLexer().getLoc();
   1092     MCExpr const *Expr = nullptr;
   1093     bool Error = parseExpression(Expr);
   1094     Expr = HexagonMCExpr::create(Expr, getContext());
   1095     if (!Error)
   1096       Operands.push_back(
   1097           HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
   1098     return Error;
   1099   }
   1100   return parseOperand(Operands);
   1101 }
   1102 
   1103 /// Parse an instruction.
   1104 bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
   1105   MCAsmParser &Parser = getParser();
   1106   MCAsmLexer &Lexer = getLexer();
   1107   while (true) {
   1108     AsmToken const &Token = Parser.getTok();
   1109     switch (Token.getKind()) {
   1110     case AsmToken::Eof:
   1111     case AsmToken::EndOfStatement: {
   1112       Lex();
   1113       return false;
   1114     }
   1115     case AsmToken::LCurly: {
   1116       if (!Operands.empty())
   1117         return true;
   1118       Operands.push_back(HexagonOperand::CreateToken(
   1119           getContext(), Token.getString(), Token.getLoc()));
   1120       Lex();
   1121       return false;
   1122     }
   1123     case AsmToken::RCurly: {
   1124       if (Operands.empty()) {
   1125         Operands.push_back(HexagonOperand::CreateToken(
   1126             getContext(), Token.getString(), Token.getLoc()));
   1127         Lex();
   1128       }
   1129       return false;
   1130     }
   1131     case AsmToken::Comma: {
   1132       Lex();
   1133       continue;
   1134     }
   1135     case AsmToken::EqualEqual:
   1136     case AsmToken::ExclaimEqual:
   1137     case AsmToken::GreaterEqual:
   1138     case AsmToken::GreaterGreater:
   1139     case AsmToken::LessEqual:
   1140     case AsmToken::LessLess: {
   1141       Operands.push_back(HexagonOperand::CreateToken(
   1142           getContext(), Token.getString().substr(0, 1), Token.getLoc()));
   1143       Operands.push_back(HexagonOperand::CreateToken(
   1144           getContext(), Token.getString().substr(1, 1), Token.getLoc()));
   1145       Lex();
   1146       continue;
   1147     }
   1148     case AsmToken::Hash: {
   1149       bool MustNotExtend = false;
   1150       bool ImplicitExpression = implicitExpressionLocation(Operands);
   1151       SMLoc ExprLoc = Lexer.getLoc();
   1152       if (!ImplicitExpression)
   1153         Operands.push_back(HexagonOperand::CreateToken(
   1154             getContext(), Token.getString(), Token.getLoc()));
   1155       Lex();
   1156       bool MustExtend = false;
   1157       bool HiOnly = false;
   1158       bool LoOnly = false;
   1159       if (Lexer.is(AsmToken::Hash)) {
   1160         Lex();
   1161         MustExtend = true;
   1162       } else if (ImplicitExpression)
   1163         MustNotExtend = true;
   1164       AsmToken const &Token = Parser.getTok();
   1165       if (Token.is(AsmToken::Identifier)) {
   1166         StringRef String = Token.getString();
   1167         if (String.lower() == "hi") {
   1168           HiOnly = true;
   1169         } else if (String.lower() == "lo") {
   1170           LoOnly = true;
   1171         }
   1172         if (HiOnly || LoOnly) {
   1173           AsmToken LParen = Lexer.peekTok();
   1174           if (!LParen.is(AsmToken::LParen)) {
   1175             HiOnly = false;
   1176             LoOnly = false;
   1177           } else {
   1178             Lex();
   1179           }
   1180         }
   1181       }
   1182       MCExpr const *Expr = nullptr;
   1183       if (parseExpression(Expr))
   1184         return true;
   1185       int64_t Value;
   1186       MCContext &Context = Parser.getContext();
   1187       assert(Expr != nullptr);
   1188       if (Expr->evaluateAsAbsolute(Value)) {
   1189         if (HiOnly)
   1190           Expr = MCBinaryExpr::createLShr(
   1191               Expr, MCConstantExpr::create(16, Context), Context);
   1192         if (HiOnly || LoOnly)
   1193           Expr = MCBinaryExpr::createAnd(
   1194               Expr, MCConstantExpr::create(0xffff, Context), Context);
   1195       } else {
   1196         MCValue Value;
   1197         if (Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) {
   1198           if (!Value.isAbsolute()) {
   1199             switch (Value.getAccessVariant()) {
   1200             case MCSymbolRefExpr::VariantKind::VK_TPREL:
   1201             case MCSymbolRefExpr::VariantKind::VK_DTPREL:
   1202               // Don't lazy extend these expression variants
   1203               MustNotExtend = !MustExtend;
   1204               break;
   1205             default:
   1206               break;
   1207             }
   1208           }
   1209         }
   1210       }
   1211       Expr = HexagonMCExpr::create(Expr, Context);
   1212       HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
   1213       HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
   1214       std::unique_ptr<HexagonOperand> Operand =
   1215           HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
   1216       Operands.push_back(std::move(Operand));
   1217       continue;
   1218     }
   1219     default:
   1220       break;
   1221     }
   1222     if (parseExpressionOrOperand(Operands))
   1223       return true;
   1224   }
   1225 }
   1226 
   1227 bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
   1228                                         StringRef Name, AsmToken ID,
   1229                                         OperandVector &Operands) {
   1230   getLexer().UnLex(ID);
   1231   return parseInstruction(Operands);
   1232 }
   1233 
   1234 static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1,
   1235                               MCOperand &MO2) {
   1236   MCInst TmpInst;
   1237   TmpInst.setOpcode(opCode);
   1238   TmpInst.addOperand(Rdd);
   1239   TmpInst.addOperand(MO1);
   1240   TmpInst.addOperand(MO2);
   1241 
   1242   return TmpInst;
   1243 }
   1244 
   1245 // Define this matcher function after the auto-generated include so we
   1246 // have the match class enum definitions.
   1247 unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
   1248                                                       unsigned Kind) {
   1249   HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
   1250 
   1251   switch (Kind) {
   1252   case MCK_0: {
   1253     int64_t Value;
   1254     return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
   1255                ? Match_Success
   1256                : Match_InvalidOperand;
   1257   }
   1258   case MCK_1: {
   1259     int64_t Value;
   1260     return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
   1261                ? Match_Success
   1262                : Match_InvalidOperand;
   1263   }
   1264   }
   1265   if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
   1266     StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
   1267     if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
   1268       return Match_Success;
   1269     if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
   1270       return Match_Success;
   1271   }
   1272 
   1273   LLVM_DEBUG(dbgs() << "Unmatched Operand:");
   1274   LLVM_DEBUG(Op->dump());
   1275   LLVM_DEBUG(dbgs() << "\n");
   1276 
   1277   return Match_InvalidOperand;
   1278 }
   1279 
   1280 // FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
   1281 bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
   1282   std::string errStr;
   1283   raw_string_ostream ES(errStr);
   1284   ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
   1285   if (Max >= 0)
   1286     ES << "0-" << Max;
   1287   else
   1288     ES << Max << "-" << (-Max - 1);
   1289   return Parser.printError(IDLoc, ES.str());
   1290 }
   1291 
   1292 int HexagonAsmParser::processInstruction(MCInst &Inst,
   1293                                          OperandVector const &Operands,
   1294                                          SMLoc IDLoc) {
   1295   MCContext &Context = getParser().getContext();
   1296   const MCRegisterInfo *RI = getContext().getRegisterInfo();
   1297   const std::string r = "r";
   1298   const std::string v = "v";
   1299   const std::string Colon = ":";
   1300   using RegPairVals = std::pair<unsigned, unsigned>;
   1301   auto GetRegPair = [this, r](RegPairVals RegPair) {
   1302     const std::string R1 = r + utostr(RegPair.first);
   1303     const std::string R2 = r + utostr(RegPair.second);
   1304 
   1305     return std::make_pair(matchRegister(R1), matchRegister(R2));
   1306   };
   1307   auto GetScalarRegs = [RI, GetRegPair](unsigned RegPair) {
   1308     const unsigned Lower = RI->getEncodingValue(RegPair);
   1309     const RegPairVals RegPair_ = std::make_pair(Lower + 1, Lower);
   1310 
   1311     return GetRegPair(RegPair_);
   1312   };
   1313   auto GetVecRegs = [GetRegPair](unsigned VecRegPair) {
   1314     const RegPairVals RegPair =
   1315         HexagonMCInstrInfo::GetVecRegPairIndices(VecRegPair);
   1316 
   1317     return GetRegPair(RegPair);
   1318   };
   1319 
   1320   bool is32bit = false; // used to distinguish between CONST32 and CONST64
   1321   switch (Inst.getOpcode()) {
   1322   default:
   1323     if (HexagonMCInstrInfo::getDesc(MII, Inst).isPseudo()) {
   1324       SMDiagnostic Diag = getSourceManager().GetMessage(
   1325           IDLoc, SourceMgr::DK_Error,
   1326           "Found pseudo instruction with no expansion");
   1327       Diag.print("", errs());
   1328       report_fatal_error("Invalid pseudo instruction");
   1329     }
   1330     break;
   1331 
   1332   case Hexagon::J2_trap1:
   1333     if (!getSTI().getFeatureBits()[Hexagon::ArchV65]) {
   1334       MCOperand &Rx = Inst.getOperand(0);
   1335       MCOperand &Ry = Inst.getOperand(1);
   1336       if (Rx.getReg() != Hexagon::R0 || Ry.getReg() != Hexagon::R0) {
   1337         Error(IDLoc, "trap1 can only have register r0 as operand");
   1338         return Match_InvalidOperand;
   1339       }
   1340     }
   1341     break;
   1342 
   1343   case Hexagon::A2_iconst: {
   1344     Inst.setOpcode(Hexagon::A2_addi);
   1345     MCOperand Reg = Inst.getOperand(0);
   1346     MCOperand S27 = Inst.getOperand(1);
   1347     HexagonMCInstrInfo::setMustNotExtend(*S27.getExpr());
   1348     HexagonMCInstrInfo::setS27_2_reloc(*S27.getExpr());
   1349     Inst.clear();
   1350     Inst.addOperand(Reg);
   1351     Inst.addOperand(MCOperand::createReg(Hexagon::R0));
   1352     Inst.addOperand(S27);
   1353     break;
   1354   }
   1355   case Hexagon::M4_mpyrr_addr:
   1356   case Hexagon::S4_addi_asl_ri:
   1357   case Hexagon::S4_addi_lsr_ri:
   1358   case Hexagon::S4_andi_asl_ri:
   1359   case Hexagon::S4_andi_lsr_ri:
   1360   case Hexagon::S4_ori_asl_ri:
   1361   case Hexagon::S4_ori_lsr_ri:
   1362   case Hexagon::S4_or_andix:
   1363   case Hexagon::S4_subi_asl_ri:
   1364   case Hexagon::S4_subi_lsr_ri: {
   1365     MCOperand &Ry = Inst.getOperand(0);
   1366     MCOperand &src = Inst.getOperand(2);
   1367     if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
   1368       return Match_InvalidOperand;
   1369     break;
   1370   }
   1371 
   1372   case Hexagon::C2_cmpgei: {
   1373     MCOperand &MO = Inst.getOperand(2);
   1374     MO.setExpr(HexagonMCExpr::create(
   1375         MCBinaryExpr::createSub(MO.getExpr(),
   1376                                 MCConstantExpr::create(1, Context), Context),
   1377         Context));
   1378     Inst.setOpcode(Hexagon::C2_cmpgti);
   1379     break;
   1380   }
   1381 
   1382   case Hexagon::C2_cmpgeui: {
   1383     MCOperand &MO = Inst.getOperand(2);
   1384     int64_t Value;
   1385     bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
   1386     (void)Success;
   1387     assert(Success && "Assured by matcher");
   1388     if (Value == 0) {
   1389       MCInst TmpInst;
   1390       MCOperand &Pd = Inst.getOperand(0);
   1391       MCOperand &Rt = Inst.getOperand(1);
   1392       TmpInst.setOpcode(Hexagon::C2_cmpeq);
   1393       TmpInst.addOperand(Pd);
   1394       TmpInst.addOperand(Rt);
   1395       TmpInst.addOperand(Rt);
   1396       Inst = TmpInst;
   1397     } else {
   1398       MO.setExpr(HexagonMCExpr::create(
   1399           MCBinaryExpr::createSub(MO.getExpr(),
   1400                                   MCConstantExpr::create(1, Context), Context),
   1401           Context));
   1402       Inst.setOpcode(Hexagon::C2_cmpgtui);
   1403     }
   1404     break;
   1405   }
   1406 
   1407   // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
   1408   case Hexagon::A2_tfrp: {
   1409     MCOperand &MO = Inst.getOperand(1);
   1410     const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.getReg());
   1411     MO.setReg(RegPair.first);
   1412     Inst.addOperand(MCOperand::createReg(RegPair.second));
   1413     Inst.setOpcode(Hexagon::A2_combinew);
   1414     break;
   1415   }
   1416 
   1417   case Hexagon::A2_tfrpt:
   1418   case Hexagon::A2_tfrpf: {
   1419     MCOperand &MO = Inst.getOperand(2);
   1420     const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.getReg());
   1421     MO.setReg(RegPair.first);
   1422     Inst.addOperand(MCOperand::createReg(RegPair.second));
   1423     Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
   1424                        ? Hexagon::C2_ccombinewt
   1425                        : Hexagon::C2_ccombinewf);
   1426     break;
   1427   }
   1428   case Hexagon::A2_tfrptnew:
   1429   case Hexagon::A2_tfrpfnew: {
   1430     MCOperand &MO = Inst.getOperand(2);
   1431     const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.getReg());
   1432     MO.setReg(RegPair.first);
   1433     Inst.addOperand(MCOperand::createReg(RegPair.second));
   1434     Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
   1435                        ? Hexagon::C2_ccombinewnewt
   1436                        : Hexagon::C2_ccombinewnewf);
   1437     break;
   1438   }
   1439 
   1440   // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
   1441   case Hexagon::V6_vassignp: {
   1442     MCOperand &MO = Inst.getOperand(1);
   1443     const std::pair<unsigned, unsigned> RegPair = GetVecRegs(MO.getReg());
   1444     MO.setReg(RegPair.first);
   1445     Inst.addOperand(MCOperand::createReg(RegPair.second));
   1446     Inst.setOpcode(Hexagon::V6_vcombine);
   1447     break;
   1448   }
   1449 
   1450   // Translate a "$Rx =  CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
   1451   case Hexagon::CONST32:
   1452     is32bit = true;
   1453     LLVM_FALLTHROUGH;
   1454   // Translate a "$Rx:y =  CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
   1455   case Hexagon::CONST64:
   1456     // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
   1457     if (!Parser.getStreamer().hasRawTextSupport()) {
   1458       MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
   1459       MCOperand &MO_1 = Inst.getOperand(1);
   1460       MCOperand &MO_0 = Inst.getOperand(0);
   1461 
   1462       // push section onto section stack
   1463       MES->PushSection();
   1464 
   1465       std::string myCharStr;
   1466       MCSectionELF *mySection;
   1467 
   1468       // check if this as an immediate or a symbol
   1469       int64_t Value;
   1470       bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
   1471       if (Absolute) {
   1472         // Create a new section - one for each constant
   1473         // Some or all of the zeros are replaced with the given immediate.
   1474         if (is32bit) {
   1475           std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
   1476           myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
   1477                           .drop_back(myImmStr.size())
   1478                           .str() +
   1479                       myImmStr;
   1480         } else {
   1481           std::string myImmStr = utohexstr(Value);
   1482           myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
   1483                           .drop_back(myImmStr.size())
   1484                           .str() +
   1485                       myImmStr;
   1486         }
   1487 
   1488         mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
   1489                                                ELF::SHF_ALLOC | ELF::SHF_WRITE);
   1490       } else if (MO_1.isExpr()) {
   1491         // .lita - for expressions
   1492         myCharStr = ".lita";
   1493         mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
   1494                                                ELF::SHF_ALLOC | ELF::SHF_WRITE);
   1495       } else
   1496         llvm_unreachable("unexpected type of machine operand!");
   1497 
   1498       MES->SwitchSection(mySection);
   1499       unsigned byteSize = is32bit ? 4 : 8;
   1500       getStreamer().emitCodeAlignment(byteSize, byteSize);
   1501 
   1502       MCSymbol *Sym;
   1503 
   1504       // for symbols, get rid of prepended ".gnu.linkonce.lx."
   1505 
   1506       // emit symbol if needed
   1507       if (Absolute) {
   1508         Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
   1509         if (Sym->isUndefined()) {
   1510           getStreamer().emitLabel(Sym);
   1511           getStreamer().emitSymbolAttribute(Sym, MCSA_Global);
   1512           getStreamer().emitIntValue(Value, byteSize);
   1513         }
   1514       } else if (MO_1.isExpr()) {
   1515         const char *StringStart = nullptr;
   1516         const char *StringEnd = nullptr;
   1517         if (*Operands[4]->getStartLoc().getPointer() == '#') {
   1518           StringStart = Operands[5]->getStartLoc().getPointer();
   1519           StringEnd = Operands[6]->getStartLoc().getPointer();
   1520         } else { // no pound
   1521           StringStart = Operands[4]->getStartLoc().getPointer();
   1522           StringEnd = Operands[5]->getStartLoc().getPointer();
   1523         }
   1524 
   1525         unsigned size = StringEnd - StringStart;
   1526         std::string DotConst = ".CONST_";
   1527         Sym = getContext().getOrCreateSymbol(DotConst +
   1528                                              StringRef(StringStart, size));
   1529 
   1530         if (Sym->isUndefined()) {
   1531           // case where symbol is not yet defined: emit symbol
   1532           getStreamer().emitLabel(Sym);
   1533           getStreamer().emitSymbolAttribute(Sym, MCSA_Local);
   1534           getStreamer().emitValue(MO_1.getExpr(), 4);
   1535         }
   1536       } else
   1537         llvm_unreachable("unexpected type of machine operand!");
   1538 
   1539       MES->PopSection();
   1540 
   1541       if (Sym) {
   1542         MCInst TmpInst;
   1543         if (is32bit) // 32 bit
   1544           TmpInst.setOpcode(Hexagon::L2_loadrigp);
   1545         else // 64 bit
   1546           TmpInst.setOpcode(Hexagon::L2_loadrdgp);
   1547 
   1548         TmpInst.addOperand(MO_0);
   1549         TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
   1550             MCSymbolRefExpr::create(Sym, getContext()), getContext())));
   1551         Inst = TmpInst;
   1552       }
   1553     }
   1554     break;
   1555 
   1556   // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
   1557   case Hexagon::A2_tfrpi: {
   1558     MCOperand &Rdd = Inst.getOperand(0);
   1559     MCOperand &MO = Inst.getOperand(1);
   1560     int64_t Value;
   1561     int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
   1562     MCOperand imm(MCOperand::createExpr(
   1563         HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));
   1564     Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
   1565     break;
   1566   }
   1567 
   1568   // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
   1569   case Hexagon::TFRI64_V4: {
   1570     MCOperand &Rdd = Inst.getOperand(0);
   1571     MCOperand &MO = Inst.getOperand(1);
   1572     int64_t Value;
   1573     if (MO.getExpr()->evaluateAsAbsolute(Value)) {
   1574       int s8 = Hi_32(Value);
   1575       if (!isInt<8>(s8))
   1576         OutOfRange(IDLoc, s8, -128);
   1577       MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
   1578           MCConstantExpr::create(s8, Context), Context))); // upper 32
   1579       auto Expr = HexagonMCExpr::create(
   1580           MCConstantExpr::create(Lo_32(Value), Context), Context);
   1581       HexagonMCInstrInfo::setMustExtend(
   1582           *Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));
   1583       MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
   1584       Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
   1585     } else {
   1586       MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
   1587           MCConstantExpr::create(0, Context), Context))); // upper 32
   1588       Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
   1589     }
   1590     break;
   1591   }
   1592 
   1593   // Handle $Rdd = combine(##imm, #imm)"
   1594   case Hexagon::TFRI64_V2_ext: {
   1595     MCOperand &Rdd = Inst.getOperand(0);
   1596     MCOperand &MO1 = Inst.getOperand(1);
   1597     MCOperand &MO2 = Inst.getOperand(2);
   1598     int64_t Value;
   1599     if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
   1600       int s8 = Value;
   1601       if (s8 < -128 || s8 > 127)
   1602         OutOfRange(IDLoc, s8, -128);
   1603     }
   1604     Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
   1605     break;
   1606   }
   1607 
   1608   // Handle $Rdd = combine(#imm, ##imm)"
   1609   case Hexagon::A4_combineii: {
   1610     MCOperand &Rdd = Inst.getOperand(0);
   1611     MCOperand &MO1 = Inst.getOperand(1);
   1612     int64_t Value;
   1613     if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
   1614       int s8 = Value;
   1615       if (s8 < -128 || s8 > 127)
   1616         OutOfRange(IDLoc, s8, -128);
   1617     }
   1618     MCOperand &MO2 = Inst.getOperand(2);
   1619     Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
   1620     break;
   1621   }
   1622 
   1623   case Hexagon::S2_tableidxb_goodsyntax:
   1624     Inst.setOpcode(Hexagon::S2_tableidxb);
   1625     break;
   1626 
   1627   case Hexagon::S2_tableidxh_goodsyntax: {
   1628     MCInst TmpInst;
   1629     MCOperand &Rx = Inst.getOperand(0);
   1630     MCOperand &Rs = Inst.getOperand(2);
   1631     MCOperand &Imm4 = Inst.getOperand(3);
   1632     MCOperand &Imm6 = Inst.getOperand(4);
   1633     Imm6.setExpr(HexagonMCExpr::create(
   1634         MCBinaryExpr::createSub(Imm6.getExpr(),
   1635                                 MCConstantExpr::create(1, Context), Context),
   1636         Context));
   1637     TmpInst.setOpcode(Hexagon::S2_tableidxh);
   1638     TmpInst.addOperand(Rx);
   1639     TmpInst.addOperand(Rx);
   1640     TmpInst.addOperand(Rs);
   1641     TmpInst.addOperand(Imm4);
   1642     TmpInst.addOperand(Imm6);
   1643     Inst = TmpInst;
   1644     break;
   1645   }
   1646 
   1647   case Hexagon::S2_tableidxw_goodsyntax: {
   1648     MCInst TmpInst;
   1649     MCOperand &Rx = Inst.getOperand(0);
   1650     MCOperand &Rs = Inst.getOperand(2);
   1651     MCOperand &Imm4 = Inst.getOperand(3);
   1652     MCOperand &Imm6 = Inst.getOperand(4);
   1653     Imm6.setExpr(HexagonMCExpr::create(
   1654         MCBinaryExpr::createSub(Imm6.getExpr(),
   1655                                 MCConstantExpr::create(2, Context), Context),
   1656         Context));
   1657     TmpInst.setOpcode(Hexagon::S2_tableidxw);
   1658     TmpInst.addOperand(Rx);
   1659     TmpInst.addOperand(Rx);
   1660     TmpInst.addOperand(Rs);
   1661     TmpInst.addOperand(Imm4);
   1662     TmpInst.addOperand(Imm6);
   1663     Inst = TmpInst;
   1664     break;
   1665   }
   1666 
   1667   case Hexagon::S2_tableidxd_goodsyntax: {
   1668     MCInst TmpInst;
   1669     MCOperand &Rx = Inst.getOperand(0);
   1670     MCOperand &Rs = Inst.getOperand(2);
   1671     MCOperand &Imm4 = Inst.getOperand(3);
   1672     MCOperand &Imm6 = Inst.getOperand(4);
   1673     Imm6.setExpr(HexagonMCExpr::create(
   1674         MCBinaryExpr::createSub(Imm6.getExpr(),
   1675                                 MCConstantExpr::create(3, Context), Context),
   1676         Context));
   1677     TmpInst.setOpcode(Hexagon::S2_tableidxd);
   1678     TmpInst.addOperand(Rx);
   1679     TmpInst.addOperand(Rx);
   1680     TmpInst.addOperand(Rs);
   1681     TmpInst.addOperand(Imm4);
   1682     TmpInst.addOperand(Imm6);
   1683     Inst = TmpInst;
   1684     break;
   1685   }
   1686 
   1687   case Hexagon::M2_mpyui:
   1688     Inst.setOpcode(Hexagon::M2_mpyi);
   1689     break;
   1690   case Hexagon::M2_mpysmi: {
   1691     MCInst TmpInst;
   1692     MCOperand &Rd = Inst.getOperand(0);
   1693     MCOperand &Rs = Inst.getOperand(1);
   1694     MCOperand &Imm = Inst.getOperand(2);
   1695     int64_t Value;
   1696     MCExpr const &Expr = *Imm.getExpr();
   1697     bool Absolute = Expr.evaluateAsAbsolute(Value);
   1698     if (!Absolute)
   1699       return Match_InvalidOperand;
   1700     if (!HexagonMCInstrInfo::mustExtend(Expr) &&
   1701         ((Value <= -256) || Value >= 256))
   1702       return Match_InvalidOperand;
   1703     if (Value < 0 && Value > -256) {
   1704       Imm.setExpr(HexagonMCExpr::create(
   1705           MCConstantExpr::create(Value * -1, Context), Context));
   1706       TmpInst.setOpcode(Hexagon::M2_mpysin);
   1707     } else
   1708       TmpInst.setOpcode(Hexagon::M2_mpysip);
   1709     TmpInst.addOperand(Rd);
   1710     TmpInst.addOperand(Rs);
   1711     TmpInst.addOperand(Imm);
   1712     Inst = TmpInst;
   1713     break;
   1714   }
   1715 
   1716   case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
   1717     MCOperand &Imm = Inst.getOperand(2);
   1718     MCInst TmpInst;
   1719     int64_t Value;
   1720     bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
   1721     if (!Absolute)
   1722       return Match_InvalidOperand;
   1723     if (Value == 0) { // convert to $Rd = $Rs
   1724       TmpInst.setOpcode(Hexagon::A2_tfr);
   1725       MCOperand &Rd = Inst.getOperand(0);
   1726       MCOperand &Rs = Inst.getOperand(1);
   1727       TmpInst.addOperand(Rd);
   1728       TmpInst.addOperand(Rs);
   1729     } else {
   1730       Imm.setExpr(HexagonMCExpr::create(
   1731           MCBinaryExpr::createSub(Imm.getExpr(),
   1732                                   MCConstantExpr::create(1, Context), Context),
   1733           Context));
   1734       TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
   1735       MCOperand &Rd = Inst.getOperand(0);
   1736       MCOperand &Rs = Inst.getOperand(1);
   1737       TmpInst.addOperand(Rd);
   1738       TmpInst.addOperand(Rs);
   1739       TmpInst.addOperand(Imm);
   1740     }
   1741     Inst = TmpInst;
   1742     break;
   1743   }
   1744 
   1745   case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
   1746     MCOperand &Rdd = Inst.getOperand(0);
   1747     MCOperand &Rss = Inst.getOperand(1);
   1748     MCOperand &Imm = Inst.getOperand(2);
   1749     int64_t Value;
   1750     bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
   1751     if (!Absolute)
   1752       return Match_InvalidOperand;
   1753     if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
   1754       MCInst TmpInst;
   1755       unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
   1756       std::string R1 = r + utostr(RegPairNum + 1);
   1757       StringRef Reg1(R1);
   1758       Rss.setReg(matchRegister(Reg1));
   1759       // Add a new operand for the second register in the pair.
   1760       std::string R2 = r + utostr(RegPairNum);
   1761       StringRef Reg2(R2);
   1762       TmpInst.setOpcode(Hexagon::A2_combinew);
   1763       TmpInst.addOperand(Rdd);
   1764       TmpInst.addOperand(Rss);
   1765       TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
   1766       Inst = TmpInst;
   1767     } else {
   1768       Imm.setExpr(HexagonMCExpr::create(
   1769           MCBinaryExpr::createSub(Imm.getExpr(),
   1770                                   MCConstantExpr::create(1, Context), Context),
   1771           Context));
   1772       Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
   1773     }
   1774     break;
   1775   }
   1776 
   1777   case Hexagon::A4_boundscheck: {
   1778     MCOperand &Rs = Inst.getOperand(1);
   1779     unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
   1780     if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
   1781       Inst.setOpcode(Hexagon::A4_boundscheck_hi);
   1782       std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
   1783       StringRef RegPair = Name;
   1784       Rs.setReg(matchRegister(RegPair));
   1785     } else { // raw:lo
   1786       Inst.setOpcode(Hexagon::A4_boundscheck_lo);
   1787       std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
   1788       StringRef RegPair = Name;
   1789       Rs.setReg(matchRegister(RegPair));
   1790     }
   1791     break;
   1792   }
   1793 
   1794   case Hexagon::A2_addsp: {
   1795     MCOperand &Rs = Inst.getOperand(1);
   1796     unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
   1797     if (RegNum & 1) { // Odd mapped to raw:hi
   1798       Inst.setOpcode(Hexagon::A2_addsph);
   1799       std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
   1800       StringRef RegPair = Name;
   1801       Rs.setReg(matchRegister(RegPair));
   1802     } else { // Even mapped raw:lo
   1803       Inst.setOpcode(Hexagon::A2_addspl);
   1804       std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
   1805       StringRef RegPair = Name;
   1806       Rs.setReg(matchRegister(RegPair));
   1807     }
   1808     break;
   1809   }
   1810 
   1811   case Hexagon::M2_vrcmpys_s1: {
   1812     MCOperand &Rt = Inst.getOperand(2);
   1813     unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
   1814     if (RegNum & 1) { // Odd mapped to sat:raw:hi
   1815       Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
   1816       std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
   1817       StringRef RegPair = Name;
   1818       Rt.setReg(matchRegister(RegPair));
   1819     } else { // Even mapped sat:raw:lo
   1820       Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
   1821       std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
   1822       StringRef RegPair = Name;
   1823       Rt.setReg(matchRegister(RegPair));
   1824     }
   1825     break;
   1826   }
   1827 
   1828   case Hexagon::M2_vrcmpys_acc_s1: {
   1829     MCInst TmpInst;
   1830     MCOperand &Rxx = Inst.getOperand(0);
   1831     MCOperand &Rss = Inst.getOperand(2);
   1832     MCOperand &Rt = Inst.getOperand(3);
   1833     unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
   1834     if (RegNum & 1) { // Odd mapped to sat:raw:hi
   1835       TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
   1836       std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
   1837       StringRef RegPair = Name;
   1838       Rt.setReg(matchRegister(RegPair));
   1839     } else { // Even mapped sat:raw:lo
   1840       TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
   1841       std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
   1842       StringRef RegPair = Name;
   1843       Rt.setReg(matchRegister(RegPair));
   1844     }
   1845     // Registers are in different positions
   1846     TmpInst.addOperand(Rxx);
   1847     TmpInst.addOperand(Rxx);
   1848     TmpInst.addOperand(Rss);
   1849     TmpInst.addOperand(Rt);
   1850     Inst = TmpInst;
   1851     break;
   1852   }
   1853 
   1854   case Hexagon::M2_vrcmpys_s1rp: {
   1855     MCOperand &Rt = Inst.getOperand(2);
   1856     unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
   1857     if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
   1858       Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
   1859       std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
   1860       StringRef RegPair = Name;
   1861       Rt.setReg(matchRegister(RegPair));
   1862     } else { // Even mapped rnd:sat:raw:lo
   1863       Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
   1864       std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
   1865       StringRef RegPair = Name;
   1866       Rt.setReg(matchRegister(RegPair));
   1867     }
   1868     break;
   1869   }
   1870 
   1871   case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
   1872     MCOperand &Imm = Inst.getOperand(2);
   1873     int64_t Value;
   1874     bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
   1875     if (!Absolute)
   1876       return Match_InvalidOperand;
   1877     if (Value == 0)
   1878       Inst.setOpcode(Hexagon::S2_vsathub);
   1879     else {
   1880       Imm.setExpr(HexagonMCExpr::create(
   1881           MCBinaryExpr::createSub(Imm.getExpr(),
   1882                                   MCConstantExpr::create(1, Context), Context),
   1883           Context));
   1884       Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
   1885     }
   1886     break;
   1887   }
   1888 
   1889   case Hexagon::S5_vasrhrnd_goodsyntax: {
   1890     MCOperand &Rdd = Inst.getOperand(0);
   1891     MCOperand &Rss = Inst.getOperand(1);
   1892     MCOperand &Imm = Inst.getOperand(2);
   1893     int64_t Value;
   1894     bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
   1895     if (!Absolute)
   1896       return Match_InvalidOperand;
   1897     if (Value == 0) {
   1898       MCInst TmpInst;
   1899       unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
   1900       std::string R1 = r + utostr(RegPairNum + 1);
   1901       StringRef Reg1(R1);
   1902       Rss.setReg(matchRegister(Reg1));
   1903       // Add a new operand for the second register in the pair.
   1904       std::string R2 = r + utostr(RegPairNum);
   1905       StringRef Reg2(R2);
   1906       TmpInst.setOpcode(Hexagon::A2_combinew);
   1907       TmpInst.addOperand(Rdd);
   1908       TmpInst.addOperand(Rss);
   1909       TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
   1910       Inst = TmpInst;
   1911     } else {
   1912       Imm.setExpr(HexagonMCExpr::create(
   1913           MCBinaryExpr::createSub(Imm.getExpr(),
   1914                                   MCConstantExpr::create(1, Context), Context),
   1915           Context));
   1916       Inst.setOpcode(Hexagon::S5_vasrhrnd);
   1917     }
   1918     break;
   1919   }
   1920 
   1921   case Hexagon::A2_not: {
   1922     MCInst TmpInst;
   1923     MCOperand &Rd = Inst.getOperand(0);
   1924     MCOperand &Rs = Inst.getOperand(1);
   1925     TmpInst.setOpcode(Hexagon::A2_subri);
   1926     TmpInst.addOperand(Rd);
   1927     TmpInst.addOperand(MCOperand::createExpr(
   1928         HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));
   1929     TmpInst.addOperand(Rs);
   1930     Inst = TmpInst;
   1931     break;
   1932   }
   1933   case Hexagon::PS_loadrubabs:
   1934     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
   1935       Inst.setOpcode(Hexagon::L2_loadrubgp);
   1936     break;
   1937   case Hexagon::PS_loadrbabs:
   1938     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
   1939       Inst.setOpcode(Hexagon::L2_loadrbgp);
   1940     break;
   1941   case Hexagon::PS_loadruhabs:
   1942     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
   1943       Inst.setOpcode(Hexagon::L2_loadruhgp);
   1944     break;
   1945   case Hexagon::PS_loadrhabs:
   1946     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
   1947       Inst.setOpcode(Hexagon::L2_loadrhgp);
   1948     break;
   1949   case Hexagon::PS_loadriabs:
   1950     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
   1951       Inst.setOpcode(Hexagon::L2_loadrigp);
   1952     break;
   1953   case Hexagon::PS_loadrdabs:
   1954     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
   1955       Inst.setOpcode(Hexagon::L2_loadrdgp);
   1956     break;
   1957   case Hexagon::PS_storerbabs:
   1958     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
   1959       Inst.setOpcode(Hexagon::S2_storerbgp);
   1960     break;
   1961   case Hexagon::PS_storerhabs:
   1962     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
   1963       Inst.setOpcode(Hexagon::S2_storerhgp);
   1964     break;
   1965   case Hexagon::PS_storerfabs:
   1966     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
   1967       Inst.setOpcode(Hexagon::S2_storerfgp);
   1968     break;
   1969   case Hexagon::PS_storeriabs:
   1970     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
   1971       Inst.setOpcode(Hexagon::S2_storerigp);
   1972     break;
   1973   case Hexagon::PS_storerdabs:
   1974     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
   1975       Inst.setOpcode(Hexagon::S2_storerdgp);
   1976     break;
   1977   case Hexagon::PS_storerbnewabs:
   1978     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
   1979       Inst.setOpcode(Hexagon::S2_storerbnewgp);
   1980     break;
   1981   case Hexagon::PS_storerhnewabs:
   1982     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
   1983       Inst.setOpcode(Hexagon::S2_storerhnewgp);
   1984     break;
   1985   case Hexagon::PS_storerinewabs:
   1986     if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
   1987       Inst.setOpcode(Hexagon::S2_storerinewgp);
   1988     break;
   1989   case Hexagon::A2_zxtb: {
   1990     Inst.setOpcode(Hexagon::A2_andir);
   1991     Inst.addOperand(
   1992         MCOperand::createExpr(MCConstantExpr::create(255, Context)));
   1993     break;
   1994   }
   1995   } // switch
   1996 
   1997   return Match_Success;
   1998 }
   1999 
   2000 unsigned HexagonAsmParser::matchRegister(StringRef Name) {
   2001   if (unsigned Reg = MatchRegisterName(Name))
   2002     return Reg;
   2003   return MatchRegisterAltName(Name);
   2004 }
   2005