LLVM  14.0.0git
PPCAsmParser.cpp
Go to the documentation of this file.
1 //===-- PPCAsmParser.cpp - Parse PowerPC 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 
11 #include "PPCTargetStreamer.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSymbolELF.h"
26 #include "llvm/Support/SourceMgr.h"
29 
30 using namespace llvm;
31 
33 
34 // Evaluate an expression containing condition register
35 // or condition register field symbols. Returns positive
36 // value on success, or -1 on error.
37 static int64_t
39  switch (E->getKind()) {
40  case MCExpr::Target:
41  return -1;
42 
43  case MCExpr::Constant: {
44  int64_t Res = cast<MCConstantExpr>(E)->getValue();
45  return Res < 0 ? -1 : Res;
46  }
47 
48  case MCExpr::SymbolRef: {
49  const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
50  StringRef Name = SRE->getSymbol().getName();
51 
52  if (Name == "lt") return 0;
53  if (Name == "gt") return 1;
54  if (Name == "eq") return 2;
55  if (Name == "so") return 3;
56  if (Name == "un") return 3;
57 
58  if (Name == "cr0") return 0;
59  if (Name == "cr1") return 1;
60  if (Name == "cr2") return 2;
61  if (Name == "cr3") return 3;
62  if (Name == "cr4") return 4;
63  if (Name == "cr5") return 5;
64  if (Name == "cr6") return 6;
65  if (Name == "cr7") return 7;
66 
67  return -1;
68  }
69 
70  case MCExpr::Unary:
71  return -1;
72 
73  case MCExpr::Binary: {
74  const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
75  int64_t LHSVal = EvaluateCRExpr(BE->getLHS());
76  int64_t RHSVal = EvaluateCRExpr(BE->getRHS());
77  int64_t Res;
78 
79  if (LHSVal < 0 || RHSVal < 0)
80  return -1;
81 
82  switch (BE->getOpcode()) {
83  default: return -1;
84  case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;
85  case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;
86  }
87 
88  return Res < 0 ? -1 : Res;
89  }
90  }
91 
92  llvm_unreachable("Invalid expression kind!");
93 }
94 
95 namespace {
96 
97 struct PPCOperand;
98 
99 class PPCAsmParser : public MCTargetAsmParser {
100  bool IsPPC64;
101 
102  void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
103 
104  bool isPPC64() const { return IsPPC64; }
105 
106  bool MatchRegisterName(unsigned &RegNo, int64_t &IntVal);
107 
108  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
109  OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
110  SMLoc &EndLoc) override;
111 
112  const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
113  PPCMCExpr::VariantKind &Variant);
114  const MCExpr *FixupVariantKind(const MCExpr *E);
115  bool ParseExpression(const MCExpr *&EVal);
116 
117  bool ParseOperand(OperandVector &Operands);
118 
119  bool ParseDirectiveWord(unsigned Size, AsmToken ID);
120  bool ParseDirectiveTC(unsigned Size, AsmToken ID);
121  bool ParseDirectiveMachine(SMLoc L);
122  bool ParseDirectiveAbiVersion(SMLoc L);
123  bool ParseDirectiveLocalEntry(SMLoc L);
124 
125  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
128  bool MatchingInlineAsm) override;
129 
130  void ProcessInstruction(MCInst &Inst, const OperandVector &Ops);
131 
132  /// @name Auto-generated Match Functions
133  /// {
134 
135 #define GET_ASSEMBLER_HEADER
136 #include "PPCGenAsmMatcher.inc"
137 
138  /// }
139 
140 
141 public:
142  PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &,
143  const MCInstrInfo &MII, const MCTargetOptions &Options)
144  : MCTargetAsmParser(Options, STI, MII) {
145  // Check for 64-bit vs. 32-bit pointer mode.
146  const Triple &TheTriple = STI.getTargetTriple();
147  IsPPC64 = TheTriple.isPPC64();
148  // Initialize the set of available features.
149  setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
150  }
151 
152  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
153  SMLoc NameLoc, OperandVector &Operands) override;
154 
155  bool ParseDirective(AsmToken DirectiveID) override;
156 
157  unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
158  unsigned Kind) override;
159 
160  const MCExpr *applyModifierToExpr(const MCExpr *E,
162  MCContext &Ctx) override;
163 };
164 
165 /// PPCOperand - Instances of this class represent a parsed PowerPC machine
166 /// instruction.
167 struct PPCOperand : public MCParsedAsmOperand {
168  enum KindTy {
169  Token,
170  Immediate,
171  ContextImmediate,
172  Expression,
173  TLSRegister
174  } Kind;
175 
176  SMLoc StartLoc, EndLoc;
177  bool IsPPC64;
178 
179  struct TokOp {
180  const char *Data;
181  unsigned Length;
182  };
183 
184  struct ImmOp {
185  int64_t Val;
186  };
187 
188  struct ExprOp {
189  const MCExpr *Val;
190  int64_t CRVal; // Cached result of EvaluateCRExpr(Val)
191  };
192 
193  struct TLSRegOp {
194  const MCSymbolRefExpr *Sym;
195  };
196 
197  union {
198  struct TokOp Tok;
199  struct ImmOp Imm;
200  struct ExprOp Expr;
201  struct TLSRegOp TLSReg;
202  };
203 
204  PPCOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
205 public:
206  PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() {
207  Kind = o.Kind;
208  StartLoc = o.StartLoc;
209  EndLoc = o.EndLoc;
210  IsPPC64 = o.IsPPC64;
211  switch (Kind) {
212  case Token:
213  Tok = o.Tok;
214  break;
215  case Immediate:
216  case ContextImmediate:
217  Imm = o.Imm;
218  break;
219  case Expression:
220  Expr = o.Expr;
221  break;
222  case TLSRegister:
223  TLSReg = o.TLSReg;
224  break;
225  }
226  }
227 
228  // Disable use of sized deallocation due to overallocation of PPCOperand
229  // objects in CreateTokenWithStringCopy.
230  void operator delete(void *p) { ::operator delete(p); }
231 
232  /// getStartLoc - Get the location of the first token of this operand.
233  SMLoc getStartLoc() const override { return StartLoc; }
234 
235  /// getEndLoc - Get the location of the last token of this operand.
236  SMLoc getEndLoc() const override { return EndLoc; }
237 
238  /// getLocRange - Get the range between the first and last token of this
239  /// operand.
240  SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
241 
242  /// isPPC64 - True if this operand is for an instruction in 64-bit mode.
243  bool isPPC64() const { return IsPPC64; }
244 
245  int64_t getImm() const {
246  assert(Kind == Immediate && "Invalid access!");
247  return Imm.Val;
248  }
249  int64_t getImmS16Context() const {
250  assert((Kind == Immediate || Kind == ContextImmediate) &&
251  "Invalid access!");
252  if (Kind == Immediate)
253  return Imm.Val;
254  return static_cast<int16_t>(Imm.Val);
255  }
256  int64_t getImmU16Context() const {
257  assert((Kind == Immediate || Kind == ContextImmediate) &&
258  "Invalid access!");
259  return Imm.Val;
260  }
261 
262  const MCExpr *getExpr() const {
263  assert(Kind == Expression && "Invalid access!");
264  return Expr.Val;
265  }
266 
267  int64_t getExprCRVal() const {
268  assert(Kind == Expression && "Invalid access!");
269  return Expr.CRVal;
270  }
271 
272  const MCExpr *getTLSReg() const {
273  assert(Kind == TLSRegister && "Invalid access!");
274  return TLSReg.Sym;
275  }
276 
277  unsigned getReg() const override {
278  assert(isRegNumber() && "Invalid access!");
279  return (unsigned) Imm.Val;
280  }
281 
282  unsigned getVSReg() const {
283  assert(isVSRegNumber() && "Invalid access!");
284  return (unsigned) Imm.Val;
285  }
286 
287  unsigned getACCReg() const {
288  assert(isACCRegNumber() && "Invalid access!");
289  return (unsigned) Imm.Val;
290  }
291 
292  unsigned getVSRpEvenReg() const {
293  assert(isVSRpEvenRegNumber() && "Invalid access!");
294  return (unsigned) Imm.Val >> 1;
295  }
296 
297  unsigned getG8pReg() const {
298  assert(isEvenRegNumber() && "Invalid access!");
299  return (unsigned)Imm.Val;
300  }
301 
302  unsigned getCCReg() const {
303  assert(isCCRegNumber() && "Invalid access!");
304  return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
305  }
306 
307  unsigned getCRBit() const {
308  assert(isCRBitNumber() && "Invalid access!");
309  return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
310  }
311 
312  unsigned getCRBitMask() const {
313  assert(isCRBitMask() && "Invalid access!");
314  return 7 - countTrailingZeros<uint64_t>(Imm.Val);
315  }
316 
317  bool isToken() const override { return Kind == Token; }
318  bool isImm() const override {
319  return Kind == Immediate || Kind == Expression;
320  }
321  bool isU1Imm() const { return Kind == Immediate && isUInt<1>(getImm()); }
322  bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); }
323  bool isU3Imm() const { return Kind == Immediate && isUInt<3>(getImm()); }
324  bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); }
325  bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
326  bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }
327  bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); }
328  bool isU6ImmX2() const { return Kind == Immediate &&
329  isUInt<6>(getImm()) &&
330  (getImm() & 1) == 0; }
331  bool isU7Imm() const { return Kind == Immediate && isUInt<7>(getImm()); }
332  bool isU7ImmX4() const { return Kind == Immediate &&
333  isUInt<7>(getImm()) &&
334  (getImm() & 3) == 0; }
335  bool isU8Imm() const { return Kind == Immediate && isUInt<8>(getImm()); }
336  bool isU8ImmX8() const { return Kind == Immediate &&
337  isUInt<8>(getImm()) &&
338  (getImm() & 7) == 0; }
339 
340  bool isU10Imm() const { return Kind == Immediate && isUInt<10>(getImm()); }
341  bool isU12Imm() const { return Kind == Immediate && isUInt<12>(getImm()); }
342  bool isU16Imm() const {
343  switch (Kind) {
344  case Expression:
345  return true;
346  case Immediate:
347  case ContextImmediate:
348  return isUInt<16>(getImmU16Context());
349  default:
350  return false;
351  }
352  }
353  bool isS16Imm() const {
354  switch (Kind) {
355  case Expression:
356  return true;
357  case Immediate:
358  case ContextImmediate:
359  return isInt<16>(getImmS16Context());
360  default:
361  return false;
362  }
363  }
364  bool isS16ImmX4() const { return Kind == Expression ||
365  (Kind == Immediate && isInt<16>(getImm()) &&
366  (getImm() & 3) == 0); }
367 
368  bool isHashImmX8() const {
369  // The Hash Imm form is used for instructions that check or store a hash.
370  // These instructions have a small immediate range that spans between
371  // -8 and -512.
372  return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&
373  (getImm() & 7) == 0);
374  }
375 
376  bool isS16ImmX16() const { return Kind == Expression ||
377  (Kind == Immediate && isInt<16>(getImm()) &&
378  (getImm() & 15) == 0); }
379  bool isS34ImmX16() const {
380  return Kind == Expression ||
381  (Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
382  }
383  bool isS34Imm() const {
384  // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
385  // ContextImmediate is needed.
386  return Kind == Expression || (Kind == Immediate && isInt<34>(getImm()));
387  }
388 
389  bool isS17Imm() const {
390  switch (Kind) {
391  case Expression:
392  return true;
393  case Immediate:
394  case ContextImmediate:
395  return isInt<17>(getImmS16Context());
396  default:
397  return false;
398  }
399  }
400  bool isTLSReg() const { return Kind == TLSRegister; }
401  bool isDirectBr() const {
402  if (Kind == Expression)
403  return true;
404  if (Kind != Immediate)
405  return false;
406  // Operand must be 64-bit aligned, signed 27-bit immediate.
407  if ((getImm() & 3) != 0)
408  return false;
409  if (isInt<26>(getImm()))
410  return true;
411  if (!IsPPC64) {
412  // In 32-bit mode, large 32-bit quantities wrap around.
413  if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))
414  return true;
415  }
416  return false;
417  }
418  bool isCondBr() const { return Kind == Expression ||
419  (Kind == Immediate && isInt<16>(getImm()) &&
420  (getImm() & 3) == 0); }
421  bool isImmZero() const { return Kind == Immediate && getImm() == 0; }
422  bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
423  bool isACCRegNumber() const {
424  return Kind == Immediate && isUInt<3>(getImm());
425  }
426  bool isVSRpEvenRegNumber() const {
427  return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
428  }
429  bool isVSRegNumber() const {
430  return Kind == Immediate && isUInt<6>(getImm());
431  }
432  bool isCCRegNumber() const { return (Kind == Expression
433  && isUInt<3>(getExprCRVal())) ||
434  (Kind == Immediate
435  && isUInt<3>(getImm())); }
436  bool isCRBitNumber() const { return (Kind == Expression
437  && isUInt<5>(getExprCRVal())) ||
438  (Kind == Immediate
439  && isUInt<5>(getImm())); }
440 
441  bool isEvenRegNumber() const { return isRegNumber() && (getImm() & 1) == 0; }
442 
443  bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) &&
444  isPowerOf2_32(getImm()); }
445  bool isATBitsAsHint() const { return false; }
446  bool isMem() const override { return false; }
447  bool isReg() const override { return false; }
448 
449  void addRegOperands(MCInst &Inst, unsigned N) const {
450  llvm_unreachable("addRegOperands");
451  }
452 
453  void addRegGPRCOperands(MCInst &Inst, unsigned N) const {
454  assert(N == 1 && "Invalid number of operands!");
455  Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
456  }
457 
458  void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {
459  assert(N == 1 && "Invalid number of operands!");
460  Inst.addOperand(MCOperand::createReg(RRegsNoR0[getReg()]));
461  }
462 
463  void addRegG8RCOperands(MCInst &Inst, unsigned N) const {
464  assert(N == 1 && "Invalid number of operands!");
465  Inst.addOperand(MCOperand::createReg(XRegs[getReg()]));
466  }
467 
468  void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {
469  assert(N == 1 && "Invalid number of operands!");
470  Inst.addOperand(MCOperand::createReg(XRegsNoX0[getReg()]));
471  }
472 
473  void addRegG8pRCOperands(MCInst &Inst, unsigned N) const {
474  assert(N == 1 && "Invalid number of operands!");
475  Inst.addOperand(MCOperand::createReg(XRegs[getG8pReg()]));
476  }
477 
478  void addRegGxRCOperands(MCInst &Inst, unsigned N) const {
479  if (isPPC64())
480  addRegG8RCOperands(Inst, N);
481  else
482  addRegGPRCOperands(Inst, N);
483  }
484 
485  void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {
486  if (isPPC64())
487  addRegG8RCNoX0Operands(Inst, N);
488  else
489  addRegGPRCNoR0Operands(Inst, N);
490  }
491 
492  void addRegF4RCOperands(MCInst &Inst, unsigned N) const {
493  assert(N == 1 && "Invalid number of operands!");
494  Inst.addOperand(MCOperand::createReg(FRegs[getReg()]));
495  }
496 
497  void addRegF8RCOperands(MCInst &Inst, unsigned N) const {
498  assert(N == 1 && "Invalid number of operands!");
499  Inst.addOperand(MCOperand::createReg(FRegs[getReg()]));
500  }
501 
502  void addRegVFRCOperands(MCInst &Inst, unsigned N) const {
503  assert(N == 1 && "Invalid number of operands!");
504  Inst.addOperand(MCOperand::createReg(VFRegs[getReg()]));
505  }
506 
507  void addRegVRRCOperands(MCInst &Inst, unsigned N) const {
508  assert(N == 1 && "Invalid number of operands!");
509  Inst.addOperand(MCOperand::createReg(VRegs[getReg()]));
510  }
511 
512  void addRegVSRCOperands(MCInst &Inst, unsigned N) const {
513  assert(N == 1 && "Invalid number of operands!");
514  Inst.addOperand(MCOperand::createReg(VSRegs[getVSReg()]));
515  }
516 
517  void addRegVSFRCOperands(MCInst &Inst, unsigned N) const {
518  assert(N == 1 && "Invalid number of operands!");
519  Inst.addOperand(MCOperand::createReg(VSFRegs[getVSReg()]));
520  }
521 
522  void addRegVSSRCOperands(MCInst &Inst, unsigned N) const {
523  assert(N == 1 && "Invalid number of operands!");
524  Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()]));
525  }
526 
527  void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {
528  assert(N == 1 && "Invalid number of operands!");
529  Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
530  }
531 
532  void addRegSPERCOperands(MCInst &Inst, unsigned N) const {
533  assert(N == 1 && "Invalid number of operands!");
534  Inst.addOperand(MCOperand::createReg(SPERegs[getReg()]));
535  }
536 
537  void addRegACCRCOperands(MCInst &Inst, unsigned N) const {
538  assert(N == 1 && "Invalid number of operands!");
539  Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()]));
540  }
541 
542  void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {
543  assert(N == 1 && "Invalid number of operands!");
544  Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
545  }
546 
547  void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const {
548  assert(N == 1 && "Invalid number of operands!");
549  Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
550  }
551 
552  void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
553  assert(N == 1 && "Invalid number of operands!");
554  Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));
555  }
556 
557  void addRegCRRCOperands(MCInst &Inst, unsigned N) const {
558  assert(N == 1 && "Invalid number of operands!");
559  Inst.addOperand(MCOperand::createReg(CRRegs[getCCReg()]));
560  }
561 
562  void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {
563  assert(N == 1 && "Invalid number of operands!");
564  Inst.addOperand(MCOperand::createReg(CRRegs[getCRBitMask()]));
565  }
566 
567  void addImmOperands(MCInst &Inst, unsigned N) const {
568  assert(N == 1 && "Invalid number of operands!");
569  if (Kind == Immediate)
570  Inst.addOperand(MCOperand::createImm(getImm()));
571  else
573  }
574 
575  void addS16ImmOperands(MCInst &Inst, unsigned N) const {
576  assert(N == 1 && "Invalid number of operands!");
577  switch (Kind) {
578  case Immediate:
579  Inst.addOperand(MCOperand::createImm(getImm()));
580  break;
581  case ContextImmediate:
582  Inst.addOperand(MCOperand::createImm(getImmS16Context()));
583  break;
584  default:
586  break;
587  }
588  }
589 
590  void addU16ImmOperands(MCInst &Inst, unsigned N) const {
591  assert(N == 1 && "Invalid number of operands!");
592  switch (Kind) {
593  case Immediate:
594  Inst.addOperand(MCOperand::createImm(getImm()));
595  break;
596  case ContextImmediate:
597  Inst.addOperand(MCOperand::createImm(getImmU16Context()));
598  break;
599  default:
601  break;
602  }
603  }
604 
605  void addBranchTargetOperands(MCInst &Inst, unsigned N) const {
606  assert(N == 1 && "Invalid number of operands!");
607  if (Kind == Immediate)
608  Inst.addOperand(MCOperand::createImm(getImm() / 4));
609  else
611  }
612 
613  void addTLSRegOperands(MCInst &Inst, unsigned N) const {
614  assert(N == 1 && "Invalid number of operands!");
615  Inst.addOperand(MCOperand::createExpr(getTLSReg()));
616  }
617 
618  StringRef getToken() const {
619  assert(Kind == Token && "Invalid access!");
620  return StringRef(Tok.Data, Tok.Length);
621  }
622 
623  void print(raw_ostream &OS) const override;
624 
625  static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,
626  bool IsPPC64) {
627  auto Op = std::make_unique<PPCOperand>(Token);
628  Op->Tok.Data = Str.data();
629  Op->Tok.Length = Str.size();
630  Op->StartLoc = S;
631  Op->EndLoc = S;
632  Op->IsPPC64 = IsPPC64;
633  return Op;
634  }
635 
636  static std::unique_ptr<PPCOperand>
637  CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {
638  // Allocate extra memory for the string and copy it.
639  // FIXME: This is incorrect, Operands are owned by unique_ptr with a default
640  // deleter which will destroy them by simply using "delete", not correctly
641  // calling operator delete on this extra memory after calling the dtor
642  // explicitly.
643  void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());
644  std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));
645  Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1);
646  Op->Tok.Length = Str.size();
647  std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size());
648  Op->StartLoc = S;
649  Op->EndLoc = S;
650  Op->IsPPC64 = IsPPC64;
651  return Op;
652  }
653 
654  static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,
655  bool IsPPC64) {
656  auto Op = std::make_unique<PPCOperand>(Immediate);
657  Op->Imm.Val = Val;
658  Op->StartLoc = S;
659  Op->EndLoc = E;
660  Op->IsPPC64 = IsPPC64;
661  return Op;
662  }
663 
664  static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,
665  SMLoc E, bool IsPPC64) {
666  auto Op = std::make_unique<PPCOperand>(Expression);
667  Op->Expr.Val = Val;
668  Op->Expr.CRVal = EvaluateCRExpr(Val);
669  Op->StartLoc = S;
670  Op->EndLoc = E;
671  Op->IsPPC64 = IsPPC64;
672  return Op;
673  }
674 
675  static std::unique_ptr<PPCOperand>
676  CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {
677  auto Op = std::make_unique<PPCOperand>(TLSRegister);
678  Op->TLSReg.Sym = Sym;
679  Op->StartLoc = S;
680  Op->EndLoc = E;
681  Op->IsPPC64 = IsPPC64;
682  return Op;
683  }
684 
685  static std::unique_ptr<PPCOperand>
686  CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
687  auto Op = std::make_unique<PPCOperand>(ContextImmediate);
688  Op->Imm.Val = Val;
689  Op->StartLoc = S;
690  Op->EndLoc = E;
691  Op->IsPPC64 = IsPPC64;
692  return Op;
693  }
694 
695  static std::unique_ptr<PPCOperand>
696  CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {
697  if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
698  return CreateImm(CE->getValue(), S, E, IsPPC64);
699 
700  if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
701  if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS ||
702  SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL)
703  return CreateTLSReg(SRE, S, E, IsPPC64);
704 
705  if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
706  int64_t Res;
707  if (TE->evaluateAsConstant(Res))
708  return CreateContextImm(Res, S, E, IsPPC64);
709  }
710 
711  return CreateExpr(Val, S, E, IsPPC64);
712  }
713 };
714 
715 } // end anonymous namespace.
716 
717 void PPCOperand::print(raw_ostream &OS) const {
718  switch (Kind) {
719  case Token:
720  OS << "'" << getToken() << "'";
721  break;
722  case Immediate:
723  case ContextImmediate:
724  OS << getImm();
725  break;
726  case Expression:
727  OS << *getExpr();
728  break;
729  case TLSRegister:
730  OS << *getTLSReg();
731  break;
732  }
733 }
734 
735 static void
737  if (Op.isImm()) {
738  Inst.addOperand(MCOperand::createImm(-Op.getImm()));
739  return;
740  }
741  const MCExpr *Expr = Op.getExpr();
742  if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
743  if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {
744  Inst.addOperand(MCOperand::createExpr(UnExpr->getSubExpr()));
745  return;
746  }
747  } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
748  if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {
749  const MCExpr *NE = MCBinaryExpr::createSub(BinExpr->getRHS(),
750  BinExpr->getLHS(), Ctx);
752  return;
753  }
754  }
756 }
757 
758 void PPCAsmParser::ProcessInstruction(MCInst &Inst,
759  const OperandVector &Operands) {
760  int Opcode = Inst.getOpcode();
761  switch (Opcode) {
762  case PPC::DCBTx:
763  case PPC::DCBTT:
764  case PPC::DCBTSTx:
765  case PPC::DCBTSTT: {
766  MCInst TmpInst;
767  TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
768  PPC::DCBT : PPC::DCBTST);
770  (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
771  TmpInst.addOperand(Inst.getOperand(0));
772  TmpInst.addOperand(Inst.getOperand(1));
773  Inst = TmpInst;
774  break;
775  }
776  case PPC::DCBTCT:
777  case PPC::DCBTDS: {
778  MCInst TmpInst;
779  TmpInst.setOpcode(PPC::DCBT);
780  TmpInst.addOperand(Inst.getOperand(2));
781  TmpInst.addOperand(Inst.getOperand(0));
782  TmpInst.addOperand(Inst.getOperand(1));
783  Inst = TmpInst;
784  break;
785  }
786  case PPC::DCBTSTCT:
787  case PPC::DCBTSTDS: {
788  MCInst TmpInst;
789  TmpInst.setOpcode(PPC::DCBTST);
790  TmpInst.addOperand(Inst.getOperand(2));
791  TmpInst.addOperand(Inst.getOperand(0));
792  TmpInst.addOperand(Inst.getOperand(1));
793  Inst = TmpInst;
794  break;
795  }
796  case PPC::DCBFx:
797  case PPC::DCBFL:
798  case PPC::DCBFLP:
799  case PPC::DCBFPS:
800  case PPC::DCBSTPS: {
801  int L = 0;
802  if (Opcode == PPC::DCBFL)
803  L = 1;
804  else if (Opcode == PPC::DCBFLP)
805  L = 3;
806  else if (Opcode == PPC::DCBFPS)
807  L = 4;
808  else if (Opcode == PPC::DCBSTPS)
809  L = 6;
810 
811  MCInst TmpInst;
812  TmpInst.setOpcode(PPC::DCBF);
813  TmpInst.addOperand(MCOperand::createImm(L));
814  TmpInst.addOperand(Inst.getOperand(0));
815  TmpInst.addOperand(Inst.getOperand(1));
816  Inst = TmpInst;
817  break;
818  }
819  case PPC::LAx: {
820  MCInst TmpInst;
821  TmpInst.setOpcode(PPC::LA);
822  TmpInst.addOperand(Inst.getOperand(0));
823  TmpInst.addOperand(Inst.getOperand(2));
824  TmpInst.addOperand(Inst.getOperand(1));
825  Inst = TmpInst;
826  break;
827  }
828  case PPC::SUBI: {
829  MCInst TmpInst;
830  TmpInst.setOpcode(PPC::ADDI);
831  TmpInst.addOperand(Inst.getOperand(0));
832  TmpInst.addOperand(Inst.getOperand(1));
833  addNegOperand(TmpInst, Inst.getOperand(2), getContext());
834  Inst = TmpInst;
835  break;
836  }
837  case PPC::SUBIS: {
838  MCInst TmpInst;
839  TmpInst.setOpcode(PPC::ADDIS);
840  TmpInst.addOperand(Inst.getOperand(0));
841  TmpInst.addOperand(Inst.getOperand(1));
842  addNegOperand(TmpInst, Inst.getOperand(2), getContext());
843  Inst = TmpInst;
844  break;
845  }
846  case PPC::SUBIC: {
847  MCInst TmpInst;
848  TmpInst.setOpcode(PPC::ADDIC);
849  TmpInst.addOperand(Inst.getOperand(0));
850  TmpInst.addOperand(Inst.getOperand(1));
851  addNegOperand(TmpInst, Inst.getOperand(2), getContext());
852  Inst = TmpInst;
853  break;
854  }
855  case PPC::SUBIC_rec: {
856  MCInst TmpInst;
857  TmpInst.setOpcode(PPC::ADDIC_rec);
858  TmpInst.addOperand(Inst.getOperand(0));
859  TmpInst.addOperand(Inst.getOperand(1));
860  addNegOperand(TmpInst, Inst.getOperand(2), getContext());
861  Inst = TmpInst;
862  break;
863  }
864  case PPC::EXTLWI:
865  case PPC::EXTLWI_rec: {
866  MCInst TmpInst;
867  int64_t N = Inst.getOperand(2).getImm();
868  int64_t B = Inst.getOperand(3).getImm();
869  TmpInst.setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
870  TmpInst.addOperand(Inst.getOperand(0));
871  TmpInst.addOperand(Inst.getOperand(1));
873  TmpInst.addOperand(MCOperand::createImm(0));
874  TmpInst.addOperand(MCOperand::createImm(N - 1));
875  Inst = TmpInst;
876  break;
877  }
878  case PPC::EXTRWI:
879  case PPC::EXTRWI_rec: {
880  MCInst TmpInst;
881  int64_t N = Inst.getOperand(2).getImm();
882  int64_t B = Inst.getOperand(3).getImm();
883  TmpInst.setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
884  TmpInst.addOperand(Inst.getOperand(0));
885  TmpInst.addOperand(Inst.getOperand(1));
886  TmpInst.addOperand(MCOperand::createImm(B + N));
887  TmpInst.addOperand(MCOperand::createImm(32 - N));
888  TmpInst.addOperand(MCOperand::createImm(31));
889  Inst = TmpInst;
890  break;
891  }
892  case PPC::INSLWI:
893  case PPC::INSLWI_rec: {
894  MCInst TmpInst;
895  int64_t N = Inst.getOperand(2).getImm();
896  int64_t B = Inst.getOperand(3).getImm();
897  TmpInst.setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
898  TmpInst.addOperand(Inst.getOperand(0));
899  TmpInst.addOperand(Inst.getOperand(0));
900  TmpInst.addOperand(Inst.getOperand(1));
901  TmpInst.addOperand(MCOperand::createImm(32 - B));
903  TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
904  Inst = TmpInst;
905  break;
906  }
907  case PPC::INSRWI:
908  case PPC::INSRWI_rec: {
909  MCInst TmpInst;
910  int64_t N = Inst.getOperand(2).getImm();
911  int64_t B = Inst.getOperand(3).getImm();
912  TmpInst.setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
913  TmpInst.addOperand(Inst.getOperand(0));
914  TmpInst.addOperand(Inst.getOperand(0));
915  TmpInst.addOperand(Inst.getOperand(1));
916  TmpInst.addOperand(MCOperand::createImm(32 - (B + N)));
918  TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
919  Inst = TmpInst;
920  break;
921  }
922  case PPC::ROTRWI:
923  case PPC::ROTRWI_rec: {
924  MCInst TmpInst;
925  int64_t N = Inst.getOperand(2).getImm();
926  TmpInst.setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
927  TmpInst.addOperand(Inst.getOperand(0));
928  TmpInst.addOperand(Inst.getOperand(1));
929  TmpInst.addOperand(MCOperand::createImm(32 - N));
930  TmpInst.addOperand(MCOperand::createImm(0));
931  TmpInst.addOperand(MCOperand::createImm(31));
932  Inst = TmpInst;
933  break;
934  }
935  case PPC::SLWI:
936  case PPC::SLWI_rec: {
937  MCInst TmpInst;
938  int64_t N = Inst.getOperand(2).getImm();
939  TmpInst.setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
940  TmpInst.addOperand(Inst.getOperand(0));
941  TmpInst.addOperand(Inst.getOperand(1));
943  TmpInst.addOperand(MCOperand::createImm(0));
944  TmpInst.addOperand(MCOperand::createImm(31 - N));
945  Inst = TmpInst;
946  break;
947  }
948  case PPC::SRWI:
949  case PPC::SRWI_rec: {
950  MCInst TmpInst;
951  int64_t N = Inst.getOperand(2).getImm();
952  TmpInst.setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
953  TmpInst.addOperand(Inst.getOperand(0));
954  TmpInst.addOperand(Inst.getOperand(1));
955  TmpInst.addOperand(MCOperand::createImm(32 - N));
957  TmpInst.addOperand(MCOperand::createImm(31));
958  Inst = TmpInst;
959  break;
960  }
961  case PPC::CLRRWI:
962  case PPC::CLRRWI_rec: {
963  MCInst TmpInst;
964  int64_t N = Inst.getOperand(2).getImm();
965  TmpInst.setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
966  TmpInst.addOperand(Inst.getOperand(0));
967  TmpInst.addOperand(Inst.getOperand(1));
968  TmpInst.addOperand(MCOperand::createImm(0));
969  TmpInst.addOperand(MCOperand::createImm(0));
970  TmpInst.addOperand(MCOperand::createImm(31 - N));
971  Inst = TmpInst;
972  break;
973  }
974  case PPC::CLRLSLWI:
975  case PPC::CLRLSLWI_rec: {
976  MCInst TmpInst;
977  int64_t B = Inst.getOperand(2).getImm();
978  int64_t N = Inst.getOperand(3).getImm();
979  TmpInst.setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
980  TmpInst.addOperand(Inst.getOperand(0));
981  TmpInst.addOperand(Inst.getOperand(1));
983  TmpInst.addOperand(MCOperand::createImm(B - N));
984  TmpInst.addOperand(MCOperand::createImm(31 - N));
985  Inst = TmpInst;
986  break;
987  }
988  case PPC::EXTLDI:
989  case PPC::EXTLDI_rec: {
990  MCInst TmpInst;
991  int64_t N = Inst.getOperand(2).getImm();
992  int64_t B = Inst.getOperand(3).getImm();
993  TmpInst.setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
994  TmpInst.addOperand(Inst.getOperand(0));
995  TmpInst.addOperand(Inst.getOperand(1));
997  TmpInst.addOperand(MCOperand::createImm(N - 1));
998  Inst = TmpInst;
999  break;
1000  }
1001  case PPC::EXTRDI:
1002  case PPC::EXTRDI_rec: {
1003  MCInst TmpInst;
1004  int64_t N = Inst.getOperand(2).getImm();
1005  int64_t B = Inst.getOperand(3).getImm();
1006  TmpInst.setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1007  TmpInst.addOperand(Inst.getOperand(0));
1008  TmpInst.addOperand(Inst.getOperand(1));
1009  TmpInst.addOperand(MCOperand::createImm(B + N));
1010  TmpInst.addOperand(MCOperand::createImm(64 - N));
1011  Inst = TmpInst;
1012  break;
1013  }
1014  case PPC::INSRDI:
1015  case PPC::INSRDI_rec: {
1016  MCInst TmpInst;
1017  int64_t N = Inst.getOperand(2).getImm();
1018  int64_t B = Inst.getOperand(3).getImm();
1019  TmpInst.setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
1020  TmpInst.addOperand(Inst.getOperand(0));
1021  TmpInst.addOperand(Inst.getOperand(0));
1022  TmpInst.addOperand(Inst.getOperand(1));
1023  TmpInst.addOperand(MCOperand::createImm(64 - (B + N)));
1024  TmpInst.addOperand(MCOperand::createImm(B));
1025  Inst = TmpInst;
1026  break;
1027  }
1028  case PPC::ROTRDI:
1029  case PPC::ROTRDI_rec: {
1030  MCInst TmpInst;
1031  int64_t N = Inst.getOperand(2).getImm();
1032  TmpInst.setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1033  TmpInst.addOperand(Inst.getOperand(0));
1034  TmpInst.addOperand(Inst.getOperand(1));
1035  TmpInst.addOperand(MCOperand::createImm(64 - N));
1036  TmpInst.addOperand(MCOperand::createImm(0));
1037  Inst = TmpInst;
1038  break;
1039  }
1040  case PPC::SLDI:
1041  case PPC::SLDI_rec: {
1042  MCInst TmpInst;
1043  int64_t N = Inst.getOperand(2).getImm();
1044  TmpInst.setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1045  TmpInst.addOperand(Inst.getOperand(0));
1046  TmpInst.addOperand(Inst.getOperand(1));
1047  TmpInst.addOperand(MCOperand::createImm(N));
1048  TmpInst.addOperand(MCOperand::createImm(63 - N));
1049  Inst = TmpInst;
1050  break;
1051  }
1052  case PPC::SUBPCIS: {
1053  MCInst TmpInst;
1054  int64_t N = Inst.getOperand(1).getImm();
1055  TmpInst.setOpcode(PPC::ADDPCIS);
1056  TmpInst.addOperand(Inst.getOperand(0));
1057  TmpInst.addOperand(MCOperand::createImm(-N));
1058  Inst = TmpInst;
1059  break;
1060  }
1061  case PPC::SRDI:
1062  case PPC::SRDI_rec: {
1063  MCInst TmpInst;
1064  int64_t N = Inst.getOperand(2).getImm();
1065  TmpInst.setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1066  TmpInst.addOperand(Inst.getOperand(0));
1067  TmpInst.addOperand(Inst.getOperand(1));
1068  TmpInst.addOperand(MCOperand::createImm(64 - N));
1069  TmpInst.addOperand(MCOperand::createImm(N));
1070  Inst = TmpInst;
1071  break;
1072  }
1073  case PPC::CLRRDI:
1074  case PPC::CLRRDI_rec: {
1075  MCInst TmpInst;
1076  int64_t N = Inst.getOperand(2).getImm();
1077  TmpInst.setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
1078  TmpInst.addOperand(Inst.getOperand(0));
1079  TmpInst.addOperand(Inst.getOperand(1));
1080  TmpInst.addOperand(MCOperand::createImm(0));
1081  TmpInst.addOperand(MCOperand::createImm(63 - N));
1082  Inst = TmpInst;
1083  break;
1084  }
1085  case PPC::CLRLSLDI:
1086  case PPC::CLRLSLDI_rec: {
1087  MCInst TmpInst;
1088  int64_t B = Inst.getOperand(2).getImm();
1089  int64_t N = Inst.getOperand(3).getImm();
1090  TmpInst.setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
1091  TmpInst.addOperand(Inst.getOperand(0));
1092  TmpInst.addOperand(Inst.getOperand(1));
1093  TmpInst.addOperand(MCOperand::createImm(N));
1094  TmpInst.addOperand(MCOperand::createImm(B - N));
1095  Inst = TmpInst;
1096  break;
1097  }
1098  case PPC::RLWINMbm:
1099  case PPC::RLWINMbm_rec: {
1100  unsigned MB, ME;
1101  int64_t BM = Inst.getOperand(3).getImm();
1102  if (!isRunOfOnes(BM, MB, ME))
1103  break;
1104 
1105  MCInst TmpInst;
1106  TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
1107  TmpInst.addOperand(Inst.getOperand(0));
1108  TmpInst.addOperand(Inst.getOperand(1));
1109  TmpInst.addOperand(Inst.getOperand(2));
1110  TmpInst.addOperand(MCOperand::createImm(MB));
1111  TmpInst.addOperand(MCOperand::createImm(ME));
1112  Inst = TmpInst;
1113  break;
1114  }
1115  case PPC::RLWIMIbm:
1116  case PPC::RLWIMIbm_rec: {
1117  unsigned MB, ME;
1118  int64_t BM = Inst.getOperand(3).getImm();
1119  if (!isRunOfOnes(BM, MB, ME))
1120  break;
1121 
1122  MCInst TmpInst;
1123  TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
1124  TmpInst.addOperand(Inst.getOperand(0));
1125  TmpInst.addOperand(Inst.getOperand(0)); // The tied operand.
1126  TmpInst.addOperand(Inst.getOperand(1));
1127  TmpInst.addOperand(Inst.getOperand(2));
1128  TmpInst.addOperand(MCOperand::createImm(MB));
1129  TmpInst.addOperand(MCOperand::createImm(ME));
1130  Inst = TmpInst;
1131  break;
1132  }
1133  case PPC::RLWNMbm:
1134  case PPC::RLWNMbm_rec: {
1135  unsigned MB, ME;
1136  int64_t BM = Inst.getOperand(3).getImm();
1137  if (!isRunOfOnes(BM, MB, ME))
1138  break;
1139 
1140  MCInst TmpInst;
1141  TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
1142  TmpInst.addOperand(Inst.getOperand(0));
1143  TmpInst.addOperand(Inst.getOperand(1));
1144  TmpInst.addOperand(Inst.getOperand(2));
1145  TmpInst.addOperand(MCOperand::createImm(MB));
1146  TmpInst.addOperand(MCOperand::createImm(ME));
1147  Inst = TmpInst;
1148  break;
1149  }
1150  case PPC::MFTB: {
1151  if (getSTI().getFeatureBits()[PPC::FeatureMFTB]) {
1152  assert(Inst.getNumOperands() == 2 && "Expecting two operands");
1153  Inst.setOpcode(PPC::MFSPR);
1154  }
1155  break;
1156  }
1157  }
1158 }
1159 
1160 static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
1161  unsigned VariantID = 0);
1162 
1163 bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1165  MCStreamer &Out, uint64_t &ErrorInfo,
1166  bool MatchingInlineAsm) {
1167  MCInst Inst;
1168 
1169  switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
1170  case Match_Success:
1171  // Post-process instructions (typically extended mnemonics)
1172  ProcessInstruction(Inst, Operands);
1173  Inst.setLoc(IDLoc);
1174  Out.emitInstruction(Inst, getSTI());
1175  return false;
1176  case Match_MissingFeature:
1177  return Error(IDLoc, "instruction use requires an option to be enabled");
1178  case Match_MnemonicFail: {
1179  FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1180  std::string Suggestion = PPCMnemonicSpellCheck(
1181  ((PPCOperand &)*Operands[0]).getToken(), FBS);
1182  return Error(IDLoc, "invalid instruction" + Suggestion,
1183  ((PPCOperand &)*Operands[0]).getLocRange());
1184  }
1185  case Match_InvalidOperand: {
1186  SMLoc ErrorLoc = IDLoc;
1187  if (ErrorInfo != ~0ULL) {
1188  if (ErrorInfo >= Operands.size())
1189  return Error(IDLoc, "too few operands for instruction");
1190 
1191  ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();
1192  if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1193  }
1194 
1195  return Error(ErrorLoc, "invalid operand for instruction");
1196  }
1197  }
1198 
1199  llvm_unreachable("Implement any new match types added!");
1200 }
1201 
1202 bool PPCAsmParser::MatchRegisterName(unsigned &RegNo, int64_t &IntVal) {
1203  if (getParser().getTok().is(AsmToken::Percent))
1204  getParser().Lex(); // Eat the '%'.
1205 
1206  if (!getParser().getTok().is(AsmToken::Identifier))
1207  return true;
1208 
1209  StringRef Name = getParser().getTok().getString();
1210  if (Name.equals_insensitive("lr")) {
1211  RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
1212  IntVal = 8;
1213  } else if (Name.equals_insensitive("ctr")) {
1214  RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
1215  IntVal = 9;
1216  } else if (Name.equals_insensitive("vrsave")) {
1217  RegNo = PPC::VRSAVE;
1218  IntVal = 256;
1219  } else if (Name.startswith_insensitive("r") &&
1220  !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1221  RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];
1222  } else if (Name.startswith_insensitive("f") &&
1223  !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1224  RegNo = FRegs[IntVal];
1225  } else if (Name.startswith_insensitive("vs") &&
1226  !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
1227  RegNo = VSRegs[IntVal];
1228  } else if (Name.startswith_insensitive("v") &&
1229  !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1230  RegNo = VRegs[IntVal];
1231  } else if (Name.startswith_insensitive("cr") &&
1232  !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
1233  RegNo = CRRegs[IntVal];
1234  } else
1235  return true;
1236  getParser().Lex();
1237  return false;
1238 }
1239 
1240 bool PPCAsmParser::
1241 ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
1242  if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success)
1243  return TokError("invalid register name");
1244  return false;
1245 }
1246 
1247 OperandMatchResultTy PPCAsmParser::tryParseRegister(unsigned &RegNo,
1248  SMLoc &StartLoc,
1249  SMLoc &EndLoc) {
1250  const AsmToken &Tok = getParser().getTok();
1251  StartLoc = Tok.getLoc();
1252  EndLoc = Tok.getEndLoc();
1253  RegNo = 0;
1254  int64_t IntVal;
1255  if (MatchRegisterName(RegNo, IntVal))
1256  return MatchOperand_NoMatch;
1257  return MatchOperand_Success;
1258 }
1259 
1260 /// Extract \code @l/@ha \endcode modifier from expression. Recursively scan
1261 /// the expression and check for VK_PPC_LO/HI/HA
1262 /// symbol variants. If all symbols with modifier use the same
1263 /// variant, return the corresponding PPCMCExpr::VariantKind,
1264 /// and a modified expression using the default symbol variant.
1265 /// Otherwise, return NULL.
1266 const MCExpr *PPCAsmParser::
1267 ExtractModifierFromExpr(const MCExpr *E,
1268  PPCMCExpr::VariantKind &Variant) {
1269  MCContext &Context = getParser().getContext();
1271 
1272  switch (E->getKind()) {
1273  case MCExpr::Target:
1274  case MCExpr::Constant:
1275  return nullptr;
1276 
1277  case MCExpr::SymbolRef: {
1278  const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1279 
1280  switch (SRE->getKind()) {
1283  break;
1286  break;
1289  break;
1292  break;
1295  break;
1298  break;
1301  break;
1304  break;
1307  break;
1308  default:
1309  return nullptr;
1310  }
1311 
1312  return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);
1313  }
1314 
1315  case MCExpr::Unary: {
1316  const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1317  const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant);
1318  if (!Sub)
1319  return nullptr;
1320  return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
1321  }
1322 
1323  case MCExpr::Binary: {
1324  const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1325  PPCMCExpr::VariantKind LHSVariant, RHSVariant;
1326  const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant);
1327  const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant);
1328 
1329  if (!LHS && !RHS)
1330  return nullptr;
1331 
1332  if (!LHS) LHS = BE->getLHS();
1333  if (!RHS) RHS = BE->getRHS();
1334 
1335  if (LHSVariant == PPCMCExpr::VK_PPC_None)
1336  Variant = RHSVariant;
1337  else if (RHSVariant == PPCMCExpr::VK_PPC_None)
1338  Variant = LHSVariant;
1339  else if (LHSVariant == RHSVariant)
1340  Variant = LHSVariant;
1341  else
1342  return nullptr;
1343 
1344  return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
1345  }
1346  }
1347 
1348  llvm_unreachable("Invalid expression kind!");
1349 }
1350 
1351 /// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace
1352 /// them by VK_PPC_TLSGD/VK_PPC_TLSLD. This is necessary to avoid having
1353 /// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT.
1354 /// FIXME: This is a hack.
1355 const MCExpr *PPCAsmParser::
1356 FixupVariantKind(const MCExpr *E) {
1357  MCContext &Context = getParser().getContext();
1358 
1359  switch (E->getKind()) {
1360  case MCExpr::Target:
1361  case MCExpr::Constant:
1362  return E;
1363 
1364  case MCExpr::SymbolRef: {
1365  const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1367 
1368  switch (SRE->getKind()) {
1371  break;
1374  break;
1375  default:
1376  return E;
1377  }
1378  return MCSymbolRefExpr::create(&SRE->getSymbol(), Variant, Context);
1379  }
1380 
1381  case MCExpr::Unary: {
1382  const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1383  const MCExpr *Sub = FixupVariantKind(UE->getSubExpr());
1384  if (Sub == UE->getSubExpr())
1385  return E;
1386  return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
1387  }
1388 
1389  case MCExpr::Binary: {
1390  const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1391  const MCExpr *LHS = FixupVariantKind(BE->getLHS());
1392  const MCExpr *RHS = FixupVariantKind(BE->getRHS());
1393  if (LHS == BE->getLHS() && RHS == BE->getRHS())
1394  return E;
1395  return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
1396  }
1397  }
1398 
1399  llvm_unreachable("Invalid expression kind!");
1400 }
1401 
1402 /// ParseExpression. This differs from the default "parseExpression" in that
1403 /// it handles modifiers.
1404 bool PPCAsmParser::
1405 ParseExpression(const MCExpr *&EVal) {
1406  // (ELF Platforms)
1407  // Handle \code @l/@ha \endcode
1408  if (getParser().parseExpression(EVal))
1409  return true;
1410 
1411  EVal = FixupVariantKind(EVal);
1412 
1414  const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
1415  if (E)
1416  EVal = PPCMCExpr::create(Variant, E, getParser().getContext());
1417 
1418  return false;
1419 }
1420 
1421 /// ParseOperand
1422 /// This handles registers in the form 'NN', '%rNN' for ELF platforms and
1423 /// rNN for MachO.
1424 bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
1425  MCAsmParser &Parser = getParser();
1426  SMLoc S = Parser.getTok().getLoc();
1427  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1428  const MCExpr *EVal;
1429 
1430  // Attempt to parse the next token as an immediate
1431  switch (getLexer().getKind()) {
1432  // Special handling for register names. These are interpreted
1433  // as immediates corresponding to the register number.
1434  case AsmToken::Percent: {
1435  unsigned RegNo;
1436  int64_t IntVal;
1437  if (MatchRegisterName(RegNo, IntVal))
1438  return Error(S, "invalid register name");
1439 
1440  Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
1441  return false;
1442  }
1443  case AsmToken::Identifier:
1444  case AsmToken::LParen:
1445  case AsmToken::Plus:
1446  case AsmToken::Minus:
1447  case AsmToken::Integer:
1448  case AsmToken::Dot:
1449  case AsmToken::Dollar:
1450  case AsmToken::Exclaim:
1451  case AsmToken::Tilde:
1452  if (!ParseExpression(EVal))
1453  break;
1454  // Fall-through
1456  default:
1457  return Error(S, "unknown operand");
1458  }
1459 
1460  // Push the parsed operand into the list of operands
1461  Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));
1462 
1463  // Check whether this is a TLS call expression
1464  bool TLSCall = false;
1465  if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(EVal))
1466  TLSCall = Ref->getSymbol().getName() == "__tls_get_addr";
1467 
1468  if (TLSCall && getLexer().is(AsmToken::LParen)) {
1469  const MCExpr *TLSSym;
1470 
1471  Parser.Lex(); // Eat the '('.
1472  S = Parser.getTok().getLoc();
1473  if (ParseExpression(TLSSym))
1474  return Error(S, "invalid TLS call expression");
1475  if (getLexer().isNot(AsmToken::RParen))
1476  return Error(Parser.getTok().getLoc(), "missing ')'");
1477  E = Parser.getTok().getLoc();
1478  Parser.Lex(); // Eat the ')'.
1479 
1480  Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));
1481  }
1482 
1483  // Otherwise, check for D-form memory operands
1484  if (!TLSCall && getLexer().is(AsmToken::LParen)) {
1485  Parser.Lex(); // Eat the '('.
1486  S = Parser.getTok().getLoc();
1487 
1488  int64_t IntVal;
1489  switch (getLexer().getKind()) {
1490  case AsmToken::Percent: {
1491  unsigned RegNo;
1492  if (MatchRegisterName(RegNo, IntVal))
1493  return Error(S, "invalid register name");
1494  break;
1495  }
1496  case AsmToken::Integer:
1497  if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
1498  IntVal > 31)
1499  return Error(S, "invalid register number");
1500  break;
1501  case AsmToken::Identifier:
1502  default:
1503  return Error(S, "invalid memory operand");
1504  }
1505 
1506  E = Parser.getTok().getLoc();
1507  if (parseToken(AsmToken::RParen, "missing ')'"))
1508  return true;
1509  Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
1510  }
1511 
1512  return false;
1513 }
1514 
1515 /// Parse an instruction mnemonic followed by its operands.
1516 bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1517  SMLoc NameLoc, OperandVector &Operands) {
1518  // The first operand is the token for the instruction name.
1519  // If the next character is a '+' or '-', we need to add it to the
1520  // instruction name, to match what TableGen is doing.
1521  std::string NewOpcode;
1522  if (parseOptionalToken(AsmToken::Plus)) {
1523  NewOpcode = std::string(Name);
1524  NewOpcode += '+';
1525  Name = NewOpcode;
1526  }
1527  if (parseOptionalToken(AsmToken::Minus)) {
1528  NewOpcode = std::string(Name);
1529  NewOpcode += '-';
1530  Name = NewOpcode;
1531  }
1532  // If the instruction ends in a '.', we need to create a separate
1533  // token for it, to match what TableGen is doing.
1534  size_t Dot = Name.find('.');
1535  StringRef Mnemonic = Name.slice(0, Dot);
1536  if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
1537  Operands.push_back(
1538  PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
1539  else
1540  Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
1541  if (Dot != StringRef::npos) {
1542  SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);
1543  StringRef DotStr = Name.slice(Dot, StringRef::npos);
1544  if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
1545  Operands.push_back(
1546  PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
1547  else
1548  Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
1549  }
1550 
1551  // If there are no more operands then finish
1552  if (parseOptionalToken(AsmToken::EndOfStatement))
1553  return false;
1554 
1555  // Parse the first operand
1556  if (ParseOperand(Operands))
1557  return true;
1558 
1559  while (!parseOptionalToken(AsmToken::EndOfStatement)) {
1560  if (parseToken(AsmToken::Comma) || ParseOperand(Operands))
1561  return true;
1562  }
1563 
1564  // We'll now deal with an unfortunate special case: the syntax for the dcbt
1565  // and dcbtst instructions differs for server vs. embedded cores.
1566  // The syntax for dcbt is:
1567  // dcbt ra, rb, th [server]
1568  // dcbt th, ra, rb [embedded]
1569  // where th can be omitted when it is 0. dcbtst is the same. We take the
1570  // server form to be the default, so swap the operands if we're parsing for
1571  // an embedded core (they'll be swapped again upon printing).
1572  if (getSTI().getFeatureBits()[PPC::FeatureBookE] &&
1573  Operands.size() == 4 &&
1574  (Name == "dcbt" || Name == "dcbtst")) {
1575  std::swap(Operands[1], Operands[3]);
1576  std::swap(Operands[2], Operands[1]);
1577  }
1578 
1579  return false;
1580 }
1581 
1582 /// ParseDirective parses the PPC specific directives
1583 bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {
1584  StringRef IDVal = DirectiveID.getIdentifier();
1585  if (IDVal == ".word")
1586  ParseDirectiveWord(2, DirectiveID);
1587  else if (IDVal == ".llong")
1588  ParseDirectiveWord(8, DirectiveID);
1589  else if (IDVal == ".tc")
1590  ParseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);
1591  else if (IDVal == ".machine")
1592  ParseDirectiveMachine(DirectiveID.getLoc());
1593  else if (IDVal == ".abiversion")
1594  ParseDirectiveAbiVersion(DirectiveID.getLoc());
1595  else if (IDVal == ".localentry")
1596  ParseDirectiveLocalEntry(DirectiveID.getLoc());
1597  else
1598  return true;
1599  return false;
1600 }
1601 
1602 /// ParseDirectiveWord
1603 /// ::= .word [ expression (, expression)* ]
1604 bool PPCAsmParser::ParseDirectiveWord(unsigned Size, AsmToken ID) {
1605  auto parseOp = [&]() -> bool {
1606  const MCExpr *Value;
1607  SMLoc ExprLoc = getParser().getTok().getLoc();
1608  if (getParser().parseExpression(Value))
1609  return true;
1610  if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
1611  assert(Size <= 8 && "Invalid size");
1612  uint64_t IntValue = MCE->getValue();
1613  if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
1614  return Error(ExprLoc, "literal value out of range for '" +
1615  ID.getIdentifier() + "' directive");
1616  getStreamer().emitIntValue(IntValue, Size);
1617  } else
1618  getStreamer().emitValue(Value, Size, ExprLoc);
1619  return false;
1620  };
1621 
1622  if (parseMany(parseOp))
1623  return addErrorSuffix(" in '" + ID.getIdentifier() + "' directive");
1624  return false;
1625 }
1626 
1627 /// ParseDirectiveTC
1628 /// ::= .tc [ symbol (, expression)* ]
1629 bool PPCAsmParser::ParseDirectiveTC(unsigned Size, AsmToken ID) {
1630  MCAsmParser &Parser = getParser();
1631  // Skip TC symbol, which is only used with XCOFF.
1632  while (getLexer().isNot(AsmToken::EndOfStatement)
1633  && getLexer().isNot(AsmToken::Comma))
1634  Parser.Lex();
1635  if (parseToken(AsmToken::Comma))
1636  return addErrorSuffix(" in '.tc' directive");
1637 
1638  // Align to word size.
1639  getParser().getStreamer().emitValueToAlignment(Size);
1640 
1641  // Emit expressions.
1642  return ParseDirectiveWord(Size, ID);
1643 }
1644 
1645 /// ParseDirectiveMachine (ELF platforms)
1646 /// ::= .machine [ cpu | "push" | "pop" ]
1647 bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) {
1648  MCAsmParser &Parser = getParser();
1649  if (Parser.getTok().isNot(AsmToken::Identifier) &&
1650  Parser.getTok().isNot(AsmToken::String))
1651  return Error(L, "unexpected token in '.machine' directive");
1652 
1653  StringRef CPU = Parser.getTok().getIdentifier();
1654 
1655  // FIXME: Right now, the parser always allows any available
1656  // instruction, so the .machine directive is not useful.
1657  // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen.
1658 
1659  Parser.Lex();
1660 
1661  if (parseToken(AsmToken::EndOfStatement))
1662  return addErrorSuffix(" in '.machine' directive");
1663 
1664  PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
1665  getParser().getStreamer().getTargetStreamer());
1666  if (TStreamer != nullptr)
1667  TStreamer->emitMachine(CPU);
1668 
1669  return false;
1670 }
1671 
1672 /// ParseDirectiveAbiVersion
1673 /// ::= .abiversion constant-expression
1674 bool PPCAsmParser::ParseDirectiveAbiVersion(SMLoc L) {
1675  int64_t AbiVersion;
1676  if (check(getParser().parseAbsoluteExpression(AbiVersion), L,
1677  "expected constant expression") ||
1678  parseToken(AsmToken::EndOfStatement))
1679  return addErrorSuffix(" in '.abiversion' directive");
1680 
1681  PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
1682  getParser().getStreamer().getTargetStreamer());
1683  if (TStreamer != nullptr)
1684  TStreamer->emitAbiVersion(AbiVersion);
1685 
1686  return false;
1687 }
1688 
1689 /// ParseDirectiveLocalEntry
1690 /// ::= .localentry symbol, expression
1691 bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) {
1692  StringRef Name;
1693  if (getParser().parseIdentifier(Name))
1694  return Error(L, "expected identifier in '.localentry' directive");
1695 
1696  MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
1697  const MCExpr *Expr;
1698 
1699  if (parseToken(AsmToken::Comma) ||
1700  check(getParser().parseExpression(Expr), L, "expected expression") ||
1701  parseToken(AsmToken::EndOfStatement))
1702  return addErrorSuffix(" in '.localentry' directive");
1703 
1704  PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
1705  getParser().getStreamer().getTargetStreamer());
1706  if (TStreamer != nullptr)
1707  TStreamer->emitLocalEntry(Sym, Expr);
1708 
1709  return false;
1710 }
1711 
1712 
1713 
1714 /// Force static initialization.
1720 }
1721 
1722 #define GET_REGISTER_MATCHER
1723 #define GET_MATCHER_IMPLEMENTATION
1724 #define GET_MNEMONIC_SPELL_CHECKER
1725 #include "PPCGenAsmMatcher.inc"
1726 
1727 // Define this matcher function after the auto-generated include so we
1728 // have the match class enum definitions.
1729 unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1730  unsigned Kind) {
1731  // If the kind is a token for a literal immediate, check if our asm
1732  // operand matches. This is for InstAliases which have a fixed-value
1733  // immediate in the syntax.
1734  int64_t ImmVal;
1735  switch (Kind) {
1736  case MCK_0: ImmVal = 0; break;
1737  case MCK_1: ImmVal = 1; break;
1738  case MCK_2: ImmVal = 2; break;
1739  case MCK_3: ImmVal = 3; break;
1740  case MCK_4: ImmVal = 4; break;
1741  case MCK_5: ImmVal = 5; break;
1742  case MCK_6: ImmVal = 6; break;
1743  case MCK_7: ImmVal = 7; break;
1744  default: return Match_InvalidOperand;
1745  }
1746 
1747  PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
1748  if (Op.isImm() && Op.getImm() == ImmVal)
1749  return Match_Success;
1750 
1751  return Match_InvalidOperand;
1752 }
1753 
1754 const MCExpr *
1755 PPCAsmParser::applyModifierToExpr(const MCExpr *E,
1757  MCContext &Ctx) {
1758  switch (Variant) {
1777  default:
1778  return nullptr;
1779  }
1780 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::MCSymbolRefExpr::getKind
VariantKind getKind() const
Definition: MCExpr.h:400
llvm::PPCMCExpr::VK_PPC_HA
@ VK_PPC_HA
Definition: PPCMCExpr.h:24
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
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MCSymbolRefExpr::VK_PPC_HIGHESTA
@ VK_PPC_HIGHESTA
Definition: MCExpr.h:255
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::AArch64CC::NE
@ NE
Definition: AArch64BaseInfo.h:256
llvm::MCOperand::createExpr
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
llvm::MCUnaryExpr::getOpcode
Opcode getOpcode() const
Get the kind of this unary expression.
Definition: MCExpr.h:467
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition: ArchiveWriter.cpp:147
llvm::MCParsedAsmOperand
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Definition: MCParsedAsmOperand.h:24
llvm::MCSymbolRefExpr::VK_PPC_TLSGD
@ VK_PPC_TLSGD
Definition: MCExpr.h:298
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
llvm::AsmToken::Dot
@ Dot
Definition: MCAsmMacro.h:49
llvm::AsmToken::EndOfStatement
@ EndOfStatement
Definition: MCAsmMacro.h:42
llvm::MCSymbolRefExpr::VK_PPC_HIGHA
@ VK_PPC_HIGHA
Definition: MCExpr.h:251
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:60
MCParsedAsmOperand.h
llvm::MCUnaryExpr::createMinus
static const MCUnaryExpr * createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.h:450
llvm::pdb::PDB_BuiltinType::Variant
@ Variant
llvm::MCBinaryExpr::Add
@ Add
Addition.
Definition: MCExpr.h:483
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:45
addNegOperand
static void addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx)
Definition: PPCAsmParser.cpp:736
llvm::MCBinaryExpr::Mul
@ Mul
Multiplication.
Definition: MCExpr.h:498
llvm::PPCMCExpr::VK_PPC_LO
@ VK_PPC_LO
Definition: PPCMCExpr.h:22
llvm::AsmToken::Integer
@ Integer
Definition: MCAsmMacro.h:32
llvm::FeatureBitset
Container class for subtarget features.
Definition: SubtargetFeature.h:40
llvm::PPCMCExpr::VK_PPC_HIGHA
@ VK_PPC_HIGHA
Definition: PPCMCExpr.h:26
STLExtras.h
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::ARM::PredBlockMask::TE
@ TE
llvm::isPowerOf2_32
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:491
llvm::MCBinaryExpr
Binary assembler expressions.
Definition: MCExpr.h:480
PPCMCTargetDesc.h
MCAsmParser.h
llvm::MCInst::getNumOperands
unsigned getNumOperands() const
Definition: MCInst.h:208
llvm::MCUnaryExpr
Unary assembler expressions.
Definition: MCExpr.h:424
MCTargetAsmParser.h
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
p
the resulting code requires compare and branches when and if * p
Definition: README.txt:396
llvm::AsmToken
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:21
llvm::HighlightColor::Warning
@ Warning
llvm::PPCMCExpr
Definition: PPCMCExpr.h:18
llvm::MCInst::setOpcode
void setOpcode(unsigned Op)
Definition: MCInst.h:197
llvm::MCSymbolELF
Definition: MCSymbolELF.h:14
llvm::AsmToken::Minus
@ Minus
Definition: MCAsmMacro.h:45
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::MCSymbolRefExpr::VK_PPC_TLS
@ VK_PPC_TLS
Definition: MCExpr.h:293
llvm::AsmToken::LParen
@ LParen
Definition: MCAsmMacro.h:48
llvm::MCAsmParser::Lex
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
llvm::getThePPC64LETarget
Target & getThePPC64LETarget()
Definition: PowerPCTargetInfo.cpp:25
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:199
llvm::AsmToken::Dollar
@ Dollar
Definition: MCAsmMacro.h:49
llvm::RegisterMCAsmParser
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Definition: TargetRegistry.h:1317
llvm::MatchOperand_Success
@ MatchOperand_Success
Definition: MCTargetAsmParser.h:122
llvm::SMLoc
Represents a location in source code.
Definition: SMLoc.h:23
llvm::ModRefInfo::Ref
@ Ref
The access may reference the value stored in memory.
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MCExpr::Target
@ Target
Target specific expression.
Definition: MCExpr.h:42
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
Twine.h
llvm::MCSubtargetInfo::getTargetTriple
const Triple & getTargetTriple() const
Definition: MCSubtargetInfo.h:107
MCSymbolELF.h
MCContext.h
llvm::PPCMCExpr::VK_PPC_HIGHEST
@ VK_PPC_HIGHEST
Definition: PPCMCExpr.h:29
MCInstrInfo.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
MCInst.h
llvm::MCBinaryExpr::getRHS
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:630
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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
llvm::MCUnaryExpr::create
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.cpp:189
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:111
llvm::PPCMCExpr::VK_PPC_HI
@ VK_PPC_HI
Definition: PPCMCExpr.h:23
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::MCSymbolRefExpr::getSymbol
const MCSymbol & getSymbol() const
Definition: MCExpr.h:398
llvm::MCSymbolRefExpr::VK_TLSLD
@ VK_TLSLD
Definition: MCExpr.h:209
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::MCSymbol::getName
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:198
isNot
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
Definition: AMDGPULegalizerInfo.cpp:2811
llvm::AsmToken::Percent
@ Percent
Definition: MCAsmMacro.h:52
llvm::PPCMCExpr::VK_PPC_HIGHERA
@ VK_PPC_HIGHERA
Definition: PPCMCExpr.h:28
llvm::MCSymbolRefExpr::VK_PPC_HA
@ VK_PPC_HA
Definition: MCExpr.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::MCUnaryExpr::Minus
@ Minus
Unary minus.
Definition: MCExpr.h:428
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
SourceMgr.h
llvm::MCExpr::Binary
@ Binary
Binary expressions.
Definition: MCExpr.h:38
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
Operands
mir Rename Register Operands
Definition: MIRNamerPass.cpp:78
llvm::MCSymbolRefExpr::VK_PPC_HI
@ VK_PPC_HI
Definition: MCExpr.h:248
llvm::MCConstantExpr
Definition: MCExpr.h:144
LLVMInitializePowerPCAsmParser
LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser()
Force static initialization.
Definition: PPCAsmParser.cpp:1715
llvm::PPCMCExpr::VK_PPC_None
@ VK_PPC_None
Definition: PPCMCExpr.h:21
llvm::MCSymbolRefExpr::VK_PPC_TLSLD
@ VK_PPC_TLSLD
Definition: MCExpr.h:310
MCAsmLexer.h
llvm::ParseInstructionInfo
Definition: MCTargetAsmParser.h:113
llvm::isUInt< 16 >
constexpr bool isUInt< 16 >(uint64_t x)
Definition: MathExtras.h:408
llvm::MCSymbolRefExpr::VariantKind
VariantKind
Definition: MCExpr.h:194
PPCMCExpr.h
uint64_t
DEFINE_PPC_REGCLASSES
DEFINE_PPC_REGCLASSES
Definition: PPCAsmParser.cpp:32
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
llvm::MCSymbolRefExpr::VK_PPC_TLS_PCREL
@ VK_PPC_TLS_PCREL
Definition: MCExpr.h:309
llvm::MCStreamer::emitInstruction
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition: MCStreamer.cpp:1087
PowerPCTargetInfo.h
llvm::MCBinaryExpr::create
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.cpp:183
llvm::AsmToken::Exclaim
@ Exclaim
Definition: MCAsmMacro.h:52
llvm::isUInt< 32 >
constexpr bool isUInt< 32 >(uint64_t x)
Definition: MathExtras.h:411
llvm::MCSymbolRefExpr::VK_PPC_HIGHEST
@ VK_PPC_HIGHEST
Definition: MCExpr.h:254
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::isUInt< 8 >
constexpr bool isUInt< 8 >(uint64_t x)
Definition: MathExtras.h:405
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:840
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::MCBinaryExpr::createSub
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:609
llvm::WinEH::EncodingType::CE
@ CE
Windows NT (Windows on ARM)
llvm::PPCTargetStreamer::emitLocalEntry
virtual void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset)=0
MatchRegisterName
static unsigned MatchRegisterName(StringRef Name)
llvm::ErrorInfo
Base class for user error types.
Definition: Error.h:349
llvm::MCTargetOptions
Definition: MCTargetOptions.h:36
llvm::MCSymbolRefExpr
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
isReg
static bool isReg(const MCInst &MI, unsigned OpNo)
Definition: MipsInstPrinter.cpp:31
llvm::AsmToken::Comma
@ Comma
Definition: MCAsmMacro.h:49
llvm::Expression
Class representing an expression and its matching format.
Definition: FileCheckImpl.h:237
llvm::isRunOfOnes
static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)
Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.
Definition: PPCMCTargetDesc.h:58
llvm::MCUnaryExpr::getSubExpr
const MCExpr * getSubExpr() const
Get the child of this unary expression.
Definition: MCExpr.h:470
llvm::MatchOperand_NoMatch
@ MatchOperand_NoMatch
Definition: MCTargetAsmParser.h:123
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MCAsmParser::getTok
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:38
llvm::AsmToken::Plus
@ Plus
Definition: MCAsmMacro.h:45
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::MCOperand::createReg
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
A
* A
Definition: README_ALTIVEC.txt:89
llvm::PPCTargetStreamer::emitAbiVersion
virtual void emitAbiVersion(int AbiVersion)=0
llvm::PPCMCExpr::create
static const PPCMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: PPCMCExpr.cpp:20
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::AsmToken::RParen
@ RParen
Definition: MCAsmMacro.h:48
LLVM_FALLTHROUGH
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition: Compiler.h:273
llvm::MCSymbolRefExpr::VK_PPC_HIGH
@ VK_PPC_HIGH
Definition: MCExpr.h:250
llvm::PPCMCExpr::VK_PPC_HIGHESTA
@ VK_PPC_HIGHESTA
Definition: PPCMCExpr.h:30
llvm::OperandMatchResultTy
OperandMatchResultTy
Definition: MCTargetAsmParser.h:121
llvm::getThePPC64Target
Target & getThePPC64Target()
Definition: PowerPCTargetInfo.cpp:21
llvm::isInt< 16 >
constexpr bool isInt< 16 >(int64_t x)
Definition: MathExtras.h:370
llvm::tgtok::IntVal
@ IntVal
Definition: TGLexer.h:64
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::MCBinaryExpr::getOpcode
Opcode getOpcode() const
Get the kind of this binary expression.
Definition: MCExpr.h:624
llvm::AsmToken::Tilde
@ Tilde
Definition: MCAsmMacro.h:45
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:25
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::MCInst::setLoc
void setLoc(SMLoc loc)
Definition: MCInst.h:203
llvm::AsmToken::Identifier
@ Identifier
Definition: MCAsmMacro.h:28
llvm::AsmToken::isNot
bool isNot(TokenKind K) const
Definition: MCAsmMacro.h:83
llvm::SMLoc::getPointer
const char * getPointer() const
Definition: SMLoc.h:34
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:321
llvm::MCBinaryExpr::Sub
@ Sub
Subtraction.
Definition: MCExpr.h:505
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::MCInst::getOpcode
unsigned getOpcode() const
Definition: MCInst.h:198
llvm::MCTargetAsmParser
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Definition: MCTargetAsmParser.h:309
PPCTargetStreamer.h
llvm::MCSymbolRefExpr::VK_TLSGD
@ VK_TLSGD
Definition: MCExpr.h:208
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:385
llvm::MCSymbolRefExpr::VK_PPC_HIGHER
@ VK_PPC_HIGHER
Definition: MCExpr.h:252
llvm::getThePPC32LETarget
Target & getThePPC32LETarget()
Definition: PowerPCTargetInfo.cpp:17
llvm::MCExpr::SymbolRef
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:40
llvm::MCExpr::Unary
@ Unary
Unary expressions.
Definition: MCExpr.h:41
llvm::SMRange
Represents a range in source code.
Definition: SMLoc.h:48
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
llvm::MCSymbolRefExpr::VK_PPC_LO
@ VK_PPC_LO
Definition: MCExpr.h:247
llvm::PPCTargetStreamer::emitMachine
virtual void emitMachine(StringRef CPU)=0
N
#define N
MCStreamer.h
llvm::MCInst::getOperand
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
llvm::HexagonMCInstrInfo::getExpr
const MCExpr & getExpr(MCExpr const &Expr)
Definition: HexagonMCInstrInfo.cpp:303
llvm::PPCMCExpr::VariantKind
VariantKind
Definition: PPCMCExpr.h:20
llvm::MCExpr::Constant
@ Constant
Constant expressions.
Definition: MCExpr.h:39
llvm::isMem
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:123
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:43
llvm::SMLoc::getFromPointer
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
llvm::PPCMCExpr::VK_PPC_HIGHER
@ VK_PPC_HIGHER
Definition: PPCMCExpr.h:27
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::PPCMCExpr::VK_PPC_HIGH
@ VK_PPC_HIGH
Definition: PPCMCExpr.h:25
llvm::MCSymbolRefExpr::VK_None
@ VK_None
Definition: MCExpr.h:195
llvm::AsmToken::String
@ String
Definition: MCAsmMacro.h:29
llvm::MCSymbolRefExpr::VK_PPC_HIGHERA
@ VK_PPC_HIGHERA
Definition: MCExpr.h:253
raw_ostream.h
llvm::AsmToken::getLoc
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:27
llvm::AsmToken::getEndLoc
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:31
TargetRegistry.h
MCExpr.h
llvm::PPCTargetStreamer
Definition: PPCTargetStreamer.h:21
llvm::Triple::isPPC64
bool isPPC64() const
Tests whether the target is 64-bit PowerPC (little and big endian).
Definition: Triple.h:768
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
EvaluateCRExpr
static int64_t EvaluateCRExpr(const MCExpr *E)
Definition: PPCAsmParser.cpp:38
getReg
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Definition: MipsDisassembler.cpp:580
llvm::MCBinaryExpr::getLHS
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:627
PPCMnemonicSpellCheck
static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37
llvm::getThePPC32Target
Target & getThePPC32Target()
Definition: PowerPCTargetInfo.cpp:13