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