//===-- HexagonAsmParser.cpp - Parse Hexagon asm to MCInst instructions----===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "HexagonTargetStreamer.h"
#include "MCTargetDesc/HexagonMCChecker.h"
#include "MCTargetDesc/HexagonMCELFStreamer.h"
#include "MCTargetDesc/HexagonMCExpr.h"
#include "MCTargetDesc/HexagonMCInstrInfo.h"
#include "MCTargetDesc/HexagonMCTargetDesc.h"
#include "MCTargetDesc/HexagonShuffler.h"
#include "TargetInfo/HexagonTargetInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>

#define DEBUG_TYPE "mcasmparser"

using namespace llvm;

static cl::opt<bool> WarnMissingParenthesis(
    "mwarn-missing-parenthesis",
    cl::desc("Warn for missing parenthesis around predicate registers"),
    cl::init(true));
static cl::opt<bool> ErrorMissingParenthesis(
    "merror-missing-parenthesis",
    cl::desc("Error for missing parenthesis around predicate registers"),
    cl::init(false));
static cl::opt<bool> WarnSignedMismatch(
    "mwarn-sign-mismatch",
    cl::desc("Warn for mismatching a signed and unsigned value"),
    cl::init(false));
static cl::opt<bool> WarnNoncontigiousRegister(
    "mwarn-noncontigious-register",
    cl::desc("Warn for register names that arent contigious"), cl::init(true));
static cl::opt<bool> ErrorNoncontigiousRegister(
    "merror-noncontigious-register",
    cl::desc("Error for register names that aren't contigious"),
    cl::init(false));

namespace {

struct HexagonOperand;

class HexagonAsmParser : public MCTargetAsmParser {

  HexagonTargetStreamer &getTargetStreamer() {
    MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
    return static_cast<HexagonTargetStreamer &>(TS);
  }

  MCAsmParser &Parser;
  MCInst MCB;
  bool InBrackets;

  MCAsmParser &getParser() const { return Parser; }
  MCAssembler *getAssembler() const {
    MCAssembler *Assembler = nullptr;
    // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
    if (!Parser.getStreamer().hasRawTextSupport()) {
      MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
      Assembler = &MES->getAssembler();
    }
    return Assembler;
  }

  MCAsmLexer &getLexer() const { return Parser.getLexer(); }

  bool equalIsAsmAssignment() override { return false; }
  bool isLabel(AsmToken &Token) override;

  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
  bool ParseDirectiveFalign(unsigned Size, SMLoc L);

  bool parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
                     SMLoc &EndLoc) override;
  OperandMatchResultTy tryParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
                                        SMLoc &EndLoc) override;
  bool ParseDirectiveSubsection(SMLoc L);
  bool ParseDirectiveComm(bool IsLocal, SMLoc L);
  bool RegisterMatchesArch(unsigned MatchNum) const;

  bool matchBundleOptions();
  bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);
  bool finishBundle(SMLoc IDLoc, MCStreamer &Out);
  void canonicalizeImmediates(MCInst &MCI);
  bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,
                           OperandVector &InstOperands, uint64_t &ErrorInfo,
                           bool MatchingInlineAsm);
  void eatToEndOfPacket();
  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                               OperandVector &Operands, MCStreamer &Out,
                               uint64_t &ErrorInfo,
                               bool MatchingInlineAsm) override;

  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
                                      unsigned Kind) override;
  bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
  int processInstruction(MCInst &Inst, OperandVector const &Operands,
                         SMLoc IDLoc);

  unsigned matchRegister(StringRef Name);

/// @name Auto-generated Match Functions
/// {

#define GET_ASSEMBLER_HEADER
#include "HexagonGenAsmMatcher.inc"

  /// }

public:
  HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,
                   const MCInstrInfo &MII, const MCTargetOptions &Options)
    : MCTargetAsmParser(Options, _STI, MII), Parser(_Parser),
      InBrackets(false) {
    MCB.setOpcode(Hexagon::BUNDLE);
    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));

    Parser.addAliasForDirective(".half", ".2byte");
    Parser.addAliasForDirective(".hword", ".2byte");
    Parser.addAliasForDirective(".word", ".4byte");

    MCAsmParserExtension::Initialize(_Parser);
  }

  bool splitIdentifier(OperandVector &Operands);
  bool parseOperand(OperandVector &Operands);
  bool parseInstruction(OperandVector &Operands);
  bool implicitExpressionLocation(OperandVector &Operands);
  bool parseExpressionOrOperand(OperandVector &Operands);
  bool parseExpression(MCExpr const *&Expr);

  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                        SMLoc NameLoc, OperandVector &Operands) override {
    llvm_unreachable("Unimplemented");
  }

  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
                        OperandVector &Operands) override;

  bool ParseDirective(AsmToken DirectiveID) override;
};

/// HexagonOperand - Instances of this class represent a parsed Hexagon machine
/// instruction.
struct HexagonOperand : public MCParsedAsmOperand {
  enum KindTy { Token, Immediate, Register } Kind;
  MCContext &Context;

  SMLoc StartLoc, EndLoc;

  struct TokTy {
    const char *Data;
    unsigned Length;
  };

  struct RegTy {
    unsigned RegNum;
  };

  struct ImmTy {
    const MCExpr *Val;
  };

  union {
    struct TokTy Tok;
    struct RegTy Reg;
    struct ImmTy Imm;
  };

  HexagonOperand(KindTy K, MCContext &Context) : Kind(K), Context(Context) {}

public:
  HexagonOperand(const HexagonOperand &o)
      : MCParsedAsmOperand(), Context(o.Context) {
    Kind = o.Kind;
    StartLoc = o.StartLoc;
    EndLoc = o.EndLoc;
    switch (Kind) {
    case Register:
      Reg = o.Reg;
      break;
    case Immediate:
      Imm = o.Imm;
      break;
    case Token:
      Tok = o.Tok;
      break;
    }
  }

  /// getStartLoc - Get the location of the first token of this operand.
  SMLoc getStartLoc() const override { return StartLoc; }

  /// getEndLoc - Get the location of the last token of this operand.
  SMLoc getEndLoc() const override { return EndLoc; }

  unsigned getReg() const override {
    assert(Kind == Register && "Invalid access!");
    return Reg.RegNum;
  }

  const MCExpr *getImm() const {
    assert(Kind == Immediate && "Invalid access!");
    return Imm.Val;
  }

  bool isToken() const override { return Kind == Token; }
  bool isImm() const override { return Kind == Immediate; }
  bool isMem() const override { llvm_unreachable("No isMem"); }
  bool isReg() const override { return Kind == Register; }

  bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
                     bool isRelocatable, bool Extendable) const {
    if (Kind == Immediate) {
      const MCExpr *myMCExpr = &HexagonMCInstrInfo::getExpr(*getImm());
      if (HexagonMCInstrInfo::mustExtend(*Imm.Val) && !Extendable)
        return false;
      int64_t Res;
      if (myMCExpr->evaluateAsAbsolute(Res)) {
        int bits = immBits + zeroBits;
        // Field bit range is zerobits + bits
        // zeroBits must be 0
        if (Res & ((1 << zeroBits) - 1))
          return false;
        if (isSigned) {
          if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
            return true;
        } else {
          if (bits == 64)
            return true;
          if (Res >= 0)
            return ((uint64_t)Res < (uint64_t)(1ULL << bits));
          else {
            const int64_t high_bit_set = 1ULL << 63;
            const uint64_t mask = (high_bit_set >> (63 - bits));
            return (((uint64_t)Res & mask) == mask);
          }
        }
      } else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)
        return true;
      else if (myMCExpr->getKind() == MCExpr::Binary ||
               myMCExpr->getKind() == MCExpr::Unary)
        return true;
    }
    return false;
  }

  bool isa30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
  bool isb30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
  bool isb15_2Imm() const { return CheckImmRange(15, 2, true, true, false); }
  bool isb13_2Imm() const { return CheckImmRange(13, 2, true, true, false); }

  bool ism32_0Imm() const { return true; }

  bool isf32Imm() const { return false; }
  bool isf64Imm() const { return false; }
  bool iss32_0Imm() const { return true; }
  bool iss31_1Imm() const { return true; }
  bool iss30_2Imm() const { return true; }
  bool iss29_3Imm() const { return true; }
  bool iss27_2Imm() const { return CheckImmRange(27, 2, true, true, false); }
  bool iss10_0Imm() const { return CheckImmRange(10, 0, true, false, false); }
  bool iss10_6Imm() const { return CheckImmRange(10, 6, true, false, false); }
  bool iss9_0Imm() const { return CheckImmRange(9, 0, true, false, false); }
  bool iss8_0Imm() const { return CheckImmRange(8, 0, true, false, false); }
  bool iss8_0Imm64() const { return CheckImmRange(8, 0, true, true, false); }
  bool iss7_0Imm() const { return CheckImmRange(7, 0, true, false, false); }
  bool iss6_0Imm() const { return CheckImmRange(6, 0, true, false, false); }
  bool iss6_3Imm() const { return CheckImmRange(6, 3, true, false, false); }
  bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }
  bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }
  bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }
  bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }
  bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }

  bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }
  bool isu32_0Imm() const { return true; }
  bool isu31_1Imm() const { return true; }
  bool isu30_2Imm() const { return true; }
  bool isu29_3Imm() const { return true; }
  bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }
  bool isu16_0Imm() const { return CheckImmRange(16, 0, false, true, false); }
  bool isu16_1Imm() const { return CheckImmRange(16, 1, false, true, false); }
  bool isu16_2Imm() const { return CheckImmRange(16, 2, false, true, false); }
  bool isu16_3Imm() const { return CheckImmRange(16, 3, false, true, false); }
  bool isu11_3Imm() const { return CheckImmRange(11, 3, false, false, false); }
  bool isu10_0Imm() const { return CheckImmRange(10, 0, false, false, false); }
  bool isu9_0Imm() const { return CheckImmRange(9, 0, false, false, false); }
  bool isu8_0Imm() const { return CheckImmRange(8, 0, false, false, false); }
  bool isu7_0Imm() const { return CheckImmRange(7, 0, false, false, false); }
  bool isu6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }
  bool isu6_1Imm() const { return CheckImmRange(6, 1, false, false, false); }
  bool isu6_2Imm() const { return CheckImmRange(6, 2, false, false, false); }
  bool isu6_3Imm() const { return CheckImmRange(6, 3, false, false, false); }
  bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }
  bool isu5_2Imm() const { return CheckImmRange(5, 2, false, false, false); }
  bool isu5_3Imm() const { return CheckImmRange(5, 3, false, false, false); }
  bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }
  bool isu4_2Imm() const { return CheckImmRange(4, 2, false, false, false); }
  bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }
  bool isu3_1Imm() const { return CheckImmRange(3, 1, false, false, false); }
  bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }
  bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }

  bool isn1Const() const {
    if (!isImm())
      return false;
    int64_t Value;
    if (!getImm()->evaluateAsAbsolute(Value))
      return false;
    return Value == -1;
  }
  bool issgp10Const() const {
    if (!isReg())
      return false;
    return getReg() == Hexagon::SGP1_0;
  }
  bool iss11_0Imm() const {
    return CheckImmRange(11 + 26, 0, true, true, true);
  }
  bool iss11_1Imm() const {
    return CheckImmRange(11 + 26, 1, true, true, true);
  }
  bool iss11_2Imm() const {
    return CheckImmRange(11 + 26, 2, true, true, true);
  }
  bool iss11_3Imm() const {
    return CheckImmRange(11 + 26, 3, true, true, true);
  }
  bool isu32_0MustExt() const { return isImm(); }

  void addRegOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    Inst.addOperand(MCOperand::createReg(getReg()));
  }

  void addImmOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    Inst.addOperand(MCOperand::createExpr(getImm()));
  }

  void addSignedImmOperands(MCInst &Inst, unsigned N) const {
    assert(N == 1 && "Invalid number of operands!");
    HexagonMCExpr *Expr =
        const_cast<HexagonMCExpr *>(cast<HexagonMCExpr>(getImm()));
    int64_t Value;
    if (!Expr->evaluateAsAbsolute(Value)) {
      Inst.addOperand(MCOperand::createExpr(Expr));
      return;
    }
    int64_t Extended = SignExtend64(Value, 32);
    HexagonMCExpr *NewExpr = HexagonMCExpr::create(
        MCConstantExpr::create(Extended, Context), Context);
    if ((Extended < 0) != (Value < 0))
      NewExpr->setSignMismatch();
    NewExpr->setMustExtend(Expr->mustExtend());
    NewExpr->setMustNotExtend(Expr->mustNotExtend());
    Inst.addOperand(MCOperand::createExpr(NewExpr));
  }

  void addn1ConstOperands(MCInst &Inst, unsigned N) const {
    addImmOperands(Inst, N);
  }
  void addsgp10ConstOperands(MCInst &Inst, unsigned N) const {
    addRegOperands(Inst, N);
  }

  StringRef getToken() const {
    assert(Kind == Token && "Invalid access!");
    return StringRef(Tok.Data, Tok.Length);
  }

  void print(raw_ostream &OS) const override;

  static std::unique_ptr<HexagonOperand> CreateToken(MCContext &Context,
                                                     StringRef Str, SMLoc S) {
    HexagonOperand *Op = new HexagonOperand(Token, Context);
    Op->Tok.Data = Str.data();
    Op->Tok.Length = Str.size();
    Op->StartLoc = S;
    Op->EndLoc = S;
    return std::unique_ptr<HexagonOperand>(Op);
  }

  static std::unique_ptr<HexagonOperand>
  CreateReg(MCContext &Context, unsigned RegNum, SMLoc S, SMLoc E) {
    HexagonOperand *Op = new HexagonOperand(Register, Context);
    Op->Reg.RegNum = RegNum;
    Op->StartLoc = S;
    Op->EndLoc = E;
    return std::unique_ptr<HexagonOperand>(Op);
  }

  static std::unique_ptr<HexagonOperand>
  CreateImm(MCContext &Context, const MCExpr *Val, SMLoc S, SMLoc E) {
    HexagonOperand *Op = new HexagonOperand(Immediate, Context);
    Op->Imm.Val = Val;
    Op->StartLoc = S;
    Op->EndLoc = E;
    return std::unique_ptr<HexagonOperand>(Op);
  }
};

} // end anonymous namespace

void HexagonOperand::print(raw_ostream &OS) const {
  switch (Kind) {
  case Immediate:
    getImm()->print(OS, nullptr);
    break;
  case Register:
    OS << "<register R";
    OS << getReg() << ">";
    break;
  case Token:
    OS << "'" << getToken() << "'";
    break;
  }
}

bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
  LLVM_DEBUG(dbgs() << "Bundle:");
  LLVM_DEBUG(MCB.dump_pretty(dbgs()));
  LLVM_DEBUG(dbgs() << "--\n");

  MCB.setLoc(IDLoc);

  // Check the bundle for errors.
  const MCRegisterInfo *RI = getContext().getRegisterInfo();
  MCSubtargetInfo const &STI = getSTI();

  MCInst OrigBundle = MCB;
  HexagonMCChecker Check(getContext(), MII, STI, MCB, *RI, true);

  bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(
      MII, STI, getContext(), MCB, &Check, true);

  if (CheckOk) {
    if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
      assert(!HexagonMCInstrInfo::isInnerLoop(MCB));
      assert(!HexagonMCInstrInfo::isOuterLoop(MCB));
      // Empty packets are valid yet aren't emitted
      return false;
    }

    assert(HexagonMCInstrInfo::isBundle(MCB));

    Out.emitInstruction(MCB, STI);
  } else
    return true; // Error

  return false; // No error
}

bool HexagonAsmParser::matchBundleOptions() {
  MCAsmParser &Parser = getParser();
  while (true) {
    if (!Parser.getTok().is(AsmToken::Colon))
      return false;
    Lex();
    char const *MemNoShuffMsg =
        "invalid instruction packet: mem_noshuf specifier not "
        "supported with this architecture";
    StringRef Option = Parser.getTok().getString();
    auto IDLoc = Parser.getTok().getLoc();
    if (Option.compare_insensitive("endloop01") == 0) {
      HexagonMCInstrInfo::setInnerLoop(MCB);
      HexagonMCInstrInfo::setOuterLoop(MCB);
    } else if (Option.compare_insensitive("endloop0") == 0) {
      HexagonMCInstrInfo::setInnerLoop(MCB);
    } else if (Option.compare_insensitive("endloop1") == 0) {
      HexagonMCInstrInfo::setOuterLoop(MCB);
    } else if (Option.compare_insensitive("mem_noshuf") == 0) {
      if (getSTI().getFeatureBits()[Hexagon::FeatureMemNoShuf])
        HexagonMCInstrInfo::setMemReorderDisabled(MCB);
      else
        return getParser().Error(IDLoc, MemNoShuffMsg);
    } else if (Option.compare_insensitive("mem_no_order") == 0) {
      // Nothing.
    } else
      return getParser().Error(IDLoc, llvm::Twine("'") + Option +
                                          "' is not a valid bundle option");
    Lex();
  }
}

// For instruction aliases, immediates are generated rather than
// MCConstantExpr.  Convert them for uniform MCExpr.
// Also check for signed/unsigned mismatches and warn
void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
  MCInst NewInst;
  NewInst.setOpcode(MCI.getOpcode());
  for (MCOperand &I : MCI)
    if (I.isImm()) {
      int64_t Value(I.getImm());
      NewInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
          MCConstantExpr::create(Value, getContext()), getContext())));
    } else {
      if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&
          WarnSignedMismatch)
        Warning(MCI.getLoc(), "Signed/Unsigned mismatch");
      NewInst.addOperand(I);
    }
  MCI = NewInst;
}

bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
                                           OperandVector &InstOperands,
                                           uint64_t &ErrorInfo,
                                           bool MatchingInlineAsm) {
  // Perform matching with tablegen asmmatcher generated function
  int result =
      MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
  if (result == Match_Success) {
    MCI.setLoc(IDLoc);
    canonicalizeImmediates(MCI);
    result = processInstruction(MCI, InstOperands, IDLoc);

    LLVM_DEBUG(dbgs() << "Insn:");
    LLVM_DEBUG(MCI.dump_pretty(dbgs()));
    LLVM_DEBUG(dbgs() << "\n\n");

    MCI.setLoc(IDLoc);
  }

  // Create instruction operand for bundle instruction
  //   Break this into a separate function Code here is less readable
  //   Think about how to get an instruction error to report correctly.
  //   SMLoc will return the "{"
  switch (result) {
  default:
    break;
  case Match_Success:
    return false;
  case Match_MissingFeature:
    return Error(IDLoc, "invalid instruction");
  case Match_MnemonicFail:
    return Error(IDLoc, "unrecognized instruction");
  case Match_InvalidOperand:
    [[fallthrough]];
  case Match_InvalidTiedOperand:
    SMLoc ErrorLoc = IDLoc;
    if (ErrorInfo != ~0U) {
      if (ErrorInfo >= InstOperands.size())
        return Error(IDLoc, "too few operands for instruction");

      ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
                     ->getStartLoc();
      if (ErrorLoc == SMLoc())
        ErrorLoc = IDLoc;
    }
    return Error(ErrorLoc, "invalid operand for instruction");
  }
  llvm_unreachable("Implement any new match types added!");
}

void HexagonAsmParser::eatToEndOfPacket() {
  assert(InBrackets);
  MCAsmLexer &Lexer = getLexer();
  while (!Lexer.is(AsmToken::RCurly))
    Lexer.Lex();
  Lexer.Lex();
  InBrackets = false;
}

bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                               OperandVector &Operands,
                                               MCStreamer &Out,
                                               uint64_t &ErrorInfo,
                                               bool MatchingInlineAsm) {
  if (!InBrackets) {
    MCB.clear();
    MCB.addOperand(MCOperand::createImm(0));
  }
  HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
  if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
    assert(Operands.size() == 1 && "Brackets should be by themselves");
    if (InBrackets) {
      getParser().Error(IDLoc, "Already in a packet");
      InBrackets = false;
      return true;
    }
    InBrackets = true;
    return false;
  }
  if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
    assert(Operands.size() == 1 && "Brackets should be by themselves");
    if (!InBrackets) {
      getParser().Error(IDLoc, "Not in a packet");
      return true;
    }
    InBrackets = false;
    if (matchBundleOptions())
      return true;
    return finishBundle(IDLoc, Out);
  }
  MCInst *SubInst = getParser().getContext().createMCInst();
  if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
                          MatchingInlineAsm)) {
    if (InBrackets)
      eatToEndOfPacket();
    return true;
  }
  HexagonMCInstrInfo::extendIfNeeded(
      getParser().getContext(), MII, MCB, *SubInst);
  MCB.addOperand(MCOperand::createInst(SubInst));
  if (!InBrackets)
    return finishBundle(IDLoc, Out);
  return false;
}

/// ParseDirective parses the Hexagon specific directives
bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
  StringRef IDVal = DirectiveID.getIdentifier();
  if (IDVal.lower() == ".falign")
    return ParseDirectiveFalign(256, DirectiveID.getLoc());
  if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
    return ParseDirectiveComm(true, DirectiveID.getLoc());
  if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
    return ParseDirectiveComm(false, DirectiveID.getLoc());
  if (IDVal.lower() == ".subsection")
    return ParseDirectiveSubsection(DirectiveID.getLoc());

  return true;
}
bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
  const MCExpr *Subsection = nullptr;
  int64_t Res;

  assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
         "Invalid subsection directive");
  getParser().parseExpression(Subsection);

  if (!Subsection->evaluateAsAbsolute(Res))
    return Error(L, "Cannot evaluate subsection number");

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in directive");

  // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
  // negative subsections together and in the same order but at the opposite
  // end of the section.  Only legacy hexagon-gcc created assembly code
  // used negative subsections.
  if ((Res < 0) && (Res > -8193))
    Subsection = HexagonMCExpr::create(
        MCConstantExpr::create(8192 + Res, getContext()), getContext());

  getStreamer().subSection(Subsection);
  return false;
}

///  ::= .falign [expression]
bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {

  int64_t MaxBytesToFill = 15;

  // if there is an argument
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
    const MCExpr *Value;
    SMLoc ExprLoc = L;

    // Make sure we have a number (false is returned if expression is a number)
    if (!getParser().parseExpression(Value)) {
      // Make sure this is a number that is in range
      auto *MCE = cast<MCConstantExpr>(Value);
      uint64_t IntValue = MCE->getValue();
      if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
        return Error(ExprLoc, "literal value out of range (256) for falign");
      MaxBytesToFill = IntValue;
      Lex();
    } else {
      return Error(ExprLoc, "not a valid expression for falign directive");
    }
  }

  getTargetStreamer().emitFAlign(16, MaxBytesToFill);
  Lex();

  return false;
}

// This is largely a copy of AsmParser's ParseDirectiveComm extended to
// accept a 3rd argument, AccessAlignment which indicates the smallest
// memory access made to the symbol, expressed in bytes.  If no
// AccessAlignment is specified it defaults to the Alignment Value.
// Hexagon's .lcomm:
//   .lcomm Symbol, Length, Alignment, AccessAlignment
bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
  // FIXME: need better way to detect if AsmStreamer (upstream removed
  // getKind())
  if (getStreamer().hasRawTextSupport())
    return true; // Only object file output requires special treatment.

  StringRef Name;
  if (getParser().parseIdentifier(Name))
    return TokError("expected identifier in directive");
  // Handle the identifier as the key symbol.
  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);

  if (getLexer().isNot(AsmToken::Comma))
    return TokError("unexpected token in directive");
  Lex();

  int64_t Size;
  SMLoc SizeLoc = getLexer().getLoc();
  if (getParser().parseAbsoluteExpression(Size))
    return true;

  int64_t ByteAlignment = 1;
  SMLoc ByteAlignmentLoc;
  if (getLexer().is(AsmToken::Comma)) {
    Lex();
    ByteAlignmentLoc = getLexer().getLoc();
    if (getParser().parseAbsoluteExpression(ByteAlignment))
      return true;
    if (!isPowerOf2_64(ByteAlignment))
      return Error(ByteAlignmentLoc, "alignment must be a power of 2");
  }

  int64_t AccessAlignment = 0;
  if (getLexer().is(AsmToken::Comma)) {
    // The optional access argument specifies the size of the smallest memory
    //   access to be made to the symbol, expressed in bytes.
    SMLoc AccessAlignmentLoc;
    Lex();
    AccessAlignmentLoc = getLexer().getLoc();
    if (getParser().parseAbsoluteExpression(AccessAlignment))
      return true;

    if (!isPowerOf2_64(AccessAlignment))
      return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
  }

  if (getLexer().isNot(AsmToken::EndOfStatement))
    return TokError("unexpected token in '.comm' or '.lcomm' directive");

  Lex();

  // NOTE: a size of zero for a .comm should create a undefined symbol
  // but a size of .lcomm creates a bss symbol of size zero.
  if (Size < 0)
    return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
                          "be less than zero");

  // NOTE: The alignment in the directive is a power of 2 value, the assembler
  // may internally end up wanting an alignment in bytes.
  // FIXME: Diagnose overflow.
  if (ByteAlignment < 0)
    return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
                                   "alignment, can't be less than zero");

  if (!Sym->isUndefined())
    return Error(Loc, "invalid symbol redefinition");

  HexagonMCELFStreamer &HexagonELFStreamer =
      static_cast<HexagonMCELFStreamer &>(getStreamer());
  if (IsLocal) {
    HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(
        Sym, Size, Align(ByteAlignment), AccessAlignment);
    return false;
  }

  HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, Align(ByteAlignment),
                                               AccessAlignment);
  return false;
}

// validate register against architecture
bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
  if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))
    if (!getSTI().getFeatureBits()[Hexagon::ArchV62])
      return false;
  return true;
}

// extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonAsmLexer();

/// Force static initialization.
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonAsmParser() {
  RegisterMCAsmParser<HexagonAsmParser> X(getTheHexagonTarget());
}

#define GET_MATCHER_IMPLEMENTATION
#define GET_REGISTER_MATCHER
#include "HexagonGenAsmMatcher.inc"

static bool previousEqual(OperandVector &Operands, size_t Index,
                          StringRef String) {
  if (Index >= Operands.size())
    return false;
  MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
  if (!Operand.isToken())
    return false;
  return static_cast<HexagonOperand &>(Operand).getToken().equals_insensitive(
      String);
}

static bool previousIsLoop(OperandVector &Operands, size_t Index) {
  return previousEqual(Operands, Index, "loop0") ||
         previousEqual(Operands, Index, "loop1") ||
         previousEqual(Operands, Index, "sp1loop0") ||
         previousEqual(Operands, Index, "sp2loop0") ||
         previousEqual(Operands, Index, "sp3loop0");
}

bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
  AsmToken const &Token = getParser().getTok();
  StringRef String = Token.getString();
  SMLoc Loc = Token.getLoc();
  Lex();
  do {
    std::pair<StringRef, StringRef> HeadTail = String.split('.');
    if (!HeadTail.first.empty())
      Operands.push_back(
          HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
    if (!HeadTail.second.empty())
      Operands.push_back(HexagonOperand::CreateToken(
          getContext(), String.substr(HeadTail.first.size(), 1), Loc));
    String = HeadTail.second;
  } while (!String.empty());
  return false;
}

bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
  MCRegister Register;
  SMLoc Begin;
  SMLoc End;
  MCAsmLexer &Lexer = getLexer();
  if (!parseRegister(Register, Begin, End)) {
    if (!ErrorMissingParenthesis)
      switch (Register) {
      default:
        break;
      case Hexagon::P0:
      case Hexagon::P1:
      case Hexagon::P2:
      case Hexagon::P3:
        if (previousEqual(Operands, 0, "if")) {
          if (WarnMissingParenthesis)
            Warning(Begin, "Missing parenthesis around predicate register");
          static char const *LParen = "(";
          static char const *RParen = ")";
          Operands.push_back(
              HexagonOperand::CreateToken(getContext(), LParen, Begin));
          Operands.push_back(
              HexagonOperand::CreateReg(getContext(), Register, Begin, End));
          const AsmToken &MaybeDotNew = Lexer.getTok();
          if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
              MaybeDotNew.getString().equals_insensitive(".new"))
            splitIdentifier(Operands);
          Operands.push_back(
              HexagonOperand::CreateToken(getContext(), RParen, Begin));
          return false;
        }
        if (previousEqual(Operands, 0, "!") &&
            previousEqual(Operands, 1, "if")) {
          if (WarnMissingParenthesis)
            Warning(Begin, "Missing parenthesis around predicate register");
          static char const *LParen = "(";
          static char const *RParen = ")";
          Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(
                                                  getContext(), LParen, Begin));
          Operands.push_back(
              HexagonOperand::CreateReg(getContext(), Register, Begin, End));
          const AsmToken &MaybeDotNew = Lexer.getTok();
          if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
              MaybeDotNew.getString().equals_insensitive(".new"))
            splitIdentifier(Operands);
          Operands.push_back(
              HexagonOperand::CreateToken(getContext(), RParen, Begin));
          return false;
        }
        break;
      }
    Operands.push_back(
        HexagonOperand::CreateReg(getContext(), Register, Begin, End));
    return false;
  }
  return splitIdentifier(Operands);
}

bool HexagonAsmParser::isLabel(AsmToken &Token) {
  MCAsmLexer &Lexer = getLexer();
  AsmToken const &Second = Lexer.getTok();
  AsmToken Third = Lexer.peekTok();
  StringRef String = Token.getString();
  if (Token.is(AsmToken::TokenKind::LCurly) ||
      Token.is(AsmToken::TokenKind::RCurly))
    return false;
  // special case for parsing vwhist256:sat
  if (String.lower() == "vwhist256" && Second.is(AsmToken::Colon) &&
      Third.getString().lower() == "sat")
    return false;
  if (!Token.is(AsmToken::TokenKind::Identifier))
    return true;
  if (!matchRegister(String.lower()))
    return true;
  assert(Second.is(AsmToken::Colon));
  StringRef Raw(String.data(), Third.getString().data() - String.data() +
                                   Third.getString().size());
  std::string Collapsed = std::string(Raw);
  llvm::erase_if(Collapsed, isSpace);
  StringRef Whole = Collapsed;
  std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
  if (!matchRegister(DotSplit.first.lower()))
    return true;
  return false;
}

bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,
                                                   SMLoc &Loc) {
  if (!Contigious && ErrorNoncontigiousRegister) {
    Error(Loc, "Register name is not contigious");
    return true;
  }
  if (!Contigious && WarnNoncontigiousRegister)
    Warning(Loc, "Register name is not contigious");
  return false;
}

bool HexagonAsmParser::parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
                                     SMLoc &EndLoc) {
  return tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success;
}

OperandMatchResultTy HexagonAsmParser::tryParseRegister(MCRegister &RegNo,
                                                        SMLoc &StartLoc,
                                                        SMLoc &EndLoc) {
  MCAsmLexer &Lexer = getLexer();
  StartLoc = getLexer().getLoc();
  SmallVector<AsmToken, 5> Lookahead;
  StringRef RawString(Lexer.getTok().getString().data(), 0);
  bool Again = Lexer.is(AsmToken::Identifier);
  bool NeededWorkaround = false;
  while (Again) {
    AsmToken const &Token = Lexer.getTok();
    RawString = StringRef(RawString.data(), Token.getString().data() -
                                                RawString.data() +
                                                Token.getString().size());
    Lookahead.push_back(Token);
    Lexer.Lex();
    bool Contigious = Lexer.getTok().getString().data() ==
                      Lookahead.back().getString().data() +
                          Lookahead.back().getString().size();
    bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
                Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
                Lexer.is(AsmToken::Colon);
    bool Workaround =
        Lexer.is(AsmToken::Colon) || Lookahead.back().is(AsmToken::Colon);
    Again = (Contigious && Type) || (Workaround && Type);
    NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
  }
  std::string Collapsed = std::string(RawString);
  llvm::erase_if(Collapsed, isSpace);
  StringRef FullString = Collapsed;
  std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
  unsigned DotReg = matchRegister(DotSplit.first.lower());
  if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
    if (DotSplit.second.empty()) {
      RegNo = DotReg;
      EndLoc = Lexer.getLoc();
      if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
        return MatchOperand_NoMatch;
      return MatchOperand_Success;
    } else {
      RegNo = DotReg;
      size_t First = RawString.find('.');
      StringRef DotString (RawString.data() + First, RawString.size() - First);
      Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
      EndLoc = Lexer.getLoc();
      if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
        return MatchOperand_NoMatch;
      return MatchOperand_Success;
    }
  }
  std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
  unsigned ColonReg = matchRegister(ColonSplit.first.lower());
  if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
    do {
      Lexer.UnLex(Lookahead.pop_back_val());
    } while (!Lookahead.empty() && !Lexer.is(AsmToken::Colon));
    RegNo = ColonReg;
    EndLoc = Lexer.getLoc();
    if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
      return MatchOperand_NoMatch;
    return MatchOperand_Success;
  }
  while (!Lookahead.empty()) {
    Lexer.UnLex(Lookahead.pop_back_val());
  }
  return MatchOperand_NoMatch;
}

bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
  if (previousEqual(Operands, 0, "call"))
    return true;
  if (previousEqual(Operands, 0, "jump"))
    if (!getLexer().getTok().is(AsmToken::Colon))
      return true;
  if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
    return true;
  if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
      (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
    return true;
  return false;
}

bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {
  SmallVector<AsmToken, 4> Tokens;
  MCAsmLexer &Lexer = getLexer();
  bool Done = false;
  static char const *Comma = ",";
  do {
    Tokens.emplace_back(Lexer.getTok());
    Lex();
    switch (Tokens.back().getKind()) {
    case AsmToken::TokenKind::Hash:
      if (Tokens.size() > 1)
        if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
          Tokens.insert(Tokens.end() - 2,
                        AsmToken(AsmToken::TokenKind::Comma, Comma));
          Done = true;
        }
      break;
    case AsmToken::TokenKind::RCurly:
    case AsmToken::TokenKind::EndOfStatement:
    case AsmToken::TokenKind::Eof:
      Done = true;
      break;
    default:
      break;
    }
  } while (!Done);
  while (!Tokens.empty()) {
    Lexer.UnLex(Tokens.back());
    Tokens.pop_back();
  }
  SMLoc Loc = Lexer.getLoc();
  return getParser().parseExpression(Expr, Loc);
}

bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
  if (implicitExpressionLocation(Operands)) {
    MCAsmParser &Parser = getParser();
    SMLoc Loc = Parser.getLexer().getLoc();
    MCExpr const *Expr = nullptr;
    bool Error = parseExpression(Expr);
    Expr = HexagonMCExpr::create(Expr, getContext());
    if (!Error)
      Operands.push_back(
          HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
    return Error;
  }
  return parseOperand(Operands);
}

/// Parse an instruction.
bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
  MCAsmParser &Parser = getParser();
  MCAsmLexer &Lexer = getLexer();
  while (true) {
    AsmToken const &Token = Parser.getTok();
    switch (Token.getKind()) {
    case AsmToken::Eof:
    case AsmToken::EndOfStatement: {
      Lex();
      return false;
    }
    case AsmToken::LCurly: {
      if (!Operands.empty())
        return true;
      Operands.push_back(HexagonOperand::CreateToken(
          getContext(), Token.getString(), Token.getLoc()));
      Lex();
      return false;
    }
    case AsmToken::RCurly: {
      if (Operands.empty()) {
        Operands.push_back(HexagonOperand::CreateToken(
            getContext(), Token.getString(), Token.getLoc()));
        Lex();
      }
      return false;
    }
    case AsmToken::Comma: {
      Lex();
      continue;
    }
    case AsmToken::EqualEqual:
    case AsmToken::ExclaimEqual:
    case AsmToken::GreaterEqual:
    case AsmToken::GreaterGreater:
    case AsmToken::LessEqual:
    case AsmToken::LessLess: {
      Operands.push_back(HexagonOperand::CreateToken(
          getContext(), Token.getString().substr(0, 1), Token.getLoc()));
      Operands.push_back(HexagonOperand::CreateToken(
          getContext(), Token.getString().substr(1, 1), Token.getLoc()));
      Lex();
      continue;
    }
    case AsmToken::Hash: {
      bool MustNotExtend = false;
      bool ImplicitExpression = implicitExpressionLocation(Operands);
      SMLoc ExprLoc = Lexer.getLoc();
      if (!ImplicitExpression)
        Operands.push_back(HexagonOperand::CreateToken(
            getContext(), Token.getString(), Token.getLoc()));
      Lex();
      bool MustExtend = false;
      bool HiOnly = false;
      bool LoOnly = false;
      if (Lexer.is(AsmToken::Hash)) {
        Lex();
        MustExtend = true;
      } else if (ImplicitExpression)
        MustNotExtend = true;
      AsmToken const &Token = Parser.getTok();
      if (Token.is(AsmToken::Identifier)) {
        StringRef String = Token.getString();
        if (String.lower() == "hi") {
          HiOnly = true;
        } else if (String.lower() == "lo") {
          LoOnly = true;
        }
        if (HiOnly || LoOnly) {
          AsmToken LParen = Lexer.peekTok();
          if (!LParen.is(AsmToken::LParen)) {
            HiOnly = false;
            LoOnly = false;
          } else {
            Lex();
          }
        }
      }
      MCExpr const *Expr = nullptr;
      if (parseExpression(Expr))
        return true;
      int64_t Value;
      MCContext &Context = Parser.getContext();
      assert(Expr != nullptr);
      if (Expr->evaluateAsAbsolute(Value)) {
        if (HiOnly)
          Expr = MCBinaryExpr::createLShr(
              Expr, MCConstantExpr::create(16, Context), Context);
        if (HiOnly || LoOnly)
          Expr = MCBinaryExpr::createAnd(
              Expr, MCConstantExpr::create(0xffff, Context), Context);
      } else {
        MCValue Value;
        if (Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) {
          if (!Value.isAbsolute()) {
            switch (Value.getAccessVariant()) {
            case MCSymbolRefExpr::VariantKind::VK_TPREL:
            case MCSymbolRefExpr::VariantKind::VK_DTPREL:
              // Don't lazy extend these expression variants
              MustNotExtend = !MustExtend;
              break;
            default:
              break;
            }
          }
        }
      }
      Expr = HexagonMCExpr::create(Expr, Context);
      HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
      HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
      std::unique_ptr<HexagonOperand> Operand =
          HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
      Operands.push_back(std::move(Operand));
      continue;
    }
    default:
      break;
    }
    if (parseExpressionOrOperand(Operands))
      return true;
  }
}

bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
                                        StringRef Name, AsmToken ID,
                                        OperandVector &Operands) {
  getLexer().UnLex(ID);
  return parseInstruction(Operands);
}

static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1,
                              MCOperand &MO2) {
  MCInst TmpInst;
  TmpInst.setOpcode(opCode);
  TmpInst.addOperand(Rdd);
  TmpInst.addOperand(MO1);
  TmpInst.addOperand(MO2);

  return TmpInst;
}

// Define this matcher function after the auto-generated include so we
// have the match class enum definitions.
unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
                                                      unsigned Kind) {
  HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);

  switch (Kind) {
  case MCK_0: {
    int64_t Value;
    return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
               ? Match_Success
               : Match_InvalidOperand;
  }
  case MCK_1: {
    int64_t Value;
    return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
               ? Match_Success
               : Match_InvalidOperand;
  }
  }
  if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
    StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
    if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
      return Match_Success;
    if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
      return Match_Success;
  }

  LLVM_DEBUG(dbgs() << "Unmatched Operand:");
  LLVM_DEBUG(Op->dump());
  LLVM_DEBUG(dbgs() << "\n");

  return Match_InvalidOperand;
}

// FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
  std::string errStr;
  raw_string_ostream ES(errStr);
  ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
  if (Max >= 0)
    ES << "0-" << Max;
  else
    ES << Max << "-" << (-Max - 1);
  return Parser.printError(IDLoc, ES.str());
}

int HexagonAsmParser::processInstruction(MCInst &Inst,
                                         OperandVector const &Operands,
                                         SMLoc IDLoc) {
  MCContext &Context = getParser().getContext();
  const MCRegisterInfo *RI = getContext().getRegisterInfo();
  const std::string r = "r";
  const std::string v = "v";
  const std::string Colon = ":";
  using RegPairVals = std::pair<unsigned, unsigned>;
  auto GetRegPair = [this, r](RegPairVals RegPair) {
    const std::string R1 = r + utostr(RegPair.first);
    const std::string R2 = r + utostr(RegPair.second);

    return std::make_pair(matchRegister(R1), matchRegister(R2));
  };
  auto GetScalarRegs = [RI, GetRegPair](unsigned RegPair) {
    const unsigned Lower = RI->getEncodingValue(RegPair);
    const RegPairVals RegPair_ = std::make_pair(Lower + 1, Lower);

    return GetRegPair(RegPair_);
  };
  auto GetVecRegs = [GetRegPair](unsigned VecRegPair) {
    const RegPairVals RegPair =
        HexagonMCInstrInfo::GetVecRegPairIndices(VecRegPair);

    return GetRegPair(RegPair);
  };

  bool is32bit = false; // used to distinguish between CONST32 and CONST64
  switch (Inst.getOpcode()) {
  default:
    if (HexagonMCInstrInfo::getDesc(MII, Inst).isPseudo()) {
      SMDiagnostic Diag = getSourceManager().GetMessage(
          IDLoc, SourceMgr::DK_Error,
          "Found pseudo instruction with no expansion");
      Diag.print("", errs());
      report_fatal_error("Invalid pseudo instruction");
    }
    break;

  case Hexagon::J2_trap1:
    if (!getSTI().getFeatureBits()[Hexagon::ArchV65]) {
      MCOperand &Rx = Inst.getOperand(0);
      MCOperand &Ry = Inst.getOperand(1);
      if (Rx.getReg() != Hexagon::R0 || Ry.getReg() != Hexagon::R0) {
        Error(IDLoc, "trap1 can only have register r0 as operand");
        return Match_InvalidOperand;
      }
    }
    break;

  case Hexagon::A2_iconst: {
    Inst.setOpcode(Hexagon::A2_addi);
    MCOperand Reg = Inst.getOperand(0);
    MCOperand S27 = Inst.getOperand(1);
    HexagonMCInstrInfo::setMustNotExtend(*S27.getExpr());
    HexagonMCInstrInfo::setS27_2_reloc(*S27.getExpr());
    Inst.clear();
    Inst.addOperand(Reg);
    Inst.addOperand(MCOperand::createReg(Hexagon::R0));
    Inst.addOperand(S27);
    break;
  }
  case Hexagon::M4_mpyrr_addr:
  case Hexagon::S4_addi_asl_ri:
  case Hexagon::S4_addi_lsr_ri:
  case Hexagon::S4_andi_asl_ri:
  case Hexagon::S4_andi_lsr_ri:
  case Hexagon::S4_ori_asl_ri:
  case Hexagon::S4_ori_lsr_ri:
  case Hexagon::S4_or_andix:
  case Hexagon::S4_subi_asl_ri:
  case Hexagon::S4_subi_lsr_ri: {
    MCOperand &Ry = Inst.getOperand(0);
    MCOperand &src = Inst.getOperand(2);
    if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
      return Match_InvalidOperand;
    break;
  }

  case Hexagon::C2_cmpgei: {
    MCOperand &MO = Inst.getOperand(2);
    MO.setExpr(HexagonMCExpr::create(
        MCBinaryExpr::createSub(MO.getExpr(),
                                MCConstantExpr::create(1, Context), Context),
        Context));
    Inst.setOpcode(Hexagon::C2_cmpgti);
    break;
  }

  case Hexagon::C2_cmpgeui: {
    MCOperand &MO = Inst.getOperand(2);
    int64_t Value;
    bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
    (void)Success;
    assert(Success && "Assured by matcher");
    if (Value == 0) {
      MCInst TmpInst;
      MCOperand &Pd = Inst.getOperand(0);
      MCOperand &Rt = Inst.getOperand(1);
      TmpInst.setOpcode(Hexagon::C2_cmpeq);
      TmpInst.addOperand(Pd);
      TmpInst.addOperand(Rt);
      TmpInst.addOperand(Rt);
      Inst = TmpInst;
    } else {
      MO.setExpr(HexagonMCExpr::create(
          MCBinaryExpr::createSub(MO.getExpr(),
                                  MCConstantExpr::create(1, Context), Context),
          Context));
      Inst.setOpcode(Hexagon::C2_cmpgtui);
    }
    break;
  }

  // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
  case Hexagon::A2_tfrp: {
    MCOperand &MO = Inst.getOperand(1);
    const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.getReg());
    MO.setReg(RegPair.first);
    Inst.addOperand(MCOperand::createReg(RegPair.second));
    Inst.setOpcode(Hexagon::A2_combinew);
    break;
  }

  case Hexagon::A2_tfrpt:
  case Hexagon::A2_tfrpf: {
    MCOperand &MO = Inst.getOperand(2);
    const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.getReg());
    MO.setReg(RegPair.first);
    Inst.addOperand(MCOperand::createReg(RegPair.second));
    Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
                       ? Hexagon::C2_ccombinewt
                       : Hexagon::C2_ccombinewf);
    break;
  }
  case Hexagon::A2_tfrptnew:
  case Hexagon::A2_tfrpfnew: {
    MCOperand &MO = Inst.getOperand(2);
    const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.getReg());
    MO.setReg(RegPair.first);
    Inst.addOperand(MCOperand::createReg(RegPair.second));
    Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
                       ? Hexagon::C2_ccombinewnewt
                       : Hexagon::C2_ccombinewnewf);
    break;
  }

  // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
  case Hexagon::V6_vassignp: {
    MCOperand &MO = Inst.getOperand(1);
    const std::pair<unsigned, unsigned> RegPair = GetVecRegs(MO.getReg());
    MO.setReg(RegPair.first);
    Inst.addOperand(MCOperand::createReg(RegPair.second));
    Inst.setOpcode(Hexagon::V6_vcombine);
    break;
  }

  // Translate a "$Rx =  CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
  case Hexagon::CONST32:
    is32bit = true;
    [[fallthrough]];
  // Translate a "$Rx:y =  CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
  case Hexagon::CONST64:
    // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
    if (!Parser.getStreamer().hasRawTextSupport()) {
      MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
      MCOperand &MO_1 = Inst.getOperand(1);
      MCOperand &MO_0 = Inst.getOperand(0);

      // push section onto section stack
      MES->pushSection();

      std::string myCharStr;
      MCSectionELF *mySection;

      // check if this as an immediate or a symbol
      int64_t Value;
      bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
      if (Absolute) {
        // Create a new section - one for each constant
        // Some or all of the zeros are replaced with the given immediate.
        if (is32bit) {
          std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
          myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
                          .drop_back(myImmStr.size())
                          .str() +
                      myImmStr;
        } else {
          std::string myImmStr = utohexstr(Value);
          myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
                          .drop_back(myImmStr.size())
                          .str() +
                      myImmStr;
        }

        mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
                                               ELF::SHF_ALLOC | ELF::SHF_WRITE);
      } else if (MO_1.isExpr()) {
        // .lita - for expressions
        myCharStr = ".lita";
        mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
                                               ELF::SHF_ALLOC | ELF::SHF_WRITE);
      } else
        llvm_unreachable("unexpected type of machine operand!");

      MES->switchSection(mySection);
      unsigned byteSize = is32bit ? 4 : 8;
      getStreamer().emitCodeAlignment(Align(byteSize), &getSTI(), byteSize);

      MCSymbol *Sym;

      // for symbols, get rid of prepended ".gnu.linkonce.lx."

      // emit symbol if needed
      if (Absolute) {
        Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
        if (Sym->isUndefined()) {
          getStreamer().emitLabel(Sym);
          getStreamer().emitSymbolAttribute(Sym, MCSA_Global);
          getStreamer().emitIntValue(Value, byteSize);
        }
      } else if (MO_1.isExpr()) {
        const char *StringStart = nullptr;
        const char *StringEnd = nullptr;
        if (*Operands[4]->getStartLoc().getPointer() == '#') {
          StringStart = Operands[5]->getStartLoc().getPointer();
          StringEnd = Operands[6]->getStartLoc().getPointer();
        } else { // no pound
          StringStart = Operands[4]->getStartLoc().getPointer();
          StringEnd = Operands[5]->getStartLoc().getPointer();
        }

        unsigned size = StringEnd - StringStart;
        std::string DotConst = ".CONST_";
        Sym = getContext().getOrCreateSymbol(DotConst +
                                             StringRef(StringStart, size));

        if (Sym->isUndefined()) {
          // case where symbol is not yet defined: emit symbol
          getStreamer().emitLabel(Sym);
          getStreamer().emitSymbolAttribute(Sym, MCSA_Local);
          getStreamer().emitValue(MO_1.getExpr(), 4);
        }
      } else
        llvm_unreachable("unexpected type of machine operand!");

      MES->popSection();

      if (Sym) {
        MCInst TmpInst;
        if (is32bit) // 32 bit
          TmpInst.setOpcode(Hexagon::L2_loadrigp);
        else // 64 bit
          TmpInst.setOpcode(Hexagon::L2_loadrdgp);

        TmpInst.addOperand(MO_0);
        TmpInst.addOperand(MCOperand::createExpr(HexagonMCExpr::create(
            MCSymbolRefExpr::create(Sym, getContext()), getContext())));
        Inst = TmpInst;
      }
    }
    break;

  // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
  case Hexagon::A2_tfrpi: {
    MCOperand &Rdd = Inst.getOperand(0);
    MCOperand &MO = Inst.getOperand(1);
    int64_t Value;
    int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
    MCOperand imm(MCOperand::createExpr(
        HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));
    Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
    break;
  }

  // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
  case Hexagon::TFRI64_V4: {
    MCOperand &Rdd = Inst.getOperand(0);
    MCOperand &MO = Inst.getOperand(1);
    int64_t Value;
    if (MO.getExpr()->evaluateAsAbsolute(Value)) {
      int s8 = Hi_32(Value);
      if (!isInt<8>(s8))
        OutOfRange(IDLoc, s8, -128);
      MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
          MCConstantExpr::create(s8, Context), Context))); // upper 32
      auto Expr = HexagonMCExpr::create(
          MCConstantExpr::create(Lo_32(Value), Context), Context);
      HexagonMCInstrInfo::setMustExtend(
          *Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));
      MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
      Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
    } else {
      MCOperand imm(MCOperand::createExpr(HexagonMCExpr::create(
          MCConstantExpr::create(0, Context), Context))); // upper 32
      Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
    }
    break;
  }

  // Handle $Rdd = combine(##imm, #imm)"
  case Hexagon::TFRI64_V2_ext: {
    MCOperand &Rdd = Inst.getOperand(0);
    MCOperand &MO1 = Inst.getOperand(1);
    MCOperand &MO2 = Inst.getOperand(2);
    int64_t Value;
    if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
      int s8 = Value;
      if (s8 < -128 || s8 > 127)
        OutOfRange(IDLoc, s8, -128);
    }
    Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
    break;
  }

  // Handle $Rdd = combine(#imm, ##imm)"
  case Hexagon::A4_combineii: {
    MCOperand &Rdd = Inst.getOperand(0);
    MCOperand &MO1 = Inst.getOperand(1);
    int64_t Value;
    if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
      int s8 = Value;
      if (s8 < -128 || s8 > 127)
        OutOfRange(IDLoc, s8, -128);
    }
    MCOperand &MO2 = Inst.getOperand(2);
    Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
    break;
  }

  case Hexagon::S2_tableidxb_goodsyntax:
    Inst.setOpcode(Hexagon::S2_tableidxb);
    break;

  case Hexagon::S2_tableidxh_goodsyntax: {
    MCInst TmpInst;
    MCOperand &Rx = Inst.getOperand(0);
    MCOperand &Rs = Inst.getOperand(2);
    MCOperand &Imm4 = Inst.getOperand(3);
    MCOperand &Imm6 = Inst.getOperand(4);
    Imm6.setExpr(HexagonMCExpr::create(
        MCBinaryExpr::createSub(Imm6.getExpr(),
                                MCConstantExpr::create(1, Context), Context),
        Context));
    TmpInst.setOpcode(Hexagon::S2_tableidxh);
    TmpInst.addOperand(Rx);
    TmpInst.addOperand(Rx);
    TmpInst.addOperand(Rs);
    TmpInst.addOperand(Imm4);
    TmpInst.addOperand(Imm6);
    Inst = TmpInst;
    break;
  }

  case Hexagon::S2_tableidxw_goodsyntax: {
    MCInst TmpInst;
    MCOperand &Rx = Inst.getOperand(0);
    MCOperand &Rs = Inst.getOperand(2);
    MCOperand &Imm4 = Inst.getOperand(3);
    MCOperand &Imm6 = Inst.getOperand(4);
    Imm6.setExpr(HexagonMCExpr::create(
        MCBinaryExpr::createSub(Imm6.getExpr(),
                                MCConstantExpr::create(2, Context), Context),
        Context));
    TmpInst.setOpcode(Hexagon::S2_tableidxw);
    TmpInst.addOperand(Rx);
    TmpInst.addOperand(Rx);
    TmpInst.addOperand(Rs);
    TmpInst.addOperand(Imm4);
    TmpInst.addOperand(Imm6);
    Inst = TmpInst;
    break;
  }

  case Hexagon::S2_tableidxd_goodsyntax: {
    MCInst TmpInst;
    MCOperand &Rx = Inst.getOperand(0);
    MCOperand &Rs = Inst.getOperand(2);
    MCOperand &Imm4 = Inst.getOperand(3);
    MCOperand &Imm6 = Inst.getOperand(4);
    Imm6.setExpr(HexagonMCExpr::create(
        MCBinaryExpr::createSub(Imm6.getExpr(),
                                MCConstantExpr::create(3, Context), Context),
        Context));
    TmpInst.setOpcode(Hexagon::S2_tableidxd);
    TmpInst.addOperand(Rx);
    TmpInst.addOperand(Rx);
    TmpInst.addOperand(Rs);
    TmpInst.addOperand(Imm4);
    TmpInst.addOperand(Imm6);
    Inst = TmpInst;
    break;
  }

  case Hexagon::M2_mpyui:
    Inst.setOpcode(Hexagon::M2_mpyi);
    break;
  case Hexagon::M2_mpysmi: {
    MCInst TmpInst;
    MCOperand &Rd = Inst.getOperand(0);
    MCOperand &Rs = Inst.getOperand(1);
    MCOperand &Imm = Inst.getOperand(2);
    int64_t Value;
    MCExpr const &Expr = *Imm.getExpr();
    bool Absolute = Expr.evaluateAsAbsolute(Value);
    if (!Absolute)
      return Match_InvalidOperand;
    if (!HexagonMCInstrInfo::mustExtend(Expr) &&
        ((Value <= -256) || Value >= 256))
      return Match_InvalidOperand;
    if (Value < 0 && Value > -256) {
      Imm.setExpr(HexagonMCExpr::create(
          MCConstantExpr::create(Value * -1, Context), Context));
      TmpInst.setOpcode(Hexagon::M2_mpysin);
    } else
      TmpInst.setOpcode(Hexagon::M2_mpysip);
    TmpInst.addOperand(Rd);
    TmpInst.addOperand(Rs);
    TmpInst.addOperand(Imm);
    Inst = TmpInst;
    break;
  }

  case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
    MCOperand &Imm = Inst.getOperand(2);
    MCInst TmpInst;
    int64_t Value;
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
    if (!Absolute)
      return Match_InvalidOperand;
    if (Value == 0) { // convert to $Rd = $Rs
      TmpInst.setOpcode(Hexagon::A2_tfr);
      MCOperand &Rd = Inst.getOperand(0);
      MCOperand &Rs = Inst.getOperand(1);
      TmpInst.addOperand(Rd);
      TmpInst.addOperand(Rs);
    } else {
      Imm.setExpr(HexagonMCExpr::create(
          MCBinaryExpr::createSub(Imm.getExpr(),
                                  MCConstantExpr::create(1, Context), Context),
          Context));
      TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
      MCOperand &Rd = Inst.getOperand(0);
      MCOperand &Rs = Inst.getOperand(1);
      TmpInst.addOperand(Rd);
      TmpInst.addOperand(Rs);
      TmpInst.addOperand(Imm);
    }
    Inst = TmpInst;
    break;
  }

  case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
    MCOperand &Rdd = Inst.getOperand(0);
    MCOperand &Rss = Inst.getOperand(1);
    MCOperand &Imm = Inst.getOperand(2);
    int64_t Value;
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
    if (!Absolute)
      return Match_InvalidOperand;
    if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
      MCInst TmpInst;
      unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
      std::string R1 = r + utostr(RegPairNum + 1);
      StringRef Reg1(R1);
      Rss.setReg(matchRegister(Reg1));
      // Add a new operand for the second register in the pair.
      std::string R2 = r + utostr(RegPairNum);
      StringRef Reg2(R2);
      TmpInst.setOpcode(Hexagon::A2_combinew);
      TmpInst.addOperand(Rdd);
      TmpInst.addOperand(Rss);
      TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
      Inst = TmpInst;
    } else {
      Imm.setExpr(HexagonMCExpr::create(
          MCBinaryExpr::createSub(Imm.getExpr(),
                                  MCConstantExpr::create(1, Context), Context),
          Context));
      Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
    }
    break;
  }

  case Hexagon::A4_boundscheck: {
    MCOperand &Rs = Inst.getOperand(1);
    unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
    if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
      Inst.setOpcode(Hexagon::A4_boundscheck_hi);
      std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
      StringRef RegPair = Name;
      Rs.setReg(matchRegister(RegPair));
    } else { // raw:lo
      Inst.setOpcode(Hexagon::A4_boundscheck_lo);
      std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
      StringRef RegPair = Name;
      Rs.setReg(matchRegister(RegPair));
    }
    break;
  }

  case Hexagon::A2_addsp: {
    MCOperand &Rs = Inst.getOperand(1);
    unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
    if (RegNum & 1) { // Odd mapped to raw:hi
      Inst.setOpcode(Hexagon::A2_addsph);
      std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
      StringRef RegPair = Name;
      Rs.setReg(matchRegister(RegPair));
    } else { // Even mapped raw:lo
      Inst.setOpcode(Hexagon::A2_addspl);
      std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
      StringRef RegPair = Name;
      Rs.setReg(matchRegister(RegPair));
    }
    break;
  }

  case Hexagon::M2_vrcmpys_s1: {
    MCOperand &Rt = Inst.getOperand(2);
    unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
    if (RegNum & 1) { // Odd mapped to sat:raw:hi
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
      std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
      StringRef RegPair = Name;
      Rt.setReg(matchRegister(RegPair));
    } else { // Even mapped sat:raw:lo
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
      std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
      StringRef RegPair = Name;
      Rt.setReg(matchRegister(RegPair));
    }
    break;
  }

  case Hexagon::M2_vrcmpys_acc_s1: {
    MCInst TmpInst;
    MCOperand &Rxx = Inst.getOperand(0);
    MCOperand &Rss = Inst.getOperand(2);
    MCOperand &Rt = Inst.getOperand(3);
    unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
    if (RegNum & 1) { // Odd mapped to sat:raw:hi
      TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
      std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
      StringRef RegPair = Name;
      Rt.setReg(matchRegister(RegPair));
    } else { // Even mapped sat:raw:lo
      TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
      std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
      StringRef RegPair = Name;
      Rt.setReg(matchRegister(RegPair));
    }
    // Registers are in different positions
    TmpInst.addOperand(Rxx);
    TmpInst.addOperand(Rxx);
    TmpInst.addOperand(Rss);
    TmpInst.addOperand(Rt);
    Inst = TmpInst;
    break;
  }

  case Hexagon::M2_vrcmpys_s1rp: {
    MCOperand &Rt = Inst.getOperand(2);
    unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
    if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
      std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
      StringRef RegPair = Name;
      Rt.setReg(matchRegister(RegPair));
    } else { // Even mapped rnd:sat:raw:lo
      Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
      std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
      StringRef RegPair = Name;
      Rt.setReg(matchRegister(RegPair));
    }
    break;
  }

  case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
    MCOperand &Imm = Inst.getOperand(2);
    int64_t Value;
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
    if (!Absolute)
      return Match_InvalidOperand;
    if (Value == 0)
      Inst.setOpcode(Hexagon::S2_vsathub);
    else {
      Imm.setExpr(HexagonMCExpr::create(
          MCBinaryExpr::createSub(Imm.getExpr(),
                                  MCConstantExpr::create(1, Context), Context),
          Context));
      Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
    }
    break;
  }

  case Hexagon::S5_vasrhrnd_goodsyntax: {
    MCOperand &Rdd = Inst.getOperand(0);
    MCOperand &Rss = Inst.getOperand(1);
    MCOperand &Imm = Inst.getOperand(2);
    int64_t Value;
    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
    if (!Absolute)
      return Match_InvalidOperand;
    if (Value == 0) {
      MCInst TmpInst;
      unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
      std::string R1 = r + utostr(RegPairNum + 1);
      StringRef Reg1(R1);
      Rss.setReg(matchRegister(Reg1));
      // Add a new operand for the second register in the pair.
      std::string R2 = r + utostr(RegPairNum);
      StringRef Reg2(R2);
      TmpInst.setOpcode(Hexagon::A2_combinew);
      TmpInst.addOperand(Rdd);
      TmpInst.addOperand(Rss);
      TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
      Inst = TmpInst;
    } else {
      Imm.setExpr(HexagonMCExpr::create(
          MCBinaryExpr::createSub(Imm.getExpr(),
                                  MCConstantExpr::create(1, Context), Context),
          Context));
      Inst.setOpcode(Hexagon::S5_vasrhrnd);
    }
    break;
  }

  case Hexagon::A2_not: {
    MCInst TmpInst;
    MCOperand &Rd = Inst.getOperand(0);
    MCOperand &Rs = Inst.getOperand(1);
    TmpInst.setOpcode(Hexagon::A2_subri);
    TmpInst.addOperand(Rd);
    TmpInst.addOperand(MCOperand::createExpr(
        HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));
    TmpInst.addOperand(Rs);
    Inst = TmpInst;
    break;
  }
  case Hexagon::PS_loadrubabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
      Inst.setOpcode(Hexagon::L2_loadrubgp);
    break;
  case Hexagon::PS_loadrbabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
      Inst.setOpcode(Hexagon::L2_loadrbgp);
    break;
  case Hexagon::PS_loadruhabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
      Inst.setOpcode(Hexagon::L2_loadruhgp);
    break;
  case Hexagon::PS_loadrhabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
      Inst.setOpcode(Hexagon::L2_loadrhgp);
    break;
  case Hexagon::PS_loadriabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
      Inst.setOpcode(Hexagon::L2_loadrigp);
    break;
  case Hexagon::PS_loadrdabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(1).getExpr()))
      Inst.setOpcode(Hexagon::L2_loadrdgp);
    break;
  case Hexagon::PS_storerbabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
      Inst.setOpcode(Hexagon::S2_storerbgp);
    break;
  case Hexagon::PS_storerhabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
      Inst.setOpcode(Hexagon::S2_storerhgp);
    break;
  case Hexagon::PS_storerfabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
      Inst.setOpcode(Hexagon::S2_storerfgp);
    break;
  case Hexagon::PS_storeriabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
      Inst.setOpcode(Hexagon::S2_storerigp);
    break;
  case Hexagon::PS_storerdabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
      Inst.setOpcode(Hexagon::S2_storerdgp);
    break;
  case Hexagon::PS_storerbnewabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
      Inst.setOpcode(Hexagon::S2_storerbnewgp);
    break;
  case Hexagon::PS_storerhnewabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
      Inst.setOpcode(Hexagon::S2_storerhnewgp);
    break;
  case Hexagon::PS_storerinewabs:
    if (!HexagonMCInstrInfo::mustExtend(*Inst.getOperand(0).getExpr()))
      Inst.setOpcode(Hexagon::S2_storerinewgp);
    break;
  case Hexagon::A2_zxtb: {
    Inst.setOpcode(Hexagon::A2_andir);
    Inst.addOperand(
        MCOperand::createExpr(MCConstantExpr::create(255, Context)));
    break;
  }
  } // switch

  return Match_Success;
}

unsigned HexagonAsmParser::matchRegister(StringRef Name) {
  if (unsigned Reg = MatchRegisterName(Name))
    return Reg;
  return MatchRegisterAltName(Name);
}
