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