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