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