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