brintos

brintos / llvm-project-archived public Read only

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