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 ParseDirectiveValue(unsigned Size, SMLoc L);
122  bool ParseDirectiveComm(bool IsLocal, SMLoc L);
123  bool RegisterMatchesArch(unsigned MatchNum) const;
124 
125  bool matchBundleOptions();
126  bool handleNoncontigiousRegister(bool Contigious, SMLoc &Loc);
127  bool finishBundle(SMLoc IDLoc, MCStreamer &Out);
128  void canonicalizeImmediates(MCInst &MCI);
129  bool matchOneInstruction(MCInst &MCB, SMLoc IDLoc,
130  OperandVector &InstOperands, uint64_t &ErrorInfo,
131  bool MatchingInlineAsm);
132  void eatToEndOfPacket();
133  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
134  OperandVector &Operands, MCStreamer &Out,
135  uint64_t &ErrorInfo,
136  bool MatchingInlineAsm) override;
137 
138  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
139  unsigned Kind) override;
140  bool OutOfRange(SMLoc IDLoc, long long Val, long long Max);
141  int processInstruction(MCInst &Inst, OperandVector const &Operands,
142  SMLoc IDLoc);
143 
144  // Check if we have an assembler and, if so, set the ELF e_header flags.
145  void chksetELFHeaderEFlags(unsigned flags) {
146  if (getAssembler())
147  getAssembler()->setELFHeaderEFlags(flags);
148  }
149 
150  unsigned matchRegister(StringRef Name);
151 
152 /// @name Auto-generated Match Functions
153 /// {
154 
155 #define GET_ASSEMBLER_HEADER
156 #include "HexagonGenAsmMatcher.inc"
157 
158  /// }
159 
160 public:
161  HexagonAsmParser(const MCSubtargetInfo &_STI, MCAsmParser &_Parser,
162  const MCInstrInfo &MII, const MCTargetOptions &Options)
163  : MCTargetAsmParser(Options, _STI, MII), Parser(_Parser),
164  InBrackets(false) {
165  MCB.setOpcode(Hexagon::BUNDLE);
166  setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
167 
169  }
170 
171  bool splitIdentifier(OperandVector &Operands);
172  bool parseOperand(OperandVector &Operands);
173  bool parseInstruction(OperandVector &Operands);
174  bool implicitExpressionLocation(OperandVector &Operands);
175  bool parseExpressionOrOperand(OperandVector &Operands);
176  bool parseExpression(MCExpr const *&Expr);
177 
178  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
179  SMLoc NameLoc, OperandVector &Operands) override {
180  llvm_unreachable("Unimplemented");
181  }
182 
183  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
184  OperandVector &Operands) override;
185 
186  bool ParseDirective(AsmToken DirectiveID) override;
187 };
188 
189 /// HexagonOperand - Instances of this class represent a parsed Hexagon machine
190 /// instruction.
191 struct HexagonOperand : public MCParsedAsmOperand {
192  enum KindTy { Token, Immediate, Register } Kind;
194 
195  SMLoc StartLoc, EndLoc;
196 
197  struct TokTy {
198  const char *Data;
199  unsigned Length;
200  };
201 
202  struct RegTy {
203  unsigned RegNum;
204  };
205 
206  struct ImmTy {
207  const MCExpr *Val;
208  };
209 
210  struct InstTy {
211  OperandVector *SubInsts;
212  };
213 
214  union {
215  struct TokTy Tok;
216  struct RegTy Reg;
217  struct ImmTy Imm;
218  };
219 
220  HexagonOperand(KindTy K, MCContext &Context)
221  : MCParsedAsmOperand(), Kind(K), Context(Context) {}
222 
223 public:
224  HexagonOperand(const HexagonOperand &o)
225  : MCParsedAsmOperand(), Context(o.Context) {
226  Kind = o.Kind;
227  StartLoc = o.StartLoc;
228  EndLoc = o.EndLoc;
229  switch (Kind) {
230  case Register:
231  Reg = o.Reg;
232  break;
233  case Immediate:
234  Imm = o.Imm;
235  break;
236  case Token:
237  Tok = o.Tok;
238  break;
239  }
240  }
241 
242  /// getStartLoc - Get the location of the first token of this operand.
243  SMLoc getStartLoc() const override { return StartLoc; }
244 
245  /// getEndLoc - Get the location of the last token of this operand.
246  SMLoc getEndLoc() const override { return EndLoc; }
247 
248  unsigned getReg() const override {
249  assert(Kind == Register && "Invalid access!");
250  return Reg.RegNum;
251  }
252 
253  const MCExpr *getImm() const {
254  assert(Kind == Immediate && "Invalid access!");
255  return Imm.Val;
256  }
257 
258  bool isToken() const override { return Kind == Token; }
259  bool isImm() const override { return Kind == Immediate; }
260  bool isMem() const override { llvm_unreachable("No isMem"); }
261  bool isReg() const override { return Kind == Register; }
262 
263  bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
264  bool isRelocatable, bool Extendable) const {
265  if (Kind == Immediate) {
266  const MCExpr *myMCExpr = &HexagonMCInstrInfo::getExpr(*getImm());
267  if (HexagonMCInstrInfo::mustExtend(*Imm.Val) && !Extendable)
268  return false;
269  int64_t Res;
270  if (myMCExpr->evaluateAsAbsolute(Res)) {
271  int bits = immBits + zeroBits;
272  // Field bit range is zerobits + bits
273  // zeroBits must be 0
274  if (Res & ((1 << zeroBits) - 1))
275  return false;
276  if (isSigned) {
277  if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
278  return true;
279  } else {
280  if (bits == 64)
281  return true;
282  if (Res >= 0)
283  return ((uint64_t)Res < (uint64_t)(1ULL << bits));
284  else {
285  const int64_t high_bit_set = 1ULL << 63;
286  const uint64_t mask = (high_bit_set >> (63 - bits));
287  return (((uint64_t)Res & mask) == mask);
288  }
289  }
290  } else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)
291  return true;
292  else if (myMCExpr->getKind() == MCExpr::Binary ||
293  myMCExpr->getKind() == MCExpr::Unary)
294  return true;
295  }
296  return false;
297  }
298 
299  bool isa30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
300  bool isb30_2Imm() const { return CheckImmRange(30, 2, true, true, true); }
301  bool isb15_2Imm() const { return CheckImmRange(15, 2, true, true, false); }
302  bool isb13_2Imm() const { return CheckImmRange(13, 2, true, true, false); }
303 
304  bool ism32_0Imm() const { return true; }
305 
306  bool isf32Imm() const { return false; }
307  bool isf64Imm() const { return false; }
308  bool iss32_0Imm() const { return true; }
309  bool iss31_1Imm() const { return true; }
310  bool iss30_2Imm() const { return true; }
311  bool iss29_3Imm() const { return true; }
312  bool iss27_2Imm() const { return CheckImmRange(27, 2, true, true, false); }
313  bool iss10_0Imm() const { return CheckImmRange(10, 0, true, false, false); }
314  bool iss10_6Imm() const { return CheckImmRange(10, 6, true, false, 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  DEBUG(dbgs() << "Bundle:");
466  DEBUG(MCB.dump_pretty(dbgs()));
467  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("endloop0") == 0)
511  else if (Option.compare_lower("endloop1") == 0)
513  else if (Option.compare_lower("mem_noshuf") == 0)
514  if (getSTI().getFeatureBits()[Hexagon::FeatureMemNoShuf])
516  else
517  return getParser().Error(IDLoc, MemNoShuffMsg);
518  else
519  return getParser().Error(IDLoc, llvm::Twine("'") + Option +
520  "' is not a valid bundle option");
521  Lex();
522  }
523 }
524 
525 // For instruction aliases, immediates are generated rather than
526 // MCConstantExpr. Convert them for uniform MCExpr.
527 // Also check for signed/unsigned mismatches and warn
528 void HexagonAsmParser::canonicalizeImmediates(MCInst &MCI) {
529  MCInst NewInst;
530  NewInst.setOpcode(MCI.getOpcode());
531  for (MCOperand &I : MCI)
532  if (I.isImm()) {
533  int64_t Value(I.getImm());
535  MCConstantExpr::create(Value, getContext()), getContext())));
536  } else {
537  if (I.isExpr() && cast<HexagonMCExpr>(I.getExpr())->signMismatch() &&
539  Warning(MCI.getLoc(), "Signed/Unsigned mismatch");
540  NewInst.addOperand(I);
541  }
542  MCI = NewInst;
543 }
544 
545 bool HexagonAsmParser::matchOneInstruction(MCInst &MCI, SMLoc IDLoc,
546  OperandVector &InstOperands,
547  uint64_t &ErrorInfo,
548  bool MatchingInlineAsm) {
549  // Perform matching with tablegen asmmatcher generated function
550  int result =
551  MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
552  if (result == Match_Success) {
553  MCI.setLoc(IDLoc);
554  canonicalizeImmediates(MCI);
555  result = processInstruction(MCI, InstOperands, IDLoc);
556 
557  DEBUG(dbgs() << "Insn:");
558  DEBUG(MCI.dump_pretty(dbgs()));
559  DEBUG(dbgs() << "\n\n");
560 
561  MCI.setLoc(IDLoc);
562  }
563 
564  // Create instruction operand for bundle instruction
565  // Break this into a separate function Code here is less readable
566  // Think about how to get an instruction error to report correctly.
567  // SMLoc will return the "{"
568  switch (result) {
569  default:
570  break;
571  case Match_Success:
572  return false;
573  case Match_MissingFeature:
574  return Error(IDLoc, "invalid instruction");
575  case Match_MnemonicFail:
576  return Error(IDLoc, "unrecognized instruction");
577  case Match_InvalidOperand:
578  SMLoc ErrorLoc = IDLoc;
579  if (ErrorInfo != ~0U) {
580  if (ErrorInfo >= InstOperands.size())
581  return Error(IDLoc, "too few operands for instruction");
582 
583  ErrorLoc = (static_cast<HexagonOperand *>(InstOperands[ErrorInfo].get()))
584  ->getStartLoc();
585  if (ErrorLoc == SMLoc())
586  ErrorLoc = IDLoc;
587  }
588  return Error(ErrorLoc, "invalid operand for instruction");
589  }
590  llvm_unreachable("Implement any new match types added!");
591 }
592 
593 void HexagonAsmParser::eatToEndOfPacket() {
594  assert(InBrackets);
595  MCAsmLexer &Lexer = getLexer();
596  while (!Lexer.is(AsmToken::RCurly))
597  Lexer.Lex();
598  Lexer.Lex();
599  InBrackets = false;
600 }
601 
602 bool HexagonAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
603  OperandVector &Operands,
604  MCStreamer &Out,
605  uint64_t &ErrorInfo,
606  bool MatchingInlineAsm) {
607  if (!InBrackets) {
608  MCB.clear();
610  }
611  HexagonOperand &FirstOperand = static_cast<HexagonOperand &>(*Operands[0]);
612  if (FirstOperand.isToken() && FirstOperand.getToken() == "{") {
613  assert(Operands.size() == 1 && "Brackets should be by themselves");
614  if (InBrackets) {
615  getParser().Error(IDLoc, "Already in a packet");
616  InBrackets = false;
617  return true;
618  }
619  InBrackets = true;
620  return false;
621  }
622  if (FirstOperand.isToken() && FirstOperand.getToken() == "}") {
623  assert(Operands.size() == 1 && "Brackets should be by themselves");
624  if (!InBrackets) {
625  getParser().Error(IDLoc, "Not in a packet");
626  return true;
627  }
628  InBrackets = false;
629  if (matchBundleOptions())
630  return true;
631  return finishBundle(IDLoc, Out);
632  }
633  MCInst *SubInst = new (getParser().getContext()) MCInst;
634  if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
635  MatchingInlineAsm)) {
636  if (InBrackets)
637  eatToEndOfPacket();
638  return true;
639  }
641  getParser().getContext(), MII, MCB, *SubInst);
642  MCB.addOperand(MCOperand::createInst(SubInst));
643  if (!InBrackets)
644  return finishBundle(IDLoc, Out);
645  return false;
646 }
647 
648 /// ParseDirective parses the Hexagon specific directives
649 bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
650  StringRef IDVal = DirectiveID.getIdentifier();
651  if ((IDVal.lower() == ".word") || (IDVal.lower() == ".4byte"))
652  return ParseDirectiveValue(4, DirectiveID.getLoc());
653  if (IDVal.lower() == ".short" || IDVal.lower() == ".hword" ||
654  IDVal.lower() == ".half")
655  return ParseDirectiveValue(2, DirectiveID.getLoc());
656  if (IDVal.lower() == ".falign")
657  return ParseDirectiveFalign(256, DirectiveID.getLoc());
658  if ((IDVal.lower() == ".lcomm") || (IDVal.lower() == ".lcommon"))
659  return ParseDirectiveComm(true, DirectiveID.getLoc());
660  if ((IDVal.lower() == ".comm") || (IDVal.lower() == ".common"))
661  return ParseDirectiveComm(false, DirectiveID.getLoc());
662  if (IDVal.lower() == ".subsection")
663  return ParseDirectiveSubsection(DirectiveID.getLoc());
664 
665  return true;
666 }
667 bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
668  const MCExpr *Subsection = nullptr;
669  int64_t Res;
670 
671  assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
672  "Invalid subsection directive");
673  getParser().parseExpression(Subsection);
674 
675  if (!Subsection->evaluateAsAbsolute(Res))
676  return Error(L, "Cannot evaluate subsection number");
677 
678  if (getLexer().isNot(AsmToken::EndOfStatement))
679  return TokError("unexpected token in directive");
680 
681  // 0-8192 is the hard-coded range in MCObjectStreamper.cpp, this keeps the
682  // negative subsections together and in the same order but at the opposite
683  // end of the section. Only legacy hexagon-gcc created assembly code
684  // used negative subsections.
685  if ((Res < 0) && (Res > -8193))
686  Subsection = HexagonMCExpr::create(
687  MCConstantExpr::create(8192 + Res, getContext()), getContext());
688 
689  getStreamer().SubSection(Subsection);
690  return false;
691 }
692 
693 /// ::= .falign [expression]
694 bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
695 
696  int64_t MaxBytesToFill = 15;
697 
698  // if there is an argument
699  if (getLexer().isNot(AsmToken::EndOfStatement)) {
700  const MCExpr *Value;
701  SMLoc ExprLoc = L;
702 
703  // Make sure we have a number (false is returned if expression is a number)
704  if (!getParser().parseExpression(Value)) {
705  // Make sure this is a number that is in range
706  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
707  uint64_t IntValue = MCE->getValue();
708  if (!isUIntN(Size, IntValue) && !isIntN(Size, IntValue))
709  return Error(ExprLoc, "literal value out of range (256) for falign");
710  MaxBytesToFill = IntValue;
711  Lex();
712  } else {
713  return Error(ExprLoc, "not a valid expression for falign directive");
714  }
715  }
716 
717  getTargetStreamer().emitFAlign(16, MaxBytesToFill);
718  Lex();
719 
720  return false;
721 }
722 
723 /// ::= .word [ expression (, expression)* ]
724 bool HexagonAsmParser::ParseDirectiveValue(unsigned Size, SMLoc L) {
725  if (getLexer().isNot(AsmToken::EndOfStatement)) {
726  while (true) {
727  const MCExpr *Value;
728  SMLoc ExprLoc = L;
729  if (getParser().parseExpression(Value))
730  return true;
731 
732  // Special case constant expressions to match code generator.
733  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
734  assert(Size <= 8 && "Invalid size");
735  uint64_t IntValue = MCE->getValue();
736  if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
737  return Error(ExprLoc, "literal value out of range for directive");
738  getStreamer().EmitIntValue(IntValue, Size);
739  } else
740  getStreamer().EmitValue(Value, Size);
741 
742  if (getLexer().is(AsmToken::EndOfStatement))
743  break;
744 
745  // FIXME: Improve diagnostic.
746  if (getLexer().isNot(AsmToken::Comma))
747  return TokError("unexpected token in directive");
748  Lex();
749  }
750  }
751 
752  Lex();
753  return false;
754 }
755 
756 // This is largely a copy of AsmParser's ParseDirectiveComm extended to
757 // accept a 3rd argument, AccessAlignment which indicates the smallest
758 // memory access made to the symbol, expressed in bytes. If no
759 // AccessAlignment is specified it defaults to the Alignment Value.
760 // Hexagon's .lcomm:
761 // .lcomm Symbol, Length, Alignment, AccessAlignment
762 bool HexagonAsmParser::ParseDirectiveComm(bool IsLocal, SMLoc Loc) {
763  // FIXME: need better way to detect if AsmStreamer (upstream removed
764  // getKind())
765  if (getStreamer().hasRawTextSupport())
766  return true; // Only object file output requires special treatment.
767 
768  StringRef Name;
769  if (getParser().parseIdentifier(Name))
770  return TokError("expected identifier in directive");
771  // Handle the identifier as the key symbol.
772  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
773 
774  if (getLexer().isNot(AsmToken::Comma))
775  return TokError("unexpected token in directive");
776  Lex();
777 
778  int64_t Size;
779  SMLoc SizeLoc = getLexer().getLoc();
780  if (getParser().parseAbsoluteExpression(Size))
781  return true;
782 
783  int64_t ByteAlignment = 1;
784  SMLoc ByteAlignmentLoc;
785  if (getLexer().is(AsmToken::Comma)) {
786  Lex();
787  ByteAlignmentLoc = getLexer().getLoc();
788  if (getParser().parseAbsoluteExpression(ByteAlignment))
789  return true;
790  if (!isPowerOf2_64(ByteAlignment))
791  return Error(ByteAlignmentLoc, "alignment must be a power of 2");
792  }
793 
794  int64_t AccessAlignment = 0;
795  if (getLexer().is(AsmToken::Comma)) {
796  // The optional access argument specifies the size of the smallest memory
797  // access to be made to the symbol, expressed in bytes.
798  SMLoc AccessAlignmentLoc;
799  Lex();
800  AccessAlignmentLoc = getLexer().getLoc();
801  if (getParser().parseAbsoluteExpression(AccessAlignment))
802  return true;
803 
804  if (!isPowerOf2_64(AccessAlignment))
805  return Error(AccessAlignmentLoc, "access alignment must be a power of 2");
806  }
807 
808  if (getLexer().isNot(AsmToken::EndOfStatement))
809  return TokError("unexpected token in '.comm' or '.lcomm' directive");
810 
811  Lex();
812 
813  // NOTE: a size of zero for a .comm should create a undefined symbol
814  // but a size of .lcomm creates a bss symbol of size zero.
815  if (Size < 0)
816  return Error(SizeLoc, "invalid '.comm' or '.lcomm' directive size, can't "
817  "be less than zero");
818 
819  // NOTE: The alignment in the directive is a power of 2 value, the assembler
820  // may internally end up wanting an alignment in bytes.
821  // FIXME: Diagnose overflow.
822  if (ByteAlignment < 0)
823  return Error(ByteAlignmentLoc, "invalid '.comm' or '.lcomm' directive "
824  "alignment, can't be less than zero");
825 
826  if (!Sym->isUndefined())
827  return Error(Loc, "invalid symbol redefinition");
828 
829  HexagonMCELFStreamer &HexagonELFStreamer =
830  static_cast<HexagonMCELFStreamer &>(getStreamer());
831  if (IsLocal) {
832  HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol(Sym, Size, ByteAlignment,
833  AccessAlignment);
834  return false;
835  }
836 
837  HexagonELFStreamer.HexagonMCEmitCommonSymbol(Sym, Size, ByteAlignment,
838  AccessAlignment);
839  return false;
840 }
841 
842 // validate register against architecture
843 bool HexagonAsmParser::RegisterMatchesArch(unsigned MatchNum) const {
844  if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].contains(MatchNum))
845  if (!getSTI().getFeatureBits()[Hexagon::ArchV62])
846  return false;
847  return true;
848 }
849 
850 // extern "C" void LLVMInitializeHexagonAsmLexer();
851 
852 /// Force static initialization.
855 }
856 
857 #define GET_MATCHER_IMPLEMENTATION
858 #define GET_REGISTER_MATCHER
859 #include "HexagonGenAsmMatcher.inc"
860 
861 static bool previousEqual(OperandVector &Operands, size_t Index,
862  StringRef String) {
863  if (Index >= Operands.size())
864  return false;
865  MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
866  if (!Operand.isToken())
867  return false;
868  return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
869 }
870 
871 static bool previousIsLoop(OperandVector &Operands, size_t Index) {
872  return previousEqual(Operands, Index, "loop0") ||
873  previousEqual(Operands, Index, "loop1") ||
874  previousEqual(Operands, Index, "sp1loop0") ||
875  previousEqual(Operands, Index, "sp2loop0") ||
876  previousEqual(Operands, Index, "sp3loop0");
877 }
878 
879 bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
880  AsmToken const &Token = getParser().getTok();
881  StringRef String = Token.getString();
882  SMLoc Loc = Token.getLoc();
883  Lex();
884  do {
885  std::pair<StringRef, StringRef> HeadTail = String.split('.');
886  if (!HeadTail.first.empty())
887  Operands.push_back(
888  HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
889  if (!HeadTail.second.empty())
890  Operands.push_back(HexagonOperand::CreateToken(
891  getContext(), String.substr(HeadTail.first.size(), 1), Loc));
892  String = HeadTail.second;
893  } while (!String.empty());
894  return false;
895 }
896 
897 bool HexagonAsmParser::parseOperand(OperandVector &Operands) {
898  unsigned Register;
899  SMLoc Begin;
900  SMLoc End;
901  MCAsmLexer &Lexer = getLexer();
902  if (!ParseRegister(Register, Begin, End)) {
904  switch (Register) {
905  default:
906  break;
907  case Hexagon::P0:
908  case Hexagon::P1:
909  case Hexagon::P2:
910  case Hexagon::P3:
911  if (previousEqual(Operands, 0, "if")) {
913  Warning(Begin, "Missing parenthesis around predicate register");
914  static char const *LParen = "(";
915  static char const *RParen = ")";
916  Operands.push_back(
917  HexagonOperand::CreateToken(getContext(), LParen, Begin));
918  Operands.push_back(
919  HexagonOperand::CreateReg(getContext(), Register, Begin, End));
920  const AsmToken &MaybeDotNew = Lexer.getTok();
921  if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
922  MaybeDotNew.getString().equals_lower(".new"))
923  splitIdentifier(Operands);
924  Operands.push_back(
925  HexagonOperand::CreateToken(getContext(), RParen, Begin));
926  return false;
927  }
928  if (previousEqual(Operands, 0, "!") &&
929  previousEqual(Operands, 1, "if")) {
931  Warning(Begin, "Missing parenthesis around predicate register");
932  static char const *LParen = "(";
933  static char const *RParen = ")";
934  Operands.insert(Operands.end() - 1, HexagonOperand::CreateToken(
935  getContext(), LParen, Begin));
936  Operands.push_back(
937  HexagonOperand::CreateReg(getContext(), Register, Begin, End));
938  const AsmToken &MaybeDotNew = Lexer.getTok();
939  if (MaybeDotNew.is(AsmToken::TokenKind::Identifier) &&
940  MaybeDotNew.getString().equals_lower(".new"))
941  splitIdentifier(Operands);
942  Operands.push_back(
943  HexagonOperand::CreateToken(getContext(), RParen, Begin));
944  return false;
945  }
946  break;
947  }
948  Operands.push_back(
949  HexagonOperand::CreateReg(getContext(), Register, Begin, End));
950  return false;
951  }
952  return splitIdentifier(Operands);
953 }
954 
955 bool HexagonAsmParser::isLabel(AsmToken &Token) {
956  MCAsmLexer &Lexer = getLexer();
957  AsmToken const &Second = Lexer.getTok();
958  AsmToken Third = Lexer.peekTok();
959  StringRef String = Token.getString();
960  if (Token.is(AsmToken::TokenKind::LCurly) ||
961  Token.is(AsmToken::TokenKind::RCurly))
962  return false;
963  // special case for parsing vwhist256:sat
964  if (String.lower() == "vwhist256" && Second.is(AsmToken::Colon) &&
965  Third.getString().lower() == "sat")
966  return false;
968  return true;
969  if (!matchRegister(String.lower()))
970  return true;
971  assert(Second.is(AsmToken::Colon));
972  StringRef Raw(String.data(), Third.getString().data() - String.data() +
973  Third.getString().size());
974  std::string Collapsed = Raw;
975  Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
976  StringRef Whole = Collapsed;
977  std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
978  if (!matchRegister(DotSplit.first.lower()))
979  return true;
980  return false;
981 }
982 
983 bool HexagonAsmParser::handleNoncontigiousRegister(bool Contigious,
984  SMLoc &Loc) {
985  if (!Contigious && ErrorNoncontigiousRegister) {
986  Error(Loc, "Register name is not contigious");
987  return true;
988  }
989  if (!Contigious && WarnNoncontigiousRegister)
990  Warning(Loc, "Register name is not contigious");
991  return false;
992 }
993 
994 bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
995  SMLoc &EndLoc) {
996  MCAsmLexer &Lexer = getLexer();
997  StartLoc = getLexer().getLoc();
998  SmallVector<AsmToken, 5> Lookahead;
999  StringRef RawString(Lexer.getTok().getString().data(), 0);
1000  bool Again = Lexer.is(AsmToken::Identifier);
1001  bool NeededWorkaround = false;
1002  while (Again) {
1003  AsmToken const &Token = Lexer.getTok();
1004  RawString = StringRef(RawString.data(), Token.getString().data() -
1005  RawString.data() +
1006  Token.getString().size());
1007  Lookahead.push_back(Token);
1008  Lexer.Lex();
1009  bool Contigious = Lexer.getTok().getString().data() ==
1010  Lookahead.back().getString().data() +
1011  Lookahead.back().getString().size();
1012  bool Type = Lexer.is(AsmToken::Identifier) || Lexer.is(AsmToken::Dot) ||
1013  Lexer.is(AsmToken::Integer) || Lexer.is(AsmToken::Real) ||
1014  Lexer.is(AsmToken::Colon);
1015  bool Workaround =
1016  Lexer.is(AsmToken::Colon) || Lookahead.back().is(AsmToken::Colon);
1017  Again = (Contigious && Type) || (Workaround && Type);
1018  NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
1019  }
1020  std::string Collapsed = RawString;
1021  Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
1022  StringRef FullString = Collapsed;
1023  std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
1024  unsigned DotReg = matchRegister(DotSplit.first.lower());
1025  if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1026  if (DotSplit.second.empty()) {
1027  RegNo = DotReg;
1028  EndLoc = Lexer.getLoc();
1029  if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1030  return true;
1031  return false;
1032  } else {
1033  RegNo = DotReg;
1034  size_t First = RawString.find('.');
1035  StringRef DotString (RawString.data() + First, RawString.size() - First);
1036  Lexer.UnLex(AsmToken(AsmToken::Identifier, DotString));
1037  EndLoc = Lexer.getLoc();
1038  if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1039  return true;
1040  return false;
1041  }
1042  }
1043  std::pair<StringRef, StringRef> ColonSplit = StringRef(FullString).split(':');
1044  unsigned ColonReg = matchRegister(ColonSplit.first.lower());
1045  if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1046  do {
1047  Lexer.UnLex(Lookahead.back());
1048  Lookahead.pop_back();
1049  } while (!Lookahead.empty () && !Lexer.is(AsmToken::Colon));
1050  RegNo = ColonReg;
1051  EndLoc = Lexer.getLoc();
1052  if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1053  return true;
1054  return false;
1055  }
1056  while (!Lookahead.empty()) {
1057  Lexer.UnLex(Lookahead.back());
1058  Lookahead.pop_back();
1059  }
1060  return true;
1061 }
1062 
1063 bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
1064  if (previousEqual(Operands, 0, "call"))
1065  return true;
1066  if (previousEqual(Operands, 0, "jump"))
1067  if (!getLexer().getTok().is(AsmToken::Colon))
1068  return true;
1069  if (previousEqual(Operands, 0, "(") && previousIsLoop(Operands, 1))
1070  return true;
1071  if (previousEqual(Operands, 1, ":") && previousEqual(Operands, 2, "jump") &&
1072  (previousEqual(Operands, 0, "nt") || previousEqual(Operands, 0, "t")))
1073  return true;
1074  return false;
1075 }
1076 
1077 bool HexagonAsmParser::parseExpression(MCExpr const *&Expr) {
1078  SmallVector<AsmToken, 4> Tokens;
1079  MCAsmLexer &Lexer = getLexer();
1080  bool Done = false;
1081  static char const *Comma = ",";
1082  do {
1083  Tokens.emplace_back(Lexer.getTok());
1084  Lex();
1085  switch (Tokens.back().getKind()) {
1086  case AsmToken::TokenKind::Hash:
1087  if (Tokens.size() > 1)
1088  if ((Tokens.end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
1089  Tokens.insert(Tokens.end() - 2,
1091  Done = true;
1092  }
1093  break;
1094  case AsmToken::TokenKind::RCurly:
1095  case AsmToken::TokenKind::EndOfStatement:
1097  Done = true;
1098  break;
1099  default:
1100  break;
1101  }
1102  } while (!Done);
1103  while (!Tokens.empty()) {
1104  Lexer.UnLex(Tokens.back());
1105  Tokens.pop_back();
1106  }
1107  SMLoc Loc = Lexer.getLoc();
1108  return getParser().parseExpression(Expr, Loc);
1109 }
1110 
1111 bool HexagonAsmParser::parseExpressionOrOperand(OperandVector &Operands) {
1112  if (implicitExpressionLocation(Operands)) {
1113  MCAsmParser &Parser = getParser();
1114  SMLoc Loc = Parser.getLexer().getLoc();
1115  MCExpr const *Expr = nullptr;
1116  bool Error = parseExpression(Expr);
1117  Expr = HexagonMCExpr::create(Expr, getContext());
1118  if (!Error)
1119  Operands.push_back(
1120  HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
1121  return Error;
1122  }
1123  return parseOperand(Operands);
1124 }
1125 
1126 /// Parse an instruction.
1127 bool HexagonAsmParser::parseInstruction(OperandVector &Operands) {
1128  MCAsmParser &Parser = getParser();
1129  MCAsmLexer &Lexer = getLexer();
1130  while (true) {
1131  AsmToken const &Token = Parser.getTok();
1132  switch (Token.getKind()) {
1133  case AsmToken::Eof:
1134  case AsmToken::EndOfStatement: {
1135  Lex();
1136  return false;
1137  }
1138  case AsmToken::LCurly: {
1139  if (!Operands.empty())
1140  return true;
1141  Operands.push_back(HexagonOperand::CreateToken(
1142  getContext(), Token.getString(), Token.getLoc()));
1143  Lex();
1144  return false;
1145  }
1146  case AsmToken::RCurly: {
1147  if (Operands.empty()) {
1148  Operands.push_back(HexagonOperand::CreateToken(
1149  getContext(), Token.getString(), Token.getLoc()));
1150  Lex();
1151  }
1152  return false;
1153  }
1154  case AsmToken::Comma: {
1155  Lex();
1156  continue;
1157  }
1158  case AsmToken::EqualEqual:
1162  case AsmToken::LessEqual:
1163  case AsmToken::LessLess: {
1164  Operands.push_back(HexagonOperand::CreateToken(
1165  getContext(), Token.getString().substr(0, 1), Token.getLoc()));
1166  Operands.push_back(HexagonOperand::CreateToken(
1167  getContext(), Token.getString().substr(1, 1), Token.getLoc()));
1168  Lex();
1169  continue;
1170  }
1171  case AsmToken::Hash: {
1172  bool MustNotExtend = false;
1173  bool ImplicitExpression = implicitExpressionLocation(Operands);
1174  SMLoc ExprLoc = Lexer.getLoc();
1175  if (!ImplicitExpression)
1176  Operands.push_back(HexagonOperand::CreateToken(
1177  getContext(), Token.getString(), Token.getLoc()));
1178  Lex();
1179  bool MustExtend = false;
1180  bool HiOnly = false;
1181  bool LoOnly = false;
1182  if (Lexer.is(AsmToken::Hash)) {
1183  Lex();
1184  MustExtend = true;
1185  } else if (ImplicitExpression)
1186  MustNotExtend = true;
1187  AsmToken const &Token = Parser.getTok();
1188  if (Token.is(AsmToken::Identifier)) {
1189  StringRef String = Token.getString();
1190  if (String.lower() == "hi") {
1191  HiOnly = true;
1192  } else if (String.lower() == "lo") {
1193  LoOnly = true;
1194  }
1195  if (HiOnly || LoOnly) {
1196  AsmToken LParen = Lexer.peekTok();
1197  if (!LParen.is(AsmToken::LParen)) {
1198  HiOnly = false;
1199  LoOnly = false;
1200  } else {
1201  Lex();
1202  }
1203  }
1204  }
1205  MCExpr const *Expr = nullptr;
1206  if (parseExpression(Expr))
1207  return true;
1208  int64_t Value;
1209  MCContext &Context = Parser.getContext();
1210  assert(Expr != nullptr);
1211  if (Expr->evaluateAsAbsolute(Value)) {
1212  if (HiOnly)
1213  Expr = MCBinaryExpr::createLShr(
1214  Expr, MCConstantExpr::create(16, Context), Context);
1215  if (HiOnly || LoOnly)
1216  Expr = MCBinaryExpr::createAnd(
1217  Expr, MCConstantExpr::create(0xffff, Context), Context);
1218  } else {
1219  MCValue Value;
1220  if (Expr->evaluateAsRelocatable(Value, nullptr, nullptr)) {
1221  if (!Value.isAbsolute()) {
1222  switch (Value.getAccessVariant()) {
1223  case MCSymbolRefExpr::VariantKind::VK_TPREL:
1224  case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1225  // Don't lazy extend these expression variants
1226  MustNotExtend = !MustExtend;
1227  break;
1228  default:
1229  break;
1230  }
1231  }
1232  }
1233  }
1234  Expr = HexagonMCExpr::create(Expr, Context);
1235  HexagonMCInstrInfo::setMustNotExtend(*Expr, MustNotExtend);
1236  HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
1237  std::unique_ptr<HexagonOperand> Operand =
1238  HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
1239  Operands.push_back(std::move(Operand));
1240  continue;
1241  }
1242  default:
1243  break;
1244  }
1245  if (parseExpressionOrOperand(Operands))
1246  return true;
1247  }
1248 }
1249 
1250 bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1252  OperandVector &Operands) {
1253  getLexer().UnLex(ID);
1254  return parseInstruction(Operands);
1255 }
1256 
1257 static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1,
1258  MCOperand &MO2) {
1259  MCInst TmpInst;
1260  TmpInst.setOpcode(opCode);
1261  TmpInst.addOperand(Rdd);
1262  TmpInst.addOperand(MO1);
1263  TmpInst.addOperand(MO2);
1264 
1265  return TmpInst;
1266 }
1267 
1268 // Define this matcher function after the auto-generated include so we
1269 // have the match class enum definitions.
1270 unsigned HexagonAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1271  unsigned Kind) {
1272  HexagonOperand *Op = static_cast<HexagonOperand *>(&AsmOp);
1273 
1274  switch (Kind) {
1275  case MCK_0: {
1276  int64_t Value;
1277  return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1278  ? Match_Success
1279  : Match_InvalidOperand;
1280  }
1281  case MCK_1: {
1282  int64_t Value;
1283  return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1284  ? Match_Success
1285  : Match_InvalidOperand;
1286  }
1287  }
1288  if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1289  StringRef myStringRef = StringRef(Op->Tok.Data, Op->Tok.Length);
1290  if (matchTokenString(myStringRef.lower()) == (MatchClassKind)Kind)
1291  return Match_Success;
1292  if (matchTokenString(myStringRef.upper()) == (MatchClassKind)Kind)
1293  return Match_Success;
1294  }
1295 
1296  DEBUG(dbgs() << "Unmatched Operand:");
1297  DEBUG(Op->dump());
1298  DEBUG(dbgs() << "\n");
1299 
1300  return Match_InvalidOperand;
1301 }
1302 
1303 // FIXME: Calls to OutOfRange shoudl propagate failure up to parseStatement.
1304 bool HexagonAsmParser::OutOfRange(SMLoc IDLoc, long long Val, long long Max) {
1305  std::string errStr;
1306  raw_string_ostream ES(errStr);
1307  ES << "value " << Val << "(" << format_hex(Val, 0) << ") out of range: ";
1308  if (Max >= 0)
1309  ES << "0-" << Max;
1310  else
1311  ES << Max << "-" << (-Max - 1);
1312  return Parser.printError(IDLoc, ES.str());
1313 }
1314 
1315 int HexagonAsmParser::processInstruction(MCInst &Inst,
1316  OperandVector const &Operands,
1317  SMLoc IDLoc) {
1318  MCContext &Context = getParser().getContext();
1319  const MCRegisterInfo *RI = getContext().getRegisterInfo();
1320  std::string r = "r";
1321  std::string v = "v";
1322  std::string Colon = ":";
1323 
1324  bool is32bit = false; // used to distinguish between CONST32 and CONST64
1325  switch (Inst.getOpcode()) {
1326  default:
1327  if (HexagonMCInstrInfo::getDesc(MII, Inst).isPseudo()) {
1328  SMDiagnostic Diag = getSourceManager().GetMessage(
1329  IDLoc, SourceMgr::DK_Error,
1330  "Found pseudo instruction with no expansion");
1331  Diag.print("", errs());
1332  report_fatal_error("Invalid pseudo instruction");
1333  }
1334  break;
1335 
1336  case Hexagon::A2_iconst: {
1337  Inst.setOpcode(Hexagon::A2_addi);
1338  MCOperand Reg = Inst.getOperand(0);
1339  MCOperand S27 = Inst.getOperand(1);
1342  Inst.clear();
1343  Inst.addOperand(Reg);
1344  Inst.addOperand(MCOperand::createReg(Hexagon::R0));
1345  Inst.addOperand(S27);
1346  break;
1347  }
1348  case Hexagon::M4_mpyrr_addr:
1349  case Hexagon::S4_addi_asl_ri:
1350  case Hexagon::S4_addi_lsr_ri:
1351  case Hexagon::S4_andi_asl_ri:
1352  case Hexagon::S4_andi_lsr_ri:
1353  case Hexagon::S4_ori_asl_ri:
1354  case Hexagon::S4_ori_lsr_ri:
1355  case Hexagon::S4_or_andix:
1356  case Hexagon::S4_subi_asl_ri:
1357  case Hexagon::S4_subi_lsr_ri: {
1358  MCOperand &Ry = Inst.getOperand(0);
1359  MCOperand &src = Inst.getOperand(2);
1360  if (RI->getEncodingValue(Ry.getReg()) != RI->getEncodingValue(src.getReg()))
1361  return Match_InvalidOperand;
1362  break;
1363  }
1364 
1365  case Hexagon::C2_cmpgei: {
1366  MCOperand &MO = Inst.getOperand(2);
1369  MCConstantExpr::create(1, Context), Context),
1370  Context));
1371  Inst.setOpcode(Hexagon::C2_cmpgti);
1372  break;
1373  }
1374 
1375  case Hexagon::C2_cmpgeui: {
1376  MCOperand &MO = Inst.getOperand(2);
1377  int64_t Value;
1378  bool Success = MO.getExpr()->evaluateAsAbsolute(Value);
1379  (void)Success;
1380  assert(Success && "Assured by matcher");
1381  if (Value == 0) {
1382  MCInst TmpInst;
1383  MCOperand &Pd = Inst.getOperand(0);
1384  MCOperand &Rt = Inst.getOperand(1);
1385  TmpInst.setOpcode(Hexagon::C2_cmpeq);
1386  TmpInst.addOperand(Pd);
1387  TmpInst.addOperand(Rt);
1388  TmpInst.addOperand(Rt);
1389  Inst = TmpInst;
1390  } else {
1393  MCConstantExpr::create(1, Context), Context),
1394  Context));
1395  Inst.setOpcode(Hexagon::C2_cmpgtui);
1396  }
1397  break;
1398  }
1399 
1400  // Translate a "$Rdd = $Rss" to "$Rdd = combine($Rs, $Rt)"
1401  case Hexagon::A2_tfrp: {
1402  MCOperand &MO = Inst.getOperand(1);
1403  unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1404  std::string R1 = r + utostr(RegPairNum + 1);
1405  StringRef Reg1(R1);
1406  MO.setReg(matchRegister(Reg1));
1407  // Add a new operand for the second register in the pair.
1408  std::string R2 = r + utostr(RegPairNum);
1409  StringRef Reg2(R2);
1410  Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1411  Inst.setOpcode(Hexagon::A2_combinew);
1412  break;
1413  }
1414 
1415  case Hexagon::A2_tfrpt:
1416  case Hexagon::A2_tfrpf: {
1417  MCOperand &MO = Inst.getOperand(2);
1418  unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1419  std::string R1 = r + utostr(RegPairNum + 1);
1420  StringRef Reg1(R1);
1421  MO.setReg(matchRegister(Reg1));
1422  // Add a new operand for the second register in the pair.
1423  std::string R2 = r + utostr(RegPairNum);
1424  StringRef Reg2(R2);
1425  Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1426  Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
1427  ? Hexagon::C2_ccombinewt
1428  : Hexagon::C2_ccombinewf);
1429  break;
1430  }
1431  case Hexagon::A2_tfrptnew:
1432  case Hexagon::A2_tfrpfnew: {
1433  MCOperand &MO = Inst.getOperand(2);
1434  unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1435  std::string R1 = r + utostr(RegPairNum + 1);
1436  StringRef Reg1(R1);
1437  MO.setReg(matchRegister(Reg1));
1438  // Add a new operand for the second register in the pair.
1439  std::string R2 = r + utostr(RegPairNum);
1440  StringRef Reg2(R2);
1441  Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1442  Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
1443  ? Hexagon::C2_ccombinewnewt
1444  : Hexagon::C2_ccombinewnewf);
1445  break;
1446  }
1447 
1448  // Translate a "$Vdd = $Vss" to "$Vdd = vcombine($Vs, $Vt)"
1449  case Hexagon::V6_vassignp: {
1450  MCOperand &MO = Inst.getOperand(1);
1451  unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
1452  std::string R1 = v + utostr(RegPairNum + 1);
1453  MO.setReg(MatchRegisterName(R1));
1454  // Add a new operand for the second register in the pair.
1455  std::string R2 = v + utostr(RegPairNum);
1457  Inst.setOpcode(Hexagon::V6_vcombine);
1458  break;
1459  }
1460 
1461  // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) "
1462  case Hexagon::CONST32:
1463  is32bit = true;
1465  // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) "
1466  case Hexagon::CONST64:
1467  // FIXME: need better way to detect AsmStreamer (upstream removed getKind())
1468  if (!Parser.getStreamer().hasRawTextSupport()) {
1469  MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
1470  MCOperand &MO_1 = Inst.getOperand(1);
1471  MCOperand &MO_0 = Inst.getOperand(0);
1472 
1473  // push section onto section stack
1474  MES->PushSection();
1475 
1476  std::string myCharStr;
1477  MCSectionELF *mySection;
1478 
1479  // check if this as an immediate or a symbol
1480  int64_t Value;
1481  bool Absolute = MO_1.getExpr()->evaluateAsAbsolute(Value);
1482  if (Absolute) {
1483  // Create a new section - one for each constant
1484  // Some or all of the zeros are replaced with the given immediate.
1485  if (is32bit) {
1486  std::string myImmStr = utohexstr(static_cast<uint32_t>(Value));
1487  myCharStr = StringRef(".gnu.linkonce.l4.CONST_00000000")
1488  .drop_back(myImmStr.size())
1489  .str() +
1490  myImmStr;
1491  } else {
1492  std::string myImmStr = utohexstr(Value);
1493  myCharStr = StringRef(".gnu.linkonce.l8.CONST_0000000000000000")
1494  .drop_back(myImmStr.size())
1495  .str() +
1496  myImmStr;
1497  }
1498 
1499  mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1501  } else if (MO_1.isExpr()) {
1502  // .lita - for expressions
1503  myCharStr = ".lita";
1504  mySection = getContext().getELFSection(myCharStr, ELF::SHT_PROGBITS,
1506  } else
1507  llvm_unreachable("unexpected type of machine operand!");
1508 
1509  MES->SwitchSection(mySection);
1510  unsigned byteSize = is32bit ? 4 : 8;
1511  getStreamer().EmitCodeAlignment(byteSize, byteSize);
1512 
1513  MCSymbol *Sym;
1514 
1515  // for symbols, get rid of prepended ".gnu.linkonce.lx."
1516 
1517  // emit symbol if needed
1518  if (Absolute) {
1519  Sym = getContext().getOrCreateSymbol(StringRef(myCharStr.c_str() + 16));
1520  if (Sym->isUndefined()) {
1521  getStreamer().EmitLabel(Sym);
1522  getStreamer().EmitSymbolAttribute(Sym, MCSA_Global);
1523  getStreamer().EmitIntValue(Value, byteSize);
1524  }
1525  } else if (MO_1.isExpr()) {
1526  const char *StringStart = nullptr;
1527  const char *StringEnd = nullptr;
1528  if (*Operands[4]->getStartLoc().getPointer() == '#') {
1529  StringStart = Operands[5]->getStartLoc().getPointer();
1530  StringEnd = Operands[6]->getStartLoc().getPointer();
1531  } else { // no pound
1532  StringStart = Operands[4]->getStartLoc().getPointer();
1533  StringEnd = Operands[5]->getStartLoc().getPointer();
1534  }
1535 
1536  unsigned size = StringEnd - StringStart;
1537  std::string DotConst = ".CONST_";
1538  Sym = getContext().getOrCreateSymbol(DotConst +
1539  StringRef(StringStart, size));
1540 
1541  if (Sym->isUndefined()) {
1542  // case where symbol is not yet defined: emit symbol
1543  getStreamer().EmitLabel(Sym);
1544  getStreamer().EmitSymbolAttribute(Sym, MCSA_Local);
1545  getStreamer().EmitValue(MO_1.getExpr(), 4);
1546  }
1547  } else
1548  llvm_unreachable("unexpected type of machine operand!");
1549 
1550  MES->PopSection();
1551 
1552  if (Sym) {
1553  MCInst TmpInst;
1554  if (is32bit) // 32 bit
1555  TmpInst.setOpcode(Hexagon::L2_loadrigp);
1556  else // 64 bit
1557  TmpInst.setOpcode(Hexagon::L2_loadrdgp);
1558 
1559  TmpInst.addOperand(MO_0);
1561  MCSymbolRefExpr::create(Sym, getContext()), getContext())));
1562  Inst = TmpInst;
1563  }
1564  }
1565  break;
1566 
1567  // Translate a "$Rdd = #-imm" to "$Rdd = combine(#[-1,0], #-imm)"
1568  case Hexagon::A2_tfrpi: {
1569  MCOperand &Rdd = Inst.getOperand(0);
1570  MCOperand &MO = Inst.getOperand(1);
1571  int64_t Value;
1572  int sVal = (MO.getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
1574  HexagonMCExpr::create(MCConstantExpr::create(sVal, Context), Context)));
1575  Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, imm, MO);
1576  break;
1577  }
1578 
1579  // Translate a "$Rdd = [#]#imm" to "$Rdd = combine(#, [#]#imm)"
1580  case Hexagon::TFRI64_V4: {
1581  MCOperand &Rdd = Inst.getOperand(0);
1582  MCOperand &MO = Inst.getOperand(1);
1583  int64_t Value;
1584  if (MO.getExpr()->evaluateAsAbsolute(Value)) {
1585  int s8 = Hi_32(Value);
1586  if (!isInt<8>(s8))
1587  OutOfRange(IDLoc, s8, -128);
1589  MCConstantExpr::create(s8, Context), Context))); // upper 32
1590  auto Expr = HexagonMCExpr::create(
1591  MCConstantExpr::create(Lo_32(Value), Context), Context);
1593  *Expr, HexagonMCInstrInfo::mustExtend(*MO.getExpr()));
1594  MCOperand imm2(MCOperand::createExpr(Expr)); // lower 32
1595  Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, imm2);
1596  } else {
1598  MCConstantExpr::create(0, Context), Context))); // upper 32
1599  Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, imm, MO);
1600  }
1601  break;
1602  }
1603 
1604  // Handle $Rdd = combine(##imm, #imm)"
1605  case Hexagon::TFRI64_V2_ext: {
1606  MCOperand &Rdd = Inst.getOperand(0);
1607  MCOperand &MO1 = Inst.getOperand(1);
1608  MCOperand &MO2 = Inst.getOperand(2);
1609  int64_t Value;
1610  if (MO2.getExpr()->evaluateAsAbsolute(Value)) {
1611  int s8 = Value;
1612  if (s8 < -128 || s8 > 127)
1613  OutOfRange(IDLoc, s8, -128);
1614  }
1615  Inst = makeCombineInst(Hexagon::A2_combineii, Rdd, MO1, MO2);
1616  break;
1617  }
1618 
1619  // Handle $Rdd = combine(#imm, ##imm)"
1620  case Hexagon::A4_combineii: {
1621  MCOperand &Rdd = Inst.getOperand(0);
1622  MCOperand &MO1 = Inst.getOperand(1);
1623  int64_t Value;
1624  if (MO1.getExpr()->evaluateAsAbsolute(Value)) {
1625  int s8 = Value;
1626  if (s8 < -128 || s8 > 127)
1627  OutOfRange(IDLoc, s8, -128);
1628  }
1629  MCOperand &MO2 = Inst.getOperand(2);
1630  Inst = makeCombineInst(Hexagon::A4_combineii, Rdd, MO1, MO2);
1631  break;
1632  }
1633 
1634  case Hexagon::S2_tableidxb_goodsyntax:
1635  Inst.setOpcode(Hexagon::S2_tableidxb);
1636  break;
1637 
1638  case Hexagon::S2_tableidxh_goodsyntax: {
1639  MCInst TmpInst;
1640  MCOperand &Rx = Inst.getOperand(0);
1641  MCOperand &Rs = Inst.getOperand(2);
1642  MCOperand &Imm4 = Inst.getOperand(3);
1643  MCOperand &Imm6 = Inst.getOperand(4);
1646  MCConstantExpr::create(1, Context), Context),
1647  Context));
1648  TmpInst.setOpcode(Hexagon::S2_tableidxh);
1649  TmpInst.addOperand(Rx);
1650  TmpInst.addOperand(Rx);
1651  TmpInst.addOperand(Rs);
1652  TmpInst.addOperand(Imm4);
1653  TmpInst.addOperand(Imm6);
1654  Inst = TmpInst;
1655  break;
1656  }
1657 
1658  case Hexagon::S2_tableidxw_goodsyntax: {
1659  MCInst TmpInst;
1660  MCOperand &Rx = Inst.getOperand(0);
1661  MCOperand &Rs = Inst.getOperand(2);
1662  MCOperand &Imm4 = Inst.getOperand(3);
1663  MCOperand &Imm6 = Inst.getOperand(4);
1666  MCConstantExpr::create(2, Context), Context),
1667  Context));
1668  TmpInst.setOpcode(Hexagon::S2_tableidxw);
1669  TmpInst.addOperand(Rx);
1670  TmpInst.addOperand(Rx);
1671  TmpInst.addOperand(Rs);
1672  TmpInst.addOperand(Imm4);
1673  TmpInst.addOperand(Imm6);
1674  Inst = TmpInst;
1675  break;
1676  }
1677 
1678  case Hexagon::S2_tableidxd_goodsyntax: {
1679  MCInst TmpInst;
1680  MCOperand &Rx = Inst.getOperand(0);
1681  MCOperand &Rs = Inst.getOperand(2);
1682  MCOperand &Imm4 = Inst.getOperand(3);
1683  MCOperand &Imm6 = Inst.getOperand(4);
1686  MCConstantExpr::create(3, Context), Context),
1687  Context));
1688  TmpInst.setOpcode(Hexagon::S2_tableidxd);
1689  TmpInst.addOperand(Rx);
1690  TmpInst.addOperand(Rx);
1691  TmpInst.addOperand(Rs);
1692  TmpInst.addOperand(Imm4);
1693  TmpInst.addOperand(Imm6);
1694  Inst = TmpInst;
1695  break;
1696  }
1697 
1698  case Hexagon::M2_mpyui:
1699  Inst.setOpcode(Hexagon::M2_mpyi);
1700  break;
1701  case Hexagon::M2_mpysmi: {
1702  MCInst TmpInst;
1703  MCOperand &Rd = Inst.getOperand(0);
1704  MCOperand &Rs = Inst.getOperand(1);
1705  MCOperand &Imm = Inst.getOperand(2);
1706  int64_t Value;
1707  MCExpr const &Expr = *Imm.getExpr();
1708  bool Absolute = Expr.evaluateAsAbsolute(Value);
1709  assert(Absolute);
1710  (void)Absolute;
1711  if (!HexagonMCInstrInfo::mustExtend(Expr) &&
1712  ((Value <= -256) || Value >= 256))
1713  return Match_InvalidOperand;
1714  if (Value < 0 && Value > -256) {
1716  MCConstantExpr::create(Value * -1, Context), Context));
1717  TmpInst.setOpcode(Hexagon::M2_mpysin);
1718  } else
1719  TmpInst.setOpcode(Hexagon::M2_mpysip);
1720  TmpInst.addOperand(Rd);
1721  TmpInst.addOperand(Rs);
1722  TmpInst.addOperand(Imm);
1723  Inst = TmpInst;
1724  break;
1725  }
1726 
1727  case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1728  MCOperand &Imm = Inst.getOperand(2);
1729  MCInst TmpInst;
1730  int64_t Value;
1731  bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1732  assert(Absolute);
1733  (void)Absolute;
1734  if (Value == 0) { // convert to $Rd = $Rs
1735  TmpInst.setOpcode(Hexagon::A2_tfr);
1736  MCOperand &Rd = Inst.getOperand(0);
1737  MCOperand &Rs = Inst.getOperand(1);
1738  TmpInst.addOperand(Rd);
1739  TmpInst.addOperand(Rs);
1740  } else {
1743  MCConstantExpr::create(1, Context), Context),
1744  Context));
1745  TmpInst.setOpcode(Hexagon::S2_asr_i_r_rnd);
1746  MCOperand &Rd = Inst.getOperand(0);
1747  MCOperand &Rs = Inst.getOperand(1);
1748  TmpInst.addOperand(Rd);
1749  TmpInst.addOperand(Rs);
1750  TmpInst.addOperand(Imm);
1751  }
1752  Inst = TmpInst;
1753  break;
1754  }
1755 
1756  case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1757  MCOperand &Rdd = Inst.getOperand(0);
1758  MCOperand &Rss = Inst.getOperand(1);
1759  MCOperand &Imm = Inst.getOperand(2);
1760  int64_t Value;
1761  bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1762  assert(Absolute);
1763  (void)Absolute;
1764  if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
1765  MCInst TmpInst;
1766  unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1767  std::string R1 = r + utostr(RegPairNum + 1);
1768  StringRef Reg1(R1);
1769  Rss.setReg(matchRegister(Reg1));
1770  // Add a new operand for the second register in the pair.
1771  std::string R2 = r + utostr(RegPairNum);
1772  StringRef Reg2(R2);
1773  TmpInst.setOpcode(Hexagon::A2_combinew);
1774  TmpInst.addOperand(Rdd);
1775  TmpInst.addOperand(Rss);
1776  TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1777  Inst = TmpInst;
1778  } else {
1781  MCConstantExpr::create(1, Context), Context),
1782  Context));
1783  Inst.setOpcode(Hexagon::S2_asr_i_p_rnd);
1784  }
1785  break;
1786  }
1787 
1788  case Hexagon::A4_boundscheck: {
1789  MCOperand &Rs = Inst.getOperand(1);
1790  unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1791  if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
1792  Inst.setOpcode(Hexagon::A4_boundscheck_hi);
1793  std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1794  StringRef RegPair = Name;
1795  Rs.setReg(matchRegister(RegPair));
1796  } else { // raw:lo
1797  Inst.setOpcode(Hexagon::A4_boundscheck_lo);
1798  std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1799  StringRef RegPair = Name;
1800  Rs.setReg(matchRegister(RegPair));
1801  }
1802  break;
1803  }
1804 
1805  case Hexagon::A2_addsp: {
1806  MCOperand &Rs = Inst.getOperand(1);
1807  unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
1808  if (RegNum & 1) { // Odd mapped to raw:hi
1809  Inst.setOpcode(Hexagon::A2_addsph);
1810  std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1811  StringRef RegPair = Name;
1812  Rs.setReg(matchRegister(RegPair));
1813  } else { // Even mapped raw:lo
1814  Inst.setOpcode(Hexagon::A2_addspl);
1815  std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1816  StringRef RegPair = Name;
1817  Rs.setReg(matchRegister(RegPair));
1818  }
1819  break;
1820  }
1821 
1822  case Hexagon::M2_vrcmpys_s1: {
1823  MCOperand &Rt = Inst.getOperand(2);
1824  unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1825  if (RegNum & 1) { // Odd mapped to sat:raw:hi
1826  Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
1827  std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1828  StringRef RegPair = Name;
1829  Rt.setReg(matchRegister(RegPair));
1830  } else { // Even mapped sat:raw:lo
1831  Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
1832  std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1833  StringRef RegPair = Name;
1834  Rt.setReg(matchRegister(RegPair));
1835  }
1836  break;
1837  }
1838 
1839  case Hexagon::M2_vrcmpys_acc_s1: {
1840  MCInst TmpInst;
1841  MCOperand &Rxx = Inst.getOperand(0);
1842  MCOperand &Rss = Inst.getOperand(2);
1843  MCOperand &Rt = Inst.getOperand(3);
1844  unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1845  if (RegNum & 1) { // Odd mapped to sat:raw:hi
1846  TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_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 sat:raw:lo
1851  TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
1852  std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1853  StringRef RegPair = Name;
1854  Rt.setReg(matchRegister(RegPair));
1855  }
1856  // Registers are in different positions
1857  TmpInst.addOperand(Rxx);
1858  TmpInst.addOperand(Rxx);
1859  TmpInst.addOperand(Rss);
1860  TmpInst.addOperand(Rt);
1861  Inst = TmpInst;
1862  break;
1863  }
1864 
1865  case Hexagon::M2_vrcmpys_s1rp: {
1866  MCOperand &Rt = Inst.getOperand(2);
1867  unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
1868  if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
1869  Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
1870  std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1871  StringRef RegPair = Name;
1872  Rt.setReg(matchRegister(RegPair));
1873  } else { // Even mapped rnd:sat:raw:lo
1874  Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
1875  std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1876  StringRef RegPair = Name;
1877  Rt.setReg(matchRegister(RegPair));
1878  }
1879  break;
1880  }
1881 
1882  case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
1883  MCOperand &Imm = Inst.getOperand(2);
1884  int64_t Value;
1885  bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1886  assert(Absolute);
1887  (void)Absolute;
1888  if (Value == 0)
1889  Inst.setOpcode(Hexagon::S2_vsathub);
1890  else {
1893  MCConstantExpr::create(1, Context), Context),
1894  Context));
1895  Inst.setOpcode(Hexagon::S5_asrhub_rnd_sat);
1896  }
1897  break;
1898  }
1899 
1900  case Hexagon::S5_vasrhrnd_goodsyntax: {
1901  MCOperand &Rdd = Inst.getOperand(0);
1902  MCOperand &Rss = Inst.getOperand(1);
1903  MCOperand &Imm = Inst.getOperand(2);
1904  int64_t Value;
1905  bool Absolute = Imm.getExpr()->evaluateAsAbsolute(Value);
1906  assert(Absolute);
1907  (void)Absolute;
1908  if (Value == 0) {
1909  MCInst TmpInst;
1910  unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
1911  std::string R1 = r + utostr(RegPairNum + 1);
1912  StringRef Reg1(R1);
1913  Rss.setReg(matchRegister(Reg1));
1914  // Add a new operand for the second register in the pair.
1915  std::string R2 = r + utostr(RegPairNum);
1916  StringRef Reg2(R2);
1917  TmpInst.setOpcode(Hexagon::A2_combinew);
1918  TmpInst.addOperand(Rdd);
1919  TmpInst.addOperand(Rss);
1920  TmpInst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
1921  Inst = TmpInst;
1922  } else {
1925  MCConstantExpr::create(1, Context), Context),
1926  Context));
1927  Inst.setOpcode(Hexagon::S5_vasrhrnd);
1928  }
1929  break;
1930  }
1931 
1932  case Hexagon::A2_not: {
1933  MCInst TmpInst;
1934  MCOperand &Rd = Inst.getOperand(0);
1935  MCOperand &Rs = Inst.getOperand(1);
1936  TmpInst.setOpcode(Hexagon::A2_subri);
1937  TmpInst.addOperand(Rd);
1939  HexagonMCExpr::create(MCConstantExpr::create(-1, Context), Context)));
1940  TmpInst.addOperand(Rs);
1941  Inst = TmpInst;
1942  break;
1943  }
1944  case Hexagon::PS_loadrubabs:
1946  Inst.setOpcode(Hexagon::L2_loadrubgp);
1947  break;
1948  case Hexagon::PS_loadrbabs:
1950  Inst.setOpcode(Hexagon::L2_loadrbgp);
1951  break;
1952  case Hexagon::PS_loadruhabs:
1954  Inst.setOpcode(Hexagon::L2_loadruhgp);
1955  break;
1956  case Hexagon::PS_loadrhabs:
1958  Inst.setOpcode(Hexagon::L2_loadrhgp);
1959  break;
1960  case Hexagon::PS_loadriabs:
1962  Inst.setOpcode(Hexagon::L2_loadrigp);
1963  break;
1964  case Hexagon::PS_loadrdabs:
1966  Inst.setOpcode(Hexagon::L2_loadrdgp);
1967  break;
1968  case Hexagon::PS_storerbabs:
1970  Inst.setOpcode(Hexagon::S2_storerbgp);
1971  break;
1972  case Hexagon::PS_storerhabs:
1974  Inst.setOpcode(Hexagon::S2_storerhgp);
1975  break;
1976  case Hexagon::PS_storerfabs:
1978  Inst.setOpcode(Hexagon::S2_storerfgp);
1979  break;
1980  case Hexagon::PS_storeriabs:
1982  Inst.setOpcode(Hexagon::S2_storerigp);
1983  break;
1984  case Hexagon::PS_storerdabs:
1986  Inst.setOpcode(Hexagon::S2_storerdgp);
1987  break;
1988  case Hexagon::PS_storerbnewabs:
1990  Inst.setOpcode(Hexagon::S2_storerbnewgp);
1991  break;
1992  case Hexagon::PS_storerhnewabs:
1994  Inst.setOpcode(Hexagon::S2_storerhnewgp);
1995  break;
1996  case Hexagon::PS_storerinewabs:
1998  Inst.setOpcode(Hexagon::S2_storerinewgp);
1999  break;
2000  case Hexagon::A2_zxtb: {
2001  Inst.setOpcode(Hexagon::A2_andir);
2002  Inst.addOperand(
2004  break;
2005  }
2006  } // switch
2007 
2008  return Match_Success;
2009 }
2010 
2011 unsigned HexagonAsmParser::matchRegister(StringRef Name) {
2012  if (unsigned Reg = MatchRegisterName(Name))
2013  return Reg;
2014  return MatchRegisterAltName(Name);
2015 }
static bool isReg(const MCInst &MI, unsigned OpNo)
static bool Check(DecodeStatus &Out, DecodeStatus In)
void push_back(const T &Elt)
Definition: SmallVector.h:212
const AsmToken & getTok() const
Get the current (last) lexed token.
Definition: MCAsmLexer.h:218
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: MCAsmLexer.h:116
LLVMContext & Context
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:313
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:345
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:189
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:253
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:136
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:54
Target specific streamer interface.
Definition: MCStreamer.h:81
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:350
demanded bits
static const MCBinaryExpr * createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:456
bool isPseudo() const
Return true if this is a pseudo instruction that doesn&#39;t correspond to a real machine instruction...
Definition: MCInstrDesc.h:242
#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
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:875
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: MCAsmLexer.h:105
SMLoc getLoc() const
Get the current source location.
Definition: MCAsmLexer.cpp:22
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:149
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
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
Definition: MCAsmLexer.h:27
.local (ELF)
Definition: MCDirectives.h:35
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:144
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:61
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:536
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:604
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:26
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:159
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText...
Definition: MCStreamer.h:275
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
int64_t getValue() const
Definition: MCExpr.h:151
virtual MCContext & getContext()=0
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:406
Streaming machine code generation interface.
Definition: MCStreamer.h:181
static HexagonMCExpr * create(MCExpr const *Expr, MCContext &Ctx)
MCTargetStreamer * getTargetStreamer()
Definition: MCStreamer.h:248
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:959
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:223
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:854
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:177
std::string & str()
Flushes the stream contents to the target string and returns the string&#39;s reference.
Definition: raw_ostream.h:478
#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:531
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:89
void setOpcode(unsigned Op)
Definition: MCInst.h:171
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
void UnLex(AsmToken const &Token)
Definition: MCAsmLexer.h:205
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:862
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:180
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:193
const AsmToken & Lex()
Consume the next token from the input stream and return it.
Definition: MCAsmLexer.h:191
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: MCAsmLexer.h:88
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:431
Base class for user error types.
Definition: Error.h:331
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:480
static MCOperand createInst(const MCInst *Val)
Definition: MCInst.h:144
#define Success
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:120
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
void emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:654
MCExpr const & getExpr(MCExpr const &Expr)
.type _foo,
Definition: MCDirectives.h:30
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1, MCOperand &MO2)
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
MCSubtargetInfo - 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:462
bool PopSection()
Restore the current and previous section from the section stack.
Definition: MCStreamer.h:359
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:44
#define DEBUG(X)
Definition: Debug.h:118
void addOperand(const MCOperand &Op)
Definition: MCInst.h:184
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:172
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:385
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:159
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:95
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
Definition: SourceMgr.h:233
TokenKind getKind() const
Definition: MCAsmLexer.h:87
void setExpr(const MCExpr *Val)
Definition: MCInst.h:101