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