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