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