LLVM  7.0.0svn
HexagonAsmParser.cpp
Go to the documentation of this file.
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 "HexagonTargetStreamer.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/ADT/Twine.h"
25 #include "llvm/BinaryFormat/ELF.h"
26 #include "llvm/MC/MCAssembler.h"
27 #include "llvm/MC/MCContext.h"
28 #include "llvm/MC/MCDirectives.h"
29 #include "llvm/MC/MCELFStreamer.h"
30 #include "llvm/MC/MCExpr.h"
31 #include "llvm/MC/MCInst.h"
37 #include "llvm/MC/MCRegisterInfo.h"
38 #include "llvm/MC/MCSectionELF.h"
39 #include "llvm/MC/MCStreamer.h"
41 #include "llvm/MC/MCSymbol.h"
42 #include "llvm/MC/MCValue.h"
43 #include "llvm/Support/Casting.h"
45 #include "llvm/Support/Debug.h"
47 #include "llvm/Support/Format.h"
49 #include "llvm/Support/SMLoc.h"
50 #include "llvm/Support/SourceMgr.h"
53 #include <algorithm>
54 #include <cassert>
55 #include <cctype>
56 #include <cstddef>
57 #include <cstdint>
58 #include <memory>
59 #include <string>
60 #include <utility>
61 
62 using namespace llvm;
63 
65  "mwarn-missing-parenthesis",
66  cl::desc("Warn for missing parenthesis around predicate registers"),
67  cl::init(true));
69  "merror-missing-parenthesis",
70  cl::desc("Error for missing parenthesis around predicate registers"),
71  cl::init(false));
73  "mwarn-sign-mismatch",
74  cl::desc("Warn for mismatching a signed and unsigned value"),
75  cl::init(true));
77  "mwarn-noncontigious-register",
78  cl::desc("Warn for register names that arent contigious"), cl::init(true));
80  "merror-noncontigious-register",
81  cl::desc("Error for register names that aren't contigious"),
82  cl::init(false));
83 
84 namespace {
85 
86 struct HexagonOperand;
87 
88 class HexagonAsmParser : public MCTargetAsmParser {
89 
90  HexagonTargetStreamer &getTargetStreamer() {
92  return static_cast<HexagonTargetStreamer &>(TS);
93  }
94 
95  MCAsmParser &Parser;
96  MCInst MCB;
97  bool InBrackets;
98 
99  MCAsmParser &getParser() const { return Parser; }
100  MCAssembler *getAssembler() const {
101  MCAssembler *Assembler = nullptr;
102  // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
103  if (!Parser.getStreamer().hasRawTextSupport()) {
104  MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
105  Assembler = &MES->getAssembler();
106  }
107  return Assembler;
108  }
109 
110  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
111 
112  bool equalIsAsmAssignment() override { return false; }
113  bool isLabel(AsmToken &Token) override;
114 
115  void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
116  bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
117  bool ParseDirectiveFalign(unsigned Size, SMLoc L);
118 
119  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
120  bool ParseDirectiveSubsection(SMLoc L);
121  bool ParseDirectiveComm(bool IsLocal, SMLoc L);
122  bool RegisterMatchesArch(unsigned MatchNum) const;
123 
124  bool matchBundleOptions();
125  bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);
126  bool finishBundle(SMLoc IDLoc, MCStreamer &Out);
127  void canonicalizeImmediates(MCInst &MCI);
128  bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,
129  OperandVector &InstOperands, uint64_t &ErrorInfo,
130  bool MatchingInlineAsm);
131  void eatToEndOfPacket();
132  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
133  OperandVector &Operands, MCStreamer &Out,
134  uint64_t &ErrorInfo,
135  bool MatchingInlineAsm) override;
136 
137  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
138  unsigned Kind) override;
139  bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
140  int processInstruction(MCInst &Inst, OperandVector const &Operands,
141  SMLoc IDLoc);
142 
143  // Check if we have an assembler and, if so, set the ELF e_header flags.
144  void chksetELFHeaderEFlags(unsigned flags) {
145  if (getAssembler())
146  getAssembler()->setELFHeaderEFlags(flags);
147  }
148 
149  unsigned matchRegister(StringRef Name);
150 
151 /// @name Auto-generated Match Functions
152 /// {
153 
154 #define GET_ASSEMBLER_HEADER
155 #include "HexagonGenAsmMatcher.inc"
156 
157  /// }
158 
159 public:
160  HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,
161  const MCInstrInfo &MII, const MCTargetOptions &Options)
162  : MCTargetAsmParser(Options, _STI, MII), Parser(_Parser),
163  InBrackets(false) {
164  MCB.setOpcode(Hexagon::BUNDLE);
165  setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
166 
167  Parser.addAliasForDirective(".half", ".2byte");
168  Parser.addAliasForDirective(".hword", ".2byte");
169  Parser.addAliasForDirective(".word", ".4byte");
170 
172  }
173 
174  bool splitIdentifier(OperandVector &Operands);
175  bool parseOperand(OperandVector &Operands);
176  bool parseInstruction(OperandVector &Operands);
177  bool implicitExpressionLocation(OperandVector &Operands);
178  bool parseExpressionOrOperand(OperandVector &Operands);
179  bool parseExpression(MCExpr const *&Expr);
180 
181  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
182  SMLoc NameLoc, OperandVector &Operands) override {
183  llvm_unreachable("Unimplemented");
184  }
185 
186  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
187  OperandVector &Operands) override;
188 
189  bool ParseDirective(AsmToken DirectiveID) override;
190 };
191 
192 /// HexagonOperand - Instances of this class represent a parsed Hexagon machine
193 /// instruction.
194 struct HexagonOperand : public MCParsedAsmOperand {
195  enum KindTy { Token, Immediate, Register } Kind;
197 
198  SMLoc StartLoc, EndLoc;
199 
200  struct TokTy {
201  const char *Data;
202  unsigned Length;
203  };
204 
205  struct RegTy {
206  unsigned RegNum;
207  };
208 
209  struct ImmTy {
210  const MCExpr *Val;
211  };
212 
213  struct InstTy {
214  OperandVector *SubInsts;
215  };
216 
217  union {
218  struct TokTy Tok;
219  struct RegTy Reg;
220  struct ImmTy Imm;
221  };
222 
223  HexagonOperand(KindTy K, MCContext &Context)
224  : MCParsedAsmOperand(), Kind(K), Context(Context) {}
225 
226 public:
227  HexagonOperand(const HexagonOperand &o)
228  : MCParsedAsmOperand(), Context(o.Context) {
229  Kind = o.Kind;
230  StartLoc = o.StartLoc;
231  EndLoc = o.EndLoc;
232  switch (Kind) {
233  case Register:
234  Reg = o.Reg;
235  break;
236  case Immediate:
237  Imm = o.Imm;
238  break;
239  case Token:
240  Tok = o.Tok;
241  break;
242  }
243  }
244 
245  /// getStartLoc - Get the location of the first token of this operand.
246  SMLoc getStartLoc() const override { return StartLoc; }
247 
248  /// getEndLoc - Get the location of the last token of this operand.
249  SMLoc getEndLoc() const override { return EndLoc; }
250 
251  unsigned getReg() const override {
252  assert(Kind == Register && "Invalid access!");
253  return Reg.RegNum;
254  }
255 
256  const MCExpr *getImm() const {
257  assert(Kind == Immediate && "Invalid access!");
258  return Imm.Val;
259  }
260 
261  bool isToken() const override { return Kind == Token; }
262  bool isImm() const override { return Kind == Immediate; }
263  bool isMem() const override { llvm_unreachable("No isMem"); }
264  bool isReg() const override { return Kind == Register; }
265 
266  bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
267  bool isRelocatable, bool Extendable) const {
268  if (Kind == Immediate) {
269  const MCExpr *myMCExpr = &HexagonMCInstrInfo::getExpr(*getImm());
270  if (HexagonMCInstrInfo::mustExtend(*Imm.Val) && !Extendable)
271  return false;
272  int64_t Res;
273  if (myMCExpr->evaluateAsAbsolute(Res)) {
274  int bits = immBits + zeroBits;
275  // Field bit range is zerobits + bits
276  // zeroBits must be 0
277  if (Res & ((1 << zeroBits) - 1))
278  return false;
279  if (isSigned) {
280  if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
281  return true;
282  } else {
283  if (bits == 64)
284  return true;
285  if (Res >= 0)
286  return ((uint64_t)Res < (uint64_t)(1ULL << bits));
287  else {
288  const int64_t high_bit_set = 1ULL << 63;
289  const uint64_t mask = (high_bit_set >> (63 - bits));
290  return (((uint64_t)Res & mask) == mask);
291  }
292  }
293  } else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)
294  return true;
295  else if (myMCExpr->getKind() == MCExpr::Binary ||
296  myMCExpr->getKind() == MCExpr::Unary)
297  return true;
298  }
299  return false;
300  }
301 
302  bool isa30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
303  bool isb30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
304  bool isb15_2Imm() const { return CheckImmRange(15, 2, true, true, false); }
305  bool isb13_2Imm() const { return CheckImmRange(13, 2, true, true, false); }
306 
307  bool ism32_0Imm() const { return true; }
308 
309  bool isf32Imm() const { return false; }
310  bool isf64Imm() const { return false; }
311  bool iss32_0Imm() const { return true; }
312  bool iss31_1Imm() const { return true; }
313  bool iss30_2Imm() const { return true; }
314  bool iss29_3Imm() const { return true; }
315  bool iss27_2Imm() const { return CheckImmRange(27, 2, true, true, false); }
316  bool iss10_0Imm() const { return CheckImmRange(10, 0, true, false, false); }
317  bool iss10_6Imm() const { return CheckImmRange(10, 6, true, false, false); }
318  bool iss9_0Imm() const { return CheckImmRange(9, 0, true, false, false); }
319  bool iss8_0Imm() const { return CheckImmRange(8, 0, true, false, false); }
320  bool iss8_0Imm64() const { return CheckImmRange(8, 0, true, true, false); }
321  bool iss7_0Imm() const { return CheckImmRange(7, 0, true, false, false); }
322  bool iss6_0Imm() const { return CheckImmRange(6, 0, true, false, false); }
323  bool iss6_3Imm() const { return CheckImmRange(6, 3, true, false, false); }
324  bool iss4_0Imm() const { return CheckImmRange(4, 0, true, false, false); }
325  bool iss4_1Imm() const { return CheckImmRange(4, 1, true, false, false); }
326  bool iss4_2Imm() const { return CheckImmRange(4, 2, true, false, false); }
327  bool iss4_3Imm() const { return CheckImmRange(4, 3, true, false, false); }
328  bool iss3_0Imm() const { return CheckImmRange(3, 0, true, false, false); }
329 
330  bool isu64_0Imm() const { return CheckImmRange(64, 0, false, true, true); }
331  bool isu32_0Imm() const { return true; }
332  bool isu31_1Imm() const { return true; }
333  bool isu30_2Imm() const { return true; }
334  bool isu29_3Imm() const { return true; }
335  bool isu26_6Imm() const { return CheckImmRange(26, 6, false, true, false); }
336  bool isu16_0Imm() const { return CheckImmRange(16, 0, false, true, false); }
337  bool isu16_1Imm() const { return CheckImmRange(16, 1, false, true, false); }
338  bool isu16_2Imm() const { return CheckImmRange(16, 2, false, true, false); }
339  bool isu16_3Imm() const { return CheckImmRange(16, 3, false, true, false); }
340  bool isu11_3Imm() const { return CheckImmRange(11, 3, false, false, false); }
341  bool isu10_0Imm() const { return CheckImmRange(10, 0, false, false, false); }
342  bool isu9_0Imm() const { return CheckImmRange(9, 0, false, false, false); }
343  bool isu8_0Imm() const { return CheckImmRange(8, 0, false, false, false); }
344  bool isu7_0Imm() const { return CheckImmRange(7, 0, false, false, false); }
345  bool isu6_0Imm() const { return CheckImmRange(6, 0, false, false, false); }
346  bool isu6_1Imm() const { return CheckImmRange(6, 1, false, false, false); }
347  bool isu6_2Imm() const { return CheckImmRange(6, 2, false, false, false); }
348  bool isu6_3Imm() const { return CheckImmRange(6, 3, false, false, false); }
349  bool isu5_0Imm() const { return CheckImmRange(5, 0, false, false, false); }
350  bool isu5_2Imm() const { return CheckImmRange(5, 2, false, false, false); }
351  bool isu5_3Imm() const { return CheckImmRange(5, 3, false, false, false); }
352  bool isu4_0Imm() const { return CheckImmRange(4, 0, false, false, false); }
353  bool isu4_2Imm() const { return CheckImmRange(4, 2, false, false, false); }
354  bool isu3_0Imm() const { return CheckImmRange(3, 0, false, false, false); }
355  bool isu3_1Imm() const { return CheckImmRange(3, 1, false, false, false); }
356  bool isu2_0Imm() const { return CheckImmRange(2, 0, false, false, false); }
357  bool isu1_0Imm() const { return CheckImmRange(1, 0, false, false, false); }
358 
359  bool isn1Const() const {
360  if (!isImm())
361  return false;
362  int64_t Value;
363  if (!getImm()->evaluateAsAbsolute(Value))
364  return false;
365  return Value == -1;
366  }
367  bool iss11_0Imm() const {
368  return CheckImmRange(11 + 26, 0, true, true, true);
369  }
370  bool iss11_1Imm() const {
371  return CheckImmRange(11 + 26, 1, true, true, true);
372  }
373  bool iss11_2Imm() const {
374  return CheckImmRange(11 + 26, 2, true, true, true);
375  }
376  bool iss11_3Imm() const {
377  return CheckImmRange(11 + 26, 3, true, true, true);
378  }
379  bool isu32_0MustExt() const { return isImm(); }
380 
381  void addRegOperands(MCInst &Inst, unsigned N) const {
382  assert(N == 1 && "Invalid number of operands!");
384  }
385 
386  void addImmOperands(MCInst &Inst, unsigned N) const {
387  assert(N == 1 && "Invalid number of operands!");
388  Inst.addOperand(MCOperand::createExpr(getImm()));
389  }
390 
391  void addSignedImmOperands(MCInst &Inst, unsigned N) const {
392  assert(N == 1 && "Invalid number of operands!");
393  HexagonMCExpr *Expr =
394  const_cast<HexagonMCExpr *>(cast<HexagonMCExpr>(getImm()));
395  int64_t Value;
396  if (!Expr->evaluateAsAbsolute(Value)) {
397  Inst.addOperand(MCOperand::createExpr(Expr));
398  return;
399  }
400  int64_t Extended = SignExtend64(Value, 32);
402  MCConstantExpr::create(Extended, Context), Context);
403  if ((Extended < 0) != (Value < 0))
404  NewExpr->setSignMismatch();
405  NewExpr->setMustExtend(Expr->mustExtend());
406  NewExpr->setMustNotExtend(Expr->mustNotExtend());
407  Inst.addOperand(MCOperand::createExpr(NewExpr));
408  }
409 
410  void addn1ConstOperands(MCInst &Inst, unsigned N) const {
411  addImmOperands(Inst, N);
412  }
413 
414  StringRef getToken() const {
415  assert(Kind == Token && "Invalid access!");
416  return StringRef(Tok.Data, Tok.Length);
417  }
418 
419  void print(raw_ostream &OS) const override;
420 
421  static std::unique_ptr<HexagonOperand> CreateToken(MCContext &Context,
422  StringRef Str, SMLoc S) {
423  HexagonOperand *Op = new HexagonOperand(Token, Context);
424  Op->Tok.Data = Str.data();
425  Op->Tok.Length = Str.size();
426  Op->StartLoc = S;
427  Op->EndLoc = S;
428  return std::unique_ptr<HexagonOperand>(Op);
429  }
430 
431  static std::unique_ptr<HexagonOperand>
432  CreateReg(MCContext &Context, unsigned RegNum, SMLoc S, SMLoc E) {
433  HexagonOperand *Op = new HexagonOperand(Register, Context);
434  Op->Reg.RegNum = RegNum;
435  Op->StartLoc = S;
436  Op->EndLoc = E;
437  return std::unique_ptr<HexagonOperand>(Op);
438  }
439 
440  static std::unique_ptr<HexagonOperand>
441  CreateImm(MCContext &Context, const MCExpr *Val, SMLoc S, SMLoc E) {
442  HexagonOperand *Op = new HexagonOperand(Immediate, Context);
443  Op->Imm.Val = Val;
444  Op->StartLoc = S;
445  Op->EndLoc = E;
446  return std::unique_ptr<HexagonOperand>(Op);
447  }
448 };
449 
450 } // end anonymous namespace
451 
452 void HexagonOperand::print(raw_ostream &OS) const {
453  switch (Kind) {
454  case Immediate:
455  getImm()->print(OS, nullptr);
456  break;
457  case Register:
458  OS << "<register R";
459  OS << getReg() << ">";
460  break;
461  case Token:
462  OS << "'" << getToken() << "'";
463  break;
464  }
465 }
466 
467 bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
468  LLVM_DEBUG(dbgs() << "Bundle:");
469  LLVM_DEBUG(MCB.dump_pretty(dbgs()));
470  LLVM_DEBUG(dbgs() << "--\n");
471 
472  MCB.setLoc(IDLoc);
473  // Check the bundle for errors.
474  const MCRegisterInfo *RI = getContext().getRegisterInfo();
475  HexagonMCChecker Check(getContext(), MII, getSTI(), MCB, *RI);
476 
477  bool CheckOk = HexagonMCInstrInfo::canonicalizePacket(MII, getSTI(),
478  getContext(), MCB,
479  &Check);
480 
481  if (CheckOk) {
482  if (HexagonMCInstrInfo::bundleSize(MCB) == 0) {
485  // Empty packets are valid yet aren't emitted
486  return false;
487  }
488  Out.EmitInstruction(MCB, getSTI());
489  } else {
490  // If compounding and duplexing didn't reduce the size below
491  // 4 or less we have a packet that is too big.
493  Error(IDLoc, "invalid instruction packet: out of slots");
494  }
495  return true; // Error
496  }
497 
498  return false; // No error
499 }
500 
501 bool HexagonAsmParser::matchBundleOptions() {
502  MCAsmParser &Parser = getParser();
503  while (true) {
504  if (!Parser.getTok().is(AsmToken::Colon))
505  return false;
506  Lex();
507  char const *MemNoShuffMsg =
508  "invalid instruction packet: mem_noshuf specifier not "
509  "supported with this architecture";
510  StringRef Option = Parser.getTok().getString();
511  auto IDLoc = Parser.getTok().getLoc();
512  if (Option.compare_lower("endloop01") == 0) {
515  } else if (Option.compare_lower("endloop0") == 0) {
517  } else if (Option.compare_lower("endloop1") == 0) {
519  } else if (Option.compare_lower("mem_noshuf") == 0) {
520  if (getSTI().getFeatureBits()[Hexagon::FeatureMemNoShuf])
522  else
523  return getParser().Error(IDLoc, MemNoShuffMsg);
524  } else
525  return getParser().Error(IDLoc, llvm::Twine("'") + Option +
526  "' is not a valid bundle option");
527  Lex();
528  }
529 }
530 
531 // For instruction aliases, immediates are generated rather than
532 // MCConstantExpr. Convert them for uniform MCExpr.
533 // Also check for signed/unsigned mismatches and warn
534 void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
535  MCInst NewInst;
536  NewInst.setOpcode(MCI.getOpcode());
537  for (MCOperand &I : MCI)
538  if (I.isImm()) {
539  int64_t Value(I.getImm());
541  MCConstantExpr::create(Value, getContext()), getContext())));
542  } else {
543  if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&
545  Warning(MCI.getLoc(), "Signed/Unsigned mismatch");
546  NewInst.addOperand(I);
547  }
548  MCI = NewInst;
549 }
550 
551 bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
552  OperandVector &InstOperands,
553  uint64_t &ErrorInfo,
554  bool MatchingInlineAsm) {
555  // Perform matching with tablegen asmmatcher generated function
556  int result =
557  MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
558  if (result == Match_Success) {
559  MCI.setLoc(IDLoc);
560  canonicalizeImmediates(MCI);
561  result = processInstruction(MCI, InstOperands, IDLoc);
562 
563  LLVM_DEBUG(dbgs() << "Insn:");
564  LLVM_DEBUG(MCI.dump_pretty(dbgs()));
565  LLVM_DEBUG(dbgs() << "\n\n");
566 
567  MCI.setLoc(IDLoc);
568  }
569 
570  // Create instruction operand for bundle instruction
571  // Break this into a separate function Code here is less readable
572  // Think about how to get an instruction error to report correctly.
573  // SMLoc will return the "{"
574  switch (result) {
575  default:
576  break;
577  case Match_Success:
578  return false;
579  case Match_MissingFeature:
580  return Error(IDLoc, "invalid instruction");
581  case Match_MnemonicFail:
582  return Error(IDLoc, "unrecognized instruction");
583  case Match_InvalidOperand:
584  SMLoc ErrorLoc = IDLoc;
585  if (ErrorInfo != ~0U) {
586  if (ErrorInfo >= InstOperands.size())
587  return Error(IDLoc, "too few operands for instruction");
588 
589  ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
590  ->getStartLoc();
591  if (ErrorLoc == SMLoc())
592  ErrorLoc = IDLoc;
593  }
594  return Error(ErrorLoc, "invalid operand for instruction");
595  }
596  llvm_unreachable("Implement any new match types added!");
597 }
598 
599 void HexagonAsmParser::eatToEndOfPacket() {
600  assert(InBrackets);
601  MCAsmLexer &Lexer = getLexer();
602  while (!Lexer.is(AsmToken::RCurly))
603  Lexer.Lex();
604  Lexer.Lex();
605  InBrackets = false;
606 }
607 
608 bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
609  OperandVector &Operands,
610  MCStreamer &Out,
611  uint64_t &ErrorInfo,
612  bool MatchingInlineAsm) {
613  if (!InBrackets) {
614  MCB.clear();
616  }
617  HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
618  if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
619  assert(Operands.size() == 1 && "Brackets should be by themselves");
620  if (InBrackets) {
621  getParser().Error(IDLoc, "Already in a packet");
622  InBrackets = false;
623  return true;
624  }
625  InBrackets = true;
626  return false;
627  }
628  if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
629  assert(Operands.size() == 1 && "Brackets should be by themselves");
630  if (!InBrackets) {
631  getParser().Error(IDLoc, "Not in a packet");
632  return true;
633  }
634  InBrackets = false;
635  if (matchBundleOptions())
636  return true;
637  return finishBundle(IDLoc, Out);
638  }
639  MCInst *SubInst = new (getParser().getContext()) MCInst;
640  if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
641  MatchingInlineAsm)) {
642  if (InBrackets)
643  eatToEndOfPacket();
644  return true;
645  }
647  getParser().getContext(), MII, MCB, *SubInst);
648  MCB.addOperand(MCOperand::createInst(SubInst));
649  if (!InBrackets)
650  return finishBundle(IDLoc, Out);
651  return false;
652 }
653 
654 /// ParseDirective parses the Hexagon specific directives
655 bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
656  StringRef IDVal = DirectiveID.getIdentifier();
657  if (IDVal.lower() == ".falign")
658  return ParseDirectiveFalign(256, DirectiveID.getLoc());
659  if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
660  return ParseDirectiveComm(true, DirectiveID.getLoc());
661  if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
662  return ParseDirectiveComm(false, DirectiveID.getLoc());
663  if (IDVal.lower() == ".subsection")
664  return ParseDirectiveSubsection(DirectiveID.getLoc());
665 
666  return true;
667 }
668 bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
669  const MCExpr *Subsection = nullptr;
670  int64_t Res;
671 
672  assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
673  "Invalid subsection directive");
674  getParser().parseExpression(Subsection);
675 
676  if (!Subsection->evaluateAsAbsolute(Res))
677  return Error(L, "Cannot evaluate subsection number");
678 
679  if (getLexer().isNot(AsmToken::EndOfStatement))
680  return TokError("unexpected token in directive");
681 
682  // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
683  // negative subsections together and in the same order but at the opposite
684  // end of the section. Only legacy hexagon-gcc created assembly code
685  // used negative subsections.
686  if ((Res < 0) && (Res > -8193))
687  Subsection = HexagonMCExpr::create(
688  MCConstantExpr::create(8192 + Res, getContext()), getContext());
689 
690  getStreamer().SubSection(Subsection);
691  return false;
692 }
693 
694 /// ::= .falign [expression]
695 bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
696 
697  int64_t MaxBytesToFill = 15;
698 
699  // if there is an argument
700  if (getLexer().isNot(AsmToken::EndOfStatement)) {
701  const MCExpr *Value;
702  SMLoc ExprLoc = L;
703 
704  // Make sure we have a number (false is returned if expression is a number)
705  if (!getParser().parseExpression(Value)) {
706  // Make sure this is a number that is in range
707  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
708  uint64_t IntValue = MCE->getValue();
709  if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
710  return Error(ExprLoc, "literal value out of range (256) for falign");
711  MaxBytesToFill = IntValue;
712  Lex();
713  } else {
714  return Error(ExprLoc, "not a valid expression for falign directive");
715  }
716  }
717 
718  getTargetStreamer().emitFAlign(16, MaxBytesToFill);
719  Lex();
720 
721  return false;
722 }
723 
724 // This is largely a copy of AsmParser's ParseDirectiveComm extended to
725 // accept a 3rd argument, AccessAlignment which indicates the smallest
726 // memory access made to the symbol, expressed in bytes. If no
727 // AccessAlignment is specified it defaults to the Alignment Value.
728 // Hexagon's .lcomm:
729 // .lcomm Symbol, Length, Alignment, AccessAlignment
730 bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
731  // FIXME: need better way to detect if AsmStreamer (upstream removed
732  // getKind())
733  if (getStreamer().hasRawTextSupport())
734  return true; // Only object file output requires special treatment.
735 
736  StringRef Name;
737  if (getParser().parseIdentifier(Name))
738  return TokError("expected identifier in directive");
739  // Handle the identifier as the key symbol.
740  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
741 
742  if (getLexer().isNot(AsmToken::Comma))
743  return TokError("unexpected token in directive");
744  Lex();
745 
746  int64_t Size;
747  SMLoc SizeLoc = getLexer().getLoc();
748  if (getParser().parseAbsoluteExpression(Size))
749  return true;
750 
751  int64_t ByteAlignment = 1;
752  SMLoc ByteAlignmentLoc;
753  if (getLexer().is(AsmToken::Comma)) {
754  Lex();
755  ByteAlignmentLoc = getLexer().getLoc();
756  if (getParser().parseAbsoluteExpression(ByteAlignment))
757  return true;
758  if (!isPowerOf2_64(ByteAlignment))
759  return Error(ByteAlignmentLoc, "alignment must be a power of 2");
760  }
761 
762  int64_t AccessAlignment = 0;
763  if (getLexer().is(AsmToken::Comma)) {
764  // The optional access argument specifies the size of the smallest memory
765  // access to be made to the symbol, expressed in bytes.
766  SMLoc AccessAlignmentLoc;
767  Lex();
768  AccessAlignmentLoc = getLexer().getLoc();
769  if (getParser().parseAbsoluteExpression(AccessAlignment))
770  return true;
771 
772  if (!isPowerOf2_64(AccessAlignment))
773  return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
774  }
775 
776  if (getLexer().isNot(AsmToken::EndOfStatement))
777  return TokError("unexpected token in '.comm' or '.lcomm' directive");
778 
779  Lex();
780 
781  // NOTE: a size of zero for a .comm should create a undefined symbol
782  // but a size of .lcomm creates a bss symbol of size zero.
783  if (Size < 0)
784  return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
785  "be less than zero");
786 
787  // NOTE: The alignment in the directive is a power of 2 value, the assembler
788  // may internally end up wanting an alignment in bytes.
789  // FIXME: Diagnose overflow.
790  if (ByteAlignment < 0)
791  return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
792  "alignment, can't be less than zero");
793 
794  if (!Sym->isUndefined())
795  return Error(Loc, "invalid symbol redefinition");
796 
797  HexagonMCELFStreamer &HexagonELFStreamer =
798  static_cast<HexagonMCELFStreamer &>(getStreamer());
799  if (IsLocal) {
800  HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(Sym, Size, ByteAlignment,
801  AccessAlignment);
802  return false;
803  }
804 
805  HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, ByteAlignment,
806  AccessAlignment);
807  return false;
808 }
809 
810 // validate register against architecture
811 bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
812  if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))
813  if (!getSTI().getFeatureBits()[Hexagon::ArchV62])
814  return false;
815  return true;
816 }
817 
818 // extern "C" void LLVMInitializeHexagonAsmLexer();
819 
820 /// Force static initialization.
823 }
824 
825 #define GET_MATCHER_IMPLEMENTATION
826 #define GET_REGISTER_MATCHER
827 #include "HexagonGenAsmMatcher.inc"
828 
829 static bool previousEqual(OperandVector &Operands, size_t Index,
830  StringRef String) {
831  if (Index >= Operands.size())
832  return false;
833  MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
834  if (!Operand.isToken())
835  return false;
836  return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
837 }
838 
839 static bool previousIsLoop(OperandVector &Operands, size_t Index) {
840  return previousEqual(Operands, Index, "loop0") ||
841  previousEqual(Operands, Index, "loop1") ||
842  previousEqual(Operands, Index, "sp1loop0") ||
843  previousEqual(Operands, Index, "sp2loop0") ||
844  previousEqual(Operands, Index, "sp3loop0");
845 }
846 
847 bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
848  AsmToken const &Token = getParser().getTok();
849  StringRef String = Token.getString();
850  SMLoc Loc = Token.getLoc();
851  Lex();
852  do {
853  std::pair<StringRef, StringRef> HeadTail = String.split('.');
854  if (!HeadTail.first.empty())
855  Operands.push_back(
856  HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
857  if (!HeadTail.second.empty())
858  Operands.push_back(HexagonOperand::CreateToken(
859  getContext(), String.substr(HeadTail.first.size(), 1), Loc));
860  String = HeadTail.second;
861  } while (!String.empty());
862  return false;
863 }
864 
865 bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
866  unsigned Register;
867  SMLoc Begin;
868  SMLoc End;
869  MCAsmLexer &Lexer = getLexer();
870  if (!ParseRegister(Register, Begin, End)) {
872  switch (Register) {
873  default:
874  break;
875  case Hexagon::P0:
876  case Hexagon::P1:
877  case Hexagon::P2:
878  case Hexagon::P3:
879  if (previousEqual(Operands, 0, "if")) {
881  Warning(Begin, "Missing parenthesis around predicate register");
882  static char const *LParen = "(";
883  static char const *RParen = ")";
884  Operands.push_back(
885  HexagonOperand::CreateToken(getContext(), LParen, Begin));
886  Operands.push_back(
887  HexagonOperand::CreateReg(getContext(), Register, Begin, End));
888  const AsmToken &MaybeDotNew = Lexer.getTok();
889  if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
890  MaybeDotNew.getString().equals_lower(".new"))
891  splitIdentifier(Operands);
892  Operands.push_back(
893  HexagonOperand::CreateToken(getContext(), RParen, Begin));
894  return false;
895  }
896  if (previousEqual(Operands, 0, "!") &&
897  previousEqual(Operands, 1, "if")) {
899  Warning(Begin, "Missing parenthesis around predicate register");
900  static char const *LParen = "(";
901  static char const *RParen = ")";
902  Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(
903  getContext(), LParen, Begin));
904  Operands.push_back(
905  HexagonOperand::CreateReg(getContext(), Register, Begin, End));
906  const AsmToken &MaybeDotNew = Lexer.getTok();
907  if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
908  MaybeDotNew.getString().equals_lower(".new"))
909  splitIdentifier(Operands);
910  Operands.push_back(
911  HexagonOperand::CreateToken(getContext(), RParen, Begin));
912  return false;
913  }
914  break;
915  }
916  Operands.push_back(
917  HexagonOperand::CreateReg(getContext(), Register, Begin, End));
918  return false;
919  }
920  return splitIdentifier(Operands);
921 }
922 
923 bool HexagonAsmParser::isLabel(AsmToken &Token) {
924  MCAsmLexer &Lexer = getLexer();
925  AsmToken const &Second = Lexer.getTok();
926  AsmToken Third = Lexer.peekTok();
927  StringRef String = Token.getString();
928  if (Token.is(AsmToken::TokenKind::LCurly) ||
929  Token.is(AsmToken::TokenKind::RCurly))
930  return false;
931  // special case for parsing vwhist256:sat
932  if (String.lower() == "vwhist256" && Second.is(AsmToken::Colon) &&
933  Third.getString().lower() == "sat")
934  return false;
936  return true;
937  if (!matchRegister(String.lower()))
938  return true;
939  assert(Second.is(AsmToken::Colon));
940  StringRef Raw(String.data(), Third.getString().data() - String.data() +
941  Third.getString().size());
942  std::string Collapsed = Raw;
943  Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
944  StringRef Whole = Collapsed;
945  std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
946  if (!matchRegister(DotSplit.first.lower()))
947  return true;
948  return false;
949 }
950 
951 bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,
952  SMLoc &Loc) {
953  if (!Contigious && ErrorNoncontigiousRegister) {
954  Error(Loc, "Register name is not contigious");
955  return true;
956  }
957  if (!Contigious && WarnNoncontigiousRegister)
958  Warning(Loc, "Register name is not contigious");
959  return false;
960 }
961 
962 bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
963  SMLoc &EndLoc) {
964  MCAsmLexer &Lexer = getLexer();
965  StartLoc = getLexer().getLoc();
966  SmallVector<AsmToken, 5> Lookahead;
967  StringRef RawString(Lexer.getTok().getString().data(), 0);
968  bool Again = Lexer.is(AsmToken::Identifier);
969  bool NeededWorkaround = false;
970  while (Again) {
971  AsmToken const &Token = Lexer.getTok();
972  RawString = StringRef(RawString.data(), Token.getString().data() -
973  RawString.data() +
974  Token.getString().size());
975  Lookahead.push_back(Token);
976  Lexer.Lex();
977  bool Contigious = Lexer.getTok().getString().data() ==
978  Lookahead.back().getString().data() +
979  Lookahead.back().getString().size();
980  bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
981  Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
982  Lexer.is(AsmToken::Colon);
983  bool Workaround =
984  Lexer.is(AsmToken::Colon) || Lookahead.back().is(AsmToken::Colon);
985  Again = (Contigious && Type) || (Workaround && Type);
986  NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
987  }
988  std::string Collapsed = RawString;
989  Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
990  StringRef FullString = Collapsed;
991  std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
992  unsigned DotReg = matchRegister(DotSplit.first.lower());
993  if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
994  if (DotSplit.second.empty()) {
995  RegNo = DotReg;
996  EndLoc = Lexer.getLoc();
997  if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
998  return true;
999  return false;
1000  } else {
1001  RegNo = DotReg;
1002  size_t First = RawString.find('.');
1003  StringRef DotString (RawString.data() + First, RawString.size() - First);
1004  Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
1005  EndLoc = Lexer.getLoc();
1006  if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1007  return true;
1008  return false;
1009  }
1010  }
1011  std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
1012  unsigned ColonReg = matchRegister(ColonSplit.first.lower());
1013  if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1014  do {
1015  Lexer.UnLex(Lookahead.back());
1016  Lookahead.pop_back();
1017  } while (!Lookahead.empty () && !Lexer.is(AsmToken::Colon));
1018  RegNo = ColonReg;
1019  EndLoc = Lexer.getLoc();
1020  if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1021  return true;
1022  return false;
1023  }
1024  while (!Lookahead.empty()) {
1025  Lexer.UnLex(Lookahead.back());
1026  Lookahead.pop_back();
1027  }
1028  return true;
1029 }
1030 
1031 bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
1032  if (previousEqual(Operands, 0, "call"))
1033  return true;
1034  if (previousEqual(Operands, 0, "jump"))
1035  if (!getLexer().getTok().is(AsmToken::Colon))
1036  return true;
1037  if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
1038  return true;
1039  if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
1040  (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
1041  return true;
1042  return false;
1043 }
1044 
1045 bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {
1046  SmallVector<AsmToken, 4> Tokens;
1047  MCAsmLexer &Lexer = getLexer();
1048  bool Done = false;
1049  static char const *Comma = ",";
1050  do {
1051  Tokens.emplace_back(Lexer.getTok());
1052  Lex();
1053  switch (Tokens.back().getKind()) {
1054  case AsmToken::TokenKind::Hash:
1055  if (Tokens.size() > 1)
1056  if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
1057  Tokens.insert(Tokens.end() - 2,
1059  Done = true;
1060  }
1061  break;
1062  case AsmToken::TokenKind::RCurly:
1063  case AsmToken::TokenKind::EndOfStatement:
1065  Done = true;
1066  break;
1067  default:
1068  break;
1069  }
1070  } while (!Done);
1071  while (!Tokens.empty()) {
1072  Lexer.UnLex(Tokens.back());
1073  Tokens.pop_back();
1074  }
1075  SMLoc Loc = Lexer.getLoc();
1076  return getParser().parseExpression(Expr, Loc);
1077 }
1078 
1079 bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1080  if (implicitExpressionLocation(Operands)) {
1081  MCAsmParser &Parser = getParser();
1082  SMLoc Loc = Parser.getLexer().getLoc();
1083  MCExpr const *Expr = nullptr;
1084  bool Error = parseExpression(Expr);
1085  Expr = HexagonMCExpr::create(Expr, getContext());
1086  if (!Error)
1087  Operands.push_back(
1088  HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
1089  return Error;
1090  }
1091  return parseOperand(Operands);
1092 }
1093 
1094 /// Parse an instruction.
1095 bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
1096  MCAsmParser &Parser = getParser();
1097  MCAsmLexer &Lexer = getLexer();
1098  while (true) {
1099  AsmToken const &Token = Parser.getTok();
1100  switch (Token.getKind()) {
1101  case AsmToken::Eof:
1102  case AsmToken::EndOfStatement: {
1103  Lex();
1104  return false;
1105  }
1106  case AsmToken::LCurly: {
1107  if (!Operands.empty())
1108  return true;
1109  Operands.push_back(HexagonOperand::CreateToken(
1110  getContext(), Token.getString(), Token.getLoc()));
1111  Lex();
1112  return false;
1113  }
1114  case AsmToken::RCurly: {
1115  if (Operands.empty()) {
1116  Operands.push_back(HexagonOperand::CreateToken(
1117  getContext(), Token.getString(), Token.getLoc()));
1118  Lex();
1119  }
1120  return false;
1121  }
1122  case AsmToken::Comma: {
1123  Lex();
1124  continue;
1125  }
1126  case AsmToken::EqualEqual:
1130  case AsmToken::LessEqual:
1131  case AsmToken::LessLess: {
1132  Operands.push_back(HexagonOperand::CreateToken(
1133  getContext(), Token.getString().substr(0, 1), Token.getLoc()));
1134  Operands.push_back(HexagonOperand::CreateToken(
1135  getContext(), Token.getString().substr(1, 1), Token.getLoc()));
1136  Lex();
1137  continue;
1138  }
1139  case AsmToken::Hash: {
1140  bool MustNotExtend = false;
1141  bool ImplicitExpression = implicitExpressionLocation(Operands);
1142  SMLoc ExprLoc = Lexer.getLoc();
1143  if (!ImplicitExpression)
1144  Operands.push_back(HexagonOperand::CreateToken(
1145  getContext(), Token.getString(), Token.getLoc()));
1146  Lex();
1147  bool MustExtend = false;
1148  bool HiOnly = false;
1149  bool LoOnly = false;
1150  if (Lexer.is(AsmToken::Hash)) {
1151  Lex();
1152  MustExtend = true;
1153  } else if (ImplicitExpression)
1154  MustNotExtend = true;
1155  AsmToken const &Token = Parser.getTok();
1156  if (Token.is(AsmToken::Identifier)) {
1157  StringRef String = Token.getString();
1158  if (String.lower() == "hi") {
1159  HiOnly = true;
1160  } else if (String.lower() == "lo") {
1161  LoOnly = true;
1162  }
1163  if (HiOnly || LoOnly) {
1164  AsmToken LParen = Lexer.peekTok();
1165  if (!LParen.is(AsmToken::LParen)) {
1166  HiOnly = false;
1167  LoOnly = false;
1168  } else {
1169  Lex();
1170  }
1171  }
1172  }
1173  MCExpr const *Expr = nullptr;
1174  if (parseExpression(Expr))
1175  return true;
1176  int64_t Value;
1177  MCContext &Context = Parser.getContext();
1178  assert(Expr != nullptr);
1179  if (Expr->evaluateAsAbsolute(Value)) {
1180  if (HiOnly)
1181  Expr = MCBinaryExpr::createLShr(
1182  Expr, MCConstantExpr::create(16, Context), Context);
1183  if (HiOnly || LoOnly)
1184  Expr = MCBinaryExpr::createAnd(
1185  Expr, MCConstantExpr::create(0xffff, Context), Context);
1186  } else {
1187  MCValue Value;
1188  if (Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) {
1189  if (!Value.isAbsolute()) {
1190  switch (Value.getAccessVariant()) {
1191  case MCSymbolRefExpr::VariantKind::VK_TPREL:
1192  case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1193  // Don't lazy extend these expression variants
1194  MustNotExtend = !MustExtend;
1195  break;
1196  default:
1197  break;
1198  }
1199  }
1200  }
1201  }
1202  Expr = HexagonMCExpr::create(Expr, Context);
1203  HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
1204  HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
1205  std::unique_ptr<HexagonOperand> Operand =
1206  HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
1207  Operands.push_back(std::move(Operand));
1208  continue;
1209  }
1210  default:
1211  break;
1212  }
1213  if (parseExpressionOrOperand(Operands))
1214  return true;
1215  }
1216 }
1217 
1218 bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1220  OperandVector &Operands) {
1221  getLexer().UnLex(ID);
1222  return parseInstruction(Operands);
1223 }
1224 
1225 static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1,
1226  MCOperand &MO2) {
1227  MCInst TmpInst;
1228  TmpInst.setOpcode(opCode);
1229  TmpInst.addOperand(Rdd);
1230  TmpInst.addOperand(MO1);
1231  TmpInst.addOperand(MO2);
1232 
1233  return TmpInst;
1234 }
1235 
1236 // Define this matcher function after the auto-generated include so we
1237 // have the match class enum definitions.
1238 unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1239  unsigned Kind) {
1240  HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
1241 
1242  switch (Kind) {
1243  case MCK_0: {
1244  int64_t Value;
1245  return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1246  ? Match_Success
1247  : Match_InvalidOperand;
1248  }
1249  case MCK_1: {
1250  int64_t Value;
1251  return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1252  ? Match_Success
1253  : Match_InvalidOperand;
1254  }
1255  }
1256  if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1257  StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
1258  if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
1259  return Match_Success;
1260  if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
1261  return Match_Success;
1262  }
1263 
1264  LLVM_DEBUG(dbgs() << "Unmatched Operand:");
1265  LLVM_DEBUG(Op->dump());
1266  LLVM_DEBUG(dbgs() << "\n");
1267 
1268  return Match_InvalidOperand;
1269 }
1270 
1271 // FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
1272 bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
1273  std::string errStr;
1274  raw_string_ostream ES(errStr);
1275  ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
1276  if (Max >= 0)
1277  ES << "0-" << Max;
1278  else
1279  ES << Max << "-" << (-Max - 1);
1280  return Parser.printError(IDLoc, ES.str());
1281 }
1282 
1283 int HexagonAsmParser::processInstruction(MCInst &Inst,
1284  OperandVector const &Operands,
1285  SMLoc IDLoc) {
1286  MCContext &Context = getParser().getContext();
1287  const MCRegisterInfo *RI = getContext().getRegisterInfo();
1288  std::string r = "r";
1289  std::string v = "v";
1290  std::string Colon = ":";
1291 
1292  bool is32bit = false; // used to distinguish between CONST32 and CONST64
1293  switch (Inst.getOpcode()) {
1294  default:
1295  if (HexagonMCInstrInfo::getDesc(MII, Inst).isPseudo()) {
1296  SMDiagnostic Diag = getSourceManager().GetMessage(
1297  IDLoc, SourceMgr::DK_Error,
1298  "Found pseudo instruction with no expansion");
1299  Diag.print("", errs());
1300  report_fatal_error("Invalid pseudo instruction");
1301  }
1302  break;
1303 
1304  case Hexagon::J2_trap1:
1305  if (!getSTI().getFeatureBits()[Hexagon::ArchV65]) {
1306  MCOperand &Rx = Inst.getOperand(0);
1307  MCOperand &Ry = Inst.getOperand(1);
1308  if (Rx.getReg() != Hexagon::R0 || Ry.getReg() != Hexagon::R0) {
1309  Error(IDLoc, "trap1 can only have register r0 as operand");
1310  return Match_InvalidOperand;
1311  }
1312  }
1313  break;
1314 
1315  case Hexagon::A2_iconst: {
1316  Inst.setOpcode(Hexagon::A2_addi);
1317  MCOperand Reg = Inst.getOperand(0);
1318  MCOperand S27 = Inst.getOperand(1);
1321  Inst.clear();
1322  Inst.addOperand(Reg);
1323  Inst.addOperand(MCOperand::createReg(Hexagon::R0));
1324  Inst.addOperand(S27);
1325  break;
1326  }
1327  case Hexagon::M4_mpyrr_addr:
1328  case Hexagon::S4_addi_asl_ri:
1329  case Hexagon::S4_addi_lsr_ri:
1330  case Hexagon::S4_andi_asl_ri:
1331  case Hexagon::S4_andi_lsr_ri:
1332  case Hexagon::S4_ori_asl_ri:
1333  case Hexagon::S4_ori_lsr_ri:
1334  case Hexagon::S4_or_andix:
1335  case Hexagon::S4_subi_asl_ri:
1336  case Hexagon::S4_subi_lsr_ri: {
1337  MCOperand &Ry = Inst.getOperand(0);
1338  MCOperand &src = Inst.getOperand(2);
1339  if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
1340  return Match_InvalidOperand;
1341  break;
1342  }
1343 
1344  case Hexagon::C2_cmpgei: {
1345  MCOperand &MO = Inst.getOperand(2);
1348  MCConstantExpr::create(1, Context), Context),
1349  Context));
1350  Inst.setOpcode(Hexagon::C2_cmpgti);
1351  break;
1352  }
1353 
1354  case Hexagon::C2_cmpgeui: {
1355  MCOperand &MO = Inst.getOperand(2);
1356  int64_t Value;
1357  bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
1358  (void)Success;
1359  assert(Success && "Assured by matcher");
1360  if (Value == 0) {
1361  MCInst TmpInst;
1362  MCOperand &Pd = Inst.getOperand(0);
1363  MCOperand &Rt = Inst.getOperand(1);
1364  TmpInst.setOpcode(Hexagon::C2_cmpeq);
1365  TmpInst.addOperand(Pd);
1366  TmpInst.addOperand(Rt);
1367  TmpInst.addOperand(Rt);
1368  Inst = TmpInst;
1369  } else {
1372  MCConstantExpr::create(1, Context), Context),
1373  Context));
1374  Inst.setOpcode(Hexagon::C2_cmpgtui);
1375  }
1376  break;
1377  }
1378 
1379  // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1380  case Hexagon::A2_tfrp: {
1381  MCOperand &MO = Inst.getOperand(1);
1382  unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1383  std::string R1 = r + utostr(RegPairNum + 1);
1384  StringRef Reg1(R1);
1385  MO.setReg(matchRegister(Reg1));
1386  // Add a new operand for the second register in the pair.
1387  std::string R2 = r + utostr(RegPairNum);
1388  StringRef Reg2(R2);
1389  Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1390  Inst.setOpcode(Hexagon::A2_combinew);
1391  break;
1392  }
1393 
1394  case Hexagon::A2_tfrpt:
1395  case Hexagon::A2_tfrpf: {
1396  MCOperand &MO = Inst.getOperand(2);
1397  unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1398  std::string R1 = r + utostr(RegPairNum + 1);
1399  StringRef Reg1(R1);
1400  MO.setReg(matchRegister(Reg1));
1401  // Add a new operand for the second register in the pair.
1402  std::string R2 = r + utostr(RegPairNum);
1403  StringRef Reg2(R2);
1404  Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1405  Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
1406  ? Hexagon::C2_ccombinewt
1407  : Hexagon::C2_ccombinewf);
1408  break;
1409  }
1410  case Hexagon::A2_tfrptnew:
1411  case Hexagon::A2_tfrpfnew: {
1412  MCOperand &MO = Inst.getOperand(2);
1413  unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1414  std::string R1 = r + utostr(RegPairNum + 1);
1415  StringRef Reg1(R1);
1416  MO.setReg(matchRegister(Reg1));
1417  // Add a new operand for the second register in the pair.
1418  std::string R2 = r + utostr(RegPairNum);
1419  StringRef Reg2(R2);
1420  Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1421  Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
1422  ? Hexagon::C2_ccombinewnewt
1423  : Hexagon::C2_ccombinewnewf);
1424  break;
1425  }
1426 
1427  // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
1428  case Hexagon::V6_vassignp: {
1429  MCOperand &MO = Inst.getOperand(1);
1430  unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1431  std::string R1 = v + utostr(RegPairNum + 1);
1432  MO.setReg(MatchRegisterName(R1));
1433  // Add a new operand for the second register in the pair.
1434  std::string R2 = v + utostr(RegPairNum);
1436  Inst.setOpcode(Hexagon::V6_vcombine);
1437  break;
1438  }
1439 
1440  // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1441  case Hexagon::CONST32:
1442  is32bit = true;
1444  // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
1445  case Hexagon::CONST64:
1446  // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
1447  if (!Parser.getStreamer().hasRawTextSupport()) {
1448  MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
1449  MCOperand &MO_1 = Inst.getOperand(1);
1450  MCOperand &MO_0 = Inst.getOperand(0);
1451 
1452  // push section onto section stack
1453  MES->PushSection();
1454 
1455  std::string myCharStr;
1456  MCSectionELF *mySection;
1457 
1458  // check if this as an immediate or a symbol
1459  int64_t Value;
1460  bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
1461  if (Absolute) {
1462  // Create a new section - one for each constant
1463  // Some or all of the zeros are replaced with the given immediate.
1464  if (is32bit) {
1465  std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
1466  myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
1467  .drop_back(myImmStr.size())
1468  .str() +
1469  myImmStr;
1470  } else {
1471  std::string myImmStr = utohexstr(Value);
1472  myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
1473  .drop_back(myImmStr.size())
1474  .str() +
1475  myImmStr;
1476  }
1477 
1478  mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1480  } else if (MO_1.isExpr()) {
1481  // .lita - for expressions
1482  myCharStr = ".lita";
1483  mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1485  } else
1486  llvm_unreachable("unexpected type of machine operand!");
1487 
1488  MES->SwitchSection(mySection);
1489  unsigned byteSize = is32bit ? 4 : 8;
1490  getStreamer().EmitCodeAlignment(byteSize, byteSize);
1491 
1492  MCSymbol *Sym;
1493 
1494  // for symbols, get rid of prepended ".gnu.linkonce.lx."
1495 
1496  // emit symbol if needed
1497  if (Absolute) {
1498  Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
1499  if (Sym->isUndefined()) {
1500  getStreamer().EmitLabel(Sym);
1501  getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
1502  getStreamer().EmitIntValue(Value, byteSize);
1503  }
1504  } else if (MO_1.isExpr()) {
1505  const char *StringStart = nullptr;
1506  const char *StringEnd = nullptr;
1507  if (*Operands[4]->getStartLoc().getPointer() == '#') {
1508  StringStart = Operands[5]->getStartLoc().getPointer();
1509  StringEnd = Operands[6]->getStartLoc().getPointer();
1510  } else { // no pound
1511  StringStart = Operands[4]->getStartLoc().getPointer();
1512  StringEnd = Operands[5]->getStartLoc().getPointer();
1513  }
1514 
1515  unsigned size = StringEnd - StringStart;
1516  std::string DotConst = ".CONST_";
1517  Sym = getContext().getOrCreateSymbol(DotConst +
1518  StringRef(StringStart, size));
1519 
1520  if (Sym->isUndefined()) {
1521  // case where symbol is not yet defined: emit symbol
1522  getStreamer().EmitLabel(Sym);
1523  getStreamer().EmitSymbolAttribute(Sym, MCSA_Local);
1524  getStreamer().EmitValue(MO_1.getExpr(), 4);
1525  }
1526  } else
1527  llvm_unreachable("unexpected type of machine operand!");
1528 
1529  MES->PopSection();
1530 
1531  if (Sym) {
1532  MCInst TmpInst;
1533  if (is32bit) // 32 bit
1534  TmpInst.setOpcode(Hexagon::L2_loadrigp);
1535  else // 64 bit
1536  TmpInst.setOpcode(Hexagon::L2_loadrdgp);
1537 
1538  TmpInst.addOperand(MO_0);
1540  MCSymbolRefExpr::create(Sym, getContext()), getContext())));
1541  Inst = TmpInst;
1542  }
1543  }
1544  break;
1545 
1546  // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
1547  case Hexagon::A2_tfrpi: {
1548  MCOperand &Rdd = Inst.getOperand(0);
1549  MCOperand &MO = Inst.getOperand(1);
1550  int64_t Value;
1551  int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
1553  HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));
1554  Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
1555  break;
1556  }
1557 
1558  // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1559  case Hexagon::TFRI64_V4: {
1560  MCOperand &Rdd = Inst.getOperand(0);
1561  MCOperand &MO = Inst.getOperand(1);
1562  int64_t Value;
1563  if (MO.getExpr()->evaluateAsAbsolute(Value)) {
1564  int s8 = Hi_32(Value);
1565  if (!isInt<8>(s8))
1566  OutOfRange(IDLoc, s8, -128);
1568  MCConstantExpr::create(s8, Context), Context))); // upper 32
1569  auto Expr = HexagonMCExpr::create(
1570  MCConstantExpr::create(Lo_32(Value), Context), Context);
1572  *Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));
1573  MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
1574  Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1575  } else {
1577  MCConstantExpr::create(0, Context), Context))); // upper 32
1578  Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
1579  }
1580  break;
1581  }
1582 
1583  // Handle $Rdd = combine(##imm, #imm)"
1584  case Hexagon::TFRI64_V2_ext: {
1585  MCOperand &Rdd = Inst.getOperand(0);
1586  MCOperand &MO1 = Inst.getOperand(1);
1587  MCOperand &MO2 = Inst.getOperand(2);
1588  int64_t Value;
1589  if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
1590  int s8 = Value;
1591  if (s8 < -128 || s8 > 127)
1592  OutOfRange(IDLoc, s8, -128);
1593  }
1594  Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
1595  break;
1596  }
1597 
1598  // Handle $Rdd = combine(#imm, ##imm)"
1599  case Hexagon::A4_combineii: {
1600  MCOperand &Rdd = Inst.getOperand(0);
1601  MCOperand &MO1 = Inst.getOperand(1);
1602  int64_t Value;
1603  if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
1604  int s8 = Value;
1605  if (s8 < -128 || s8 > 127)
1606  OutOfRange(IDLoc, s8, -128);
1607  }
1608  MCOperand &MO2 = Inst.getOperand(2);
1609  Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
1610  break;
1611  }
1612 
1613  case Hexagon::S2_tableidxb_goodsyntax:
1614  Inst.setOpcode(Hexagon::S2_tableidxb);
1615  break;
1616 
1617  case Hexagon::S2_tableidxh_goodsyntax: {
1618  MCInst TmpInst;
1619  MCOperand &Rx = Inst.getOperand(0);
1620  MCOperand &Rs = Inst.getOperand(2);
1621  MCOperand &Imm4 = Inst.getOperand(3);
1622  MCOperand &Imm6 = Inst.getOperand(4);
1625  MCConstantExpr::create(1, Context), Context),
1626  Context));
1627  TmpInst.setOpcode(Hexagon::S2_tableidxh);
1628  TmpInst.addOperand(Rx);
1629  TmpInst.addOperand(Rx);
1630  TmpInst.addOperand(Rs);
1631  TmpInst.addOperand(Imm4);
1632  TmpInst.addOperand(Imm6);
1633  Inst = TmpInst;
1634  break;
1635  }
1636 
1637  case Hexagon::S2_tableidxw_goodsyntax: {
1638  MCInst TmpInst;
1639  MCOperand &Rx = Inst.getOperand(0);
1640  MCOperand &Rs = Inst.getOperand(2);
1641  MCOperand &Imm4 = Inst.getOperand(3);
1642  MCOperand &Imm6 = Inst.getOperand(4);
1645  MCConstantExpr::create(2, Context), Context),
1646  Context));
1647  TmpInst.setOpcode(Hexagon::S2_tableidxw);
1648  TmpInst.addOperand(Rx);
1649  TmpInst.addOperand(Rx);
1650  TmpInst.addOperand(Rs);
1651  TmpInst.addOperand(Imm4);
1652  TmpInst.addOperand(Imm6);
1653  Inst = TmpInst;
1654  break;
1655  }
1656 
1657  case Hexagon::S2_tableidxd_goodsyntax: {
1658  MCInst TmpInst;
1659  MCOperand &Rx = Inst.getOperand(0);
1660  MCOperand &Rs = Inst.getOperand(2);
1661  MCOperand &Imm4 = Inst.getOperand(3);
1662  MCOperand &Imm6 = Inst.getOperand(4);
1665  MCConstantExpr::create(3, Context), Context),
1666  Context));
1667  TmpInst.setOpcode(Hexagon::S2_tableidxd);
1668  TmpInst.addOperand(Rx);
1669  TmpInst.addOperand(Rx);
1670  TmpInst.addOperand(Rs);
1671  TmpInst.addOperand(Imm4);
1672  TmpInst.addOperand(Imm6);
1673  Inst = TmpInst;
1674  break;
1675  }
1676 
1677  case Hexagon::M2_mpyui:
1678  Inst.setOpcode(Hexagon::M2_mpyi);
1679  break;
1680  case Hexagon::M2_mpysmi: {
1681  MCInst TmpInst;
1682  MCOperand &Rd = Inst.getOperand(0);
1683  MCOperand &Rs = Inst.getOperand(1);
1684  MCOperand &Imm = Inst.getOperand(2);
1685  int64_t Value;
1686  MCExpr const &Expr = *Imm.getExpr();
1687  bool Absolute = Expr.evaluateAsAbsolute(Value);
1688  assert(Absolute);
1689  (void)Absolute;
1690  if (!HexagonMCInstrInfo::mustExtend(Expr) &&
1691  ((Value <= -256) || Value >= 256))
1692  return Match_InvalidOperand;
1693  if (Value < 0 && Value > -256) {
1695  MCConstantExpr::create(Value * -1, Context), Context));
1696  TmpInst.setOpcode(Hexagon::M2_mpysin);
1697  } else
1698  TmpInst.setOpcode(Hexagon::M2_mpysip);
1699  TmpInst.addOperand(Rd);
1700  TmpInst.addOperand(Rs);
1701  TmpInst.addOperand(Imm);
1702  Inst = TmpInst;
1703  break;
1704  }
1705 
1706  case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1707  MCOperand &Imm = Inst.getOperand(2);
1708  MCInst TmpInst;
1709  int64_t Value;
1710  bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1711  assert(Absolute);
1712  (void)Absolute;
1713  if (Value == 0) { // convert to $Rd = $Rs
1714  TmpInst.setOpcode(Hexagon::A2_tfr);
1715  MCOperand &Rd = Inst.getOperand(0);
1716  MCOperand &Rs = Inst.getOperand(1);
1717  TmpInst.addOperand(Rd);
1718  TmpInst.addOperand(Rs);
1719  } else {
1722  MCConstantExpr::create(1, Context), Context),
1723  Context));
1724  TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
1725  MCOperand &Rd = Inst.getOperand(0);
1726  MCOperand &Rs = Inst.getOperand(1);
1727  TmpInst.addOperand(Rd);
1728  TmpInst.addOperand(Rs);
1729  TmpInst.addOperand(Imm);
1730  }
1731  Inst = TmpInst;
1732  break;
1733  }
1734 
1735  case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1736  MCOperand &Rdd = Inst.getOperand(0);
1737  MCOperand &Rss = Inst.getOperand(1);
1738  MCOperand &Imm = Inst.getOperand(2);
1739  int64_t Value;
1740  bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1741  assert(Absolute);
1742  (void)Absolute;
1743  if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
1744  MCInst TmpInst;
1745  unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1746  std::string R1 = r + utostr(RegPairNum + 1);
1747  StringRef Reg1(R1);
1748  Rss.setReg(matchRegister(Reg1));
1749  // Add a new operand for the second register in the pair.
1750  std::string R2 = r + utostr(RegPairNum);
1751  StringRef Reg2(R2);
1752  TmpInst.setOpcode(Hexagon::A2_combinew);
1753  TmpInst.addOperand(Rdd);
1754  TmpInst.addOperand(Rss);
1755  TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1756  Inst = TmpInst;
1757  } else {
1760  MCConstantExpr::create(1, Context), Context),
1761  Context));
1762  Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
1763  }
1764  break;
1765  }
1766 
1767  case Hexagon::A4_boundscheck: {
1768  MCOperand &Rs = Inst.getOperand(1);
1769  unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1770  if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
1771  Inst.setOpcode(Hexagon::A4_boundscheck_hi);
1772  std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1773  StringRef RegPair = Name;
1774  Rs.setReg(matchRegister(RegPair));
1775  } else { // raw:lo
1776  Inst.setOpcode(Hexagon::A4_boundscheck_lo);
1777  std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1778  StringRef RegPair = Name;
1779  Rs.setReg(matchRegister(RegPair));
1780  }
1781  break;
1782  }
1783 
1784  case Hexagon::A2_addsp: {
1785  MCOperand &Rs = Inst.getOperand(1);
1786  unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1787  if (RegNum & 1) { // Odd mapped to raw:hi
1788  Inst.setOpcode(Hexagon::A2_addsph);
1789  std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1790  StringRef RegPair = Name;
1791  Rs.setReg(matchRegister(RegPair));
1792  } else { // Even mapped raw:lo
1793  Inst.setOpcode(Hexagon::A2_addspl);
1794  std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1795  StringRef RegPair = Name;
1796  Rs.setReg(matchRegister(RegPair));
1797  }
1798  break;
1799  }
1800 
1801  case Hexagon::M2_vrcmpys_s1: {
1802  MCOperand &Rt = Inst.getOperand(2);
1803  unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1804  if (RegNum & 1) { // Odd mapped to sat:raw:hi
1805  Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
1806  std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1807  StringRef RegPair = Name;
1808  Rt.setReg(matchRegister(RegPair));
1809  } else { // Even mapped sat:raw:lo
1810  Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
1811  std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1812  StringRef RegPair = Name;
1813  Rt.setReg(matchRegister(RegPair));
1814  }
1815  break;
1816  }
1817 
1818  case Hexagon::M2_vrcmpys_acc_s1: {
1819  MCInst TmpInst;
1820  MCOperand &Rxx = Inst.getOperand(0);
1821  MCOperand &Rss = Inst.getOperand(2);
1822  MCOperand &Rt = Inst.getOperand(3);
1823  unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1824  if (RegNum & 1) { // Odd mapped to sat:raw:hi
1825  TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
1826  std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1827  StringRef RegPair = Name;
1828  Rt.setReg(matchRegister(RegPair));
1829  } else { // Even mapped sat:raw:lo
1830  TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
1831  std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1832  StringRef RegPair = Name;
1833  Rt.setReg(matchRegister(RegPair));
1834  }
1835  // Registers are in different positions
1836  TmpInst.addOperand(Rxx);
1837  TmpInst.addOperand(Rxx);
1838  TmpInst.addOperand(Rss);
1839  TmpInst.addOperand(Rt);
1840  Inst = TmpInst;
1841  break;
1842  }
1843 
1844  case Hexagon::M2_vrcmpys_s1rp: {
1845  MCOperand &Rt = Inst.getOperand(2);
1846  unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1847  if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
1848  Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
1849  std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1850  StringRef RegPair = Name;
1851  Rt.setReg(matchRegister(RegPair));
1852  } else { // Even mapped rnd:sat:raw:lo
1853  Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
1854  std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1855  StringRef RegPair = Name;
1856  Rt.setReg(matchRegister(RegPair));
1857  }
1858  break;
1859  }
1860 
1861  case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
1862  MCOperand &Imm = Inst.getOperand(2);
1863  int64_t Value;
1864  bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1865  assert(Absolute);
1866  (void)Absolute;
1867  if (Value == 0)
1868  Inst.setOpcode(Hexagon::S2_vsathub);
1869  else {
1872  MCConstantExpr::create(1, Context), Context),
1873  Context));
1874  Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
1875  }
1876  break;
1877  }
1878 
1879  case Hexagon::S5_vasrhrnd_goodsyntax: {
1880  MCOperand &Rdd = Inst.getOperand(0);
1881  MCOperand &Rss = Inst.getOperand(1);
1882  MCOperand &Imm = Inst.getOperand(2);
1883  int64_t Value;
1884  bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1885  assert(Absolute);
1886  (void)Absolute;
1887  if (Value == 0) {
1888  MCInst TmpInst;
1889  unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1890  std::string R1 = r + utostr(RegPairNum + 1);
1891  StringRef Reg1(R1);
1892  Rss.setReg(matchRegister(Reg1));
1893  // Add a new operand for the second register in the pair.
1894  std::string R2 = r + utostr(RegPairNum);
1895  StringRef Reg2(R2);
1896  TmpInst.setOpcode(Hexagon::A2_combinew);
1897  TmpInst.addOperand(Rdd);
1898  TmpInst.addOperand(Rss);
1899  TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1900  Inst = TmpInst;
1901  } else {
1904  MCConstantExpr::create(1, Context), Context),
1905  Context));
1906  Inst.setOpcode(Hexagon::S5_vasrhrnd);
1907  }
1908  break;
1909  }
1910 
1911  case Hexagon::A2_not: {
1912  MCInst TmpInst;
1913  MCOperand &Rd = Inst.getOperand(0);
1914  MCOperand &Rs = Inst.getOperand(1);
1915  TmpInst.setOpcode(Hexagon::A2_subri);
1916  TmpInst.addOperand(Rd);
1918  HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));
1919  TmpInst.addOperand(Rs);
1920  Inst = TmpInst;
1921  break;
1922  }
1923  case Hexagon::PS_loadrubabs:
1925  Inst.setOpcode(Hexagon::L2_loadrubgp);
1926  break;
1927  case Hexagon::PS_loadrbabs:
1929  Inst.setOpcode(Hexagon::L2_loadrbgp);
1930  break;
1931  case Hexagon::PS_loadruhabs:
1933  Inst.setOpcode(Hexagon::L2_loadruhgp);
1934  break;
1935  case Hexagon::PS_loadrhabs:
1937  Inst.setOpcode(Hexagon::L2_loadrhgp);
1938  break;
1939  case Hexagon::PS_loadriabs:
1941  Inst.setOpcode(Hexagon::L2_loadrigp);
1942  break;
1943  case Hexagon::PS_loadrdabs:
1945  Inst.setOpcode(Hexagon::L2_loadrdgp);
1946  break;
1947  case Hexagon::PS_storerbabs:
1949  Inst.setOpcode(Hexagon::S2_storerbgp);
1950  break;
1951  case Hexagon::PS_storerhabs:
1953  Inst.setOpcode(Hexagon::S2_storerhgp);
1954  break;
1955  case Hexagon::PS_storerfabs:
1957  Inst.setOpcode(Hexagon::S2_storerfgp);
1958  break;
1959  case Hexagon::PS_storeriabs:
1961  Inst.setOpcode(Hexagon::S2_storerigp);
1962  break;
1963  case Hexagon::PS_storerdabs:
1965  Inst.setOpcode(Hexagon::S2_storerdgp);
1966  break;
1967  case Hexagon::PS_storerbnewabs:
1969  Inst.setOpcode(Hexagon::S2_storerbnewgp);
1970  break;
1971  case Hexagon::PS_storerhnewabs:
1973  Inst.setOpcode(Hexagon::S2_storerhnewgp);
1974  break;
1975  case Hexagon::PS_storerinewabs:
1977  Inst.setOpcode(Hexagon::S2_storerinewgp);
1978  break;
1979  case Hexagon::A2_zxtb: {
1980  Inst.setOpcode(Hexagon::A2_andir);
1981  Inst.addOperand(
1983  break;
1984  }
1985  } // switch
1986 
1987  return Match_Success;
1988 }
1989 
1990 unsigned HexagonAsmParser::matchRegister(StringRef Name) {
1991  if (unsigned Reg = MatchRegisterName(Name))
1992  return Reg;
1993  return MatchRegisterAltName(Name);
1994 }
static bool isReg(const MCInst &MI, unsigned OpNo)
static bool Check(DecodeStatus &Out, DecodeStatus In)
void push_back(const T &Elt)
Definition: SmallVector.h:213
const AsmToken & getTok() const
Get the current (last) lexed token.
Definition: MCAsmLexer.h:109
void setMustExtend(bool Val=true)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:111
LLVMContext & Context
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:321
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:115
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true) const
Definition: SourceMgr.cpp:368
This represents an "assembler immediate".
Definition: MCValue.h:40
virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range=None)=0
Emit a warning at the location L, with the message Msg.
void clear()
Definition: MCInst.h:191
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:144
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:176
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:137
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:110
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition: Format.h:186
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:137
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition: MathExtras.h:281
MCTargetAsmParser - Generic interface to target specific assembly parsers.
void setMustNotExtend(bool Val=true)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
virtual bool isToken() const =0
isToken - Is this a token operand?
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ") const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
Definition: MCInst.cpp:73
Target specific streamer interface.
Definition: MCStreamer.h:83
unsigned Reg
constexpr bool isInt< 8 >(int64_t x)
Definition: MathExtras.h:295
bool isAbsolute() const
Is this an absolute (as opposed to relocatable) value.
Definition: MCValue.h:53
void PushSection()
Save the current and previous section on the section stack.
Definition: MCStreamer.h:359
demanded bits
static const MCBinaryExpr * createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:464
bool isPseudo() const
Return true if this is a pseudo instruction that doesn&#39;t correspond to a real machine instruction...
Definition: MCInstrDesc.h:240
#define R2(n)
void LLVMInitializeHexagonAsmParser()
Force static initialization.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:34
static cl::opt< bool > WarnSignedMismatch("mwarn-sign-mismatch", cl::desc("Warn for mismatching a signed and unsigned value"), cl::init(true))
bool isOuterLoop(MCInst const &MCI)
static bool is32bit(MachineTypes Machine)
MCSymbolRefExpr::VariantKind getAccessVariant() const
Definition: MCValue.cpp:47
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:128
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo=false)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:892
return AArch64::GPR64RegClass contains(Reg)
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
Definition: MCAsmMacro.h:100
SMLoc getLoc() const
Get the current source location.
Definition: MCAsmLexer.cpp:24
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
Generic assembler lexer interface, for use by target specific assembly lexers.
Definition: MCAsmLexer.h:40
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
#define HEXAGON_PACKET_SIZE
Definition: Hexagon.h:33
static cl::opt< bool > WarnNoncontigiousRegister("mwarn-noncontigious-register", cl::desc("Warn for register names that arent contigious"), cl::init(true))
static cl::opt< bool > ErrorMissingParenthesis("merror-missing-parenthesis", cl::desc("Error for missing parenthesis around predicate registers"), cl::init(false))
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range=None)=0
Emit an error at the location L, with the message Msg.
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:22
.local (ELF)
Definition: MCDirectives.h:35
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:156
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:65
void setMemReorderDisabled(MCInst &MCI)
Context object for machine code objects.
Definition: MCContext.h:63
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \\\)
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:544
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Definition: MCExpr.cpp:633
bool canonicalizePacket(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCContext &Context, MCInst &MCB, HexagonMCChecker *Checker)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:28
void extendIfNeeded(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB, MCInst const &MCI)
void setMustExtend(MCExpr const &Expr, bool Val=true)
const MCExpr * getExpr() const
Definition: MCInst.h:96
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:598
LLVM_NODISCARD std::string upper() const
Convert the given ASCII string to uppercase.
Definition: StringRef.cpp:116
Unary expressions.
Definition: MCExpr.h:42
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText...
Definition: MCStreamer.h:284
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
int64_t getValue() const
Definition: MCExpr.h:152
virtual MCContext & getContext()=0
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:410
Streaming machine code generation interface.
Definition: MCStreamer.h:183
static HexagonMCExpr * create(MCExpr const *Expr, MCContext &Ctx)
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:257
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
bool mustExtend(MCExpr const &Expr)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
Definition: MCStreamer.cpp:976
void setSignMismatch(bool Val=true)
MCAssembler & getAssembler()
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
virtual MCAsmLexer & getLexer()=0
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:426
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
static cl::opt< bool > ErrorNoncontigiousRegister("merror-noncontigious-register", cl::desc("Error for register names that aren't contigious"), cl::init(false))
static const unsigned End
bool isExpr() const
Definition: MCInst.h:61
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
Definition: MCAsmLexer.h:114
bool Error(SMLoc L, const Twine &Msg, SMRange Range=None)
Return an error at the location L, with the message Msg.
Definition: MCAsmParser.cpp:88
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:948
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:390
bool mustNotExtend() const
void setLoc(SMLoc loc)
Definition: MCInst.h:179
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:493
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static const MCBinaryExpr * createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:539
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the last N elements dropped.
Definition: StringRef.h:654
LLVM_NODISCARD int compare_lower(StringRef RHS) const
compare_lower - Compare two strings, ignoring case.
Definition: StringRef.cpp:38
void HexagonMCEmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, unsigned AccessSize)
MCStreamer & getStreamer()
Definition: MCStreamer.h:91
void setOpcode(unsigned Op)
Definition: MCInst.h:173
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1032
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
void UnLex(AsmToken const &Token)
Definition: MCAsmLexer.h:96
ExprKind getKind() const
Definition: MCExpr.h:73
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
Definition: MCSymbol.h:257
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:182
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:727
Promote Memory to Register
Definition: Mem2Reg.cpp:110
static bool previousIsLoop(OperandVector &Operands, size_t Index)
static bool previousEqual(OperandVector &Operands, size_t Index, StringRef String)
std::string utostr(uint64_t X, bool isNeg=false)
Definition: StringExtras.h:203
const AsmToken & Lex()
Consume the next token from the input stream and return it.
Definition: MCAsmLexer.h:82
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
bool is(TokenKind K) const
Definition: MCAsmMacro.h:83
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, const SectionAddrMap &Addrs) const
Try to evaluate the expression to an absolute value.
Definition: MCExpr.cpp:452
Base class for user error types.
Definition: Error.h:331
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:479
static MCOperand createInst(const MCInst *Val)
Definition: MCInst.h:144
#define Success
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:121
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
void emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:653
MCExpr const & getExpr(MCExpr const &Expr)
.type _foo,
Definition: MCDirectives.h:30
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:62
static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1, MCOperand &MO2)
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
Generic base class for all target subtargets.
bool mustExtend() const
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:28
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
References to labels and assigned expressions.
Definition: MCExpr.h:41
void setMustNotExtend(MCExpr const &Expr, bool Val=true)
size_t bundleSize(MCInst const &MCI)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition: MathExtras.h:741
void setReg(unsigned Reg)
Set the register number.
Definition: MCInst.h:71
const unsigned Kind
LLVM_NODISCARD std::string lower() const
Definition: StringRef.cpp:108
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isInnerLoop(MCInst const &MCI)
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:477
bool PopSection()
Restore the current and previous section from the section stack.
Definition: MCStreamer.h:368
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition: MathExtras.h:276
LLVM Value Representation.
Definition: Value.h:73
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:235
Binary expressions.
Definition: MCExpr.h:39
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
Check for a valid bundle.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
void addOperand(const MCOperand &Op)
Definition: MCInst.h:186
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
static cl::opt< bool > WarnMissingParenthesis("mwarn-missing-parenthesis", cl::desc("Warn for missing parenthesis around predicate registers"), cl::init(true))
Represents a location in source code.
Definition: SMLoc.h:24
void setS27_2_reloc(MCExpr const &Expr, bool Val=true)
unsigned getOpcode() const
Definition: MCInst.h:174
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:385
#define LLVM_DEBUG(X)
Definition: Debug.h:119
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:35
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:164
Target & getTheHexagonTarget()
void HexagonMCEmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, unsigned AccessSize)
std::string utohexstr(uint64_t X, bool LowerCase=false)
Definition: StringExtras.h:105
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:260
TokenKind getKind() const
Definition: MCAsmMacro.h:82
void setExpr(const MCExpr *Val)
Definition: MCInst.h:101