[llvm] r252443 - [Hexagon] Enabling ASM parsing on Hexagon backend and adding instruction parsing tests. General updating of the code emission.

David Blaikie via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 9 08:07:50 PST 2015


This seems to have broken a bot (
http://lab.llvm.org:8011/builders/clang-x86_64-ubuntu-gdb-75/builds/26199 )
even after a fix in r252447 (
http://lab.llvm.org:8011/builders/clang-x86_64-ubuntu-gdb-75/builds/26202 )

On Sun, Nov 8, 2015 at 8:07 PM, Colin LeMahieu via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

> Author: colinl
> Date: Sun Nov  8 22:07:48 2015
> New Revision: 252443
>
> URL: http://llvm.org/viewvc/llvm-project?rev=252443&view=rev
> Log:
> [Hexagon] Enabling ASM parsing on Hexagon backend and adding instruction
> parsing tests.  General updating of the code emission.
>
> Added:
>     llvm/trunk/lib/Target/Hexagon/AsmParser/
>     llvm/trunk/lib/Target/Hexagon/AsmParser/CMakeLists.txt
>     llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
>     llvm/trunk/lib/Target/Hexagon/AsmParser/LLVMBuild.txt
>     llvm/trunk/lib/Target/Hexagon/AsmParser/Makefile
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h
>     llvm/trunk/test/MC/Disassembler/Hexagon/invalid_packet.txt
>     llvm/trunk/test/MC/Disassembler/Hexagon/too_many_instructions.txt
>     llvm/trunk/test/MC/Disassembler/Hexagon/too_many_loop_ends.txt
>     llvm/trunk/test/MC/Disassembler/Hexagon/unextendable.txt
>     llvm/trunk/test/MC/Hexagon/instructions/
>     llvm/trunk/test/MC/Hexagon/instructions/alu32_alu.s
>     llvm/trunk/test/MC/Hexagon/instructions/alu32_perm.s
>     llvm/trunk/test/MC/Hexagon/instructions/alu32_pred.s
>     llvm/trunk/test/MC/Hexagon/instructions/cr.s
>     llvm/trunk/test/MC/Hexagon/instructions/j.s
>     llvm/trunk/test/MC/Hexagon/instructions/jr.s
>     llvm/trunk/test/MC/Hexagon/instructions/ld.s
>     llvm/trunk/test/MC/Hexagon/instructions/memop.s
>     llvm/trunk/test/MC/Hexagon/instructions/nv_j.s
>     llvm/trunk/test/MC/Hexagon/instructions/nv_st.s
>     llvm/trunk/test/MC/Hexagon/instructions/st.s
>     llvm/trunk/test/MC/Hexagon/instructions/system_user.s
>     llvm/trunk/test/MC/Hexagon/instructions/xtype_alu.s
>     llvm/trunk/test/MC/Hexagon/instructions/xtype_bit.s
>     llvm/trunk/test/MC/Hexagon/instructions/xtype_complex.s
>     llvm/trunk/test/MC/Hexagon/instructions/xtype_fp.s
>     llvm/trunk/test/MC/Hexagon/instructions/xtype_mpy.s
>     llvm/trunk/test/MC/Hexagon/instructions/xtype_perm.s
>     llvm/trunk/test/MC/Hexagon/instructions/xtype_pred.s
>     llvm/trunk/test/MC/Hexagon/instructions/xtype_shift.s
> Modified:
>     llvm/trunk/lib/Target/Hexagon/CMakeLists.txt
>     llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
>     llvm/trunk/lib/Target/Hexagon/Disassembler/LLVMBuild.txt
>     llvm/trunk/lib/Target/Hexagon/Hexagon.td
>     llvm/trunk/lib/Target/Hexagon/HexagonMCInstLower.cpp
>     llvm/trunk/lib/Target/Hexagon/HexagonOperands.td
>     llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.td
>     llvm/trunk/lib/Target/Hexagon/LLVMBuild.txt
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h
>     llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h
>     llvm/trunk/test/CodeGen/Hexagon/absaddr-store.ll
>     llvm/trunk/test/CodeGen/Hexagon/absimm.ll
>     llvm/trunk/test/CodeGen/Hexagon/always-ext.ll
>     llvm/trunk/test/CodeGen/Hexagon/compound.ll
>     llvm/trunk/test/CodeGen/Hexagon/static.ll
>     llvm/trunk/test/CodeGen/Hexagon/zextloadi1.ll
>     llvm/trunk/test/MC/Disassembler/Hexagon/j.txt
>     llvm/trunk/test/MC/Disassembler/Hexagon/ld.txt
>     llvm/trunk/test/MC/Disassembler/Hexagon/lit.local.cfg
>     llvm/trunk/test/MC/Disassembler/Hexagon/nv_j.txt
>     llvm/trunk/test/MC/Disassembler/Hexagon/nv_st.txt
>     llvm/trunk/test/MC/Disassembler/Hexagon/st.txt
>
> Added: llvm/trunk/lib/Target/Hexagon/AsmParser/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/AsmParser/CMakeLists.txt?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/AsmParser/CMakeLists.txt (added)
> +++ llvm/trunk/lib/Target/Hexagon/AsmParser/CMakeLists.txt Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,7 @@
> +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/..
> ${CMAKE_CURRENT_SOURCE_DIR}/.. )
> +
> +add_llvm_library(LLVMHexagonAsmParser
> +  HexagonAsmParser.cpp
> +  )
> +
> +add_dependencies( LLVMHexagonAsmParser HexagonCommonTableGen )
>
> Added: llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp (added)
> +++ llvm/trunk/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp Sun Nov
> 8 22:07:48 2015
> @@ -0,0 +1,2152 @@
> +//===-- 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 "HexagonRegisterInfo.h"
> +#include "HexagonTargetStreamer.h"
> +#include "MCTargetDesc/HexagonBaseInfo.h"
> +#include "MCTargetDesc/HexagonMCELFStreamer.h"
> +#include "MCTargetDesc/HexagonMCChecker.h"
> +#include "MCTargetDesc/HexagonMCExpr.h"
> +#include "MCTargetDesc/HexagonMCShuffler.h"
> +#include "MCTargetDesc/HexagonMCTargetDesc.h"
> +#include "MCTargetDesc/HexagonMCAsmInfo.h"
> +#include "MCTargetDesc/HexagonShuffler.h"
> +#include "llvm/ADT/SmallString.h"
> +#include "llvm/ADT/SmallVector.h"
> +#include "llvm/ADT/StringExtras.h"
> +#include "llvm/ADT/Twine.h"
> +#include "llvm/MC/MCContext.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/MCParsedAsmOperand.h"
> +#include "llvm/MC/MCStreamer.h"
> +#include "llvm/MC/MCSectionELF.h"
> +#include "llvm/MC/MCSubtargetInfo.h"
> +#include "llvm/MC/MCTargetAsmParser.h"
> +#include "llvm/Support/CommandLine.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/ELF.h"
> +#include "llvm/Support/SourceMgr.h"
> +#include "llvm/Support/MemoryBuffer.h"
> +#include "llvm/Support/TargetRegistry.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include <sstream>
> +
> +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);
> +  }
> +
> +  MCSubtargetInfo &STI;
> +  MCAsmParser &Parser;
> +  MCAssembler *Assembler;
> +  MCInstrInfo const &MCII;
> +  MCInst MCB;
> +  bool InBrackets;
> +
> +  MCAsmParser &getParser() const { return Parser; }
> +  MCAssembler *getAssembler() const { return Assembler; }
> +  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
> +
> +  unsigned ArchVersion;
> +
> +  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);
> +
> +  virtual 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 &MustExtend);
> +
> +  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
> +                               OperandVector &Operands, MCStreamer &Out,
> +                               uint64_t &ErrorInfo, bool
> MatchingInlineAsm);
> +
> +  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned
> Kind) override;
> +  void OutOfRange(SMLoc IDLoc, long long Val, long long Max);
> +  int processInstruction(MCInst &Inst, OperandVector const &Operands,
> +                         SMLoc IDLoc, bool &MustExtend);
> +
> +  // Check if we have an assembler and, if so, set the ELF e_header flags.
> +  void chksetELFHeaderEFlags(unsigned flags) {
> +    if (getAssembler())
> +      getAssembler()->setELFHeaderEFlags(flags);
> +  }
> +
> +/// @name Auto-generated Match Functions
> +/// {
> +
> +#define GET_ASSEMBLER_HEADER
> +#include "HexagonGenAsmMatcher.inc"
> +
> +  /// }
> +
> +public:
> +  HexagonAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser,
> +                   const MCInstrInfo &MII, const MCTargetOptions &Options)
> +    : MCTargetAsmParser(Options), STI(_STI), Parser(_Parser),
> +      MCII (MII), InBrackets(false) {
> +  MCB.setOpcode(Hexagon::BUNDLE);
> +  setAvailableFeatures(
> +    ComputeAvailableFeatures(_STI.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 mustExtend(OperandVector &Operands);
> +  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);
> +  virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef
> Name,
> +                                SMLoc NameLoc, OperandVector &Operands) {
> +    llvm_unreachable("Unimplemented");
> +  }
> +  virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef
> Name,
> +                                AsmToken ID, OperandVector &Operands);
> +
> +  virtual bool ParseDirective(AsmToken DirectiveID);
> +};
> +
> +/// 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;
> +    bool MustExtend;
> +  };
> +
> +  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 { return StartLoc; }
> +
> +  /// getEndLoc - Get the location of the last token of this operand.
> +  SMLoc getEndLoc() const { return EndLoc; }
> +
> +  unsigned getReg() const {
> +    assert(Kind == Register && "Invalid access!");
> +    return Reg.RegNum;
> +  }
> +
> +  const MCExpr *getImm() const {
> +    assert(Kind == Immediate && "Invalid access!");
> +    return Imm.Val;
> +  }
> +
> +  bool isToken() const { return Kind == Token; }
> +  bool isImm() const { return Kind == Immediate; }
> +  bool isMem() const { llvm_unreachable("No isMem"); }
> +  bool isReg() const { return Kind == Register; }
> +
> +  bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
> +                     bool isRelocatable, bool Extendable) const {
> +    if (Kind == Immediate) {
> +      const MCExpr *myMCExpr = getImm();
> +      if (Imm.MustExtend && !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)) ? true :
> false;
> +          else {
> +            const int64_t high_bit_set = 1ULL << 63;
> +            const uint64_t mask = (high_bit_set >> (63 - bits));
> +            return (((uint64_t)Res & mask) == mask) ? true : false;
> +          }
> +        }
> +      } else if (myMCExpr->getKind() == MCExpr::SymbolRef &&
> isRelocatable)
> +        return true;
> +      else if (myMCExpr->getKind() == MCExpr::Binary ||
> +               myMCExpr->getKind() == MCExpr::Unary)
> +        return true;
> +    }
> +    return false;
> +  }
> +
> +  bool isf32Ext() const { return false; }
> +  bool iss32Imm() const { return CheckImmRange(32, 0, true, true, false);
> }
> +  bool iss8Imm() const { return CheckImmRange(8, 0, true, false, false); }
> +  bool iss8Imm64() const { return CheckImmRange(8, 0, true, true, false);
> }
> +  bool iss7Imm() const { return CheckImmRange(7, 0, true, false, false); }
> +  bool iss6Imm() const { return CheckImmRange(6, 0, true, false, false); }
> +  bool iss4Imm() const { return CheckImmRange(4, 0, 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 iss4_6Imm() const { return CheckImmRange(4, 0, true, false,
> false); }
> +  bool iss3_6Imm() const { return CheckImmRange(3, 0, true, false,
> false); }
> +  bool iss3Imm() const { return CheckImmRange(3, 0, true, false, false); }
> +
> +  bool isu64Imm() const { return CheckImmRange(64, 0, false, true, true);
> }
> +  bool isu32Imm() const { return CheckImmRange(32, 0, false, true,
> false); }
> +  bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true,
> false); }
> +  bool isu16Imm() const { return CheckImmRange(16, 0, 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 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 isu10Imm() const { return CheckImmRange(10, 0, false, false,
> false); }
> +  bool isu9Imm() const { return CheckImmRange(9, 0, false, false, false);
> }
> +  bool isu8Imm() const { return CheckImmRange(8, 0, false, false, false);
> }
> +  bool isu7Imm() const { return CheckImmRange(7, 0, false, false, false);
> }
> +  bool isu6Imm() const { return CheckImmRange(6, 0, false, false, false);
> }
> +  bool isu5Imm() const { return CheckImmRange(5, 0, false, false, false);
> }
> +  bool isu4Imm() const { return CheckImmRange(4, 0, false, false, false);
> }
> +  bool isu3Imm() const { return CheckImmRange(3, 0, false, false, false);
> }
> +  bool isu2Imm() const { return CheckImmRange(2, 0, false, false, false);
> }
> +  bool isu1Imm() const { return CheckImmRange(1, 0, false, false, false);
> }
> +
> +  bool ism6Imm() const { return CheckImmRange(6, 0, false, false, false);
> }
> +  bool isn8Imm() const { return CheckImmRange(8, 0, false, false, false);
> }
> +
> +  bool iss16Ext() const { return CheckImmRange(16 + 26, 0, true, true,
> true); }
> +  bool iss12Ext() const { return CheckImmRange(12 + 26, 0, true, true,
> true); }
> +  bool iss10Ext() const { return CheckImmRange(10 + 26, 0, true, true,
> true); }
> +  bool iss9Ext() const { return CheckImmRange(9 + 26, 0, true, true,
> true); }
> +  bool iss8Ext() const { return CheckImmRange(8 + 26, 0, true, true,
> true); }
> +  bool iss7Ext() const { return CheckImmRange(7 + 26, 0, true, true,
> true); }
> +  bool iss6Ext() const { return CheckImmRange(6 + 26, 0, true, true,
> true); }
> +  bool iss11_0Ext() const {
> +    return CheckImmRange(11 + 26, 0, true, true, true);
> +  }
> +  bool iss11_1Ext() const {
> +    return CheckImmRange(11 + 26, 1, true, true, true);
> +  }
> +  bool iss11_2Ext() const {
> +    return CheckImmRange(11 + 26, 2, true, true, true);
> +  }
> +  bool iss11_3Ext() const {
> +    return CheckImmRange(11 + 26, 3, true, true, true);
> +  }
> +
> +  bool isu6Ext() const { return CheckImmRange(6 + 26, 0, false, true,
> true); }
> +  bool isu7Ext() const { return CheckImmRange(7 + 26, 0, false, true,
> true); }
> +  bool isu8Ext() const { return CheckImmRange(8 + 26, 0, false, true,
> true); }
> +  bool isu9Ext() const { return CheckImmRange(9 + 26, 0, false, true,
> true); }
> +  bool isu10Ext() const { return CheckImmRange(10 + 26, 0, false, true,
> true); }
> +  bool isu6_0Ext() const { return CheckImmRange(6 + 26, 0, false, true,
> true); }
> +  bool isu6_1Ext() const { return CheckImmRange(6 + 26, 1, false, true,
> true); }
> +  bool isu6_2Ext() const { return CheckImmRange(6 + 26, 2, false, true,
> true); }
> +  bool isu6_3Ext() const { return CheckImmRange(6 + 26, 3, false, true,
> true); }
> +  bool isu32MustExt() const { return isImm() && Imm.MustExtend; }
> +
> +  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!");
> +    MCExpr const *Expr = 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)) {
> +      Inst.addOperand(MCOperand::createExpr(Expr));
> +      return;
> +    }
> +    // Flip bit 33 to signal signed unsigned mismatch
> +    Extended ^= 0x100000000;
> +    Inst.addOperand(MCOperand::createImm(Extended));
> +  }
> +
> +  void addf32ExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +
> +  void adds32ImmOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds8ImmOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds8Imm64Operands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds6ImmOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds4ImmOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds4_0ImmOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds4_1ImmOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds4_2ImmOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds4_3ImmOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds3ImmOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +
> +  void addu64ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu32ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu26_6ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu16ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu16_0ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu16_1ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu16_2ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu16_3ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu11_3ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu10ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu9ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu8ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu7ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu6ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu6_0ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu6_1ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu6_2ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu6_3ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu5ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu4ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu3ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu2ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu1ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +
> +  void addm6ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addn8ImmOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +
> +  void adds16ExtOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds12ExtOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds10ExtOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds9ExtOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds8ExtOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds6ExtOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds11_0ExtOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds11_1ExtOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds11_2ExtOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +  void adds11_3ExtOperands(MCInst &Inst, unsigned N) const {
> +    addSignedImmOperands(Inst, N);
> +  }
> +
> +  void addu6ExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu7ExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu8ExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu9ExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu10ExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu6_0ExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu6_1ExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu6_2ExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu6_3ExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +  void addu32MustExtOperands(MCInst &Inst, unsigned N) const {
> +    addImmOperands(Inst, N);
> +  }
> +
> +  void adds4_6ImmOperands(MCInst &Inst, unsigned N) const {
> +    assert(N == 1 && "Invalid number of operands!");
> +    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
> +    Inst.addOperand(MCOperand::createImm(CE->getValue() << 6));
> +  }
> +
> +  void adds3_6ImmOperands(MCInst &Inst, unsigned N) const {
> +    assert(N == 1 && "Invalid number of operands!");
> +    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
> +    Inst.addOperand(MCOperand::createImm(CE->getValue() << 6));
> +  }
> +
> +  StringRef getToken() const {
> +    assert(Kind == Token && "Invalid access!");
> +    return StringRef(Tok.Data, Tok.Length);
> +  }
> +
> +  virtual void print(raw_ostream &OS) const;
> +
> +  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->Imm.MustExtend = false;
> +    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;
> +  }
> +}
> +
> +/// @name Auto-generated Match Functions
> +static unsigned MatchRegisterName(StringRef Name);
> +
> +bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
> +  DEBUG(dbgs() << "Bundle:");
> +  DEBUG(MCB.dump_pretty(dbgs()));
> +  DEBUG(dbgs() << "--\n");
> +
> +  // Check the bundle for errors.
> +  const MCRegisterInfo *RI = getContext().getRegisterInfo();
> +  HexagonMCChecker Check(MCII, STI, MCB, MCB, *RI);
> +
> +  bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MCII, STI,
> getContext(),
> +                                                        MCB, &Check);
> +
> +  while (Check.getNextErrInfo() == true) {
> +    unsigned Reg = Check.getErrRegister();
> +    Twine R(RI->getName(Reg));
> +
> +    uint64_t Err = Check.getError();
> +    if (Err != HexagonMCErrInfo::CHECK_SUCCESS) {
> +      if (HexagonMCErrInfo::CHECK_ERROR_BRANCHES & Err)
> +        Error(IDLoc,
> +              "unconditional branch cannot precede another branch in
> packet");
> +
> +      if (HexagonMCErrInfo::CHECK_ERROR_NEWP & Err ||
> +          HexagonMCErrInfo::CHECK_ERROR_NEWV & Err)
> +        Error(IDLoc, "register `" + R +
> +                         "' used with `.new' "
> +                         "but not validly modified in the same packet");
> +
> +      if (HexagonMCErrInfo::CHECK_ERROR_REGISTERS & Err)
> +        Error(IDLoc, "register `" + R + "' modified more than once");
> +
> +      if (HexagonMCErrInfo::CHECK_ERROR_READONLY & Err)
> +        Error(IDLoc, "cannot write to read-only register `" + R + "'");
> +
> +      if (HexagonMCErrInfo::CHECK_ERROR_LOOP & Err)
> +        Error(IDLoc, "loop-setup and some branch instructions "
> +                     "cannot be in the same packet");
> +
> +      if (HexagonMCErrInfo::CHECK_ERROR_ENDLOOP & Err) {
> +        Twine N(HexagonMCInstrInfo::isInnerLoop(MCB) ? '0' : '1');
> +        Error(IDLoc, "packet marked with `:endloop" + N + "' " +
> +                         "cannot contain instructions that modify
> register " +
> +                         "`" + R + "'");
> +      }
> +
> +      if (HexagonMCErrInfo::CHECK_ERROR_SOLO & Err)
> +        Error(IDLoc,
> +              "instruction cannot appear in packet with other
> instructions");
> +
> +      if (HexagonMCErrInfo::CHECK_ERROR_NOSLOTS & Err)
> +        Error(IDLoc, "too many slots used in packet");
> +
> +      if (Err & HexagonMCErrInfo::CHECK_ERROR_SHUFFLE) {
> +        uint64_t Erm = Check.getShuffleError();
> +
> +        if (HexagonShuffler::SHUFFLE_ERROR_INVALID == Erm)
> +          Error(IDLoc, "invalid instruction packet");
> +        else if (HexagonShuffler::SHUFFLE_ERROR_STORES == Erm)
> +          Error(IDLoc, "invalid instruction packet: too many stores");
> +        else if (HexagonShuffler::SHUFFLE_ERROR_LOADS == Erm)
> +          Error(IDLoc, "invalid instruction packet: too many loads");
> +        else if (HexagonShuffler::SHUFFLE_ERROR_BRANCHES == Erm)
> +          Error(IDLoc, "too many branches in packet");
> +        else if (HexagonShuffler::SHUFFLE_ERROR_NOSLOTS == Erm)
> +          Error(IDLoc, "invalid instruction packet: out of slots");
> +        else if (HexagonShuffler::SHUFFLE_ERROR_SLOTS == Erm)
> +          Error(IDLoc, "invalid instruction packet: slot error");
> +        else if (HexagonShuffler::SHUFFLE_ERROR_ERRATA2 == Erm)
> +          Error(IDLoc, "v60 packet violation");
> +        else if (HexagonShuffler::SHUFFLE_ERROR_STORE_LOAD_CONFLICT ==
> Erm)
> +          Error(IDLoc, "slot 0 instruction does not allow slot 1 store");
> +        else
> +          Error(IDLoc, "unknown error in instruction packet");
> +      }
> +    }
> +
> +    unsigned Warn = Check.getWarning();
> +    if (Warn != HexagonMCErrInfo::CHECK_SUCCESS) {
> +      if (HexagonMCErrInfo::CHECK_WARN_CURRENT & Warn)
> +        Warning(IDLoc, "register `" + R + "' used with `.cur' "
> +                                          "but not used in the same
> packet");
> +      else if (HexagonMCErrInfo::CHECK_WARN_TEMPORARY & Warn)
> +        Warning(IDLoc, "register `" + R + "' used with `.tmp' "
> +                                          "but not used in the same
> packet");
> +    }
> +  }
> +
> +  if (CheckOk) {
> +    MCB.setLoc(IDLoc);
> +    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, STI);
> +  } 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();
> +  MCAsmLexer &Lexer = getLexer();
> +  while (true) {
> +    if (!Parser.getTok().is(AsmToken::Colon))
> +      return false;
> +    Lexer.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 if (Option.compare_lower("mem_noshuf") == 0)
> +      HexagonMCInstrInfo::setMemReorderDisabled(MCB);
> +    else if (Option.compare_lower("mem_shuf") == 0)
> +      HexagonMCInstrInfo::setMemStoreReorderEnabled(MCB);
> +    else
> +      return true;
> +    Lexer.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());
> +      if ((Value & 0x100000000) != (Value & 0x80000000)) {
> +        // Detect flipped bit 33 wrt bit 32 and signal warning
> +        Value ^= 0x100000000;
> +        if (WarnSignedMismatch)
> +          Warning (MCI.getLoc(), "Signed/Unsigned mismatch");
> +      }
> +      NewInst.addOperand(MCOperand::createExpr(
> +          MCConstantExpr::create(Value, getContext())));
> +    }
> +    else
> +      NewInst.addOperand(I);
> +  MCI = NewInst;
> +}
> +
> +bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
> +                                           OperandVector &InstOperands,
> +                                           uint64_t &ErrorInfo,
> +                                           bool MatchingInlineAsm,
> +                                           bool &MustExtend) {
> +  // Perform matching with tablegen asmmatcher generated function
> +  int result =
> +      MatchInstructionImpl(InstOperands, MCI, ErrorInfo,
> MatchingInlineAsm);
> +  if (result == Match_Success) {
> +    MCI.setLoc(IDLoc);
> +    MustExtend = mustExtend(InstOperands);
> +    canonicalizeImmediates(MCI);
> +    result = processInstruction(MCI, InstOperands, IDLoc, MustExtend);
> +
> +    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::mustExtend(OperandVector &Operands) {
> +  unsigned Count = 0;
> +  for (std::unique_ptr<MCParsedAsmOperand> &i : Operands)
> +    if (i->isImm())
> +      if (static_cast<HexagonOperand *>(i.get())->Imm.MustExtend)
> +        ++Count;
> +  // Multiple extenders should have been filtered by iss9Ext et. al.
> +  assert(Count < 2 && "Multiple extenders");
> +  return Count == 1;
> +}
> +
> +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;
> +  bool MustExtend = false;
> +  if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
> +                          MatchingInlineAsm, MustExtend))
> +    return true;
> +  HexagonMCInstrInfo::extendIfNeeded(
> +      MCII, MCB, *SubInst,
> +      HexagonMCInstrInfo::isExtended(MCII, *SubInst) || MustExtend);
> +  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 = 0;
> +  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 = MCConstantExpr::create(8192 + Res, this->getContext());
> +
> +  getStreamer().SubSection(Subsection);
> +  return false;
> +}
> +
> +///  ::= .falign [expression]
> +bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
> +
> +  int64_t MaxBytesToFill = 15;
> +
> +  // if there is an arguement
> +  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) == false) {
> +      // 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)) {
> +
> +    for (;;) {
> +      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 {
> +  return true;
> +}
> +
> +// extern "C" void LLVMInitializeHexagonAsmLexer();
> +
> +/// Force static initialization.
> +extern "C" void LLVMInitializeHexagonAsmParser() {
> +  RegisterMCAsmParser<HexagonAsmParser> X(TheHexagonTarget);
> +}
> +
> +#define GET_MATCHER_IMPLEMENTATION
> +#define GET_REGISTER_MATCHER
> +#include "HexagonGenAsmMatcher.inc"
> +
> +namespace {
> +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);
> +}
> +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();
> +  getLexer().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));
> +          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));
> +          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;
> +  if (!Token.is(AsmToken::TokenKind::Identifier))
> +    return true;
> +  if (!MatchRegisterName(String.lower()))
> +    return true;
> +  assert(Second.is(AsmToken::Colon));
> +  StringRef Raw (String.data(), Third.getString().data() - String.data() +
> +                 Third.getString().size());
> +  std::string Collapsed = Raw;
> +  Collapsed.erase(std::remove_if(Collapsed.begin(), Collapsed.end(),
> isspace),
> +                  Collapsed.end());
> +  StringRef Whole = Collapsed;
> +  std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
> +  if (!MatchRegisterName(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(std::remove_if(Collapsed.begin(), Collapsed.end(),
> isspace),
> +                  Collapsed.end());
> +  StringRef FullString = Collapsed;
> +  std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
> +  unsigned DotReg = MatchRegisterName(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 = MatchRegisterName(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) {
> +  llvm::SmallVector<AsmToken, 4> Tokens;
> +  MCAsmLexer &Lexer = getLexer();
> +  bool Done = false;
> +  static char const * Comma = ",";
> +  do {
> +    Tokens.emplace_back (Lexer.getTok());
> +    Lexer.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();
> +    std::unique_ptr<HexagonOperand> Expr =
> +        HexagonOperand::CreateImm(nullptr, Loc, Loc);
> +    MCExpr const *& Val = Expr->Imm.Val;
> +    Operands.push_back(std::move(Expr));
> +    return parseExpression(Val);
> +  }
> +  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: {
> +      Lexer.Lex();
> +      return false;
> +    }
> +    case AsmToken::LCurly: {
> +      if (!Operands.empty())
> +        return true;
> +      Operands.push_back(
> +          HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
> +      Lexer.Lex();
> +      return false;
> +    }
> +    case AsmToken::RCurly: {
> +      if (Operands.empty()) {
> +        Operands.push_back(
> +            HexagonOperand::CreateToken(Token.getString(),
> Token.getLoc()));
> +        Lexer.Lex();
> +      }
> +      return false;
> +    }
> +    case AsmToken::Comma: {
> +      Lexer.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()));
> +      Lexer.Lex();
> +      continue;
> +    }
> +    case AsmToken::Hash: {
> +      bool MustNotExtend = false;
> +      bool ImplicitExpression = implicitExpressionLocation(Operands);
> +      std::unique_ptr<HexagonOperand> Expr = HexagonOperand::CreateImm(
> +          nullptr, Lexer.getLoc(), Lexer.getLoc());
> +      if (!ImplicitExpression)
> +        Operands.push_back(
> +          HexagonOperand::CreateToken(Token.getString(), Token.getLoc()));
> +      Lexer.Lex();
> +      bool MustExtend = false;
> +      bool HiOnly = false;
> +      bool LoOnly = false;
> +      if (Lexer.is(AsmToken::Hash)) {
> +        Lexer.Lex();
> +        MustExtend = true;
> +      } else if (ImplicitExpression)
> +        MustNotExtend = true;
> +      AsmToken const &Token = Parser.getTok();
> +      if (Token.is(AsmToken::Identifier)) {
> +        StringRef String = Token.getString();
> +        AsmToken IDToken = Token;
> +        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 {
> +            Lexer.Lex();
> +          }
> +        }
> +      }
> +      if (parseExpression(Expr->Imm.Val))
> +        return true;
> +      int64_t Value;
> +      MCContext &Context = Parser.getContext();
> +      assert(Expr->Imm.Val != nullptr);
> +      if (Expr->Imm.Val->evaluateAsAbsolute(Value)) {
> +        if (HiOnly)
> +          Expr->Imm.Val = MCBinaryExpr::createLShr(
> +              Expr->Imm.Val, MCConstantExpr::create(16, Context),
> Context);
> +        if (HiOnly || LoOnly)
> +          Expr->Imm.Val = MCBinaryExpr::createAnd(
> +              Expr->Imm.Val, MCConstantExpr::create(0xffff, Context),
> Context);
> +      }
> +      if (MustNotExtend)
> +        Expr->Imm.Val = HexagonNoExtendOperand::Create(Expr->Imm.Val,
> Context);
> +      Expr->Imm.MustExtend = MustExtend;
> +      Operands.push_back(std::move(Expr));
> +      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);
> +}
> +
> +namespace {
> +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;
> +  }
> +  case MCK__MINUS_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;
> +}
> +
> +void HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long
> Max) {
> +  std::stringstream errStr;
> +  errStr << "value " << Val << "(0x" << std::hex << Val << std::dec
> +         << ") out of range: ";
> +  if (Max >= 0)
> +    errStr << "0-" << Max;
> +  else
> +    errStr << Max << "-" << (-Max - 1);
> +  Error(IDLoc, errStr.str().c_str());
> +}
> +
> +int HexagonAsmParser::processInstruction(MCInst &Inst,
> +                                         OperandVector const &Operands,
> +                                         SMLoc IDLoc, bool &MustExtend) {
> +  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::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(MCBinaryExpr::createSub(
> +        MO.getExpr(), MCConstantExpr::create(1, 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);
> +    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(MCBinaryExpr::createSub(
> +          MO.getExpr(), MCConstantExpr::create(1, Context), Context));
> +      Inst.setOpcode(Hexagon::C2_cmpgtui);
> +    }
> +    break;
> +  }
> +  case Hexagon::J2_loop1r:
> +  case Hexagon::J2_loop1i:
> +  case Hexagon::J2_loop0r:
> +  case Hexagon::J2_loop0i: {
> +    MCOperand &MO = Inst.getOperand(0);
> +    // Loop has different opcodes for extended vs not extended, but we
> should
> +    //   not use the other opcode as it is a legacy artifact of TD files.
> +    int64_t Value;
> +    if (MO.getExpr()->evaluateAsAbsolute(Value)) {
> +      // if the the operand can fit within a 7:2 field
> +      if (Value < (1 << 8) && Value >= -(1 << 8)) {
> +        SMLoc myLoc = Operands[2]->getStartLoc();
> +        // # is left in startLoc in the case of ##
> +        // If '##' found then force extension.
> +        if (*myLoc.getPointer() == '#') {
> +          MustExtend = true;
> +          break;
> +        }
> +      } else {
> +        // If immediate and out of 7:2 range.
> +        MustExtend = true;
> +      }
> +    }
> +    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 + llvm::utostr_32(RegPairNum + 1);
> +    StringRef Reg1(R1);
> +    MO.setReg(MatchRegisterName(Reg1));
> +    // Add a new operand for the second register in the pair.
> +    std::string R2 = r + llvm::utostr_32(RegPairNum);
> +    StringRef Reg2(R2);
> +    Inst.addOperand(MCOperand::createReg(MatchRegisterName(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 + llvm::utostr_32(RegPairNum + 1);
> +    StringRef Reg1(R1);
> +    MO.setReg(MatchRegisterName(Reg1));
> +    // Add a new operand for the second register in the pair.
> +    std::string R2 = r + llvm::utostr_32(RegPairNum);
> +    StringRef Reg2(R2);
> +    Inst.addOperand(MCOperand::createReg(MatchRegisterName(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 + llvm::utostr_32(RegPairNum + 1);
> +    StringRef Reg1(R1);
> +    MO.setReg(MatchRegisterName(Reg1));
> +    // Add a new operand for the second register in the pair.
> +    std::string R2 = r + llvm::utostr_32(RegPairNum);
> +    StringRef Reg2(R2);
> +    Inst.addOperand(MCOperand::createReg(MatchRegisterName(Reg2)));
> +    Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
> +                       ? Hexagon::C2_ccombinewnewt
> +                       : Hexagon::C2_ccombinewnewf);
> +    break;
> +  }
> +
> +  // Translate a "$Rx =  CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
> +  case Hexagon::CONST32:
> +  case Hexagon::CONST32_Float_Real:
> +  case Hexagon::CONST32_Int_Real:
> +  case Hexagon::FCONST32_nsdata:
> +    is32bit = true;
> +  // Translate a "$Rx:y =  CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
> +  case Hexagon::CONST64_Float_Real:
> +  case Hexagon::CONST64_Int_Real:
> +
> +    // 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 = 0;
> +        const char *StringEnd = 0;
> +        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(MCSymbolRefExpr::create(Sym,
> 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(MCConstantExpr::create(sVal,
> 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)) {
> +      unsigned long long u64 = Value;
> +      signed int s8 = (u64 >> 32) & 0xFFFFFFFF;
> +      if (s8 < -128 || s8 > 127)
> +        OutOfRange(IDLoc, s8, -128);
> +      MCOperand imm(MCOperand::createExpr(
> +          MCConstantExpr::create(s8, Context))); // upper 32
> +      MCOperand imm2(MCOperand::createExpr(
> +          MCConstantExpr::create(u64 & 0xFFFFFFFF, Context))); // lower 32
> +      Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
> +    } else {
> +      MCOperand imm(MCOperand::createExpr(
> +          MCConstantExpr::create(0, 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(MCBinaryExpr::createSub(
> +        Imm6.getExpr(), MCConstantExpr::create(1, 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(MCBinaryExpr::createSub(
> +        Imm6.getExpr(), MCConstantExpr::create(2, 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(MCBinaryExpr::createSub(
> +        Imm6.getExpr(), MCConstantExpr::create(3, 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;
> +    bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
> +    assert(Absolute);
> +    (void)Absolute;
> +    if (!MustExtend) {
> +      if (Value < 0 && Value > -256) {
> +        Imm.setExpr(MCConstantExpr::create(Value * -1, 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(MCBinaryExpr::createSub(
> +          Imm.getExpr(), MCConstantExpr::create(1, 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 + llvm::utostr_32(RegPairNum + 1);
> +      StringRef Reg1(R1);
> +      Rss.setReg(MatchRegisterName(Reg1));
> +      // Add a new operand for the second register in the pair.
> +      std::string R2 = r + llvm::utostr_32(RegPairNum);
> +      StringRef Reg2(R2);
> +      TmpInst.setOpcode(Hexagon::A2_combinew);
> +      TmpInst.addOperand(Rdd);
> +      TmpInst.addOperand(Rss);
> +      TmpInst.addOperand(MCOperand::createReg(MatchRegisterName(Reg2)));
> +      Inst = TmpInst;
> +    } else {
> +      Imm.setExpr(MCBinaryExpr::createSub(
> +          Imm.getExpr(), MCConstantExpr::create(1, 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 + llvm::utostr_32(RegNum) + Colon + llvm::utostr_32(RegNum -
> 1);
> +      StringRef RegPair = Name;
> +      Rs.setReg(MatchRegisterName(RegPair));
> +    } else { // raw:lo
> +      Inst.setOpcode(Hexagon::A4_boundscheck_lo);
> +      std::string Name =
> +          r + llvm::utostr_32(RegNum + 1) + Colon +
> llvm::utostr_32(RegNum);
> +      StringRef RegPair = Name;
> +      Rs.setReg(MatchRegisterName(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 + llvm::utostr_32(RegNum) + Colon + llvm::utostr_32(RegNum -
> 1);
> +      StringRef RegPair = Name;
> +      Rs.setReg(MatchRegisterName(RegPair));
> +    } else { // Even mapped raw:lo
> +      Inst.setOpcode(Hexagon::A2_addspl);
> +      std::string Name =
> +          r + llvm::utostr_32(RegNum + 1) + Colon +
> llvm::utostr_32(RegNum);
> +      StringRef RegPair = Name;
> +      Rs.setReg(MatchRegisterName(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 + llvm::utostr_32(RegNum) + Colon + llvm::utostr_32(RegNum -
> 1);
> +      StringRef RegPair = Name;
> +      Rt.setReg(MatchRegisterName(RegPair));
> +    } else { // Even mapped sat:raw:lo
> +      Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
> +      std::string Name =
> +          r + llvm::utostr_32(RegNum + 1) + Colon +
> llvm::utostr_32(RegNum);
> +      StringRef RegPair = Name;
> +      Rt.setReg(MatchRegisterName(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 + llvm::utostr_32(RegNum) + Colon + llvm::utostr_32(RegNum -
> 1);
> +      StringRef RegPair = Name;
> +      Rt.setReg(MatchRegisterName(RegPair));
> +    } else { // Even mapped sat:raw:lo
> +      TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
> +      std::string Name =
> +          r + llvm::utostr_32(RegNum + 1) + Colon +
> llvm::utostr_32(RegNum);
> +      StringRef RegPair = Name;
> +      Rt.setReg(MatchRegisterName(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 + llvm::utostr_32(RegNum) + Colon + llvm::utostr_32(RegNum -
> 1);
> +      StringRef RegPair = Name;
> +      Rt.setReg(MatchRegisterName(RegPair));
> +    } else { // Even mapped rnd:sat:raw:lo
> +      Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
> +      std::string Name =
> +          r + llvm::utostr_32(RegNum + 1) + Colon +
> llvm::utostr_32(RegNum);
> +      StringRef RegPair = Name;
> +      Rt.setReg(MatchRegisterName(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(MCBinaryExpr::createSub(
> +          Imm.getExpr(), MCConstantExpr::create(1, 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 + llvm::utostr_32(RegPairNum + 1);
> +      StringRef Reg1(R1);
> +      Rss.setReg(MatchRegisterName(Reg1));
> +      // Add a new operand for the second register in the pair.
> +      std::string R2 = r + llvm::utostr_32(RegPairNum);
> +      StringRef Reg2(R2);
> +      TmpInst.setOpcode(Hexagon::A2_combinew);
> +      TmpInst.addOperand(Rdd);
> +      TmpInst.addOperand(Rss);
> +      TmpInst.addOperand(MCOperand::createReg(MatchRegisterName(Reg2)));
> +      Inst = TmpInst;
> +    } else {
> +      Imm.setExpr(MCBinaryExpr::createSub(
> +          Imm.getExpr(), MCConstantExpr::create(1, 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(MCConstantExpr::create(-1, Context)));
> +    TmpInst.addOperand(Rs);
> +    Inst = TmpInst;
> +    break;
> +  }
> +  } // switch
> +
> +  return Match_Success;
> +}
>
> Added: llvm/trunk/lib/Target/Hexagon/AsmParser/LLVMBuild.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/AsmParser/LLVMBuild.txt?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/AsmParser/LLVMBuild.txt (added)
> +++ llvm/trunk/lib/Target/Hexagon/AsmParser/LLVMBuild.txt Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,23 @@
> +;===- ./lib/Target/Hexagon/AsmParser/LLVMBuild.txt --------------*- Conf
> -*-===;
> +;
> +;                     The LLVM Compiler Infrastructure
> +;
> +; This file is distributed under the University of Illinois Open Source
> +; License. See LICENSE.TXT for details.
> +;
>
> +;===------------------------------------------------------------------------===;
> +;
> +; This is an LLVMBuild description file for the components in this
> subdirectory.
> +;
> +; For more information on the LLVMBuild system, please see:
> +;
> +;   http://llvm.org/docs/LLVMBuild.html
> +;
>
> +;===------------------------------------------------------------------------===;
> +
> +[component_0]
> +type = Library
> +name = HexagonAsmParser
> +parent = Hexagon
> +required_libraries = MC MCParser Support HexagonDesc HexagonInfo
> +add_to_library_groups = Hexagon
>
> Added: llvm/trunk/lib/Target/Hexagon/AsmParser/Makefile
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/AsmParser/Makefile?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/AsmParser/Makefile (added)
> +++ llvm/trunk/lib/Target/Hexagon/AsmParser/Makefile Sun Nov  8 22:07:48
> 2015
> @@ -0,0 +1,15 @@
> +##===- lib/Target/Hexagon/AsmParser/Makefile ------------------*-
> Makefile -*-===##
> +#
> +#                     The LLVM Compiler Infrastructure
> +#
> +# This file is distributed under the University of Illinois Open Source
> +# License. See LICENSE.TXT for details.
> +#
>
> +##===----------------------------------------------------------------------===##
> +LEVEL = ../../../..
> +LIBRARYNAME = LLVMHexagonAsmParser
> +
> +# Hack: we need to include 'main' Hexagon target directory to grab
> private headers
> +CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
> +
> +include $(LEVEL)/Makefile.common
>
> Modified: llvm/trunk/lib/Target/Hexagon/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/CMakeLists.txt?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Target/Hexagon/CMakeLists.txt Sun Nov  8 22:07:48 2015
> @@ -1,5 +1,6 @@
>  set(LLVM_TARGET_DEFINITIONS Hexagon.td)
>
> +tablegen(LLVM HexagonGenAsmMatcher.inc -gen-asm-matcher)
>  tablegen(LLVM HexagonGenAsmWriter.inc -gen-asm-writer)
>  tablegen(LLVM HexagonGenCallingConv.inc -gen-callingconv)
>  tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel)
> @@ -50,6 +51,7 @@ add_llvm_target(HexagonCodeGen
>    HexagonVLIWPacketizer.cpp
>  )
>
> +add_subdirectory(AsmParser)
>  add_subdirectory(TargetInfo)
>  add_subdirectory(MCTargetDesc)
>  add_subdirectory(Disassembler)
>
> Modified:
> llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp
> (original)
> +++ llvm/trunk/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp Sun
> Nov  8 22:07:48 2015
> @@ -7,42 +7,45 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> +#define DEBUG_TYPE "hexagon-disassembler"
> +
>  #include "Hexagon.h"
>  #include "MCTargetDesc/HexagonBaseInfo.h"
> -#include "MCTargetDesc/HexagonMCInstrInfo.h"
> +#include "MCTargetDesc/HexagonMCChecker.h"
>  #include "MCTargetDesc/HexagonMCTargetDesc.h"
> -
> -#include "llvm/MC/MCContext.h"
> +#include "MCTargetDesc/HexagonMCInstrInfo.h"
> +#include "MCTargetDesc/HexagonInstPrinter.h"
> +#include "llvm/ADT/StringExtras.h"
>  #include "llvm/MC/MCDisassembler.h"
> +#include "llvm/MC/MCContext.h"
>  #include "llvm/MC/MCExpr.h"
>  #include "llvm/MC/MCFixedLenDisassembler.h"
>  #include "llvm/MC/MCInst.h"
>  #include "llvm/MC/MCInstrDesc.h"
> +#include "llvm/MC/MCInstrInfo.h"
>  #include "llvm/MC/MCSubtargetInfo.h"
>  #include "llvm/Support/Debug.h"
> -#include "llvm/Support/Endian.h"
>  #include "llvm/Support/ErrorHandling.h"
>  #include "llvm/Support/LEB128.h"
> -#include "llvm/Support/TargetRegistry.h"
> +#include "llvm/Support/MemoryObject.h"
>  #include "llvm/Support/raw_ostream.h"
> -#include <array>
> +#include "llvm/Support/TargetRegistry.h"
>  #include <vector>
>
>  using namespace llvm;
>  using namespace Hexagon;
>
> -#define DEBUG_TYPE "hexagon-disassembler"
> -
> -// Pull DecodeStatus and its enum values into the global namespace.
> -typedef llvm::MCDisassembler::DecodeStatus DecodeStatus;
> +typedef MCDisassembler::DecodeStatus DecodeStatus;
>
>  namespace {
>  /// \brief Hexagon disassembler for all Hexagon platforms.
>  class HexagonDisassembler : public MCDisassembler {
>  public:
> +  std::unique_ptr<MCInstrInfo const> const MCII;
>    std::unique_ptr<MCInst *> CurrentBundle;
> -  HexagonDisassembler(MCSubtargetInfo const &STI, MCContext &Ctx)
> -      : MCDisassembler(STI, Ctx), CurrentBundle(new MCInst *) {}
> +  HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
> +                      MCInstrInfo const *MCII)
> +      : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *)
> {}
>
>    DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
>                                      ArrayRef<uint8_t> Bytes, uint64_t
> Address,
> @@ -52,10 +55,16 @@ public:
>                                ArrayRef<uint8_t> Bytes, uint64_t Address,
>                                raw_ostream &VStream,
>                                raw_ostream &CStream) const override;
> +
> +  void adjustExtendedInstructions(MCInst &MCI, MCInst const &MCB) const;
> +  void addSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst)
> const;
>  };
>  }
>
> -static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> +// Forward declare these because the auto-generated code will reference
> them.
> +// Definitions are further down.
> +
> +static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
>                                                 uint64_t Address,
>                                                 const void *Decoder);
>  static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned
> RegNo,
> @@ -64,23 +73,39 @@ static DecodeStatus DecodeIntRegsLow8Reg
>  static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
>                                                    uint64_t Address,
>                                                    const void *Decoder);
> +static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> +                                                  uint64_t Address,
> +                                                  const void *Decoder);
>  static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
>                                                    uint64_t Address,
>                                                    const void *Decoder);
> +static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> +                                                uint64_t Address,
> +                                                const void *Decoder);
>  static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
>                                                     uint64_t Address,
>                                                     const void *Decoder);
>  static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
>                                                 uint64_t Address,
>                                                 const void *Decoder);
> +static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> +                                               uint64_t Address,
> +                                               const void *Decoder);
>  static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned
> RegNo,
>                                                   uint64_t Address,
> -                                                 void const *Decoder);
> +                                                 const void *Decoder);
> +
> +static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn);
> +static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn,
> +                                 void const *Decoder);
>
>  static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned
> &op,
>                                   raw_ostream &os);
> -static void AddSubinstOperands(MCInst *MI, unsigned opcode, unsigned
> inst);
>
> +static unsigned getRegFromSubinstEncoding(unsigned encoded_reg);
> +
> +static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
> +                                       uint64_t Address, const void
> *Decoder);
>  static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp, uint64_t
> Address,
>                                    const void *Decoder);
>  static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp, uint64_t
> Address,
> @@ -111,129 +136,15 @@ static DecodeStatus s4_6ImmDecoder(MCIns
>                                     const void *Decoder);
>  static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t
> Address,
>                                     const void *Decoder);
> -
> -static const uint16_t IntRegDecoderTable[] = {
> -    Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,  Hexagon::R4,
> -    Hexagon::R5,  Hexagon::R6,  Hexagon::R7,  Hexagon::R8,  Hexagon::R9,
> -    Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
> -    Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
> -    Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
> -    Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
> -    Hexagon::R30, Hexagon::R31};
> -
> -static const uint16_t PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
> -                                               Hexagon::P2, Hexagon::P3};
> -
> -static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
> -                                        const uint16_t Table[], size_t
> Size) {
> -  if (RegNo < Size) {
> -    Inst.addOperand(MCOperand::createReg(Table[RegNo]));
> -    return MCDisassembler::Success;
> -  } else
> -    return MCDisassembler::Fail;
> -}
> -
> -static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> -                                               uint64_t /*Address*/,
> -                                               void const *Decoder) {
> -  if (RegNo > 31)
> -    return MCDisassembler::Fail;
> -
> -  unsigned Register = IntRegDecoderTable[RegNo];
> -  Inst.addOperand(MCOperand::createReg(Register));
> -  return MCDisassembler::Success;
> -}
> -
> -static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> -                                               uint64_t /*Address*/,
> -                                               const void *Decoder) {
> -  static const uint16_t CtrlRegDecoderTable[] = {
> -      Hexagon::SA0,  Hexagon::LC0,        Hexagon::SA1,  Hexagon::LC1,
> -      Hexagon::P3_0, Hexagon::NoRegister, Hexagon::C6,   Hexagon::C7,
> -      Hexagon::USR,  Hexagon::PC,         Hexagon::UGP,  Hexagon::GP,
> -      Hexagon::CS0,  Hexagon::CS1,        Hexagon::UPCL, Hexagon::UPCH};
> -
> -  if (RegNo >= sizeof(CtrlRegDecoderTable) /
> sizeof(CtrlRegDecoderTable[0]))
> -    return MCDisassembler::Fail;
> -
> -  if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister)
> -    return MCDisassembler::Fail;
> -
> -  unsigned Register = CtrlRegDecoderTable[RegNo];
> -  Inst.addOperand(MCOperand::createReg(Register));
> -  return MCDisassembler::Success;
> -}
> -
> -static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned
> RegNo,
> -                                                 uint64_t /*Address*/,
> -                                                 void const *Decoder) {
> -  static const uint16_t CtrlReg64DecoderTable[] = {
> -      Hexagon::C1_0,       Hexagon::NoRegister, Hexagon::C3_2,
> -      Hexagon::NoRegister, Hexagon::NoRegister, Hexagon::NoRegister,
> -      Hexagon::C7_6,       Hexagon::NoRegister, Hexagon::C9_8,
> -      Hexagon::NoRegister, Hexagon::C11_10,     Hexagon::NoRegister,
> -      Hexagon::CS,         Hexagon::NoRegister, Hexagon::UPC,
> -      Hexagon::NoRegister};
> -
> -  if (RegNo >= sizeof(CtrlReg64DecoderTable) /
> sizeof(CtrlReg64DecoderTable[0]))
> -    return MCDisassembler::Fail;
> -
> -  if (CtrlReg64DecoderTable[RegNo] == Hexagon::NoRegister)
> -    return MCDisassembler::Fail;
> -
> -  unsigned Register = CtrlReg64DecoderTable[RegNo];
> -  Inst.addOperand(MCOperand::createReg(Register));
> -  return MCDisassembler::Success;
> -}
> -
> -static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> -                                               uint64_t /*Address*/,
> -                                               const void *Decoder) {
> -  unsigned Register = 0;
> -  switch (RegNo) {
> -  case 0:
> -    Register = Hexagon::M0;
> -    break;
> -  case 1:
> -    Register = Hexagon::M1;
> -    break;
> -  default:
> -    return MCDisassembler::Fail;
> -  }
> -  Inst.addOperand(MCOperand::createReg(Register));
> -  return MCDisassembler::Success;
> -}
> -
> -static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> -                                                  uint64_t /*Address*/,
> -                                                  const void *Decoder) {
> -  static const uint16_t DoubleRegDecoderTable[] = {
> -      Hexagon::D0,  Hexagon::D1,  Hexagon::D2,  Hexagon::D3,
> -      Hexagon::D4,  Hexagon::D5,  Hexagon::D6,  Hexagon::D7,
> -      Hexagon::D8,  Hexagon::D9,  Hexagon::D10, Hexagon::D11,
> -      Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
> -
> -  return (DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable,
> -                              sizeof(DoubleRegDecoderTable)));
> -}
> -
> -static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> -                                                uint64_t /*Address*/,
> -                                                void const *Decoder) {
> -  if (RegNo > 3)
> -    return MCDisassembler::Fail;
> -
> -  unsigned Register = PredRegDecoderTable[RegNo];
> -  Inst.addOperand(MCOperand::createReg(Register));
> -  return MCDisassembler::Success;
> -}
> +static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t
> Address,
> +                                    const void *Decoder);
>
>  #include "HexagonGenDisassemblerTables.inc"
>
> -static MCDisassembler *createHexagonDisassembler(Target const &T,
> -                                                 MCSubtargetInfo const
> &STI,
> +static MCDisassembler *createHexagonDisassembler(const Target &T,
> +                                                 const MCSubtargetInfo
> &STI,
>                                                   MCContext &Ctx) {
> -  return new HexagonDisassembler(STI, Ctx);
> +  return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo());
>  }
>
>  extern "C" void LLVMInitializeHexagonDisassembler() {
> @@ -251,7 +162,6 @@ DecodeStatus HexagonDisassembler::getIns
>    Size = 0;
>
>    *CurrentBundle = &MI;
> -  MI.clear();
>    MI.setOpcode(Hexagon::BUNDLE);
>    MI.addOperand(MCOperand::createImm(0));
>    while (Result == Success && Complete == false) {
> @@ -263,7 +173,21 @@ DecodeStatus HexagonDisassembler::getIns
>      Size += HEXAGON_INSTR_SIZE;
>      Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
>    }
> -  return Result;
> +  if(Result == MCDisassembler::Fail)
> +    return Result;
> +  HexagonMCChecker Checker (*MCII, STI, MI, MI,
> *getContext().getRegisterInfo());
> +  if(!Checker.check())
> +    return MCDisassembler::Fail;
> +  return MCDisassembler::Success;
> +}
> +
> +namespace {
> +HexagonDisassembler const &disassembler(void const *Decoder) {
> +  return *static_cast<HexagonDisassembler const *>(Decoder);
> +}
> +MCContext &contextFromDecoder(void const *Decoder) {
> +  return disassembler(Decoder).getContext();
> +}
>  }
>
>  DecodeStatus HexagonDisassembler::getSingleInstruction(
> @@ -272,8 +196,7 @@ DecodeStatus HexagonDisassembler::getSin
>    assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
>
>    uint32_t Instruction =
> -      llvm::support::endian::read<uint32_t, llvm::support::little,
> -                                  llvm::support::unaligned>(Bytes.data());
> +      (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0]
> << 0);
>
>    auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
>    if ((Instruction & HexagonII::INST_PARSE_MASK) ==
> @@ -377,8 +300,8 @@ DecodeStatus HexagonDisassembler::getSin
>      MILow->setOpcode(opLow);
>      MCInst *MIHigh = new (getContext()) MCInst;
>      MIHigh->setOpcode(opHigh);
> -    AddSubinstOperands(MILow, opLow, instLow);
> -    AddSubinstOperands(MIHigh, opHigh, instHigh);
> +    addSubinstOperands(MILow, opLow, instLow);
> +    addSubinstOperands(MIHigh, opHigh, instHigh);
>      // see ConvertToSubInst() in
>      // lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp
>
> @@ -395,16 +318,189 @@ DecodeStatus HexagonDisassembler::getSin
>      // Calling the auto-generated decoder function.
>      Result =
>          decodeInstruction(DecoderTable32, MI, Instruction, Address, this,
> STI);
> +
> +    // If a, "standard" insn isn't found check special cases.
> +    if (MCDisassembler::Success != Result ||
> +        MI.getOpcode() == Hexagon::A4_ext) {
> +      Result = decodeImmext(MI, Instruction, this);
> +      if (MCDisassembler::Success != Result) {
> +        Result = decodeSpecial(MI, Instruction);
> +      }
> +    } else {
> +      // If the instruction is a compound instruction, register values
> will
> +      // follow the duplex model, so the register values in the MCInst are
> +      // incorrect. If the instruction is a compound, loop through the
> +      // operands and change registers appropriately.
> +      if (llvm::HexagonMCInstrInfo::getType(*MCII, MI) ==
> +          HexagonII::TypeCOMPOUND) {
> +        for (MCInst::iterator i = MI.begin(), last = MI.end(); i < last;
> ++i) {
> +          if (i->isReg()) {
> +            unsigned reg = i->getReg() - Hexagon::R0;
> +            i->setReg(getRegFromSubinstEncoding(reg));
> +          }
> +        }
> +      }
> +    }
>    }
>
> +  if (HexagonMCInstrInfo::isNewValue(*MCII, MI)) {
> +    unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(*MCII, MI);
> +    MCOperand &MCO = MI.getOperand(OpIndex);
> +    assert(MCO.isReg() && "New value consumers must be registers");
> +    unsigned Register =
> +        getContext().getRegisterInfo()->getEncodingValue(MCO.getReg());
> +    if ((Register & 0x6) == 0)
> +      // HexagonPRM 10.11 Bit 1-2 == 0 is reserved
> +      return MCDisassembler::Fail;
> +    unsigned Lookback = (Register & 0x6) >> 1;
> +    unsigned Offset = 1;
> +    bool Vector = HexagonMCInstrInfo::isVector(*MCII, MI);
> +    auto Instructions =
> HexagonMCInstrInfo::bundleInstructions(**CurrentBundle);
> +    auto i = Instructions.end() - 1;
> +    for (auto n = Instructions.begin() - 1;; --i, ++Offset) {
> +      if (i == n)
> +        // Couldn't find producer
> +        return MCDisassembler::Fail;
> +      if (Vector && !HexagonMCInstrInfo::isVector(*MCII, *i->getInst()))
> +        // Skip scalars when calculating distances for vectors
> +        ++Lookback;
> +      if (HexagonMCInstrInfo::isImmext(*i->getInst()))
> +        ++Lookback;
> +      if (Offset == Lookback)
> +        break;
> +    }
> +    auto const &Inst = *i->getInst();
> +    bool SubregBit = (Register & 0x1) != 0;
> +    if (SubregBit && HexagonMCInstrInfo::hasNewValue2(*MCII, Inst)) {
> +      // If subreg bit is set we're selecting the second produced newvalue
> +      unsigned Producer =
> +          HexagonMCInstrInfo::getNewValueOperand2(*MCII, Inst).getReg();
> +      assert(Producer != Hexagon::NoRegister);
> +      MCO.setReg(Producer);
> +    } else if (HexagonMCInstrInfo::hasNewValue(*MCII, Inst)) {
> +      unsigned Producer =
> +          HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg();
> +      if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
> +        Producer = ((Producer - Hexagon::W0) << 1) + SubregBit +
> Hexagon::V0;
> +      else if (SubregBit)
> +        // Subreg bit should not be set for non-doublevector newvalue
> producers
> +        return MCDisassembler::Fail;
> +      assert(Producer != Hexagon::NoRegister);
> +      MCO.setReg(Producer);
> +    } else
> +      return MCDisassembler::Fail;
> +  }
> +
> +  adjustExtendedInstructions(MI, MCB);
> +  MCInst const *Extender =
> +    HexagonMCInstrInfo::extenderForIndex(MCB,
> +
>  HexagonMCInstrInfo::bundleSize(MCB));
> +  if(Extender != nullptr) {
> +    MCInst const & Inst = HexagonMCInstrInfo::isDuplex(*MCII, MI) ?
> +                          *MI.getOperand(1).getInst() : MI;
> +    if (!HexagonMCInstrInfo::isExtendable(*MCII, Inst) &&
> +        !HexagonMCInstrInfo::isExtended(*MCII, Inst))
> +      return MCDisassembler::Fail;
> +  }
>    return Result;
>  }
> +
> +void HexagonDisassembler::adjustExtendedInstructions(MCInst &MCI,
> +                                                     MCInst const &MCB)
> const {
> +  if (!HexagonMCInstrInfo::hasExtenderForIndex(
> +          MCB, HexagonMCInstrInfo::bundleSize(MCB))) {
> +    unsigned opcode;
> +    // This code is used by the disassembler to disambiguate between GP
> +    // relative and absolute addressing instructions since they both have
> +    // same encoding bits. However, an absolute addressing instruction
> must
> +    // follow an immediate extender. Disassembler alwaus select absolute
> +    // addressing instructions first and uses this code to change them
> into
> +    // GP relative instruction in the absence of the corresponding
> immediate
> +    // extender.
> +    switch (MCI.getOpcode()) {
> +    case Hexagon::S2_storerbabs:
> +      opcode = Hexagon::S2_storerbgp;
> +      break;
> +    case Hexagon::S2_storerhabs:
> +      opcode = Hexagon::S2_storerhgp;
> +      break;
> +    case Hexagon::S2_storerfabs:
> +      opcode = Hexagon::S2_storerfgp;
> +      break;
> +    case Hexagon::S2_storeriabs:
> +      opcode = Hexagon::S2_storerigp;
> +      break;
> +    case Hexagon::S2_storerbnewabs:
> +      opcode = Hexagon::S2_storerbnewgp;
> +      break;
> +    case Hexagon::S2_storerhnewabs:
> +      opcode = Hexagon::S2_storerhnewgp;
> +      break;
> +    case Hexagon::S2_storerinewabs:
> +      opcode = Hexagon::S2_storerinewgp;
> +      break;
> +    case Hexagon::S2_storerdabs:
> +      opcode = Hexagon::S2_storerdgp;
> +      break;
> +    case Hexagon::L4_loadrb_abs:
> +      opcode = Hexagon::L2_loadrbgp;
> +      break;
> +    case Hexagon::L4_loadrub_abs:
> +      opcode = Hexagon::L2_loadrubgp;
> +      break;
> +    case Hexagon::L4_loadrh_abs:
> +      opcode = Hexagon::L2_loadrhgp;
> +      break;
> +    case Hexagon::L4_loadruh_abs:
> +      opcode = Hexagon::L2_loadruhgp;
> +      break;
> +    case Hexagon::L4_loadri_abs:
> +      opcode = Hexagon::L2_loadrigp;
> +      break;
> +    case Hexagon::L4_loadrd_abs:
> +      opcode = Hexagon::L2_loadrdgp;
> +      break;
> +    default:
> +      opcode = MCI.getOpcode();
> +    }
> +    MCI.setOpcode(opcode);
> +  }
> +}
> +
> +namespace llvm {
> +extern const MCInstrDesc HexagonInsts[];
> +}
> +
> +static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
> +                                        const uint16_t Table[], size_t
> Size) {
> +  if (RegNo < Size) {
> +    Inst.addOperand(MCOperand::createReg(Table[RegNo]));
> +    return MCDisassembler::Success;
> +  } else
> +    return MCDisassembler::Fail;
> +}
> +
>  static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned
> RegNo,
>                                                     uint64_t Address,
>                                                     const void *Decoder) {
>    return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
>  }
>
> +static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> +                                               uint64_t Address,
> +                                               const void *Decoder) {
> +  static const uint16_t IntRegDecoderTable[] = {
> +      Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,  Hexagon::R4,
> +      Hexagon::R5,  Hexagon::R6,  Hexagon::R7,  Hexagon::R8,  Hexagon::R9,
> +      Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13,
> Hexagon::R14,
> +      Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18,
> Hexagon::R19,
> +      Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
> Hexagon::R24,
> +      Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28,
> Hexagon::R29,
> +      Hexagon::R30, Hexagon::R31};
> +
> +  return (DecodeRegisterClass(Inst, RegNo, IntRegDecoderTable,
> +                              sizeof(IntRegDecoderTable)));
> +}
>
>  static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
>                                                    uint64_t /*Address*/,
> @@ -422,6 +518,19 @@ static DecodeStatus DecodeVectorRegsRegi
>                                sizeof(VecRegDecoderTable)));
>  }
>
> +static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> +                                                  uint64_t /*Address*/,
> +                                                  const void *Decoder) {
> +  static const uint16_t DoubleRegDecoderTable[] = {
> +      Hexagon::D0,  Hexagon::D1,  Hexagon::D2,  Hexagon::D3,
> +      Hexagon::D4,  Hexagon::D5,  Hexagon::D6,  Hexagon::D7,
> +      Hexagon::D8,  Hexagon::D9,  Hexagon::D10, Hexagon::D11,
> +      Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
> +
> +  return (DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable,
> +                              sizeof(DoubleRegDecoderTable)));
> +}
> +
>  static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
>                                                    uint64_t /*Address*/,
>                                                    const void *Decoder) {
> @@ -435,6 +544,16 @@ static DecodeStatus DecodeVecDblRegsRegi
>                                sizeof(VecDblRegDecoderTable)));
>  }
>
> +static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> +                                                uint64_t /*Address*/,
> +                                                const void *Decoder) {
> +  static const uint16_t PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
> +                                                 Hexagon::P2,
> Hexagon::P3};
> +
> +  return (DecodeRegisterClass(Inst, RegNo, PredRegDecoderTable,
> +                              sizeof(PredRegDecoderTable)));
> +}
> +
>  static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
>                                                     uint64_t /*Address*/,
>                                                     const void *Decoder) {
> @@ -445,111 +564,535 @@ static DecodeStatus DecodeVecPredRegsReg
>                                sizeof(VecPredRegDecoderTable)));
>  }
>
> +static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> +                                               uint64_t /*Address*/,
> +                                               const void *Decoder) {
> +  static const uint16_t CtrlRegDecoderTable[] = {
> +    Hexagon::SA0, Hexagon::LC0, Hexagon::SA1, Hexagon::LC1,
> +    Hexagon::P3_0, Hexagon::C5, Hexagon::C6, Hexagon::C7,
> +    Hexagon::USR, Hexagon::PC, Hexagon::UGP, Hexagon::GP,
> +    Hexagon::CS0, Hexagon::CS1, Hexagon::UPCL, Hexagon::UPC
> +  };
> +
> +  if (RegNo >= sizeof(CtrlRegDecoderTable) /
> sizeof(CtrlRegDecoderTable[0]))
> +    return MCDisassembler::Fail;
> +
> +  if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister)
> +    return MCDisassembler::Fail;
> +
> +  unsigned Register = CtrlRegDecoderTable[RegNo];
> +  Inst.addOperand(MCOperand::createReg(Register));
> +  return MCDisassembler::Success;
> +}
> +
> +static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned
> RegNo,
> +                                                 uint64_t /*Address*/,
> +                                                 const void *Decoder) {
> +  static const uint16_t CtrlReg64DecoderTable[] = {
> +      Hexagon::C1_0,   Hexagon::NoRegister,
> +      Hexagon::C3_2,   Hexagon::NoRegister,
> +      Hexagon::C7_6,   Hexagon::NoRegister,
> +      Hexagon::C9_8,   Hexagon::NoRegister,
> +      Hexagon::C11_10, Hexagon::NoRegister,
> +      Hexagon::CS,     Hexagon::NoRegister,
> +      Hexagon::UPC,    Hexagon::NoRegister
> +  };
> +
> +  if (RegNo >= sizeof(CtrlReg64DecoderTable) /
> sizeof(CtrlReg64DecoderTable[0]))
> +    return MCDisassembler::Fail;
> +
> +  if (CtrlReg64DecoderTable[RegNo] == Hexagon::NoRegister)
> +    return MCDisassembler::Fail;
> +
> +  unsigned Register = CtrlReg64DecoderTable[RegNo];
> +  Inst.addOperand(MCOperand::createReg(Register));
> +  return MCDisassembler::Success;
> +}
> +
> +static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned
> RegNo,
> +                                               uint64_t /*Address*/,
> +                                               const void *Decoder) {
> +  unsigned Register = 0;
> +  switch (RegNo) {
> +  case 0:
> +    Register = Hexagon::M0;
> +    break;
> +  case 1:
> +    Register = Hexagon::M1;
> +    break;
> +  default:
> +    return MCDisassembler::Fail;
> +  }
> +  Inst.addOperand(MCOperand::createReg(Register));
> +  return MCDisassembler::Success;
> +}
> +
> +namespace {
> +uint32_t fullValue(MCInstrInfo const &MCII,
> +                  MCInst &MCB,
> +                  MCInst &MI,
> +                  int64_t Value) {
> +  MCInst const *Extender = HexagonMCInstrInfo::extenderForIndex(
> +    MCB, HexagonMCInstrInfo::bundleSize(MCB));
> +  if(!Extender || MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII,
> MI))
> +    return Value;
> +  unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
> +  uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f;
> +  int64_t Bits;
> +  bool Success =
> Extender->getOperand(0).getExpr()->evaluateAsAbsolute(Bits);
> +  assert(Success);(void)Success;
> +  uint32_t Upper26 = static_cast<uint32_t>(Bits);
> +  uint32_t Operand = Upper26 | Lower6;
> +  return Operand;
> +}
> +template <size_t T>
> +void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) {
> +  HexagonDisassembler const &Disassembler = disassembler(Decoder);
> +  int64_t FullValue = fullValue(*Disassembler.MCII,
> +                                **Disassembler.CurrentBundle,
> +                                MI, SignExtend64<T>(tmp));
> +  int64_t Extended = SignExtend64<32>(FullValue);
> +  HexagonMCInstrInfo::addConstant(MI, Extended,
> +                                  Disassembler.getContext());
> +}
> +}
> +
> +static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
> +                                       uint64_t /*Address*/,
> +                                       const void *Decoder) {
> +  HexagonDisassembler const &Disassembler = disassembler(Decoder);
> +  int64_t FullValue = fullValue(*Disassembler.MCII,
> +                                **Disassembler.CurrentBundle,
> +                                MI, tmp);
> +  assert(FullValue >= 0 && "Negative in unsigned decoder");
> +  HexagonMCInstrInfo::addConstant(MI, FullValue,
> Disassembler.getContext());
> +  return MCDisassembler::Success;
> +}
> +
>  static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp,
>                                    uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<16>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<16>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp,
>                                    uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<12>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<12>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp,
>                                      uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<11>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<11>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp,
>                                      uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<12>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  HexagonMCInstrInfo::addConstant(MI, SignExtend64<12>(tmp),
> contextFromDecoder(Decoder));
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp,
>                                      uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<13>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<13>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp,
>                                      uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<14>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<14>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp,
>                                    uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<10>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<10>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t
> /*Address*/,
>                                   const void *Decoder) {
> -  uint64_t imm = SignExtend64<8>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<8>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp,
>                                     uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<6>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<6>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp,
>                                     uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<4>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<4>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp,
>                                     uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<5>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<5>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp,
>                                     uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<6>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<6>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp,
>                                     uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<7>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<7>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp,
>                                     uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<10>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<10>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
>  static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp,
>                                     uint64_t /*Address*/, const void
> *Decoder) {
> -  uint64_t imm = SignExtend64<9>(tmp);
> -  MI.addOperand(MCOperand::createImm(imm));
> +  signedDecoder<19>(MI, tmp, Decoder);
>    return MCDisassembler::Success;
>  }
>
> +// custom decoder for various jump/call immediates
> +static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t
> Address,
> +                                    const void *Decoder) {
> +  HexagonDisassembler const &Disassembler = disassembler(Decoder);
> +  unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII,
> MI);
> +  // r13_2 is not extendable, so if there are no extent bits, it's r13_2
> +  if (Bits == 0)
> +    Bits = 15;
> +  uint32_t FullValue = fullValue(*Disassembler.MCII,
> +                                **Disassembler.CurrentBundle,
> +                                MI, SignExtend64(tmp, Bits));
> +  int64_t Extended = SignExtend64<32>(FullValue) + Address;
> +  if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address, true,
> +                                              0, 4))
> +    HexagonMCInstrInfo::addConstant(MI, Extended,
> Disassembler.getContext());
> +  return MCDisassembler::Success;
> +}
> +
> +// Addressing mode dependent load store opcode map.
> +//   - If an insn is preceded by an extender the address is absolute.
> +//      - memw(##symbol) = r0
> +//   - If an insn is not preceded by an extender the address is GP
> relative.
> +//      - memw(gp + #symbol) = r0
> +// Please note that the instructions must be ordered in the descending
> order
> +// of their opcode.
> +// HexagonII::INST_ICLASS_ST
> +static unsigned int StoreConditionalOpcodeData[][2] = {
> +    {S4_pstorerdfnew_abs, 0xafc02084},
> +    {S4_pstorerdtnew_abs, 0xafc02080},
> +    {S4_pstorerdf_abs, 0xafc00084},
> +    {S4_pstorerdt_abs, 0xafc00080},
> +    {S4_pstorerinewfnew_abs, 0xafa03084},
> +    {S4_pstorerinewtnew_abs, 0xafa03080},
> +    {S4_pstorerhnewfnew_abs, 0xafa02884},
> +    {S4_pstorerhnewtnew_abs, 0xafa02880},
> +    {S4_pstorerbnewfnew_abs, 0xafa02084},
> +    {S4_pstorerbnewtnew_abs, 0xafa02080},
> +    {S4_pstorerinewf_abs, 0xafa01084},
> +    {S4_pstorerinewt_abs, 0xafa01080},
> +    {S4_pstorerhnewf_abs, 0xafa00884},
> +    {S4_pstorerhnewt_abs, 0xafa00880},
> +    {S4_pstorerbnewf_abs, 0xafa00084},
> +    {S4_pstorerbnewt_abs, 0xafa00080},
> +    {S4_pstorerifnew_abs, 0xaf802084},
> +    {S4_pstoreritnew_abs, 0xaf802080},
> +    {S4_pstorerif_abs, 0xaf800084},
> +    {S4_pstorerit_abs, 0xaf800080},
> +    {S4_pstorerhfnew_abs, 0xaf402084},
> +    {S4_pstorerhtnew_abs, 0xaf402080},
> +    {S4_pstorerhf_abs, 0xaf400084},
> +    {S4_pstorerht_abs, 0xaf400080},
> +    {S4_pstorerbfnew_abs, 0xaf002084},
> +    {S4_pstorerbtnew_abs, 0xaf002080},
> +    {S4_pstorerbf_abs, 0xaf000084},
> +    {S4_pstorerbt_abs, 0xaf000080}};
> +// HexagonII::INST_ICLASS_LD
> +
> +// HexagonII::INST_ICLASS_LD_ST_2
> +static unsigned int LoadStoreOpcodeData[][2] = {{L4_loadrd_abs,
> 0x49c00000},
> +                                                {L4_loadri_abs,
> 0x49800000},
> +                                                {L4_loadruh_abs,
> 0x49600000},
> +                                                {L4_loadrh_abs,
> 0x49400000},
> +                                                {L4_loadrub_abs,
> 0x49200000},
> +                                                {L4_loadrb_abs,
> 0x49000000},
> +                                                {S2_storerdabs,
> 0x48c00000},
> +                                                {S2_storerinewabs,
> 0x48a01000},
> +                                                {S2_storerhnewabs,
> 0x48a00800},
> +                                                {S2_storerbnewabs,
> 0x48a00000},
> +                                                {S2_storeriabs,
> 0x48800000},
> +                                                {S2_storerfabs,
> 0x48600000},
> +                                                {S2_storerhabs,
> 0x48400000},
> +                                                {S2_storerbabs,
> 0x48000000}};
> +static int NumCondS =
> +    sizeof(StoreConditionalOpcodeData) /
> sizeof(StoreConditionalOpcodeData[0]);
> +static int NumLS = sizeof(LoadStoreOpcodeData) /
> sizeof(LoadStoreOpcodeData[0]);
> +
> +static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
> +
> +  unsigned MachineOpcode = 0;
> +  unsigned LLVMOpcode = 0;
> +  int i;
> +
> +  if ((insn & HexagonII::INST_ICLASS_MASK) == HexagonII::INST_ICLASS_ST) {
> +    for (i = 0; i < NumCondS; ++i) {
> +      if ((insn & StoreConditionalOpcodeData[i][1]) ==
> +          StoreConditionalOpcodeData[i][1]) {
> +        MachineOpcode = StoreConditionalOpcodeData[i][1];
> +        LLVMOpcode = StoreConditionalOpcodeData[i][0];
> +        break;
> +      }
> +    }
> +  }
> +  if ((insn & HexagonII::INST_ICLASS_MASK) ==
> HexagonII::INST_ICLASS_LD_ST_2) {
> +    for (i = 0; i < NumLS; ++i) {
> +      if ((insn & LoadStoreOpcodeData[i][1]) ==
> LoadStoreOpcodeData[i][1]) {
> +        MachineOpcode = LoadStoreOpcodeData[i][1];
> +        LLVMOpcode = LoadStoreOpcodeData[i][0];
> +        break;
> +      }
> +    }
> +  }
> +
> +  if (MachineOpcode) {
> +    unsigned Value = 0;
> +    unsigned shift = 0;
> +    MI.setOpcode(LLVMOpcode);
> +    // Remove the parse bits from the insn.
> +    insn &= ~HexagonII::INST_PARSE_MASK;
> +
> +    switch (LLVMOpcode) {
> +    default:
> +      return MCDisassembler::Fail;
> +      break;
> +
> +    case Hexagon::S4_pstorerdf_abs:
> +    case Hexagon::S4_pstorerdt_abs:
> +    case Hexagon::S4_pstorerdfnew_abs:
> +    case Hexagon::S4_pstorerdtnew_abs: {
> +      // op: Pv
> +      Value = insn & UINT64_C(3);
> +      DecodePredRegsRegisterClass(MI, Value, 0, 0);
> +      // op: u6
> +      Value = (insn >> 12) & UINT64_C(48);
> +      Value |= (insn >> 3) & UINT64_C(15);
> +      MI.addOperand(MCOperand::createImm(Value));
> +      // op: Rtt
> +      Value = (insn >> 8) & UINT64_C(31);
> +      DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
> +      break;
> +    }
> +
> +    case Hexagon::S4_pstorerbnewf_abs:
> +    case Hexagon::S4_pstorerbnewt_abs:
> +    case Hexagon::S4_pstorerbnewfnew_abs:
> +    case Hexagon::S4_pstorerbnewtnew_abs:
> +    case Hexagon::S4_pstorerhnewf_abs:
> +    case Hexagon::S4_pstorerhnewt_abs:
> +    case Hexagon::S4_pstorerhnewfnew_abs:
> +    case Hexagon::S4_pstorerhnewtnew_abs:
> +    case Hexagon::S4_pstorerinewf_abs:
> +    case Hexagon::S4_pstorerinewt_abs:
> +    case Hexagon::S4_pstorerinewfnew_abs:
> +    case Hexagon::S4_pstorerinewtnew_abs: {
> +      // op: Pv
> +      Value = insn & UINT64_C(3);
> +      DecodePredRegsRegisterClass(MI, Value, 0, 0);
> +      // op: u6
> +      Value = (insn >> 12) & UINT64_C(48);
> +      Value |= (insn >> 3) & UINT64_C(15);
> +      MI.addOperand(MCOperand::createImm(Value));
> +      // op: Nt
> +      Value = (insn >> 8) & UINT64_C(7);
> +      DecodeIntRegsRegisterClass(MI, Value, 0, 0);
> +      break;
> +    }
> +
> +    case Hexagon::S4_pstorerbf_abs:
> +    case Hexagon::S4_pstorerbt_abs:
> +    case Hexagon::S4_pstorerbfnew_abs:
> +    case Hexagon::S4_pstorerbtnew_abs:
> +    case Hexagon::S4_pstorerhf_abs:
> +    case Hexagon::S4_pstorerht_abs:
> +    case Hexagon::S4_pstorerhfnew_abs:
> +    case Hexagon::S4_pstorerhtnew_abs:
> +    case Hexagon::S4_pstorerif_abs:
> +    case Hexagon::S4_pstorerit_abs:
> +    case Hexagon::S4_pstorerifnew_abs:
> +    case Hexagon::S4_pstoreritnew_abs: {
> +      // op: Pv
> +      Value = insn & UINT64_C(3);
> +      DecodePredRegsRegisterClass(MI, Value, 0, 0);
> +      // op: u6
> +      Value = (insn >> 12) & UINT64_C(48);
> +      Value |= (insn >> 3) & UINT64_C(15);
> +      MI.addOperand(MCOperand::createImm(Value));
> +      // op: Rt
> +      Value = (insn >> 8) & UINT64_C(31);
> +      DecodeIntRegsRegisterClass(MI, Value, 0, 0);
> +      break;
> +    }
> +
> +    case Hexagon::L4_ploadrdf_abs:
> +    case Hexagon::L4_ploadrdt_abs:
> +    case Hexagon::L4_ploadrdfnew_abs:
> +    case Hexagon::L4_ploadrdtnew_abs: {
> +      // op: Rdd
> +      Value = insn & UINT64_C(31);
> +      DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
> +      // op: Pt
> +      Value = ((insn >> 9) & UINT64_C(3));
> +      DecodePredRegsRegisterClass(MI, Value, 0, 0);
> +      // op: u6
> +      Value = ((insn >> 15) & UINT64_C(62));
> +      Value |= ((insn >> 8) & UINT64_C(1));
> +      MI.addOperand(MCOperand::createImm(Value));
> +      break;
> +    }
> +
> +    case Hexagon::L4_ploadrbf_abs:
> +    case Hexagon::L4_ploadrbt_abs:
> +    case Hexagon::L4_ploadrbfnew_abs:
> +    case Hexagon::L4_ploadrbtnew_abs:
> +    case Hexagon::L4_ploadrhf_abs:
> +    case Hexagon::L4_ploadrht_abs:
> +    case Hexagon::L4_ploadrhfnew_abs:
> +    case Hexagon::L4_ploadrhtnew_abs:
> +    case Hexagon::L4_ploadrubf_abs:
> +    case Hexagon::L4_ploadrubt_abs:
> +    case Hexagon::L4_ploadrubfnew_abs:
> +    case Hexagon::L4_ploadrubtnew_abs:
> +    case Hexagon::L4_ploadruhf_abs:
> +    case Hexagon::L4_ploadruht_abs:
> +    case Hexagon::L4_ploadruhfnew_abs:
> +    case Hexagon::L4_ploadruhtnew_abs:
> +    case Hexagon::L4_ploadrif_abs:
> +    case Hexagon::L4_ploadrit_abs:
> +    case Hexagon::L4_ploadrifnew_abs:
> +    case Hexagon::L4_ploadritnew_abs:
> +      // op: Rd
> +      Value = insn & UINT64_C(31);
> +      DecodeIntRegsRegisterClass(MI, Value, 0, 0);
> +      // op: Pt
> +      Value = (insn >> 9) & UINT64_C(3);
> +      DecodePredRegsRegisterClass(MI, Value, 0, 0);
> +      // op: u6
> +      Value = (insn >> 15) & UINT64_C(62);
> +      Value |= (insn >> 8) & UINT64_C(1);
> +      MI.addOperand(MCOperand::createImm(Value));
> +      break;
> +
> +    // op: g16_2
> +    case (Hexagon::L4_loadri_abs):
> +      ++shift;
> +    // op: g16_1
> +    case Hexagon::L4_loadrh_abs:
> +    case Hexagon::L4_loadruh_abs:
> +      ++shift;
> +    // op: g16_0
> +    case Hexagon::L4_loadrb_abs:
> +    case Hexagon::L4_loadrub_abs: {
> +      // op: Rd
> +      Value |= insn & UINT64_C(31);
> +      DecodeIntRegsRegisterClass(MI, Value, 0, 0);
> +      Value = (insn >> 11) & UINT64_C(49152);
> +      Value |= (insn >> 7) & UINT64_C(15872);
> +      Value |= (insn >> 5) & UINT64_C(511);
> +      MI.addOperand(MCOperand::createImm(Value << shift));
> +      break;
> +    }
> +
> +    case Hexagon::L4_loadrd_abs: {
> +      Value = insn & UINT64_C(31);
> +      DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
> +      Value = (insn >> 11) & UINT64_C(49152);
> +      Value |= (insn >> 7) & UINT64_C(15872);
> +      Value |= (insn >> 5) & UINT64_C(511);
> +      MI.addOperand(MCOperand::createImm(Value << 3));
> +      break;
> +    }
> +
> +    case Hexagon::S2_storerdabs: {
> +      // op: g16_3
> +      Value = (insn >> 11) & UINT64_C(49152);
> +      Value |= (insn >> 7) & UINT64_C(15872);
> +      Value |= (insn >> 5) & UINT64_C(256);
> +      Value |= insn & UINT64_C(255);
> +      MI.addOperand(MCOperand::createImm(Value << 3));
> +      // op: Rtt
> +      Value = (insn >> 8) & UINT64_C(31);
> +      DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
> +      break;
> +    }
> +
> +    // op: g16_2
> +    case Hexagon::S2_storerinewabs:
> +      ++shift;
> +    // op: g16_1
> +    case Hexagon::S2_storerhnewabs:
> +      ++shift;
> +    // op: g16_0
> +    case Hexagon::S2_storerbnewabs: {
> +      Value = (insn >> 11) & UINT64_C(49152);
> +      Value |= (insn >> 7) & UINT64_C(15872);
> +      Value |= (insn >> 5) & UINT64_C(256);
> +      Value |= insn & UINT64_C(255);
> +      MI.addOperand(MCOperand::createImm(Value << shift));
> +      // op: Nt
> +      Value = (insn >> 8) & UINT64_C(7);
> +      DecodeIntRegsRegisterClass(MI, Value, 0, 0);
> +      break;
> +    }
> +
> +    // op: g16_2
> +    case Hexagon::S2_storeriabs:
> +      ++shift;
> +    // op: g16_1
> +    case Hexagon::S2_storerhabs:
> +    case Hexagon::S2_storerfabs:
> +      ++shift;
> +    // op: g16_0
> +    case Hexagon::S2_storerbabs: {
> +      Value = (insn >> 11) & UINT64_C(49152);
> +      Value |= (insn >> 7) & UINT64_C(15872);
> +      Value |= (insn >> 5) & UINT64_C(256);
> +      Value |= insn & UINT64_C(255);
> +      MI.addOperand(MCOperand::createImm(Value << shift));
> +      // op: Rt
> +      Value = (insn >> 8) & UINT64_C(31);
> +      DecodeIntRegsRegisterClass(MI, Value, 0, 0);
> +      break;
> +    }
> +    }
> +    return MCDisassembler::Success;
> +  }
> +  return MCDisassembler::Fail;
> +}
> +
> +static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn,
> +                                 void const *Decoder) {
> +
> +  // Instruction Class for a constant a extender: bits 31:28 = 0x0000
> +  if ((~insn & 0xf0000000) == 0xf0000000) {
> +    unsigned Value;
> +    // 27:16 High 12 bits of 26-bit extender.
> +    Value = (insn & 0x0fff0000) << 4;
> +    // 13:0 Low 14 bits of 26-bit extender.
> +    Value |= ((insn & 0x3fff) << 6);
> +    MI.setOpcode(Hexagon::A4_ext);
> +    HexagonMCInstrInfo::addConstant(MI, Value,
> contextFromDecoder(Decoder));
> +    return MCDisassembler::Success;
> +  }
> +  return MCDisassembler::Fail;
> +}
> +
>  // These values are from HexagonGenMCCodeEmitter.inc and HexagonIsetDx.td
>  enum subInstBinaryValues {
>    V4_SA1_addi_BITS = 0x0000,
> @@ -807,6 +1350,8 @@ static unsigned getRegFromSubinstEncodin
>      return Hexagon::R0 + encoded_reg;
>    else if (encoded_reg < 16)
>      return Hexagon::R0 + encoded_reg + 8;
> +
> +  // patently false value
>    return Hexagon::NoRegister;
>  }
>
> @@ -815,10 +1360,13 @@ static unsigned getDRegFromSubinstEncodi
>      return Hexagon::D0 + encoded_dreg;
>    else if (encoded_dreg < 8)
>      return Hexagon::D0 + encoded_dreg + 4;
> +
> +  // patently false value
>    return Hexagon::NoRegister;
>  }
>
> -static void AddSubinstOperands(MCInst *MI, unsigned opcode, unsigned
> inst) {
> +void HexagonDisassembler::addSubinstOperands(MCInst *MI, unsigned opcode,
> +                                             unsigned inst) const {
>    int64_t operand;
>    MCOperand Op;
>    switch (opcode) {
> @@ -838,8 +1386,7 @@ static void AddSubinstOperands(MCInst *M
>    case Hexagon::V4_SS2_allocframe:
>      // u 8-4{5_3}
>      operand = ((inst & 0x1f0) >> 4) << 3;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SL1_loadri_io:
>      // Rd 3-0, Rs 7-4, u 11-8{4_2}
> @@ -850,8 +1397,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = (inst & 0xf00) >> 6;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SL1_loadrub_io:
>      // Rd 3-0, Rs 7-4, u 11-8
> @@ -862,8 +1408,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = (inst & 0xf00) >> 8;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SL2_loadrb_io:
>      // Rd 3-0, Rs 7-4, u 10-8
> @@ -874,8 +1419,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = (inst & 0x700) >> 8;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SL2_loadrh_io:
>    case Hexagon::V4_SL2_loadruh_io:
> @@ -887,8 +1431,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = ((inst & 0x700) >> 8) << 1;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SL2_loadrd_sp:
>      // Rdd 2-0, u 7-3{5_3}
> @@ -896,8 +1439,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = ((inst & 0x0f8) >> 3) << 3;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SL2_loadri_sp:
>      // Rd 3-0, u 8-4{5_2}
> @@ -905,8 +1447,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = ((inst & 0x1f0) >> 4) << 2;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SA1_addi:
>      // Rx 3-0 (x2), s7 10-4
> @@ -915,8 +1456,7 @@ static void AddSubinstOperands(MCInst *M
>      MI->addOperand(Op);
>      MI->addOperand(Op);
>      operand = SignExtend64<7>((inst & 0x7f0) >> 4);
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SA1_addrx:
>      // Rx 3-0 (x2), Rs 7-4
> @@ -949,8 +1489,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = ((inst & 0x3f0) >> 4) << 2;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SA1_seti:
>      // Rd 3-0, u 9-4
> @@ -958,8 +1497,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = (inst & 0x3f0) >> 4;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SA1_clrf:
>    case Hexagon::V4_SA1_clrfnew:
> @@ -977,8 +1515,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = inst & 0x3;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SA1_combine0i:
>    case Hexagon::V4_SA1_combine1i:
> @@ -989,8 +1526,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = (inst & 0x060) >> 5;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SA1_combinerz:
>    case Hexagon::V4_SA1_combinezr:
> @@ -1008,8 +1544,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = (inst & 0xf00) >> 8;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      operand = getRegFromSubinstEncoding(inst & 0xf);
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
> @@ -1020,8 +1555,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = ((inst & 0xf00) >> 8) << 2;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      operand = getRegFromSubinstEncoding(inst & 0xf);
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
> @@ -1033,8 +1567,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = inst & 0xf;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SS2_storewi0:
>    case Hexagon::V4_SS2_storewi1:
> @@ -1043,14 +1576,12 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = (inst & 0xf) << 2;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      break;
>    case Hexagon::V4_SS2_stored_sp:
>      // s 8-3{6_3}, Rtt 2-0
>      operand = SignExtend64<9>(((inst & 0x1f8) >> 3) << 3);
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      operand = getDRegFromSubinstEncoding(inst & 0x7);
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
> @@ -1061,8 +1592,7 @@ static void AddSubinstOperands(MCInst *M
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>      operand = ((inst & 0x700) >> 8) << 1;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      operand = getRegFromSubinstEncoding(inst & 0xf);
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
> @@ -1070,8 +1600,7 @@ static void AddSubinstOperands(MCInst *M
>    case Hexagon::V4_SS2_storew_sp:
>      // u 8-4{5_2}, Rd 3-0
>      operand = ((inst & 0x1f0) >> 4) << 2;
> -    Op = MCOperand::createImm(operand);
> -    MI->addOperand(Op);
> +    HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
>      operand = getRegFromSubinstEncoding(inst & 0xf);
>      Op = MCOperand::createReg(operand);
>      MI->addOperand(Op);
>
> Modified: llvm/trunk/lib/Target/Hexagon/Disassembler/LLVMBuild.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/Disassembler/LLVMBuild.txt?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/Disassembler/LLVMBuild.txt (original)
> +++ llvm/trunk/lib/Target/Hexagon/Disassembler/LLVMBuild.txt Sun Nov  8
> 22:07:48 2015
> @@ -19,5 +19,5 @@
>  type = Library
>  name = HexagonDisassembler
>  parent = Hexagon
> -required_libraries = HexagonDesc HexagonInfo MCDisassembler Support
> +required_libraries = HexagonDesc HexagonInfo MC MCDisassembler Support
>  add_to_library_groups = Hexagon
>
> Modified: llvm/trunk/lib/Target/Hexagon/Hexagon.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/Hexagon.td?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/Hexagon.td (original)
> +++ llvm/trunk/lib/Target/Hexagon/Hexagon.td Sun Nov  8 22:07:48 2015
> @@ -30,6 +30,9 @@ def ArchV60: SubtargetFeature<"v60", "He
>  // Hexagon ISA Extensions
>  def ExtensionHVX: SubtargetFeature<"hvx", "UseHVXOps",
>                                     "true", "Hexagon HVX instructions">;
> +def ExtensionHVXDbl: SubtargetFeature<"hvxDbl", "UseHVXDblOps",
> +                                   "true", "Hexagon HVX Double
> instructions">;
> +
>
>  //===----------------------------------------------------------------------===//
>  // Hexagon Instruction Predicate Definitions.
>
>  //===----------------------------------------------------------------------===//
> @@ -212,7 +215,13 @@ def : Proc<"hexagonv5",  HexagonModelV4,
>  // Declare the target which we are implementing
>
>  //===----------------------------------------------------------------------===//
>
> +def HexagonAsmParserVariant : AsmParserVariant {
> +  int Variant = 0;
> +  string TokenizingCharacters = "#()=:.<>!+*";
> +}
> +
>  def Hexagon : Target {
>    // Pull in Instruction Info:
>    let InstructionSet = HexagonInstrInfo;
> +  let AssemblyParserVariants = [HexagonAsmParserVariant];
>  }
>
> Modified: llvm/trunk/lib/Target/Hexagon/HexagonMCInstLower.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonMCInstLower.cpp?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/HexagonMCInstLower.cpp (original)
> +++ llvm/trunk/lib/Target/Hexagon/HexagonMCInstLower.cpp Sun Nov  8
> 22:07:48 2015
> @@ -73,11 +73,14 @@ void llvm::HexagonLowerToMC(MachineInstr
>        APFloat Val = MO.getFPImm()->getValueAPF();
>        // FP immediates are used only when setting GPRs, so they may be
> dealt
>        // with like regular immediates from this point on.
> -      MCO = MCOperand::createImm(*Val.bitcastToAPInt().getRawData());
> +      MCO = MCOperand::createExpr(
> +        MCConstantExpr::create(*Val.bitcastToAPInt().getRawData(),
> +                               AP.OutContext));
>        break;
>      }
>      case MachineOperand::MO_Immediate:
> -      MCO = MCOperand::createImm(MO.getImm());
> +      MCO = MCOperand::createExpr(
> +        MCConstantExpr::create(MO.getImm(), AP.OutContext));
>        break;
>      case MachineOperand::MO_MachineBasicBlock:
>        MCO = MCOperand::createExpr
>
> Modified: llvm/trunk/lib/Target/Hexagon/HexagonOperands.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonOperands.td?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/HexagonOperands.td (original)
> +++ llvm/trunk/lib/Target/Hexagon/HexagonOperands.td Sun Nov  8 22:07:48
> 2015
> @@ -1,4 +1,4 @@
> -//===- HexagonOperands.td - Hexagon immediate processing -*- tablegen
> -*-===//
> +//===- HexagonImmediates.td - Hexagon immediate processing -*- tablegen
> -*-===//
>  //
>  //                     The LLVM Compiler Infrastructure
>  //
> @@ -7,57 +7,100 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> +def s32ImmOperand : AsmOperandClass { let Name = "s32Imm"; }
> +def s8ImmOperand : AsmOperandClass { let Name = "s8Imm"; }
> +def s8Imm64Operand : AsmOperandClass { let Name = "s8Imm64"; }
> +def s6ImmOperand : AsmOperandClass { let Name = "s6Imm"; }
> +def s4ImmOperand : AsmOperandClass { let Name = "s4Imm"; }
>  def s4_0ImmOperand : AsmOperandClass { let Name = "s4_0Imm"; }
>  def s4_1ImmOperand : AsmOperandClass { let Name = "s4_1Imm"; }
>  def s4_2ImmOperand : AsmOperandClass { let Name = "s4_2Imm"; }
>  def s4_3ImmOperand : AsmOperandClass { let Name = "s4_3Imm"; }
>  def s4_6ImmOperand : AsmOperandClass { let Name = "s4_6Imm"; }
>  def s3_6ImmOperand : AsmOperandClass { let Name = "s3_6Imm"; }
> -
> +def u64ImmOperand : AsmOperandClass { let Name = "u64Imm"; }
> +def u32ImmOperand : AsmOperandClass { let Name = "u32Imm"; }
> +def u26_6ImmOperand : AsmOperandClass { let Name = "u26_6Imm"; }
> +def u16ImmOperand : AsmOperandClass { let Name = "u16Imm"; }
> +def u16_0ImmOperand : AsmOperandClass { let Name = "u16_0Imm"; }
> +def u16_1ImmOperand : AsmOperandClass { let Name = "u16_1Imm"; }
> +def u16_2ImmOperand : AsmOperandClass { let Name = "u16_2Imm"; }
> +def u16_3ImmOperand : AsmOperandClass { let Name = "u16_3Imm"; }
> +def u11_3ImmOperand : AsmOperandClass { let Name = "u11_3Imm"; }
> +def u10ImmOperand : AsmOperandClass { let Name = "u10Imm"; }
> +def u9ImmOperand : AsmOperandClass { let Name = "u9Imm"; }
> +def u8ImmOperand : AsmOperandClass { let Name = "u8Imm"; }
> +def u7ImmOperand : AsmOperandClass { let Name = "u7Imm"; }
> +def u6ImmOperand : AsmOperandClass { let Name = "u6Imm"; }
> +def u6_0ImmOperand : AsmOperandClass { let Name = "u6_0Imm"; }
> +def u6_1ImmOperand : AsmOperandClass { let Name = "u6_1Imm"; }
> +def u6_2ImmOperand : AsmOperandClass { let Name = "u6_2Imm"; }
> +def u6_3ImmOperand : AsmOperandClass { let Name = "u6_3Imm"; }
> +def u5ImmOperand : AsmOperandClass { let Name = "u5Imm"; }
> +def u4ImmOperand : AsmOperandClass { let Name = "u4Imm"; }
> +def u3ImmOperand : AsmOperandClass { let Name = "u3Imm"; }
> +def u2ImmOperand : AsmOperandClass { let Name = "u2Imm"; }
> +def u1ImmOperand : AsmOperandClass { let Name = "u1Imm"; }
> +def n8ImmOperand : AsmOperandClass { let Name = "n8Imm"; }
>  // Immediate operands.
>
> -let PrintMethod = "printImmOperand" in {
> -  def s32Imm : Operand<i32>;
> -  def s8Imm : Operand<i32>;
> -  def s8Imm64 : Operand<i64>;
> -  def s6Imm : Operand<i32>;
> +let OperandType = "OPERAND_IMMEDIATE",
> +    DecoderMethod = "unsignedImmDecoder" in {
> +  def s32Imm : Operand<i32> { let ParserMatchClass = s32ImmOperand;
> +                              let DecoderMethod = "s32ImmDecoder"; }
> +  def s8Imm : Operand<i32> { let ParserMatchClass = s8ImmOperand;
> +                             let DecoderMethod = "s8ImmDecoder"; }
> +  def s8Imm64 : Operand<i64>  { let ParserMatchClass = s8Imm64Operand;
> +                                let DecoderMethod = "s8ImmDecoder"; }
> +  def s6Imm : Operand<i32> { let ParserMatchClass = s6ImmOperand;
> +                             let DecoderMethod = "s6_0ImmDecoder"; }
>    def s6_3Imm : Operand<i32>;
> -  def s4Imm : Operand<i32>;
> -  def s4_0Imm : Operand<i32> { let DecoderMethod = "s4_0ImmDecoder"; }
> -  def s4_1Imm : Operand<i32> { let DecoderMethod = "s4_1ImmDecoder"; }
> -  def s4_2Imm : Operand<i32> { let DecoderMethod = "s4_2ImmDecoder"; }
> -  def s4_3Imm : Operand<i32> { let DecoderMethod = "s4_3ImmDecoder"; }
> -  def u64Imm : Operand<i64>;
> -  def u32Imm : Operand<i32>;
> -  def u26_6Imm : Operand<i32>;
> -  def u16Imm : Operand<i32>;
> -  def u16_0Imm : Operand<i32>;
> -  def u16_1Imm : Operand<i32>;
> -  def u16_2Imm : Operand<i32>;
> -  def u16_3Imm : Operand<i32>;
> -  def u11_3Imm : Operand<i32>;
> -  def u10Imm : Operand<i32>;
> -  def u9Imm : Operand<i32>;
> -  def u8Imm : Operand<i32>;
> -  def u7Imm : Operand<i32>;
> -  def u6Imm : Operand<i32>;
> -  def u6_0Imm : Operand<i32>;
> -  def u6_1Imm : Operand<i32>;
> -  def u6_2Imm : Operand<i32>;
> -  def u6_3Imm : Operand<i32>;
> -  def u5Imm : Operand<i32>;
> +  def s4Imm : Operand<i32> { let ParserMatchClass = s4ImmOperand;
> +                             let DecoderMethod = "s4_0ImmDecoder"; }
> +  def s4_0Imm : Operand<i32> { let ParserMatchClass = s4_0ImmOperand;
> +                               let DecoderMethod = "s4_0ImmDecoder"; }
> +  def s4_1Imm : Operand<i32> { let ParserMatchClass = s4_1ImmOperand;
> +                               let DecoderMethod = "s4_1ImmDecoder"; }
> +  def s4_2Imm : Operand<i32> { let ParserMatchClass = s4_2ImmOperand;
> +                               let DecoderMethod = "s4_2ImmDecoder"; }
> +  def s4_3Imm : Operand<i32> { let ParserMatchClass = s4_3ImmOperand;
> +                               let DecoderMethod = "s4_3ImmDecoder"; }
> +  def u64Imm : Operand<i64> { let ParserMatchClass = u64ImmOperand; }
> +  def u32Imm : Operand<i32> { let ParserMatchClass = u32ImmOperand; }
> +  def u26_6Imm : Operand<i32> { let ParserMatchClass = u26_6ImmOperand; }
> +  def u16Imm : Operand<i32> { let ParserMatchClass = u16ImmOperand; }
> +  def u16_0Imm : Operand<i32> { let ParserMatchClass = u16_0ImmOperand; }
> +  def u16_1Imm : Operand<i32> { let ParserMatchClass = u16_1ImmOperand; }
> +  def u16_2Imm : Operand<i32> { let ParserMatchClass = u16_2ImmOperand; }
> +  def u16_3Imm : Operand<i32> { let ParserMatchClass = u16_3ImmOperand; }
> +  def u11_3Imm : Operand<i32> { let ParserMatchClass = u11_3ImmOperand; }
> +  def u10Imm : Operand<i32> { let ParserMatchClass = u10ImmOperand; }
> +  def u9Imm : Operand<i32> { let ParserMatchClass = u9ImmOperand; }
> +  def u8Imm : Operand<i32> { let ParserMatchClass = u8ImmOperand; }
> +  def u7Imm : Operand<i32> { let ParserMatchClass = u7ImmOperand; }
> +  def u6Imm : Operand<i32> { let ParserMatchClass = u6ImmOperand; }
> +  def u6_0Imm : Operand<i32> { let ParserMatchClass = u6_0ImmOperand; }
> +  def u6_1Imm : Operand<i32> { let ParserMatchClass = u6_1ImmOperand; }
> +  def u6_2Imm : Operand<i32> { let ParserMatchClass = u6_2ImmOperand; }
> +  def u6_3Imm : Operand<i32> { let ParserMatchClass = u6_3ImmOperand; }
> +  def u5Imm : Operand<i32> { let ParserMatchClass = u5ImmOperand; }
> +  def u5_0Imm : Operand<i32>;
> +  def u5_1Imm : Operand<i32>;
>    def u5_2Imm : Operand<i32>;
>    def u5_3Imm : Operand<i32>;
> -  def u4Imm : Operand<i32>;
> +  def u4Imm : Operand<i32> { let ParserMatchClass = u4ImmOperand; }
>    def u4_0Imm : Operand<i32>;
> +  def u4_1Imm : Operand<i32>;
>    def u4_2Imm : Operand<i32>;
> -  def u3Imm : Operand<i32>;
> +  def u4_3Imm : Operand<i32>;
> +  def u3Imm : Operand<i32> { let ParserMatchClass = u3ImmOperand; }
>    def u3_0Imm : Operand<i32>;
>    def u3_1Imm : Operand<i32>;
> -  def u2Imm : Operand<i32>;
> -  def u1Imm : Operand<i32>;
> -  def n8Imm : Operand<i32>;
> -  def m6Imm : Operand<i32>;
> +  def u3_2Imm : Operand<i32>;
> +  def u3_3Imm : Operand<i32>;
> +  def u2Imm : Operand<i32> { let ParserMatchClass = u2ImmOperand; }
> +  def u1Imm : Operand<i32> { let ParserMatchClass = u1ImmOperand; }
> +  def n8Imm : Operand<i32> { let ParserMatchClass = n8ImmOperand; }
>  }
>
>  let OperandType = "OPERAND_IMMEDIATE" in {
> @@ -73,9 +116,6 @@ let OperandType = "OPERAND_IMMEDIATE" in
>                                 let DecoderMethod = "s3_6ImmDecoder";}
>  }
>
> -let PrintMethod = "printNOneImmOperand" in
> -def nOneImm : Operand<i32>;
> -
>  //
>  // Immediate predicates
>  //
> @@ -169,7 +209,6 @@ def s4_3ImmPred  : PatLeaf<(i32 imm), [{
>    return isShiftedInt<4,3>(v);
>  }]>;
>
> -
>  def u64ImmPred  : PatLeaf<(i64 imm), [{
>    // Adding "N ||" to suppress gcc unused warning.
>    return (N || true);
> @@ -225,6 +264,11 @@ def u11_3ImmPred : PatLeaf<(i32 imm), [{
>    return isShiftedUInt<11,3>(v);
>  }]>;
>
> +def u10ImmPred  : PatLeaf<(i32 imm), [{
> +  int64_t v = (int64_t)N->getSExtValue();
> +  return isUInt<10>(v);
> +}]>;
> +
>  def u9ImmPred  : PatLeaf<(i32 imm), [{
>    int64_t v = (int64_t)N->getSExtValue();
>    return isUInt<9>(v);
> @@ -296,6 +340,11 @@ def u1ImmPred  : PatLeaf<(i1 imm), [{
>    return isUInt<1>(v);
>  }]>;
>
> +def u1ImmPred32  : PatLeaf<(i32 imm), [{
> +  int64_t v = (int64_t)N->getSExtValue();
> +  return isUInt<1>(v);
> +}]>;
> +
>  def m5BImmPred  : PatLeaf<(i32 imm), [{
>    // m5BImmPred predicate - True if the (char) number is in range -1 ..
> -31
>    // and will fit in a 5 bit field when made positive, for use in memops.
> @@ -408,29 +457,65 @@ def SetClr3ImmPred : PatLeaf<(i32 imm),
>
>
>  // Extendable immediate operands.
> +def f32ExtOperand : AsmOperandClass { let Name = "f32Ext"; }
> +def s16ExtOperand : AsmOperandClass { let Name = "s16Ext"; }
> +def s12ExtOperand : AsmOperandClass { let Name = "s12Ext"; }
> +def s10ExtOperand : AsmOperandClass { let Name = "s10Ext"; }
> +def s9ExtOperand : AsmOperandClass { let Name = "s9Ext"; }
> +def s8ExtOperand : AsmOperandClass { let Name = "s8Ext"; }
> +def s7ExtOperand : AsmOperandClass { let Name = "s7Ext"; }
> +def s6ExtOperand : AsmOperandClass { let Name = "s6Ext"; }
> +def s11_0ExtOperand : AsmOperandClass { let Name = "s11_0Ext"; }
> +def s11_1ExtOperand : AsmOperandClass { let Name = "s11_1Ext"; }
> +def s11_2ExtOperand : AsmOperandClass { let Name = "s11_2Ext"; }
> +def s11_3ExtOperand : AsmOperandClass { let Name = "s11_3Ext"; }
> +def u6ExtOperand : AsmOperandClass { let Name = "u6Ext"; }
> +def u7ExtOperand : AsmOperandClass { let Name = "u7Ext"; }
> +def u8ExtOperand : AsmOperandClass { let Name = "u8Ext"; }
> +def u9ExtOperand : AsmOperandClass { let Name = "u9Ext"; }
> +def u10ExtOperand : AsmOperandClass { let Name = "u10Ext"; }
> +def u6_0ExtOperand : AsmOperandClass { let Name = "u6_0Ext"; }
> +def u6_1ExtOperand : AsmOperandClass { let Name = "u6_1Ext"; }
> +def u6_2ExtOperand : AsmOperandClass { let Name = "u6_2Ext"; }
> +def u6_3ExtOperand : AsmOperandClass { let Name = "u6_3Ext"; }
> +def u32MustExtOperand : AsmOperandClass { let Name = "u32MustExt"; }
> +
>
> -let PrintMethod = "printExtOperand" in {
> -  def f32Ext : Operand<f32>;
> -  def s16Ext : Operand<i32> { let DecoderMethod = "s16ImmDecoder"; }
> -  def s12Ext : Operand<i32> { let DecoderMethod = "s12ImmDecoder"; }
> -  def s11_0Ext : Operand<i32> { let DecoderMethod = "s11_0ImmDecoder"; }
> -  def s11_1Ext : Operand<i32> { let DecoderMethod = "s11_1ImmDecoder"; }
> -  def s11_2Ext : Operand<i32> { let DecoderMethod = "s11_2ImmDecoder"; }
> -  def s11_3Ext : Operand<i32> { let DecoderMethod = "s11_3ImmDecoder"; }
> -  def s10Ext : Operand<i32> { let DecoderMethod = "s10ImmDecoder"; }
> -  def s9Ext : Operand<i32> { let DecoderMethod = "s90ImmDecoder"; }
> -  def s8Ext : Operand<i32> { let DecoderMethod = "s8ImmDecoder"; }
> -  def s7Ext : Operand<i32>;
> -  def s6Ext : Operand<i32> { let DecoderMethod = "s6_0ImmDecoder"; }
> -  def u6Ext : Operand<i32>;
> -  def u7Ext : Operand<i32>;
> -  def u8Ext : Operand<i32>;
> -  def u9Ext : Operand<i32>;
> -  def u10Ext : Operand<i32>;
> -  def u6_0Ext : Operand<i32>;
> -  def u6_1Ext : Operand<i32>;
> -  def u6_2Ext : Operand<i32>;
> -  def u6_3Ext : Operand<i32>;
> +
> +let OperandType = "OPERAND_IMMEDIATE", PrintMethod = "printExtOperand",
> +    DecoderMethod = "unsignedImmDecoder" in {
> +  def f32Ext : Operand<f32> { let ParserMatchClass = f32ExtOperand; }
> +  def s16Ext : Operand<i32> { let ParserMatchClass = s16ExtOperand;
> +                              let DecoderMethod = "s16ImmDecoder"; }
> +  def s12Ext : Operand<i32> { let ParserMatchClass = s12ExtOperand;
> +                              let DecoderMethod = "s12ImmDecoder"; }
> +  def s11_0Ext : Operand<i32> { let ParserMatchClass = s11_0ExtOperand;
> +                              let DecoderMethod = "s11_0ImmDecoder"; }
> +  def s11_1Ext : Operand<i32> { let ParserMatchClass = s11_1ExtOperand;
> +                              let DecoderMethod = "s11_1ImmDecoder"; }
> +  def s11_2Ext : Operand<i32> { let ParserMatchClass = s11_2ExtOperand;
> +                              let DecoderMethod = "s11_2ImmDecoder"; }
> +  def s11_3Ext : Operand<i32> { let ParserMatchClass = s11_3ExtOperand;
> +                              let DecoderMethod = "s11_3ImmDecoder"; }
> +  def s10Ext : Operand<i32> { let ParserMatchClass = s10ExtOperand;
> +                              let DecoderMethod = "s10ImmDecoder"; }
> +  def s9Ext : Operand<i32> { let ParserMatchClass = s9ExtOperand;
> +                              let DecoderMethod = "s90ImmDecoder"; }
> +  def s8Ext : Operand<i32> { let ParserMatchClass = s8ExtOperand;
> +                              let DecoderMethod = "s8ImmDecoder"; }
> +  def s7Ext : Operand<i32> { let ParserMatchClass = s7ExtOperand; }
> +  def s6Ext : Operand<i32> { let ParserMatchClass = s6ExtOperand;
> +                              let DecoderMethod = "s6_0ImmDecoder"; }
> +  def u6Ext : Operand<i32> { let ParserMatchClass = u6ExtOperand; }
> +  def u7Ext : Operand<i32> { let ParserMatchClass = u7ExtOperand; }
> +  def u8Ext : Operand<i32> { let ParserMatchClass = u8ExtOperand; }
> +  def u9Ext : Operand<i32> { let ParserMatchClass = u9ExtOperand; }
> +  def u10Ext : Operand<i32> { let ParserMatchClass = u10ExtOperand; }
> +  def u6_0Ext : Operand<i32> { let ParserMatchClass = u6_0ExtOperand; }
> +  def u6_1Ext : Operand<i32> { let ParserMatchClass = u6_1ExtOperand; }
> +  def u6_2Ext : Operand<i32> { let ParserMatchClass = u6_2ExtOperand; }
> +  def u6_3Ext : Operand<i32> { let ParserMatchClass = u6_3ExtOperand; }
> +  def u32MustExt : Operand<i32> { let ParserMatchClass =
> u32MustExtOperand; }
>  }
>
>
> @@ -492,21 +577,21 @@ let PrintMethod = "printGlobalOperand" i
>  let PrintMethod = "printJumpTable" in
>  def jumptablebase : Operand<i32>;
>
> -def brtarget : Operand<OtherVT>;
> +def brtarget : Operand<OtherVT> {
> +  let DecoderMethod = "brtargetDecoder";
> +  let PrintMethod = "printBrtarget";
> +}
>  def brtargetExt : Operand<OtherVT> {
> -  let PrintMethod = "printExtBrtarget";
> +  let DecoderMethod = "brtargetDecoder";
> +  let PrintMethod = "printBrtarget";
> +}
> +def calltarget : Operand<i32> {
> +  let DecoderMethod = "brtargetDecoder";
> +  let PrintMethod = "printBrtarget";
>  }
> -def calltarget : Operand<i32>;
>
>  def bblabel : Operand<i32>;
> -def bbl   : SDNode<"ISD::BasicBlock", SDTPtrLeaf   , [],
> "BasicBlockSDNode">;
> -
> -def symbolHi32 : Operand<i32> {
> -  let PrintMethod = "printSymbolHi";
> -}
> -def symbolLo32 : Operand<i32> {
> -  let PrintMethod = "printSymbolLo";
> -}
> +def bbl     : SDNode<"ISD::BasicBlock", SDTPtrLeaf, [],
> "BasicBlockSDNode">;
>
>  // Return true if for a 32 to 64-bit sign-extended load.
>  def is_sext_i32 : PatLeaf<(i64 DoubleRegs:$src1), [{
>
> Modified: llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.td
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.td?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.td (original)
> +++ llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.td Sun Nov  8
> 22:07:48 2015
> @@ -137,20 +137,21 @@ let Namespace = "Hexagon" in {
>    def LC1  : Rc<3,  "lc1",       ["c3"]>,   DwarfRegNum<[70]>;
>    def P3_0 : Rc<4,  "p3:0",      ["c4"], [P0, P1, P2, P3]>,
>                                              DwarfRegNum<[71]>;
> -  def C6   : Rc<6,  "c6",        [], [M0]>, DwarfRegNum<[72]>;
> -  def C7   : Rc<7,  "c7",        [], [M1]>, DwarfRegNum<[73]>;
> +  def C5   : Rc<5,  "c5",        ["c5"]>,   DwarfRegNum<[72]>; // future
> use
> +  def C6   : Rc<6,  "c6",        [], [M0]>, DwarfRegNum<[73]>;
> +  def C7   : Rc<7,  "c7",        [], [M1]>, DwarfRegNum<[74]>;
>
> -  def USR  : Rc<8,  "usr",       ["c8"]>,   DwarfRegNum<[74]> {
> +  def USR  : Rc<8,  "usr",       ["c8"]>,   DwarfRegNum<[75]> {
>      let SubRegIndices = [subreg_overflow];
>      let SubRegs = [USR_OVF];
>    }
> -  def PC   : Rc<9,  "pc">,                  DwarfRegNum<[75]>;
> -  def UGP  : Rc<10, "ugp",       ["c10"]>,  DwarfRegNum<[76]>;
> -  def GP   : Rc<11, "gp">,                  DwarfRegNum<[77]>;
> -  def CS0  : Rc<12, "cs0",       ["c12"]>,  DwarfRegNum<[78]>;
> -  def CS1  : Rc<13, "cs1",       ["c13"]>,  DwarfRegNum<[79]>;
> -  def UPCL : Rc<14, "upcyclelo", ["c14"]>,  DwarfRegNum<[80]>;
> -  def UPCH : Rc<15, "upcyclehi", ["c15"]>,  DwarfRegNum<[81]>;
> +  def PC   : Rc<9,  "pc">,                  DwarfRegNum<[76]>;
> +  def UGP  : Rc<10, "ugp",       ["c10"]>,  DwarfRegNum<[77]>;
> +  def GP   : Rc<11, "gp">,                  DwarfRegNum<[78]>;
> +  def CS0  : Rc<12, "cs0",       ["c12"]>,  DwarfRegNum<[79]>;
> +  def CS1  : Rc<13, "cs1",       ["c13"]>,  DwarfRegNum<[80]>;
> +  def UPCL : Rc<14, "upcyclelo", ["c14"]>,  DwarfRegNum<[81]>;
> +  def UPCH : Rc<15, "upcyclehi", ["c15"]>,  DwarfRegNum<[82]>;
>  }
>
>    // Control registers pairs.
>
> Modified: llvm/trunk/lib/Target/Hexagon/LLVMBuild.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/LLVMBuild.txt?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/LLVMBuild.txt (original)
> +++ llvm/trunk/lib/Target/Hexagon/LLVMBuild.txt Sun Nov  8 22:07:48 2015
> @@ -16,7 +16,7 @@
>
>  ;===------------------------------------------------------------------------===;
>
>  [common]
> -subdirectories = Disassembler MCTargetDesc TargetInfo
> +subdirectories = AsmParser Disassembler MCTargetDesc TargetInfo
>
>  [component_0]
>  type = TargetGroup
>
> Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt (original)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt Sun Nov  8
> 22:07:48 2015
> @@ -3,10 +3,12 @@ add_llvm_library(LLVMHexagonDesc
>    HexagonELFObjectWriter.cpp
>    HexagonInstPrinter.cpp
>    HexagonMCAsmInfo.cpp
> +  HexagonMCChecker.cpp
>    HexagonMCCodeEmitter.cpp
>    HexagonMCCompound.cpp
>    HexagonMCDuplexInfo.cpp
>    HexagonMCELFStreamer.cpp
> +  HexagonMCExpr.cpp
>    HexagonMCInstrInfo.cpp
>    HexagonMCShuffler.cpp
>    HexagonMCTargetDesc.cpp
>
> Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h (original)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h Sun Nov
> 8 22:07:48 2015
> @@ -44,6 +44,25 @@ namespace HexagonII {
>      TypeMEMOP   = 9,
>      TypeNV      = 10,
>      TypeDUPLEX  = 11,
> +    TypeCOMPOUND = 12,
> +    TypeCVI_FIRST     = 13,
> +    TypeCVI_VA        = TypeCVI_FIRST,
> +    TypeCVI_VA_DV     = 14,
> +    TypeCVI_VX        = 15,
> +    TypeCVI_VX_DV     = 16,
> +    TypeCVI_VP        = 17,
> +    TypeCVI_VP_VS     = 18,
> +    TypeCVI_VS        = 19,
> +    TypeCVI_VINLANESAT= 20,
> +    TypeCVI_VM_LD     = 21,
> +    TypeCVI_VM_TMP_LD = 22,
> +    TypeCVI_VM_CUR_LD = 23,
> +    TypeCVI_VM_VP_LDU = 24,
> +    TypeCVI_VM_ST     = 25,
> +    TypeCVI_VM_NEW_ST = 26,
> +    TypeCVI_VM_STU    = 27,
> +    TypeCVI_HIST      = 28,
> +    TypeCVI_LAST      = TypeCVI_HIST,
>      TypePREFIX  = 30, // Such as extenders.
>      TypeENDLOOP = 31  // Such as end of a HW loop.
>    };
> @@ -164,7 +183,15 @@ namespace HexagonII {
>
>      // Floating-point instructions.
>      FPPos  = 48,
> -    FPMask = 0x1
> +    FPMask = 0x1,
> +
> +    // New-Value producer-2 instructions.
> +    hasNewValuePos2  = 50,
> +    hasNewValueMask2 = 0x1,
> +
> +    // Which operand consumes or produces a new value.
> +    NewValueOpPos2  = 51,
> +    NewValueOpMask2 = 0x7
>    };
>
>    // *** The code above must match HexagonInstrFormat*.td *** //
> @@ -219,6 +246,26 @@ namespace HexagonII {
>      INST_PARSE_EXTENDER   = 0x00000000
>    };
>
> +  enum InstIClassBits {
> +    INST_ICLASS_MASK      = 0xf0000000,
> +    INST_ICLASS_EXTENDER  = 0x00000000,
> +    INST_ICLASS_J_1       = 0x10000000,
> +    INST_ICLASS_J_2       = 0x20000000,
> +    INST_ICLASS_LD_ST_1   = 0x30000000,
> +    INST_ICLASS_LD_ST_2   = 0x40000000,
> +    INST_ICLASS_J_3       = 0x50000000,
> +    INST_ICLASS_CR        = 0x60000000,
> +    INST_ICLASS_ALU32_1   = 0x70000000,
> +    INST_ICLASS_XTYPE_1   = 0x80000000,
> +    INST_ICLASS_LD        = 0x90000000,
> +    INST_ICLASS_ST        = 0xa0000000,
> +    INST_ICLASS_ALU32_2   = 0xb0000000,
> +    INST_ICLASS_XTYPE_2   = 0xc0000000,
> +    INST_ICLASS_XTYPE_3   = 0xd0000000,
> +    INST_ICLASS_XTYPE_4   = 0xe0000000,
> +    INST_ICLASS_ALU32_3   = 0xf0000000
> +  };
> +
>  } // End namespace HexagonII.
>
>  } // End namespace llvm.
>
> Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp
> (original)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.cpp Sun
> Nov  8 22:07:48 2015
> @@ -12,13 +12,13 @@
>
>  //===----------------------------------------------------------------------===//
>
>  #include "HexagonAsmPrinter.h"
> -#include "Hexagon.h"
>  #include "HexagonInstPrinter.h"
> +#include "MCTargetDesc/HexagonBaseInfo.h"
>  #include "MCTargetDesc/HexagonMCInstrInfo.h"
> -#include "llvm/ADT/StringExtras.h"
>  #include "llvm/MC/MCAsmInfo.h"
>  #include "llvm/MC/MCExpr.h"
>  #include "llvm/MC/MCInst.h"
> +#include "llvm/Support/Debug.h"
>  #include "llvm/Support/raw_ostream.h"
>
>  using namespace llvm;
> @@ -28,63 +28,33 @@ using namespace llvm;
>  #define GET_INSTRUCTION_NAME
>  #include "HexagonGenAsmWriter.inc"
>
> -// Return the minimum value that a constant extendable operand can have
> -// without being extended.
> -static int getMinValue(uint64_t TSFlags) {
> -  unsigned isSigned =
> -      (TSFlags >> HexagonII::ExtentSignedPos) &
> HexagonII::ExtentSignedMask;
> -  unsigned bits =
> -      (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
> -
> -  if (isSigned)
> -    return -1U << (bits - 1);
> -
> -  return 0;
> -}
> -
> -// Return the maximum value that a constant extendable operand can have
> -// without being extended.
> -static int getMaxValue(uint64_t TSFlags) {
> -  unsigned isSigned =
> -      (TSFlags >> HexagonII::ExtentSignedPos) &
> HexagonII::ExtentSignedMask;
> -  unsigned bits =
> -      (TSFlags >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
> -
> -  if (isSigned)
> -    return ~(-1U << (bits - 1));
> -
> -  return ~(-1U << bits);
> -}
> -
> -// Return true if the instruction must be extended.
> -static bool isExtended(uint64_t TSFlags) {
> -  return (TSFlags >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
> -}
> -
> -// Currently just used in an assert statement
> -static bool isExtendable(uint64_t TSFlags) LLVM_ATTRIBUTE_UNUSED;
> -// Return true if the instruction may be extended based on the operand
> value.
> -static bool isExtendable(uint64_t TSFlags) {
> -  return (TSFlags >> HexagonII::ExtendablePos) &
> HexagonII::ExtendableMask;
> +HexagonInstPrinter::HexagonInstPrinter(MCAsmInfo const &MAI,
> +                                       MCInstrInfo const &MII,
> +                                       MCRegisterInfo const &MRI)
> +    : MCInstPrinter(MAI, MII, MRI), MII(MII), HasExtender(false) {
>  }
>
>  StringRef HexagonInstPrinter::getOpcodeName(unsigned Opcode) const {
>    return MII.getName(Opcode);
>  }
>
> -void HexagonInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo)
> const {
> -  OS << getRegisterName(RegNo);
> +void HexagonInstPrinter::printRegName(raw_ostream &O, unsigned RegNo)
> const {
> +  O << getRegName(RegNo);
> +}
> +
> +StringRef HexagonInstPrinter::getRegName(unsigned RegNo) const {
> +  return getRegisterName(RegNo);
>  }
>
>  void HexagonInstPrinter::setExtender(MCInst const &MCI) {
>    HasExtender = HexagonMCInstrInfo::isImmext(MCI);
>  }
>
> -void HexagonInstPrinter::printInst(MCInst const *MI, raw_ostream &OS,
> -                                   StringRef Annot,
> -                                   MCSubtargetInfo const &STI) {
> +void HexagonInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
> +                                   StringRef Annot, const MCSubtargetInfo
> &STI) {
>    assert(HexagonMCInstrInfo::isBundle(*MI));
>    assert(HexagonMCInstrInfo::bundleSize(*MI) <= HEXAGON_PACKET_SIZE);
> +  assert(HexagonMCInstrInfo::bundleSize(*MI) > 0);
>    HasExtender = false;
>    for (auto const &I : HexagonMCInstrInfo::bundleInstructions(*MI)) {
>      MCInst const &MCI = *I.getInst();
> @@ -116,173 +86,148 @@ void HexagonInstPrinter::printInst(MCIns
>    }
>  }
>
> -void HexagonInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
> +void HexagonInstPrinter::printOperand(MCInst const *MI, unsigned OpNo,
>                                        raw_ostream &O) const {
> -  const MCOperand& MO = MI->getOperand(OpNo);
> -
> +  if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo &&
> +      (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI)))
> +    O << "#";
> +  MCOperand const &MO = MI->getOperand(OpNo);
>    if (MO.isReg()) {
> -    printRegName(O, MO.getReg());
> -  } else if(MO.isExpr()) {
> -    MO.getExpr()->print(O, &MAI);
> -  } else if(MO.isImm()) {
> -    printImmOperand(MI, OpNo, O);
> +    O << getRegisterName(MO.getReg());
> +  } else if (MO.isExpr()) {
> +    int64_t Value;
> +    if (MO.getExpr()->evaluateAsAbsolute(Value))
> +      O << formatImm(Value);
> +    else
> +      O << *MO.getExpr();
>    } else {
>      llvm_unreachable("Unknown operand");
>    }
>  }
>
> -void HexagonInstPrinter::printImmOperand(const MCInst *MI, unsigned OpNo,
> +void HexagonInstPrinter::printExtOperand(MCInst const *MI, unsigned OpNo,
>                                           raw_ostream &O) const {
> -  const MCOperand& MO = MI->getOperand(OpNo);
> -
> -  if(MO.isExpr()) {
> -    MO.getExpr()->print(O, &MAI);
> -  } else if(MO.isImm()) {
> -    O << MI->getOperand(OpNo).getImm();
> -  } else {
> -    llvm_unreachable("Unknown operand");
> -  }
> -}
> -
> -void HexagonInstPrinter::printExtOperand(const MCInst *MI, unsigned OpNo,
> -                                         raw_ostream &O) const {
> -  const MCOperand &MO = MI->getOperand(OpNo);
> -  const MCInstrDesc &MII = getMII().get(MI->getOpcode());
> -
> -  assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
> -         "Expecting an extendable operand");
> -
> -  if (MO.isExpr() || isExtended(MII.TSFlags)) {
> -    O << "#";
> -  } else if (MO.isImm()) {
> -    int ImmValue = MO.getImm();
> -    if (ImmValue < getMinValue(MII.TSFlags) ||
> -        ImmValue > getMaxValue(MII.TSFlags))
> -      O << "#";
> -  }
>    printOperand(MI, OpNo, O);
>  }
>
> -void HexagonInstPrinter::printUnsignedImmOperand(const MCInst *MI,
> -                                    unsigned OpNo, raw_ostream &O) const {
> +void HexagonInstPrinter::printUnsignedImmOperand(MCInst const *MI,
> +                                                 unsigned OpNo,
> +                                                 raw_ostream &O) const {
>    O << MI->getOperand(OpNo).getImm();
>  }
>
> -void HexagonInstPrinter::printNegImmOperand(const MCInst *MI, unsigned
> OpNo,
> +void HexagonInstPrinter::printNegImmOperand(MCInst const *MI, unsigned
> OpNo,
>                                              raw_ostream &O) const {
>    O << -MI->getOperand(OpNo).getImm();
>  }
>
> -void HexagonInstPrinter::printNOneImmOperand(const MCInst *MI, unsigned
> OpNo,
> +void HexagonInstPrinter::printNOneImmOperand(MCInst const *MI, unsigned
> OpNo,
>                                               raw_ostream &O) const {
>    O << -1;
>  }
>
>  void HexagonInstPrinter::prints3_6ImmOperand(MCInst const *MI, unsigned
> OpNo,
>                                               raw_ostream &O) const {
> -  int64_t Imm = MI->getOperand(OpNo).getImm();
> +  int64_t Imm;
> +  bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
> +  Imm = SignExtend64<9>(Imm);
> +  assert(Success); (void)Success;
>    assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO.");
>    O << formatImm(Imm/64);
>  }
>
>  void HexagonInstPrinter::prints3_7ImmOperand(MCInst const *MI, unsigned
> OpNo,
>                                               raw_ostream &O) const {
> -  int64_t Imm = MI->getOperand(OpNo).getImm();
> +  int64_t Imm;
> +  bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
> +  Imm = SignExtend64<10>(Imm);
> +  assert(Success); (void)Success;
>    assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO.");
>    O << formatImm(Imm/128);
>  }
>
>  void HexagonInstPrinter::prints4_6ImmOperand(MCInst const *MI, unsigned
> OpNo,
>                                               raw_ostream &O) const {
> -  int64_t Imm = MI->getOperand(OpNo).getImm();
> +  int64_t Imm;
> +  bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
> +  Imm = SignExtend64<10>(Imm);
> +  assert(Success); (void)Success;
>    assert(((Imm & 0x3f) == 0) && "Lower 6 bits must be ZERO.");
>    O << formatImm(Imm/64);
>  }
>
>  void HexagonInstPrinter::prints4_7ImmOperand(MCInst const *MI, unsigned
> OpNo,
>                                               raw_ostream &O) const {
> -  int64_t Imm = MI->getOperand(OpNo).getImm();
> +  int64_t Imm;
> +  bool Success = MI->getOperand(OpNo).getExpr()->evaluateAsAbsolute(Imm);
> +  Imm = SignExtend64<11>(Imm);
> +  assert(Success); (void)Success;
>    assert(((Imm & 0x7f) == 0) && "Lower 7 bits must be ZERO.");
>    O << formatImm(Imm/128);
>  }
>
> -void HexagonInstPrinter::printMEMriOperand(const MCInst *MI, unsigned
> OpNo,
> -                                           raw_ostream &O) const {
> -  const MCOperand& MO0 = MI->getOperand(OpNo);
> -  const MCOperand& MO1 = MI->getOperand(OpNo + 1);
> -
> -  printRegName(O, MO0.getReg());
> -  O << " + #" << MO1.getImm();
> -}
> -
> -void HexagonInstPrinter::printFrameIndexOperand(const MCInst *MI,
> unsigned OpNo,
> -                                                raw_ostream &O) const {
> -  const MCOperand& MO0 = MI->getOperand(OpNo);
> -  const MCOperand& MO1 = MI->getOperand(OpNo + 1);
> -
> -  printRegName(O, MO0.getReg());
> -  O << ", #" << MO1.getImm();
> -}
> -
> -void HexagonInstPrinter::printGlobalOperand(const MCInst *MI, unsigned
> OpNo,
> +void HexagonInstPrinter::printGlobalOperand(MCInst const *MI, unsigned
> OpNo,
>                                              raw_ostream &O) const {
> -  assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
> -
>    printOperand(MI, OpNo, O);
>  }
>
> -void HexagonInstPrinter::printJumpTable(const MCInst *MI, unsigned OpNo,
> +void HexagonInstPrinter::printJumpTable(MCInst const *MI, unsigned OpNo,
>                                          raw_ostream &O) const {
>    assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
>
>    printOperand(MI, OpNo, O);
>  }
>
> -void HexagonInstPrinter::printConstantPool(const MCInst *MI, unsigned
> OpNo,
> +void HexagonInstPrinter::printConstantPool(MCInst const *MI, unsigned
> OpNo,
>                                             raw_ostream &O) const {
>    assert(MI->getOperand(OpNo).isExpr() && "Expecting expression");
>
>    printOperand(MI, OpNo, O);
>  }
>
> -void HexagonInstPrinter::printBranchOperand(const MCInst *MI, unsigned
> OpNo,
> +void HexagonInstPrinter::printBranchOperand(MCInst const *MI, unsigned
> OpNo,
>                                              raw_ostream &O) const {
>    // Branches can take an immediate operand.  This is used by the branch
>    // selection pass to print $+8, an eight byte displacement from the PC.
>    llvm_unreachable("Unknown branch operand.");
>  }
>
> -void HexagonInstPrinter::printCallOperand(const MCInst *MI, unsigned OpNo,
> -                                          raw_ostream &O) const {
> -}
> +void HexagonInstPrinter::printCallOperand(MCInst const *MI, unsigned OpNo,
> +                                          raw_ostream &O) const {}
>
> -void HexagonInstPrinter::printAbsAddrOperand(const MCInst *MI, unsigned
> OpNo,
> -                                             raw_ostream &O) const {
> -}
> +void HexagonInstPrinter::printAbsAddrOperand(MCInst const *MI, unsigned
> OpNo,
> +                                             raw_ostream &O) const {}
>
> -void HexagonInstPrinter::printPredicateOperand(const MCInst *MI, unsigned
> OpNo,
> -                                               raw_ostream &O) const {
> -}
> +void HexagonInstPrinter::printPredicateOperand(MCInst const *MI, unsigned
> OpNo,
> +                                               raw_ostream &O) const {}
>
> -void HexagonInstPrinter::printSymbol(const MCInst *MI, unsigned OpNo,
> +void HexagonInstPrinter::printSymbol(MCInst const *MI, unsigned OpNo,
>                                       raw_ostream &O, bool hi) const {
> -  assert(MI->getOperand(OpNo).isImm() && "Unknown symbol operand");
> +  MCOperand const &MO = MI->getOperand(OpNo);
>
> -  O << '#' << (hi ? "HI" : "LO") << "(#";
> -  printOperand(MI, OpNo, O);
> +  O << '#' << (hi ? "HI" : "LO") << '(';
> +  if (MO.isImm()) {
> +    O << '#';
> +    printOperand(MI, OpNo, O);
> +  } else {
> +    printOperand(MI, OpNo, O);
> +    assert("Unknown symbol operand");
> +  }
>    O << ')';
>  }
>
> -void HexagonInstPrinter::printExtBrtarget(const MCInst *MI, unsigned OpNo,
> -                                          raw_ostream &O) const {
> -  const MCOperand &MO = MI->getOperand(OpNo);
> -  const MCInstrDesc &MII = getMII().get(MI->getOpcode());
> -
> -  assert((isExtendable(MII.TSFlags) || isExtended(MII.TSFlags)) &&
> -         "Expecting an extendable operand");
> -
> -  if (MO.isExpr() || isExtended(MII.TSFlags)) {
> -    O << "##";
> +void HexagonInstPrinter::printBrtarget(MCInst const *MI, unsigned OpNo,
> +                                       raw_ostream &O) const {
> +  MCOperand const &MO = MI->getOperand(OpNo);
> +  assert (MO.isExpr());
> +  MCExpr const &Expr = *MO.getExpr();
> +  int64_t Value;
> +  if (Expr.evaluateAsAbsolute(Value))
> +    O << format("0x%" PRIx64, Value);
> +  else {
> +    if (HasExtender || HexagonMCInstrInfo::isConstExtended(MII, *MI))
> +      if (HexagonMCInstrInfo::getExtendableOp(MII, *MI) == OpNo)
> +        O << "##";
> +    O << Expr;
>    }
> -  printOperand(MI, OpNo, O);
>  }
>
> Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h
> (original)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h Sun
> Nov  8 22:07:48 2015
> @@ -7,7 +7,6 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>  //
> -// This class prints an Hexagon MCInst to a .s file.
>  //
>
>  //===----------------------------------------------------------------------===//
>
> @@ -15,7 +14,6 @@
>  #define LLVM_LIB_TARGET_HEXAGON_INSTPRINTER_HEXAGONINSTPRINTER_H
>
>  #include "llvm/MC/MCInstPrinter.h"
> -#include "llvm/MC/MCInstrInfo.h"
>
>  namespace llvm {
>  /// Prints bundles as a newline separated list of individual instructions
> @@ -25,76 +23,69 @@ namespace llvm {
>  /// r0 = add(r1, r2)
>  /// r0 = #0 \v jump 0x0
>  /// :endloop0 :endloop1
> -  class HexagonInstPrinter : public MCInstPrinter {
> -  public:
> -    explicit HexagonInstPrinter(MCAsmInfo const &MAI,
> -                                MCInstrInfo const &MII,
> -                                MCRegisterInfo const &MRI)
> -      : MCInstPrinter(MAI, MII, MRI), MII(MII) {}
> -
> -    void printInst(MCInst const *MI, raw_ostream &O, StringRef Annot,
> -                   const MCSubtargetInfo &STI) override;
> -    virtual StringRef getOpcodeName(unsigned Opcode) const;
> -    void printInstruction(const MCInst *MI, raw_ostream &O);
> -    void printRegName(raw_ostream &OS, unsigned RegNo) const override;
> -    static const char *getRegisterName(unsigned RegNo);
> -
> -    void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
> const;
> -    void printImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
> const;
> -    void printExtOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
> const;
> -    void printUnsignedImmOperand(const MCInst *MI, unsigned OpNo,
> -                                 raw_ostream &O) const;
> -    void printNegImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream
> &O)
> -           const;
> -    void printNOneImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream
> &O)
> -             const;
> -    void prints3_6ImmOperand(MCInst const *MI, unsigned OpNo,
> -                             raw_ostream &O) const;
> -    void prints3_7ImmOperand(MCInst const *MI, unsigned OpNo,
> -                             raw_ostream &O) const;
> -    void prints4_6ImmOperand(MCInst const *MI, unsigned OpNo,
> -                             raw_ostream &O) const;
> -    void prints4_7ImmOperand(MCInst const *MI, unsigned OpNo,
> +class HexagonInstPrinter : public MCInstPrinter {
> +public:
> +  explicit HexagonInstPrinter(MCAsmInfo const &MAI, MCInstrInfo const
> &MII,
> +                              MCRegisterInfo const &MRI);
> +  void printInst(MCInst const *MI, raw_ostream &O, StringRef Annot,
> +                 const MCSubtargetInfo &STI) override;
> +  virtual StringRef getOpcodeName(unsigned Opcode) const;
> +  void printInstruction(MCInst const *MI, raw_ostream &O);
> +
> +  StringRef getRegName(unsigned RegNo) const;
> +  static char const *getRegisterName(unsigned RegNo);
> +  void printRegName(raw_ostream &O, unsigned RegNo) const override;
> +
> +  void printOperand(MCInst const *MI, unsigned OpNo, raw_ostream &O)
> const;
> +  void printExtOperand(MCInst const *MI, unsigned OpNo, raw_ostream &O)
> const;
> +  void printUnsignedImmOperand(MCInst const *MI, unsigned OpNo,
> +                               raw_ostream &O) const;
> +  void printNegImmOperand(MCInst const *MI, unsigned OpNo,
> +                          raw_ostream &O) const;
> +  void printNOneImmOperand(MCInst const *MI, unsigned OpNo,
> +                           raw_ostream &O) const;
> +  void prints3_6ImmOperand(MCInst const *MI, unsigned OpNo,
> +                           raw_ostream &O) const;
> +  void prints3_7ImmOperand(MCInst const *MI, unsigned OpNo,
> +                           raw_ostream &O) const;
> +  void prints4_6ImmOperand(MCInst const *MI, unsigned OpNo,
> +                           raw_ostream &O) const;
> +  void prints4_7ImmOperand(MCInst const *MI, unsigned OpNo,
> +                           raw_ostream &O) const;
> +  void printBranchOperand(MCInst const *MI, unsigned OpNo,
> +                          raw_ostream &O) const;
> +  void printCallOperand(MCInst const *MI, unsigned OpNo, raw_ostream &O)
> const;
> +  void printAbsAddrOperand(MCInst const *MI, unsigned OpNo,
> +                           raw_ostream &O) const;
> +  void printPredicateOperand(MCInst const *MI, unsigned OpNo,
>                               raw_ostream &O) const;
> -    void printMEMriOperand(const MCInst *MI, unsigned OpNo, raw_ostream
> &O)
> -           const;
> -    void printFrameIndexOperand(const MCInst *MI, unsigned OpNo,
> -                                raw_ostream &O) const;
> -    void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream
> &O)
> -           const;
> -    void printCallOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)
> -           const;
> -    void printAbsAddrOperand(const MCInst *MI, unsigned OpNo, raw_ostream
> &O)
> -           const;
> -    void printPredicateOperand(const MCInst *MI, unsigned OpNo,
> raw_ostream &O)
> -           const;
> -    void printGlobalOperand(const MCInst *MI, unsigned OpNo, raw_ostream
> &O)
> -           const;
> -    void printJumpTable(const MCInst *MI, unsigned OpNo, raw_ostream &O)
> const;
> -    void printExtBrtarget(const MCInst *MI, unsigned OpNo, raw_ostream
> &O) const;
> -
> -    void printConstantPool(const MCInst *MI, unsigned OpNo,
> -                           raw_ostream &O) const;
> -
> -    void printSymbolHi(const MCInst *MI, unsigned OpNo, raw_ostream &O)
> const
> -      { printSymbol(MI, OpNo, O, true); }
> -    void printSymbolLo(const MCInst *MI, unsigned OpNo, raw_ostream &O)
> const
> -      { printSymbol(MI, OpNo, O, false); }
> -
> -    const MCInstrInfo &getMII() const {
> -      return MII;
> -    }
> -
> -  protected:
> -    void printSymbol(const MCInst *MI, unsigned OpNo, raw_ostream &O,
> bool hi)
> -           const;
> -
> -  private:
> -    const MCInstrInfo &MII;
> -
> -    bool HasExtender;
> -    void setExtender(MCInst const &MCI);
> -  };
> +  void printGlobalOperand(MCInst const *MI, unsigned OpNo,
> +                          raw_ostream &O) const;
> +  void printJumpTable(MCInst const *MI, unsigned OpNo, raw_ostream &O)
> const;
> +  void printBrtarget(MCInst const *MI, unsigned OpNo, raw_ostream &O)
> const;
> +
> +  void printConstantPool(MCInst const *MI, unsigned OpNo, raw_ostream &O)
> const;
> +
> +  void printSymbolHi(MCInst const *MI, unsigned OpNo, raw_ostream &O)
> const {
> +    printSymbol(MI, OpNo, O, true);
> +  }
> +  void printSymbolLo(MCInst const *MI, unsigned OpNo, raw_ostream &O)
> const {
> +    printSymbol(MI, OpNo, O, false);
> +  }
> +
> +  MCAsmInfo const &getMAI() const { return MAI; }
> +  MCInstrInfo const &getMII() const { return MII; }
> +
> +protected:
> +  void printSymbol(MCInst const *MI, unsigned OpNo, raw_ostream &O,
> +                   bool hi) const;
> +
> +private:
> +  MCInstrInfo const &MII;
> +
> +  bool HasExtender;
> +  void setExtender(MCInst const &MCI);
> +};
>
>  } // end namespace llvm
>
>
> Added: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp (added)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp Sun
> Nov  8 22:07:48 2015
> @@ -0,0 +1,580 @@
> +//===----- HexagonMCChecker.cpp - Instruction bundle checking
> -------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This implements the checking of insns inside a bundle according to the
> +// packet constraint rules of the Hexagon ISA.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "HexagonMCChecker.h"
> +
> +#include "HexagonBaseInfo.h"
> +
> +#include "llvm/ADT/SmallVector.h"
> +#include "llvm/MC/MCInstrDesc.h"
> +#include "llvm/MC/MCInstrInfo.h"
> +#include "llvm/Support/CommandLine.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/raw_ostream.h"
> +
> +using namespace llvm;
> +
> +static cl::opt<bool> RelaxNVChecks("relax-nv-checks", cl::init(false),
> +  cl::ZeroOrMore, cl::Hidden, cl::desc("Relax checks of new-value
> validity"));
> +
> +const HexagonMCChecker::PredSense
> +  HexagonMCChecker::Unconditional(Hexagon::NoRegister, false);
> +
> +void HexagonMCChecker::init() {
> +  // Initialize read-only registers set.
> +  ReadOnly.insert(Hexagon::PC);
> +
> +  // Figure out the loop-registers definitions.
> +  if (HexagonMCInstrInfo::isInnerLoop(MCB)) {
> +    Defs[Hexagon::SA0].insert(Unconditional); // FIXME: define or change
> SA0?
> +    Defs[Hexagon::LC0].insert(Unconditional);
> +  }
> +  if (HexagonMCInstrInfo::isOuterLoop(MCB)) {
> +    Defs[Hexagon::SA1].insert(Unconditional); // FIXME: define or change
> SA0?
> +    Defs[Hexagon::LC1].insert(Unconditional);
> +  }
> +
> +  if (HexagonMCInstrInfo::isBundle(MCB))
> +    // Unfurl a bundle.
> +    for (auto const&I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
> +      init(*I.getInst());
> +    }
> +  else
> +    init(MCB);
> +}
> +
> +void HexagonMCChecker::init(MCInst const& MCI) {
> +  const MCInstrDesc& MCID = HexagonMCInstrInfo::getDesc(MCII, MCI);
> +  unsigned PredReg = Hexagon::NoRegister;
> +  bool isTrue = false;
> +
> +  // Get used registers.
> +  for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i)
> +    if (MCI.getOperand(i).isReg()) {
> +      unsigned R = MCI.getOperand(i).getReg();
> +
> +      if (HexagonMCInstrInfo::isPredicated(MCII, MCI) &&
> isPredicateRegister(R)) {
> +        // Note an used predicate register.
> +        PredReg = R;
> +        isTrue = HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI);
> +
> +        // Note use of new predicate register.
> +        if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI))
> +          NewPreds.insert(PredReg);
> +      }
> +      else
> +        // Note register use.  Super-registers are not tracked directly,
> +        // but their components.
> +        for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R,
> &RI).isValid());
> +           SRI.isValid();
> +           ++SRI)
> +         if (!MCSubRegIterator(*SRI, &RI).isValid())
> +           // Skip super-registers used indirectly.
> +           Uses.insert(*SRI);
> +    }
> +
> +  // Get implicit register definitions.
> +  const uint16_t* ImpDefs = MCID.getImplicitDefs();
> +  for (unsigned i = 0; i < MCID.getNumImplicitDefs(); ++i) {
> +    unsigned R = ImpDefs[i];
> +
> +    if (Hexagon::R31 != R && MCID.isCall())
> +      // Any register other than the LR and the PC are actually volatile
> ones
> +      // as defined by the ABI, not modified implicitly by the call insn.
> +      continue;
> +    if (Hexagon::PC == R)
> +      // Branches are the only insns that can change the PC,
> +      // otherwise a read-only register.
> +      continue;
> +
> +    if (Hexagon::USR_OVF == R)
> +      // Many insns change the USR implicitly, but only one or another
> flag.
> +      // The instruction table models the USR.OVF flag, which can be
> implicitly
> +      // modified more than once, but cannot be modified in the same
> packet
> +      // with an instruction that modifies is explicitly. Deal with such
> situ-
> +      // ations individually.
> +      SoftDefs.insert(R);
> +    else if (isPredicateRegister(R) &&
> HexagonMCInstrInfo::isPredicateLate(MCII, MCI))
> +      // Include implicit late predicates.
> +      LatePreds.insert(R);
> +    else
> +      Defs[R].insert(PredSense(PredReg, isTrue));
> +  }
> +
> +  // Figure out explicit register definitions.
> +  for (unsigned i = 0; i < MCID.getNumDefs(); ++i) {
> +    unsigned R = MCI.getOperand(i).getReg(),
> +             S = Hexagon::NoRegister;
> +
> +    // Note register definitions, direct ones as well as indirect
> side-effects.
> +    // Super-registers are not tracked directly, but their components.
> +    for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R,
> &RI).isValid());
> +        SRI.isValid();
> +        ++SRI) {
> +      if (MCSubRegIterator(*SRI, &RI).isValid())
> +        // Skip super-registers defined indirectly.
> +        continue;
> +
> +      if (R == *SRI) {
> +        if (S == R)
> +          // Avoid scoring the defined register multiple times.
> +          continue;
> +        else
> +          // Note that the defined register has already been scored.
> +          S = R;
> +      }
> +
> +      if (Hexagon::P3_0 != R && Hexagon::P3_0 == *SRI)
> +        // P3:0 is a special case, since multiple predicate register
> definitions
> +        // in a packet is allowed as the equivalent of their logical
> "and".
> +        // Only an explicit definition of P3:0 is noted as such; if a
> +        // side-effect, then note as a soft definition.
> +        SoftDefs.insert(*SRI);
> +      else if (HexagonMCInstrInfo::isPredicateLate(MCII, MCI) &&
> isPredicateRegister(*SRI))
> +        // Some insns produce predicates too late to be used in the same
> packet.
> +        LatePreds.insert(*SRI);
> +      else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) ==
> HexagonII::TypeCVI_VM_CUR_LD)
> +        // Current loads should be used in the same packet.
> +        // TODO: relies on the impossibility of a current and a temporary
> loads
> +        // in the same packet.
> +        CurDefs.insert(*SRI), Defs[*SRI].insert(PredSense(PredReg,
> isTrue));
> +      else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) ==
> HexagonII::TypeCVI_VM_TMP_LD)
> +        // Temporary loads should be used in the same packet, but don't
> commit
> +        // results, so it should be disregarded if another insn changes
> the same
> +        // register.
> +        // TODO: relies on the impossibility of a current and a temporary
> loads
> +        // in the same packet.
> +        TmpDefs.insert(*SRI);
> +      else if (i <= 1 && llvm::HexagonMCInstrInfo::hasNewValue2(MCII,
> MCI) )
> +        // vshuff(Vx, Vy, Rx) <- Vx(0) and Vy(1) are both source and
> +        // destination registers with this instruction. same for
> vdeal(Vx,Vy,Rx)
> +        Uses.insert(*SRI);
> +      else
> +        Defs[*SRI].insert(PredSense(PredReg, isTrue));
> +    }
> +  }
> +
> +  // Figure out register definitions that produce new values.
> +  if (HexagonMCInstrInfo::hasNewValue(MCII, MCI)) {
> +    unsigned R = HexagonMCInstrInfo::getNewValueOperand(MCII,
> MCI).getReg();
> +
> +    if (HexagonMCInstrInfo::isCompound(MCII, MCI))
> +      compoundRegisterMap(R); // Compound insns have a limited register
> range.
> +
> +    for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R,
> &RI).isValid());
> +        SRI.isValid();
> +        ++SRI)
> +      if (!MCSubRegIterator(*SRI, &RI).isValid())
> +        // No super-registers defined indirectly.
> +        NewDefs[*SRI].push_back(NewSense::Def(PredReg,
> HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
> +
> HexagonMCInstrInfo::isFloat(MCII, MCI)));
> +
> +    // For fairly unique 2-dot-new producers, example:
> +    // vdeal(V1, V9, R0) V1.new and V9.new can be used by consumers.
> +    if (HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) {
> +      unsigned R2 = HexagonMCInstrInfo::getNewValueOperand2(MCII,
> MCI).getReg();
> +
> +      for(MCRegAliasIterator SRI(R2, &RI, !MCSubRegIterator(R2,
> &RI).isValid());
> +          SRI.isValid();
> +          ++SRI)
> +        if (!MCSubRegIterator(*SRI, &RI).isValid())
> +          NewDefs[*SRI].push_back(NewSense::Def(PredReg,
> HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
> +
> HexagonMCInstrInfo::isFloat(MCII, MCI)));
> +    }
> +  }
> +
> +  // Figure out definitions of new predicate registers.
> +  if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI))
> +    for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i)
> +      if (MCI.getOperand(i).isReg()) {
> +        unsigned P = MCI.getOperand(i).getReg();
> +
> +        if (isPredicateRegister(P))
> +          NewPreds.insert(P);
> +      }
> +
> +  // Figure out uses of new values.
> +  if (HexagonMCInstrInfo::isNewValue(MCII, MCI)) {
> +    unsigned N = HexagonMCInstrInfo::getNewValueOperand(MCII,
> MCI).getReg();
> +
> +    if (!MCSubRegIterator(N, &RI).isValid()) {
> +      // Super-registers cannot use new values.
> +      if (MCID.isBranch())
> +        NewUses[N] =
> NewSense::Jmp(llvm::HexagonMCInstrInfo::getType(MCII, MCI) ==
> HexagonII::TypeNV);
> +      else
> +        NewUses[N] = NewSense::Use(PredReg,
> HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI));
> +    }
> +  }
> +}
> +
> +HexagonMCChecker::HexagonMCChecker(MCInstrInfo const &MCII,
> MCSubtargetInfo const &STI, MCInst &mcb, MCInst &mcbdx,
> +                                   MCRegisterInfo const &ri)
> +    : MCB(mcb), MCBDX(mcbdx), RI(ri), MCII(MCII), STI(STI),
> +      bLoadErrInfo(false) {
> +  init();
> +}
> +
> +bool HexagonMCChecker::check() {
> +  bool chkB = checkBranches();
> +  bool chkP = checkPredicates();
> +  bool chkNV = checkNewValues();
> +  bool chkR = checkRegisters();
> +  bool chkS = checkSolo();
> +  bool chkSh = checkShuffle();
> +  bool chkSl = checkSlots();
> +  bool chk = chkB && chkP && chkNV && chkR && chkS && chkSh && chkSl;
> +
> +  return chk;
> +}
> +
> +bool HexagonMCChecker::checkSlots()
> +
> +{
> +  unsigned slotsUsed = 0;
> +  for (auto HMI: HexagonMCInstrInfo::bundleInstructions(MCBDX)) {
> +    MCInst const& MCI = *HMI.getInst();
> +    if (HexagonMCInstrInfo::isImmext(MCI))
> +      continue;
> +    if (HexagonMCInstrInfo::isDuplex(MCII, MCI))
> +      slotsUsed += 2;
> +    else
> +      ++slotsUsed;
> +  }
> +
> +  if (slotsUsed > HEXAGON_PACKET_SIZE) {
> +    HexagonMCErrInfo errInfo;
> +    errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NOSLOTS);
> +    addErrInfo(errInfo);
> +    return false;
> +  }
> +  return true;
> +}
> +
> +// Check legal use of branches.
> +bool HexagonMCChecker::checkBranches() {
> +  HexagonMCErrInfo errInfo;
> +  if (HexagonMCInstrInfo::isBundle(MCB)) {
> +    bool hasConditional = false;
> +    unsigned Branches = 0, Returns = 0, NewIndirectBranches = 0,
> +             NewValueBranches = 0, Conditional =
> HEXAGON_PRESHUFFLE_PACKET_SIZE,
> +             Unconditional = HEXAGON_PRESHUFFLE_PACKET_SIZE;
> +
> +    for (unsigned i = HexagonMCInstrInfo::bundleInstructionsOffset;
> +         i < MCB.size(); ++i) {
> +      MCInst const &MCI = *MCB.begin()[i].getInst();
> +
> +      if (HexagonMCInstrInfo::isImmext(MCI))
> +        continue;
> +      if (HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch() ||
> +          HexagonMCInstrInfo::getDesc(MCII, MCI).isCall()) {
> +        ++Branches;
> +        if (HexagonMCInstrInfo::getDesc(MCII, MCI).isIndirectBranch() &&
> +            HexagonMCInstrInfo::isPredicatedNew(MCII, MCI))
> +          ++NewIndirectBranches;
> +        if (HexagonMCInstrInfo::isNewValue(MCII, MCI))
> +          ++NewValueBranches;
> +
> +        if (HexagonMCInstrInfo::isPredicated(MCII, MCI) ||
> +            HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) {
> +          hasConditional = true;
> +          Conditional = i; // Record the position of the conditional
> branch.
> +        } else {
> +          Unconditional = i; // Record the position of the unconditional
> branch.
> +        }
> +      }
> +      if (HexagonMCInstrInfo::getDesc(MCII, MCI).isReturn() &&
> +          HexagonMCInstrInfo::getDesc(MCII, MCI).mayLoad())
> +        ++Returns;
> +    }
> +
> +    if (Branches) // FIXME: should "Defs.count(Hexagon::PC)" be here too?
> +      if (HexagonMCInstrInfo::isInnerLoop(MCB) ||
> +          HexagonMCInstrInfo::isOuterLoop(MCB)) {
> +        // Error out if there's any branch in a loop-end packet.
> +        errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_ENDLOOP,
> Hexagon::PC);
> +        addErrInfo(errInfo);
> +        return false;
> +      }
> +    if (Branches > 1)
> +      if (!hasConditional || Conditional > Unconditional) {
> +        // Error out if more than one unconditional branch or
> +        // the conditional branch appears after the unconditional one.
> +        errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_BRANCHES);
> +        addErrInfo(errInfo);
> +        return false;
> +      }
> +  }
> +
> +  return true;
> +}
> +
> +// Check legal use of predicate registers.
> +bool HexagonMCChecker::checkPredicates() {
> +  HexagonMCErrInfo errInfo;
> +  // Check for proper use of new predicate registers.
> +  for (const auto& I : NewPreds) {
> +    unsigned P = I;
> +
> +    if (!Defs.count(P) || LatePreds.count(P)) {
> +      // Error out if the new predicate register is not defined,
> +      // or defined "late"
> +      // (e.g., "{ if (p3.new)... ; p3 = sp1loop0(#r7:2, Rs) }").
> +      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NEWP, P);
> +      addErrInfo(errInfo);
> +      return false;
> +    }
> +  }
> +
> +  // Check for proper use of auto-anded of predicate registers.
> +  for (const auto& I : LatePreds) {
> +    unsigned P = I;
> +
> +    if (LatePreds.count(P) > 1 || Defs.count(P)) {
> +      // Error out if predicate register defined "late" multiple times or
> +      // defined late and regularly defined
> +      // (e.g., "{ p3 = sp1loop0(...); p3 = cmp.eq(...) }".
> +      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, P);
> +      addErrInfo(errInfo);
> +      return false;
> +    }
> +  }
> +
> +  return true;
> +}
> +
> +// Check legal use of new values.
> +bool HexagonMCChecker::checkNewValues() {
> +  HexagonMCErrInfo errInfo;
> +  memset(&errInfo, 0, sizeof(errInfo));
> +  for (auto& I : NewUses) {
> +    unsigned R = I.first;
> +    NewSense &US = I.second;
> +
> +    if (!hasValidNewValueDef(US, NewDefs[R])) {
> +      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NEWV, R);
> +      addErrInfo(errInfo);
> +      return false;
> +    }
> +  }
> +
> +  return true;
> +}
> +
> +// Check for legal register uses and definitions.
> +bool HexagonMCChecker::checkRegisters() {
> +  HexagonMCErrInfo errInfo;
> +  // Check for proper register definitions.
> +  for (const auto& I : Defs) {
> +    unsigned R = I.first;
> +
> +    if (ReadOnly.count(R)) {
> +      // Error out for definitions of read-only registers.
> +      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_READONLY, R);
> +      addErrInfo(errInfo);
> +      return false;
> +    }
> +    if (isLoopRegister(R) && Defs.count(R) > 1 &&
> +        (HexagonMCInstrInfo::isInnerLoop(MCB) ||
> +         HexagonMCInstrInfo::isOuterLoop(MCB))) {
> +      // Error out for definitions of loop registers at the end of a loop.
> +      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_LOOP, R);
> +      addErrInfo(errInfo);
> +      return false;
> +    }
> +    if (SoftDefs.count(R)) {
> +      // Error out for explicit changes to registers also weakly defined
> +      // (e.g., "{ usr = r0; r0 = sfadd(...) }").
> +      unsigned UsrR = Hexagon::USR; // Silence warning about mixed types
> in ?:.
> +      unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
> +      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, BadR);
> +      addErrInfo(errInfo);
> +      return false;
> +    }
> +    if (!isPredicateRegister(R) && Defs[R].size() > 1) {
> +      // Check for multiple register definitions.
> +      PredSet &PM = Defs[R];
> +
> +      // Check for multiple unconditional register definitions.
> +      if (PM.count(Unconditional)) {
> +        // Error out on an unconditional change when there are any other
> +        // changes, conditional or not.
> +        unsigned UsrR = Hexagon::USR;
> +        unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
> +        errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, BadR);
> +        addErrInfo(errInfo);
> +        return false;
> +      }
> +      // Check for multiple conditional register definitions.
> +      for (const auto& J : PM) {
> +        PredSense P = J;
> +
> +        // Check for multiple uses of the same condition.
> +        if (PM.count(P) > 1) {
> +          // Error out on conditional changes based on the same predicate
> +          // (e.g., "{ if (!p0) r0 =...; if (!p0) r0 =... }").
> +          errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, R);
> +          addErrInfo(errInfo);
> +          return false;
> +        }
> +        // Check for the use of the complementary condition.
> +        P.second = !P.second;
> +        if (PM.count(P) && PM.size() > 2) {
> +          // Error out on conditional changes based on the same predicate
> +          // multiple times
> +          // (e.g., "{ if (p0) r0 =...; if (!p0) r0 =... }; if (!p0) r0
> =... }").
> +          errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, R);
> +          addErrInfo(errInfo);
> +          return false;
> +        }
> +      }
> +    }
> +  }
> +
> +  // Check for use of current definitions.
> +  for (const auto& I : CurDefs) {
> +    unsigned R = I;
> +
> +    if (!Uses.count(R)) {
> +      // Warn on an unused current definition.
> +      errInfo.setWarning(HexagonMCErrInfo::CHECK_WARN_CURRENT, R);
> +      addErrInfo(errInfo);
> +      return true;
> +    }
> +  }
> +
> +  // Check for use of temporary definitions.
> +  for (const auto& I : TmpDefs) {
> +    unsigned R = I;
> +
> +    if (!Uses.count(R)) {
> +      // special case for vhist
> +      bool vHistFound = false;
> +      for (auto const&HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
> +        if(llvm::HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) ==
> HexagonII::TypeCVI_HIST) {
> +          vHistFound = true;  // vhist() implicitly uses ALL REGxx.tmp
> +          break;
> +        }
> +      }
> +      // Warn on an unused temporary definition.
> +      if (vHistFound == false) {
> +        errInfo.setWarning(HexagonMCErrInfo::CHECK_WARN_TEMPORARY, R);
> +        addErrInfo(errInfo);
> +        return true;
> +      }
> +    }
> +  }
> +
> +  return true;
> +}
> +
> +// Check for legal use of solo insns.
> +bool HexagonMCChecker::checkSolo() {
> +  HexagonMCErrInfo errInfo;
> +  if (HexagonMCInstrInfo::isBundle(MCB) &&
> +      HexagonMCInstrInfo::bundleSize(MCB) > 1) {
> +    for (auto const&I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
> +      if (llvm::HexagonMCInstrInfo::isSolo(MCII, *I.getInst())) {
> +        errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SOLO);
> +        addErrInfo(errInfo);
> +        return false;
> +      }
> +    }
> +  }
> +
> +  return true;
> +}
> +
> +bool HexagonMCChecker::checkShuffle() {
> +  HexagonMCErrInfo errInfo;
> +  // Branch info is lost when duplexing. The unduplexed insns must be
> +  // checked and only branch errors matter for this case.
> +  HexagonMCShuffler MCS(MCII, STI, MCB);
> +  if (!MCS.check()) {
> +    if (MCS.getError() == HexagonShuffler::SHUFFLE_ERROR_BRANCHES) {
> +      errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SHUFFLE);
> +      errInfo.setShuffleError(MCS.getError());
> +      addErrInfo(errInfo);
> +      return false;
> +    }
> +  }
> +  HexagonMCShuffler MCSDX(MCII, STI, MCBDX);
> +  if (!MCSDX.check()) {
> +    errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SHUFFLE);
> +    errInfo.setShuffleError(MCSDX.getError());
> +    addErrInfo(errInfo);
> +    return false;
> +  }
> +  return true;
> +}
> +
> +void HexagonMCChecker::compoundRegisterMap(unsigned& Register) {
> +  switch (Register) {
> +  default:
> +    break;
> +  case Hexagon::R15:
> +    Register = Hexagon::R23;
> +    break;
> +  case Hexagon::R14:
> +    Register = Hexagon::R22;
> +    break;
> +  case Hexagon::R13:
> +    Register = Hexagon::R21;
> +    break;
> +  case Hexagon::R12:
> +    Register = Hexagon::R20;
> +    break;
> +  case Hexagon::R11:
> +    Register = Hexagon::R19;
> +    break;
> +  case Hexagon::R10:
> +    Register = Hexagon::R18;
> +    break;
> +  case Hexagon::R9:
> +    Register = Hexagon::R17;
> +    break;
> +  case Hexagon::R8:
> +    Register = Hexagon::R16;
> +    break;
> +  }
> +}
> +
> +bool HexagonMCChecker::hasValidNewValueDef(const NewSense &Use,
> +      const NewSenseList &Defs) const {
> +  bool Strict = !RelaxNVChecks;
> +
> +  for (unsigned i = 0, n = Defs.size(); i < n; ++i) {
> +    const NewSense &Def = Defs[i];
> +    // NVJ cannot use a new FP value [7.6.1]
> +    if (Use.IsNVJ && (Def.IsFloat || Def.PredReg != 0))
> +      continue;
> +    // If the definition was not predicated, then it does not matter if
> +    // the use is.
> +    if (Def.PredReg == 0)
> +      return true;
> +    // With the strict checks, both the definition and the use must be
> +    // predicated on the same register and condition.
> +    if (Strict) {
> +      if (Def.PredReg == Use.PredReg && Def.Cond == Use.Cond)
> +        return true;
> +    } else {
> +      // With the relaxed checks, if the definition was predicated, the
> only
> +      // detectable violation is if the use is predicated on the opposing
> +      // condition, otherwise, it's ok.
> +      if (Def.PredReg != Use.PredReg || Def.Cond == Use.Cond)
> +        return true;
> +    }
> +  }
> +  return false;
> +}
> +
>
> Added: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h (added)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.h Sun Nov
> 8 22:07:48 2015
> @@ -0,0 +1,218 @@
> +//===----- HexagonMCChecker.h - Instruction bundle checking
> ---------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// This implements the checking of insns inside a bundle according to the
> +// packet constraint rules of the Hexagon ISA.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef HEXAGONMCCHECKER_H
> +#define HEXAGONMCCHECKER_H
> +
> +#include <map>
> +#include <set>
> +#include <queue>
> +#include "MCTargetDesc/HexagonMCShuffler.h"
> +
> +using namespace llvm;
> +
> +namespace llvm {
> +class MCOperandInfo;
> +
> +typedef struct {
> +  unsigned Error, Warning, ShuffleError;
> +  unsigned Register;
> +} ErrInfo_T;
> +
> +class HexagonMCErrInfo {
> +public:
> +  enum {
> +    CHECK_SUCCESS         = 0,
> +    // Errors.
> +    CHECK_ERROR_BRANCHES  = 0x00001,
> +    CHECK_ERROR_NEWP      = 0x00002,
> +    CHECK_ERROR_NEWV      = 0x00004,
> +    CHECK_ERROR_REGISTERS = 0x00008,
> +    CHECK_ERROR_READONLY  = 0x00010,
> +    CHECK_ERROR_LOOP      = 0x00020,
> +    CHECK_ERROR_ENDLOOP   = 0x00040,
> +    CHECK_ERROR_SOLO      = 0x00080,
> +    CHECK_ERROR_SHUFFLE   = 0x00100,
> +    CHECK_ERROR_NOSLOTS   = 0x00200,
> +    CHECK_ERROR_UNKNOWN   = 0x00400,
> +    // Warnings.
> +    CHECK_WARN_CURRENT    = 0x10000,
> +    CHECK_WARN_TEMPORARY  = 0x20000
> +  };
> +  ErrInfo_T s;
> +
> +  void reset() {
> +    s.Error = CHECK_SUCCESS;
> +    s.Warning = CHECK_SUCCESS;
> +    s.ShuffleError = HexagonShuffler::SHUFFLE_SUCCESS;
> +    s.Register = Hexagon::NoRegister;
> +  };
> +  HexagonMCErrInfo() {
> +    reset();
> +  };
> +
> +  void setError(unsigned e, unsigned r = Hexagon::NoRegister)
> +    { s.Error = e; s.Register = r; };
> +  void setWarning(unsigned w, unsigned r = Hexagon::NoRegister)
> +    { s.Warning = w; s.Register = r; };
> +  void setShuffleError(unsigned e) { s.ShuffleError = e; };
> +};
> +
> +/// Check for a valid bundle.
> +class HexagonMCChecker {
> +  /// Insn bundle.
> +  MCInst& MCB;
> +  MCInst& MCBDX;
> +  const MCRegisterInfo& RI;
> +  MCInstrInfo const &MCII;
> +  MCSubtargetInfo const &STI;
> +  bool bLoadErrInfo;
> +
> +  /// Set of definitions: register #, if predicated, if predicated true.
> +  typedef std::pair<unsigned, bool> PredSense;
> +  static const PredSense Unconditional;
> +  typedef std::multiset<PredSense> PredSet;
> +  typedef std::multiset<PredSense>::iterator PredSetIterator;
> +
> +  typedef llvm::DenseMap<unsigned, PredSet>::iterator DefsIterator;
> +  llvm::DenseMap<unsigned, PredSet> Defs;
> +
> +  /// Information about how a new-value register is defined or used:
> +  ///   PredReg = predicate register, 0 if use/def not predicated,
> +  ///   Cond    = true/false for if(PredReg)/if(!PredReg) respectively,
> +  ///   IsFloat = true if definition produces a floating point value
> +  ///             (not valid for uses),
> +  ///   IsNVJ   = true if the use is a new-value branch (not valid for
> +  ///             definitions).
> +  struct NewSense {
> +    unsigned PredReg;
> +    bool IsFloat, IsNVJ, Cond;
> +    // The special-case "constructors":
> +    static NewSense Jmp(bool isNVJ) {
> +      NewSense NS = { /*PredReg=*/ 0, /*IsFloat=*/ false, /*IsNVJ=*/
> isNVJ,
> +                      /*Cond=*/ false };
> +      return NS;
> +    }
> +    static NewSense Use(unsigned PR, bool True) {
> +      NewSense NS = { /*PredReg=*/ PR, /*IsFloat=*/ false, /*IsNVJ=*/
> false,
> +                      /*Cond=*/ True };
> +      return NS;
> +    }
> +    static NewSense Def(unsigned PR, bool True, bool Float) {
> +      NewSense NS = { /*PredReg=*/ PR, /*IsFloat=*/ Float, /*IsNVJ=*/
> false,
> +                      /*Cond=*/ True };
> +      return NS;
> +    }
> +  };
> +  /// Set of definitions that produce new register:
> +  typedef llvm::SmallVector<NewSense,2> NewSenseList;
> +  typedef llvm::DenseMap<unsigned, NewSenseList>::iterator
> NewDefsIterator;
> +  llvm::DenseMap<unsigned, NewSenseList> NewDefs;
> +
> +  /// Set of weak definitions whose clashes should be enforced
> selectively.
> +  typedef std::set<unsigned>::iterator SoftDefsIterator;
> +  std::set<unsigned> SoftDefs;
> +
> +  /// Set of current definitions committed to the register file.
> +  typedef std::set<unsigned>::iterator CurDefsIterator;
> +  std::set<unsigned> CurDefs;
> +
> +  /// Set of temporary definitions not committed to the register file.
> +  typedef std::set<unsigned>::iterator TmpDefsIterator;
> +  std::set<unsigned> TmpDefs;
> +
> +  /// Set of new predicates used.
> +  typedef std::set<unsigned>::iterator NewPredsIterator;
> +  std::set<unsigned> NewPreds;
> +
> +  /// Set of predicates defined late.
> +  typedef std::multiset<unsigned>::iterator LatePredsIterator;
> +  std::multiset<unsigned> LatePreds;
> +
> +  /// Set of uses.
> +  typedef std::set<unsigned>::iterator UsesIterator;
> +  std::set<unsigned> Uses;
> +
> +  /// Set of new values used: new register, if new-value jump.
> +  typedef llvm::DenseMap<unsigned, NewSense>::iterator NewUsesIterator;
> +  llvm::DenseMap<unsigned, NewSense> NewUses;
> +
> +  /// Pre-defined set of read-only registers.
> +  typedef std::set<unsigned>::iterator ReadOnlyIterator;
> +  std::set<unsigned> ReadOnly;
> +
> +  std::queue<ErrInfo_T> ErrInfoQ;
> +  HexagonMCErrInfo CrntErrInfo;
> +
> +  void getErrInfo() {
> +    if (bLoadErrInfo == true) {
> +      if (ErrInfoQ.empty()) {
> +        CrntErrInfo.reset();
> +      } else {
> +        CrntErrInfo.s = ErrInfoQ.front();
> +        ErrInfoQ.pop();
> +      }
> +    }
> +    bLoadErrInfo = false;
> +  }
> +
> +  void init();
> +  void init(MCInst const&);
> +
> +  // Checks performed.
> +  bool checkBranches();
> +  bool checkPredicates();
> +  bool checkNewValues();
> +  bool checkRegisters();
> +  bool checkSolo();
> +  bool checkShuffle();
> +  bool checkSlots();
> +
> +  static void compoundRegisterMap(unsigned&);
> +
> +  bool isPredicateRegister(unsigned R) const {
> +    return (Hexagon::P0 == R || Hexagon::P1 == R ||
> +            Hexagon::P2 == R || Hexagon::P3 == R);
> +  };
> +  bool isLoopRegister(unsigned R) const {
> +    return (Hexagon::SA0 == R || Hexagon::LC0 == R ||
> +            Hexagon::SA1 == R || Hexagon::LC1 == R);
> +  };
> +
> +  bool hasValidNewValueDef(const NewSense &Use,
> +                           const NewSenseList &Defs) const;
> +
> +  public:
> +  explicit HexagonMCChecker(MCInstrInfo const &MCII, MCSubtargetInfo
> const &STI, MCInst& mcb, MCInst &mcbdx,
> +                            const MCRegisterInfo& ri);
> +
> +  bool check();
> +
> +  /// add a new error/warning
> +  void addErrInfo(HexagonMCErrInfo &err) { ErrInfoQ.push(err.s); };
> +
> +  /// Return the error code for the last operation in the insn bundle.
> +  unsigned getError() { getErrInfo(); return CrntErrInfo.s.Error; };
> +  unsigned getWarning() { getErrInfo(); return CrntErrInfo.s.Warning; };
> +  unsigned getShuffleError() { getErrInfo(); return
> CrntErrInfo.s.ShuffleError; };
> +  unsigned getErrRegister() { getErrInfo(); return
> CrntErrInfo.s.Register; };
> +  bool getNextErrInfo() {
> +    bLoadErrInfo = true;
> +    return (ErrInfoQ.empty()) ? false : (getErrInfo(), true);
> +  }
> +};
> +
> +}
> +
> +#endif // HEXAGONMCCHECKER_H
>
> Modified:
> llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp
> (original)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp Sun
> Nov  8 22:07:48 2015
> @@ -195,15 +195,13 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      // Special case this one from Group L2.
>      // Rd = memw(r29+#u5:2)
>      if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
> -      if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg
> &&
> -          MCI.getOperand(2).isImm() &&
> -          isShiftedUInt<5, 2>(MCI.getOperand(2).getImm())) {
> +      if (HexagonMCInstrInfo::isIntReg(SrcReg) &&
> +          Hexagon::R29 == SrcReg && inRange<5, 2>(MCI, 2)) {
>          return HexagonII::HSIG_L2;
>        }
>        // Rd = memw(Rs+#u4:2)
>        if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
> -          (MCI.getOperand(2).isImm() &&
> -           isShiftedUInt<4, 2>(MCI.getOperand(2).getImm()))) {
> +          inRange<4, 2>(MCI, 2)) {
>          return HexagonII::HSIG_L1;
>        }
>      }
> @@ -214,7 +212,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      SrcReg = MCI.getOperand(1).getReg();
>      if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
>          HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
> -        MCI.getOperand(2).isImm() &&
> isUInt<4>(MCI.getOperand(2).getImm())) {
> +        inRange<4>(MCI, 2)) {
>        return HexagonII::HSIG_L1;
>      }
>      break;
> @@ -235,8 +233,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      SrcReg = MCI.getOperand(1).getReg();
>      if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
>          HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
> -        MCI.getOperand(2).isImm() &&
> -        isShiftedUInt<3, 1>(MCI.getOperand(2).getImm())) {
> +        inRange<3, 1>(MCI, 2)) {
>        return HexagonII::HSIG_L2;
>      }
>      break;
> @@ -246,7 +243,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      SrcReg = MCI.getOperand(1).getReg();
>      if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
>          HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
> -        MCI.getOperand(2).isImm() &&
> isUInt<3>(MCI.getOperand(2).getImm())) {
> +        inRange<3>(MCI, 2)) {
>        return HexagonII::HSIG_L2;
>      }
>      break;
> @@ -256,8 +253,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      SrcReg = MCI.getOperand(1).getReg();
>      if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
>          HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg &&
> -        MCI.getOperand(2).isImm() &&
> -        isShiftedUInt<5, 3>(MCI.getOperand(2).getImm())) {
> +        inRange<5, 3>(MCI, 2)) {
>        return HexagonII::HSIG_L2;
>      }
>      break;
> @@ -326,15 +322,13 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      Src2Reg = MCI.getOperand(2).getReg();
>      if (HexagonMCInstrInfo::isIntReg(Src1Reg) &&
>          HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
> -        Hexagon::R29 == Src1Reg && MCI.getOperand(1).isImm() &&
> -        isShiftedUInt<5, 2>(MCI.getOperand(1).getImm())) {
> +        Hexagon::R29 == Src1Reg && inRange<5, 2>(MCI, 1)) {
>        return HexagonII::HSIG_S2;
>      }
>      // memw(Rs+#u4:2) = Rt
>      if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
>          HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
> -        MCI.getOperand(1).isImm() &&
> -        isShiftedUInt<4, 2>(MCI.getOperand(1).getImm())) {
> +        inRange<4, 2>(MCI, 1)) {
>        return HexagonII::HSIG_S1;
>      }
>      break;
> @@ -344,7 +338,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      Src2Reg = MCI.getOperand(2).getReg();
>      if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
>          HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
> -        MCI.getOperand(1).isImm() &&
> isUInt<4>(MCI.getOperand(1).getImm())) {
> +        inRange<4>(MCI, 1)) {
>        return HexagonII::HSIG_S1;
>      }
>      break;
> @@ -363,8 +357,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      Src2Reg = MCI.getOperand(2).getReg();
>      if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
>          HexagonMCInstrInfo::isIntRegForSubInst(Src2Reg) &&
> -        MCI.getOperand(1).isImm() &&
> -        isShiftedUInt<3, 1>(MCI.getOperand(1).getImm())) {
> +        inRange<3, 1>(MCI, 1)) {
>        return HexagonII::HSIG_S2;
>      }
>      break;
> @@ -374,8 +367,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      Src2Reg = MCI.getOperand(2).getReg();
>      if (HexagonMCInstrInfo::isDblRegForSubInst(Src2Reg) &&
>          HexagonMCInstrInfo::isIntReg(Src1Reg) && Hexagon::R29 == Src1Reg
> &&
> -        MCI.getOperand(1).isImm() &&
> -        isShiftedInt<6, 3>(MCI.getOperand(1).getImm())) {
> +        inSRange<6, 3>(MCI, 1)) {
>        return HexagonII::HSIG_S2;
>      }
>      break;
> @@ -383,9 +375,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      // memw(Rs+#u4:2) = #U1
>      Src1Reg = MCI.getOperand(0).getReg();
>      if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
> -        MCI.getOperand(1).isImm() &&
> -        isShiftedUInt<4, 2>(MCI.getOperand(1).getImm()) &&
> -        MCI.getOperand(2).isImm() &&
> isUInt<1>(MCI.getOperand(2).getImm())) {
> +        inRange<4, 2>(MCI, 1) && inRange<1>(MCI, 2)) {
>        return HexagonII::HSIG_S2;
>      }
>      break;
> @@ -393,16 +383,13 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      // memb(Rs+#u4) = #U1
>      Src1Reg = MCI.getOperand(0).getReg();
>      if (HexagonMCInstrInfo::isIntRegForSubInst(Src1Reg) &&
> -        MCI.getOperand(1).isImm() &&
> isUInt<4>(MCI.getOperand(1).getImm()) &&
> -        MCI.getOperand(2).isImm() &&
> isUInt<1>(MCI.getOperand(2).getImm())) {
> +        inRange<4>(MCI, 1) && inRange<1>(MCI, 2)) {
>        return HexagonII::HSIG_S2;
>      }
>      break;
>    case Hexagon::S2_allocframe:
> -    if (MCI.getOperand(0).isImm() &&
> -        isShiftedUInt<5, 3>(MCI.getOperand(0).getImm())) {
> +    if (inRange<5, 3>(MCI, 0))
>        return HexagonII::HSIG_S2;
> -    }
>      break;
>    //
>    // Group A:
> @@ -428,8 +415,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
>        // Rd = add(r29,#u6:2)
>        if (HexagonMCInstrInfo::isIntReg(SrcReg) && Hexagon::R29 == SrcReg
> &&
> -          MCI.getOperand(2).isImm() &&
> -          isShiftedUInt<6, 2>(MCI.getOperand(2).getImm())) {
> +          inRange<6, 2>(MCI, 2)) {
>          return HexagonII::HSIG_A;
>        }
>        // Rx = add(Rx,#s7)
> @@ -439,8 +425,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>        // Rd = add(Rs,#1)
>        // Rd = add(Rs,#-1)
>        if (HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
> -          MCI.getOperand(2).isImm() && ((MCI.getOperand(2).getImm() == 1)
> ||
> -                                        (MCI.getOperand(2).getImm() ==
> -1))) {
> +          (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == -1)) {
>          return HexagonII::HSIG_A;
>        }
>      }
> @@ -460,8 +445,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      SrcReg = MCI.getOperand(1).getReg();
>      if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
>          HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
> -        MCI.getOperand(2).isImm() && ((MCI.getOperand(2).getImm() == 1) ||
> -                                      (MCI.getOperand(2).getImm() ==
> 255))) {
> +        (minConstant(MCI, 2) == 1 || minConstant(MCI, 2) == 255)) {
>        return HexagonII::HSIG_A;
>      }
>      break;
> @@ -491,8 +475,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      DstReg = MCI.getOperand(0).getReg();  // Rd
>      PredReg = MCI.getOperand(1).getReg(); // P0
>      if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg) &&
> -        Hexagon::P0 == PredReg && MCI.getOperand(2).isImm() &&
> -        MCI.getOperand(2).getImm() == 0) {
> +        Hexagon::P0 == PredReg && minConstant(MCI, 2) == 0) {
>        return HexagonII::HSIG_A;
>      }
>      break;
> @@ -502,7 +485,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      SrcReg = MCI.getOperand(1).getReg();
>      if (Hexagon::P0 == DstReg &&
>          HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
> -        MCI.getOperand(2).isImm() &&
> isUInt<2>(MCI.getOperand(2).getImm())) {
> +        inRange<2>(MCI, 2)) {
>        return HexagonII::HSIG_A;
>      }
>      break;
> @@ -511,10 +494,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      // Rdd = combine(#u2,#U2)
>      DstReg = MCI.getOperand(0).getReg();
>      if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
> -        // TODO: Handle Globals/Symbols
> -        (MCI.getOperand(1).isImm() &&
> isUInt<2>(MCI.getOperand(1).getImm())) &&
> -        ((MCI.getOperand(2).isImm() &&
> -          isUInt<2>(MCI.getOperand(2).getImm())))) {
> +        inRange<2>(MCI, 1) && inRange<2>(MCI, 2)) {
>        return HexagonII::HSIG_A;
>      }
>      break;
> @@ -524,7 +504,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      SrcReg = MCI.getOperand(1).getReg();
>      if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
>          HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
> -        (MCI.getOperand(2).isImm() && MCI.getOperand(2).getImm() == 0)) {
> +        minConstant(MCI, 2) == 0) {
>        return HexagonII::HSIG_A;
>      }
>      break;
> @@ -534,7 +514,7 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>      SrcReg = MCI.getOperand(2).getReg();
>      if (HexagonMCInstrInfo::isDblRegForSubInst(DstReg) &&
>          HexagonMCInstrInfo::isIntRegForSubInst(SrcReg) &&
> -        (MCI.getOperand(1).isImm() && MCI.getOperand(1).getImm() == 0)) {
> +        minConstant(MCI, 1) == 0) {
>        return HexagonII::HSIG_A;
>      }
>      break;
> @@ -556,19 +536,17 @@ unsigned HexagonMCInstrInfo::getDuplexCa
>  }
>
>  bool HexagonMCInstrInfo::subInstWouldBeExtended(MCInst const
> &potentialDuplex) {
> -
>    unsigned DstReg, SrcReg;
> -
>    switch (potentialDuplex.getOpcode()) {
>    case Hexagon::A2_addi:
>      // testing for case of: Rx = add(Rx,#s7)
>      DstReg = potentialDuplex.getOperand(0).getReg();
>      SrcReg = potentialDuplex.getOperand(1).getReg();
>      if (DstReg == SrcReg &&
> HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
> -      if (potentialDuplex.getOperand(2).isExpr())
> +      int64_t Value;
> +      if
> (!potentialDuplex.getOperand(2).getExpr()->evaluateAsAbsolute(Value))
>          return true;
> -      if (potentialDuplex.getOperand(2).isImm() &&
> -          !(isShiftedInt<7, 0>(potentialDuplex.getOperand(2).getImm())))
> +      if (!isShiftedInt<7, 0>(Value))
>          return true;
>      }
>      break;
> @@ -576,15 +554,14 @@ bool HexagonMCInstrInfo::subInstWouldBeE
>      DstReg = potentialDuplex.getOperand(0).getReg();
>
>      if (HexagonMCInstrInfo::isIntRegForSubInst(DstReg)) {
> -      if (potentialDuplex.getOperand(1).isExpr())
> +      int64_t Value;
> +      if
> (!potentialDuplex.getOperand(1).getExpr()->evaluateAsAbsolute(Value))
>          return true;
>        // Check for case of Rd = #-1.
> -      if (potentialDuplex.getOperand(1).isImm() &&
> -          (potentialDuplex.getOperand(1).getImm() == -1))
> +      if (Value == -1)
>          return false;
>        // Check for case of Rd = #u6.
> -      if (potentialDuplex.getOperand(1).isImm() &&
> -          !isShiftedUInt<6, 0>(potentialDuplex.getOperand(1).getImm()))
> +      if (!isShiftedUInt<6, 0>(Value))
>          return true;
>      }
>      break;
> @@ -712,19 +689,23 @@ inline static void addOps(MCInst &subIns
>
>  MCInst HexagonMCInstrInfo::deriveSubInst(MCInst const &Inst) {
>    MCInst Result;
> +  bool Absolute;
> +  int64_t Value;
>    switch (Inst.getOpcode()) {
>    default:
>      // dbgs() << "opcode: "<< Inst->getOpcode() << "\n";
>      llvm_unreachable("Unimplemented subinstruction \n");
>      break;
>    case Hexagon::A2_addi:
> -    if (Inst.getOperand(2).isImm() && Inst.getOperand(2).getImm() == 1) {
> +    Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
> +    assert(Absolute);(void)Absolute;
> +    if (Value == 1) {
>        Result.setOpcode(Hexagon::V4_SA1_inc);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 1);
>        break;
>      } //  1,2 SUBInst $Rd = add($Rs, #1)
> -    else if (Inst.getOperand(2).isImm() && Inst.getOperand(2).getImm() ==
> -1) {
> +    else if (Value == -1) {
>        Result.setOpcode(Hexagon::V4_SA1_dec);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 1);
> @@ -754,7 +735,7 @@ MCInst HexagonMCInstrInfo::deriveSubInst
>      addOps(Result, Inst, 0);
>      break; //    1 SUBInst allocframe(#$u5_3)
>    case Hexagon::A2_andir:
> -    if (Inst.getOperand(2).getImm() == 255) {
> +    if (minConstant(Inst, 2) == 255) {
>        Result.setOpcode(Hexagon::V4_SA1_zxtb);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 1);
> @@ -772,26 +753,27 @@ MCInst HexagonMCInstrInfo::deriveSubInst
>      break; //    2,3 SUBInst p0 = cmp.eq($Rs, #$u2)
>    case Hexagon::A4_combineii:
>    case Hexagon::A2_combineii:
> -    if (Inst.getOperand(1).getImm() == 1) {
> +    Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
> +    assert(Absolute);(void)Absolute;
> +    if (Value == 1) {
>        Result.setOpcode(Hexagon::V4_SA1_combine1i);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 2);
>        break; //  1,3 SUBInst $Rdd = combine(#1, #$u2)
>      }
> -
> -    if (Inst.getOperand(1).getImm() == 3) {
> +    if (Value == 3) {
>        Result.setOpcode(Hexagon::V4_SA1_combine3i);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 2);
>        break; //  1,3 SUBInst $Rdd = combine(#3, #$u2)
>      }
> -    if (Inst.getOperand(1).getImm() == 0) {
> +    if (Value == 0) {
>        Result.setOpcode(Hexagon::V4_SA1_combine0i);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 2);
>        break; //  1,3 SUBInst $Rdd = combine(#0, #$u2)
>      }
> -    if (Inst.getOperand(1).getImm() == 2) {
> +    if (Value == 2) {
>        Result.setOpcode(Hexagon::V4_SA1_combine2i);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 2);
> @@ -894,12 +876,14 @@ MCInst HexagonMCInstrInfo::deriveSubInst
>        break; //    1,2,3 SUBInst $Rd = memw($Rs + #$u4_2)
>      }
>    case Hexagon::S4_storeirb_io:
> -    if (Inst.getOperand(2).getImm() == 0) {
> +    Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
> +    assert(Absolute);(void)Absolute;
> +    if (Value == 0) {
>        Result.setOpcode(Hexagon::V4_SS2_storebi0);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 1);
>        break; //    1,2 SUBInst memb($Rs + #$u4_0)=#0
> -    } else if (Inst.getOperand(2).getImm() == 1) {
> +    } else if (Value == 1) {
>        Result.setOpcode(Hexagon::V4_SS2_storebi1);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 1);
> @@ -923,12 +907,14 @@ MCInst HexagonMCInstrInfo::deriveSubInst
>      addOps(Result, Inst, 2);
>      break; //    1,2,3 SUBInst memb($Rs + #$u4_0) = $Rt
>    case Hexagon::S4_storeiri_io:
> -    if (Inst.getOperand(2).getImm() == 0) {
> +    Absolute = Inst.getOperand(2).getExpr()->evaluateAsAbsolute(Value);
> +    assert(Absolute);(void)Absolute;
> +    if (Value == 0) {
>        Result.setOpcode(Hexagon::V4_SS2_storewi0);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 1);
>        break; //  3 1,2 SUBInst memw($Rs + #$u4_2)=#0
> -    } else if (Inst.getOperand(2).getImm() == 1) {
> +    } else if (Value == 1) {
>        Result.setOpcode(Hexagon::V4_SS2_storewi1);
>        addOps(Result, Inst, 0);
>        addOps(Result, Inst, 1);
> @@ -983,7 +969,8 @@ MCInst HexagonMCInstrInfo::deriveSubInst
>      addOps(Result, Inst, 0);
>      break; //  2 SUBInst if (p0) $Rd = #0
>    case Hexagon::A2_tfrsi:
> -    if (Inst.getOperand(1).isImm() && Inst.getOperand(1).getImm() == -1) {
> +    Absolute = Inst.getOperand(1).getExpr()->evaluateAsAbsolute(Value);
> +    if (Absolute && Value == -1) {
>        Result.setOpcode(Hexagon::V4_SA1_setin1);
>        addOps(Result, Inst, 0);
>        break; //  2 1 SUBInst $Rd = #-1
> @@ -1044,6 +1031,8 @@ HexagonMCInstrInfo::getDuplexPossibiltie
>                       << "\n");
>          bisReversable = false;
>        }
> +      if (HexagonMCInstrInfo::isMemReorderDisabled(MCB)) // }:mem_noshuf
> +        bisReversable = false;
>
>        // Try in order.
>        if (isOrderedDuplexPair(
>
> Added: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp (added)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.cpp Sun Nov
> 8 22:07:48 2015
> @@ -0,0 +1,49 @@
> +//===-- HexagonMCExpr.cpp - Hexagon specific MC expression classes
> +//----------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "HexagonMCExpr.h"
> +#include "llvm/MC/MCContext.h"
> +#include "llvm/MC/MCValue.h"
> +#include "llvm/Support/raw_ostream.h"
> +
> +using namespace llvm;
> +
> +#define DEBUG_TYPE "hexagon-mcexpr"
> +
> +HexagonNoExtendOperand *HexagonNoExtendOperand::Create(MCExpr const *Expr,
> +                                                       MCContext &Ctx) {
> +  return new (Ctx) HexagonNoExtendOperand(Expr);
> +}
> +
> +bool HexagonNoExtendOperand::evaluateAsRelocatableImpl(
> +    MCValue &Res, MCAsmLayout const *Layout, MCFixup const *Fixup) const {
> +  return Expr->evaluateAsRelocatable(Res, Layout, Fixup);
> +}
> +
> +void HexagonNoExtendOperand::visitUsedExpr(MCStreamer &Streamer) const {}
> +
> +MCFragment *llvm::HexagonNoExtendOperand::findAssociatedFragment() const {
> +  return Expr->findAssociatedFragment();
> +}
> +
> +void HexagonNoExtendOperand::fixELFSymbolsInTLSFixups(MCAssembler &Asm)
> const {}
> +
> +MCExpr const *HexagonNoExtendOperand::getExpr() const { return Expr; }
> +
> +bool HexagonNoExtendOperand::classof(MCExpr const *E) {
> +  return E->getKind() == MCExpr::Target;
> +}
> +
> +HexagonNoExtendOperand::HexagonNoExtendOperand(MCExpr const *Expr)
> +    : Expr(Expr) {}
> +
> +void HexagonNoExtendOperand::printImpl(raw_ostream &OS, const MCAsmInfo
> *MAI) const {
> +  Expr->print(OS, MAI);
> +}
>
> Added: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h (added)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCExpr.h Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,35 @@
> +//==- HexagonMCExpr.h - Hexagon specific MC expression classes --*- C++
> -*-===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONMCEXPR_H
> +#define LLVM_LIB_TARGET_HEXAGON_HEXAGONMCEXPR_H
> +
> +#include "llvm/MC/MCExpr.h"
> +
> +namespace llvm {
> +class MCInst;
> +class HexagonNoExtendOperand : public MCTargetExpr {
> +public:
> +  static HexagonNoExtendOperand *Create(MCExpr const *Expr, MCContext
> &Ctx);
> +  void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
> +  bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
> +                                 const MCFixup *Fixup) const override;
> +  void visitUsedExpr(MCStreamer &Streamer) const override;
> +  MCFragment *findAssociatedFragment() const override;
> +  void fixELFSymbolsInTLSFixups(MCAssembler &Asm) const override;
> +  static bool classof(MCExpr const *E);
> +  MCExpr const *getExpr() const;
> +
> +private:
> +  HexagonNoExtendOperand(MCExpr const *Expr);
> +  MCExpr const *Expr;
> +};
> +} // end namespace llvm
> +
> +#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONMCEXPR_H
>
> Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp
> (original)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.cpp Sun
> Nov  8 22:07:48 2015
> @@ -15,12 +15,32 @@
>
>  #include "Hexagon.h"
>  #include "HexagonBaseInfo.h"
> +#include "HexagonMCChecker.h"
>
>  #include "llvm/MC/MCContext.h"
> +#include "llvm/MC/MCExpr.h"
>  #include "llvm/MC/MCInstrInfo.h"
>  #include "llvm/MC/MCSubtargetInfo.h"
>
>  namespace llvm {
> +void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value,
> +                                     MCContext &Context) {
> +  MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value,
> Context)));
> +}
> +
> +void HexagonMCInstrInfo::addConstExtender(MCInstrInfo const &MCII, MCInst
> &MCB,
> +                                          MCInst const &MCI) {
> +  assert(HexagonMCInstrInfo::isBundle(MCB));
> +  MCOperand const &exOp =
> +      MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
> +
> +  // Create the extender.
> +  MCInst *XMCI =
> +      new MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp));
> +
> +  MCB.addOperand(MCOperand::createInst(XMCI));
> +}
> +
>  iterator_range<MCInst::const_iterator>
>  HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) {
>    assert(isBundle(MCI));
> @@ -35,6 +55,38 @@ size_t HexagonMCInstrInfo::bundleSize(MC
>      return (1);
>  }
>
> +bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII,
> +                                            MCSubtargetInfo const &STI,
> +                                            MCContext &Context, MCInst
> &MCB,
> +                                            HexagonMCChecker *Check) {
> +  // Examine the packet and convert pairs of instructions to compound
> +  // instructions when possible.
> +  if (!HexagonDisableCompound)
> +    HexagonMCInstrInfo::tryCompound(MCII, Context, MCB);
> +  // Check the bundle for errors.
> +  bool CheckOk = Check ? Check->check() : true;
> +  if (!CheckOk)
> +    return false;
> +  HexagonMCShuffle(MCII, STI, MCB);
> +  // Examine the packet and convert pairs of instructions to duplex
> +  // instructions when possible.
> +  MCInst InstBundlePreDuplex = MCInst(MCB);
> +  if (!HexagonDisableDuplex) {
> +    SmallVector<DuplexCandidate, 8> possibleDuplexes;
> +    possibleDuplexes = HexagonMCInstrInfo::getDuplexPossibilties(MCII,
> MCB);
> +    HexagonMCShuffle(MCII, STI, Context, MCB, possibleDuplexes);
> +  }
> +  // Examines packet and pad the packet, if needed, when an
> +  // end-loop is in the bundle.
> +  HexagonMCInstrInfo::padEndloop(MCB);
> +  // 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)
> +    return false;
> +  HexagonMCShuffle(MCII, STI, MCB);
> +  return true;
> +}
> +
>  void HexagonMCInstrInfo::clampExtended(MCInstrInfo const &MCII, MCInst
> &MCI) {
>    assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
>           HexagonMCInstrInfo::isExtended(MCII, MCI));
> @@ -64,6 +116,27 @@ MCInst *HexagonMCInstrInfo::deriveDuplex
>    return duplexInst;
>  }
>
> +MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII,
> +                                          MCInst const &Inst,
> +                                          MCOperand const &MO) {
> +  assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) ||
> +         HexagonMCInstrInfo::isExtended(MCII, Inst));
> +
> +  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst);
> +  MCInst XMI;
> +  XMI.setOpcode((Desc.isBranch() || Desc.isCall() ||
> +                 HexagonMCInstrInfo::getType(MCII, Inst) ==
> HexagonII::TypeCR)
> +                    ? Hexagon::A4_ext_b
> +                    : Hexagon::A4_ext);
> +  if (MO.isImm())
> +    XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f)));
> +  else if (MO.isExpr())
> +    XMI.addOperand(MCOperand::createExpr(MO.getExpr()));
> +  else
> +    llvm_unreachable("invalid extendable operand");
> +  return XMI;
> +}
> +
>  MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB,
>                                                     size_t Index) {
>    assert(Index <= bundleSize(MCB));
> @@ -76,6 +149,12 @@ MCInst const *HexagonMCInstrInfo::extend
>    return nullptr;
>  }
>
> +void HexagonMCInstrInfo::extendIfNeeded(MCInstrInfo const &MCII, MCInst
> &MCB,
> +                                        MCInst const &MCI, bool
> MustExtend) {
> +  if (isConstExtended(MCII, MCI) || MustExtend)
> +    addConstExtender(MCII, MCB, MCI);
> +}
> +
>  HexagonII::MemAccessSize
>  HexagonMCInstrInfo::getAccessSize(MCInstrInfo const &MCII, MCInst const
> &MCI) {
>    const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
> @@ -186,6 +265,25 @@ MCOperand const &HexagonMCInstrInfo::get
>    return (MCO);
>  }
>
> +/// Return the new value or the newly produced value.
> +unsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII,
> +                                                  MCInst const &MCI) {
> +  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
> +  return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2);
> +}
> +
> +MCOperand const &
> +HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII,
> +                                        MCInst const &MCI) {
> +  unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI);
> +  MCOperand const &MCO = MCI.getOperand(O);
> +
> +  assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
> +          HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) &&
> +         MCO.isReg());
> +  return (MCO);
> +}
> +
>  int HexagonMCInstrInfo::getSubTarget(MCInstrInfo const &MCII,
>                                       MCInst const &MCI) {
>    const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
> @@ -242,6 +340,13 @@ bool HexagonMCInstrInfo::hasNewValue(MCI
>    return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);
>  }
>
> +/// Return whether the insn produces a second value.
> +bool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII,
> +                                      MCInst const &MCI) {
> +  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
> +  return ((F >> HexagonII::hasNewValuePos2) &
> HexagonII::hasNewValueMask2);
> +}
> +
>  MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t
> Index) {
>    assert(isBundle(MCB));
>    assert(Index < HEXAGON_PACKET_SIZE);
> @@ -261,6 +366,11 @@ bool HexagonMCInstrInfo::isCanon(MCInstr
>            HexagonMCInstrInfo::getType(MCII, MCI) !=
> HexagonII::TypeENDLOOP);
>  }
>
> +bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII,
> +                                    MCInst const &MCI) {
> +  return (getType(MCII, MCI) == HexagonII::TypeCOMPOUND);
> +}
> +
>  bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) {
>    return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) ||
>            (Reg >= Hexagon::D8 && Reg <= Hexagon::D11));
> @@ -282,14 +392,21 @@ bool HexagonMCInstrInfo::isConstExtended
>                                           MCInst const &MCI) {
>    if (HexagonMCInstrInfo::isExtended(MCII, MCI))
>      return true;
> -
> -  if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))
> +  // Branch insns are handled as necessary by relaxation.
> +  if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) ||
> +      (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCOMPOUND
> &&
> +       HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) ||
> +      (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNV &&
> +       HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()))
> +    return false;
> +  // Otherwise loop instructions and other CR insts are handled by
> relaxation
> +  else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR)
> &&
> +           (MCI.getOpcode() != Hexagon::C4_addipc))
> +    return false;
> +  else if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))
>      return false;
>
> -  short ExtOpNum = HexagonMCInstrInfo::getCExtOpNum(MCII, MCI);
> -  int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
> -  int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
> -  MCOperand const &MO = MCI.getOperand(ExtOpNum);
> +  MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII,
> MCI);
>
>    // We could be using an instruction with an extendable immediate and
> shoehorn
>    // a global address into it. If it is a global address it will be
> constant
> @@ -297,15 +414,13 @@ bool HexagonMCInstrInfo::isConstExtended
>    // We currently only handle isGlobal() because it is the only kind of
>    // object we are going to end up with here for now.
>    // In the future we probably should add isSymbol(), etc.
> -  if (MO.isExpr())
> +  assert(!MO.isImm());
> +  int64_t Value;
> +  if (!MO.getExpr()->evaluateAsAbsolute(Value))
>      return true;
> -
> -  // If the extendable operand is not 'Immediate' type, the instruction
> should
> -  // have 'isExtended' flag set.
> -  assert(MO.isImm() && "Extendable operand must be Immediate type");
> -
> -  int ImmValue = MO.getImm();
> -  return (ImmValue < MinValue || ImmValue > MaxValue);
> +  int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
> +  int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
> +  return (MinValue > Value || Value > MaxValue);
>  }
>
>  bool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII,
> @@ -374,6 +489,19 @@ bool HexagonMCInstrInfo::isPredicated(MC
>    return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
>  }
>
> +bool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII,
> +                                         MCInst const &MCI) {
> +  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
> +  return (F >> HexagonII::PredicateLatePos &
> HexagonII::PredicateLateMask);
> +}
> +
> +/// Return whether the insn is newly predicated.
> +bool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII,
> +                                         MCInst const &MCI) {
> +  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
> +  return ((F >> HexagonII::PredicatedNewPos) &
> HexagonII::PredicatedNewMask);
> +}
> +
>  bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII,
>                                            MCInst const &MCI) {
>    const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
> @@ -394,6 +522,18 @@ bool HexagonMCInstrInfo::isSolo(MCInstrI
>    return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask);
>  }
>
> +bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) {
> +  assert(isBundle(MCI));
> +  auto Flags = MCI.getOperand(0).getImm();
> +  return (Flags & memReorderDisabledMask) != 0;
> +}
> +
> +bool HexagonMCInstrInfo::isMemStoreReorderEnabled(MCInst const &MCI) {
> +  assert(isBundle(MCI));
> +  auto Flags = MCI.getOperand(0).getImm();
> +  return (Flags & memStoreReorderEnabledMask) != 0;
> +}
> +
>  bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const
> &MCI) {
>    const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
>    return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask);
> @@ -405,6 +545,27 @@ bool HexagonMCInstrInfo::isSoloAin1(MCIn
>    return ((F >> HexagonII::SoloAin1Pos) & HexagonII::SoloAin1Mask);
>  }
>
> +bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const
> &MCI) {
> +  if ((getType(MCII, MCI) <= HexagonII::TypeCVI_LAST) &&
> +      (getType(MCII, MCI) >= HexagonII::TypeCVI_FIRST))
> +    return true;
> +  return false;
> +}
> +
> +int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) {
> +  auto Sentinal =
> static_cast<int64_t>(std::numeric_limits<uint32_t>::max())
> +                  << 8;
> +  if (MCI.size() <= Index)
> +    return Sentinal;
> +  MCOperand const &MCO = MCI.getOperand(Index);
> +  if (!MCO.isExpr())
> +    return Sentinal;
> +  int64_t Value;
> +  if (!MCO.getExpr()->evaluateAsAbsolute(Value))
> +    return Sentinal;
> +  return Value;
> +}
> +
>  void HexagonMCInstrInfo::padEndloop(MCInst &MCB) {
>    MCInst Nop;
>    Nop.setOpcode(Hexagon::A2_nop);
> @@ -456,6 +617,20 @@ void HexagonMCInstrInfo::setInnerLoop(MC
>    Operand.setImm(Operand.getImm() | innerLoopMask);
>  }
>
> +void HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) {
> +  assert(isBundle(MCI));
> +  MCOperand &Operand = MCI.getOperand(0);
> +  Operand.setImm(Operand.getImm() | memReorderDisabledMask);
> +  assert(isMemReorderDisabled(MCI));
> +}
> +
> +void HexagonMCInstrInfo::setMemStoreReorderEnabled(MCInst &MCI) {
> +  assert(isBundle(MCI));
> +  MCOperand &Operand = MCI.getOperand(0);
> +  Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask);
> +  assert(isMemStoreReorderEnabled(MCI));
> +}
> +
>  void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
>    assert(isBundle(MCI));
>    MCOperand &Operand = MCI.getOperand(0);
>
> Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h
> (original)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCInstrInfo.h Sun
> Nov  8 22:07:48 2015
> @@ -14,9 +14,11 @@
>  #ifndef LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H
>  #define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCINSTRINFO_H
>
> +#include "HexagonMCExpr.h"
>  #include "llvm/MC/MCInst.h"
>
>  namespace llvm {
> +class HexagonMCChecker;
>  class MCContext;
>  class MCInstrDesc;
>  class MCInstrInfo;
> @@ -39,20 +41,44 @@ int64_t const innerLoopMask = 1 << inner
>  size_t const outerLoopOffset = 1;
>  int64_t const outerLoopMask = 1 << outerLoopOffset;
>
> +// do not reorder memory load/stores by default load/stores are re-ordered
> +// and by default loads can be re-ordered
> +size_t const memReorderDisabledOffset = 2;
> +int64_t const memReorderDisabledMask = 1 << memReorderDisabledOffset;
> +
> +// allow re-ordering of memory stores by default stores cannot be
> re-ordered
> +size_t const memStoreReorderEnabledOffset = 3;
> +int64_t const memStoreReorderEnabledMask = 1 <<
> memStoreReorderEnabledOffset;
> +
>  size_t const bundleInstructionsOffset = 1;
>
> +void addConstant(MCInst &MI, uint64_t Value, MCContext &Context);
> +void addConstExtender(MCInstrInfo const &MCII, MCInst &MCB, MCInst const
> &MCI);
> +
>  // Returns a iterator range of instructions in this bundle
>  iterator_range<MCInst::const_iterator> bundleInstructions(MCInst const
> &MCI);
>
>  // Returns the number of instructions in the bundle
>  size_t bundleSize(MCInst const &MCI);
>
> +// Put the packet in to canonical form, compound, duplex, pad, and shuffle
> +bool canonicalizePacket(MCInstrInfo const &MCII, MCSubtargetInfo const
> &STI,
> +                        MCContext &Context, MCInst &MCB,
> +                        HexagonMCChecker *Checker);
> +
>  // Clamp off upper 26 bits of extendable operand for emission
>  void clampExtended(MCInstrInfo const &MCII, MCInst &MCI);
>
> +// Return the extender for instruction at Index or nullptr if none
> +MCInst const *extenderForIndex(MCInst const &MCB, size_t Index);
> +void extendIfNeeded(MCInstrInfo const &MCII, MCInst &MCB, MCInst const
> &MCI,
> +                    bool MustExtend);
> +
>  // Create a duplex instruction given the two subinsts
>  MCInst *deriveDuplex(MCContext &Context, unsigned iClass, MCInst const
> &inst0,
>                       MCInst const &inst1);
> +MCInst deriveExtender(MCInstrInfo const &MCII, MCInst const &Inst,
> +                      MCOperand const &MO);
>
>  // Convert this instruction in to a duplex subinst
>  MCInst deriveSubInst(MCInst const &Inst);
> @@ -108,6 +134,9 @@ unsigned short getNewValueOp(MCInstrInfo
>
>  // Return the operand that consumes or produces a new value.
>  MCOperand const &getNewValueOperand(MCInstrInfo const &MCII, MCInst const
> &MCI);
> +unsigned short getNewValueOp2(MCInstrInfo const &MCII, MCInst const &MCI);
> +MCOperand const &getNewValueOperand2(MCInstrInfo const &MCII,
> +                                     MCInst const &MCI);
>
>  int getSubTarget(MCInstrInfo const &MCII, MCInst const &MCI);
>
> @@ -125,6 +154,7 @@ bool hasImmExt(MCInst const &MCI);
>
>  // Return whether the instruction is a legal new-value producer.
>  bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI);
> +bool hasNewValue2(MCInstrInfo const &MCII, MCInst const &MCI);
>
>  // Return the instruction at Index
>  MCInst const &instruction(MCInst const &MCB, size_t Index);
> @@ -134,10 +164,24 @@ bool isBundle(MCInst const &MCI);
>
>  // Return whether the insn is an actual insn.
>  bool isCanon(MCInstrInfo const &MCII, MCInst const &MCI);
> +bool isCompound(MCInstrInfo const &MCII, MCInst const &MCI);
>
>  // Return the duplex iclass given the two duplex classes
>  unsigned iClassOfDuplexPair(unsigned Ga, unsigned Gb);
>
> +int64_t minConstant(MCInst const &MCI, size_t Index);
> +template <unsigned N, unsigned S>
> +bool inRange(MCInst const &MCI, size_t Index) {
> +  return isShiftedUInt<N, S>(minConstant(MCI, Index));
> +}
> +template <unsigned N, unsigned S>
> +bool inSRange(MCInst const &MCI, size_t Index) {
> +  return isShiftedInt<N, S>(minConstant(MCI, Index));
> +}
> +template <unsigned N> bool inRange(MCInst const &MCI, size_t Index) {
> +  return isUInt<N>(minConstant(MCI, Index));
> +}
> +
>  // Return whether the instruction needs to be constant extended.
>  bool isConstExtended(MCInstrInfo const &MCII, MCInst const &MCI);
>
> @@ -173,6 +217,8 @@ bool isIntReg(unsigned Reg);
>
>  // Is this register suitable for use in a duplex subinst
>  bool isIntRegForSubInst(unsigned Reg);
> +bool isMemReorderDisabled(MCInst const &MCI);
> +bool isMemStoreReorderEnabled(MCInst const &MCI);
>
>  // Return whether the insn is a new-value consumer.
>  bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI);
> @@ -191,6 +237,8 @@ bool isOuterLoop(MCInst const &MCI);
>
>  // Return whether this instruction is predicated
>  bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI);
> +bool isPredicateLate(MCInstrInfo const &MCII, MCInst const &MCI);
> +bool isPredicatedNew(MCInstrInfo const &MCII, MCInst const &MCI);
>
>  // Return whether the predicate sense is true
>  bool isPredicatedTrue(MCInstrInfo const &MCII, MCInst const &MCI);
> @@ -209,6 +257,7 @@ bool isSoloAX(MCInstrInfo const &MCII, M
>
>  /// Return whether the insn can be packaged only with an A-type insn in
> slot #1.
>  bool isSoloAin1(MCInstrInfo const &MCII, MCInst const &MCI);
> +bool isVector(MCInstrInfo const &MCII, MCInst const &MCI);
>
>  // Pad the bundle with nops to satisfy endloop requirements
>  void padEndloop(MCInst &MCI);
> @@ -220,6 +269,8 @@ void replaceDuplex(MCContext &Context, M
>
>  // Marks a bundle as endloop0
>  void setInnerLoop(MCInst &MCI);
> +void setMemReorderDisabled(MCInst &MCI);
> +void setMemStoreReorderEnabled(MCInst &MCI);
>
>  // Marks a bundle as endloop1
>  void setOuterLoop(MCInst &MCI);
>
> Modified:
> llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
> (original)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp Sun
> Nov  8 22:07:48 2015
> @@ -40,6 +40,14 @@ using namespace llvm;
>  #define GET_REGINFO_MC_DESC
>  #include "HexagonGenRegisterInfo.inc"
>
> +cl::opt<bool> llvm::HexagonDisableCompound
> +  ("mno-compound",
> +   cl::desc("Disable looking for compound instructions for Hexagon"));
> +
> +cl::opt<bool> llvm::HexagonDisableDuplex
> +  ("mno-pairing",
> +   cl::desc("Disable looking for duplex instructions for Hexagon"));
> +
>  MCInstrInfo *llvm::createHexagonMCInstrInfo() {
>    MCInstrInfo *X = new MCInstrInfo();
>    InitHexagonMCInstrInfo(X);
> @@ -54,7 +62,10 @@ static MCRegisterInfo *createHexagonMCRe
>
>  static MCSubtargetInfo *
>  createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef
> FS) {
> -  return createHexagonMCSubtargetInfoImpl(TT, CPU, FS);
> +  StringRef CPUName = CPU;
> +  if (CPU.empty())
> +    CPUName = "hexagonv5";
> +  return createHexagonMCSubtargetInfoImpl(TT, CPUName, FS);
>  }
>
>  namespace {
>
> Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h
> (original)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h Sun
> Nov  8 22:07:48 2015
> @@ -16,6 +16,8 @@
>
>  #include <cstdint>
>
> +#include "llvm/Support/CommandLine.h"
> +
>  namespace llvm {
>  struct InstrItinerary;
>  struct InstrStage;
> @@ -33,7 +35,8 @@ class raw_ostream;
>  class raw_pwrite_stream;
>
>  extern Target TheHexagonTarget;
> -
> +extern cl::opt<bool> HexagonDisableCompound;
> +extern cl::opt<bool> HexagonDisableDuplex;
>  extern const InstrStage HexagonStages[];
>
>  MCInstrInfo *createHexagonMCInstrInfo();
>
> Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h (original)
> +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonShuffler.h Sun Nov
> 8 22:07:48 2015
> @@ -108,6 +108,8 @@ public:
>      SHUFFLE_ERROR_BRANCHES, ///< No free slots for branch insns.
>      SHUFFLE_ERROR_NOSLOTS,  ///< No free slots for other insns.
>      SHUFFLE_ERROR_SLOTS,    ///< Over-subscribed slots.
> +    SHUFFLE_ERROR_ERRATA2, ///< Errata violation (v60).
> +    SHUFFLE_ERROR_STORE_LOAD_CONFLICT, ///< store/load conflict
>      SHUFFLE_ERROR_UNKNOWN   ///< Unknown error.
>    };
>
>
> Modified: llvm/trunk/test/CodeGen/Hexagon/absaddr-store.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/absaddr-store.ll?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Hexagon/absaddr-store.ll (original)
> +++ llvm/trunk/test/CodeGen/Hexagon/absaddr-store.ll Sun Nov  8 22:07:48
> 2015
> @@ -1,5 +1,6 @@
>  ; RUN: llc -march=hexagon -hexagon-small-data-threshold=0 < %s |
> FileCheck %s
>  ; Check that we generate load instructions with absolute addressing mode.
> +; XFAIL: *
>
>  @a0 = external global i32
>  @a1 = external global i32
>
> Modified: llvm/trunk/test/CodeGen/Hexagon/absimm.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/absimm.ll?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Hexagon/absimm.ll (original)
> +++ llvm/trunk/test/CodeGen/Hexagon/absimm.ll Sun Nov  8 22:07:48 2015
> @@ -1,6 +1,7 @@
>  ; RUN: llc -march=hexagon < %s | FileCheck %s
>  ; Check that we generate absolute addressing mode instructions
>  ; with immediate value.
> +; XFAIL: *
>
>  define i32 @f1(i32 %i) nounwind {
>  ; CHECK: memw(##786432){{ *}}={{ *}}r{{[0-9]+}}
>
> Modified: llvm/trunk/test/CodeGen/Hexagon/always-ext.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/always-ext.ll?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Hexagon/always-ext.ll (original)
> +++ llvm/trunk/test/CodeGen/Hexagon/always-ext.ll Sun Nov  8 22:07:48 2015
> @@ -1,4 +1,5 @@
>  ; RUN: llc -march=hexagon < %s | FileCheck %s
> +; XFAIL: *
>
>  ; Check that we don't generate an invalid packet with too many
> instructions
>  ; due to a store that has a must-extend operand.
>
> Modified: llvm/trunk/test/CodeGen/Hexagon/compound.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/compound.ll?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Hexagon/compound.ll (original)
> +++ llvm/trunk/test/CodeGen/Hexagon/compound.ll Sun Nov  8 22:07:48 2015
> @@ -1,4 +1,5 @@
>  ; RUN: llc -march=hexagon -filetype=obj -o - %s | llvm-objdump -d - |
> FileCheck %s
> +; XFAIL: *
>
>  ; CHECK: p0 = cmp.gt(r0,#-1); if (!p0.new) jump:nt
>
>
> Modified: llvm/trunk/test/CodeGen/Hexagon/static.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/static.ll?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Hexagon/static.ll (original)
> +++ llvm/trunk/test/CodeGen/Hexagon/static.ll Sun Nov  8 22:07:48 2015
> @@ -1,4 +1,5 @@
>  ; RUN: llc -march=hexagon -mcpu=hexagonv4 -disable-dfa-sched
> -disable-hexagon-misched < %s | FileCheck %s
> +; XFAIL: *
>
>  @num = external global i32
>  @acc = external global i32
>
> Modified: llvm/trunk/test/CodeGen/Hexagon/zextloadi1.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/Hexagon/zextloadi1.ll?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/CodeGen/Hexagon/zextloadi1.ll (original)
> +++ llvm/trunk/test/CodeGen/Hexagon/zextloadi1.ll Sun Nov  8 22:07:48 2015
> @@ -1,4 +1,5 @@
>  ; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
> +; XFAIL: *
>
>  ; CHECK: r{{[0-9]+}} = ##i129_l+16
>  ; CHECK: r{{[0-9]+}} = ##i129_s+16
>
> Added: llvm/trunk/test/MC/Disassembler/Hexagon/invalid_packet.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Hexagon/invalid_packet.txt?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/Hexagon/invalid_packet.txt (added)
> +++ llvm/trunk/test/MC/Disassembler/Hexagon/invalid_packet.txt Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,4 @@
> +# RUN: llvm-mc -triple=hexagon -disassemble < %s 2>&1 | FileCheck %s
> +
> +#CHECK: warning: invalid instruction encoding
> +0x00 0x40 0x20 0x6c 0x00 0xc0 0x00 0x7f
> \ No newline at end of file
>
> Modified: llvm/trunk/test/MC/Disassembler/Hexagon/j.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Hexagon/j.txt?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/Hexagon/j.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/Hexagon/j.txt Sun Nov  8 22:07:48 2015
> @@ -11,149 +11,149 @@
>
>  # Compare and jump
>  0x00 0xc0 0x89 0x11
> -# CHECK: p0 = cmp.eq(r9,#-1); if (p0.new) jump:nt
> +# CHECK: p0 = cmp.eq(r17,#-1); if (p0.new) jump:nt
>  0x00 0xc1 0x89 0x11
> -# CHECK: p0 = cmp.gt(r9,#-1); if (p0.new) jump:nt
> +# CHECK: p0 = cmp.gt(r17,#-1); if (p0.new) jump:nt
>  0x00 0xc3 0x89 0x11
> -# CHECK: p0 = tstbit(r9, #0); if (p0.new) jump:nt
> +# CHECK: p0 = tstbit(r17, #0); if (p0.new) jump:nt
>  0x00 0xe0 0x89 0x11
> -# CHECK: p0 = cmp.eq(r9,#-1); if (p0.new) jump:t
> +# CHECK: p0 = cmp.eq(r17,#-1); if (p0.new) jump:t
>  0x00 0xe1 0x89 0x11
> -# CHECK: p0 = cmp.gt(r9,#-1); if (p0.new) jump:t
> +# CHECK: p0 = cmp.gt(r17,#-1); if (p0.new) jump:t
>  0x00 0xe3 0x89 0x11
> -# CHECK: p0 = tstbit(r9, #0); if (p0.new) jump:t
> +# CHECK: p0 = tstbit(r17, #0); if (p0.new) jump:t
>  0x00 0xc0 0xc9 0x11
> -# CHECK: p0 = cmp.eq(r9,#-1); if (!p0.new) jump:nt
> +# CHECK: p0 = cmp.eq(r17,#-1); if (!p0.new) jump:nt
>  0x00 0xc1 0xc9 0x11
> -# CHECK: p0 = cmp.gt(r9,#-1); if (!p0.new) jump:nt
> +# CHECK: p0 = cmp.gt(r17,#-1); if (!p0.new) jump:nt
>  0x00 0xc3 0xc9 0x11
> -# CHECK: p0 = tstbit(r9, #0); if (!p0.new) jump:nt
> +# CHECK: p0 = tstbit(r17, #0); if (!p0.new) jump:nt
>  0x00 0xe0 0xc9 0x11
> -# CHECK: p0 = cmp.eq(r9,#-1); if (!p0.new) jump:t
> +# CHECK: p0 = cmp.eq(r17,#-1); if (!p0.new) jump:t
>  0x00 0xe1 0xc9 0x11
> -# CHECK: p0 = cmp.gt(r9,#-1); if (!p0.new) jump:t
> +# CHECK: p0 = cmp.gt(r17,#-1); if (!p0.new) jump:t
>  0x00 0xe3 0xc9 0x11
> -# CHECK: p0 = tstbit(r9, #0); if (!p0.new) jump:t
> +# CHECK: p0 = tstbit(r17, #0); if (!p0.new) jump:t
>  0x00 0xd5 0x09 0x10
> -# CHECK: p0 = cmp.eq(r9, #21); if (p0.new) jump:nt
> +# CHECK: p0 = cmp.eq(r17, #21); if (p0.new) jump:nt
>  0x00 0xf5 0x09 0x10
> -# CHECK: p0 = cmp.eq(r9, #21); if (p0.new) jump:t
> +# CHECK: p0 = cmp.eq(r17, #21); if (p0.new) jump:t
>  0x00 0xd5 0x49 0x10
> -# CHECK: p0 = cmp.eq(r9, #21); if (!p0.new) jump:nt
> +# CHECK: p0 = cmp.eq(r17, #21); if (!p0.new) jump:nt
>  0x00 0xf5 0x49 0x10
> -# CHECK: p0 = cmp.eq(r9, #21); if (!p0.new) jump:t
> +# CHECK: p0 = cmp.eq(r17, #21); if (!p0.new) jump:t
>  0x00 0xd5 0x89 0x10
> -# CHECK: p0 = cmp.gt(r9, #21); if (p0.new) jump:nt
> +# CHECK: p0 = cmp.gt(r17, #21); if (p0.new) jump:nt
>  0x00 0xf5 0x89 0x10
> -# CHECK: p0 = cmp.gt(r9, #21); if (p0.new) jump:t
> +# CHECK: p0 = cmp.gt(r17, #21); if (p0.new) jump:t
>  0x00 0xd5 0xc9 0x10
> -# CHECK: p0 = cmp.gt(r9, #21); if (!p0.new) jump:nt
> +# CHECK: p0 = cmp.gt(r17, #21); if (!p0.new) jump:nt
>  0x00 0xf5 0xc9 0x10
> -# CHECK: p0 = cmp.gt(r9, #21); if (!p0.new) jump:t
> +# CHECK: p0 = cmp.gt(r17, #21); if (!p0.new) jump:t
>  0x00 0xd5 0x09 0x11
> -# CHECK: p0 = cmp.gtu(r9, #21); if (p0.new) jump:nt
> +# CHECK: p0 = cmp.gtu(r17, #21); if (p0.new) jump:nt
>  0x00 0xf5 0x09 0x11
> -# CHECK: p0 = cmp.gtu(r9, #21); if (p0.new) jump:t
> +# CHECK: p0 = cmp.gtu(r17, #21); if (p0.new) jump:t
>  0x00 0xd5 0x49 0x11
> -# CHECK: p0 = cmp.gtu(r9, #21); if (!p0.new) jump:nt
> +# CHECK: p0 = cmp.gtu(r17, #21); if (!p0.new) jump:nt
>  0x00 0xf5 0x49 0x11
> -# CHECK: p0 = cmp.gtu(r9, #21); if (!p0.new) jump:t
> +# CHECK: p0 = cmp.gtu(r17, #21); if (!p0.new) jump:t
>  0x00 0xc0 0x89 0x13
> -# CHECK: p1 = cmp.eq(r9,#-1); if (p1.new) jump:nt
> +# CHECK: p1 = cmp.eq(r17,#-1); if (p1.new) jump:nt
>  0x00 0xc1 0x89 0x13
> -# CHECK: p1 = cmp.gt(r9,#-1); if (p1.new) jump:nt
> +# CHECK: p1 = cmp.gt(r17,#-1); if (p1.new) jump:nt
>  0x00 0xc3 0x89 0x13
> -# CHECK: p1 = tstbit(r9, #0); if (p1.new) jump:nt
> +# CHECK: p1 = tstbit(r17, #0); if (p1.new) jump:nt
>  0x00 0xe0 0x89 0x13
> -# CHECK: p1 = cmp.eq(r9,#-1); if (p1.new) jump:t
> +# CHECK: p1 = cmp.eq(r17,#-1); if (p1.new) jump:t
>  0x00 0xe1 0x89 0x13
> -# CHECK: p1 = cmp.gt(r9,#-1); if (p1.new) jump:t
> +# CHECK: p1 = cmp.gt(r17,#-1); if (p1.new) jump:t
>  0x00 0xe3 0x89 0x13
> -# CHECK: p1 = tstbit(r9, #0); if (p1.new) jump:t
> +# CHECK: p1 = tstbit(r17, #0); if (p1.new) jump:t
>  0x00 0xc0 0xc9 0x13
> -# CHECK: p1 = cmp.eq(r9,#-1); if (!p1.new) jump:nt
> +# CHECK: p1 = cmp.eq(r17,#-1); if (!p1.new) jump:nt
>  0x00 0xc1 0xc9 0x13
> -# CHECK: p1 = cmp.gt(r9,#-1); if (!p1.new) jump:nt
> +# CHECK: p1 = cmp.gt(r17,#-1); if (!p1.new) jump:nt
>  0x00 0xc3 0xc9 0x13
> -# CHECK: p1 = tstbit(r9, #0); if (!p1.new) jump:nt
> +# CHECK: p1 = tstbit(r17, #0); if (!p1.new) jump:nt
>  0x00 0xe0 0xc9 0x13
> -# CHECK: p1 = cmp.eq(r9,#-1); if (!p1.new) jump:t
> +# CHECK: p1 = cmp.eq(r17,#-1); if (!p1.new) jump:t
>  0x00 0xe1 0xc9 0x13
> -# CHECK: p1 = cmp.gt(r9,#-1); if (!p1.new) jump:t
> +# CHECK: p1 = cmp.gt(r17,#-1); if (!p1.new) jump:t
>  0x00 0xe3 0xc9 0x13
> -# CHECK: p1 = tstbit(r9, #0); if (!p1.new) jump:t
> +# CHECK: p1 = tstbit(r17, #0); if (!p1.new) jump:t
>  0x00 0xd5 0x09 0x12
> -# CHECK: p1 = cmp.eq(r9, #21); if (p1.new) jump:nt
> +# CHECK: p1 = cmp.eq(r17, #21); if (p1.new) jump:nt
>  0x00 0xf5 0x09 0x12
> -# CHECK: p1 = cmp.eq(r9, #21); if (p1.new) jump:t
> +# CHECK: p1 = cmp.eq(r17, #21); if (p1.new) jump:t
>  0x00 0xd5 0x49 0x12
> -# CHECK: p1 = cmp.eq(r9, #21); if (!p1.new) jump:nt
> +# CHECK: p1 = cmp.eq(r17, #21); if (!p1.new) jump:nt
>  0x00 0xf5 0x49 0x12
> -# CHECK: p1 = cmp.eq(r9, #21); if (!p1.new) jump:t
> +# CHECK: p1 = cmp.eq(r17, #21); if (!p1.new) jump:t
>  0x00 0xd5 0x89 0x12
> -# CHECK: p1 = cmp.gt(r9, #21); if (p1.new) jump:nt
> +# CHECK: p1 = cmp.gt(r17, #21); if (p1.new) jump:nt
>  0x00 0xf5 0x89 0x12
> -# CHECK: p1 = cmp.gt(r9, #21); if (p1.new) jump:t
> +# CHECK: p1 = cmp.gt(r17, #21); if (p1.new) jump:t
>  0x00 0xd5 0xc9 0x12
> -# CHECK: p1 = cmp.gt(r9, #21); if (!p1.new) jump:nt
> +# CHECK: p1 = cmp.gt(r17, #21); if (!p1.new) jump:nt
>  0x00 0xf5 0xc9 0x12
> -# CHECK: p1 = cmp.gt(r9, #21); if (!p1.new) jump:t
> +# CHECK: p1 = cmp.gt(r17, #21); if (!p1.new) jump:t
>  0x00 0xd5 0x09 0x13
> -# CHECK: p1 = cmp.gtu(r9, #21); if (p1.new) jump:nt
> +# CHECK: p1 = cmp.gtu(r17, #21); if (p1.new) jump:nt
>  0x00 0xf5 0x09 0x13
> -# CHECK: p1 = cmp.gtu(r9, #21); if (p1.new) jump:t
> +# CHECK: p1 = cmp.gtu(r17, #21); if (p1.new) jump:t
>  0x00 0xd5 0x49 0x13
> -# CHECK: p1 = cmp.gtu(r9, #21); if (!p1.new) jump:nt
> +# CHECK: p1 = cmp.gtu(r17, #21); if (!p1.new) jump:nt
>  0x00 0xf5 0x49 0x13
> -# CHECK: p1 = cmp.gtu(r9, #21); if (!p1.new) jump:t
> +# CHECK: p1 = cmp.gtu(r17, #21); if (!p1.new) jump:t
>  0x00 0xcd 0x09 0x14
> -# CHECK: p0 = cmp.eq(r9, r13); if (p0.new) jump:nt
> +# CHECK: p0 = cmp.eq(r17, r21); if (p0.new) jump:nt
>  0x00 0xdd 0x09 0x14
> -# CHECK: p1 = cmp.eq(r9, r13); if (p1.new) jump:nt
> +# CHECK: p1 = cmp.eq(r17, r21); if (p1.new) jump:nt
>  0x00 0xed 0x09 0x14
> -# CHECK: p0 = cmp.eq(r9, r13); if (p0.new) jump:t
> +# CHECK: p0 = cmp.eq(r17, r21); if (p0.new) jump:t
>  0x00 0xfd 0x09 0x14
> -# CHECK: p1 = cmp.eq(r9, r13); if (p1.new) jump:t
> +# CHECK: p1 = cmp.eq(r17, r21); if (p1.new) jump:t
>  0x00 0xcd 0x49 0x14
> -# CHECK: p0 = cmp.eq(r9, r13); if (!p0.new) jump:nt
> +# CHECK: p0 = cmp.eq(r17, r21); if (!p0.new) jump:nt
>  0x00 0xdd 0x49 0x14
> -# CHECK: p1 = cmp.eq(r9, r13); if (!p1.new) jump:nt
> +# CHECK: p1 = cmp.eq(r17, r21); if (!p1.new) jump:nt
>  0x00 0xed 0x49 0x14
> -# CHECK: p0 = cmp.eq(r9, r13); if (!p0.new) jump:t
> +# CHECK: p0 = cmp.eq(r17, r21); if (!p0.new) jump:t
>  0x00 0xfd 0x49 0x14
> -# CHECK: p1 = cmp.eq(r9, r13); if (!p1.new) jump:t
> +# CHECK: p1 = cmp.eq(r17, r21); if (!p1.new) jump:t
>  0x00 0xcd 0x89 0x14
> -# CHECK: p0 = cmp.gt(r9, r13); if (p0.new) jump:nt
> +# CHECK: p0 = cmp.gt(r17, r21); if (p0.new) jump:nt
>  0x00 0xdd 0x89 0x14
> -# CHECK: p1 = cmp.gt(r9, r13); if (p1.new) jump:nt
> +# CHECK: p1 = cmp.gt(r17, r21); if (p1.new) jump:nt
>  0x00 0xed 0x89 0x14
> -# CHECK: p0 = cmp.gt(r9, r13); if (p0.new) jump:t
> +# CHECK: p0 = cmp.gt(r17, r21); if (p0.new) jump:t
>  0x00 0xfd 0x89 0x14
> -# CHECK: p1 = cmp.gt(r9, r13); if (p1.new) jump:t
> +# CHECK: p1 = cmp.gt(r17, r21); if (p1.new) jump:t
>  0x00 0xcd 0xc9 0x14
> -# CHECK: p0 = cmp.gt(r9, r13); if (!p0.new) jump:nt
> +# CHECK: p0 = cmp.gt(r17, r21); if (!p0.new) jump:nt
>  0x00 0xdd 0xc9 0x14
> -# CHECK: p1 = cmp.gt(r9, r13); if (!p1.new) jump:nt
> +# CHECK: p1 = cmp.gt(r17, r21); if (!p1.new) jump:nt
>  0x00 0xed 0xc9 0x14
> -# CHECK: p0 = cmp.gt(r9, r13); if (!p0.new) jump:t
> +# CHECK: p0 = cmp.gt(r17, r21); if (!p0.new) jump:t
>  0x00 0xfd 0xc9 0x14
> -# CHECK: p1 = cmp.gt(r9, r13); if (!p1.new) jump:t
> +# CHECK: p1 = cmp.gt(r17, r21); if (!p1.new) jump:t
>  0x00 0xcd 0x09 0x15
> -# CHECK: p0 = cmp.gtu(r9, r13); if (p0.new) jump:nt
> +# CHECK: p0 = cmp.gtu(r17, r21); if (p0.new) jump:nt
>  0x00 0xdd 0x09 0x15
> -# CHECK: p1 = cmp.gtu(r9, r13); if (p1.new) jump:nt
> +# CHECK: p1 = cmp.gtu(r17, r21); if (p1.new) jump:nt
>  0x00 0xed 0x09 0x15
> -# CHECK: p0 = cmp.gtu(r9, r13); if (p0.new) jump:t
> +# CHECK: p0 = cmp.gtu(r17, r21); if (p0.new) jump:t
>  0x00 0xfd 0x09 0x15
> -# CHECK: p1 = cmp.gtu(r9, r13); if (p1.new) jump:t
> +# CHECK: p1 = cmp.gtu(r17, r21); if (p1.new) jump:t
>  0x00 0xcd 0x49 0x15
> -# CHECK: p0 = cmp.gtu(r9, r13); if (!p0.new) jump:nt
> +# CHECK: p0 = cmp.gtu(r17, r21); if (!p0.new) jump:nt
>  0x00 0xdd 0x49 0x15
> -# CHECK: p1 = cmp.gtu(r9, r13); if (!p1.new) jump:nt
> +# CHECK: p1 = cmp.gtu(r17, r21); if (!p1.new) jump:nt
>  0x00 0xed 0x49 0x15
> -# CHECK: p0 = cmp.gtu(r9, r13); if (!p0.new) jump:t
> +# CHECK: p0 = cmp.gtu(r17, r21); if (!p0.new) jump:t
>  0x00 0xfd 0x49 0x15
> -# CHECK: p1 = cmp.gtu(r9, r13); if (!p1.new) jump:t
> +# CHECK: p1 = cmp.gtu(r17, r21); if (!p1.new) jump:t
>
>  # Jump to address
>  0x22 0xc0 0x00 0x58
> @@ -197,6 +197,6 @@
>
>  # Transfer and jump
>  0x00 0xd5 0x09 0x16
> -# CHECK: r9 = #21 ; jump
> +# CHECK: r17 = #21 ; jump
>  0x00 0xc9 0x0d 0x17
> -# CHECK: r9 = r13 ; jump
> +# CHECK: r17 = r21 ; jump
>
> Modified: llvm/trunk/test/MC/Disassembler/Hexagon/ld.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Hexagon/ld.txt?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/Hexagon/ld.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/Hexagon/ld.txt Sun Nov  8 22:07:48 2015
> @@ -1,15 +1,22 @@
>  # RUN: llvm-mc -triple hexagon -disassemble < %s | FileCheck %s
>  # Hexagon Programmer's Reference Manual 11.5 LD
> +# XFAIL: *
>
>  # Load doubleword
>  0x90 0xff 0xd5 0x3a
>  # CHECK: r17:16 = memd(r21 + r31<<#3)
> -0x10 0xc5 0xc0 0x49
> -# CHECK: r17:16 = memd(##320)
> +0xb0 0xc2 0xc0 0x49
> +# CHECK: r17:16 = memd(#168)
> +0x02 0x40 0x00 0x00 0x10 0xc5 0xc0 0x49
> +# CHECK: r17:16 = memd(##168)
> +0xd0 0xc0 0xd5 0x91
> +# CHECK: r17:16 = memd(r21 + #48)
>  0xb0 0xe0 0xd5 0x99
>  # CHECK: r17:16 = memd(r21 ++ #40:circ(m1))
>  0x10 0xe2 0xd5 0x99
>  # CHECK: r17:16 = memd(r21 ++ I:circ(m1))
> +0x00 0x40 0x00 0x00 0x70 0xd7 0xd5 0x9b
> +# CHECK: r17:16 = memd(r21 = ##31)
>  0xb0 0xc0 0xd5 0x9b
>  # CHECK: r17:16 = memd(r21++#40)
>  0x10 0xe0 0xd5 0x9d
> @@ -53,6 +60,8 @@
>  0x91 0xff 0x15 0x3a
>  # CHECK: r17 = memb(r21 + r31<<#3)
>  0xb1 0xc2 0x00 0x49
> +# CHECK: r17 = memb(#21)
> +0x00 0x40 0x00 0x00 0xb1 0xc2 0x00 0x49
>  # CHECK: r17 = memb(##21)
>  0xf1 0xc3 0x15 0x91
>  # CHECK: r17 = memb(r21 + #31)
> @@ -60,6 +69,8 @@
>  # CHECK: r17 = memb(r21 ++ #5:circ(m1))
>  0x11 0xe2 0x15 0x99
>  # CHECK: r17 = memb(r21 ++ I:circ(m1))
> +0x00 0x40 0x00 0x00 0x71 0xd7 0x15 0x9b
> +# CHECK: r17 = memb(r21 = ##31)
>  0xb1 0xc0 0x15 0x9b
>  # CHECK: r17 = memb(r21++#5)
>  0x11 0xe0 0x15 0x9d
> @@ -99,17 +110,37 @@
>  # CHECK: p3 = r5
>  # CHECK-NEXT: if (!p3.new) r17 = memb(r21++#5)
>
> +# Load byte into shifted vector
> +0xf0 0xc3 0x95 0x90
> +# CHECK: r17:16 = memb_fifo(r21 + #31)
> +0xb0 0xe0 0x95 0x98
> +# CHECK: r17:16 = memb_fifo(r21 ++ #5:circ(m1))
> +0x10 0xe2 0x95 0x98
> +# CHECK: r17:16 = memb_fifo(r21 ++ I:circ(m1))
> +
> +# Load half into shifted vector
> +0xf0 0xc3 0x55 0x90
> +# CHECK: r17:16 = memh_fifo(r21 + #62)
> +0xb0 0xe0 0x55 0x98
> +# CHECK: r17:16 = memh_fifo(r21 ++ #10:circ(m1))
> +0x10 0xe2 0x55 0x98
> +# CHECK: r17:16 = memh_fifo(r21 ++ I:circ(m1))
> +
>  # Load halfword
>  0x91 0xff 0x55 0x3a
>  # CHECK: r17 = memh(r21 + r31<<#3)
> -0x51 0xc5 0x40 0x49
> -# CHECK: r17 = memh(##84)
> +0xb1 0xc2 0x40 0x49
> +# CHECK: r17 = memh(#42)
> +0x00 0x40 0x00 0x00 0x51 0xc5 0x40 0x49
> +# CHECK: r17 = memh(##42)
>  0xf1 0xc3 0x55 0x91
>  # CHECK: r17 = memh(r21 + #62)
>  0xb1 0xe0 0x55 0x99
>  # CHECK: r17 = memh(r21 ++ #10:circ(m1))
>  0x11 0xe2 0x55 0x99
>  # CHECK: r17 = memh(r21 ++ I:circ(m1))
> +0x00 0x40 0x00 0x00 0x71 0xd7 0x55 0x9b
> +# CHECK: r17 = memh(r21 = ##31)
>  0xb1 0xc0 0x55 0x9b
>  # CHECK: r17 = memh(r21++#10)
>  0x11 0xe0 0x55 0x9d
> @@ -138,11 +169,23 @@
>  0x03 0x40 0x45 0x85 0xb1 0xfe 0x55 0x9b
>  # CHECK: p3 = r5
>  # CHECK-NEXT: if (!p3.new) r17 = memh(r21++#10)
> +0xf1 0xdb 0x55 0x41
> +# CHECK: if (p3) r17 = memh(r21 + #62)
> +0xf1 0xdb 0x55 0x45
> +# CHECK: if (!p3) r17 = memh(r21 + #62)
> +0x03 0x40 0x45 0x85 0xf1 0xdb 0x55 0x43
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (p3.new) r17 = memh(r21 + #62)
> +0x03 0x40 0x45 0x85 0xf1 0xdb 0x55 0x47
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (!p3.new) r17 = memh(r21 + #62)
>
>  # Load unsigned byte
>  0x91 0xff 0x35 0x3a
>  # CHECK: r17 = memub(r21 + r31<<#3)
>  0xb1 0xc2 0x20 0x49
> +# CHECK: r17 = memub(#21)
> +0x00 0x40 0x00 0x00 0xb1 0xc2 0x20 0x49
>  # CHECK: r17 = memub(##21)
>  0xf1 0xc3 0x35 0x91
>  # CHECK: r17 = memub(r21 + #31)
> @@ -150,6 +193,8 @@
>  # CHECK: r17 = memub(r21 ++ #5:circ(m1))
>  0x11 0xe2 0x35 0x99
>  # CHECK: r17 = memub(r21 ++ I:circ(m1))
> +0x00 0x40 0x00 0x00 0x71 0xd7 0x35 0x9b
> +# CHECK: r17 = memub(r21 = ##31)
>  0xb1 0xc0 0x35 0x9b
>  # CHECK: r17 = memub(r21++#5)
>  0x11 0xe0 0x35 0x9d
> @@ -192,14 +237,18 @@
>  # Load unsigned halfword
>  0x91 0xff 0x75 0x3a
>  # CHECK: r17 = memuh(r21 + r31<<#3)
> -0x51 0xc5 0x60 0x49
> -# CHECK: r17 = memuh(##84)
> +0xb1 0xc2 0x60 0x49
> +# CHECK: r17 = memuh(#42)
> +0x00 0x40 0x00 0x00 0x51 0xc5 0x60 0x49
> +# CHECK: r17 = memuh(##42)
>  0xb1 0xc2 0x75 0x91
>  # CHECK: r17 = memuh(r21 + #42)
>  0xb1 0xe0 0x75 0x99
>  # CHECK: r17 = memuh(r21 ++ #10:circ(m1))
>  0x11 0xe2 0x75 0x99
>  # CHECK: r17 = memuh(r21 ++ I:circ(m1))
> +0x00 0x40 0x00 0x00 0x71 0xd7 0x75 0x9b
> +# CHECK: r17 = memuh(r21 = ##31)
>  0xb1 0xc0 0x75 0x9b
>  # CHECK: r17 = memuh(r21++#10)
>  0x11 0xe0 0x75 0x9d
> @@ -242,14 +291,18 @@
>  # Load word
>  0x91 0xff 0x95 0x3a
>  # CHECK: r17 = memw(r21 + r31<<#3)
> -0x91 0xc2 0x80 0x49
> -# CHECK: r17 = memw(##80)
> +0xb1 0xc2 0x80 0x49
> +# CHECK: r17 = memw(#84)
> +0x01 0x40 0x00 0x00 0x91 0xc2 0x80 0x49
> +# CHECK: r17 = memw(##84)
>  0xb1 0xc2 0x95 0x91
>  # CHECK: r17 = memw(r21 + #84)
>  0xb1 0xe0 0x95 0x99
>  # CHECK: r17 = memw(r21 ++ #20:circ(m1))
>  0x11 0xe2 0x95 0x99
>  # CHECK: r17 = memw(r21 ++ I:circ(m1))
> +0x00 0x40 0x00 0x00 0x71 0xd7 0x95 0x9b
> +# CHECK: r17 = memw(r21 = ##31)
>  0xb1 0xc0 0x95 0x9b
>  # CHECK: r17 = memw(r21++#20)
>  0x11 0xe0 0x95 0x9d
> @@ -338,14 +391,36 @@
>  # CHECK: r17:16 = memubh(r21 ++ #20:circ(m1))
>  0x10 0xe2 0xb5 0x98
>  # CHECK: r17:16 = memubh(r21 ++ I:circ(m1))
> +0x00 0x40 0x00 0x00 0x71 0xd7 0x35 0x9a
> +# CHECK: r17 = membh(r21 = ##31)
>  0xb1 0xc0 0x35 0x9a
>  # CHECK: r17 = membh(r21++#10)
> +0x00 0x40 0x00 0x00 0x71 0xd7 0x75 0x9a
> +# CHECK: r17 = memubh(r21 = ##31)
>  0xb1 0xc0 0x75 0x9a
>  # CHECK: r17 = memubh(r21++#10)
> +0x00 0x40 0x00 0x00 0x70 0xd7 0xb5 0x9a
> +# CHECK: r17:16 = memubh(r21 = ##31)
>  0xb0 0xc0 0xb5 0x9a
>  # CHECK: r17:16 = memubh(r21++#20)
> +0x00 0x40 0x00 0x00 0x70 0xd7 0xf5 0x9a
> +# CHECK: r17:16 = membh(r21 = ##31)
>  0xb0 0xc0 0xf5 0x9a
>  # CHECK: r17:16 = membh(r21++#20)
> +0x00 0x40 0x00 0x00 0xf1 0xf7 0x35 0x9c
> +# CHECK: r17 = membh(r21<<#3 + ##31)
> +0x11 0xe0 0x35 0x9c
> +# CHECK: r17 = membh(r21++m1)
> +0x00 0x40 0x00 0x00 0xf1 0xf7 0x75 0x9c
> +# CHECK: r17 = memubh(r21<<#3 + ##31)
> +0x11 0xe0 0x75 0x9c
> +# CHECK: r17 = memubh(r21++m1)
> +0x00 0x40 0x00 0x00 0xf0 0xf7 0xf5 0x9c
> +# CHECK: r17:16 = membh(r21<<#3 + ##31)
> +0x10 0xe0 0xf5 0x9c
> +# CHECK: r17:16 = membh(r21++m1)
> +0x00 0x40 0x00 0x00 0xf0 0xf7 0xb5 0x9c
> +# CHECK: r17:16 = memubh(r21<<#3 + ##31)
>  0x11 0xe0 0x35 0x9c
>  # CHECK: r17 = membh(r21++m1)
>  0x11 0xe0 0x75 0x9c
>
> Modified: llvm/trunk/test/MC/Disassembler/Hexagon/lit.local.cfg
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Hexagon/lit.local.cfg?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/Hexagon/lit.local.cfg (original)
> +++ llvm/trunk/test/MC/Disassembler/Hexagon/lit.local.cfg Sun Nov  8
> 22:07:48 2015
> @@ -1,3 +1,3 @@
> -if not 'Hexagon' in config.root.targets:
> -    config.unsupported = True
> -
> +if not 'Hexagon' in config.root.targets:
> +    config.unsupported = True
> +
>
> Modified: llvm/trunk/test/MC/Disassembler/Hexagon/nv_j.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Hexagon/nv_j.txt?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/Hexagon/nv_j.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/Hexagon/nv_j.txt Sun Nov  8 22:07:48
> 2015
> @@ -4,133 +4,133 @@
>  # Jump to address conditioned on new register value
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x02 0x20
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.eq(r2.new, r21)) jump:nt
> +# CHECK-NEXT: if (cmp.eq(r17.new, r21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x02 0x20
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.eq(r2.new, r21)) jump:t
> +# CHECK-NEXT: if (cmp.eq(r17.new, r21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x42 0x20
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.eq(r2.new, r21)) jump:nt
> +# CHECK-NEXT: if (!cmp.eq(r17.new, r21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x42 0x20
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.eq(r2.new, r21)) jump:t
> +# CHECK-NEXT: if (!cmp.eq(r17.new, r21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x82 0x20
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gt(r2.new, r21)) jump:nt
> +# CHECK-NEXT: if (cmp.gt(r17.new, r21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x82 0x20
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gt(r2.new, r21)) jump:t
> +# CHECK-NEXT: if (cmp.gt(r17.new, r21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0xc2 0x20
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gt(r2.new, r21)) jump:nt
> +# CHECK-NEXT: if (!cmp.gt(r17.new, r21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0xc2 0x20
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gt(r2.new, r21)) jump:t
> +# CHECK-NEXT: if (!cmp.gt(r17.new, r21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x02 0x21
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gtu(r2.new, r21)) jump:nt
> +# CHECK-NEXT: if (cmp.gtu(r17.new, r21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x02 0x21
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gtu(r2.new, r21)) jump:t
> +# CHECK-NEXT: if (cmp.gtu(r17.new, r21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x42 0x21
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gtu(r2.new, r21)) jump:nt
> +# CHECK-NEXT: if (!cmp.gtu(r17.new, r21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x42 0x21
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gtu(r2.new, r21)) jump:t
> +# CHECK-NEXT: if (!cmp.gtu(r17.new, r21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x82 0x21
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gt(r21, r2.new)) jump:nt
> +# CHECK-NEXT: if (cmp.gt(r21, r17.new)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x82 0x21
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gt(r21, r2.new)) jump:t
> +# CHECK-NEXT: if (cmp.gt(r21, r17.new)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0xc2 0x21
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gt(r21, r2.new)) jump:nt
> +# CHECK-NEXT: if (!cmp.gt(r21, r17.new)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0xc2 0x21
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gt(r21, r2.new)) jump:t
> +# CHECK-NEXT: if (!cmp.gt(r21, r17.new)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x02 0x22
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gtu(r21, r2.new)) jump:nt
> +# CHECK-NEXT: if (cmp.gtu(r21, r17.new)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x02 0x22
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gtu(r21, r2.new)) jump:t
> +# CHECK-NEXT: if (cmp.gtu(r21, r17.new)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x42 0x22
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gtu(r21, r2.new)) jump:nt
> +# CHECK-NEXT: if (!cmp.gtu(r21, r17.new)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x42 0x22
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gtu(r21, r2.new)) jump:t
> +# CHECK-NEXT: if (!cmp.gtu(r21, r17.new)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x02 0x24
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.eq(r2.new, #21)) jump:nt
> +# CHECK-NEXT: if (cmp.eq(r17.new, #21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x02 0x24
>  # CHECK: r17 = r17
> -# CHECK-NETX: if (cmp.eq(r2.new, #21)) jump:t
> +# CHECK-NETX: if (cmp.eq(r17.new, #21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x42 0x24
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.eq(r2.new, #21)) jump:nt
> +# CHECK-NEXT: if (!cmp.eq(r17.new, #21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x42 0x24
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.eq(r2.new, #21)) jump:t
> +# CHECK-NEXT: if (!cmp.eq(r17.new, #21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x82 0x24
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gt(r2.new, #21)) jump:nt
> +# CHECK-NEXT: if (cmp.gt(r17.new, #21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x82 0x24
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gt(r2.new, #21)) jump:t
> +# CHECK-NEXT: if (cmp.gt(r17.new, #21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0xc2 0x24
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gt(r2.new, #21)) jump:nt
> +# CHECK-NEXT: if (!cmp.gt(r17.new, #21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0xc2 0x24
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gt(r2.new, #21)) jump:t
> +# CHECK-NEXT: if (!cmp.gt(r17.new, #21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x02 0x25
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gtu(r2.new, #21)) jump:nt
> +# CHECK-NEXT: if (cmp.gtu(r17.new, #21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x02 0x25
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gtu(r2.new, #21)) jump:t
> +# CHECK-NEXT: if (cmp.gtu(r17.new, #21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xd5 0x42 0x25
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gtu(r2.new, #21)) jump:nt
> +# CHECK-NEXT: if (!cmp.gtu(r17.new, #21)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xf5 0x42 0x25
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gtu(r2.new, #21)) jump:t
> +# CHECK-NEXT: if (!cmp.gtu(r17.new, #21)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xc0 0x82 0x25
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (tstbit(r2.new, #0)) jump:nt
> +# CHECK-NEXT: if (tstbit(r17.new, #0)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xe0 0x82 0x25
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (tstbit(r2.new, #0)) jump:t
> +# CHECK-NEXT: if (tstbit(r17.new, #0)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xc0 0xc2 0x25
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!tstbit(r2.new, #0)) jump:nt
> +# CHECK-NEXT: if (!tstbit(r17.new, #0)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xe0 0xc2 0x25
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!tstbit(r2.new, #0)) jump:t
> +# CHECK-NEXT: if (!tstbit(r17.new, #0)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xc0 0x02 0x26
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.eq(r2.new, #-1)) jump:nt
> +# CHECK-NEXT: if (cmp.eq(r17.new, #-1)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xe0 0x02 0x26
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.eq(r2.new, #-1)) jump:t
> +# CHECK-NEXT: if (cmp.eq(r17.new, #-1)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xc0 0x42 0x26
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.eq(r2.new, #-1)) jump:nt
> +# CHECK-NEXT: if (!cmp.eq(r17.new, #-1)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xe0 0x42 0x26
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.eq(r2.new, #-1)) jump:t
> +# CHECK-NEXT: if (!cmp.eq(r17.new, #-1)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xc0 0x82 0x26
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gt(r2.new, #-1)) jump:nt
> +# CHECK-NEXT: if (cmp.gt(r17.new, #-1)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xe0 0x82 0x26
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (cmp.gt(r2.new, #-1)) jump:t
> +# CHECK-NEXT: if (cmp.gt(r17.new, #-1)) jump:t
>  0x11 0x40 0x71 0x70 0x92 0xc0 0xc2 0x26
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gt(r2.new, #-1)) jump:nt
> +# CHECK-NEXT: if (!cmp.gt(r17.new, #-1)) jump:nt
>  0x11 0x40 0x71 0x70 0x92 0xe0 0xc2 0x26
>  # CHECK: r17 = r17
> -# CHECK-NEXT: if (!cmp.gt(r2.new, #-1)) jump:t
> +# CHECK-NEXT: if (!cmp.gt(r17.new, #-1)) jump:t
>
> Modified: llvm/trunk/test/MC/Disassembler/Hexagon/nv_st.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Hexagon/nv_st.txt?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/Hexagon/nv_st.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/Hexagon/nv_st.txt Sun Nov  8 22:07:48
> 2015
> @@ -4,200 +4,209 @@
>  # Store new-value byte
>  0x1f 0x40 0x7f 0x70 0x82 0xf5 0xb1 0x3b
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memb(r17 + r21<<#3) = r2.new
> +# CHECK-NEXT: memb(r17 + r21<<#3) = r31.new
> +0x1f 0x40 0x7f 0x70 0x11 0xc2 0xa0 0x48
> +# CHECK: r31 = r31
> +# CHECK-NEXT: memb(#17) = r31.new
>  0x1f 0x40 0x7f 0x70 0x15 0xc2 0xb1 0xa1
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memb(r17+#21) = r2.new
> +# CHECK-NEXT: memb(r17+#21) = r31.new
>  0x1f 0x40 0x7f 0x70 0x02 0xe2 0xb1 0xa9
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memb(r17 ++ I:circ(m1)) = r2.new
> +# CHECK-NEXT: memb(r17 ++ I:circ(m1)) = r31.new
>  0x1f 0x40 0x7f 0x70 0x28 0xe2 0xb1 0xa9
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memb(r17 ++ #5:circ(m1)) = r2.new
> +# CHECK-NEXT: memb(r17 ++ #5:circ(m1)) = r31.new
>  0x1f 0x40 0x7f 0x70 0x28 0xc2 0xb1 0xab
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memb(r17++#5) = r2.new
> +# CHECK-NEXT: memb(r17++#5) = r31.new
>  0x1f 0x40 0x7f 0x70 0x00 0xe2 0xb1 0xad
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memb(r17++m1) = r2.new
> +# CHECK-NEXT: memb(r17++m1) = r31.new
>  0x1f 0x40 0x7f 0x70 0x00 0xe2 0xb1 0xaf
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memb(r17 ++ m1:brev) = r2.new
> +# CHECK-NEXT: memb(r17 ++ m1:brev) = r31.new
>
>  # Store new-value byte conditionally
>  0x1f 0x40 0x7f 0x70 0xe2 0xf5 0xb1 0x34
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (p3) memb(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (p3) memb(r17+r21<<#3) = r31.new
>  0x1f 0x40 0x7f 0x70 0xe2 0xf5 0xb1 0x35
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (!p3) memb(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (!p3) memb(r17+r21<<#3) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xe2 0xf5 0xb1 0x36
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (p3.new) memb(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (p3.new) memb(r17+r21<<#3) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xe2 0xf5 0xb1 0x37
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (!p3.new) memb(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (!p3.new) memb(r17+r21<<#3) = r31.new
>  0x1f 0x40 0x7f 0x70 0xab 0xc2 0xb1 0x40
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (p3) memb(r17+#21) = r2.new
> +# CHECK-NEXT: if (p3) memb(r17+#21) = r31.new
>  0x1f 0x40 0x7f 0x70 0xab 0xc2 0xb1 0x44
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (!p3) memb(r17+#21) = r2.new
> +# CHECK-NEXT: if (!p3) memb(r17+#21) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xc2 0xb1 0x42
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (p3.new) memb(r17+#21) = r2.new
> +# CHECK-NEXT: if (p3.new) memb(r17+#21) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xc2 0xb1 0x46
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (!p3.new) memb(r17+#21) = r2.new
> +# CHECK-NEXT: if (!p3.new) memb(r17+#21) = r31.new
>  0x1f 0x40 0x7f 0x70 0x2b 0xe2 0xb1 0xab
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (p3) memb(r17++#5) = r2.new
> +# CHECK-NEXT: if (p3) memb(r17++#5) = r31.new
>  0x1f 0x40 0x7f 0x70 0x2f 0xe2 0xb1 0xab
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (!p3) memb(r17++#5) = r2.new
> +# CHECK-NEXT: if (!p3) memb(r17++#5) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xe2 0xb1 0xab
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (p3.new) memb(r17++#5) = r2.new
> +# CHECK-NEXT: if (p3.new) memb(r17++#5) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xaf 0xe2 0xb1 0xab
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (!p3.new) memb(r17++#5) = r2.new
> +# CHECK-NEXT: if (!p3.new) memb(r17++#5) = r31.new
>
>  # Store new-value halfword
>  0x1f 0x40 0x7f 0x70 0x8a 0xf5 0xb1 0x3b
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memh(r17 + r21<<#3) = r2.new
> +# CHECK-NEXT: memh(r17 + r21<<#3) = r31.new
> +0x1f 0x40 0x7f 0x70 0x15 0xca 0xa0 0x48
> +# CHECK: r31 = r31
> +# CHECK-NEXT: memh(#42) = r31.new
>  0x1f 0x40 0x7f 0x70 0x15 0xca 0xb1 0xa1
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memh(r17+#42) = r2.new
> +# CHECK-NEXT: memh(r17+#42) = r31.new
>  0x1f 0x40 0x7f 0x70 0x02 0xea 0xb1 0xa9
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memh(r17 ++ I:circ(m1)) = r2.new
> +# CHECK-NEXT: memh(r17 ++ I:circ(m1)) = r31.new
>  0x1f 0x40 0x7f 0x70 0x28 0xea 0xb1 0xa9
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memh(r17 ++ #10:circ(m1)) = r2.new
> +# CHECK-NEXT: memh(r17 ++ #10:circ(m1)) = r31.new
>  0x1f 0x40 0x7f 0x70 0x28 0xca 0xb1 0xab
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memh(r17++#10) = r2.new
> +# CHECK-NEXT: memh(r17++#10) = r31.new
>  0x1f 0x40 0x7f 0x70 0x00 0xea 0xb1 0xad
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memh(r17++m1) = r2.new
> +# CHECK-NEXT: memh(r17++m1) = r31.new
>  0x1f 0x40 0x7f 0x70 0x00 0xea 0xb1 0xaf
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memh(r17 ++ m1:brev) = r2.new
> +# CHECK-NEXT: memh(r17 ++ m1:brev) = r31.new
>
>  # Store new-value halfword conditionally
>  0x1f 0x40 0x7f 0x70 0xea 0xf5 0xb1 0x34
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (p3) memh(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (p3) memh(r17+r21<<#3) = r31.new
>  0x1f 0x40 0x7f 0x70 0xea 0xf5 0xb1 0x35
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (!p3) memh(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (!p3) memh(r17+r21<<#3) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xea 0xf5 0xb1 0x36
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (p3.new) memh(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (p3.new) memh(r17+r21<<#3) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xea 0xf5 0xb1 0x37
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (!p3.new) memh(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (!p3.new) memh(r17+r21<<#3) = r31.new
>  0x1f 0x40 0x7f 0x70 0xab 0xca 0xb1 0x40
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (p3) memh(r17+#42) = r2.new
> +# CHECK-NEXT: if (p3) memh(r17+#42) = r31.new
>  0x1f 0x40 0x7f 0x70 0xab 0xca 0xb1 0x44
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (!p3) memh(r17+#42) = r2.new
> +# CHECK-NEXT: if (!p3) memh(r17+#42) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xca 0xb1 0x42
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (p3.new) memh(r17+#42) = r2.new
> +# CHECK-NEXT: if (p3.new) memh(r17+#42) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xca 0xb1 0x46
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (!p3.new) memh(r17+#42) = r2.new
> +# CHECK-NEXT: if (!p3.new) memh(r17+#42) = r31.new
>  0x1f 0x40 0x7f 0x70 0x2b 0xea 0xb1 0xab
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (p3) memh(r17++#10) = r2.new
> +# CHECK-NEXT: if (p3) memh(r17++#10) = r31.new
>  0x1f 0x40 0x7f 0x70 0x2f 0xea 0xb1 0xab
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (!p3) memh(r17++#10) = r2.new
> +# CHECK-NEXT: if (!p3) memh(r17++#10) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xea 0xb1 0xab
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (p3.new) memh(r17++#10) = r2.new
> +# CHECK-NEXT: if (p3.new) memh(r17++#10) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xaf 0xea 0xb1 0xab
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (!p3.new) memh(r17++#10) = r2.new
> +# CHECK-NEXT: if (!p3.new) memh(r17++#10) = r31.new
>
>  # Store new-value word
>  0x1f 0x40 0x7f 0x70 0x92 0xf5 0xb1 0x3b
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memw(r17 + r21<<#3) = r2.new
> -0x1f 0x40 0x7f 0x70 0x15 0xd2 0xb1 0xa1
> +# CHECK-NEXT: memw(r17 + r21<<#3) = r31.new
> +0x1f 0x40 0x7f 0x70 0x15 0xd2 0xa0 0x48
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memw(r17+#84) = r2.new
> -0x1f 0x40 0x7f 0x70 0x28 0xf2 0xb1 0xa9
> +# CHECK-NEXT: memw(#84) = r31.new
> +0x1f 0x40 0x7f 0x70 0x15 0xd2 0xb1 0xa1
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memw(r17 ++ #20:circ(m1)) = r2.new
> +# CHECK-NEXT: memw(r17+#84) = r31.new
>  0x1f 0x40 0x7f 0x70 0x02 0xf2 0xb1 0xa9
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memw(r17 ++ I:circ(m1)) = r2.new
> +# CHECK-NEXT: memw(r17 ++ I:circ(m1)) = r31.new
> +0x1f 0x40 0x7f 0x70 0x28 0xf2 0xb1 0xa9
> +# CHECK: r31 = r31
> +# CHECK-NEXT: memw(r17 ++ #20:circ(m1)) = r31.new
>  0x1f 0x40 0x7f 0x70 0x28 0xd2 0xb1 0xab
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memw(r17++#20) = r2.new
> +# CHECK-NEXT: memw(r17++#20) = r31.new
>  0x1f 0x40 0x7f 0x70 0x00 0xf2 0xb1 0xad
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memw(r17++m1) = r2.new
> +# CHECK-NEXT: memw(r17++m1) = r31.new
>  0x1f 0x40 0x7f 0x70 0x00 0xf2 0xb1 0xaf
>  # CHECK: r31 = r31
> -# CHECK-NEXT: memw(r17 ++ m1:brev) = r2.new
> +# CHECK-NEXT: memw(r17 ++ m1:brev) = r31.new
>
>  # Store new-value word conditionally
>  0x1f 0x40 0x7f 0x70 0xf2 0xf5 0xb1 0x34
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (p3) memw(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (p3) memw(r17+r21<<#3) = r31.new
>  0x1f 0x40 0x7f 0x70 0xf2 0xf5 0xb1 0x35
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (!p3) memw(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (!p3) memw(r17+r21<<#3) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xf2 0xf5 0xb1 0x36
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (p3.new) memw(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (p3.new) memw(r17+r21<<#3) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xf2 0xf5 0xb1 0x37
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (!p3.new) memw(r17+r21<<#3) = r2.new
> +# CHECK-NEXT: if (!p3.new) memw(r17+r21<<#3) = r31.new
>  0x1f 0x40 0x7f 0x70 0xab 0xd2 0xb1 0x40
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (p3) memw(r17+#84) = r2.new
> +# CHECK-NEXT: if (p3) memw(r17+#84) = r31.new
>  0x1f 0x40 0x7f 0x70 0xab 0xd2 0xb1 0x44
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (!p3) memw(r17+#84) = r2.new
> +# CHECK-NEXT: if (!p3) memw(r17+#84) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xd2 0xb1 0x42
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (p3.new) memw(r17+#84) = r2.new
> +# CHECK-NEXT: if (p3.new) memw(r17+#84) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xd2 0xb1 0x46
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (!p3.new) memw(r17+#84) = r2.new
> +# CHECK-NEXT: if (!p3.new) memw(r17+#84) = r31.new
>  0x1f 0x40 0x7f 0x70 0x2b 0xf2 0xb1 0xab
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (p3) memw(r17++#20) = r2.new
> +# CHECK-NEXT: if (p3) memw(r17++#20) = r31.new
>  0x1f 0x40 0x7f 0x70 0x2f 0xf2 0xb1 0xab
>  # CHECK: r31 = r31
> -# CHECK-NEXT: if (!p3) memw(r17++#20) = r2.new
> +# CHECK-NEXT: if (!p3) memw(r17++#20) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xab 0xf2 0xb1 0xab
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (p3.new) memw(r17++#20) = r2.new
> +# CHECK-NEXT: if (p3.new) memw(r17++#20) = r31.new
>  0x03 0x40 0x45 0x85 0x1f 0x40 0x7f 0x70 0xaf 0xf2 0xb1 0xab
>  # CHECK: p3 = r5
>  # CHECK-NEXT: r31 = r31
> -# CHECK-NEXT: if (!p3.new) memw(r17++#20) = r2.new
> +# CHECK-NEXT: if (!p3.new) memw(r17++#20) = r31.new
>
> Modified: llvm/trunk/test/MC/Disassembler/Hexagon/st.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Hexagon/st.txt?rev=252443&r1=252442&r2=252443&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/Hexagon/st.txt (original)
> +++ llvm/trunk/test/MC/Disassembler/Hexagon/st.txt Sun Nov  8 22:07:48 2015
> @@ -1,11 +1,14 @@
>  # RUN: llvm-mc -triple=hexagon -disassemble < %s | FileCheck %s
>  # Hexagon Programmer's Reference Manual 11.8 ST
> +# XFAIL: *
>
>  # Store doubleword
>  0x9e 0xf5 0xd1 0x3b
>  # CHECK: memd(r17 + r21<<#3) = r31:30
>  0x28 0xd4 0xc0 0x48
> -# CHECK: memd(##320) = r21:20
> +# CHECK: memd(#320) = r21:20
> +0x02 0x40 0x00 0x00 0x28 0xd4 0xc0 0x48
> +# CHECK: memd(##168) = r21:20
>  0x15 0xd4 0xd1 0xa1
>  # CHECK: memd(r17+#168) = r21:20
>  0x02 0xf4 0xd1 0xa9
> @@ -14,6 +17,8 @@
>  # CHECK: memd(r17 ++ #40:circ(m1)) = r21:20
>  0x28 0xd4 0xd1 0xab
>  # CHECK: memd(r17++#40) = r21:20
> +0x00 0x40 0x00 0x00 0xd5 0xfe 0xd1 0xad
> +# CHECK: memd(r17<<#3 + ##21) = r31:30
>  0x00 0xf4 0xd1 0xad
>  # CHECK: memd(r17++m1) = r21:20
>  0x00 0xf4 0xd1 0xaf
> @@ -50,6 +55,16 @@
>  0x03 0x40 0x45 0x85 0xaf 0xf4 0xd1 0xab
>  # CHECK: p3 = r5
>  # CHECK-NEXT: if (!p3.new) memd(r17++#40) = r21:20
> +0x02 0x40 0x00 0x00 0xc3 0xd4 0xc2 0xaf
> +# CHECK: if (p3) memd(##168) = r21:20
> +0x02 0x40 0x00 0x00 0xc7 0xd4 0xc2 0xaf
> +# CHECK: if (!p3) memd(##168) = r21:20
> +0x03 0x40 0x45 0x85 0x02 0x40 0x00 0x00 0xc3 0xf4 0xc2 0xaf
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (p3.new) memd(##168) = r21:20
> +0x03 0x40 0x45 0x85 0x02 0x40 0x00 0x00 0xc7 0xf4 0xc2 0xaf
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (!p3.new) memd(##168) = r21:20
>
>  # Store byte
>  0x9f 0xf5 0x11 0x3b
> @@ -57,6 +72,8 @@
>  0x9f 0xca 0x11 0x3c
>  # CHECK: memb(r17+#21)=#31
>  0x15 0xd5 0x00 0x48
> +# CHECK: memb(#21) = r21
> +0x00 0x40 0x00 0x00 0x15 0xd5 0x00 0x48
>  # CHECK: memb(##21) = r21
>  0x15 0xd5 0x11 0xa1
>  # CHECK: memb(r17+#21) = r21
> @@ -66,6 +83,8 @@
>  # CHECK: memb(r17 ++ #5:circ(m1)) = r21
>  0x28 0xd5 0x11 0xab
>  # CHECK: memb(r17++#5) = r21
> +0x00 0x40 0x00 0x00 0xd5 0xff 0x11 0xad
> +# CHECK: memb(r17<<#3 + ##21) = r31
>  0x00 0xf5 0x11 0xad
>  # CHECK: memb(r17++m1) = r21
>  0x00 0xf5 0x11 0xaf
> @@ -112,6 +131,16 @@
>  0x03 0x40 0x45 0x85 0xaf 0xf5 0x11 0xab
>  # CHECK: p3 = r5
>  # CHECK-NEXT: if (!p3.new) memb(r17++#5) = r21
> +0x00 0x40 0x00 0x00 0xab 0xd5 0x01 0xaf
> +# CHECK: if (p3) memb(##21) = r21
> +0x00 0x40 0x00 0x00 0xaf 0xd5 0x01 0xaf
> +# CHECK: if (!p3) memb(##21) = r21
> +0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xab 0xf5 0x01 0xaf
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (p3.new) memb(##21) = r21
> +0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xaf 0xf5 0x01 0xaf
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (!p3.new) memb(##21) = r21
>
>  # Store halfword
>  0x9f 0xf5 0x51 0x3b
> @@ -120,10 +149,14 @@
>  # CHECK: memh(r17 + r21<<#3) = r31.h
>  0x95 0xcf 0x31 0x3c
>  # CHECK: memh(r17+#62)=#21
> +0x00 0x40 0x00 0x00 0x2a 0xd5 0x40 0x48
> +# CHECK: memh(##42) = r21
> +0x00 0x40 0x00 0x00 0x2a 0xd5 0x60 0x48
> +# CHECK: memh(##42) = r21.h
>  0x2a 0xd5 0x40 0x48
> -# CHECK: memh(##84) = r21
> +# CHECK: memh(#84) = r21
>  0x2a 0xd5 0x60 0x48
> -# CHECK: memh(##84) = r21.h
> +# CHECK: memh(#84) = r21.h
>  0x15 0xdf 0x51 0xa1
>  # CHECK: memh(r17+#42) = r31
>  0x15 0xdf 0x71 0xa1
> @@ -138,8 +171,12 @@
>  # CHECK: memh(r17 ++ #10:circ(m1)) = r21.h
>  0x28 0xd5 0x51 0xab
>  # CHECK: memh(r17++#10) = r21
> +0x00 0x40 0x00 0x00 0xd5 0xff 0x51 0xad
> +# CHECK: memh(r17<<#3 + ##21) = r31
>  0x28 0xd5 0x71 0xab
>  # CHECK: memh(r17++#10) = r21.h
> +0x00 0x40 0x00 0x00 0xd5 0xff 0x71 0xad
> +# CHECK: memh(r17<<#3 + ##21) = r31.h
>  0x00 0xf5 0x51 0xad
>  # CHECK: memh(r17++m1) = r21
>  0x00 0xf5 0x71 0xad
> @@ -220,22 +257,48 @@
>  0x03 0x40 0x45 0x85 0xaf 0xf5 0x71 0xab
>  # CHECK: p3 = r5
>  # CHECK-NEXT: if (!p3.new) memh(r17++#10) = r21.h
> +0x00 0x40 0x00 0x00 0xd3 0xd5 0x42 0xaf
> +# CHECK: if (p3) memh(##42) = r21
> +0x00 0x40 0x00 0x00 0xd3 0xd5 0x62 0xaf
> +# CHECK: if (p3) memh(##42) = r21.h
> +0x00 0x40 0x00 0x00 0xd7 0xd5 0x42 0xaf
> +# CHECK: if (!p3) memh(##42) = r21
> +0x00 0x40 0x00 0x00 0xd7 0xd5 0x62 0xaf
> +# CHECK: if (!p3) memh(##42) = r21.h
> +0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xd3 0xf5 0x42 0xaf
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (p3.new) memh(##42) = r21
> +0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xd3 0xf5 0x62 0xaf
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (p3.new) memh(##42) = r21.h
> +0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xd7 0xf5 0x42 0xaf
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (!p3.new) memh(##42) = r21
> +0x03 0x40 0x45 0x85 0x00 0x40 0x00 0x00 0xd7 0xf5 0x62 0xaf
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (!p3.new) memh(##42) = r21.h
>
>  # Store word
>  0x9f 0xf5 0x91 0x3b
>  # CHECK: memw(r17 + r21<<#3) = r31
>  0x9f 0xca 0x51 0x3c
> +# CHECK: memw(r17{{ *}}+{{ *}}#84)=#31
> +0x15 0xdf 0x80 0x48
> +# CHECK: memw(#84) = r31
> +0x01 0x40 0x00 0x00 0x14 0xd5 0x80 0x48
> +# CHECK: memw(##84) = r21
> +0x9f 0xca 0x51 0x3c
>  # CHECK: memw(r17+#84)=#31
>  0x15 0xdf 0x91 0xa1
>  # CHECK: memw(r17+#84) = r31
> -0x14 0xd5 0x80 0x48
> -# CHECK: memw(##80) = r21
>  0x02 0xf5 0x91 0xa9
>  # CHECK: memw(r17 ++ I:circ(m1)) = r21
>  0x28 0xf5 0x91 0xa9
>  # CHECK: memw(r17 ++ #20:circ(m1)) = r21
>  0x28 0xd5 0x91 0xab
>  # CHECK: memw(r17++#20) = r21
> +0x00 0x40 0x00 0x00 0xd5 0xff 0x91 0xad
> +# CHECK: memw(r17<<#3 + ##21) = r31
>  0x00 0xf5 0x91 0xad
>  # CHECK: memw(r17++m1) = r21
>  0x00 0xf5 0x91 0xaf
> @@ -282,7 +345,17 @@
>  0x03 0x40 0x45 0x85 0xab 0xf5 0x91 0xab
>  # CHECK: p3 = r5
>  # CHECK-NEXT: if (p3.new) memw(r17++#20) = r21
> +0x01 0x40 0x00 0x00 0xa3 0xd5 0x81 0xaf
> +# CHECK: if (p3) memw(##84) = r21
> +0x01 0x40 0x00 0x00 0xa7 0xd5 0x81 0xaf
> +# CHECK: if (!p3) memw(##84) = r21
> +0x03 0x40 0x45 0x85 0x01 0x40 0x00 0x00 0xa3 0xf5 0x81 0xaf
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (p3.new) memw(##84) = r21
> +0x03 0x40 0x45 0x85 0x01 0x40 0x00 0x00 0xa7 0xf5 0x81 0xaf
> +# CHECK: p3 = r5
> +# CHECK-NEXT: if (!p3.new) memw(##84) = r21
>
>  # Allocate stack frame
>  0x1f 0xc0 0x9d 0xa0
> -# CHECK: allocframe(#248)
> \ No newline at end of file
> +# CHECK: allocframe(#248)
>
> Added: llvm/trunk/test/MC/Disassembler/Hexagon/too_many_instructions.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Hexagon/too_many_instructions.txt?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/Hexagon/too_many_instructions.txt
> (added)
> +++ llvm/trunk/test/MC/Disassembler/Hexagon/too_many_instructions.txt Sun
> Nov  8 22:07:48 2015
> @@ -0,0 +1,4 @@
> +# RUN: llvm-mc -triple=hexagon -disassemble < %s 2>&1 | FileCheck %s
> +
> +#CHECK: warning: invalid instruction encoding
> +0x00 0x40 0x00 0x7f 0x00 0x40 0x00 0x7f 0x00 0x40 0x00 0x7f 0x00 0x40
> 0x00 0x7f 0x00 0xc0 0x00 0x7f
> \ No newline at end of file
>
> Added: llvm/trunk/test/MC/Disassembler/Hexagon/too_many_loop_ends.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Hexagon/too_many_loop_ends.txt?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/Hexagon/too_many_loop_ends.txt (added)
> +++ llvm/trunk/test/MC/Disassembler/Hexagon/too_many_loop_ends.txt Sun
> Nov  8 22:07:48 2015
> @@ -0,0 +1,4 @@
> +# RUN: llvm-mc -triple=hexagon -disassemble < %s 2>&1 | FileCheck %s
> +
> +#CHECK: warning: invalid instruction encoding
> +0x00 0x80 0x00 0x7f 0x00 0x80 0x00 0x7f 0x00 0x80 0x00 0x7f 0x00 0xc0
> 0x00 0x7f
> \ No newline at end of file
>
> Added: llvm/trunk/test/MC/Disassembler/Hexagon/unextendable.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/Hexagon/unextendable.txt?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Disassembler/Hexagon/unextendable.txt (added)
> +++ llvm/trunk/test/MC/Disassembler/Hexagon/unextendable.txt Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,9 @@
> +# RUN: llvm-mc -triple=hexagon -disassemble < %s 2>&1 | FileCheck %s
> +
> +#Invalid immediate extend duplex load/load
> +#CHECK: warning: invalid instruction encoding
> +0xfe 0x40 0x00 0x00 0x11 0x00 0x00 0x00
> +
> +#Invalid immediate extend barrier
> +#CHECK: warning: invalid instruction encoding
> +0xfe 0x40 0x00 0x00 0x00 0xc0 0x00 0xa8
> \ No newline at end of file
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/alu32_alu.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/alu32_alu.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/alu32_alu.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/alu32_alu.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,84 @@
> +# RUN: llvm-mc -triple hexagon -filetype=obj %s | llvm-objdump -d - |
> FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.1.1 ALU32/ALU
> +
> +# Add
> +# CHECK: f1 c3 15 b0
> +r17 = add(r21, #31)
> +# CHECK: 11 df 15 f3
> +r17 = add(r21, r31)
> +# CHECK: 11 df 55 f6
> +r17 = add(r21, r31):sat
> +
> +# And
> +# CHECK: f1 c3 15 76
> +r17 = and(r21, #31)
> +# CHECK: f1 c3 95 76
> +r17 = or(r21, #31)
> +# CHECK: 11 df 15 f1
> +r17 = and(r21, r31)
> +# CHECK: 11 df 35 f1
> +r17 = or(r21, r31)
> +# CHECK: 11 df 75 f1
> +r17 = xor(r21, r31)
> +# CHECK: 11 d5 9f f1
> +r17 = and(r21, ~r31)
> +# CHECK: 11 d5 bf f1
> +r17 = or(r21, ~r31)
> +
> +# Nop
> +# CHECK: 00 c0 00 7f
> +nop
> +
> +# Subtract
> +# CHECK: b1 c2 5f 76
> +r17 = sub(#21, r31)
> +# CHECK: 11 df 35 f3
> +r17 = sub(r31, r21)
> +# CHECK: 11 df d5 f6
> +r17 = sub(r31, r21):sat
> +
> +# Sign extend
> +# CHECK: 11 c0 bf 70
> +r17 = sxtb(r31)
> +
> +# Transfer immediate
> +# CHECK: 15 c0 31 72
> +r17.h = #21
> +# CHECK: 15 c0 31 71
> +r17.l = #21
> +# CHECK: f1 ff 5f 78
> +r17 = #32767
> +# CHECK: f1 ff df 78
> +r17 = #-1
> +
> +# Transfer register
> +# CHECK: 11 c0 75 70
> +r17 = r21
> +
> +# Vector add halfwords
> +# CHECK: 11 df 15 f6
> +r17 = vaddh(r21, r31)
> +# CHECK: 11 df 35 f6
> +r17 = vaddh(r21, r31):sat
> +# CHECK: 11 df 75 f6
> +r17 = vadduh(r21, r31):sat
> +
> +# Vector average halfwords
> +# CHECK: 11 df 15 f7
> +r17 = vavgh(r21, r31)
> +# CHECK: 11 df 35 f7
> +r17 = vavgh(r21, r31):rnd
> +# CHECK: 11 df 75 f7
> +r17 = vnavgh(r31, r21)
> +
> +# Vector subtract halfwords
> +# CHECK: 11 df 95 f6
> +r17 = vsubh(r31, r21)
> +# CHECK: 11 df b5 f6
> +r17 = vsubh(r31, r21):sat
> +# CHECK: 11 df f5 f6
> +r17 = vsubuh(r31, r21):sat
> +
> +# Zero extend
> +# CHECK: 11 c0 d5 70
> +r17 = zxth(r21)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/alu32_perm.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/alu32_perm.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/alu32_perm.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/alu32_perm.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,40 @@
> +# RUN: llvm-mc -triple hexagon -filetype=obj %s -o - | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.1.2 ALU32/PERM
> +
> +# Combine words in to doublewords
> +# CHECK: 11 df 95 f3
> +r17 = combine(r31.h, r21.h)
> +# CHECK: 11 df b5 f3
> +r17 = combine(r31.h, r21.l)
> +# CHECK: 11 df d5 f3
> +r17 = combine(r31.l, r21.h)
> +# CHECK: 11 df f5 f3
> +r17 = combine(r31.l, r21.l)
> +# CHECK: b0 e2 0f 7c
> +r17:16 = combine(#21, #31)
> +# CHECK: b0 e2 3f 73
> +r17:16 = combine(#21, r31)
> +# CHECK: f0 e3 15 73
> +r17:16 = combine(r21, #31)
> +# CHECK: 10 df 15 f5
> +r17:16 = combine(r21, r31)
> +
> +# Mux
> +# CHECK: f1 c3 75 73
> +r17 = mux(p3, r21, #31)
> +# CHECK: b1 c2 ff 73
> +r17 = mux(p3, #21, r31)
> +# CHECK: b1 e2 8f 7b
> +r17 = mux(p3, #21, #31)
> +# CHECK: 71 df 15 f4
> +r17 = mux(p3, r21, r31)
> +
> +# Shift word by 16
> +# CHECK: 11 c0 15 70
> +r17 = aslh(r21)
> +# CHECK: 11 c0 35 70
> +r17 = asrh(r21)
> +
> +# Pack high and low halfwords
> +# CHECK: 10 df 95 f5
> +r17:16 = packhl(r21, r31)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/alu32_pred.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/alu32_pred.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/alu32_pred.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/alu32_pred.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,222 @@
> +# RUN: llvm-mc -triple hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.1.3 ALU32/PRED
> +
> +# Conditional add
> +# CHECK: f1 c3 75 74
> +if (p3) r17 = add(r21, #31)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 e3 75 74
> +{ p3 = r5
> +  if (p3.new) r17 = add(r21, #31) }
> +# CHECK: f1 c3 f5 74
> +if (!p3) r17 = add(r21, #31)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 e3 f5 74
> +{ p3 = r5
> +  if (!p3.new) r17 = add(r21, #31) }
> +# CHECK: 71 df 15 fb
> +if (p3) r17 = add(r21, r31)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 71 ff 15 fb
> +{ p3 = r5
> +  if (p3.new) r17 = add(r21, r31) }
> +# CHECK: f1 df 15 fb
> +if (!p3) r17 = add(r21, r31)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 15 fb
> +{ p3 = r5
> +  if (!p3.new) r17 = add(r21, r31) }
> +
> +# Conditional shift halfword
> +# CHECK: 11 e3 15 70
> +if (p3) r17 = aslh(r21)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 e7 15 70
> +{ p3 = r5
> +  if (p3.new) r17 = aslh(r21) }
> +# CHECK: 11 eb 15 70
> +if (!p3) r17 = aslh(r21)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 ef 15 70
> +{ p3 = r5
> +  if (!p3.new) r17 = aslh(r21) }
> +# CHECK: 11 e3 35 70
> +if (p3) r17 = asrh(r21)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 e7 35 70
> +{ p3 = r5
> +  if (p3.new) r17 = asrh(r21) }
> +# CHECK: 11 eb 35 70
> +if (!p3) r17 = asrh(r21)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 ef 35 70
> +{ p3 = r5
> +  if (!p3.new) r17 = asrh(r21) }
> +
> +# Conditional combine
> +# CHECK: 70 df 15 fd
> +if (p3) r17:16 = combine(r21, r31)
> +# CHECK: f0 df 15 fd
> +if (!p3) r17:16 = combine(r21, r31)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 70 ff 15 fd
> +{ p3 = r5
> +  if (p3.new) r17:16 = combine(r21, r31) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f0 ff 15 fd
> +{ p3 = r5
> +  if (!p3.new) r17:16 = combine(r21, r31) }
> +
> +# Conditional logical operations
> +# CHECK: 71 df 15 f9
> +if (p3) r17 = and(r21, r31)
> +# CHECK: f1 df 15 f9
> +if (!p3) r17 = and(r21, r31)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 71 ff 15 f9
> +{ p3 = r5
> +  if (p3.new) r17 = and(r21, r31) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 15 f9
> +{ p3 = r5
> +  if (!p3.new) r17 = and(r21, r31) }
> +# CHECK: 71 df 35 f9
> +if (p3) r17 = or(r21, r31)
> +# CHECK: f1 df 35 f9
> +if (!p3) r17 = or(r21, r31)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 71 ff 35 f9
> +{ p3 = r5
> +  if (p3.new) r17 = or(r21, r31) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 35 f9
> +{ p3 = r5
> +  if (!p3.new) r17 = or(r21, r31) }
> +# CHECK: 71 df 75 f9
> +if (p3) r17 = xor(r21, r31)
> +# CHECK: f1 df 75 f9
> +if (!p3) r17 = xor(r21, r31)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 71 ff 75 f9
> +{ p3 = r5
> +  if (p3.new) r17 = xor(r21, r31) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 75 f9
> +{ p3 = r5
> +  if (!p3.new) r17 = xor(r21, r31) }
> +
> +# Conditional subtract
> +# CHECK: 71 df 35 fb
> +if (p3) r17 = sub(r31, r21)
> +# CHECK: f1 df 35 fb
> +if (!p3) r17 = sub(r31, r21)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 71 ff 35 fb
> +{ p3 = r5
> +  if (p3.new) r17 = sub(r31, r21) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 35 fb
> +{ p3 = r5
> +  if (!p3.new) r17 = sub(r31, r21) }
> +
> +# Conditional sign extend
> +# CHECK: 11 e3 b5 70
> +if (p3) r17 = sxtb(r21)
> +# CHECK: 11 eb b5 70
> +if (!p3) r17 = sxtb(r21)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 e7 b5 70
> +{ p3 = r5
> +  if (p3.new) r17 = sxtb(r21) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 ef b5 70
> +{ p3 = r5
> +  if (!p3.new) r17 = sxtb(r21) }
> +# CHECK: 11 e3 f5 70
> +if (p3) r17 = sxth(r21)
> +# CHECK: 11 eb f5 70
> +if (!p3) r17 = sxth(r21)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 e7 f5 70
> +{ p3 = r5
> +  if (p3.new) r17 = sxth(r21) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 ef f5 70
> +{ p3 = r5
> +  if (!p3.new) r17 = sxth(r21) }
> +
> +# Conditional transfer
> +# CHECK: b1 c2 60 7e
> +if (p3) r17 = #21
> +# CHECK: b1 c2 e0 7e
> +if (!p3) r17 = #21
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 e2 60 7e
> +{ p3 = r5
> +  if (p3.new) r17 = #21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 e2 e0 7e
> +{ p3 = r5
> +  if (!p3.new) r17 = #21 }
> +
> +# Conditional zero extend
> +# CHECK: 11 e3 95 70
> +if (p3) r17 = zxtb(r21)
> +# CHECK: 11 eb 95 70
> +if (!p3) r17 = zxtb(r21)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 e7 95 70
> +{ p3 = r5
> +  if (p3.new) r17 = zxtb(r21) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 ef 95 70
> +{ p3 = r5
> +  if (!p3.new) r17 = zxtb(r21) }
> +# CHECK: 11 e3 d5 70
> +if (p3) r17 = zxth(r21)
> +# CHECK: 11 eb d5 70
> +if (!p3) r17 = zxth(r21)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 e7 d5 70
> +{ p3 = r5
> +  if (p3.new) r17 = zxth(r21) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 11 ef d5 70
> +{ p3 = r5
> +  if (!p3.new) r17 = zxth(r21) }
> +
> +# Compare
> +# CHECK: e3 c3 15 75
> +p3 = cmp.eq(r21, #31)
> +# CHECK: f3 c3 15 75
> +p3 = !cmp.eq(r21, #31)
> +# CHECK: e3 c3 55 75
> +p3 = cmp.gt(r21, #31)
> +# CHECK: f3 c3 55 75
> +p3 = !cmp.gt(r21, #31)
> +# CHECK: e3 c3 95 75
> +p3 = cmp.gtu(r21, #31)
> +# CHECK: f3 c3 95 75
> +p3 = !cmp.gtu(r21, #31)
> +# CHECK: 03 df 15 f2
> +p3 = cmp.eq(r21, r31)
> +# CHECK: 13 df 15 f2
> +p3 = !cmp.eq(r21, r31)
> +# CHECK: 03 df 55 f2
> +p3 = cmp.gt(r21, r31)
> +# CHECK: 13 df 55 f2
> +p3 = !cmp.gt(r21, r31)
> +# CHECK: 03 df 75 f2
> +p3 = cmp.gtu(r21, r31)
> +# CHECK: 13 df 75 f2
> +p3 = !cmp.gtu(r21, r31)
> +
> +# Compare to general register
> +# CHECK: f1 e3 55 73
> +r17 = cmp.eq(r21, #31)
> +# CHECK: f1 e3 75 73
> +r17 = !cmp.eq(r21, #31)
> +# CHECK: 11 df 55 f3
> +r17 = cmp.eq(r21, r31)
> +# CHECK: 11 df 75 f3
> +r17 = !cmp.eq(r21, r31)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/cr.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/cr.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/cr.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/cr.s Sun Nov  8 22:07:48 2015
> @@ -0,0 +1,78 @@
> +# RUN: llvm-mc --triple hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.2 CR
> +
> +# Corner detection acceleration
> +# CHECK: 93 e1 12 6b
> +p3 = !fastcorner9(p2, p1)
> +# CHECK: 91 e3 02 6b
> +p1 = fastcorner9(p2, p3)
> +
> +# Logical reductions on predicates
> +# CHECK: 01 c0 82 6b
> +p1 = any8(p2)
> +# CHECK: 01 c0 a2 6b
> +p1 = all8(p2)
> +
> +# Looping instructions
> +# CHECK: 00 c0 15 60
> +loop0(0, r21)
> +# CHECK: 00 c0 35 60
> +loop1(0, r21)
> +# CHECK: 60 c0 00 69
> +loop0(0, #12)
> +# CHECK: 60 c0 20 69
> +loop1(0, #12)
> +
> +# Add to PC
> +# CHECK: 91 ca 49 6a
> +r17 = add(pc, #21)
> +
> +# Pipelined loop instructions
> +# CHECK: 00 c0 b5 60
> +p3 = sp1loop0(0, r21)
> +# CHECK: 00 c0 d5 60
> +p3 = sp2loop0(0, r21)
> +# CHECK: 00 c0 f5 60
> +p3 = sp3loop0(0, r21)
> +# CHECK: a1 c0 a0 69
> +p3 = sp1loop0(0, #21)
> +# CHECK: a1 c0 c0 69
> +p3 = sp2loop0(0, #21)
> +# CHECK: a1 c0 e0 69
> +p3 = sp3loop0(0, #21)
> +
> +# Logical operations on predicates
> +# CHECK: 01 c3 02 6b
> +p1 = and(p3, p2)
> +# CHECK: c1 c3 12 6b
> +p1 = and(p2, and(p3, p3))
> +# CHECK: 01 c3 22 6b
> +p1 = or(p3, p2)
> +# CHECK: c1 c3 32 6b
> +p1 = and(p2, or(p3, p3))
> +# CHECK: 01 c3 42 6b
> +p1 = xor(p2, p3)
> +# CHECK: c1 c3 52 6b
> +p1 = or(p2, and(p3, p3))
> +# CHECK: 01 c2 63 6b
> +p1 = and(p2, !p3)
> +# CHECK: c1 c3 72 6b
> +p1 = or(p2, or(p3, p3))
> +# CHECK: c1 c3 92 6b
> +p1 = and(p2, and(p3, !p3))
> +# CHECK: c1 c3 b2 6b
> +p1 = and(p2, or(p3, !p3))
> +# CHECK: 01 c0 c2 6b
> +p1 = not(p2)
> +# CHECK: c1 c3 d2 6b
> +p1 = or(p2, and(p3, !p3))
> +# CHECK: 01 c2 e3 6b
> +p1 = or(p2, !p3)
> +# CHECK: c1 c3 f2 6b
> +p1 = or(p2, or(p3, !p3))
> +
> +# User control register transfer
> +# CHECK: 0d c0 35 62
> +cs1 = r21
> +# CHECK: 11 c0 0d 6a
> +r17 = cs1
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/j.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/j.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/j.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/j.s Sun Nov  8 22:07:48 2015
> @@ -0,0 +1,207 @@
> +# RUN: llvm-mc -triple hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.4 J
> +# XFAIL: *
> +
> +# Call subroutine
> +# CHECK: 00 c0 00 5a
> +call 0
> +# CHECK: 00 c3 00 5d
> +if (p3) call 0
> +# CHECK: 00 c3 20 5d
> +if (!p3) call 0
> +
> +# Compare and jump
> +# CHECK: 00 c0 89 11
> +{ p0 = cmp.eq(r17,#-1); if (p0.new) jump:nt 0 }
> +# CHECK: 00 c1 89 11
> +{ p0 = cmp.gt(r17,#-1); if (p0.new) jump:nt 0 }
> +# CHECK: 00 c3 89 11
> +{ p0 = tstbit(r17, #0); if (p0.new) jump:nt 0 }
> +# CHECK: 00 e0 89 11
> +{ p0 = cmp.eq(r17,#-1); if (p0.new) jump:t 0 }
> +# CHECK: 00 e1 89 11
> +{ p0 = cmp.gt(r17,#-1); if (p0.new) jump:t 0 }
> +# CHECK: 00 e3 89 11
> +{ p0 = tstbit(r17, #0); if (p0.new) jump:t 0 }
> +# CHECK: 00 c0 c9 11
> +{ p0 = cmp.eq(r17,#-1); if (!p0.new) jump:nt 0 }
> +# CHECK: 00 c1 c9 11
> +{ p0 = cmp.gt(r17,#-1); if (!p0.new) jump:nt 0 }
> +# CHECK: 00 c3 c9 11
> +{ p0 = tstbit(r17, #0); if (!p0.new) jump:nt 0 }
> +# CHECK: 00 e0 c9 11
> +{ p0 = cmp.eq(r17,#-1); if (!p0.new) jump:t 0 }
> +# CHECK: 00 e1 c9 11
> +{ p0 = cmp.gt(r17,#-1); if (!p0.new) jump:t 0 }
> +# CHECK: 00 e3 c9 11
> +{ p0 = tstbit(r17, #0); if (!p0.new) jump:t 0 }
> +# CHECK: 00 d5 09 10
> +{ p0 = cmp.eq(r17, #21); if (p0.new) jump:nt 0 }
> +# CHECK: 00 f5 09 10
> +{ p0 = cmp.eq(r17, #21); if (p0.new) jump:t 0 }
> +# CHECK: 00 d5 49 10
> +{ p0 = cmp.eq(r17, #21); if (!p0.new) jump:nt 0 }
> +# CHECK: 00 f5 49 10
> +{ p0 = cmp.eq(r17, #21); if (!p0.new) jump:t 0 }
> +# CHECK: 00 d5 89 10
> +{ p0 = cmp.gt(r17, #21); if (p0.new) jump:nt 0 }
> +# CHECK: 00 f5 89 10
> +{ p0 = cmp.gt(r17, #21); if (p0.new) jump:t 0 }
> +# CHECK: 00 d5 c9 10
> +{ p0 = cmp.gt(r17, #21); if (!p0.new) jump:nt 0 }
> +# CHECK: 00 f5 c9 10
> +{ p0 = cmp.gt(r17, #21); if (!p0.new) jump:t 0 }
> +# CHECK: 00 d5 09 11
> +{ p0 = cmp.gtu(r17, #21); if (p0.new) jump:nt 0 }
> +# CHECK: 00 f5 09 11
> +{ p0 = cmp.gtu(r17, #21); if (p0.new) jump:t 0 }
> +# CHECK: 00 d5 49 11
> +{ p0 = cmp.gtu(r17, #21); if (!p0.new) jump:nt 0 }
> +# CHECK: 00 f5 49 11
> +{ p0 = cmp.gtu(r17, #21); if (!p0.new) jump:t 0 }
> +# CHECK: 00 c0 89 13
> +{ p1 = cmp.eq(r17,#-1); if (p1.new) jump:nt 0 }
> +# CHECK: 00 c1 89 13
> +{ p1 = cmp.gt(r17,#-1); if (p1.new) jump:nt 0 }
> +# CHECK: 00 c3 89 13
> +{ p1 = tstbit(r17, #0); if (p1.new) jump:nt 0 }
> +# CHECK: 00 e0 89 13
> +{ p1 = cmp.eq(r17,#-1); if (p1.new) jump:t 0 }
> +# CHECK: 00 e1 89 13
> +{ p1 = cmp.gt(r17,#-1); if (p1.new) jump:t 0 }
> +# CHECK: 00 e3 89 13
> +{ p1 = tstbit(r17, #0); if (p1.new) jump:t 0 }
> +# CHECK: 00 c0 c9 13
> +{ p1 = cmp.eq(r17,#-1); if (!p1.new) jump:nt 0 }
> +# CHECK: 00 c1 c9 13
> +{ p1 = cmp.gt(r17,#-1); if (!p1.new) jump:nt 0 }
> +# CHECK: 00 c3 c9 13
> +{ p1 = tstbit(r17, #0); if (!p1.new) jump:nt 0 }
> +# CHECK: 00 e0 c9 13
> +{ p1 = cmp.eq(r17,#-1); if (!p1.new) jump:t 0 }
> +# CHECK: 00 e1 c9 13
> +{ p1 = cmp.gt(r17,#-1); if (!p1.new) jump:t 0 }
> +# CHECK: 00 e3 c9 13
> +{ p1 = tstbit(r17, #0); if (!p1.new) jump:t 0 }
> +# CHECK: 00 d5 09 12
> +{ p1 = cmp.eq(r17, #21); if (p1.new) jump:nt 0 }
> +# CHECK: 00 f5 09 12
> +{ p1 = cmp.eq(r17, #21); if (p1.new) jump:t 0 }
> +# CHECK: 00 d5 49 12
> +{ p1 = cmp.eq(r17, #21); if (!p1.new) jump:nt 0 }
> +# CHECK: 00 f5 49 12
> +{ p1 = cmp.eq(r17, #21); if (!p1.new) jump:t 0 }
> +# CHECK: 00 d5 89 12
> +{ p1 = cmp.gt(r17, #21); if (p1.new) jump:nt 0 }
> +# CHECK: 00 f5 89 12
> +{ p1 = cmp.gt(r17, #21); if (p1.new) jump:t 0 }
> +# CHECK: 00 d5 c9 12
> +{ p1 = cmp.gt(r17, #21); if (!p1.new) jump:nt 0 }
> +# CHECK: 00 f5 c9 12
> +{ p1 = cmp.gt(r17, #21); if (!p1.new) jump:t 0 }
> +# CHECK: 00 d5 09 13
> +{ p1 = cmp.gtu(r17, #21); if (p1.new) jump:nt 0 }
> +# CHECK: 00 f5 09 13
> +{ p1 = cmp.gtu(r17, #21); if (p1.new) jump:t 0 }
> +# CHECK: 00 d5 49 13
> +{ p1 = cmp.gtu(r17, #21); if (!p1.new) jump:nt 0 }
> +# CHECK: 00 f5 49 13
> +{ p1 = cmp.gtu(r17, #21); if (!p1.new) jump:t 0 }
> +# CHECK: 00 cd 09 14
> +{ p0 = cmp.eq(r17, r21); if (p0.new) jump:nt 0 }
> +# CHECK: 00 dd 09 14
> +{ p1 = cmp.eq(r17, r21); if (p1.new) jump:nt 0 }
> +# CHECK: 00 ed 09 14
> +{ p0 = cmp.eq(r17, r21); if (p0.new) jump:t 0 }
> +# CHECK: 00 fd 09 14
> +{ p1 = cmp.eq(r17, r21); if (p1.new) jump:t 0 }
> +# CHECK: 00 cd 49 14
> +{ p0 = cmp.eq(r17, r21); if (!p0.new) jump:nt 0 }
> +# CHECK: 00 dd 49 14
> +{ p1 = cmp.eq(r17, r21); if (!p1.new) jump:nt 0 }
> +# CHECK: 00 ed 49 14
> +{ p0 = cmp.eq(r17, r21); if (!p0.new) jump:t 0 }
> +# CHECK: 00 fd 49 14
> +{ p1 = cmp.eq(r17, r21); if (!p1.new) jump:t 0 }
> +# CHECK: 00 cd 89 14
> +{ p0 = cmp.gt(r17, r21); if (p0.new) jump:nt 0 }
> +# CHECK: 00 dd 89 14
> +{ p1 = cmp.gt(r17, r21); if (p1.new) jump:nt 0 }
> +# CHECK: 00 ed 89 14
> +{ p0 = cmp.gt(r17, r21); if (p0.new) jump:t 0 }
> +# CHECK: 00 fd 89 14
> +{ p1 = cmp.gt(r17, r21); if (p1.new) jump:t 0 }
> +# CHECK: 00 cd c9 14
> +{ p0 = cmp.gt(r17, r21); if (!p0.new) jump:nt 0 }
> +# CHECK: 00 dd c9 14
> +{ p1 = cmp.gt(r17, r21); if (!p1.new) jump:nt 0 }
> +# CHECK: 00 ed c9 14
> +{ p0 = cmp.gt(r17, r21); if (!p0.new) jump:t 0 }
> +# CHECK: 00 fd c9 14
> +{ p1 = cmp.gt(r17, r21); if (!p1.new) jump:t 0 }
> +# CHECK: 00 cd 09 15
> +{ p0 = cmp.gtu(r17, r21); if (p0.new) jump:nt 0 }
> +# CHECK: 00 dd 09 15
> +{ p1 = cmp.gtu(r17, r21); if (p1.new) jump:nt 0 }
> +# CHECK: 00 ed 09 15
> +{ p0 = cmp.gtu(r17, r21); if (p0.new) jump:t 0 }
> +# CHECK: 00 fd 09 15
> +{ p1 = cmp.gtu(r17, r21); if (p1.new) jump:t 0 }
> +# CHECK: 00 cd 49 15
> +{ p0 = cmp.gtu(r17, r21); if (!p0.new) jump:nt 0 }
> +# CHECK: 00 dd 49 15
> +{ p1 = cmp.gtu(r17, r21); if (!p1.new) jump:nt 0 }
> +# CHECK: 00 ed 49 15
> +{ p0 = cmp.gtu(r17, r21); if (!p0.new) jump:t 0 }
> +# CHECK: 00 fd 49 15
> +{ p1 = cmp.gtu(r17, r21); if (!p1.new) jump:t 0 }
> +
> +# Jump to address
> +# CHECK: 00 c0 00 58
> +jump 0
> +# CHECK: 00 c3 00 5c
> +if (p3) jump 0
> +# CHECK: 00 c3 20 5c
> +if (!p3) jump 0
> +
> +# Jump to address conditioned on new predicate
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 cb 00 5c
> +{ p3 = r5
> +  if (p3.new) jump:nt 0 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 db 00 5c
> +{ p3 = r5
> +  if (p3.new) jump:t 0 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 cb 20 5c
> +{ p3 = r5
> +  if (!p3.new) jump:nt 0 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 db 20 5c
> +{ p3 = r5
> +  if (!p3.new) jump:t 0 }
> +
> +# Jump to address conditioned on register value
> +# CHECK: 00 c0 11 61
> +if (r17!=#0) jump:nt 0
> +# CHECK: 00 d0 11 61
> +if (r17!=#0) jump:t 0
> +# CHECK: 00 c0 51 61
> +if (r17>=#0) jump:nt 0
> +# CHECK: 00 d0 51 61
> +if (r17>=#0) jump:t 0
> +# CHECK: 00 c0 91 61
> +if (r17==#0) jump:nt 0
> +# CHECK: 00 d0 91 61
> +if (r17==#0) jump:t 0
> +# CHECK: 00 c0 d1 61
> +if (r17<=#0) jump:nt 0
> +# CHECK: 00 d0 d1 61
> +if (r17<=#0) jump:t 0
> +
> +# Transfer and jump
> +# CHECK: 00 d5 09 16
> +{ r17 = #21 ; jump 0}
> +# CHECK: 00 c9 0d 17
> +{ r17 = r21 ; jump 0 }
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/jr.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/jr.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/jr.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/jr.s Sun Nov  8 22:07:48 2015
> @@ -0,0 +1,38 @@
> +# RUN: llvm-mc -triple hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.3 JR
> +
> +# Call subroutine from register
> +# CHECK: 00 c0 b5 50
> +callr r21
> +# CHECK: 00 c1 15 51
> +if (p1) callr r21
> +# CHECK: 00 c3 35 51
> +if (!p3) callr r21
> +
> +# Hint an indirect jump address
> +# CHECK: 00 c0 b5 52
> +hintjr(r21)
> +
> +# Jump to address from register
> +# CHECK: 00 c0 95 52
> +jumpr r21
> +# CHECK: 00 c1 55 53
> +if (p1) jumpr r21
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 cb 55 53
> +{ p3 = r5
> +  if (p3.new) jumpr:nt r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 db 55 53
> +{ p3 = r5
> +  if (p3.new) jumpr:t r21 }
> +# CHECK: 00 c3 75 53
> +if (!p3) jumpr r21
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 cb 75 53
> +{ p3 = r5
> +  if (!p3.new) jumpr:nt r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 db 75 53
> +{ p3 = r5
> +  if (!p3.new) jumpr:t r21 }
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/ld.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/ld.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/ld.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/ld.s Sun Nov  8 22:07:48 2015
> @@ -0,0 +1,499 @@
> +# RUN: llvm-mc -triple hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.5 LD
> +# XFAIL: *
> +
> +# Load doubleword
> +# CHECK: 90 ff d5 3a
> +r17:16 = memd(r21 + r31<<#3)
> +# CHECK: b0 c2 c0 49
> +r17:16 = memd(#168)
> +# CHECK: 02 40 00 00
> +# CHECK-NEXT: 10 c5 c0 49
> +r17:16 = memd(##168)
> +# CHECK: d0 c0 d5 91
> +r17:16 = memd(r21 + #48)
> +# CHECK: b0 e0 d5 99
> +r17:16 = memd(r21 ++ #40:circ(m1))
> +# CHECK: 10 e2 d5 99
> +r17:16 = memd(r21 ++ I:circ(m1))
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 70 d7 d5 9b
> +r17:16 = memd(r21 = ##31)
> +# CHECK: b0 c0 d5 9b
> +r17:16 = memd(r21++#40)
> +# CHECK: 10 e0 d5 9d
> +r17:16 = memd(r21++m1)
> +# CHECK: 10 e0 d5 9f
> +r17:16 = memd(r21 ++ m1:brev)
> +
> +# Load doubleword conditionally
> +# CHECK: f0 ff d5 30
> +if (p3) r17:16 = memd(r21+r31<<#3)
> +# CHECK: f0 ff d5 31
> +if (!p3) r17:16 = memd(r21+r31<<#3)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f0 ff d5 32
> +{ p3 = r5
> +  if (p3.new) r17:16 = memd(r21+r31<<#3) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f0 ff d5 33
> +{ p3 = r5
> +  if (!p3.new) r17:16 = memd(r21+r31<<#3) }
> +# CHECK: 70 d8 d5 41
> +if (p3) r17:16 = memd(r21 + #24)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 70 d8 d5 43
> +{ p3 = r5
> +  if (p3.new) r17:16 = memd(r21 + #24) }
> +# CHECK: 70 d8 d5 45
> +if (!p3) r17:16 = memd(r21 + #24)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 70 d8 d5 47
> +{ p3 = r5
> +  if (!p3.new) r17:16 = memd(r21 + #24) }
> +# CHECK: b0 e6 d5 9b
> +if (p3) r17:16 = memd(r21++#40)
> +# CHECK: b0 ee d5 9b
> +if (!p3) r17:16 = memd(r21++#40)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b0 f6 d5 9b
> +{ p3 = r5
> +  if (p3.new) r17:16 = memd(r21++#40) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b0 fe d5 9b
> +{ p3 = r5
> +  if (!p3.new) r17:16 = memd(r21++#40) }
> +
> +# Load byte
> +# CHECK: 91 ff 15 3a
> +r17 = memb(r21 + r31<<#3)
> +# CHECK: b1 c2 00 49
> +r17 = memb(#21)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: b1 c2 00 49
> +r17 = memb(##21)
> +# CHECK: f1 c3 15 91
> +r17 = memb(r21 + #31)
> +# CHECK: b1 e0 15 99
> +r17 = memb(r21 ++ #5:circ(m1))
> +# CHECK: 11 e2 15 99
> +r17 = memb(r21 ++ I:circ(m1))
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 71 d7 15 9b
> +r17 = memb(r21 = ##31)
> +# CHECK: b1 c0 15 9b
> +r17 = memb(r21++#5)
> +# CHECK: 11 e0 15 9d
> +r17 = memb(r21++m1)
> +# CHECK: 11 e0 15 9f
> +r17 = memb(r21 ++ m1:brev)
> +
> +# Load byte conditionally
> +# CHECK: f1 ff 15 30
> +if (p3) r17 = memb(r21+r31<<#3)
> +# CHECK: f1 ff 15 31
> +if (!p3) r17 = memb(r21+r31<<#3)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 15 32
> +{ p3 = r5
> +  if (p3.new) r17 = memb(r21+r31<<#3) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 15 33
> +{ p3 = r5
> +  if (!p3.new) r17 = memb(r21+r31<<#3) }
> +# CHECK: 91 dd 15 41
> +if (p3) r17 = memb(r21 + #44)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 91 dd 15 43
> +{ p3 = r5
> +  if (p3.new) r17 = memb(r21 + #44) }
> +# CHECK: 91 dd 15 45
> +if (!p3) r17 = memb(r21 + #44)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 91 dd 15 47
> +{ p3 = r5
> +  if (!p3.new) r17 = memb(r21 + #44) }
> +# CHECK: b1 e6 15 9b
> +if (p3) r17 = memb(r21++#5)
> +# CHECK: b1 ee 15 9b
> +if (!p3) r17 = memb(r21++#5)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 f6 15 9b
> +{ p3 = r5
> +  if (p3.new) r17 = memb(r21++#5) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 fe 15 9b
> +{ p3 = r5
> +  if (!p3.new) r17 = memb(r21++#5) }
> +
> +# Load byte into shifted vector
> +# CHECK: f0 c3 95 90
> +r17:16 = memb_fifo(r21 + #31)
> +# CHECK: b0 e0 95 98
> +r17:16 = memb_fifo(r21 ++ #5:circ(m1))
> +# CHECK: 10 e2 95 98
> +r17:16 = memb_fifo(r21 ++ I:circ(m1))
> +
> +# Load half into shifted vector
> +# CHECK: f0 c3 55 90
> +r17:16 = memh_fifo(r21 + #62)
> +# CHECK: b0 e0 55 98
> +r17:16 = memh_fifo(r21 ++ #10:circ(m1))
> +# CHECK: 10 e2 55 98
> +r17:16 = memh_fifo(r21 ++ I:circ(m1))
> +
> +# Load halfword
> +# CHECK: 91 ff 55 3a
> +r17 = memh(r21 + r31<<#3)
> +# CHECK: b1 c2 40 49
> +r17 = memh(#42)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 51 c5 40 49
> +r17 = memh(##42)
> +# CHECK: f1 c3 55 91
> +r17 = memh(r21 + #62)
> +# CHECK: b1 e0 55 99
> +r17 = memh(r21 ++ #10:circ(m1))
> +# CHECK: 11 e2 55 99
> +r17 = memh(r21 ++ I:circ(m1))
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 71 d7 55 9b
> +r17 = memh(r21 = ##31)
> +# CHECK: b1 c0 55 9b
> +r17 = memh(r21++#10)
> +# CHECK: 11 e0 55 9d
> +r17 = memh(r21++m1)
> +# CHECK: 11 e0 55 9f
> +r17 = memh(r21 ++ m1:brev)
> +
> +# Load halfword conditionally
> +# CHECK: f1 ff 55 30
> +if (p3) r17 = memh(r21+r31<<#3)
> +# CHECK: f1 ff 55 31
> +if (!p3) r17 = memh(r21+r31<<#3)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 55 32
> +{ p3 = r5
> +  if (p3.new) r17 = memh(r21+r31<<#3) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 55 33
> +{ p3 = r5
> +  if (!p3.new) r17 = memh(r21+r31<<#3) }
> +# CHECK: b1 e6 55 9b
> +if (p3) r17 = memh(r21++#10)
> +# CHECK: b1 ee 55 9b
> +if (!p3) r17 = memh(r21++#10)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 f6 55 9b
> +{ p3 = r5
> +  if (p3.new) r17 = memh(r21++#10) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 fe 55 9b
> +{ p3 = r5
> +  if (!p3.new) r17 = memh(r21++#10) }
> +# CHECK: f1 db 55 41
> +if (p3) r17 = memh(r21 + #62)
> +# CHECK: f1 db 55 45
> +if (!p3) r17 = memh(r21 + #62)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 db 55 43
> +{ p3 = r5
> +  if (p3.new) r17 = memh(r21 + #62) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 db 55 47
> +{ p3 = r5
> +  if (!p3.new) r17 = memh(r21 + #62) }
> +
> +# Load unsigned byte
> +# CHECK: 91 ff 35 3a
> +r17 = memub(r21 + r31<<#3)
> +# CHECK: b1 c2 20 49
> +r17 = memub(#21)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: b1 c2 20 49
> +r17 = memub(##21)
> +# CHECK: f1 c3 35 91
> +r17 = memub(r21 + #31)
> +# CHECK: b1 e0 35 99
> +r17 = memub(r21 ++ #5:circ(m1))
> +# CHECK: 11 e2 35 99
> +r17 = memub(r21 ++ I:circ(m1))
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 71 d7 35 9b
> +r17 = memub(r21 = ##31)
> +# CHECK: b1 c0 35 9b
> +r17 = memub(r21++#5)
> +# CHECK: 11 e0 35 9d
> +r17 = memub(r21++m1)
> +# CHECK: 11 e0 35 9f
> +r17 = memub(r21 ++ m1:brev)
> +
> +# Load unsigned byte conditionally
> +# CHECK: f1 ff 35 30
> +if (p3) r17 = memub(r21+r31<<#3)
> +# CHECK: f1 ff 35 31
> +if (!p3) r17 = memub(r21+r31<<#3)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 35 32
> +{ p3 = r5
> +  if (p3.new) r17 = memub(r21+r31<<#3) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 35 33
> +{ p3 = r5
> +  if (!p3.new) r17 = memub(r21+r31<<#3) }
> +# CHECK: f1 db 35 41
> +if (p3) r17 = memub(r21 + #31)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 db 35 43
> +{ p3 = r5
> +  if (p3.new) r17 = memub(r21 + #31) }
> +# CHECK: f1 db 35 45
> +if (!p3) r17 = memub(r21 + #31)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 db 35 47
> +{ p3 = r5
> +  if (!p3.new) r17 = memub(r21 + #31) }
> +# CHECK: b1 e6 35 9b
> +if (p3) r17 = memub(r21++#5)
> +# CHECK: b1 ee 35 9b
> +if (!p3) r17 = memub(r21++#5)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 f6 35 9b
> +{ p3 = r5
> +  if (p3.new) r17 = memub(r21++#5) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 fe 35 9b
> +{ p3 = r5
> +  if (!p3.new) r17 = memub(r21++#5) }
> +
> +# Load unsigned halfword
> +# CHECK: 91 ff 75 3a
> +r17 = memuh(r21 + r31<<#3)
> +# CHECK: b1 c2 60 49
> +r17 = memuh(#42)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 51 c5 60 49
> +r17 = memuh(##42)
> +# CHECK: b1 c2 75 91
> +r17 = memuh(r21 + #42)
> +# CHECK: b1 e0 75 99
> +r17 = memuh(r21 ++ #10:circ(m1))
> +# CHECK: 11 e2 75 99
> +r17 = memuh(r21 ++ I:circ(m1))
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 71 d7 75 9b
> +r17 = memuh(r21 = ##31)
> +# CHECK: b1 c0 75 9b
> +r17 = memuh(r21++#10)
> +# CHECK: 11 e0 75 9d
> +r17 = memuh(r21++m1)
> +# CHECK: 11 e0 75 9f
> +r17 = memuh(r21 ++ m1:brev)
> +
> +# Load unsigned halfword conditionally
> +# CHECK: f1 ff 75 30
> +if (p3) r17 = memuh(r21+r31<<#3)
> +# CHECK: f1 ff 75 31
> +if (!p3) r17 = memuh(r21+r31<<#3)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 75 32
> +{ p3 = r5
> +  if (p3.new) r17 = memuh(r21+r31<<#3) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 75 33
> +{ p3 = r5
> +  if (!p3.new) r17 = memuh(r21+r31<<#3) }
> +# CHECK: b1 da 75 41
> +if (p3) r17 = memuh(r21 + #42)
> +# CHECK: b1 da 75 45
> +if (!p3) r17 = memuh(r21 + #42)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 da 75 43
> +{ p3 = r5
> +  if (p3.new) r17 = memuh(r21 + #42) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 da 75 47
> +{ p3 = r5
> +  if (!p3.new) r17 = memuh(r21 + #42) }
> +# CHECK: b1 e6 75 9b
> +if (p3) r17 = memuh(r21++#10)
> +# CHECK: b1 ee 75 9b
> +if (!p3) r17 = memuh(r21++#10)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 f6 75 9b
> +{ p3 = r5
> +  if (p3.new) r17 = memuh(r21++#10) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 fe 75 9b
> +{ p3 = r5
> +  if (!p3.new) r17 = memuh(r21++#10) }
> +
> +# Load word
> +# CHECK: 91 ff 95 3a
> +r17 = memw(r21 + r31<<#3)
> +# CHECK: b1 c2 80 49
> +r17 = memw(#84)
> +# CHECK: 01 40 00 00
> +# CHECK-NEXT: 91 c2 80 49
> +r17 = memw(##84)
> +# CHECK: b1 c2 95 91
> +r17 = memw(r21 + #84)
> +# CHECK: b1 e0 95 99
> +r17 = memw(r21 ++ #20:circ(m1))
> +# CHECK: 11 e2 95 99
> +r17 = memw(r21 ++ I:circ(m1))
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 71 d7 95 9b
> +r17 = memw(r21 = ##31)
> +# CHECK: b1 c0 95 9b
> +r17 = memw(r21++#20)
> +# CHECK: 11 e0 95 9d
> +r17 = memw(r21++m1)
> +# CHECK: 11 e0 95 9f
> +r17 = memw(r21 ++ m1:brev)
> +
> +# Load word conditionally
> +# CHECK: f1 ff 95 30
> +if (p3) r17 = memw(r21+r31<<#3)
> +# CHECK: f1 ff 95 31
> +if (!p3) r17 = memw(r21+r31<<#3)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 95 32
> +{ p3 = r5
> +  if (p3.new) r17 = memw(r21+r31<<#3) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f1 ff 95 33
> +{ p3 = r5
> +  if (!p3.new) r17 = memw(r21+r31<<#3) }
> +# CHECK: b1 da 95 41
> +if (p3) r17 = memw(r21 + #84)
> +# CHECK: b1 da 95 45
> +if (!p3) r17 = memw(r21 + #84)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 da 95 43
> +{ p3 = r5
> +  if (p3.new) r17 = memw(r21 + #84) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 da 95 47
> +{ p3 = r5
> +  if (!p3.new) r17 = memw(r21 + #84) }
> +# CHECK: b1 e6 95 9b
> +if (p3) r17 = memw(r21++#20)
> +# CHECK: b1 ee 95 9b
> +if (!p3) r17 = memw(r21++#20)
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 f6 95 9b
> +{ p3 = r5
> +  if (p3.new) r17 = memw(r21++#20) }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: b1 fe 95 9b
> +{ p3 = r5
> +  if (!p3.new) r17 = memw(r21++#20) }
> +
> +# Deallocate stack frame
> +# CHECK: 1e c0 1e 90
> +deallocframe
> +
> +# Deallocate stack frame and return
> +# CHECK: 1e c0 1e 96
> +dealloc_return
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1e cb 1e 96
> +{ p3 = r5
> +  if (p3.new) dealloc_return:nt }
> +# CHECK: 1e d3 1e 96
> +if (p3) dealloc_return
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1e db 1e 96
> +{ p3 = r5
> +  if (p3.new) dealloc_return:t }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1e eb 1e 96
> +{ p3 = r5
> +  if (!p3.new) dealloc_return:nt }
> +# CHECK: 1e f3 1e 96
> +if (!p3) dealloc_return
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1e fb 1e 96
> +{ p3 = r5
> +  if (!p3.new) dealloc_return:t }
> +
> +# Load and unpack bytes to halfwords
> +# CHECK: f1 c3 35 90
> +r17 = membh(r21 + #62)
> +# CHECK: f1 c3 75 90
> +r17 = memubh(r21 + #62)
> +# CHECK: f0 c3 b5 90
> +r17:16 = memubh(r21 + #124)
> +# CHECK: f0 c3 f5 90
> +r17:16 = membh(r21 + #124)
> +# CHECK: b1 e0 35 98
> +r17 = membh(r21 ++ #10:circ(m1))
> +# CHECK: 11 e2 35 98
> +r17 = membh(r21 ++ I:circ(m1))
> +# CHECK: b1 e0 75 98
> +r17 = memubh(r21 ++ #10:circ(m1))
> +# CHECK: 11 e2 75 98
> +r17 = memubh(r21 ++ I:circ(m1))
> +# CHECK: b0 e0 f5 98
> +r17:16 = membh(r21 ++ #20:circ(m1))
> +# CHECK: 10 e2 f5 98
> +r17:16 = membh(r21 ++ I:circ(m1))
> +# CHECK: b0 e0 b5 98
> +r17:16 = memubh(r21 ++ #20:circ(m1))
> +# CHECK: 10 e2 b5 98
> +r17:16 = memubh(r21 ++ I:circ(m1))
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 71 d7 35 9a
> +r17 = membh(r21 = ##31)
> +# CHECK: b1 c0 35 9a
> +r17 = membh(r21++#10)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 71 d7 75 9a
> +r17 = memubh(r21 = ##31)
> +# CHECK: b1 c0 75 9a
> +r17 = memubh(r21++#10)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 70 d7 b5 9a
> +r17:16 = memubh(r21 = ##31)
> +# CHECK: b0 c0 b5 9a
> +r17:16 = memubh(r21++#20)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 70 d7 f5 9a
> +r17:16 = membh(r21 = ##31)
> +# CHECK: b0 c0 f5 9a
> +r17:16 = membh(r21++#20)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: f1 f7 35 9c
> +r17 = membh(r21<<#3 + ##31)
> +# CHECK: 11 e0 35 9c
> +r17 = membh(r21++m1)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: f1 f7 75 9c
> +r17 = memubh(r21<<#3 + ##31)
> +# CHECK: 11 e0 75 9c
> +r17 = memubh(r21++m1)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: f0 f7 f5 9c
> +r17:16 = membh(r21<<#3 + ##31)
> +# CHECK: 10 e0 f5 9c
> +r17:16 = membh(r21++m1)
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: f0 f7 b5 9c
> +r17:16 = memubh(r21<<#3 + ##31)
> +# CHECK: 11 e0 35 9c
> +r17 = membh(r21++m1)
> +# CHECK: 11 e0 75 9c
> +r17 = memubh(r21++m1)
> +# CHECK: 10 e0 f5 9c
> +r17:16 = membh(r21++m1)
> +# CHECK: 10 e0 b5 9c
> +r17:16 = memubh(r21++m1)
> +# CHECK: 11 e0 35 9e
> +r17 = membh(r21 ++ m1:brev)
> +# CHECK: 11 e0 75 9e
> +r17 = memubh(r21 ++ m1:brev)
> +# CHECK: 10 e0 b5 9e
> +r17:16 = memubh(r21 ++ m1:brev)
> +# CHECK: 10 e0 f5 9e
> +r17:16 = membh(r21 ++ m1:brev)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/memop.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/memop.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/memop.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/memop.s Sun Nov  8 22:07:48
> 2015
> @@ -0,0 +1,56 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.6 MEMOP
> +
> +# Operation on memory byte
> +# CHECK: 95 d9 11 3e
> +memb(r17+#51) += r21
> +# CHECK: b5 d9 11 3e
> +memb(r17+#51) -= r21
> +# CHECK: d5 d9 11 3e
> +memb(r17+#51) &= r21
> +# CHECK: f5 d9 11 3e
> +memb(r17+#51) |= r21
> +# CHECK: 95 d9 11 3f
> +memb(r17+#51) += #21
> +# CHECK: b5 d9 11 3f
> +memb(r17+#51) -= #21
> +# CHECK: d5 d9 11 3f
> +memb(r17+#51) = clrbit(#21)
> +# CHECK: f5 d9 11 3f
> +memb(r17+#51) = setbit(#21)
> +
> +# Operation on memory halfword
> +# CHECK: 95 d9 31 3e
> +memh(r17+#102) += r21
> +# CHECK: b5 d9 31 3e
> +memh(r17+#102) -= r21
> +# CHECK: d5 d9 31 3e
> +memh(r17+#102) &= r21
> +# CHECK: f5 d9 31 3e
> +memh(r17+#102) |= r21
> +# CHECK: 95 d9 31 3f
> +memh(r17+#102) += #21
> +# CHECK: b5 d9 31 3f
> +memh(r17+#102) -= #21
> +# CHECK: d5 d9 31 3f
> +memh(r17+#102) = clrbit(#21)
> +# CHECK: f5 d9 31 3f
> +memh(r17+#102) = setbit(#21)
> +
> +# Operation on memory word
> +# CHECK: 95 d9 51 3e
> +memw(r17+#204) += r21
> +# CHECK: b5 d9 51 3e
> +memw(r17+#204) -= r21
> +# CHECK: d5 d9 51 3e
> +memw(r17+#204) &= r21
> +# CHECK: f5 d9 51 3e
> +memw(r17+#204) |= r21
> +# CHECK: 95 d9 51 3f
> +memw(r17+#204) += #21
> +# CHECK: b5 d9 51 3f
> +memw(r17+#204) -= #21
> +# CHECK: d5 d9 51 3f
> +memw(r17+#204) = clrbit(#21)
> +# CHECK: f5 d9 51 3f
> +memw(r17+#204) = setbit(#21)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/nv_j.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/nv_j.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/nv_j.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/nv_j.s Sun Nov  8 22:07:48 2015
> @@ -0,0 +1,180 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.7.1 NV/J
> +
> +# Jump to address conditioned on new register value
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 02 20
> +{ r17 = r17
> +  if (cmp.eq(r17.new, r21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 02 20
> +{ r17 = r17
> +  if (cmp.eq(r17.new, r21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 42 20
> +{ r17 = r17
> +  if (!cmp.eq(r17.new, r21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 42 20
> +{ r17 = r17
> +  if (!cmp.eq(r17.new, r21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 82 20
> +{ r17 = r17
> +  if (cmp.gt(r17.new, r21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 82 20
> +{ r17 = r17
> +  if (cmp.gt(r17.new, r21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 c2 20
> +{ r17 = r17
> +  if (!cmp.gt(r17.new, r21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 c2 20
> +{ r17 = r17
> +  if (!cmp.gt(r17.new, r21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 02 21
> +{ r17 = r17
> +  if (cmp.gtu(r17.new, r21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 02 21
> +{ r17 = r17
> +  if (cmp.gtu(r17.new, r21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 42 21
> +{ r17 = r17
> +  if (!cmp.gtu(r17.new, r21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 42 21
> +{ r17 = r17
> +  if (!cmp.gtu(r17.new, r21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 82 21
> +{ r17 = r17
> +  if (cmp.gt(r21, r17.new)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 82 21
> +{ r17 = r17
> +  if (cmp.gt(r21, r17.new)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 c2 21
> +{ r17 = r17
> +  if (!cmp.gt(r21, r17.new)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 c2 21
> +{ r17 = r17
> +  if (!cmp.gt(r21, r17.new)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 02 22
> +{ r17 = r17
> +  if (cmp.gtu(r21, r17.new)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 02 22
> +{ r17 = r17
> +  if (cmp.gtu(r21, r17.new)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 42 22
> +{ r17 = r17
> +  if (!cmp.gtu(r21, r17.new)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 42 22
> +{ r17 = r17
> +  if (!cmp.gtu(r21, r17.new)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 02 24
> +{ r17 = r17
> +  if (cmp.eq(r17.new, #21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 02 24
> +{ r17 = r17
> +  if (cmp.eq(r17.new, #21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 42 24
> +{ r17 = r17
> +  if (!cmp.eq(r17.new, #21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 42 24
> +{ r17 = r17
> +  if (!cmp.eq(r17.new, #21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 82 24
> +{ r17 = r17
> +  if (cmp.gt(r17.new, #21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 82 24
> +{ r17 = r17
> +  if (cmp.gt(r17.new, #21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 c2 24
> +{ r17 = r17
> +  if (!cmp.gt(r17.new, #21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 c2 24
> +{ r17 = r17
> +  if (!cmp.gt(r17.new, #21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 02 25
> +{ r17 = r17
> +  if (cmp.gtu(r17.new, #21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 02 25
> +{ r17 = r17
> +  if (cmp.gtu(r17.new, #21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 d5 42 25
> +{ r17 = r17
> +  if (!cmp.gtu(r17.new, #21)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 f5 42 25
> +{ r17 = r17
> +  if (!cmp.gtu(r17.new, #21)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 c0 82 25
> +{ r17 = r17
> +  if (tstbit(r17.new, #0)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 e0 82 25
> +{ r17 = r17
> +  if (tstbit(r17.new, #0)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 c0 c2 25
> +{ r17 = r17
> +  if (!tstbit(r17.new, #0)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 e0 c2 25
> +{ r17 = r17
> +  if (!tstbit(r17.new, #0)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 c0 02 26
> +{ r17 = r17
> +  if (cmp.eq(r17.new, #-1)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 e0 02 26
> +{ r17 = r17
> +  if (cmp.eq(r17.new, #-1)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 c0 42 26
> +{ r17 = r17
> +  if (!cmp.eq(r17.new, #-1)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 e0 42 26
> +{ r17 = r17
> +  if (!cmp.eq(r17.new, #-1)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 c0 82 26
> +{ r17 = r17
> +  if (cmp.gt(r17.new, #-1)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 e0 82 26
> +{ r17 = r17
> +  if (cmp.gt(r17.new, #-1)) jump:t 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 c0 c2 26
> +{ r17 = r17
> +  if (!cmp.gt(r17.new, #-1)) jump:nt 0x0 }
> +# CHECK: 11 40 71 70
> +# CHECK-NEXT: 00 e0 c2 26
> +{ r17 = r17
> +  if (!cmp.gt(r17.new, #-1)) jump:t 0x0 }
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/nv_st.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/nv_st.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/nv_st.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/nv_st.s Sun Nov  8 22:07:48
> 2015
> @@ -0,0 +1,290 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.7.2 NV/ST
> +
> +# Store new-value byte
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 82 f5 b1 3b
> +{ r31 = r31
> +  memb(r17 + r21<<#3) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 11 c2 a0 48
> +{ r31 = r31
> +  memb(#17) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 15 c2 b1 a1
> +{ r31 = r31
> +  memb(r17+#21) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 02 e2 b1 a9
> +{ r31 = r31
> +  memb(r17 ++ I:circ(m1)) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 28 e2 b1 a9
> +{ r31 = r31
> +  memb(r17 ++ #5:circ(m1)) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 28 c2 b1 ab
> +{ r31 = r31
> +  memb(r17++#5) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 00 e2 b1 ad
> +{ r31 = r31
> +  memb(r17++m1) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 00 e2 b1 af
> +{ r31 = r31
> +  memb(r17 ++ m1:brev) = r31.new }
> +
> +# Store new-value byte conditionally
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: e2 f5 b1 34
> +{ r31 = r31
> +  if (p3) memb(r17+r21<<#3) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: e2 f5 b1 35
> +{ r31 = r31
> +  if (!p3) memb(r17+r21<<#3) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: e2 f5 b1 36
> +{ p3 = r5
> +  r31 = r31
> +  if (p3.new) memb(r17+r21<<#3) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: e2 f5 b1 37
> +{ p3 = r5
> +  r31 = r31
> +  if (!p3.new) memb(r17+r21<<#3) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: ab c2 b1 40
> +{ r31 = r31
> +  if (p3) memb(r17+#21) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: ab c2 b1 44
> +{ r31 = r31
> +  if (!p3) memb(r17+#21) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ab c2 b1 42
> +{ p3 = r5
> +  r31 = r31
> +  if (p3.new) memb(r17+#21) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ab c2 b1 46
> +{ p3 = r5
> +  r31 = r31
> +  if (!p3.new) memb(r17+#21) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 2b e2 b1 ab
> +{ r31 = r31
> +  if (p3) memb(r17++#5) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 2f e2 b1 ab
> +{ r31 = r31
> +  if (!p3) memb(r17++#5) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ab e2 b1 ab
> +{ p3 = r5
> +  r31 = r31
> +  if (p3.new) memb(r17++#5) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: af e2 b1 ab
> +{ p3 = r5
> +  r31 = r31
> +  if (!p3.new) memb(r17++#5) = r31.new }
> +
> +# Store new-value halfword
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 8a f5 b1 3b
> +{ r31 = r31
> +  memh(r17 + r21<<#3) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 15 ca a0 48
> +{ r31 = r31
> +  memh(#42) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 15 ca b1 a1
> +{ r31 = r31
> +  memh(r17+#42) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 02 ea b1 a9
> +{ r31 = r31
> +  memh(r17 ++ I:circ(m1)) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 28 ea b1 a9
> +{ r31 = r31
> +  memh(r17 ++ #10:circ(m1)) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 28 ca b1 ab
> +{ r31 = r31
> +  memh(r17++#10) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 00 ea b1 ad
> +{ r31 = r31
> +  memh(r17++m1) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 00 ea b1 af
> +{ r31 = r31
> +  memh(r17 ++ m1:brev) = r31.new }
> +
> +# Store new-value halfword conditionally
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: ea f5 b1 34
> +{ r31 = r31
> +  if (p3) memh(r17+r21<<#3) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: ea f5 b1 35
> +{ r31 = r31
> +  if (!p3) memh(r17+r21<<#3) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ea f5 b1 36
> +{ p3 = r5
> +  r31 = r31
> +  if (p3.new) memh(r17+r21<<#3) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ea f5 b1 37
> +{ p3 = r5
> +  r31 = r31
> +  if (!p3.new) memh(r17+r21<<#3) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: ab ca b1 40
> +{ r31 = r31
> +  if (p3) memh(r17+#42) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: ab ca b1 44
> +{ r31 = r31
> +  if (!p3) memh(r17+#42) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ab ca b1 42
> +{ p3 = r5
> +  r31 = r31
> +  if (p3.new) memh(r17+#42) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ab ca b1 46
> +{ p3 = r5
> +  r31 = r31
> +  if (!p3.new) memh(r17+#42) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 2b ea b1 ab
> +{ r31 = r31
> +  if (p3) memh(r17++#10) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 2f ea b1 ab
> +{ r31 = r31
> +  if (!p3) memh(r17++#10) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ab ea b1 ab
> +{ p3 = r5
> +  r31 = r31
> +  if (p3.new) memh(r17++#10) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: af ea b1 ab
> +{ p3 = r5
> +  r31 = r31
> +  if (!p3.new) memh(r17++#10) = r31.new }
> +
> +# Store new-value word
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 92 f5 b1 3b
> +{ r31 = r31
> +  memw(r17 + r21<<#3) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 15 d2 a0 48
> +{ r31 = r31
> +  memw(#84) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 15 d2 b1 a1
> +{ r31 = r31
> +  memw(r17+#84) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 02 f2 b1 a9
> +{ r31 = r31
> +  memw(r17 ++ I:circ(m1)) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 28 f2 b1 a9
> +{ r31 = r31
> +  memw(r17 ++ #20:circ(m1)) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 28 d2 b1 ab
> +{ r31 = r31
> +  memw(r17++#20) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 00 f2 b1 ad
> +{ r31 = r31
> +  memw(r17++m1) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 00 f2 b1 af
> +{ r31 = r31
> +  memw(r17 ++ m1:brev) = r31.new }
> +
> +# Store new-value word conditionally
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: f2 f5 b1 34
> +{ r31 = r31
> +  if (p3) memw(r17+r21<<#3) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: f2 f5 b1 35
> +{ r31 = r31
> +  if (!p3) memw(r17+r21<<#3) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: f2 f5 b1 36
> +{ p3 = r5
> +  r31 = r31
> +  if (p3.new) memw(r17+r21<<#3) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: f2 f5 b1 37
> +{ p3 = r5
> +  r31 = r31
> +  if (!p3.new) memw(r17+r21<<#3) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: ab d2 b1 40
> +{ r31 = r31
> +  if (p3) memw(r17+#84) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: ab d2 b1 44
> +{ r31 = r31
> +  if (!p3) memw(r17+#84) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ab d2 b1 42
> +{ p3 = r5
> +  r31 = r31
> +  if (p3.new) memw(r17+#84) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ab d2 b1 46
> +{ p3 = r5
> +  r31 = r31
> +  if (!p3.new) memw(r17+#84) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 2b f2 b1 ab
> +{ r31 = r31
> +  if (p3) memw(r17++#20) = r31.new }
> +# CHECK: 1f 40 7f 70
> +# CHECK-NEXT: 2f f2 b1 ab
> +{ r31 = r31
> +  if (!p3) memw(r17++#20) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: ab f2 b1 ab
> +{ p3 = r5
> +  r31 = r31
> +  if (p3.new) memw(r17++#20) = r31.new }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 1f 40 7f 70
> +# CHECK-NEXT: af f2 b1 ab
> +{ p3 = r5
> +  r31 = r31
> +  if (!p3.new) memw(r17++#20) = r31.new }
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/st.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/st.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/st.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/st.s Sun Nov  8 22:07:48 2015
> @@ -0,0 +1,435 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.8 ST
> +# XFAIL: *
> +
> +# Store doubleword
> +# CHECK: 9e f5 d1 3b
> +memd(r17 + r21<<#3) = r31:30
> +# CHECK: 28 d4 c0 48
> +memd(#320) = r21:20
> +# CHECK: 02 40 00 00
> +# CHECK-NEXT: 28 d4 c0 48
> +memd(##168) = r21:20
> +memd(r17+#168) = r21:20
> +# CHECK: 02 f4 d1 a9
> +memd(r17 ++ I:circ(m1)) = r21:20
> +# CHECK: 28 f4 d1 a9
> +memd(r17 ++ #40:circ(m1)) = r21:20
> +# CHECK: 28 d4 d1 ab
> +memd(r17++#40) = r21:20
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: d5 fe d1 ad
> +memd(r17<<#3 + ##21) = r31:30
> +memd(r17++m1) = r21:20
> +# CHECK: 00 f4 d1 af
> +memd(r17 ++ m1:brev) = r21:20
> +
> +# Store doubleword conditionally
> +# CHECK: fe f5 d1 34
> +if (p3) memd(r17+r21<<#3) = r31:30
> +# CHECK: fe f5 d1 35
> +if (!p3) memd(r17+r21<<#3) = r31:30
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: fe f5 d1 36
> +{ p3 = r5
> +  if (p3.new) memd(r17+r21<<#3) = r31:30 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: fe f5 d1 37
> +{ p3 = r5
> +  if (!p3.new) memd(r17+r21<<#3) = r31:30 }
> +# CHECK: ab de d1 40
> +if (p3) memd(r17+#168) = r31:30
> +# CHECK: ab de d1 44
> +if (!p3) memd(r17+#168) = r31:30
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab de d1 42
> +{ p3 = r5
> +  if (p3.new) memd(r17+#168) = r31:30 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab de d1 46
> +{ p3 = r5
> +  if (!p3.new) memd(r17+#168) = r31:30 }
> +# CHECK: 2b f4 d1 ab
> +if (p3) memd(r17++#40) = r21:20
> +# CHECK: 2f f4 d1 ab
> +if (!p3) memd(r17++#40) = r21:20
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab f4 d1 ab
> +{ p3 = r5
> +  if (p3.new) memd(r17++#40) = r21:20 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: af f4 d1 ab
> +{ p3 = r5
> +  if (!p3.new) memd(r17++#40) = r21:20 }
> +# CHECK: 02 40 00 00
> +# CHECK-NEXT: c3 d4 c2 af
> +if (p3) memd(##168) = r21:20
> +# CHECK: 02 40 00 00
> +# CHECK-NEXT: c7 d4 c2 af
> +if (!p3) memd(##168) = r21:20
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 02 40 00 00
> +# CHECK-NEXT: c3 f4 c2 af
> +{ p3 = r5
> +  if (p3.new) memd(##168) = r21:20 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 02 40 00 00
> +# CHECK-NEXT: c7 f4 c2 af
> +{ p3 = r5
> +  if (!p3.new) memd(##168) = r21:20 }
> +
> +# Store byte
> +# CHECK: 9f f5 11 3b
> +memb(r17 + r21<<#3) = r31
> +# CHECK: 9f ca 11 3c
> +memb(r17+#21)=#31
> +# CHECK: 15 d5 00 48
> +memb(#21) = r21
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 15 d5 00 48
> +memb(##21) = r21
> +# CHECK: 15 d5 11 a1
> +memb(r17+#21) = r21
> +# CHECK: 02 f5 11 a9
> +memb(r17 ++ I:circ(m1)) = r21
> +# CHECK: 28 f5 11 a9
> +memb(r17 ++ #5:circ(m1)) = r21
> +# CHECK: 28 d5 11 ab
> +memb(r17++#5) = r21
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: d5 ff 11 ad
> +memb(r17<<#3 + ##21) = r31
> +# CHECK: 00 f5 11 ad
> +memb(r17++m1) = r21
> +# CHECK: 00 f5 11 af
> +memb(r17 ++ m1:brev) = r21
> +
> +# Store byte conditionally
> +# CHECK: ff f5 11 34
> +if (p3) memb(r17+r21<<#3) = r31
> +# CHECK: ff f5 11 35
> +if (!p3) memb(r17+r21<<#3) = r31
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff f5 11 36
> +{ p3 = r5
> +  if (p3.new) memb(r17+r21<<#3) = r31 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff f5 11 37
> +{ p3 = r5
> +  if (!p3.new) memb(r17+r21<<#3) = r31 }
> +# CHECK: ff ca 11 38
> +if (p3) memb(r17+#21)=#31
> +# CHECK: ff ca 91 38
> +if (!p3) memb(r17+#21)=#31
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff ca 11 39
> +{ p3 = r5
> +  if (p3.new) memb(r17+#21)=#31 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff ca 91 39
> +{ p3 = r5
> +  if (!p3.new) memb(r17+#21)=#31 }
> +# CHECK: ab df 11 40
> +if (p3) memb(r17+#21) = r31
> +# CHECK: ab df 11 44
> +if (!p3) memb(r17+#21) = r31
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab df 11 42
> +{ p3 = r5
> +  if (p3.new) memb(r17+#21) = r31 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab df 11 46
> +{ p3 = r5
> +  if (!p3.new) memb(r17+#21) = r31 }
> +# CHECK: 2b f5 11 ab
> +if (p3) memb(r17++#5) = r21
> +# CHECK: 2f f5 11 ab
> +if (!p3) memb(r17++#5) = r21
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab f5 11 ab
> +{ p3 = r5
> +  if (p3.new) memb(r17++#5) = r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: af f5 11 ab
> +{ p3 = r5
> +  if (!p3.new) memb(r17++#5) = r21 }
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: ab d5 01 af
> +if (p3) memb(##21) = r21
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: af d5 01 af
> +if (!p3) memb(##21) = r21
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 40 00 00
> +# CHECK-NEXT: ab f5 01 af
> +{ p3 = r5
> +  if (p3.new) memb(##21) = r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 40 00 00
> +# CHECK-NEXT: af f5 01 af
> +{ p3 = r5
> +  if (!p3.new) memb(##21) = r21 }
> +
> +# Store halfword
> +# CHECK: 9f f5 51 3b
> +memh(r17 + r21<<#3) = r31
> +# CHECK: 9f f5 71 3b
> +memh(r17 + r21<<#3) = r31.h
> +# CHECK: 95 cf 31 3c
> +memh(r17+#62)=#21
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 2a d5 40 48
> +memh(##42) = r21
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: 2a d5 60 48
> +memh(##42) = r21.h
> +# CHECK: 2a d5 40 48
> +memh(#84) = r21
> +# CHECK: 2a d5 60 48
> +memh(#84) = r21.h
> +# CHECK: 15 df 51 a1
> +memh(r17+#42) = r31
> +# CHECK: 15 df 71 a1
> +memh(r17+#42) = r31.h
> +# CHECK: 02 f5 51 a9
> +memh(r17 ++ I:circ(m1)) = r21
> +# CHECK: 28 f5 51 a9
> +memh(r17 ++ #10:circ(m1)) = r21
> +# CHECK: 02 f5 71 a9
> +memh(r17 ++ I:circ(m1)) = r21.h
> +# CHECK: 28 f5 71 a9
> +memh(r17 ++ #10:circ(m1)) = r21.h
> +# CHECK: 28 d5 51 ab
> +memh(r17++#10) = r21
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: d5 ff 51 ad
> +memh(r17<<#3 + ##21) = r31
> +# CHECK: 28 d5 71 ab
> +memh(r17++#10) = r21.h
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: d5 ff 71 ad
> +memh(r17<<#3 + ##21) = r31.h
> +# CHECK: 00 f5 51 ad
> +memh(r17++m1) = r21
> +# CHECK: 00 f5 71 ad
> +memh(r17++m1) = r21.h
> +# CHECK: 00 f5 51 af
> +memh(r17 ++ m1:brev) = r21
> +# CHECK: 00 f5 71 af
> +memh(r17 ++ m1:brev) = r21.h
> +
> +# Store halfword conditionally
> +# CHECK: ff f5 51 34
> +if (p3) memh(r17+r21<<#3) = r31
> +# CHECK: ff f5 71 34
> +if (p3) memh(r17+r21<<#3) = r31.h
> +# CHECK: ff f5 51 35
> +if (!p3) memh(r17+r21<<#3) = r31
> +# CHECK: ff f5 71 35
> +if (!p3) memh(r17+r21<<#3) = r31.h
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff f5 51 36
> +{ p3 = r5
> +  if (p3.new) memh(r17+r21<<#3) = r31 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff f5 71 36
> +{ p3 = r5
> +  if (p3.new) memh(r17+r21<<#3) = r31.h }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff f5 51 37
> +{ p3 = r5
> +  if (!p3.new) memh(r17+r21<<#3) = r31 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff f5 71 37
> +{ p3 = r5
> +  if (!p3.new) memh(r17+r21<<#3) = r31.h }
> +# CHECK: f5 cf 31 38
> +if (p3) memh(r17+#62)=#21
> +# CHECK: f5 cf b1 38
> +if (!p3) memh(r17+#62)=#21
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f5 cf 31 39
> +{ p3 = r5
> +  if (p3.new) memh(r17+#62)=#21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: f5 cf b1 39
> +{ p3 = r5
> +  if (!p3.new) memh(r17+#62)=#21 }
> +# CHECK: fb d5 51 40
> +if (p3) memh(r17+#62) = r21
> +# CHECK: fb d5 71 40
> +if (p3) memh(r17+#62) = r21.h
> +# CHECK: fb d5 51 44
> +if (!p3) memh(r17+#62) = r21
> +# CHECK: fb d5 71 44
> +if (!p3) memh(r17+#62) = r21.h
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: fb d5 51 42
> +{ p3 = r5
> +  if (p3.new) memh(r17+#62) = r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: fb d5 71 42
> +{ p3 = r5
> +  if (p3.new) memh(r17+#62) = r21.h }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: fb d5 51 46
> +{ p3 = r5
> +  if (!p3.new) memh(r17+#62) = r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: fb d5 71 46
> +{ p3 = r5
> +  if (!p3.new) memh(r17+#62) = r21.h }
> +# CHECK: 2b f5 51 ab
> +if (p3) memh(r17++#10) = r21
> +# CHECK: 2f f5 51 ab
> +if (!p3) memh(r17++#10) = r21
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab f5 51 ab
> +{ p3 = r5
> +  if (p3.new) memh(r17++#10) = r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: af f5 51 ab
> +{ p3 = r5
> +  if (!p3.new) memh(r17++#10) = r21 }
> +# CHECK: 2b f5 71 ab
> +if (p3) memh(r17++#10) = r21.h
> +# CHECK: 2f f5 71 ab
> +if (!p3) memh(r17++#10) = r21.h
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab f5 71 ab
> +{ p3 = r5
> +  if (p3.new) memh(r17++#10) = r21.h }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: af f5 71 ab
> +{ p3 = r5
> +  if (!p3.new) memh(r17++#10) = r21.h }
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: d3 d5 42 af
> +if (p3) memh(##42) = r21
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: d3 d5 62 af
> +if (p3) memh(##42) = r21.h
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: d7 d5 42 af
> +if (!p3) memh(##42) = r21
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: d7 d5 62 af
> +if (!p3) memh(##42) = r21.h
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 40 00 00
> +# CHECK-NEXT: d3 f5 42 af
> +{ p3 = r5
> +  if (p3.new) memh(##42) = r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 40 00 00
> +# CHECK-NEXT: d3 f5 62 af
> +{ p3 = r5
> +  if (p3.new) memh(##42) = r21.h }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 40 00 00
> +# CHECK-NEXT: d7 f5 42 af
> +{ p3 = r5
> +  if (!p3.new) memh(##42) = r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 00 40 00 00
> +# CHECK-NEXT: d7 f5 62 af
> +{ p3 = r5
> +  if (!p3.new) memh(##42) = r21.h }
> +
> +# Store word
> +# CHECK: 9f f5 91 3b
> +memw(r17 + r21<<#3) = r31
> +# CHECK: 9f ca 51 3c
> +memw(r17+#84)=#31
> +# CHECK: 15 df 80 48
> +memw(#84) = r31
> +# CHECK: 01 40 00 00
> +# CHECK-NEXT: 14 d5 80 48
> +memw(##84) = r21
> +# CHECK: 9f ca 51 3c
> +memw(r17+#84)=#31
> +# CHECK: 15 df 91 a1
> +memw(r17+#84) = r31
> +# CHECK: 02 f5 91 a9
> +memw(r17 ++ I:circ(m1)) = r21
> +# CHECK: 28 f5 91 a9
> +memw(r17 ++ #20:circ(m1)) = r21
> +# CHECK: 28 d5 91 ab
> +memw(r17++#20) = r21
> +# CHECK: 00 40 00 00
> +# CHECK-NEXT: d5 ff 91 ad
> +memw(r17<<#3 + ##21) = r31
> +# CHECK: 00 f5 91 ad
> +memw(r17++m1) = r21
> +# CHECK: 00 f5 91 af
> +memw(r17 ++ m1:brev) = r21
> +
> +# Store word conditionally
> +# CHECK: ff f5 91 34
> +if (p3) memw(r17+r21<<#3) = r31
> +# CHECK: ff f5 91 35
> +if (!p3) memw(r17+r21<<#3) = r31
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff f5 91 36
> +{ p3 = r5
> +  if (p3.new) memw(r17+r21<<#3) = r31 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff f5 91 37
> +{ p3 = r5
> +  if (!p3.new) memw(r17+r21<<#3) = r31 }
> +# CHECK: ff ca 51 38
> +if (p3) memw(r17+#84)=#31
> +# CHECK: ff ca d1 38
> +if (!p3) memw(r17+#84)=#31
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff ca 51 39
> +{ p3 = r5
> +  if (p3.new) memw(r17+#84)=#31 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ff ca d1 39
> +{ p3 = r5
> +  if (!p3.new) memw(r17+#84)=#31 }
> +# CHECK: ab df 91 40
> +if (p3) memw(r17+#84) = r31
> +# CHECK: ab df 91 44
> +if (!p3) memw(r17+#84) = r31
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab df 91 42
> +{ p3 = r5
> +  if (p3.new) memw(r17+#84) = r31 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab df 91 46
> +{ p3 = r5
> +  if (!p3.new) memw(r17+#84) = r31 }
> +# CHECK: 2b f5 91 ab
> +if (p3) memw(r17++#20) = r21
> +# CHECK: 2f f5 91 ab
> +if (!p3) memw(r17++#20) = r21
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: af f5 91 ab
> +{ p3 = r5
> +  if (!p3.new) memw(r17++#20) = r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: ab f5 91 ab
> +{ p3 = r5
> +  if (p3.new) memw(r17++#20) = r21 }
> +# CHECK: 01 40 00 00
> +# CHECK-NEXT: a3 d5 81 af
> +if (p3) memw(##84) = r21
> +# CHECK: 01 40 00 00
> +# CHECK-NEXT: a7 d5 81 af
> +if (!p3) memw(##84) = r21
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 01 40 00 00
> +# CHECK-NEXT: a3 f5 81 af
> +{ p3 = r5
> +  if (p3.new) memw(##84) = r21 }
> +# CHECK: 03 40 45 85
> +# CHECK-NEXT: 01 40 00 00
> +# CHECK-NEXT: a7 f5 81 af
> +{ p3 = r5
> +  if (!p3.new) memw(##84) = r21 }
> +
> +# Allocate stack frame
> +# CHECK: 1f c0 9d a0
> +allocframe(#248)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/system_user.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/system_user.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/system_user.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/system_user.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,26 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.9.1 SYSTEM/USER
> +
> +# Load locked
> +# CHECK: 11 c0 15 92
> +r17 = memw_locked(r21)
> +# CHECK: 10 d0 15 92
> +r17:16 = memd_locked(r21)
> +
> +# Store conditional
> +# CHECK: 03 d5 b1 a0
> +memw_locked(r17, p3) = r21
> +# CHECK: 03 d4 f1 a0
> +memd_locked(r17, p3) = r21:20
> +
> +# Memory barrier
> +# CHECK: 00 c0 00 a8
> +barrier
> +
> +# Data cache prefetch
> +# CHECK: 15 c0 11 94
> +dcfetch(r17 + #168)
> +
> +# Send value to ETM trace
> +# CHECK: 00 c0 51 62
> +trace(r17)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/xtype_alu.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/xtype_alu.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/xtype_alu.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/xtype_alu.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,395 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.10.1 XTYPE/ALU
> +
> +# Absolute value doubleword
> +# CHECK: d0 c0 94 80
> +r17:16 = abs(r21:20)
> +# CHECK: 91 c0 95 8c
> +r17 = abs(r21)
> +# CHECK: b1 c0 95 8c
> +r17 = abs(r21):sat
> +
> +# Add and accumulate
> +# CHECK: ff d1 35 db
> +r17 = add(r21, add(r31, #23))
> +# CHECK: ff d1 b5 db
> +r17 = add(r21, sub(#23, r31))
> +# CHECK: f1 c2 15 e2
> +r17 += add(r21, #23)
> +# CHECK: f1 c2 95 e2
> +r17 -= add(r21, #23)
> +# CHECK: 31 df 15 ef
> +r17 += add(r21, r31)
> +# CHECK: 31 df 95 ef
> +r17 -= add(r21, r31)
> +
> +# Add doublewords
> +# CHECK: f0 de 14 d3
> +r17:16 = add(r21:20, r31:30)
> +# CHECK: b0 de 74 d3
> +r17:16 = add(r21:20, r31:30):sat
> +# CHECK: d0 de 74 d3
> +r17:16 = add(r21:20, r31:30):raw:lo
> +# CHECK: f0 de 74 d3
> +r17:16 = add(r21:20, r31:30):raw:hi
> +
> +# Add halfword
> +# CHECK: 11 d5 1f d5
> +r17 = add(r21.l, r31.l)
> +# CHECK: 51 d5 1f d5
> +r17 = add(r21.l, r31.h)
> +# CHECK: 91 d5 1f d5
> +r17 = add(r21.l, r31.l):sat
> +# CHECK: d1 d5 1f d5
> +r17 = add(r21.l, r31.h):sat
> +# CHECK: 11 d5 5f d5
> +r17 = add(r21.l, r31.l):<<16
> +# CHECK: 31 d5 5f d5
> +r17 = add(r21.l, r31.h):<<16
> +# CHECK: 51 d5 5f d5
> +r17 = add(r21.h, r31.l):<<16
> +# CHECK: 71 d5 5f d5
> +r17 = add(r21.h, r31.h):<<16
> +# CHECK: 91 d5 5f d5
> +r17 = add(r21.l, r31.l):sat:<<16
> +# CHECK: b1 d5 5f d5
> +r17 = add(r21.l, r31.h):sat:<<16
> +# CHECK: d1 d5 5f d5
> +r17 = add(r21.h, r31.l):sat:<<16
> +# CHECK: f1 d5 5f d5
> +r17 = add(r21.h, r31.h):sat:<<16
> +
> +# Add or subtract doublewords with carry
> +# CHECK: 70 de d4 c2
> +r17:16 = add(r21:20, r31:30, p3):carry
> +# CHECK: 70 de f4 c2
> +r17:16 = sub(r21:20, r31:30, p3):carry
> +
> +# Logical doublewords
> +# CHECK: 90 c0 94 80
> +r17:16 = not(r21:20)
> +# CHECK: 10 de f4 d3
> +r17:16 = and(r21:20, r31:30)
> +# CHECK: 30 d4 fe d3
> +r17:16 = and(r21:20, ~r31:30)
> +# CHECK: 50 de f4 d3
> +r17:16 = or(r21:20, r31:30)
> +# CHECK: 70 d4 fe d3
> +r17:16 = or(r21:20, ~r31:30)
> +# CHECK: 90 de f4 d3
> +r17:16 = xor(r21:20, r31:30)
> +
> +# Logical-logical doublewords
> +# CHECK: 10 de 94 ca
> +r17:16 ^= xor(r21:20, r31:30)
> +
> +# Logical-logical words
> +# CHECK: f1 c3 15 da
> +r17 |= and(r21, #31)
> +# CHECK: f5 c3 51 da
> +r17 = or(r21, and(r17, #31))
> +# CHECK: f1 c3 95 da
> +r17 |= or(r21, #31)
> +# CHECK: 11 df 35 ef
> +r17 |= and(r21, ~r31)
> +# CHECK: 31 df 35 ef
> +r17 &= and(r21, ~r31)
> +# CHECK: 51 df 35 ef
> +r17 ^= and(r21, ~r31)
> +# CHECK: 11 df 55 ef
> +r17 &= and(r21, r31)
> +# CHECK: 31 df 55 ef
> +r17 &= or(r21, r31)
> +# CHECK: 51 df 55 ef
> +r17 &= xor(r21, r31)
> +# CHECK: 71 df 55 ef
> +r17 |= and(r21, r31)
> +# CHECK: 71 df 95 ef
> +r17 ^= xor(r21, r31)
> +# CHECK: 11 df d5 ef
> +r17 |= or(r21, r31)
> +# CHECK: 31 df d5 ef
> +r17 |= xor(r21, r31)
> +# CHECK: 51 df d5 ef
> +r17 ^= and(r21, r31)
> +# CHECK: 71 df d5 ef
> +r17 ^= or(r21, r31)
> +
> +# Maximum words
> +# CHECK: 11 df d5 d5
> +r17 = max(r21, r31)
> +# CHECK: 91 df d5 d5
> +r17 = maxu(r21, r31)
> +
> +# Maximum doublewords
> +# CHECK: 90 de d4 d3
> +r17:16 = max(r21:20, r31:30)
> +# CHECK: b0 de d4 d3
> +r17:16 = maxu(r21:20, r31:30)
> +
> +# Minimum words
> +# CHECK: 11 d5 bf d5
> +r17 = min(r21, r31)
> +# CHECK: 91 d5 bf d5
> +r17 = minu(r21, r31)
> +
> +# Minimum doublewords
> +# CHECK: d0 d4 be d3
> +r17:16 = min(r21:20, r31:30)
> +# CHECK: f0 d4 be d3
> +r17:16 = minu(r21:20, r31:30)
> +
> +# Module wrap
> +# CHECK: f1 df f5 d3
> +r17 = modwrap(r21, r31)
> +
> +# Negate
> +# CHECK: b0 c0 94 80
> +r17:16 = neg(r21:20)
> +# CHECK: d1 c0 95 8c
> +r17 = neg(r21):sat
> +
> +# Round
> +# CHECK: 31 c0 d4 88
> +r17 = round(r21:20):sat
> +# CHECK: 11 df f5 8c
> +r17 = cround(r21, #31)
> +# CHECK: 91 df f5 8c
> +r17 = round(r21, #31)
> +# CHECK: d1 df f5 8c
> +r17 = round(r21, #31):sat
> +# CHECK: 11 df d5 c6
> +r17 = cround(r21, r31)
> +# CHECK: 91 df d5 c6
> +r17 = round(r21, r31)
> +# CHECK: d1 df d5 c6
> +r17 = round(r21, r31):sat
> +
> +# Subtract doublewords
> +# CHECK: f0 d4 3e d3
> +r17:16 = sub(r21:20, r31:30)
> +
> +# Subtract and accumulate words
> +# CHECK: 71 d5 1f ef
> +r17 += sub(r21, r31)
> +
> +# Subtract halfword
> +# CHECK: 11 d5 3f d5
> +r17 = sub(r21.l, r31.l)
> +# CHECK: 51 d5 3f d5
> +r17 = sub(r21.l, r31.h)
> +# CHECK: 91 d5 3f d5
> +r17 = sub(r21.l, r31.l):sat
> +# CHECK: d1 d5 3f d5
> +r17 = sub(r21.l, r31.h):sat
> +# CHECK: 11 d5 7f d5
> +r17 = sub(r21.l, r31.l):<<16
> +# CHECK: 31 d5 7f d5
> +r17 = sub(r21.l, r31.h):<<16
> +# CHECK: 51 d5 7f d5
> +r17 = sub(r21.h, r31.l):<<16
> +# CHECK: 71 d5 7f d5
> +r17 = sub(r21.h, r31.h):<<16
> +# CHECK: 91 d5 7f d5
> +r17 = sub(r21.l, r31.l):sat:<<16
> +# CHECK: b1 d5 7f d5
> +r17 = sub(r21.l, r31.h):sat:<<16
> +# CHECK: d1 d5 7f d5
> +r17 = sub(r21.h, r31.l):sat:<<16
> +# CHECK: f1 d5 7f d5
> +r17 = sub(r21.h, r31.h):sat:<<16
> +
> +# Sign extend word to doubleword
> +# CHECK: 10 c0 55 84
> +r17:16 = sxtw(r21)
> +
> +# Vector absolute value halfwords
> +# CHECK: 90 c0 54 80
> +r17:16 = vabsh(r21:20)
> +# CHECK: b0 c0 54 80
> +r17:16 = vabsh(r21:20):sat
> +
> +# Vector absolute value words
> +# CHECK: d0 c0 54 80
> +r17:16 = vabsw(r21:20)
> +# CHECK: f0 c0 54 80
> +r17:16 = vabsw(r21:20):sat
> +
> +# Vector absolute difference halfwords
> +# CHECK: 10 d4 7e e8
> +r17:16 = vabsdiffh(r21:20, r31:30)
> +
> +# Vector absolute difference words
> +# CHECK: 10 d4 3e e8
> +r17:16 = vabsdiffw(r21:20, r31:30)
> +
> +# Vector add halfwords
> +# CHECK: 50 de 14 d3
> +r17:16 = vaddh(r21:20, r31:30)
> +# CHECK: 70 de 14 d3
> +r17:16 = vaddh(r21:20, r31:30):sat
> +# CHECK: 90 de 14 d3
> +r17:16 = vadduh(r21:20, r31:30):sat
> +
> +# Vector add halfwords with saturate and pack to unsigned bytes
> +# CHECK: 31 de 54 c1
> +r17 = vaddhub(r21:20, r31:30):sat
> +
> +# Vector reduce add unsigned bytes
> +# CHECK: 30 de 54 e8
> +r17:16 = vraddub(r21:20, r31:30)
> +# CHECK: 30 de 54 ea
> +r17:16 += vraddub(r21:20, r31:30)
> +
> +# Vector reduce add halfwords
> +# CHECK: 31 de 14 e9
> +r17 = vradduh(r21:20, r31:30)
> +# CHECK: f1 de 34 e9
> +r17 = vraddh(r21:20, r31:30)
> +
> +# Vector add bytes
> +# CHECK: 10 de 14 d3
> +r17:16 = vaddub(r21:20, r31:30)
> +# CHECK: 30 de 14 d3
> +r17:16 = vaddub(r21:20, r31:30):sat
> +
> +# Vector add words
> +# CHECK: b0 de 14 d3
> +r17:16 = vaddw(r21:20, r31:30)
> +# CHECK: d0 de 14 d3
> +r17:16 = vaddw(r21:20, r31:30):sat
> +
> +# Vector average halfwords
> +# CHECK: 50 de 54 d3
> +r17:16 = vavgh(r21:20, r31:30)
> +# CHECK: 70 de 54 d3
> +r17:16 = vavgh(r21:20, r31:30):rnd
> +# CHECK: 90 de 54 d3
> +r17:16 = vavgh(r21:20, r31:30):crnd
> +# CHECK: b0 de 54 d3
> +r17:16 = vavguh(r21:20, r31:30)
> +# CHECK: d0 de 54 d3
> +r17:16 = vavguh(r21:20, r31:30):rnd
> +# CHECK: 10 d4 9e d3
> +r17:16 = vnavgh(r21:20, r31:30)
> +# CHECK: 30 d4 9e d3
> +r17:16 = vnavgh(r21:20, r31:30):rnd:sat
> +# CHECK: 50 d4 9e d3
> +r17:16 = vnavgh(r21:20, r31:30):crnd:sat
> +
> +# Vector average unsigned bytes
> +# CHECK: 10 de 54 d3
> +r17:16 = vavgub(r21:20, r31:30)
> +# CHECK: 30 de 54 d3
> +r17:16 = vavgub(r21:20, r31:30):rnd
> +
> +# Vector average words
> +# CHECK: 10 de 74 d3
> +r17:16 = vavgw(r21:20, r31:30)
> +# CHECK: 30 de 74 d3
> +r17:16 = vavgw(r21:20, r31:30):rnd
> +# CHECK: 50 de 74 d3
> +r17:16 = vavgw(r21:20, r31:30):crnd
> +# CHECK: 70 de 74 d3
> +r17:16 = vavguw(r21:20, r31:30)
> +# CHECK: 90 de 74 d3
> +r17:16 = vavguw(r21:20, r31:30):rnd
> +# CHECK: 70 d4 9e d3
> +r17:16 = vnavgw(r21:20, r31:30)
> +# CHECK: 90 d4 9e d3
> +r17:16 = vnavgw(r21:20, r31:30):rnd:sat
> +# CHECK: d0 d4 9e d3
> +r17:16 = vnavgw(r21:20, r31:30):crnd:sat
> +
> +# Vector conditional negate
> +# CHECK: 50 df d4 c3
> +r17:16 = vcnegh(r21:20, r31)
> +
> +# CHECK: f0 ff 34 cb
> +r17:16 += vrcnegh(r21:20, r31)
> +
> +# Vector maximum bytes
> +# CHECK: 10 d4 de d3
> +r17:16 = vmaxub(r21:20, r31:30)
> +# CHECK: d0 d4 de d3
> +r17:16 = vmaxb(r21:20, r31:30)
> +
> +# Vector maximum halfwords
> +# CHECK: 30 d4 de d3
> +r17:16 = vmaxh(r21:20, r31:30)
> +# CHECK: 50 d4 de d3
> +r17:16 = vmaxuh(r21:20, r31:30)
> +
> +# Vector reduce maximum halfwords
> +# CHECK: 3f d0 34 cb
> +r17:16 = vrmaxh(r21:20, r31)
> +# CHECK: 3f f0 34 cb
> +r17:16 = vrmaxuh(r21:20, r31)
> +
> +# Vector reduce maximum words
> +# CHECK: 5f d0 34 cb
> +r17:16 = vrmaxw(r21:20, r31)
> +# CHECK: 5f f0 34 cb
> +r17:16 = vrmaxuw(r21:20, r31)
> +
> +# Vector maximum words
> +# CHECK: b0 d4 be d3
> +r17:16 = vmaxuw(r21:20, r31:30)
> +# CHECK: 70 d4 de d3
> +r17:16 = vmaxw(r21:20, r31:30)
> +
> +# Vector minimum bytes
> +# CHECK: 10 d4 be d3
> +r17:16 = vminub(r21:20, r31:30)
> +# CHECK: f0 d4 de d3
> +r17:16 = vminb(r21:20, r31:30)
> +
> +# Vector minimum halfwords
> +# CHECK: 30 d4 be d3
> +r17:16 = vminh(r21:20, r31:30)
> +# CHECK: 50 d4 be d3
> +r17:16 = vminuh(r21:20, r31:30)
> +
> +# Vector reduce minimum halfwords
> +# CHECK: bf d0 34 cb
> +r17:16 = vrminh(r21:20, r31)
> +# CHECK: bf f0 34 cb
> +r17:16 = vrminuh(r21:20, r31)
> +
> +# Vector reduce minimum words
> +# CHECK: df d0 34 cb
> +r17:16 = vrminw(r21:20, r31)
> +# CHECK: df f0 34 cb
> +r17:16 = vrminuw(r21:20, r31)
> +
> +# Vector minimum words
> +# CHECK: 70 d4 be d3
> +r17:16 = vminw(r21:20, r31:30)
> +# CHECK: 90 d4 be d3
> +r17:16 = vminuw(r21:20, r31:30)
> +
> +# Vector sum of absolute differences unsigned bytes
> +# CHECK: 50 de 54 e8
> +r17:16 = vrsadub(r21:20, r31:30)
> +# CHECK: 50 de 54 ea
> +r17:16 += vrsadub(r21:20, r31:30)
> +
> +# Vector subtract halfwords
> +# CHECK: 50 d4 3e d3
> +r17:16 = vsubh(r21:20, r31:30)
> +# CHECK: 70 d4 3e d3
> +r17:16 = vsubh(r21:20, r31:30):sat
> +# CHECK: 90 d4 3e d3
> +r17:16 = vsubuh(r21:20, r31:30):sat
> +
> +# Vector subtract bytes
> +# CHECK: 10 d4 3e d3
> +r17:16 = vsubub(r21:20, r31:30)
> +# CHECK: 30 d4 3e d3
> +r17:16 = vsubub(r21:20, r31:30):sat
> +
> +# Vector subtract words
> +# CHECK: b0 d4 3e d3
> +r17:16 = vsubw(r21:20, r31:30)
> +# CHECK: d0 d4 3e d3
> +r17:16 = vsubw(r21:20, r31:30):sat
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/xtype_bit.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/xtype_bit.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/xtype_bit.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/xtype_bit.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,118 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.10.2 XTYPE/BIT
> +
> +# Count leading
> +# CHECK: 11 c0 54 88
> +r17 = clb(r21:20)
> +# CHECK: 51 c0 54 88
> +r17 = cl0(r21:20)
> +# CHECK: 91 c0 54 88
> +r17 = cl1(r21:20)
> +# CHECK: 11 c0 74 88
> +r17 = normamt(r21:20)
> +# CHECK: 51 d7 74 88
> +r17 = add(clb(r21:20), #23)
> +# CHECK: 11 d7 35 8c
> +r17 = add(clb(r21), #23)
> +# CHECK: 91 c0 15 8c
> +r17 = clb(r21)
> +# CHECK: b1 c0 15 8c
> +r17 = cl0(r21)
> +# CHECK: d1 c0 15 8c
> +r17 = cl1(r21)
> +# CHECK: f1 c0 15 8c
> +r17 = normamt(r21)
> +
> +# Count population
> +# CHECK: 71 c0 74 88
> +r17 = popcount(r21:20)
> +
> +# Count trailing
> +# CHECK: 51 c0 f4 88
> +r17 = ct0(r21:20)
> +# CHECK: 91 c0 f4 88
> +r17 = ct1(r21:20)
> +# CHECK: 91 c0 55 8c
> +r17 = ct0(r21)
> +# CHECK: b1 c0 55 8c
> +r17 = ct1(r21)
> +
> +# Extract bitfield
> +# CHECK: f0 df 54 81
> +r17:16 = extractu(r21:20, #31, #23)
> +# CHECK: f0 df 54 8a
> +r17:16 = extract(r21:20, #31, #23)
> +# CHECK: f1 df 55 8d
> +r17 = extractu(r21, #31, #23)
> +# CHECK: f1 df d5 8d
> +r17 = extract(r21, #31, #23)
> +# CHECK: 10 de 14 c1
> +r17:16 = extractu(r21:20, r31:30)
> +# CHECK: 90 de d4 c1
> +r17:16 = extract(r21:20, r31:30)
> +# CHECK: 11 de 15 c9
> +r17 = extractu(r21, r31:30)
> +# CHECK: 51 de 15 c9
> +r17 = extract(r21, r31:30)
> +
> +# Insert bitfield
> +# CHECK: f0 df 54 83
> +r17:16 = insert(r21:20, #31, #23)
> +# CHECK: f1 df 55 8f
> +r17 = insert(r21, #31, #23)
> +# CHECK: 11 de 15 c8
> +r17 = insert(r21, r31:30)
> +# CHECK: 10 de 14 ca
> +r17:16 = insert(r21:20, r31:30)
> +
> +# Interleave/deinterleave
> +# CHECK: 90 c0 d4 80
> +r17:16 = deinterleave(r21:20)
> +# CHECK: b0 c0 d4 80
> +r17:16 = interleave(r21:20)
> +
> +# Linear feedback-shift iteration
> +# CHECK: d0 de 94 c1
> +r17:16 = lfs(r21:20, r31:30)
> +
> +# Masked parity
> +# CHECK: 11 de 14 d0
> +r17 = parity(r21:20, r31:30)
> +# CHECK: 11 df f5 d5
> +r17 = parity(r21, r31)
> +
> +# Bit reverse
> +# CHECK: d0 c0 d4 80
> +r17:16 = brev(r21:20)
> +# CHECK: d1 c0 55 8c
> +r17 = brev(r21)
> +
> +# Set/clear/toggle bit
> +# CHECK: 11 df d5 8c
> +r17 = setbit(r21, #31)
> +# CHECK: 31 df d5 8c
> +r17 = clrbit(r21, #31)
> +# CHECK: 51 df d5 8c
> +r17 = togglebit(r21, #31)
> +# CHECK: 11 df 95 c6
> +r17 = setbit(r21, r31)
> +# CHECK: 51 df 95 c6
> +r17 = clrbit(r21, r31)
> +# CHECK: 91 df 95 c6
> +r17 = togglebit(r21, r31)
> +
> +# Split bitfield
> +# CHECK: 90 df d5 88
> +r17:16 = bitsplit(r21, #31)
> +# CHECK: 10 df 35 d4
> +r17:16 = bitsplit(r21, r31)
> +
> +# Table index
> +# CHECK: f1 cd 15 87
> +r17 = tableidxb(r21, #7, #13):raw
> +# CHECK: f1 cd 55 87
> +r17 = tableidxh(r21, #7, #13):raw
> +# CHECK: f1 cd 95 87
> +r17 = tableidxw(r21, #7, #13):raw
> +# CHECK: f1 cd d5 87
> +r17 = tableidxd(r21, #7, #13):raw
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/xtype_complex.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/xtype_complex.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/xtype_complex.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/xtype_complex.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,128 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.10.3 XTYPE/COMPLEX
> +
> +# Complex add/sub halfwords
> +# CHECK: 90 de 54 c1
> +r17:16 = vxaddsubh(r21:20, r31:30):sat
> +# CHECK: d0 de 54 c1
> +r17:16 = vxsubaddh(r21:20, r31:30):sat
> +# CHECK: 10 de d4 c1
> +r17:16 = vxaddsubh(r21:20, r31:30):rnd:>>1:sat
> +# CHECK: 50 de d4 c1
> +r17:16 = vxsubaddh(r21:20, r31:30):rnd:>>1:sat
> +
> +# Complex add/sub words
> +# CHECK: 10 de 54 c1
> +r17:16 = vxaddsubw(r21:20, r31:30):sat
> +# CHECK: 50 de 54 c1
> +r17:16 = vxsubaddw(r21:20, r31:30):sat
> +
> +# Complex multiply
> +# CHECK: d0 df 15 e5
> +r17:16 = cmpy(r21, r31):sat
> +# CHECK: d0 df 95 e5
> +r17:16 = cmpy(r21, r31):<<1:sat
> +# CHECK: d0 df 55 e5
> +r17:16 = cmpy(r21, r31*):sat
> +# CHECK: d0 df d5 e5
> +r17:16 = cmpy(r21, r31*):<<1:sat
> +# CHECK: d0 df 15 e7
> +r17:16 += cmpy(r21, r31):sat
> +# CHECK: d0 df 95 e7
> +r17:16 += cmpy(r21, r31):<<1:sat
> +# CHECK: f0 df 15 e7
> +r17:16 -= cmpy(r21, r31):sat
> +# CHECK: f0 df 95 e7
> +r17:16 -= cmpy(r21, r31):<<1:sat
> +# CHECK: d0 df 55 e7
> +r17:16 += cmpy(r21, r31*):sat
> +# CHECK: d0 df d5 e7
> +r17:16 += cmpy(r21, r31*):<<1:sat
> +# CHECK: f0 df 55 e7
> +r17:16 -= cmpy(r21, r31*):sat
> +# CHECK: f0 df d5 e7
> +r17:16 -= cmpy(r21, r31*):<<1:sat
> +
> +# Complex multiply real or imaginary
> +# CHECK: 30 df 15 e5
> +r17:16 = cmpyi(r21, r31)
> +# CHECK: 50 df 15 e5
> +r17:16 = cmpyr(r21, r31)
> +# CHECK: 30 df 15 e7
> +r17:16 += cmpyi(r21, r31)
> +# CHECK: 50 df 15 e7
> +r17:16 += cmpyr(r21, r31)
> +
> +# Complex multiply with round and pack
> +# CHECK: d1 df 35 ed
> +r17 = cmpy(r21, r31):rnd:sat
> +# CHECK: d1 df b5 ed
> +r17 = cmpy(r21, r31):<<1:rnd:sat
> +# CHECK: d1 df 75 ed
> +r17 = cmpy(r21, r31*):rnd:sat
> +# CHECK: d1 df f5 ed
> +r17 = cmpy(r21, r31*):<<1:rnd:sat
> +
> +# Complex multiply 32x16
> +# CHECK: 91 df 14 c5
> +r17 = cmpyiwh(r21:20, r31):<<1:rnd:sat
> +# CHECK: b1 df 14 c5
> +r17 = cmpyiwh(r21:20, r31*):<<1:rnd:sat
> +# CHECK: d1 df 14 c5
> +r17 = cmpyrwh(r21:20, r31):<<1:rnd:sat
> +# CHECK: f1 df 14 c5
> +r17 = cmpyrwh(r21:20, r31*):<<1:rnd:sat
> +
> +# Vector complex multiply real or imaginary
> +# CHECK: d0 de 34 e8
> +r17:16 = vcmpyr(r21:20, r31:30):sat
> +# CHECK: d0 de b4 e8
> +r17:16 = vcmpyr(r21:20, r31:30):<<1:sat
> +# CHECK: d0 de 54 e8
> +r17:16 = vcmpyi(r21:20, r31:30):sat
> +# CHECK: d0 de d4 e8
> +r17:16 = vcmpyi(r21:20, r31:30):<<1:sat
> +# CHECK: 90 de 34 ea
> +r17:16 += vcmpyr(r21:20, r31:30):sat
> +# CHECK: 90 de 54 ea
> +r17:16 += vcmpyi(r21:20, r31:30):sat
> +
> +# Vector complex conjugate
> +# CHECK: f0 c0 94 80
> +r17:16 = vconj(r21:20):sat
> +
> +# Vector complex rotate
> +# CHECK: 10 df d4 c3
> +r17:16 = vcrotate(r21:20, r31)
> +
> +# Vector reduce complex multiply real or imaginary
> +# CHECK: 10 de 14 e8
> +r17:16 = vrcmpyi(r21:20, r31:30)
> +# CHECK: 30 de 14 e8
> +r17:16 = vrcmpyr(r21:20, r31:30)
> +# CHECK: 10 de 54 e8
> +r17:16 = vrcmpyi(r21:20, r31:30*)
> +# CHECK: 30 de 74 e8
> +r17:16 = vrcmpyr(r21:20, r31:30*)
> +
> +# Vector reduce complex multiply by scalar
> +# CHECK: 90 de b4 e8
> +r17:16 = vrcmpys(r21:20, r31:30):<<1:sat:raw:hi
> +# CHECK: 90 de f4 e8
> +r17:16 = vrcmpys(r21:20, r31:30):<<1:sat:raw:lo
> +# CHECK: 90 de b4 ea
> +r17:16 += vrcmpys(r21:20, r31:30):<<1:sat:raw:hi
> +# CHECK: 90 de f4 ea
> +r17:16 += vrcmpys(r21:20, r31:30):<<1:sat:raw:lo
> +
> +# Vector reduce complex multiply by scalar with round and pack
> +# CHECK: d1 de b4 e9
> +r17 = vrcmpys(r21:20, r31:30):<<1:rnd:sat:raw:hi
> +# CHECK: f1 de b4 e9
> +r17 = vrcmpys(r21:20, r31:30):<<1:rnd:sat:raw:lo
> +
> +# Vector reduce complex rotate
> +# CHECK: f0 ff d4 c3
> +r17:16 = vrcrotate(r21:20, r31, #3)
> +# CHECK: 30 ff b4 cb
> +r17:16 += vrcrotate(r21:20, r31, #3)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/xtype_fp.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/xtype_fp.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/xtype_fp.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/xtype_fp.s Sun Nov  8 22:07:48
> 2015
> @@ -0,0 +1,146 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.10.4 XTYPE/FP
> +
> +# Floating point addition
> +# CHECK: 11 df 15 eb
> +r17 = sfadd(r21, r31)
> +
> +# Classify floating-point value
> +# CHECK: 03 d5 f1 85
> +p3 = sfclass(r17, #21)
> +# CHECK: b3 c2 90 dc
> +p3 = dfclass(r17:16, #21)
> +
> +# Compare floating-point value
> +# CHECK: 03 d5 f1 c7
> +p3 = sfcmp.ge(r17, r21)
> +# CHECK: 23 d5 f1 c7
> +p3 = sfcmp.uo(r17, r21)
> +# CHECK: 63 d5 f1 c7
> +p3 = sfcmp.eq(r17, r21)
> +# CHECK: 83 d5 f1 c7
> +p3 = sfcmp.gt(r17, r21)
> +# CHECK: 03 d4 f0 d2
> +p3 = dfcmp.eq(r17:16, r21:20)
> +# CHECK: 23 d4 f0 d2
> +p3 = dfcmp.gt(r17:16, r21:20)
> +# CHECK: 43 d4 f0 d2
> +p3 = dfcmp.ge(r17:16, r21:20)
> +# CHECK: 63 d4 f0 d2
> +p3 = dfcmp.uo(r17:16, r21:20)
> +
> +# Convert floating-point value to other format
> +# CHECK: 10 c0 95 84
> +r17:16 = convert_sf2df(r21)
> +# CHECK: 31 c0 14 88
> +r17 = convert_df2sf(r21:20)
> +
> +# Convert integer to floating-point value
> +# CHECK: 50 c0 f4 80
> +r17:16 = convert_ud2df(r21:20)
> +# CHECK: 70 c0 f4 80
> +r17:16 = convert_d2df(r21:20)
> +# CHECK: 30 c0 95 84
> +r17:16 = convert_uw2df(r21)
> +# CHECK: 50 c0 95 84
> +r17:16 = convert_w2df(r21)
> +# CHECK: 31 c0 34 88
> +r17 = convert_ud2sf(r21:20)
> +# CHECK: 31 c0 54 88
> +r17 = convert_d2sf(r21:20)
> +# CHECK: 11 c0 35 8b
> +r17 = convert_uw2sf(r21)
> +# CHECK: 11 c0 55 8b
> +r17 = convert_w2sf(r21)
> +
> +# Convert floating-point value to integer
> +# CHECK: 10 c0 f4 80
> +r17:16 = convert_df2d(r21:20)
> +# CHECK: 30 c0 f4 80
> +r17:16 = convert_df2ud(r21:20)
> +# CHECK: d0 c0 f4 80
> +r17:16 = convert_df2d(r21:20):chop
> +# CHECK: f0 c0 f4 80
> +r17:16 = convert_df2ud(r21:20):chop
> +# CHECK: 70 c0 95 84
> +r17:16 = convert_sf2ud(r21)
> +# CHECK: 90 c0 95 84
> +r17:16 = convert_sf2d(r21)
> +# CHECK: b0 c0 95 84
> +r17:16 = convert_sf2ud(r21):chop
> +# CHECK: d0 c0 95 84
> +r17:16 = convert_sf2d(r21):chop
> +# CHECK: 31 c0 74 88
> +r17 = convert_df2uw(r21:20)
> +# CHECK: 31 c0 94 88
> +r17 = convert_df2w(r21:20)
> +# CHECK: 31 c0 b4 88
> +r17 = convert_df2uw(r21:20):chop
> +# CHECK: 31 c0 f4 88
> +r17 = convert_df2w(r21:20):chop
> +# CHECK: 11 c0 75 8b
> +r17 = convert_sf2uw(r21)
> +# CHECK: 31 c0 75 8b
> +r17 = convert_sf2uw(r21):chop
> +# CHECK: 11 c0 95 8b
> +r17 = convert_sf2w(r21)
> +# CHECK: 31 c0 95 8b
> +r17 = convert_sf2w(r21):chop
> +
> +# Floating point extreme value assistance
> +# CHECK: 11 c0 b5 8b
> +r17 = sffixupr(r21)
> +# CHECK: 11 df d5 eb
> +r17 = sffixupn(r21, r31)
> +# CHECK: 31 df d5 eb
> +r17 = sffixupd(r21, r31)
> +
> +# Floating point fused multiply-add
> +# CHECK: 91 df 15 ef
> +r17 += sfmpy(r21, r31)
> +# CHECK: b1 df 15 ef
> +r17 -= sfmpy(r21, r31)
> +
> +# Floating point fused multiply-add with scaling
> +# CHECK: f1 df 75 ef
> +r17 += sfmpy(r21, r31, p3):scale
> +
> +# Floating point reciprocal square root approximation
> +# CHECK: 71 c0 f5 8b
> +r17, p3 = sfinvsqrta(r21)
> +
> +# Floating point fused multiply-add for library routines
> +# CHECK: d1 df 15 ef
> +r17 += sfmpy(r21, r31):lib
> +# CHECK: f1 df 15 ef
> +r17 -= sfmpy(r21, r31):lib
> +
> +# Create floating-point constant
> +# CHECK: b1 c2 00 d6
> +r17 = sfmake(#21):pos
> +# CHECK: b1 c2 40 d6
> +r17 = sfmake(#21):neg
> +# CHECK: b0 c2 00 d9
> +r17:16 = dfmake(#21):pos
> +# CHECK: b0 c2 40 d9
> +r17:16 = dfmake(#21):neg
> +
> +# Floating point maximum
> +# CHECK: 11 df 95 eb
> +r17 = sfmax(r21, r31)
> +
> +# Floating point minimum
> +# CHECK: 31 df 95 eb
> +r17 = sfmin(r21, r31)
> +
> +# Floating point multiply
> +# CHECK: 11 df 55 eb
> +r17 = sfmpy(r21, r31)
> +
> +# Floating point reciprocal approximation
> +# CHECK: f1 df f5 eb
> +r17, p3 = sfrecipa(r21, r31)
> +
> +# Floating point subtraction
> +# CHECK: 31 df 15 eb
> +r17 = sfsub(r21, r31)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/xtype_mpy.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/xtype_mpy.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/xtype_mpy.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/xtype_mpy.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,400 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.10.5 XTYPE/MPY
> +
> +# Multiply and use lower result
> +# CHECK: b1 df 35 d7
> +r17 = add(#21, mpyi(r21, r31))
> +# CHECK: bf d1 35 d8
> +r17 = add(#21, mpyi(r21, #31))
> +# CHECK: b5 d1 3f df
> +r17 = add(r21, mpyi(#84, r31))
> +# CHECK: f5 f1 b5 df
> +r17 = add(r21, mpyi(r21, #31))
> +# CHECK: 15 d1 1f e3
> +r17 = add(r21, mpyi(r17, r31))
> +# CHECK: f1 c3 15 e0
> +r17 =+ mpyi(r21, #31)
> +# CHECK: f1 c3 95 e0
> +r17 =- mpyi(r21, #31)
> +# CHECK: f1 c3 15 e1
> +r17 += mpyi(r21, #31)
> +# CHECK: f1 c3 95 e1
> +r17 -= mpyi(r21, #31)
> +# CHECK: 11 df 15 ed
> +r17 = mpyi(r21, r31)
> +# CHECK: 11 df 15 ef
> +r17 += mpyi(r21, r31)
> +
> +# Vector multiply word by signed half (32x16)
> +# CHECK: b0 de 14 e8
> +r17:16 = vmpyweh(r21:20, r31:30):sat
> +# CHECK: b0 de 94 e8
> +r17:16 = vmpyweh(r21:20, r31:30):<<1:sat
> +# CHECK: f0 de 14 e8
> +r17:16 = vmpywoh(r21:20, r31:30):sat
> +# CHECK: f0 de 94 e8
> +r17:16 = vmpywoh(r21:20, r31:30):<<1:sat
> +# CHECK: b0 de 34 e8
> +r17:16 = vmpyweh(r21:20, r31:30):rnd:sat
> +# CHECK: b0 de b4 e8
> +r17:16 = vmpyweh(r21:20, r31:30):<<1:rnd:sat
> +# CHECK: f0 de 34 e8
> +r17:16 = vmpywoh(r21:20, r31:30):rnd:sat
> +# CHECK: f0 de b4 e8
> +r17:16 = vmpywoh(r21:20, r31:30):<<1:rnd:sat
> +# CHECK: b0 de 14 ea
> +r17:16 += vmpyweh(r21:20, r31:30):sat
> +# CHECK: b0 de 94 ea
> +r17:16 += vmpyweh(r21:20, r31:30):<<1:sat
> +# CHECK: f0 de 14 ea
> +r17:16 += vmpywoh(r21:20, r31:30):sat
> +# CHECK: f0 de 94 ea
> +r17:16 += vmpywoh(r21:20, r31:30):<<1:sat
> +# CHECK: b0 de 34 ea
> +r17:16 += vmpyweh(r21:20, r31:30):rnd:sat
> +# CHECK: b0 de b4 ea
> +r17:16 += vmpyweh(r21:20, r31:30):<<1:rnd:sat
> +# CHECK: f0 de 34 ea
> +r17:16 += vmpywoh(r21:20, r31:30):rnd:sat
> +# CHECK: f0 de b4 ea
> +r17:16 += vmpywoh(r21:20, r31:30):<<1:rnd:sat
> +
> +# Vector multiply word by unsigned half (32x16)
> +# CHECK: b0 de 54 e8
> +r17:16 = vmpyweuh(r21:20, r31:30):sat
> +# CHECK: b0 de d4 e8
> +r17:16 = vmpyweuh(r21:20, r31:30):<<1:sat
> +# CHECK: f0 de 54 e8
> +r17:16 = vmpywouh(r21:20, r31:30):sat
> +# CHECK: f0 de d4 e8
> +r17:16 = vmpywouh(r21:20, r31:30):<<1:sat
> +# CHECK: b0 de 74 e8
> +r17:16 = vmpyweuh(r21:20, r31:30):rnd:sat
> +# CHECK: b0 de f4 e8
> +r17:16 = vmpyweuh(r21:20, r31:30):<<1:rnd:sat
> +# CHECK: f0 de 74 e8
> +r17:16 = vmpywouh(r21:20, r31:30):rnd:sat
> +# CHECK: f0 de f4 e8
> +r17:16 = vmpywouh(r21:20, r31:30):<<1:rnd:sat
> +# CHECK: b0 de 54 ea
> +r17:16 += vmpyweuh(r21:20, r31:30):sat
> +# CHECK: b0 de d4 ea
> +r17:16 += vmpyweuh(r21:20, r31:30):<<1:sat
> +# CHECK: f0 de 54 ea
> +r17:16 += vmpywouh(r21:20, r31:30):sat
> +# CHECK: f0 de d4 ea
> +r17:16 += vmpywouh(r21:20, r31:30):<<1:sat
> +# CHECK: b0 de 74 ea
> +r17:16 += vmpyweuh(r21:20, r31:30):rnd:sat
> +# CHECK: b0 de f4 ea
> +r17:16 += vmpyweuh(r21:20, r31:30):<<1:rnd:sat
> +# CHECK: f0 de 74 ea
> +r17:16 += vmpywouh(r21:20, r31:30):rnd:sat
> +# CHECK: f0 de f4 ea
> +r17:16 += vmpywouh(r21:20, r31:30):<<1:rnd:sat
> +
> +# Multiply signed halfwords
> +# CHECK: 10 df 95 e4
> +r17:16 = mpy(r21.l, r31.l):<<1
> +# CHECK: 30 df 95 e4
> +r17:16 = mpy(r21.l, r31.h):<<1
> +# CHECK: 50 df 95 e4
> +r17:16 = mpy(r21.h, r31.l):<<1
> +# CHECK: 70 df 95 e4
> +r17:16 = mpy(r21.h, r31.h):<<1
> +# CHECK: 10 df b5 e4
> +r17:16 = mpy(r21.l, r31.l):<<1:rnd
> +# CHECK: 30 df b5 e4
> +r17:16 = mpy(r21.l, r31.h):<<1:rnd
> +# CHECK: 50 df b5 e4
> +r17:16 = mpy(r21.h, r31.l):<<1:rnd
> +# CHECK: 70 df b5 e4
> +r17:16 = mpy(r21.h, r31.h):<<1:rnd
> +# CHECK: 10 df 95 e6
> +r17:16 += mpy(r21.l, r31.l):<<1
> +# CHECK: 30 df 95 e6
> +r17:16 += mpy(r21.l, r31.h):<<1
> +# CHECK: 50 df 95 e6
> +r17:16 += mpy(r21.h, r31.l):<<1
> +# CHECK: 70 df 95 e6
> +r17:16 += mpy(r21.h, r31.h):<<1
> +# CHECK: 10 df b5 e6
> +r17:16 -= mpy(r21.l, r31.l):<<1
> +# CHECK: 30 df b5 e6
> +r17:16 -= mpy(r21.l, r31.h):<<1
> +# CHECK: 50 df b5 e6
> +r17:16 -= mpy(r21.h, r31.l):<<1
> +# CHECK: 70 df b5 e6
> +r17:16 -= mpy(r21.h, r31.h):<<1
> +# CHECK: 11 df 95 ec
> +r17 = mpy(r21.l, r31.l):<<1
> +# CHECK: 31 df 95 ec
> +r17 = mpy(r21.l, r31.h):<<1
> +# CHECK: 51 df 95 ec
> +r17 = mpy(r21.h, r31.l):<<1
> +# CHECK: 71 df 95 ec
> +r17 = mpy(r21.h, r31.h):<<1
> +# CHECK: 91 df 95 ec
> +r17 = mpy(r21.l, r31.l):<<1:sat
> +# CHECK: b1 df 95 ec
> +r17 = mpy(r21.l, r31.h):<<1:sat
> +# CHECK: d1 df 95 ec
> +r17 = mpy(r21.h, r31.l):<<1:sat
> +# CHECK: f1 df 95 ec
> +r17 = mpy(r21.h, r31.h):<<1:sat
> +# CHECK: 11 df b5 ec
> +r17 = mpy(r21.l, r31.l):<<1:rnd
> +# CHECK: 31 df b5 ec
> +r17 = mpy(r21.l, r31.h):<<1:rnd
> +# CHECK: 51 df b5 ec
> +r17 = mpy(r21.h, r31.l):<<1:rnd
> +# CHECK: 71 df b5 ec
> +r17 = mpy(r21.h, r31.h):<<1:rnd
> +# CHECK: 91 df b5 ec
> +r17 = mpy(r21.l, r31.l):<<1:rnd:sat
> +# CHECK: b1 df b5 ec
> +r17 = mpy(r21.l, r31.h):<<1:rnd:sat
> +# CHECK: d1 df b5 ec
> +r17 = mpy(r21.h, r31.l):<<1:rnd:sat
> +# CHECK: f1 df b5 ec
> +r17 = mpy(r21.h, r31.h):<<1:rnd:sat
> +# CHECK: 11 df 95 ee
> +r17 += mpy(r21.l, r31.l):<<1
> +# CHECK: 31 df 95 ee
> +r17 += mpy(r21.l, r31.h):<<1
> +# CHECK: 51 df 95 ee
> +r17 += mpy(r21.h, r31.l):<<1
> +# CHECK: 71 df 95 ee
> +r17 += mpy(r21.h, r31.h):<<1
> +# CHECK: 91 df 95 ee
> +r17 += mpy(r21.l, r31.l):<<1:sat
> +# CHECK: b1 df 95 ee
> +r17 += mpy(r21.l, r31.h):<<1:sat
> +# CHECK: d1 df 95 ee
> +r17 += mpy(r21.h, r31.l):<<1:sat
> +# CHECK: f1 df 95 ee
> +r17 += mpy(r21.h, r31.h):<<1:sat
> +# CHECK: 11 df b5 ee
> +r17 -= mpy(r21.l, r31.l):<<1
> +# CHECK: 31 df b5 ee
> +r17 -= mpy(r21.l, r31.h):<<1
> +# CHECK: 51 df b5 ee
> +r17 -= mpy(r21.h, r31.l):<<1
> +# CHECK: 71 df b5 ee
> +r17 -= mpy(r21.h, r31.h):<<1
> +# CHECK: 91 df b5 ee
> +r17 -= mpy(r21.l, r31.l):<<1:sat
> +# CHECK: b1 df b5 ee
> +r17 -= mpy(r21.l, r31.h):<<1:sat
> +# CHECK: d1 df b5 ee
> +r17 -= mpy(r21.h, r31.l):<<1:sat
> +# CHECK: f1 df b5 ee
> +r17 -= mpy(r21.h, r31.h):<<1:sat
> +
> +# Multiply unsigned halfwords
> +# CHECK: 10 df d5 e4
> +r17:16 = mpyu(r21.l, r31.l):<<1
> +# CHECK: 30 df d5 e4
> +r17:16 = mpyu(r21.l, r31.h):<<1
> +# CHECK: 50 df d5 e4
> +r17:16 = mpyu(r21.h, r31.l):<<1
> +# CHECK: 70 df d5 e4
> +r17:16 = mpyu(r21.h, r31.h):<<1
> +# CHECK: 10 df d5 e6
> +r17:16 += mpyu(r21.l, r31.l):<<1
> +# CHECK: 30 df d5 e6
> +r17:16 += mpyu(r21.l, r31.h):<<1
> +# CHECK: 50 df d5 e6
> +r17:16 += mpyu(r21.h, r31.l):<<1
> +# CHECK: 70 df d5 e6
> +r17:16 += mpyu(r21.h, r31.h):<<1
> +# CHECK: 10 df f5 e6
> +r17:16 -= mpyu(r21.l, r31.l):<<1
> +# CHECK: 30 df f5 e6
> +r17:16 -= mpyu(r21.l, r31.h):<<1
> +# CHECK: 50 df f5 e6
> +r17:16 -= mpyu(r21.h, r31.l):<<1
> +# CHECK: 70 df f5 e6
> +r17:16 -= mpyu(r21.h, r31.h):<<1
> +# CHECK: 11 df d5 ec
> +r17 = mpyu(r21.l, r31.l):<<1
> +# CHECK: 31 df d5 ec
> +r17 = mpyu(r21.l, r31.h):<<1
> +# CHECK: 51 df d5 ec
> +r17 = mpyu(r21.h, r31.l):<<1
> +# CHECK: 71 df d5 ec
> +r17 = mpyu(r21.h, r31.h):<<1
> +# CHECK: 11 df d5 ee
> +r17 += mpyu(r21.l, r31.l):<<1
> +# CHECK: 31 df d5 ee
> +r17 += mpyu(r21.l, r31.h):<<1
> +# CHECK: 51 df d5 ee
> +r17 += mpyu(r21.h, r31.l):<<1
> +# CHECK: 71 df d5 ee
> +r17 += mpyu(r21.h, r31.h):<<1
> +# CHECK: 11 df f5 ee
> +r17 -= mpyu(r21.l, r31.l):<<1
> +# CHECK: 31 df f5 ee
> +r17 -= mpyu(r21.l, r31.h):<<1
> +# CHECK: 51 df f5 ee
> +r17 -= mpyu(r21.h, r31.l):<<1
> +# CHECK: 71 df f5 ee
> +r17 -= mpyu(r21.h, r31.h):<<1
> +
> +# Polynomial multiply words
> +# CHECK: f0 df 55 e5
> +r17:16 = pmpyw(r21, r31)
> +# CHECK: f0 df 35 e7
> +r17:16 ^= pmpyw(r21, r31)
> +
> +# Vector reduce multiply word by signed half (32x16)
> +# CHECK: 50 de 34 e8
> +r17:16 = vrmpywoh(r21:20, r31:30)
> +# CHECK: 50 de b4 e8
> +r17:16 = vrmpywoh(r21:20, r31:30):<<1
> +# CHECK: 90 de 54 e8
> +r17:16 = vrmpyweh(r21:20, r31:30)
> +# CHECK: 90 de d4 e8
> +r17:16 = vrmpyweh(r21:20, r31:30):<<1
> +# CHECK: d0 de 74 ea
> +r17:16 += vrmpywoh(r21:20, r31:30)
> +# CHECK: d0 de f4 ea
> +r17:16 += vrmpywoh(r21:20, r31:30):<<1
> +# CHECK: d0 de 34 ea
> +r17:16 += vrmpyweh(r21:20, r31:30)
> +# CHECK: d0 de b4 ea
> +r17:16 += vrmpyweh(r21:20, r31:30):<<1
> +
> +# Multiply and use upper result
> +# CHECK: 31 df 15 ed
> +r17 = mpy(r21, r31)
> +# CHECK: 31 df 35 ed
> +r17 = mpy(r21, r31):rnd
> +# CHECK: 31 df 55 ed
> +r17 = mpyu(r21, r31)
> +# CHECK: 31 df 75 ed
> +r17 = mpysu(r21, r31)
> +# CHECK: 11 df b5 ed
> +r17 = mpy(r21, r31.h):<<1:sat
> +# CHECK: 31 df b5 ed
> +r17 = mpy(r21, r31.l):<<1:sat
> +# CHECK: 91 df b5 ed
> +r17 = mpy(r21, r31.h):<<1:rnd:sat
> +# CHECK: 11 df f5 ed
> +r17 = mpy(r21, r31):<<1:sat
> +# CHECK: 91 df f5 ed
> +r17 = mpy(r21, r31.l):<<1:rnd:sat
> +# CHECK: 51 df b5 ed
> +r17 = mpy(r21, r31):<<1
> +# CHECK: 11 df 75 ef
> +r17 += mpy(r21, r31):<<1:sat
> +# CHECK: 31 df 75 ef
> +r17 -= mpy(r21, r31):<<1:sat
> +
> +# Multiply and use full result
> +# CHECK: 10 df 15 e5
> +r17:16 = mpy(r21, r31)
> +# CHECK: 10 df 55 e5
> +r17:16 = mpyu(r21, r31)
> +# CHECK: 10 df 15 e7
> +r17:16 += mpy(r21, r31)
> +# CHECK: 10 df 35 e7
> +r17:16 -= mpy(r21, r31)
> +# CHECK: 10 df 55 e7
> +r17:16 += mpyu(r21, r31)
> +# CHECK: 10 df 75 e7
> +r17:16 -= mpyu(r21, r31)
> +
> +# Vector dual multiply
> +# CHECK: 90 de 14 e8
> +r17:16 = vdmpy(r21:20, r31:30):sat
> +# CHECK: 90 de 94 e8
> +r17:16 = vdmpy(r21:20, r31:30):<<1:sat
> +# CHECK: 90 de 14 ea
> +r17:16 += vdmpy(r21:20, r31:30):sat
> +# CHECK: 90 de 94 ea
> +r17:16 += vdmpy(r21:20, r31:30):<<1:sat
> +
> +# Vector dual multiply with round and pack
> +# CHECK: 11 de 14 e9
> +r17 = vdmpy(r21:20, r31:30):rnd:sat
> +# CHECK: 11 de 94 e9
> +r17 = vdmpy(r21:20, r31:30):<<1:rnd:sat
> +
> +# Vector reduce multiply bytes
> +# CHECK: 30 de 94 e8
> +r17:16 = vrmpybu(r21:20, r31:30)
> +# CHECK: 30 de d4 e8
> +r17:16 = vrmpybsu(r21:20, r31:30)
> +# CHECK: 30 de 94 ea
> +r17:16 += vrmpybu(r21:20, r31:30)
> +# CHECK: 30 de d4 ea
> +r17:16 += vrmpybsu(r21:20, r31:30)
> +
> +# Vector dual multiply signed by unsigned bytes
> +# CHECK: 30 de b4 e8
> +r17:16 = vdmpybsu(r21:20, r31:30):sat
> +# CHECK: 30 de 34 ea
> +r17:16 += vdmpybsu(r21:20, r31:30):sat
> +
> +# Vector multiply even haldwords
> +# CHECK: d0 de 14 e8
> +r17:16 = vmpyeh(r21:20, r31:30):sat
> +# CHECK: d0 de 94 e8
> +r17:16 = vmpyeh(r21:20, r31:30):<<1:sat
> +# CHECK: 50 de 34 ea
> +r17:16 += vmpyeh(r21:20, r31:30)
> +# CHECK: d0 de 14 ea
> +r17:16 += vmpyeh(r21:20, r31:30):sat
> +# CHECK: d0 de 94 ea
> +r17:16 += vmpyeh(r21:20, r31:30):<<1:sat
> +
> +# Vector multiply halfwords
> +# CHECK: b0 df 15 e5
> +r17:16 = vmpyh(r21, r31):sat
> +# CHECK: b0 df 95 e5
> +r17:16 = vmpyh(r21, r31):<<1:sat
> +# CHECK: 30 df 35 e7
> +r17:16 += vmpyh(r21, r31)
> +# CHECK: b0 df 15 e7
> +r17:16 += vmpyh(r21, r31):sat
> +# CHECK: b0 df 95 e7
> +r17:16 += vmpyh(r21, r31):<<1:sat
> +
> +# Vector multiply halfwords with round and pack
> +# CHECK: f1 df 35 ed
> +r17 = vmpyh(r21, r31):rnd:sat
> +# CHECK: f1 df b5 ed
> +r17 = vmpyh(r21, r31):<<1:rnd:sat
> +
> +# Vector multiply halfwords signed by unsigned
> +# CHECK: f0 df 15 e5
> +r17:16 = vmpyhsu(r21, r31):sat
> +# CHECK: f0 df 95 e5
> +r17:16 = vmpyhsu(r21, r31):<<1:sat
> +# CHECK: b0 df 75 e7
> +r17:16 += vmpyhsu(r21, r31):sat
> +# CHECK: b0 df f5 e7
> +r17:16 += vmpyhsu(r21, r31):<<1:sat
> +
> +# Vector reduce multiply halfwords
> +# CHECK: 50 de 14 e8
> +r17:16 = vrmpyh(r21:20, r31:30)
> +# CHECK: 50 de 14 ea
> +r17:16 += vrmpyh(r21:20, r31:30)
> +
> +# Vector multiply bytes
> +# CHECK: 30 df 55 e5
> +r17:16 = vmpybsu(r21, r31)
> +# CHECK: 30 df 95 e5
> +r17:16 = vmpybu(r21, r31)
> +# CHECK: 30 df 95 e7
> +r17:16 += vmpybu(r21, r31)
> +# CHECK: 30 df d5 e7
> +r17:16 += vmpybsu(r21, r31)
> +
> +# Vector polynomial multiply halfwords
> +# CHECK: f0 df d5 e5
> +r17:16 = vpmpyh(r21, r31)
> +# CHECK: f0 df b5 e7
> +r17:16 ^= vpmpyh(r21, r31)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/xtype_perm.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/xtype_perm.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/xtype_perm.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/xtype_perm.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,104 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.10.6 XTYPE/PERM
> +
> +# CABAC decode bin
> +# CHECK: d0 de d4 c1
> +r17:16 = decbin(r21:20, r31:30)
> +
> +# Saturate
> +# CHECK: 11 c0 d4 88
> +r17 = sat(r21:20)
> +# CHECK: 91 c0 d5 8c
> +r17 = sath(r21)
> +# CHECK: b1 c0 d5 8c
> +r17 = satuh(r21)
> +# CHECK: d1 c0 d5 8c
> +r17 = satub(r21)
> +# CHECK: f1 c0 d5 8c
> +r17 = satb(r21)
> +
> +# Swizzle bytes
> +# CHECK: f1 c0 95 8c
> +r17 = swiz(r21)
> +
> +# Vector align
> +# CHECK: 70 d4 1e c2
> +r17:16 = valignb(r21:20, r31:30, p3)
> +# CHECK: 70 de 94 c2
> +r17:16 = vspliceb(r21:20, r31:30, p3)
> +
> +# Vector round and pack
> +# CHECK: 91 c0 94 88
> +r17 = vrndwh(r21:20)
> +# CHECK: d1 c0 94 88
> +r17 = vrndwh(r21:20):sat
> +
> +# Vector saturate and pack
> +# CHECK: 11 c0 14 88
> +r17 = vsathub(r21:20)
> +# CHECK: 51 c0 14 88
> +r17 = vsatwh(r21:20)
> +# CHECK: 91 c0 14 88
> +r17 = vsatwuh(r21:20)
> +# CHECK: d1 c0 14 88
> +r17 = vsathb(r21:20)
> +# CHECK: 11 c0 95 8c
> +r17 = vsathb(r21)
> +# CHECK: 51 c0 95 8c
> +r17 = vsathub(r21)
> +
> +# Vector saturate without pack
> +# CHECK: 90 c0 14 80
> +r17:16 = vsathub(r21:20)
> +# CHECK: b0 c0 14 80
> +r17:16 = vsatwuh(r21:20)
> +# CHECK: d0 c0 14 80
> +r17:16 = vsatwh(r21:20)
> +# CHECK: f0 c0 14 80
> +r17:16 = vsathb(r21:20)
> +
> +# Vector shuffle
> +# CHECK: 50 de 14 c1
> +r17:16 = shuffeb(r21:20, r31:30)
> +# CHECK: 90 d4 1e c1
> +r17:16 = shuffob(r21:20, r31:30)
> +# CHECK: d0 de 14 c1
> +r17:16 = shuffeh(r21:20, r31:30)
> +# CHECK: 10 d4 9e c1
> +r17:16 = shuffoh(r21:20, r31:30)
> +
> +# Vector splat bytes
> +# CHECK: f1 c0 55 8c
> +r17 = vsplatb(r21)
> +
> +# Vector splat halfwords
> +# CHECK: 50 c0 55 84
> +r17:16 = vsplath(r21)
> +
> +# Vector splice
> +# CHECK: 70 de 94 c0
> +r17:16 = vspliceb(r21:20, r31:30, #3)
> +# CHECK: 70 de 94 c2
> +r17:16 = vspliceb(r21:20, r31:30, p3)
> +
> +# Vector sign extend
> +# CHECK: 10 c0 15 84
> +r17:16 = vsxtbh(r21)
> +# CHECK: 90 c0 15 84
> +r17:16 = vsxthw(r21)
> +
> +# Vector truncate
> +# CHECK: 11 c0 94 88
> +r17 = vtrunohb(r21:20)
> +# CHECK: 51 c0 94 88
> +r17 = vtrunehb(r21:20)
> +# CHECK: 50 de 94 c1
> +r17:16 = vtrunewh(r21:20, r31:30)
> +# CHECK: 90 de 94 c1
> +r17:16 = vtrunowh(r21:20, r31:30)
> +
> +# Vector zero extend
> +# CHECK: 50 c0 15 84
> +r17:16 = vzxtbh(r21)
> +# CHECK: d0 c0 15 84
> +r17:16 = vzxthw(r21)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/xtype_pred.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/xtype_pred.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/xtype_pred.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/xtype_pred.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,136 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.10.7 XTYPE/PRED
> +
> +# Bounds check
> +# CHECK: 83 f4 10 d2
> +p3 = boundscheck(r17:16, r21:20):raw:lo
> +# CHECK: a3 f4 10 d2
> +p3 = boundscheck(r17:16, r21:20):raw:hi
> +
> +# Compare byte
> +# CHECK: 43 d5 d1 c7
> +p3 = cmpb.gt(r17, r21)
> +# CHECK: c3 d5 d1 c7
> +p3 = cmpb.eq(r17, r21)
> +# CHECK: e3 d5 d1 c7
> +p3 = cmpb.gtu(r17, r21)
> +# CHECK: a3 c2 11 dd
> +p3 = cmpb.eq(r17, #21)
> +# CHECK: a3 c2 31 dd
> +p3 = cmpb.gt(r17, #21)
> +# CHECK: a3 c2 51 dd
> +p3 = cmpb.gtu(r17, #21)
> +
> +# Compare half
> +# CHECK: 63 d5 d1 c7
> +p3 = cmph.eq(r17, r21)
> +# CHECK: 83 d5 d1 c7
> +p3 = cmph.gt(r17, r21)
> +# CHECK: a3 d5 d1 c7
> +p3 = cmph.gtu(r17, r21)
> +# CHECK: ab c2 11 dd
> +p3 = cmph.eq(r17, #21)
> +# CHECK: ab c2 31 dd
> +p3 = cmph.gt(r17, #21)
> +# CHECK: ab c2 51 dd
> +p3 = cmph.gtu(r17, #21)
> +
> +# Compare doublewords
> +# CHECK: 03 de 94 d2
> +p3 = cmp.eq(r21:20, r31:30)
> +# CHECK: 43 de 94 d2
> +p3 = cmp.gt(r21:20, r31:30)
> +# CHECK: 83 de 94 d2
> +p3 = cmp.gtu(r21:20, r31:30)
> +
> +# Compare bitmask
> +# CHECK: 03 d5 91 85
> +p3 = bitsclr(r17, #21)
> +# CHECK: 03 d5 b1 85
> +p3 = !bitsclr(r17, #21)
> +# CHECK: 03 d5 51 c7
> +p3 = bitsset(r17, r21)
> +# CHECK: 03 d5 71 c7
> +p3 = !bitsset(r17, r21)
> +# CHECK: 03 d5 91 c7
> +p3 = bitsclr(r17, r21)
> +# CHECK: 03 d5 b1 c7
> +p3 = !bitsclr(r17, r21)
> +
> +# mask generate from predicate
> +# CHECK: 10 c3 00 86
> +r17:16 = mask(p3)
> +
> +# Check for TLB match
> +# CHECK: 63 f5 10 d2
> +p3 = tlbmatch(r17:16, r21)
> +
> +# Predicate Transfer
> +# CHECK: 03 c0 45 85
> +p3 = r5
> +# CHECK: 05 c0 43 89
> +r5 = p3
> +
> +# Test bit
> +# CHECK: 03 d5 11 85
> +p3 = tstbit(r17, #21)
> +# CHECK: 03 d5 31 85
> +p3 = !tstbit(r17, #21)
> +# CHECK: 03 d5 11 c7
> +p3 = tstbit(r17, r21)
> +# CHECK: 03 d5 31 c7
> +p3 = !tstbit(r17, r21)
> +
> +# Vector compare halfwords
> +# CHECK: 63 de 14 d2
> +p3 = vcmph.eq(r21:20, r31:30)
> +# CHECK: 83 de 14 d2
> +p3 = vcmph.gt(r21:20, r31:30)
> +# CHECK: a3 de 14 d2
> +p3 = vcmph.gtu(r21:20, r31:30)
> +# CHECK: eb c3 14 dc
> +p3 = vcmph.eq(r21:20, #31)
> +# CHECK: eb c3 34 dc
> +p3 = vcmph.gt(r21:20, #31)
> +# CHECK: eb c3 54 dc
> +p3 = vcmph.gtu(r21:20, #31)
> +
> +# Vector compare bytes for any match
> +# CHECK: 03 fe 14 d2
> +p3 = any8(vcmpb.eq(r21:20, r31:30))
> +
> +# Vector compare bytes
> +# CHECK: 63 de 14 d2
> +p3 = vcmph.eq(r21:20, r31:30)
> +# CHECK: 83 de 14 d2
> +p3 = vcmph.gt(r21:20, r31:30)
> +# CHECK: a3 de 14 d2
> +p3 = vcmph.gtu(r21:20, r31:30)
> +# CHECK: eb c3 14 dc
> +p3 = vcmph.eq(r21:20, #31)
> +# CHECK: eb c3 34 dc
> +p3 = vcmph.gt(r21:20, #31)
> +# CHECK: eb c3 54 dc
> +p3 = vcmph.gtu(r21:20, #31)
> +
> +# Vector compare words
> +# CHECK: 03 de 14 d2
> +p3 = vcmpw.eq(r21:20, r31:30)
> +# CHECK: 23 de 14 d2
> +p3 = vcmpw.gt(r21:20, r31:30)
> +# CHECK: 43 de 14 d2
> +p3 = vcmpw.gtu(r21:20, r31:30)
> +# CHECK: f3 c3 14 dc
> +p3 = vcmpw.eq(r21:20, #31)
> +# CHECK: f3 c3 34 dc
> +p3 = vcmpw.gt(r21:20, #31)
> +# CHECK: f3 c3 54 dc
> +p3 = vcmpw.gtu(r21:20, #31)
> +
> +# Viterbi pack even and odd predicate bits
> +# CHECK: 11 c2 03 89
> +r17 = vitpack(p3, p2)
> +
> +# Vector mux
> +# CHECK: 70 de 14 d1
> +r17:16 = vmux(p3, r21:20, r31:30)
>
> Added: llvm/trunk/test/MC/Hexagon/instructions/xtype_shift.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Hexagon/instructions/xtype_shift.s?rev=252443&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/MC/Hexagon/instructions/xtype_shift.s (added)
> +++ llvm/trunk/test/MC/Hexagon/instructions/xtype_shift.s Sun Nov  8
> 22:07:48 2015
> @@ -0,0 +1,260 @@
> +# RUN: llvm-mc -triple=hexagon -filetype=obj -o - %s | llvm-objdump -d -
> | FileCheck %s
> +# Hexagon Programmer's Reference Manual 11.10.8 XTYPE/SHIFT
> +
> +# Shift by immediate
> +# CHECK: 10 df 14 80
> +r17:16 = asr(r21:20, #31)
> +# CHECK: 30 df 14 80
> +r17:16 = lsr(r21:20, #31)
> +# CHECK: 50 df 14 80
> +r17:16 = asl(r21:20, #31)
> +# CHECK: 11 df 15 8c
> +r17 = asr(r21, #31)
> +# CHECK: 31 df 15 8c
> +r17 = lsr(r21, #31)
> +# CHECK: 51 df 15 8c
> +r17 = asl(r21, #31)
> +
> +# Shift by immediate and accumulate
> +# CHECK: 10 df 14 82
> +r17:16 -= asr(r21:20, #31)
> +# CHECK: 30 df 14 82
> +r17:16 -= lsr(r21:20, #31)
> +# CHECK: 50 df 14 82
> +r17:16 -= asl(r21:20, #31)
> +# CHECK: 90 df 14 82
> +r17:16 += asr(r21:20, #31)
> +# CHECK: b0 df 14 82
> +r17:16 += lsr(r21:20, #31)
> +# CHECK: d0 df 14 82
> +r17:16 += asl(r21:20, #31)
> +# CHECK: 11 df 15 8e
> +r17 -= asr(r21, #31)
> +# CHECK: 31 df 15 8e
> +r17 -= lsr(r21, #31)
> +# CHECK: 51 df 15 8e
> +r17 -= asl(r21, #31)
> +# CHECK: 91 df 15 8e
> +r17 += asr(r21, #31)
> +# CHECK: b1 df 15 8e
> +r17 += lsr(r21, #31)
> +# CHECK: d1 df 15 8e
> +r17 += asl(r21, #31)
> +# CHECK: 4c f7 11 de
> +r17 = add(#21, asl(r17, #23))
> +# CHECK: 4e f7 11 de
> +r17 = sub(#21, asl(r17, #23))
> +# CHECK: 5c f7 11 de
> +r17 = add(#21, lsr(r17, #23))
> +# CHECK: 5e f7 11 de
> +r17 = sub(#21, lsr(r17, #23))
> +
> +# Shift by immediate and add
> +# CHECK: f1 d5 1f c4
> +r17 = addasl(r21, r31, #7)
> +
> +# Shift by immediate and logical
> +# CHECK: 10 df 54 82
> +r17:16 &= asr(r21:20, #31)
> +# CHECK: 30 df 54 82
> +r17:16 &= lsr(r21:20, #31)
> +# CHECK: 50 df 54 82
> +r17:16 &= asl(r21:20, #31)
> +# CHECK: 90 df 54 82
> +r17:16 |= asr(r21:20, #31)
> +# CHECK: b0 df 54 82
> +r17:16 |= lsr(r21:20, #31)
> +# CHECK: d0 df 54 82
> +r17:16 |= asl(r21:20, #31)
> +# CHECK: 30 df 94 82
> +r17:16 ^= lsr(r21:20, #31)
> +# CHECK: 50 df 94 82
> +r17:16 ^= asl(r21:20, #31)
> +# CHECK: 11 df 55 8e
> +r17 &= asr(r21, #31)
> +# CHECK: 31 df 55 8e
> +r17 &= lsr(r21, #31)
> +# CHECK: 51 df 55 8e
> +r17 &= asl(r21, #31)
> +# CHECK: 91 df 55 8e
> +r17 |= asr(r21, #31)
> +# CHECK: b1 df 55 8e
> +r17 |= lsr(r21, #31)
> +# CHECK: d1 df 55 8e
> +r17 |= asl(r21, #31)
> +# CHECK: 31 df 95 8e
> +r17 ^= lsr(r21, #31)
> +# CHECK: 51 df 95 8e
> +r17 ^= asl(r21, #31)
> +# CHECK: 48 ff 11 de
> +r17 = and(#21, asl(r17, #31))
> +# CHECK: 4a ff 11 de
> +r17 = or(#21, asl(r17, #31))
> +# CHECK: 58 ff 11 de
> +r17 = and(#21, lsr(r17, #31))
> +# CHECK: 5a ff 11 de
> +r17 = or(#21, lsr(r17, #31))
> +
> +# Shift right by immediate with rounding
> +# CHECK: f0 df d4 80
> +r17:16 = asr(r21:20, #31):rnd
> +# CHECK: 11 df 55 8c
> +r17 = asr(r21, #31):rnd
> +
> +# Shift left by immediate with saturation
> +# CHECK: 51 df 55 8c
> +r17 = asl(r21, #31):sat
> +
> +# Shift by register
> +# CHECK: 10 df 94 c3
> +r17:16 = asr(r21:20, r31)
> +# CHECK: 50 df 94 c3
> +r17:16 = lsr(r21:20, r31)
> +# CHECK: 90 df 94 c3
> +r17:16 = asl(r21:20, r31)
> +# CHECK: d0 df 94 c3
> +r17:16 = lsl(r21:20, r31)
> +# CHECK: 11 df 55 c6
> +r17 = asr(r21, r31)
> +# CHECK: 51 df 55 c6
> +r17 = lsr(r21, r31)
> +# CHECK: 91 df 55 c6
> +r17 = asl(r21, r31)
> +# CHECK: d1 df 55 c6
> +r17 = lsl(r21, r31)
> +# CHECK: f1 df 8a c6
> +r17 = lsl(#21, r31)
> +
> +# Shift by register and accumulate
> +# CHECK: 10 df 94 cb
> +r17:16 -= asr(r21:20, r31)
> +# CHECK: 50 df 94 cb
> +r17:16 -= lsr(r21:20, r31)
> +# CHECK: 90 df 94 cb
> +r17:16 -= asl(r21:20, r31)
> +# CHECK: d0 df 94 cb
> +r17:16 -= lsl(r21:20, r31)
> +# CHECK: 10 df d4 cb
> +r17:16 += asr(r21:20, r31)
> +# CHECK: 50 df d4 cb
> +r17:16 += lsr(r21:20, r31)
> +# CHECK: 90 df d4 cb
> +r17:16 += asl(r21:20, r31)
> +# CHECK: d0 df d4 cb
> +r17:16 += lsl(r21:20, r31)
> +# CHECK: 11 df 95 cc
> +r17 -= asr(r21, r31)
> +# CHECK: 51 df 95 cc
> +r17 -= lsr(r21, r31)
> +# CHECK: 91 df 95 cc
> +r17 -= asl(r21, r31)
> +# CHECK: d1 df 95 cc
> +r17 -= lsl(r21, r31)
> +# CHECK: 11 df d5 cc
> +r17 += asr(r21, r31)
> +# CHECK: 51 df d5 cc
> +r17 += lsr(r21, r31)
> +# CHECK: 91 df d5 cc
> +r17 += asl(r21, r31)
> +# CHECK: d1 df d5 cc
> +r17 += lsl(r21, r31)
> +
> +# Shift by register and logical
> +# CHECK: 10 df 14 cb
> +r17:16 |= asr(r21:20, r31)
> +# CHECK: 50 df 14 cb
> +r17:16 |= lsr(r21:20, r31)
> +# CHECK: 90 df 14 cb
> +r17:16 |= asl(r21:20, r31)
> +# CHECK: d0 df 14 cb
> +r17:16 |= lsl(r21:20, r31)
> +# CHECK: 10 df 54 cb
> +r17:16 &= asr(r21:20, r31)
> +# CHECK: 50 df 54 cb
> +r17:16 &= lsr(r21:20, r31)
> +# CHECK: 90 df 54 cb
> +r17:16 &= asl(r21:20, r31)
> +# CHECK: d0 df 54 cb
> +r17:16 &= lsl(r21:20, r31)
> +# CHECK: 10 df 74 cb
> +r17:16 ^= asr(r21:20, r31)
> +# CHECK: 50 df 74 cb
> +r17:16 ^= lsr(r21:20, r31)
> +# CHECK: 90 df 74 cb
> +r17:16 ^= asl(r21:20, r31)
> +# CHECK: d0 df 74 cb
> +r17:16 ^= lsl(r21:20, r31)
> +# CHECK: 11 df 15 cc
> +r17 |= asr(r21, r31)
> +# CHECK: 51 df 15 cc
> +r17 |= lsr(r21, r31)
> +# CHECK: 91 df 15 cc
> +r17 |= asl(r21, r31)
> +# CHECK: d1 df 15 cc
> +r17 |= lsl(r21, r31)
> +# CHECK: 11 df 55 cc
> +r17 &= asr(r21, r31)
> +# CHECK: 51 df 55 cc
> +r17 &= lsr(r21, r31)
> +# CHECK: 91 df 55 cc
> +r17 &= asl(r21, r31)
> +# CHECK: d1 df 55 cc
> +r17 &= lsl(r21, r31)
> +
> +# Shift by register with saturation
> +# CHECK: 11 df 15 c6
> +r17 = asr(r21, r31):sat
> +# CHECK: 91 df 15 c6
> +r17 = asl(r21, r31):sat
> +
> +# Vector shift halfwords by immediate
> +# CHECK: 10 c5 94 80
> +r17:16 = vasrh(r21:20, #5)
> +# CHECK: 30 c5 94 80
> +r17:16 = vlsrh(r21:20, #5)
> +# CHECK: 50 c5 94 80
> +r17:16 = vaslh(r21:20, #5)
> +
> +# Vector arithmetic shift halfwords with round
> +# CHECK: 10 c5 34 80
> +r17:16 = vasrh(r21:20, #5):raw
> +
> +# Vector arithmetic shift halfwords with saturate and pack
> +# CHECK: 91 c5 74 88
> +r17 = vasrhub(r21:20, #5):raw
> +# CHECK: b1 c5 74 88
> +r17 = vasrhub(r21:20, #5):sat
> +
> +# Vector shift halfwords by register
> +# CHECK: 10 df 54 c3
> +r17:16 = vasrh(r21:20, r31)
> +# CHECK: 50 df 54 c3
> +r17:16 = vlsrh(r21:20, r31)
> +# CHECK: 90 df 54 c3
> +r17:16 = vaslh(r21:20, r31)
> +# CHECK: d0 df 54 c3
> +r17:16 = vlslh(r21:20, r31)
> +
> +# Vector shift words by immediate
> +# CHECK: 10 df 54 80
> +r17:16 = vasrw(r21:20, #31)
> +# CHECK: 30 df 54 80
> +r17:16 = vlsrw(r21:20, #31)
> +# CHECK: 50 df 54 80
> +r17:16 = vaslw(r21:20, #31)
> +
> +# Vector shift words by register
> +# CHECK: 10 df 14 c3
> +r17:16 = vasrw(r21:20, r31)
> +# CHECK: 50 df 14 c3
> +r17:16 = vlsrw(r21:20, r31)
> +# CHECK: 90 df 14 c3
> +r17:16 = vaslw(r21:20, r31)
> +# CHECK: d0 df 14 c3
> +r17:16 = vlslw(r21:20, r31)
> +
> +# Vector shift words with truncate and pack
> +# CHECK: 51 df d4 88
> +r17 = vasrw(r21:20, #31)
> +# CHECK: 51 df 14 c5
> +r17 = vasrw(r21:20, r31)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151109/8fc0b2e6/attachment-0001.html>


More information about the llvm-commits mailing list