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