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