//===-- HexagonAsmParser.cpp - Parse Hexagon asm to MCInst instructions----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "mcasmparser"

#include "Hexagon.h"
#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 "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/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/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>

using namespace llvm;

static cl::opt<bool> EnableFutureRegs("mfuture-regs",
                                      cl::desc("Enable future registers"));

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(true));
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;
  MCAssembler *Assembler;
  MCInst MCB;
  bool InBrackets;

  MCAsmParser &getParser() const { return Parser; }
  MCAssembler *getAssembler() const { 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(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
  bool ParseDirectiveSubsection(SMLoc L);
  bool ParseDirectiveValue(unsigned Size, 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);

  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);

  // Check if we have an assembler and, if so, set the ELF e_header flags.
  void chksetELFHeaderEFlags(unsigned flags) {
    if (getAssembler())
      getAssembler()->setELFHeaderEFlags(flags);
  }

  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),
      MCB(HexagonMCInstrInfo::createBundle()), InBrackets(false) {
    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));

    MCAsmParserExtension::Initialize(_Parser);

    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();
    }
  }

  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;

  SMLoc StartLoc, EndLoc;

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

  struct RegTy {
    unsigned RegNum;
  };

  struct ImmTy {
    const MCExpr *Val;
  };

  struct InstTy {
    OperandVector *SubInsts;
  };

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

  HexagonOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}

public:
  HexagonOperand(const HexagonOperand &o) : MCParsedAsmOperand() {
    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 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);
    if ((Extended < 0) != (Value < 0))
      Expr->setSignMismatch();
    Inst.addOperand(MCOperand::createExpr(Expr));
  }

  void addn1ConstOperands(MCInst &Inst, unsigned N) const {
    addImmOperands(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(StringRef Str, SMLoc S) {
    HexagonOperand *Op = new HexagonOperand(Token);
    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(unsigned RegNum, SMLoc S,
                                                   SMLoc E) {
    HexagonOperand *Op = new HexagonOperand(Register);
    Op->Reg.RegNum = RegNum;
    Op->StartLoc = S;
    Op->EndLoc = E;
    return std::unique_ptr<HexagonOperand>(Op);
  }

  static std::unique_ptr<HexagonOperand> CreateImm(const MCExpr *Val, SMLoc S,
                                                   SMLoc E) {
    HexagonOperand *Op = new HexagonOperand(Immediate);
    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) {
  DEBUG(dbgs() << "Bundle:");
  DEBUG(MCB.dump_pretty(dbgs()));
  DEBUG(dbgs() << "--\n");

  MCB.setLoc(IDLoc);
  // Check the bundle for errors.
  const MCRegisterInfo *RI = getContext().getRegisterInfo();
  HexagonMCChecker Check(getContext(), MII, getSTI(), MCB, *RI);

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

  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;
    }
    Out.EmitInstruction(MCB, getSTI());
  } else {
    // If compounding and duplexing didn't reduce the size below
    // 4 or less we have a packet that is too big.
    if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE) {
      Error(IDLoc, "invalid instruction packet: out of slots");
      return true; // Error
    }
  }

  return false; // No error
}

bool HexagonAsmParser::matchBundleOptions() {
  MCAsmParser &Parser = getParser();
  while (true) {
    if (!Parser.getTok().is(AsmToken::Colon))
      return false;
    Lex();
    StringRef Option = Parser.getTok().getString();
    if (Option.compare_lower("endloop0") == 0)
      HexagonMCInstrInfo::setInnerLoop(MCB);
    else if (Option.compare_lower("endloop1") == 0)
      HexagonMCInstrInfo::setOuterLoop(MCB);
    else
      return true;
    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);

    DEBUG(dbgs() << "Insn:");
    DEBUG(MCI.dump_pretty(dbgs()));
    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:
    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!");
}

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");
      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 = new (getParser().getContext()) MCInst;
  if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
                          MatchingInlineAsm))
    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() == ".word") || (IDVal.lower() == ".4byte"))
    return ParseDirectiveValue(4, DirectiveID.getLoc());
  if (IDVal.lower() == ".short" || IDVal.lower() == ".hword" ||
      IDVal.lower() == ".half")
    return ParseDirectiveValue(2, DirectiveID.getLoc());
  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
      const MCConstantExpr *MCE = dyn_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;
}

///  ::= .word [ expression (, expression)* ]
bool HexagonAsmParser::ParseDirectiveValue(unsigned Size, SMLoc L) {
  if (getLexer().isNot(AsmToken::EndOfStatement)) {
    while (true) {
      const MCExpr *Value;
      SMLoc ExprLoc = L;
      if (getParser().parseExpression(Value))
        return true;

      // Special case constant expressions to match code generator.
      if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
        assert(Size <= 8 && "Invalid size");
        uint64_t IntValue = MCE->getValue();
        if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
          return Error(ExprLoc, "literal value out of range for directive");
        getStreamer().EmitIntValue(IntValue, Size);
      } else
        getStreamer().EmitValue(Value, Size);

      if (getLexer().is(AsmToken::EndOfStatement))
        break;

      // FIXME: Improve diagnostic.
      if (getLexer().isNot(AsmToken::Comma))
        return TokError("unexpected token in directive");
      Lex();
    }
  }

  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, ByteAlignment,
                                                      AccessAlignment);
    return false;
  }

  HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, 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" void LLVMInitializeHexagonAsmLexer();

/// Force static initialization.
extern "C" 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_lower(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(HeadTail.first, Loc));
    if (!HeadTail.second.empty())
      Operands.push_back(HexagonOperand::CreateToken(
          String.substr(HeadTail.first.size(), 1), Loc));
    String = HeadTail.second;
  } while (!String.empty());
  return false;
}

bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
  unsigned 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(LParen, Begin));
          Operands.push_back(HexagonOperand::CreateReg(Register, Begin, End));
          const AsmToken &MaybeDotNew = Lexer.getTok();
          if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
              MaybeDotNew.getString().equals_lower(".new"))
            splitIdentifier(Operands);
          Operands.push_back(HexagonOperand::CreateToken(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(LParen, Begin));
          Operands.push_back(HexagonOperand::CreateReg(Register, Begin, End));
          const AsmToken &MaybeDotNew = Lexer.getTok();
          if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
              MaybeDotNew.getString().equals_lower(".new"))
            splitIdentifier(Operands);
          Operands.push_back(HexagonOperand::CreateToken(RParen, Begin));
          return false;
        }
        break;
      }
    Operands.push_back(HexagonOperand::CreateReg(
        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;
  (void)Second;
  assert(Second.is(AsmToken::Colon));
  StringRef Raw (String.data(), Third.getString().data() - String.data() +
                 Third.getString().size());
  std::string Collapsed = Raw;
  Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
  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(unsigned &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 = RawString;
  Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
  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 true;
      return false;
    } 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 true;
      return false;
    }
  }
  std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
  unsigned ColonReg = matchRegister(ColonSplit.first.lower());
  if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
    Lexer.UnLex(Lookahead.back());
    Lookahead.pop_back();
    Lexer.UnLex(Lookahead.back());
    Lookahead.pop_back();
    RegNo = ColonReg;
    EndLoc = Lexer.getLoc();
    if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
      return true;
    return false;
  }
  while (!Lookahead.empty()) {
    Lexer.UnLex(Lookahead.back());
    Lookahead.pop_back();
  }
  return true;
}

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();
  }
  return getParser().parseExpression(Expr);
}

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(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::EndOfStatement: {
      Lex();
      return false;
    }
    case AsmToken::LCurly: {
      if (!Operands.empty())
        return true;
      Operands.push_back(
          HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
      Lex();
      return false;
    }
    case AsmToken::RCurly: {
      if (Operands.empty()) {
        Operands.push_back(
            HexagonOperand::CreateToken(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(
          Token.getString().substr(0, 1), Token.getLoc()));
      Operands.push_back(HexagonOperand::CreateToken(
          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(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(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;
  }

  DEBUG(dbgs() << "Unmatched Operand:");
  DEBUG(Op->dump());
  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();
  std::string r = "r";
  std::string v = "v";
  std::string Colon = ":";

  bool is32bit = false; // used to distinguish between CONST32 and CONST64
  switch (Inst.getOpcode()) {
  default:
    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);
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
    std::string R1 = r + utostr(RegPairNum + 1);
    StringRef Reg1(R1);
    MO.setReg(matchRegister(Reg1));
    // Add a new operand for the second register in the pair.
    std::string R2 = r + utostr(RegPairNum);
    StringRef Reg2(R2);
    Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
    Inst.setOpcode(Hexagon::A2_combinew);
    break;
  }

  case Hexagon::A2_tfrpt:
  case Hexagon::A2_tfrpf: {
    MCOperand &MO = Inst.getOperand(2);
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
    std::string R1 = r + utostr(RegPairNum + 1);
    StringRef Reg1(R1);
    MO.setReg(matchRegister(Reg1));
    // Add a new operand for the second register in the pair.
    std::string R2 = r + utostr(RegPairNum);
    StringRef Reg2(R2);
    Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
    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);
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
    std::string R1 = r + utostr(RegPairNum + 1);
    StringRef Reg1(R1);
    MO.setReg(matchRegister(Reg1));
    // Add a new operand for the second register in the pair.
    std::string R2 = r + utostr(RegPairNum);
    StringRef Reg2(R2);
    Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
    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);
    unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
    std::string R1 = v + utostr(RegPairNum + 1);
    MO.setReg(MatchRegisterName(R1));
    // Add a new operand for the second register in the pair.
    std::string R2 = v + utostr(RegPairNum);
    Inst.addOperand(MCOperand::createReg(MatchRegisterName(R2)));
    Inst.setOpcode(Hexagon::V6_vcombine);
    break;
  }

  // Translate a "$Rx =  CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
  case Hexagon::CONST32:
    is32bit = true;
    LLVM_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(byteSize, 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 &_dst_ = Inst.getOperand(1);
    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(_dst_);
    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 &_dst_ = Inst.getOperand(1);
    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(_dst_);
    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 &_dst_ = Inst.getOperand(1);
    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(_dst_);
    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);
    assert(Absolute);
    (void)Absolute;
    if (!HexagonMCInstrInfo::mustExtend(Expr)) {
      if (Value < 0 && Value > -256) {
        Imm.setExpr(HexagonMCExpr::create(
            MCConstantExpr::create(Value * -1, Context), Context));
        TmpInst.setOpcode(Hexagon::M2_mpysin);
      } else if (Value < 256 && Value >= 0)
        TmpInst.setOpcode(Hexagon::M2_mpysip);
      else
        return Match_InvalidOperand;
    } else {
      if (Value >= 0)
        TmpInst.setOpcode(Hexagon::M2_mpysip);
      else
        return Match_InvalidOperand;
    }
    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);
    assert(Absolute);
    (void)Absolute;
    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);
    assert(Absolute);
    (void)Absolute;
    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);
    assert(Absolute);
    (void)Absolute;
    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);
    assert(Absolute);
    (void)Absolute;
    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);
}
