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