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