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