187590faeSEric Christopher //===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst instructions -------===//
2640192daSUlrich Weigand //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6640192daSUlrich Weigand //
7640192daSUlrich Weigand //===----------------------------------------------------------------------===//
8640192daSUlrich Weigand 
996e65783SUlrich Weigand #include "MCTargetDesc/PPCMCExpr.h"
10b3e8a6d2SBenjamin Kramer #include "MCTargetDesc/PPCMCTargetDesc.h"
116b9ee9bcSRafael Espindola #include "PPCTargetStreamer.h"
12ee6ced19SRichard Trieu #include "TargetInfo/PowerPCTargetInfo.h"
13690d8ea1SCraig Topper #include "llvm/ADT/STLExtras.h"
14640192daSUlrich Weigand #include "llvm/ADT/Twine.h"
15bb68610dSUlrich Weigand #include "llvm/MC/MCContext.h"
168a8cd2baSChandler Carruth #include "llvm/MC/MCExpr.h"
178a8cd2baSChandler Carruth #include "llvm/MC/MCInst.h"
188a8cd2baSChandler Carruth #include "llvm/MC/MCInstrInfo.h"
198a8cd2baSChandler Carruth #include "llvm/MC/MCParser/MCAsmLexer.h"
208a8cd2baSChandler Carruth #include "llvm/MC/MCParser/MCAsmParser.h"
218a8cd2baSChandler Carruth #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22b3e8a6d2SBenjamin Kramer #include "llvm/MC/MCParser/MCTargetAsmParser.h"
238a8cd2baSChandler Carruth #include "llvm/MC/MCStreamer.h"
248a8cd2baSChandler Carruth #include "llvm/MC/MCSubtargetInfo.h"
25b3e8a6d2SBenjamin Kramer #include "llvm/MC/MCSymbolELF.h"
2689b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
27640192daSUlrich Weigand #include "llvm/Support/SourceMgr.h"
28640192daSUlrich Weigand #include "llvm/Support/raw_ostream.h"
29640192daSUlrich Weigand 
30640192daSUlrich Weigand using namespace llvm;
31640192daSUlrich Weigand 
320dad994aSNemanja Ivanovic DEFINE_PPC_REGCLASSES;
33640192daSUlrich Weigand 
34b86cb7d0SUlrich Weigand // Evaluate an expression containing condition register
35b86cb7d0SUlrich Weigand // or condition register field symbols.  Returns positive
36b86cb7d0SUlrich Weigand // value on success, or -1 on error.
37b86cb7d0SUlrich Weigand static int64_t
EvaluateCRExpr(const MCExpr * E)38b86cb7d0SUlrich Weigand EvaluateCRExpr(const MCExpr *E) {
39b86cb7d0SUlrich Weigand   switch (E->getKind()) {
40b86cb7d0SUlrich Weigand   case MCExpr::Target:
41b86cb7d0SUlrich Weigand     return -1;
42b86cb7d0SUlrich Weigand 
43b86cb7d0SUlrich Weigand   case MCExpr::Constant: {
44b86cb7d0SUlrich Weigand     int64_t Res = cast<MCConstantExpr>(E)->getValue();
45b86cb7d0SUlrich Weigand     return Res < 0 ? -1 : Res;
46b86cb7d0SUlrich Weigand   }
47b86cb7d0SUlrich Weigand 
48b86cb7d0SUlrich Weigand   case MCExpr::SymbolRef: {
49b86cb7d0SUlrich Weigand     const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
50b86cb7d0SUlrich Weigand     StringRef Name = SRE->getSymbol().getName();
51b86cb7d0SUlrich Weigand 
52b86cb7d0SUlrich Weigand     if (Name == "lt") return 0;
53b86cb7d0SUlrich Weigand     if (Name == "gt") return 1;
54b86cb7d0SUlrich Weigand     if (Name == "eq") return 2;
55b86cb7d0SUlrich Weigand     if (Name == "so") return 3;
56b86cb7d0SUlrich Weigand     if (Name == "un") return 3;
57b86cb7d0SUlrich Weigand 
58b86cb7d0SUlrich Weigand     if (Name == "cr0") return 0;
59b86cb7d0SUlrich Weigand     if (Name == "cr1") return 1;
60b86cb7d0SUlrich Weigand     if (Name == "cr2") return 2;
61b86cb7d0SUlrich Weigand     if (Name == "cr3") return 3;
62b86cb7d0SUlrich Weigand     if (Name == "cr4") return 4;
63b86cb7d0SUlrich Weigand     if (Name == "cr5") return 5;
64b86cb7d0SUlrich Weigand     if (Name == "cr6") return 6;
65b86cb7d0SUlrich Weigand     if (Name == "cr7") return 7;
66b86cb7d0SUlrich Weigand 
67b86cb7d0SUlrich Weigand     return -1;
68b86cb7d0SUlrich Weigand   }
69b86cb7d0SUlrich Weigand 
70b86cb7d0SUlrich Weigand   case MCExpr::Unary:
71b86cb7d0SUlrich Weigand     return -1;
72b86cb7d0SUlrich Weigand 
73b86cb7d0SUlrich Weigand   case MCExpr::Binary: {
74b86cb7d0SUlrich Weigand     const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
75b86cb7d0SUlrich Weigand     int64_t LHSVal = EvaluateCRExpr(BE->getLHS());
76b86cb7d0SUlrich Weigand     int64_t RHSVal = EvaluateCRExpr(BE->getRHS());
77b86cb7d0SUlrich Weigand     int64_t Res;
78b86cb7d0SUlrich Weigand 
79b86cb7d0SUlrich Weigand     if (LHSVal < 0 || RHSVal < 0)
80b86cb7d0SUlrich Weigand       return -1;
81b86cb7d0SUlrich Weigand 
82b86cb7d0SUlrich Weigand     switch (BE->getOpcode()) {
83b86cb7d0SUlrich Weigand     default: return -1;
84b86cb7d0SUlrich Weigand     case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;
85b86cb7d0SUlrich Weigand     case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;
86b86cb7d0SUlrich Weigand     }
87b86cb7d0SUlrich Weigand 
88b86cb7d0SUlrich Weigand     return Res < 0 ? -1 : Res;
89b86cb7d0SUlrich Weigand   }
90b86cb7d0SUlrich Weigand   }
91b86cb7d0SUlrich Weigand 
92b86cb7d0SUlrich Weigand   llvm_unreachable("Invalid expression kind!");
93b86cb7d0SUlrich Weigand }
94b86cb7d0SUlrich Weigand 
95f7df7221SCraig Topper namespace {
96f7df7221SCraig Topper 
97640192daSUlrich Weigand struct PPCOperand;
98640192daSUlrich Weigand 
99640192daSUlrich Weigand class PPCAsmParser : public MCTargetAsmParser {
100640192daSUlrich Weigand   bool IsPPC64;
101640192daSUlrich Weigand 
Warning(SMLoc L,const Twine & Msg)102961d4694SRafael Espindola   void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
103640192daSUlrich Weigand 
isPPC64() const104640192daSUlrich Weigand   bool isPPC64() const { return IsPPC64; }
105640192daSUlrich Weigand 
106d6642c11SNirav Dave   bool MatchRegisterName(unsigned &RegNo, int64_t &IntVal);
107640192daSUlrich Weigand 
1080d3fa925SCraig Topper   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
1098d5bf042SEric Astor   OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1108d5bf042SEric Astor                                         SMLoc &EndLoc) override;
111640192daSUlrich Weigand 
11296e65783SUlrich Weigand   const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
11396e65783SUlrich Weigand                                         PPCMCExpr::VariantKind &Variant);
11452cf8e44SUlrich Weigand   const MCExpr *FixupVariantKind(const MCExpr *E);
11596e65783SUlrich Weigand   bool ParseExpression(const MCExpr *&EVal);
11696e65783SUlrich Weigand 
117960ea3f0SDavid Blaikie   bool ParseOperand(OperandVector &Operands);
118640192daSUlrich Weigand 
119d6642c11SNirav Dave   bool ParseDirectiveWord(unsigned Size, AsmToken ID);
120d6642c11SNirav Dave   bool ParseDirectiveTC(unsigned Size, AsmToken ID);
12155daa779SUlrich Weigand   bool ParseDirectiveMachine(SMLoc L);
1220daa5164SUlrich Weigand   bool ParseDirectiveAbiVersion(SMLoc L);
123bb68610dSUlrich Weigand   bool ParseDirectiveLocalEntry(SMLoc L);
12400d68c38SQiu Chaofan   bool ParseGNUAttribute(SMLoc L);
125640192daSUlrich Weigand 
126640192daSUlrich Weigand   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
127960ea3f0SDavid Blaikie                                OperandVector &Operands, MCStreamer &Out,
12826bb14e6STim Northover                                uint64_t &ErrorInfo,
1290d3fa925SCraig Topper                                bool MatchingInlineAsm) override;
130640192daSUlrich Weigand 
131960ea3f0SDavid Blaikie   void ProcessInstruction(MCInst &Inst, const OperandVector &Ops);
132d839490fSUlrich Weigand 
133640192daSUlrich Weigand   /// @name Auto-generated Match Functions
134640192daSUlrich Weigand   /// {
135640192daSUlrich Weigand 
136640192daSUlrich Weigand #define GET_ASSEMBLER_HEADER
137640192daSUlrich Weigand #include "PPCGenAsmMatcher.inc"
138640192daSUlrich Weigand 
139640192daSUlrich Weigand   /// }
140640192daSUlrich Weigand 
141640192daSUlrich Weigand 
142640192daSUlrich Weigand public:
PPCAsmParser(const MCSubtargetInfo & STI,MCAsmParser &,const MCInstrInfo & MII,const MCTargetOptions & Options)143b11ef089SAkira Hatanaka   PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &,
144bd9fc284SAkira Hatanaka                const MCInstrInfo &MII, const MCTargetOptions &Options)
1454191b9eaSOliver Stannard     : MCTargetAsmParser(Options, STI, MII) {
146640192daSUlrich Weigand     // Check for 64-bit vs. 32-bit pointer mode.
1474fed928fSBenjamin Kramer     const Triple &TheTriple = STI.getTargetTriple();
1483e92df3eSFangrui Song     IsPPC64 = TheTriple.isPPC64();
149640192daSUlrich Weigand     // Initialize the set of available features.
150640192daSUlrich Weigand     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
151640192daSUlrich Weigand   }
152640192daSUlrich Weigand 
153960ea3f0SDavid Blaikie   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
154960ea3f0SDavid Blaikie                         SMLoc NameLoc, OperandVector &Operands) override;
155640192daSUlrich Weigand 
1560d3fa925SCraig Topper   bool ParseDirective(AsmToken DirectiveID) override;
157c0944b50SUlrich Weigand 
158960ea3f0SDavid Blaikie   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
1590d3fa925SCraig Topper                                       unsigned Kind) override;
160b822af47SJoerg Sonnenberger 
1610d3fa925SCraig Topper   const MCExpr *applyModifierToExpr(const MCExpr *E,
162b822af47SJoerg Sonnenberger                                     MCSymbolRefExpr::VariantKind,
1630d3fa925SCraig Topper                                     MCContext &Ctx) override;
164640192daSUlrich Weigand };
165640192daSUlrich Weigand 
166640192daSUlrich Weigand /// PPCOperand - Instances of this class represent a parsed PowerPC machine
167640192daSUlrich Weigand /// instruction.
168640192daSUlrich Weigand struct PPCOperand : public MCParsedAsmOperand {
169640192daSUlrich Weigand   enum KindTy {
170640192daSUlrich Weigand     Token,
171640192daSUlrich Weigand     Immediate,
172bfef1dd6SJoerg Sonnenberger     ContextImmediate,
1735b427591SUlrich Weigand     Expression,
1745b427591SUlrich Weigand     TLSRegister
175640192daSUlrich Weigand   } Kind;
176640192daSUlrich Weigand 
177640192daSUlrich Weigand   SMLoc StartLoc, EndLoc;
178640192daSUlrich Weigand   bool IsPPC64;
179640192daSUlrich Weigand 
180640192daSUlrich Weigand   struct TokOp {
181640192daSUlrich Weigand     const char *Data;
182640192daSUlrich Weigand     unsigned Length;
183640192daSUlrich Weigand   };
184640192daSUlrich Weigand 
185640192daSUlrich Weigand   struct ImmOp {
186640192daSUlrich Weigand     int64_t Val;
187640192daSUlrich Weigand   };
188640192daSUlrich Weigand 
189640192daSUlrich Weigand   struct ExprOp {
190640192daSUlrich Weigand     const MCExpr *Val;
191b86cb7d0SUlrich Weigand     int64_t CRVal;     // Cached result of EvaluateCRExpr(Val)
192640192daSUlrich Weigand   };
193640192daSUlrich Weigand 
1945b427591SUlrich Weigand   struct TLSRegOp {
1955b427591SUlrich Weigand     const MCSymbolRefExpr *Sym;
1965b427591SUlrich Weigand   };
1975b427591SUlrich Weigand 
198640192daSUlrich Weigand   union {
199640192daSUlrich Weigand     struct TokOp Tok;
200640192daSUlrich Weigand     struct ImmOp Imm;
201640192daSUlrich Weigand     struct ExprOp Expr;
2025b427591SUlrich Weigand     struct TLSRegOp TLSReg;
203640192daSUlrich Weigand   };
204640192daSUlrich Weigand 
PPCOperand__anon662ace330111::PPCOperand205f3a344d2SKazu Hirata   PPCOperand(KindTy K) : Kind(K) {}
206f3a344d2SKazu Hirata 
207640192daSUlrich Weigand public:
PPCOperand__anon662ace330111::PPCOperand208e5947760SKazu Hirata   PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() {
209640192daSUlrich Weigand     Kind = o.Kind;
210640192daSUlrich Weigand     StartLoc = o.StartLoc;
211640192daSUlrich Weigand     EndLoc = o.EndLoc;
212640192daSUlrich Weigand     IsPPC64 = o.IsPPC64;
213640192daSUlrich Weigand     switch (Kind) {
214640192daSUlrich Weigand     case Token:
215640192daSUlrich Weigand       Tok = o.Tok;
216640192daSUlrich Weigand       break;
217640192daSUlrich Weigand     case Immediate:
218bfef1dd6SJoerg Sonnenberger     case ContextImmediate:
219640192daSUlrich Weigand       Imm = o.Imm;
220640192daSUlrich Weigand       break;
221640192daSUlrich Weigand     case Expression:
222640192daSUlrich Weigand       Expr = o.Expr;
223640192daSUlrich Weigand       break;
2245b427591SUlrich Weigand     case TLSRegister:
2255b427591SUlrich Weigand       TLSReg = o.TLSReg;
2265b427591SUlrich Weigand       break;
227640192daSUlrich Weigand     }
228640192daSUlrich Weigand   }
229640192daSUlrich Weigand 
230c2a2830eSRichard Smith   // Disable use of sized deallocation due to overallocation of PPCOperand
231c2a2830eSRichard Smith   // objects in CreateTokenWithStringCopy.
operator delete__anon662ace330111::PPCOperand232c2a2830eSRichard Smith   void operator delete(void *p) { ::operator delete(p); }
233c2a2830eSRichard Smith 
234640192daSUlrich Weigand   /// getStartLoc - Get the location of the first token of this operand.
getStartLoc__anon662ace330111::PPCOperand2350d3fa925SCraig Topper   SMLoc getStartLoc() const override { return StartLoc; }
236640192daSUlrich Weigand 
237640192daSUlrich Weigand   /// getEndLoc - Get the location of the last token of this operand.
getEndLoc__anon662ace330111::PPCOperand2380da86301SPeter Collingbourne   SMLoc getEndLoc() const override { return EndLoc; }
239640192daSUlrich Weigand 
240e86a8b79SHal Finkel   /// getLocRange - Get the range between the first and last token of this
241e86a8b79SHal Finkel   /// operand.
getLocRange__anon662ace330111::PPCOperand242e86a8b79SHal Finkel   SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
243e86a8b79SHal Finkel 
244640192daSUlrich Weigand   /// isPPC64 - True if this operand is for an instruction in 64-bit mode.
isPPC64__anon662ace330111::PPCOperand245640192daSUlrich Weigand   bool isPPC64() const { return IsPPC64; }
246640192daSUlrich Weigand 
getImm__anon662ace330111::PPCOperand247640192daSUlrich Weigand   int64_t getImm() const {
248640192daSUlrich Weigand     assert(Kind == Immediate && "Invalid access!");
249640192daSUlrich Weigand     return Imm.Val;
250640192daSUlrich Weigand   }
getImmS16Context__anon662ace330111::PPCOperand251bfef1dd6SJoerg Sonnenberger   int64_t getImmS16Context() const {
25287590faeSEric Christopher     assert((Kind == Immediate || Kind == ContextImmediate) &&
25387590faeSEric Christopher            "Invalid access!");
254bfef1dd6SJoerg Sonnenberger     if (Kind == Immediate)
255bfef1dd6SJoerg Sonnenberger       return Imm.Val;
256bfef1dd6SJoerg Sonnenberger     return static_cast<int16_t>(Imm.Val);
257bfef1dd6SJoerg Sonnenberger   }
getImmU16Context__anon662ace330111::PPCOperand258bfef1dd6SJoerg Sonnenberger   int64_t getImmU16Context() const {
25987590faeSEric Christopher     assert((Kind == Immediate || Kind == ContextImmediate) &&
26087590faeSEric Christopher            "Invalid access!");
261bfef1dd6SJoerg Sonnenberger     return Imm.Val;
262bfef1dd6SJoerg Sonnenberger   }
263640192daSUlrich Weigand 
getExpr__anon662ace330111::PPCOperand264640192daSUlrich Weigand   const MCExpr *getExpr() const {
265640192daSUlrich Weigand     assert(Kind == Expression && "Invalid access!");
266640192daSUlrich Weigand     return Expr.Val;
267640192daSUlrich Weigand   }
268640192daSUlrich Weigand 
getExprCRVal__anon662ace330111::PPCOperand269b86cb7d0SUlrich Weigand   int64_t getExprCRVal() const {
270b86cb7d0SUlrich Weigand     assert(Kind == Expression && "Invalid access!");
271b86cb7d0SUlrich Weigand     return Expr.CRVal;
272b86cb7d0SUlrich Weigand   }
273b86cb7d0SUlrich Weigand 
getTLSReg__anon662ace330111::PPCOperand2745b427591SUlrich Weigand   const MCExpr *getTLSReg() const {
2755b427591SUlrich Weigand     assert(Kind == TLSRegister && "Invalid access!");
2765b427591SUlrich Weigand     return TLSReg.Sym;
2775b427591SUlrich Weigand   }
2785b427591SUlrich Weigand 
getReg__anon662ace330111::PPCOperand2790d3fa925SCraig Topper   unsigned getReg() const override {
280640192daSUlrich Weigand     assert(isRegNumber() && "Invalid access!");
281640192daSUlrich Weigand     return (unsigned) Imm.Val;
282640192daSUlrich Weigand   }
283640192daSUlrich Weigand 
getVSReg__anon662ace330111::PPCOperand28427774d92SHal Finkel   unsigned getVSReg() const {
28527774d92SHal Finkel     assert(isVSRegNumber() && "Invalid access!");
28627774d92SHal Finkel     return (unsigned) Imm.Val;
28727774d92SHal Finkel   }
28827774d92SHal Finkel 
getACCReg__anon662ace330111::PPCOperand2899b86b700SBaptiste Saleil   unsigned getACCReg() const {
2909b86b700SBaptiste Saleil     assert(isACCRegNumber() && "Invalid access!");
2919b86b700SBaptiste Saleil     return (unsigned) Imm.Val;
2929b86b700SBaptiste Saleil   }
2939b86b700SBaptiste Saleil 
getVSRpEvenReg__anon662ace330111::PPCOperand2941372e23cSBaptiste Saleil   unsigned getVSRpEvenReg() const {
2951372e23cSBaptiste Saleil     assert(isVSRpEvenRegNumber() && "Invalid access!");
2961372e23cSBaptiste Saleil     return (unsigned) Imm.Val >> 1;
2971372e23cSBaptiste Saleil   }
2981372e23cSBaptiste Saleil 
getG8pReg__anon662ace330111::PPCOperand2991c450c3dSKai Luo   unsigned getG8pReg() const {
3001c450c3dSKai Luo     assert(isEvenRegNumber() && "Invalid access!");
3011c450c3dSKai Luo     return (unsigned)Imm.Val;
3021c450c3dSKai Luo   }
3031c450c3dSKai Luo 
getCCReg__anon662ace330111::PPCOperand304640192daSUlrich Weigand   unsigned getCCReg() const {
305640192daSUlrich Weigand     assert(isCCRegNumber() && "Invalid access!");
306b86cb7d0SUlrich Weigand     return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
307b86cb7d0SUlrich Weigand   }
308b86cb7d0SUlrich Weigand 
getCRBit__anon662ace330111::PPCOperand309b86cb7d0SUlrich Weigand   unsigned getCRBit() const {
310b86cb7d0SUlrich Weigand     assert(isCRBitNumber() && "Invalid access!");
311b86cb7d0SUlrich Weigand     return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
312640192daSUlrich Weigand   }
313640192daSUlrich Weigand 
getCRBitMask__anon662ace330111::PPCOperand314640192daSUlrich Weigand   unsigned getCRBitMask() const {
315640192daSUlrich Weigand     assert(isCRBitMask() && "Invalid access!");
316df1ecbd7SMichael J. Spencer     return 7 - countTrailingZeros<uint64_t>(Imm.Val);
317640192daSUlrich Weigand   }
318640192daSUlrich Weigand 
isToken__anon662ace330111::PPCOperand3190d3fa925SCraig Topper   bool isToken() const override { return Kind == Token; }
isImm__anon662ace330111::PPCOperand32087590faeSEric Christopher   bool isImm() const override {
32187590faeSEric Christopher     return Kind == Immediate || Kind == Expression;
32287590faeSEric Christopher   }
isU1Imm__anon662ace330111::PPCOperand323e8effe1eSNemanja Ivanovic   bool isU1Imm() const { return Kind == Immediate && isUInt<1>(getImm()); }
isU2Imm__anon662ace330111::PPCOperand32427774d92SHal Finkel   bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); }
isU3Imm__anon662ace330111::PPCOperand325535e69deSKit Barton   bool isU3Imm() const { return Kind == Immediate && isUInt<3>(getImm()); }
isU4Imm__anon662ace330111::PPCOperand3269e9623caSJoerg Sonnenberger   bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); }
isU5Imm__anon662ace330111::PPCOperand327640192daSUlrich Weigand   bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
isS5Imm__anon662ace330111::PPCOperand328640192daSUlrich Weigand   bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }
isU6Imm__anon662ace330111::PPCOperand329640192daSUlrich Weigand   bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); }
isU6ImmX2__anon662ace330111::PPCOperand3300013b929SJoerg Sonnenberger   bool isU6ImmX2() const { return Kind == Immediate &&
3310013b929SJoerg Sonnenberger                                   isUInt<6>(getImm()) &&
3320013b929SJoerg Sonnenberger                                   (getImm() & 1) == 0; }
isU7Imm__anon662ace330111::PPCOperand33380722719SChuang-Yu Cheng   bool isU7Imm() const { return Kind == Immediate && isUInt<7>(getImm()); }
isU7ImmX4__anon662ace330111::PPCOperand3340013b929SJoerg Sonnenberger   bool isU7ImmX4() const { return Kind == Immediate &&
3350013b929SJoerg Sonnenberger                                   isUInt<7>(getImm()) &&
3360013b929SJoerg Sonnenberger                                   (getImm() & 3) == 0; }
isU8Imm__anon662ace330111::PPCOperand33780722719SChuang-Yu Cheng   bool isU8Imm() const { return Kind == Immediate && isUInt<8>(getImm()); }
isU8ImmX8__anon662ace330111::PPCOperand3380013b929SJoerg Sonnenberger   bool isU8ImmX8() const { return Kind == Immediate &&
3390013b929SJoerg Sonnenberger                                   isUInt<8>(getImm()) &&
3400013b929SJoerg Sonnenberger                                   (getImm() & 7) == 0; }
341e26236eeSBill Schmidt 
isU10Imm__anon662ace330111::PPCOperand342e26236eeSBill Schmidt   bool isU10Imm() const { return Kind == Immediate && isUInt<10>(getImm()); }
isU12Imm__anon662ace330111::PPCOperand343c93a9a2cSHal Finkel   bool isU12Imm() const { return Kind == Immediate && isUInt<12>(getImm()); }
isU16Imm__anon662ace330111::PPCOperand344*2aaba44bSNemanja Ivanovic   bool isU16Imm() const { return isExtImm<16>(/*Signed*/ false, 1); }
isS16Imm__anon662ace330111::PPCOperand345*2aaba44bSNemanja Ivanovic   bool isS16Imm() const { return isExtImm<16>(/*Signed*/ true, 1); }
isS16ImmX4__anon662ace330111::PPCOperand346*2aaba44bSNemanja Ivanovic   bool isS16ImmX4() const { return isExtImm<16>(/*Signed*/ true, 4); }
isS16ImmX16__anon662ace330111::PPCOperand347*2aaba44bSNemanja Ivanovic   bool isS16ImmX16() const { return isExtImm<16>(/*Signed*/ true, 16); }
isS17Imm__anon662ace330111::PPCOperand348*2aaba44bSNemanja Ivanovic   bool isS17Imm() const { return isExtImm<17>(/*Signed*/ true, 1); }
349f28cb01bSStefan Pintilie 
isHashImmX8__anon662ace330111::PPCOperand350f28cb01bSStefan Pintilie   bool isHashImmX8() const {
351f28cb01bSStefan Pintilie     // The Hash Imm form is used for instructions that check or store a hash.
352f28cb01bSStefan Pintilie     // These instructions have a small immediate range that spans between
353f28cb01bSStefan Pintilie     // -8 and -512.
354f28cb01bSStefan Pintilie     return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&
355f28cb01bSStefan Pintilie             (getImm() & 7) == 0);
356f28cb01bSStefan Pintilie   }
357f28cb01bSStefan Pintilie 
isS34ImmX16__anon662ace330111::PPCOperand358043e4787SVictor Huang   bool isS34ImmX16() const {
359043e4787SVictor Huang     return Kind == Expression ||
360043e4787SVictor Huang            (Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
361043e4787SVictor Huang   }
isS34Imm__anon662ace330111::PPCOperand3625cee3401SVictor Huang   bool isS34Imm() const {
3635cee3401SVictor Huang     // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
3645cee3401SVictor Huang     // ContextImmediate is needed.
3655cee3401SVictor Huang     return Kind == Expression || (Kind == Immediate && isInt<34>(getImm()));
3665cee3401SVictor Huang   }
3675cee3401SVictor Huang 
isTLSReg__anon662ace330111::PPCOperand3685b427591SUlrich Weigand   bool isTLSReg() const { return Kind == TLSRegister; }
isDirectBr__anon662ace330111::PPCOperand369eb9d13fcSJoerg Sonnenberger   bool isDirectBr() const {
370eb9d13fcSJoerg Sonnenberger     if (Kind == Expression)
371eb9d13fcSJoerg Sonnenberger       return true;
372eb9d13fcSJoerg Sonnenberger     if (Kind != Immediate)
373eb9d13fcSJoerg Sonnenberger       return false;
374eb9d13fcSJoerg Sonnenberger     // Operand must be 64-bit aligned, signed 27-bit immediate.
375eb9d13fcSJoerg Sonnenberger     if ((getImm() & 3) != 0)
376eb9d13fcSJoerg Sonnenberger       return false;
377eb9d13fcSJoerg Sonnenberger     if (isInt<26>(getImm()))
378eb9d13fcSJoerg Sonnenberger       return true;
379eb9d13fcSJoerg Sonnenberger     if (!IsPPC64) {
380eb9d13fcSJoerg Sonnenberger       // In 32-bit mode, large 32-bit quantities wrap around.
381eb9d13fcSJoerg Sonnenberger       if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))
382eb9d13fcSJoerg Sonnenberger         return true;
383eb9d13fcSJoerg Sonnenberger     }
384eb9d13fcSJoerg Sonnenberger     return false;
385eb9d13fcSJoerg Sonnenberger   }
isCondBr__anon662ace330111::PPCOperand386b6a30d15SUlrich Weigand   bool isCondBr() const { return Kind == Expression ||
387b6a30d15SUlrich Weigand                                  (Kind == Immediate && isInt<16>(getImm()) &&
388b6a30d15SUlrich Weigand                                   (getImm() & 3) == 0); }
isImmZero__anon662ace330111::PPCOperand3895cee3401SVictor Huang   bool isImmZero() const { return Kind == Immediate && getImm() == 0; }
isRegNumber__anon662ace330111::PPCOperand390640192daSUlrich Weigand   bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
isACCRegNumber__anon662ace330111::PPCOperand3919b86b700SBaptiste Saleil   bool isACCRegNumber() const {
3929b86b700SBaptiste Saleil     return Kind == Immediate && isUInt<3>(getImm());
3939b86b700SBaptiste Saleil   }
isVSRpEvenRegNumber__anon662ace330111::PPCOperand3941372e23cSBaptiste Saleil   bool isVSRpEvenRegNumber() const {
3951372e23cSBaptiste Saleil     return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
3961372e23cSBaptiste Saleil   }
isVSRegNumber__anon662ace330111::PPCOperand39787590faeSEric Christopher   bool isVSRegNumber() const {
39887590faeSEric Christopher     return Kind == Immediate && isUInt<6>(getImm());
39987590faeSEric Christopher   }
isCCRegNumber__anon662ace330111::PPCOperand400b86cb7d0SUlrich Weigand   bool isCCRegNumber() const { return (Kind == Expression
401b86cb7d0SUlrich Weigand                                        && isUInt<3>(getExprCRVal())) ||
402b86cb7d0SUlrich Weigand                                       (Kind == Immediate
403b86cb7d0SUlrich Weigand                                        && isUInt<3>(getImm())); }
isCRBitNumber__anon662ace330111::PPCOperand404b86cb7d0SUlrich Weigand   bool isCRBitNumber() const { return (Kind == Expression
405b86cb7d0SUlrich Weigand                                        && isUInt<5>(getExprCRVal())) ||
406b86cb7d0SUlrich Weigand                                       (Kind == Immediate
407b86cb7d0SUlrich Weigand                                        && isUInt<5>(getImm())); }
4081c450c3dSKai Luo 
isEvenRegNumber__anon662ace330111::PPCOperand4091c450c3dSKai Luo   bool isEvenRegNumber() const { return isRegNumber() && (getImm() & 1) == 0; }
4101c450c3dSKai Luo 
isCRBitMask__anon662ace330111::PPCOperand411640192daSUlrich Weigand   bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) &&
412640192daSUlrich Weigand                                     isPowerOf2_32(getImm()); }
isATBitsAsHint__anon662ace330111::PPCOperand413522e4d9dSHal Finkel   bool isATBitsAsHint() const { return false; }
isMem__anon662ace330111::PPCOperand4140d3fa925SCraig Topper   bool isMem() const override { return false; }
isReg__anon662ace330111::PPCOperand4150d3fa925SCraig Topper   bool isReg() const override { return false; }
416640192daSUlrich Weigand 
addRegOperands__anon662ace330111::PPCOperand417640192daSUlrich Weigand   void addRegOperands(MCInst &Inst, unsigned N) const {
418640192daSUlrich Weigand     llvm_unreachable("addRegOperands");
419640192daSUlrich Weigand   }
420640192daSUlrich Weigand 
addRegGPRCOperands__anon662ace330111::PPCOperand421640192daSUlrich Weigand   void addRegGPRCOperands(MCInst &Inst, unsigned N) const {
422640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
423e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
424640192daSUlrich Weigand   }
425640192daSUlrich Weigand 
addRegGPRCNoR0Operands__anon662ace330111::PPCOperand426640192daSUlrich Weigand   void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {
427640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
428e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(RRegsNoR0[getReg()]));
429640192daSUlrich Weigand   }
430640192daSUlrich Weigand 
addRegG8RCOperands__anon662ace330111::PPCOperand431640192daSUlrich Weigand   void addRegG8RCOperands(MCInst &Inst, unsigned N) const {
432640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
433e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(XRegs[getReg()]));
434640192daSUlrich Weigand   }
435640192daSUlrich Weigand 
addRegG8RCNoX0Operands__anon662ace330111::PPCOperand436640192daSUlrich Weigand   void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {
437640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
438e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(XRegsNoX0[getReg()]));
439640192daSUlrich Weigand   }
440640192daSUlrich Weigand 
addRegG8pRCOperands__anon662ace330111::PPCOperand4411c450c3dSKai Luo   void addRegG8pRCOperands(MCInst &Inst, unsigned N) const {
4421c450c3dSKai Luo     assert(N == 1 && "Invalid number of operands!");
4431c450c3dSKai Luo     Inst.addOperand(MCOperand::createReg(XRegs[getG8pReg()]));
4441c450c3dSKai Luo   }
4451c450c3dSKai Luo 
addRegGxRCOperands__anon662ace330111::PPCOperand446640192daSUlrich Weigand   void addRegGxRCOperands(MCInst &Inst, unsigned N) const {
447640192daSUlrich Weigand     if (isPPC64())
448640192daSUlrich Weigand       addRegG8RCOperands(Inst, N);
449640192daSUlrich Weigand     else
450640192daSUlrich Weigand       addRegGPRCOperands(Inst, N);
451640192daSUlrich Weigand   }
452640192daSUlrich Weigand 
addRegGxRCNoR0Operands__anon662ace330111::PPCOperand453640192daSUlrich Weigand   void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {
454640192daSUlrich Weigand     if (isPPC64())
455640192daSUlrich Weigand       addRegG8RCNoX0Operands(Inst, N);
456640192daSUlrich Weigand     else
457640192daSUlrich Weigand       addRegGPRCNoR0Operands(Inst, N);
458640192daSUlrich Weigand   }
459640192daSUlrich Weigand 
addRegF4RCOperands__anon662ace330111::PPCOperand460640192daSUlrich Weigand   void addRegF4RCOperands(MCInst &Inst, unsigned N) const {
461640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
462e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(FRegs[getReg()]));
463640192daSUlrich Weigand   }
464640192daSUlrich Weigand 
addRegF8RCOperands__anon662ace330111::PPCOperand465640192daSUlrich Weigand   void addRegF8RCOperands(MCInst &Inst, unsigned N) const {
466640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
467e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(FRegs[getReg()]));
468640192daSUlrich Weigand   }
469640192daSUlrich Weigand 
addRegVFRCOperands__anon662ace330111::PPCOperand47011049f8fSNemanja Ivanovic   void addRegVFRCOperands(MCInst &Inst, unsigned N) const {
47111049f8fSNemanja Ivanovic     assert(N == 1 && "Invalid number of operands!");
47211049f8fSNemanja Ivanovic     Inst.addOperand(MCOperand::createReg(VFRegs[getReg()]));
47311049f8fSNemanja Ivanovic   }
47411049f8fSNemanja Ivanovic 
addRegVRRCOperands__anon662ace330111::PPCOperand475640192daSUlrich Weigand   void addRegVRRCOperands(MCInst &Inst, unsigned N) const {
476640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
477e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(VRegs[getReg()]));
478640192daSUlrich Weigand   }
479640192daSUlrich Weigand 
addRegVSRCOperands__anon662ace330111::PPCOperand48027774d92SHal Finkel   void addRegVSRCOperands(MCInst &Inst, unsigned N) const {
48127774d92SHal Finkel     assert(N == 1 && "Invalid number of operands!");
482e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(VSRegs[getVSReg()]));
48327774d92SHal Finkel   }
48427774d92SHal Finkel 
addRegVSFRCOperands__anon662ace330111::PPCOperand48519be506aSHal Finkel   void addRegVSFRCOperands(MCInst &Inst, unsigned N) const {
48619be506aSHal Finkel     assert(N == 1 && "Invalid number of operands!");
487e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(VSFRegs[getVSReg()]));
48819be506aSHal Finkel   }
48919be506aSHal Finkel 
addRegVSSRCOperands__anon662ace330111::PPCOperand490f3c94b1eSNemanja Ivanovic   void addRegVSSRCOperands(MCInst &Inst, unsigned N) const {
491f3c94b1eSNemanja Ivanovic     assert(N == 1 && "Invalid number of operands!");
492e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()]));
493f3c94b1eSNemanja Ivanovic   }
494f3c94b1eSNemanja Ivanovic 
addRegSPE4RCOperands__anon662ace330111::PPCOperand495d52990c7SJustin Hibbits   void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {
496d52990c7SJustin Hibbits     assert(N == 1 && "Invalid number of operands!");
497d52990c7SJustin Hibbits     Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
498d52990c7SJustin Hibbits   }
499d52990c7SJustin Hibbits 
addRegSPERCOperands__anon662ace330111::PPCOperand500d52990c7SJustin Hibbits   void addRegSPERCOperands(MCInst &Inst, unsigned N) const {
501d52990c7SJustin Hibbits     assert(N == 1 && "Invalid number of operands!");
502d52990c7SJustin Hibbits     Inst.addOperand(MCOperand::createReg(SPERegs[getReg()]));
503d52990c7SJustin Hibbits   }
504d52990c7SJustin Hibbits 
addRegACCRCOperands__anon662ace330111::PPCOperand5059b86b700SBaptiste Saleil   void addRegACCRCOperands(MCInst &Inst, unsigned N) const {
5069b86b700SBaptiste Saleil     assert(N == 1 && "Invalid number of operands!");
5079b86b700SBaptiste Saleil     Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()]));
5089b86b700SBaptiste Saleil   }
5099b86b700SBaptiste Saleil 
addRegVSRpRCOperands__anon662ace330111::PPCOperand5101372e23cSBaptiste Saleil   void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {
5111372e23cSBaptiste Saleil     assert(N == 1 && "Invalid number of operands!");
5121372e23cSBaptiste Saleil     Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
5131372e23cSBaptiste Saleil   }
5141372e23cSBaptiste Saleil 
addRegVSRpEvenRCOperands__anon662ace330111::PPCOperand51566d2e3f4SAhsan Saghir   void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const {
51666d2e3f4SAhsan Saghir     assert(N == 1 && "Invalid number of operands!");
51766d2e3f4SAhsan Saghir     Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
51866d2e3f4SAhsan Saghir   }
51966d2e3f4SAhsan Saghir 
addRegCRBITRCOperands__anon662ace330111::PPCOperand520640192daSUlrich Weigand   void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
521640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
522e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));
523640192daSUlrich Weigand   }
524640192daSUlrich Weigand 
addRegCRRCOperands__anon662ace330111::PPCOperand525640192daSUlrich Weigand   void addRegCRRCOperands(MCInst &Inst, unsigned N) const {
526640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
527e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(CRRegs[getCCReg()]));
528640192daSUlrich Weigand   }
529640192daSUlrich Weigand 
addCRBitMaskOperands__anon662ace330111::PPCOperand530640192daSUlrich Weigand   void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {
531640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
532e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(CRRegs[getCRBitMask()]));
533640192daSUlrich Weigand   }
534640192daSUlrich Weigand 
addImmOperands__anon662ace330111::PPCOperand535640192daSUlrich Weigand   void addImmOperands(MCInst &Inst, unsigned N) const {
536640192daSUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
537640192daSUlrich Weigand     if (Kind == Immediate)
538e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(getImm()));
539640192daSUlrich Weigand     else
540e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createExpr(getExpr()));
541640192daSUlrich Weigand   }
542640192daSUlrich Weigand 
addS16ImmOperands__anon662ace330111::PPCOperand543bfef1dd6SJoerg Sonnenberger   void addS16ImmOperands(MCInst &Inst, unsigned N) const {
544bfef1dd6SJoerg Sonnenberger     assert(N == 1 && "Invalid number of operands!");
545bfef1dd6SJoerg Sonnenberger     switch (Kind) {
546bfef1dd6SJoerg Sonnenberger       case Immediate:
547e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(getImm()));
548bfef1dd6SJoerg Sonnenberger         break;
549bfef1dd6SJoerg Sonnenberger       case ContextImmediate:
550e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(getImmS16Context()));
551bfef1dd6SJoerg Sonnenberger         break;
552bfef1dd6SJoerg Sonnenberger       default:
553e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createExpr(getExpr()));
554bfef1dd6SJoerg Sonnenberger         break;
555bfef1dd6SJoerg Sonnenberger     }
556bfef1dd6SJoerg Sonnenberger   }
557bfef1dd6SJoerg Sonnenberger 
addU16ImmOperands__anon662ace330111::PPCOperand558bfef1dd6SJoerg Sonnenberger   void addU16ImmOperands(MCInst &Inst, unsigned N) const {
559bfef1dd6SJoerg Sonnenberger     assert(N == 1 && "Invalid number of operands!");
560bfef1dd6SJoerg Sonnenberger     switch (Kind) {
561bfef1dd6SJoerg Sonnenberger       case Immediate:
562e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(getImm()));
563bfef1dd6SJoerg Sonnenberger         break;
564bfef1dd6SJoerg Sonnenberger       case ContextImmediate:
565e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createImm(getImmU16Context()));
566bfef1dd6SJoerg Sonnenberger         break;
567bfef1dd6SJoerg Sonnenberger       default:
568e9119e41SJim Grosbach         Inst.addOperand(MCOperand::createExpr(getExpr()));
569bfef1dd6SJoerg Sonnenberger         break;
570bfef1dd6SJoerg Sonnenberger     }
571bfef1dd6SJoerg Sonnenberger   }
572bfef1dd6SJoerg Sonnenberger 
addBranchTargetOperands__anon662ace330111::PPCOperand573b6a30d15SUlrich Weigand   void addBranchTargetOperands(MCInst &Inst, unsigned N) const {
574b6a30d15SUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
575b6a30d15SUlrich Weigand     if (Kind == Immediate)
576e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createImm(getImm() / 4));
577b6a30d15SUlrich Weigand     else
578e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createExpr(getExpr()));
579b6a30d15SUlrich Weigand   }
580b6a30d15SUlrich Weigand 
addTLSRegOperands__anon662ace330111::PPCOperand5815b427591SUlrich Weigand   void addTLSRegOperands(MCInst &Inst, unsigned N) const {
5825b427591SUlrich Weigand     assert(N == 1 && "Invalid number of operands!");
583e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createExpr(getTLSReg()));
5845b427591SUlrich Weigand   }
5855b427591SUlrich Weigand 
getToken__anon662ace330111::PPCOperand586640192daSUlrich Weigand   StringRef getToken() const {
587640192daSUlrich Weigand     assert(Kind == Token && "Invalid access!");
588640192daSUlrich Weigand     return StringRef(Tok.Data, Tok.Length);
589640192daSUlrich Weigand   }
590640192daSUlrich Weigand 
5910d3fa925SCraig Topper   void print(raw_ostream &OS) const override;
592640192daSUlrich Weigand 
CreateToken__anon662ace330111::PPCOperand593960ea3f0SDavid Blaikie   static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,
594960ea3f0SDavid Blaikie                                                  bool IsPPC64) {
5950eaee545SJonas Devlieghere     auto Op = std::make_unique<PPCOperand>(Token);
596640192daSUlrich Weigand     Op->Tok.Data = Str.data();
597640192daSUlrich Weigand     Op->Tok.Length = Str.size();
598640192daSUlrich Weigand     Op->StartLoc = S;
599640192daSUlrich Weigand     Op->EndLoc = S;
600640192daSUlrich Weigand     Op->IsPPC64 = IsPPC64;
601640192daSUlrich Weigand     return Op;
602640192daSUlrich Weigand   }
603640192daSUlrich Weigand 
604960ea3f0SDavid Blaikie   static std::unique_ptr<PPCOperand>
CreateTokenWithStringCopy__anon662ace330111::PPCOperand605960ea3f0SDavid Blaikie   CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {
60672d45cc8SBenjamin Kramer     // Allocate extra memory for the string and copy it.
607960ea3f0SDavid Blaikie     // FIXME: This is incorrect, Operands are owned by unique_ptr with a default
608960ea3f0SDavid Blaikie     // deleter which will destroy them by simply using "delete", not correctly
609960ea3f0SDavid Blaikie     // calling operator delete on this extra memory after calling the dtor
610960ea3f0SDavid Blaikie     // explicitly.
61172d45cc8SBenjamin Kramer     void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());
612960ea3f0SDavid Blaikie     std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));
613769989c4SBenjamin Kramer     Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1);
61472d45cc8SBenjamin Kramer     Op->Tok.Length = Str.size();
615769989c4SBenjamin Kramer     std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size());
61672d45cc8SBenjamin Kramer     Op->StartLoc = S;
61772d45cc8SBenjamin Kramer     Op->EndLoc = S;
61872d45cc8SBenjamin Kramer     Op->IsPPC64 = IsPPC64;
61972d45cc8SBenjamin Kramer     return Op;
62072d45cc8SBenjamin Kramer   }
62172d45cc8SBenjamin Kramer 
CreateImm__anon662ace330111::PPCOperand622960ea3f0SDavid Blaikie   static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,
623960ea3f0SDavid Blaikie                                                bool IsPPC64) {
6240eaee545SJonas Devlieghere     auto Op = std::make_unique<PPCOperand>(Immediate);
625640192daSUlrich Weigand     Op->Imm.Val = Val;
626640192daSUlrich Weigand     Op->StartLoc = S;
627640192daSUlrich Weigand     Op->EndLoc = E;
628640192daSUlrich Weigand     Op->IsPPC64 = IsPPC64;
629640192daSUlrich Weigand     return Op;
630640192daSUlrich Weigand   }
631640192daSUlrich Weigand 
CreateExpr__anon662ace330111::PPCOperand632960ea3f0SDavid Blaikie   static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,
633960ea3f0SDavid Blaikie                                                 SMLoc E, bool IsPPC64) {
6340eaee545SJonas Devlieghere     auto Op = std::make_unique<PPCOperand>(Expression);
635640192daSUlrich Weigand     Op->Expr.Val = Val;
636b86cb7d0SUlrich Weigand     Op->Expr.CRVal = EvaluateCRExpr(Val);
637640192daSUlrich Weigand     Op->StartLoc = S;
638640192daSUlrich Weigand     Op->EndLoc = E;
639640192daSUlrich Weigand     Op->IsPPC64 = IsPPC64;
640640192daSUlrich Weigand     return Op;
641640192daSUlrich Weigand   }
6425b427591SUlrich Weigand 
643960ea3f0SDavid Blaikie   static std::unique_ptr<PPCOperand>
CreateTLSReg__anon662ace330111::PPCOperand644960ea3f0SDavid Blaikie   CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {
6450eaee545SJonas Devlieghere     auto Op = std::make_unique<PPCOperand>(TLSRegister);
6465b427591SUlrich Weigand     Op->TLSReg.Sym = Sym;
6475b427591SUlrich Weigand     Op->StartLoc = S;
6485b427591SUlrich Weigand     Op->EndLoc = E;
6495b427591SUlrich Weigand     Op->IsPPC64 = IsPPC64;
6505b427591SUlrich Weigand     return Op;
6515b427591SUlrich Weigand   }
6525b427591SUlrich Weigand 
653960ea3f0SDavid Blaikie   static std::unique_ptr<PPCOperand>
CreateContextImm__anon662ace330111::PPCOperand654bfef1dd6SJoerg Sonnenberger   CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
6550eaee545SJonas Devlieghere     auto Op = std::make_unique<PPCOperand>(ContextImmediate);
656bfef1dd6SJoerg Sonnenberger     Op->Imm.Val = Val;
657bfef1dd6SJoerg Sonnenberger     Op->StartLoc = S;
658bfef1dd6SJoerg Sonnenberger     Op->EndLoc = E;
659bfef1dd6SJoerg Sonnenberger     Op->IsPPC64 = IsPPC64;
660bfef1dd6SJoerg Sonnenberger     return Op;
661bfef1dd6SJoerg Sonnenberger   }
662bfef1dd6SJoerg Sonnenberger 
663bfef1dd6SJoerg Sonnenberger   static std::unique_ptr<PPCOperand>
CreateFromMCExpr__anon662ace330111::PPCOperand664960ea3f0SDavid Blaikie   CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {
6655b427591SUlrich Weigand     if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
6665b427591SUlrich Weigand       return CreateImm(CE->getValue(), S, E, IsPPC64);
6675b427591SUlrich Weigand 
6685b427591SUlrich Weigand     if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
669365f861cSKamau Bridgeman       if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS ||
670365f861cSKamau Bridgeman           SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL)
6715b427591SUlrich Weigand         return CreateTLSReg(SRE, S, E, IsPPC64);
6725b427591SUlrich Weigand 
673bfef1dd6SJoerg Sonnenberger     if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
674bfef1dd6SJoerg Sonnenberger       int64_t Res;
67513760bd1SJim Grosbach       if (TE->evaluateAsConstant(Res))
676bfef1dd6SJoerg Sonnenberger         return CreateContextImm(Res, S, E, IsPPC64);
677bfef1dd6SJoerg Sonnenberger     }
678bfef1dd6SJoerg Sonnenberger 
6795b427591SUlrich Weigand     return CreateExpr(Val, S, E, IsPPC64);
6805b427591SUlrich Weigand   }
681*2aaba44bSNemanja Ivanovic 
682*2aaba44bSNemanja Ivanovic private:
683*2aaba44bSNemanja Ivanovic   template <unsigned Width>
isExtImm__anon662ace330111::PPCOperand684*2aaba44bSNemanja Ivanovic   bool isExtImm(bool Signed, unsigned Multiple) const {
685*2aaba44bSNemanja Ivanovic     switch (Kind) {
686*2aaba44bSNemanja Ivanovic     default:
687*2aaba44bSNemanja Ivanovic       return false;
688*2aaba44bSNemanja Ivanovic     case Expression:
689*2aaba44bSNemanja Ivanovic       return true;
690*2aaba44bSNemanja Ivanovic     case Immediate:
691*2aaba44bSNemanja Ivanovic     case ContextImmediate:
692*2aaba44bSNemanja Ivanovic       if (Signed)
693*2aaba44bSNemanja Ivanovic         return isInt<Width>(getImmS16Context()) &&
694*2aaba44bSNemanja Ivanovic                (getImmS16Context() & (Multiple - 1)) == 0;
695*2aaba44bSNemanja Ivanovic       else
696*2aaba44bSNemanja Ivanovic         return isUInt<Width>(getImmU16Context()) &&
697*2aaba44bSNemanja Ivanovic                (getImmU16Context() & (Multiple - 1)) == 0;
698*2aaba44bSNemanja Ivanovic     }
699*2aaba44bSNemanja Ivanovic   }
700640192daSUlrich Weigand };
701640192daSUlrich Weigand 
702640192daSUlrich Weigand } // end anonymous namespace.
703640192daSUlrich Weigand 
print(raw_ostream & OS) const704640192daSUlrich Weigand void PPCOperand::print(raw_ostream &OS) const {
705640192daSUlrich Weigand   switch (Kind) {
706640192daSUlrich Weigand   case Token:
707640192daSUlrich Weigand     OS << "'" << getToken() << "'";
708640192daSUlrich Weigand     break;
709640192daSUlrich Weigand   case Immediate:
710bfef1dd6SJoerg Sonnenberger   case ContextImmediate:
711640192daSUlrich Weigand     OS << getImm();
712640192daSUlrich Weigand     break;
713640192daSUlrich Weigand   case Expression:
714f4a13653SRafael Espindola     OS << *getExpr();
715640192daSUlrich Weigand     break;
7165b427591SUlrich Weigand   case TLSRegister:
717f4a13653SRafael Espindola     OS << *getTLSReg();
7185b427591SUlrich Weigand     break;
719640192daSUlrich Weigand   }
720640192daSUlrich Weigand }
721640192daSUlrich Weigand 
7225aab5afcSJoerg Sonnenberger static void
addNegOperand(MCInst & Inst,MCOperand & Op,MCContext & Ctx)7235aab5afcSJoerg Sonnenberger addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) {
7245aab5afcSJoerg Sonnenberger   if (Op.isImm()) {
725e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createImm(-Op.getImm()));
7265aab5afcSJoerg Sonnenberger     return;
7275aab5afcSJoerg Sonnenberger   }
7285aab5afcSJoerg Sonnenberger   const MCExpr *Expr = Op.getExpr();
7295aab5afcSJoerg Sonnenberger   if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
7305aab5afcSJoerg Sonnenberger     if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {
731e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createExpr(UnExpr->getSubExpr()));
7325aab5afcSJoerg Sonnenberger       return;
7335aab5afcSJoerg Sonnenberger     }
7345aab5afcSJoerg Sonnenberger   } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
7355aab5afcSJoerg Sonnenberger     if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {
73613760bd1SJim Grosbach       const MCExpr *NE = MCBinaryExpr::createSub(BinExpr->getRHS(),
7375aab5afcSJoerg Sonnenberger                                                  BinExpr->getLHS(), Ctx);
738e9119e41SJim Grosbach       Inst.addOperand(MCOperand::createExpr(NE));
7395aab5afcSJoerg Sonnenberger       return;
7405aab5afcSJoerg Sonnenberger     }
7415aab5afcSJoerg Sonnenberger   }
74213760bd1SJim Grosbach   Inst.addOperand(MCOperand::createExpr(MCUnaryExpr::createMinus(Expr, Ctx)));
7435aab5afcSJoerg Sonnenberger }
7445aab5afcSJoerg Sonnenberger 
ProcessInstruction(MCInst & Inst,const OperandVector & Operands)745960ea3f0SDavid Blaikie void PPCAsmParser::ProcessInstruction(MCInst &Inst,
746960ea3f0SDavid Blaikie                                       const OperandVector &Operands) {
747ad873cdbSUlrich Weigand   int Opcode = Inst.getOpcode();
748ad873cdbSUlrich Weigand   switch (Opcode) {
749fefcfffeSHal Finkel   case PPC::DCBTx:
750fefcfffeSHal Finkel   case PPC::DCBTT:
751fefcfffeSHal Finkel   case PPC::DCBTSTx:
752fefcfffeSHal Finkel   case PPC::DCBTSTT: {
753fefcfffeSHal Finkel     MCInst TmpInst;
754fefcfffeSHal Finkel     TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
755fefcfffeSHal Finkel                       PPC::DCBT : PPC::DCBTST);
756e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(
757fefcfffeSHal Finkel       (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
758fefcfffeSHal Finkel     TmpInst.addOperand(Inst.getOperand(0));
759fefcfffeSHal Finkel     TmpInst.addOperand(Inst.getOperand(1));
760fefcfffeSHal Finkel     Inst = TmpInst;
761fefcfffeSHal Finkel     break;
762fefcfffeSHal Finkel   }
763fefcfffeSHal Finkel   case PPC::DCBTCT:
764fefcfffeSHal Finkel   case PPC::DCBTDS: {
765fefcfffeSHal Finkel     MCInst TmpInst;
766fefcfffeSHal Finkel     TmpInst.setOpcode(PPC::DCBT);
767fefcfffeSHal Finkel     TmpInst.addOperand(Inst.getOperand(2));
768fefcfffeSHal Finkel     TmpInst.addOperand(Inst.getOperand(0));
769fefcfffeSHal Finkel     TmpInst.addOperand(Inst.getOperand(1));
770fefcfffeSHal Finkel     Inst = TmpInst;
771fefcfffeSHal Finkel     break;
772fefcfffeSHal Finkel   }
773fefcfffeSHal Finkel   case PPC::DCBTSTCT:
774fefcfffeSHal Finkel   case PPC::DCBTSTDS: {
775fefcfffeSHal Finkel     MCInst TmpInst;
776fefcfffeSHal Finkel     TmpInst.setOpcode(PPC::DCBTST);
777fefcfffeSHal Finkel     TmpInst.addOperand(Inst.getOperand(2));
778fefcfffeSHal Finkel     TmpInst.addOperand(Inst.getOperand(0));
779fefcfffeSHal Finkel     TmpInst.addOperand(Inst.getOperand(1));
780fefcfffeSHal Finkel     Inst = TmpInst;
781fefcfffeSHal Finkel     break;
782fefcfffeSHal Finkel   }
783277736eeSHal Finkel   case PPC::DCBFx:
784277736eeSHal Finkel   case PPC::DCBFL:
78528fdeea9SEsme-Yi   case PPC::DCBFLP:
78628fdeea9SEsme-Yi   case PPC::DCBFPS:
78728fdeea9SEsme-Yi   case PPC::DCBSTPS: {
788277736eeSHal Finkel     int L = 0;
789277736eeSHal Finkel     if (Opcode == PPC::DCBFL)
790277736eeSHal Finkel       L = 1;
791277736eeSHal Finkel     else if (Opcode == PPC::DCBFLP)
792277736eeSHal Finkel       L = 3;
79328fdeea9SEsme-Yi     else if (Opcode == PPC::DCBFPS)
79428fdeea9SEsme-Yi       L = 4;
79528fdeea9SEsme-Yi     else if (Opcode == PPC::DCBSTPS)
79628fdeea9SEsme-Yi       L = 6;
797277736eeSHal Finkel 
798277736eeSHal Finkel     MCInst TmpInst;
799277736eeSHal Finkel     TmpInst.setOpcode(PPC::DCBF);
800277736eeSHal Finkel     TmpInst.addOperand(MCOperand::createImm(L));
801277736eeSHal Finkel     TmpInst.addOperand(Inst.getOperand(0));
802277736eeSHal Finkel     TmpInst.addOperand(Inst.getOperand(1));
803277736eeSHal Finkel     Inst = TmpInst;
804277736eeSHal Finkel     break;
805277736eeSHal Finkel   }
8066ca71579SUlrich Weigand   case PPC::LAx: {
8076ca71579SUlrich Weigand     MCInst TmpInst;
8086ca71579SUlrich Weigand     TmpInst.setOpcode(PPC::LA);
8096ca71579SUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
8106ca71579SUlrich Weigand     TmpInst.addOperand(Inst.getOperand(2));
8116ca71579SUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
8126ca71579SUlrich Weigand     Inst = TmpInst;
8136ca71579SUlrich Weigand     break;
8146ca71579SUlrich Weigand   }
8154069e24bSUlrich Weigand   case PPC::SUBI: {
8164069e24bSUlrich Weigand     MCInst TmpInst;
8174069e24bSUlrich Weigand     TmpInst.setOpcode(PPC::ADDI);
8184069e24bSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
8194069e24bSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
8205aab5afcSJoerg Sonnenberger     addNegOperand(TmpInst, Inst.getOperand(2), getContext());
8214069e24bSUlrich Weigand     Inst = TmpInst;
8224069e24bSUlrich Weigand     break;
8234069e24bSUlrich Weigand   }
8244069e24bSUlrich Weigand   case PPC::SUBIS: {
8254069e24bSUlrich Weigand     MCInst TmpInst;
8264069e24bSUlrich Weigand     TmpInst.setOpcode(PPC::ADDIS);
8274069e24bSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
8284069e24bSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
8295aab5afcSJoerg Sonnenberger     addNegOperand(TmpInst, Inst.getOperand(2), getContext());
8304069e24bSUlrich Weigand     Inst = TmpInst;
8314069e24bSUlrich Weigand     break;
8324069e24bSUlrich Weigand   }
8334069e24bSUlrich Weigand   case PPC::SUBIC: {
8344069e24bSUlrich Weigand     MCInst TmpInst;
8354069e24bSUlrich Weigand     TmpInst.setOpcode(PPC::ADDIC);
8364069e24bSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
8374069e24bSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
8385aab5afcSJoerg Sonnenberger     addNegOperand(TmpInst, Inst.getOperand(2), getContext());
8394069e24bSUlrich Weigand     Inst = TmpInst;
8404069e24bSUlrich Weigand     break;
8414069e24bSUlrich Weigand   }
84224ee4edeSJinsong Ji   case PPC::SUBIC_rec: {
8434069e24bSUlrich Weigand     MCInst TmpInst;
84424ee4edeSJinsong Ji     TmpInst.setOpcode(PPC::ADDIC_rec);
8454069e24bSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
8464069e24bSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
8475aab5afcSJoerg Sonnenberger     addNegOperand(TmpInst, Inst.getOperand(2), getContext());
8484069e24bSUlrich Weigand     Inst = TmpInst;
8494069e24bSUlrich Weigand     break;
8504069e24bSUlrich Weigand   }
851ad873cdbSUlrich Weigand   case PPC::EXTLWI:
85224ee4edeSJinsong Ji   case PPC::EXTLWI_rec: {
853d839490fSUlrich Weigand     MCInst TmpInst;
854d839490fSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
855ad873cdbSUlrich Weigand     int64_t B = Inst.getOperand(3).getImm();
85624ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
857ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
858ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
859e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(B));
860e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(0));
861e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(N - 1));
862ad873cdbSUlrich Weigand     Inst = TmpInst;
863ad873cdbSUlrich Weigand     break;
864ad873cdbSUlrich Weigand   }
865ad873cdbSUlrich Weigand   case PPC::EXTRWI:
86624ee4edeSJinsong Ji   case PPC::EXTRWI_rec: {
867ad873cdbSUlrich Weigand     MCInst TmpInst;
868ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
869ad873cdbSUlrich Weigand     int64_t B = Inst.getOperand(3).getImm();
87024ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
871ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
872ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
873e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(B + N));
874e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(32 - N));
875e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(31));
876ad873cdbSUlrich Weigand     Inst = TmpInst;
877ad873cdbSUlrich Weigand     break;
878ad873cdbSUlrich Weigand   }
879ad873cdbSUlrich Weigand   case PPC::INSLWI:
88024ee4edeSJinsong Ji   case PPC::INSLWI_rec: {
881ad873cdbSUlrich Weigand     MCInst TmpInst;
882ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
883ad873cdbSUlrich Weigand     int64_t B = Inst.getOperand(3).getImm();
88424ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
885ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
886ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
887ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
888e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(32 - B));
889e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(B));
890e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
891ad873cdbSUlrich Weigand     Inst = TmpInst;
892ad873cdbSUlrich Weigand     break;
893ad873cdbSUlrich Weigand   }
894ad873cdbSUlrich Weigand   case PPC::INSRWI:
89524ee4edeSJinsong Ji   case PPC::INSRWI_rec: {
896ad873cdbSUlrich Weigand     MCInst TmpInst;
897ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
898ad873cdbSUlrich Weigand     int64_t B = Inst.getOperand(3).getImm();
89924ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
900ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
901ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
902ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
903e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(32 - (B + N)));
904e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(B));
905e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
906ad873cdbSUlrich Weigand     Inst = TmpInst;
907ad873cdbSUlrich Weigand     break;
908ad873cdbSUlrich Weigand   }
909ad873cdbSUlrich Weigand   case PPC::ROTRWI:
91024ee4edeSJinsong Ji   case PPC::ROTRWI_rec: {
911ad873cdbSUlrich Weigand     MCInst TmpInst;
912ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
91324ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
914ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
915ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
916e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(32 - N));
917e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(0));
918e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(31));
919ad873cdbSUlrich Weigand     Inst = TmpInst;
920ad873cdbSUlrich Weigand     break;
921ad873cdbSUlrich Weigand   }
922ad873cdbSUlrich Weigand   case PPC::SLWI:
92324ee4edeSJinsong Ji   case PPC::SLWI_rec: {
924ad873cdbSUlrich Weigand     MCInst TmpInst;
925ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
92624ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
927d839490fSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
928d839490fSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
929e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(N));
930e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(0));
931e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(31 - N));
932d839490fSUlrich Weigand     Inst = TmpInst;
933d839490fSUlrich Weigand     break;
934d839490fSUlrich Weigand   }
935ad873cdbSUlrich Weigand   case PPC::SRWI:
93624ee4edeSJinsong Ji   case PPC::SRWI_rec: {
937d839490fSUlrich Weigand     MCInst TmpInst;
938d839490fSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
93924ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
940d839490fSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
941d839490fSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
942e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(32 - N));
943e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(N));
944e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(31));
945d839490fSUlrich Weigand     Inst = TmpInst;
946d839490fSUlrich Weigand     break;
947d839490fSUlrich Weigand   }
948ad873cdbSUlrich Weigand   case PPC::CLRRWI:
94924ee4edeSJinsong Ji   case PPC::CLRRWI_rec: {
950d839490fSUlrich Weigand     MCInst TmpInst;
951d839490fSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
95224ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
953ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
954ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
955e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(0));
956e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(0));
957e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(31 - N));
958ad873cdbSUlrich Weigand     Inst = TmpInst;
959ad873cdbSUlrich Weigand     break;
960ad873cdbSUlrich Weigand   }
961ad873cdbSUlrich Weigand   case PPC::CLRLSLWI:
96224ee4edeSJinsong Ji   case PPC::CLRLSLWI_rec: {
963ad873cdbSUlrich Weigand     MCInst TmpInst;
964ad873cdbSUlrich Weigand     int64_t B = Inst.getOperand(2).getImm();
965ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(3).getImm();
96624ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
967ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
968ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
969e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(N));
970e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(B - N));
971e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(31 - N));
972ad873cdbSUlrich Weigand     Inst = TmpInst;
973ad873cdbSUlrich Weigand     break;
974ad873cdbSUlrich Weigand   }
975ad873cdbSUlrich Weigand   case PPC::EXTLDI:
97624ee4edeSJinsong Ji   case PPC::EXTLDI_rec: {
977ad873cdbSUlrich Weigand     MCInst TmpInst;
978ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
979ad873cdbSUlrich Weigand     int64_t B = Inst.getOperand(3).getImm();
98024ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
981ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
982ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
983e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(B));
984e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(N - 1));
985ad873cdbSUlrich Weigand     Inst = TmpInst;
986ad873cdbSUlrich Weigand     break;
987ad873cdbSUlrich Weigand   }
988ad873cdbSUlrich Weigand   case PPC::EXTRDI:
98924ee4edeSJinsong Ji   case PPC::EXTRDI_rec: {
990ad873cdbSUlrich Weigand     MCInst TmpInst;
991ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
992ad873cdbSUlrich Weigand     int64_t B = Inst.getOperand(3).getImm();
99324ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
994ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
995ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
996e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(B + N));
997e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(64 - N));
998ad873cdbSUlrich Weigand     Inst = TmpInst;
999ad873cdbSUlrich Weigand     break;
1000ad873cdbSUlrich Weigand   }
1001ad873cdbSUlrich Weigand   case PPC::INSRDI:
100224ee4edeSJinsong Ji   case PPC::INSRDI_rec: {
1003ad873cdbSUlrich Weigand     MCInst TmpInst;
1004ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
1005ad873cdbSUlrich Weigand     int64_t B = Inst.getOperand(3).getImm();
100624ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
1007ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
1008ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
1009ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
1010e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(64 - (B + N)));
1011e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(B));
1012ad873cdbSUlrich Weigand     Inst = TmpInst;
1013ad873cdbSUlrich Weigand     break;
1014ad873cdbSUlrich Weigand   }
1015ad873cdbSUlrich Weigand   case PPC::ROTRDI:
101624ee4edeSJinsong Ji   case PPC::ROTRDI_rec: {
1017ad873cdbSUlrich Weigand     MCInst TmpInst;
1018ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
101924ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1020ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
1021ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
1022e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(64 - N));
1023e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(0));
1024ad873cdbSUlrich Weigand     Inst = TmpInst;
1025ad873cdbSUlrich Weigand     break;
1026ad873cdbSUlrich Weigand   }
1027ad873cdbSUlrich Weigand   case PPC::SLDI:
102824ee4edeSJinsong Ji   case PPC::SLDI_rec: {
1029ad873cdbSUlrich Weigand     MCInst TmpInst;
1030ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
103124ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1032d839490fSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
1033d839490fSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
1034e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(N));
1035e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(63 - N));
1036d839490fSUlrich Weigand     Inst = TmpInst;
1037d839490fSUlrich Weigand     break;
1038d839490fSUlrich Weigand   }
1039425071efSTony Jiang   case PPC::SUBPCIS: {
1040425071efSTony Jiang     MCInst TmpInst;
1041425071efSTony Jiang     int64_t N = Inst.getOperand(1).getImm();
1042425071efSTony Jiang     TmpInst.setOpcode(PPC::ADDPCIS);
1043425071efSTony Jiang     TmpInst.addOperand(Inst.getOperand(0));
1044425071efSTony Jiang     TmpInst.addOperand(MCOperand::createImm(-N));
1045425071efSTony Jiang     Inst = TmpInst;
1046425071efSTony Jiang     break;
1047425071efSTony Jiang   }
1048ad873cdbSUlrich Weigand   case PPC::SRDI:
104924ee4edeSJinsong Ji   case PPC::SRDI_rec: {
1050d839490fSUlrich Weigand     MCInst TmpInst;
1051d839490fSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
105224ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1053d839490fSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
1054d839490fSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
1055e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(64 - N));
1056e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(N));
1057d839490fSUlrich Weigand     Inst = TmpInst;
1058d839490fSUlrich Weigand     break;
1059d839490fSUlrich Weigand   }
1060ad873cdbSUlrich Weigand   case PPC::CLRRDI:
106124ee4edeSJinsong Ji   case PPC::CLRRDI_rec: {
1062ad873cdbSUlrich Weigand     MCInst TmpInst;
1063ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(2).getImm();
106424ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
1065ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
1066ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
1067e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(0));
1068e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(63 - N));
1069ad873cdbSUlrich Weigand     Inst = TmpInst;
1070ad873cdbSUlrich Weigand     break;
1071ad873cdbSUlrich Weigand   }
1072ad873cdbSUlrich Weigand   case PPC::CLRLSLDI:
107324ee4edeSJinsong Ji   case PPC::CLRLSLDI_rec: {
1074ad873cdbSUlrich Weigand     MCInst TmpInst;
1075ad873cdbSUlrich Weigand     int64_t B = Inst.getOperand(2).getImm();
1076ad873cdbSUlrich Weigand     int64_t N = Inst.getOperand(3).getImm();
107724ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
1078ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(0));
1079ad873cdbSUlrich Weigand     TmpInst.addOperand(Inst.getOperand(1));
1080e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(N));
1081e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(B - N));
1082ad873cdbSUlrich Weigand     Inst = TmpInst;
1083ad873cdbSUlrich Weigand     break;
1084ad873cdbSUlrich Weigand   }
10856e9110abSHal Finkel   case PPC::RLWINMbm:
108624ee4edeSJinsong Ji   case PPC::RLWINMbm_rec: {
10876e9110abSHal Finkel     unsigned MB, ME;
10886e9110abSHal Finkel     int64_t BM = Inst.getOperand(3).getImm();
10896e9110abSHal Finkel     if (!isRunOfOnes(BM, MB, ME))
10906e9110abSHal Finkel       break;
10916e9110abSHal Finkel 
10926e9110abSHal Finkel     MCInst TmpInst;
109324ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
10946e9110abSHal Finkel     TmpInst.addOperand(Inst.getOperand(0));
10956e9110abSHal Finkel     TmpInst.addOperand(Inst.getOperand(1));
10966e9110abSHal Finkel     TmpInst.addOperand(Inst.getOperand(2));
1097e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(MB));
1098e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(ME));
10996e9110abSHal Finkel     Inst = TmpInst;
11006e9110abSHal Finkel     break;
11016e9110abSHal Finkel   }
11026e9110abSHal Finkel   case PPC::RLWIMIbm:
110324ee4edeSJinsong Ji   case PPC::RLWIMIbm_rec: {
11046e9110abSHal Finkel     unsigned MB, ME;
11056e9110abSHal Finkel     int64_t BM = Inst.getOperand(3).getImm();
11066e9110abSHal Finkel     if (!isRunOfOnes(BM, MB, ME))
11076e9110abSHal Finkel       break;
11086e9110abSHal Finkel 
11096e9110abSHal Finkel     MCInst TmpInst;
111024ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
11116e9110abSHal Finkel     TmpInst.addOperand(Inst.getOperand(0));
11126e9110abSHal Finkel     TmpInst.addOperand(Inst.getOperand(0)); // The tied operand.
11136e9110abSHal Finkel     TmpInst.addOperand(Inst.getOperand(1));
11146e9110abSHal Finkel     TmpInst.addOperand(Inst.getOperand(2));
1115e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(MB));
1116e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(ME));
11176e9110abSHal Finkel     Inst = TmpInst;
11186e9110abSHal Finkel     break;
11196e9110abSHal Finkel   }
11206e9110abSHal Finkel   case PPC::RLWNMbm:
112124ee4edeSJinsong Ji   case PPC::RLWNMbm_rec: {
11226e9110abSHal Finkel     unsigned MB, ME;
11236e9110abSHal Finkel     int64_t BM = Inst.getOperand(3).getImm();
11246e9110abSHal Finkel     if (!isRunOfOnes(BM, MB, ME))
11256e9110abSHal Finkel       break;
11266e9110abSHal Finkel 
11276e9110abSHal Finkel     MCInst TmpInst;
112824ee4edeSJinsong Ji     TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
11296e9110abSHal Finkel     TmpInst.addOperand(Inst.getOperand(0));
11306e9110abSHal Finkel     TmpInst.addOperand(Inst.getOperand(1));
11316e9110abSHal Finkel     TmpInst.addOperand(Inst.getOperand(2));
1132e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(MB));
1133e9119e41SJim Grosbach     TmpInst.addOperand(MCOperand::createImm(ME));
11346e9110abSHal Finkel     Inst = TmpInst;
11356e9110abSHal Finkel     break;
11366e9110abSHal Finkel   }
11374f79f96fSKit Barton   case PPC::MFTB: {
1138bd9fc284SAkira Hatanaka     if (getSTI().getFeatureBits()[PPC::FeatureMFTB]) {
11394f79f96fSKit Barton       assert(Inst.getNumOperands() == 2 && "Expecting two operands");
11404f79f96fSKit Barton       Inst.setOpcode(PPC::MFSPR);
11414f79f96fSKit Barton     }
11424f79f96fSKit Barton     break;
11434f79f96fSKit Barton   }
1144d839490fSUlrich Weigand   }
1145d839490fSUlrich Weigand }
1146d839490fSUlrich Weigand 
1147e98944edSStanislav Mekhanoshin static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
1148e86a8b79SHal Finkel                                          unsigned VariantID = 0);
1149e86a8b79SHal Finkel 
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)1150960ea3f0SDavid Blaikie bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1151960ea3f0SDavid Blaikie                                            OperandVector &Operands,
115226bb14e6STim Northover                                            MCStreamer &Out, uint64_t &ErrorInfo,
1153640192daSUlrich Weigand                                            bool MatchingInlineAsm) {
1154640192daSUlrich Weigand   MCInst Inst;
1155640192daSUlrich Weigand 
115686ecbb7bSRanjeet Singh   switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
1157640192daSUlrich Weigand   case Match_Success:
1158d839490fSUlrich Weigand     // Post-process instructions (typically extended mnemonics)
1159d839490fSUlrich Weigand     ProcessInstruction(Inst, Operands);
1160640192daSUlrich Weigand     Inst.setLoc(IDLoc);
1161bcd24b2dSFangrui Song     Out.emitInstruction(Inst, getSTI());
1162640192daSUlrich Weigand     return false;
1163640192daSUlrich Weigand   case Match_MissingFeature:
1164640192daSUlrich Weigand     return Error(IDLoc, "instruction use requires an option to be enabled");
1165e86a8b79SHal Finkel   case Match_MnemonicFail: {
1166e98944edSStanislav Mekhanoshin     FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1167e86a8b79SHal Finkel     std::string Suggestion = PPCMnemonicSpellCheck(
1168e86a8b79SHal Finkel         ((PPCOperand &)*Operands[0]).getToken(), FBS);
1169e86a8b79SHal Finkel     return Error(IDLoc, "invalid instruction" + Suggestion,
1170e86a8b79SHal Finkel                  ((PPCOperand &)*Operands[0]).getLocRange());
1171e86a8b79SHal Finkel   }
1172640192daSUlrich Weigand   case Match_InvalidOperand: {
1173640192daSUlrich Weigand     SMLoc ErrorLoc = IDLoc;
117426bb14e6STim Northover     if (ErrorInfo != ~0ULL) {
1175640192daSUlrich Weigand       if (ErrorInfo >= Operands.size())
1176640192daSUlrich Weigand         return Error(IDLoc, "too few operands for instruction");
1177640192daSUlrich Weigand 
1178960ea3f0SDavid Blaikie       ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();
1179640192daSUlrich Weigand       if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1180640192daSUlrich Weigand     }
1181640192daSUlrich Weigand 
1182640192daSUlrich Weigand     return Error(ErrorLoc, "invalid operand for instruction");
1183640192daSUlrich Weigand   }
1184640192daSUlrich Weigand   }
1185640192daSUlrich Weigand 
1186640192daSUlrich Weigand   llvm_unreachable("Implement any new match types added!");
1187640192daSUlrich Weigand }
1188640192daSUlrich Weigand 
MatchRegisterName(unsigned & RegNo,int64_t & IntVal)1189d6642c11SNirav Dave bool PPCAsmParser::MatchRegisterName(unsigned &RegNo, int64_t &IntVal) {
1190b2f66307SBill Wendling   if (getParser().getTok().is(AsmToken::Percent))
1191b2f66307SBill Wendling     getParser().Lex(); // Eat the '%'.
1192b2f66307SBill Wendling 
1193b2f66307SBill Wendling   if (!getParser().getTok().is(AsmToken::Identifier))
1194b2f66307SBill Wendling     return true;
1195b2f66307SBill Wendling 
1196d6642c11SNirav Dave   StringRef Name = getParser().getTok().getString();
119742f74e82SMartin Storsjö   if (Name.equals_insensitive("lr")) {
1198640192daSUlrich Weigand     RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
1199640192daSUlrich Weigand     IntVal = 8;
120042f74e82SMartin Storsjö   } else if (Name.equals_insensitive("ctr")) {
1201640192daSUlrich Weigand     RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
1202640192daSUlrich Weigand     IntVal = 9;
120342f74e82SMartin Storsjö   } else if (Name.equals_insensitive("vrsave")) {
120452727c6bSHal Finkel     RegNo = PPC::VRSAVE;
120552727c6bSHal Finkel     IntVal = 256;
120642f74e82SMartin Storsjö   } else if (Name.startswith_insensitive("r") &&
1207640192daSUlrich Weigand              !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1208640192daSUlrich Weigand     RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];
120942f74e82SMartin Storsjö   } else if (Name.startswith_insensitive("f") &&
1210640192daSUlrich Weigand              !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1211640192daSUlrich Weigand     RegNo = FRegs[IntVal];
121242f74e82SMartin Storsjö   } else if (Name.startswith_insensitive("vs") &&
12134dc8fcc2SHal Finkel              !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
12144dc8fcc2SHal Finkel     RegNo = VSRegs[IntVal];
121542f74e82SMartin Storsjö   } else if (Name.startswith_insensitive("v") &&
1216640192daSUlrich Weigand              !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1217640192daSUlrich Weigand     RegNo = VRegs[IntVal];
121842f74e82SMartin Storsjö   } else if (Name.startswith_insensitive("cr") &&
1219640192daSUlrich Weigand              !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
1220640192daSUlrich Weigand     RegNo = CRRegs[IntVal];
1221d6642c11SNirav Dave   } else
1222d6642c11SNirav Dave     return true;
1223d6642c11SNirav Dave   getParser().Lex();
1224640192daSUlrich Weigand   return false;
1225640192daSUlrich Weigand }
1226640192daSUlrich Weigand 
1227640192daSUlrich Weigand bool PPCAsmParser::
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)1228640192daSUlrich Weigand ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) {
12298d5bf042SEric Astor   if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success)
12308d5bf042SEric Astor     return TokError("invalid register name");
12318d5bf042SEric Astor   return false;
12328d5bf042SEric Astor }
12338d5bf042SEric Astor 
tryParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)12348d5bf042SEric Astor OperandMatchResultTy PPCAsmParser::tryParseRegister(unsigned &RegNo,
12358d5bf042SEric Astor                                                     SMLoc &StartLoc,
12368d5bf042SEric Astor                                                     SMLoc &EndLoc) {
1237d6642c11SNirav Dave   const AsmToken &Tok = getParser().getTok();
1238640192daSUlrich Weigand   StartLoc = Tok.getLoc();
1239640192daSUlrich Weigand   EndLoc = Tok.getEndLoc();
1240640192daSUlrich Weigand   RegNo = 0;
1241640192daSUlrich Weigand   int64_t IntVal;
1242d6642c11SNirav Dave   if (MatchRegisterName(RegNo, IntVal))
12438d5bf042SEric Astor     return MatchOperand_NoMatch;
12448d5bf042SEric Astor   return MatchOperand_Success;
1245640192daSUlrich Weigand }
1246640192daSUlrich Weigand 
124736c17ee5SNAKAMURA Takumi /// Extract \code @l/@ha \endcode modifier from expression.  Recursively scan
1248e67c565dSUlrich Weigand /// the expression and check for VK_PPC_LO/HI/HA
124996e65783SUlrich Weigand /// symbol variants.  If all symbols with modifier use the same
125096e65783SUlrich Weigand /// variant, return the corresponding PPCMCExpr::VariantKind,
125196e65783SUlrich Weigand /// and a modified expression using the default symbol variant.
125296e65783SUlrich Weigand /// Otherwise, return NULL.
125396e65783SUlrich Weigand const MCExpr *PPCAsmParser::
ExtractModifierFromExpr(const MCExpr * E,PPCMCExpr::VariantKind & Variant)125496e65783SUlrich Weigand ExtractModifierFromExpr(const MCExpr *E,
125596e65783SUlrich Weigand                         PPCMCExpr::VariantKind &Variant) {
125696e65783SUlrich Weigand   MCContext &Context = getParser().getContext();
125796e65783SUlrich Weigand   Variant = PPCMCExpr::VK_PPC_None;
125896e65783SUlrich Weigand 
125996e65783SUlrich Weigand   switch (E->getKind()) {
126096e65783SUlrich Weigand   case MCExpr::Target:
126196e65783SUlrich Weigand   case MCExpr::Constant:
1262062a2baeSCraig Topper     return nullptr;
126396e65783SUlrich Weigand 
126496e65783SUlrich Weigand   case MCExpr::SymbolRef: {
126596e65783SUlrich Weigand     const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
126696e65783SUlrich Weigand 
126796e65783SUlrich Weigand     switch (SRE->getKind()) {
1268d51c09f5SUlrich Weigand     case MCSymbolRefExpr::VK_PPC_LO:
1269d51c09f5SUlrich Weigand       Variant = PPCMCExpr::VK_PPC_LO;
127096e65783SUlrich Weigand       break;
1271e67c565dSUlrich Weigand     case MCSymbolRefExpr::VK_PPC_HI:
1272e67c565dSUlrich Weigand       Variant = PPCMCExpr::VK_PPC_HI;
1273e67c565dSUlrich Weigand       break;
1274d51c09f5SUlrich Weigand     case MCSymbolRefExpr::VK_PPC_HA:
1275d51c09f5SUlrich Weigand       Variant = PPCMCExpr::VK_PPC_HA;
127696e65783SUlrich Weigand       break;
127780b8f82fSSean Fertile     case MCSymbolRefExpr::VK_PPC_HIGH:
127880b8f82fSSean Fertile       Variant = PPCMCExpr::VK_PPC_HIGH;
127980b8f82fSSean Fertile       break;
128080b8f82fSSean Fertile     case MCSymbolRefExpr::VK_PPC_HIGHA:
128180b8f82fSSean Fertile       Variant = PPCMCExpr::VK_PPC_HIGHA;
128280b8f82fSSean Fertile       break;
1283e9126f55SUlrich Weigand     case MCSymbolRefExpr::VK_PPC_HIGHER:
1284e9126f55SUlrich Weigand       Variant = PPCMCExpr::VK_PPC_HIGHER;
1285e9126f55SUlrich Weigand       break;
1286e9126f55SUlrich Weigand     case MCSymbolRefExpr::VK_PPC_HIGHERA:
1287e9126f55SUlrich Weigand       Variant = PPCMCExpr::VK_PPC_HIGHERA;
1288e9126f55SUlrich Weigand       break;
1289e9126f55SUlrich Weigand     case MCSymbolRefExpr::VK_PPC_HIGHEST:
1290e9126f55SUlrich Weigand       Variant = PPCMCExpr::VK_PPC_HIGHEST;
1291e9126f55SUlrich Weigand       break;
1292e9126f55SUlrich Weigand     case MCSymbolRefExpr::VK_PPC_HIGHESTA:
1293e9126f55SUlrich Weigand       Variant = PPCMCExpr::VK_PPC_HIGHESTA;
1294e9126f55SUlrich Weigand       break;
129596e65783SUlrich Weigand     default:
1296062a2baeSCraig Topper       return nullptr;
129796e65783SUlrich Weigand     }
129896e65783SUlrich Weigand 
129913760bd1SJim Grosbach     return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);
130096e65783SUlrich Weigand   }
130196e65783SUlrich Weigand 
130296e65783SUlrich Weigand   case MCExpr::Unary: {
130396e65783SUlrich Weigand     const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
130496e65783SUlrich Weigand     const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant);
130596e65783SUlrich Weigand     if (!Sub)
1306062a2baeSCraig Topper       return nullptr;
130713760bd1SJim Grosbach     return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
130896e65783SUlrich Weigand   }
130996e65783SUlrich Weigand 
131096e65783SUlrich Weigand   case MCExpr::Binary: {
131196e65783SUlrich Weigand     const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
131296e65783SUlrich Weigand     PPCMCExpr::VariantKind LHSVariant, RHSVariant;
131396e65783SUlrich Weigand     const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant);
131496e65783SUlrich Weigand     const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant);
131596e65783SUlrich Weigand 
131696e65783SUlrich Weigand     if (!LHS && !RHS)
1317062a2baeSCraig Topper       return nullptr;
131896e65783SUlrich Weigand 
131996e65783SUlrich Weigand     if (!LHS) LHS = BE->getLHS();
132096e65783SUlrich Weigand     if (!RHS) RHS = BE->getRHS();
132196e65783SUlrich Weigand 
132296e65783SUlrich Weigand     if (LHSVariant == PPCMCExpr::VK_PPC_None)
132396e65783SUlrich Weigand       Variant = RHSVariant;
132496e65783SUlrich Weigand     else if (RHSVariant == PPCMCExpr::VK_PPC_None)
132596e65783SUlrich Weigand       Variant = LHSVariant;
132696e65783SUlrich Weigand     else if (LHSVariant == RHSVariant)
132796e65783SUlrich Weigand       Variant = LHSVariant;
132896e65783SUlrich Weigand     else
1329062a2baeSCraig Topper       return nullptr;
133096e65783SUlrich Weigand 
133113760bd1SJim Grosbach     return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
133296e65783SUlrich Weigand   }
133396e65783SUlrich Weigand   }
133496e65783SUlrich Weigand 
133596e65783SUlrich Weigand   llvm_unreachable("Invalid expression kind!");
133696e65783SUlrich Weigand }
133796e65783SUlrich Weigand 
133852cf8e44SUlrich Weigand /// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace
133952cf8e44SUlrich Weigand /// them by VK_PPC_TLSGD/VK_PPC_TLSLD.  This is necessary to avoid having
134052cf8e44SUlrich Weigand /// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT.
134152cf8e44SUlrich Weigand /// FIXME: This is a hack.
134252cf8e44SUlrich Weigand const MCExpr *PPCAsmParser::
FixupVariantKind(const MCExpr * E)134352cf8e44SUlrich Weigand FixupVariantKind(const MCExpr *E) {
134452cf8e44SUlrich Weigand   MCContext &Context = getParser().getContext();
134552cf8e44SUlrich Weigand 
134652cf8e44SUlrich Weigand   switch (E->getKind()) {
134752cf8e44SUlrich Weigand   case MCExpr::Target:
134852cf8e44SUlrich Weigand   case MCExpr::Constant:
134952cf8e44SUlrich Weigand     return E;
135052cf8e44SUlrich Weigand 
135152cf8e44SUlrich Weigand   case MCExpr::SymbolRef: {
135252cf8e44SUlrich Weigand     const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
135352cf8e44SUlrich Weigand     MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
135452cf8e44SUlrich Weigand 
135552cf8e44SUlrich Weigand     switch (SRE->getKind()) {
135652cf8e44SUlrich Weigand     case MCSymbolRefExpr::VK_TLSGD:
135752cf8e44SUlrich Weigand       Variant = MCSymbolRefExpr::VK_PPC_TLSGD;
135852cf8e44SUlrich Weigand       break;
135952cf8e44SUlrich Weigand     case MCSymbolRefExpr::VK_TLSLD:
136052cf8e44SUlrich Weigand       Variant = MCSymbolRefExpr::VK_PPC_TLSLD;
136152cf8e44SUlrich Weigand       break;
136252cf8e44SUlrich Weigand     default:
136352cf8e44SUlrich Weigand       return E;
136452cf8e44SUlrich Weigand     }
136513760bd1SJim Grosbach     return MCSymbolRefExpr::create(&SRE->getSymbol(), Variant, Context);
136652cf8e44SUlrich Weigand   }
136752cf8e44SUlrich Weigand 
136852cf8e44SUlrich Weigand   case MCExpr::Unary: {
136952cf8e44SUlrich Weigand     const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
137052cf8e44SUlrich Weigand     const MCExpr *Sub = FixupVariantKind(UE->getSubExpr());
137152cf8e44SUlrich Weigand     if (Sub == UE->getSubExpr())
137252cf8e44SUlrich Weigand       return E;
137313760bd1SJim Grosbach     return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
137452cf8e44SUlrich Weigand   }
137552cf8e44SUlrich Weigand 
137652cf8e44SUlrich Weigand   case MCExpr::Binary: {
137752cf8e44SUlrich Weigand     const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
137852cf8e44SUlrich Weigand     const MCExpr *LHS = FixupVariantKind(BE->getLHS());
137952cf8e44SUlrich Weigand     const MCExpr *RHS = FixupVariantKind(BE->getRHS());
138052cf8e44SUlrich Weigand     if (LHS == BE->getLHS() && RHS == BE->getRHS())
138152cf8e44SUlrich Weigand       return E;
138213760bd1SJim Grosbach     return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
138352cf8e44SUlrich Weigand   }
138452cf8e44SUlrich Weigand   }
138552cf8e44SUlrich Weigand 
138652cf8e44SUlrich Weigand   llvm_unreachable("Invalid expression kind!");
138752cf8e44SUlrich Weigand }
138852cf8e44SUlrich Weigand 
1389e0b4cb62SIain Sandoe /// ParseExpression.  This differs from the default "parseExpression" in that
1390e0b4cb62SIain Sandoe /// it handles modifiers.
139196e65783SUlrich Weigand bool PPCAsmParser::
ParseExpression(const MCExpr * & EVal)139296e65783SUlrich Weigand ParseExpression(const MCExpr *&EVal) {
1393e0b4cb62SIain Sandoe   // (ELF Platforms)
1394e0b4cb62SIain Sandoe   // Handle \code @l/@ha \endcode
139596e65783SUlrich Weigand   if (getParser().parseExpression(EVal))
139696e65783SUlrich Weigand     return true;
139796e65783SUlrich Weigand 
139852cf8e44SUlrich Weigand   EVal = FixupVariantKind(EVal);
139952cf8e44SUlrich Weigand 
140096e65783SUlrich Weigand   PPCMCExpr::VariantKind Variant;
140196e65783SUlrich Weigand   const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
140296e65783SUlrich Weigand   if (E)
1403a50567a3SFangrui Song     EVal = PPCMCExpr::create(Variant, E, getParser().getContext());
140496e65783SUlrich Weigand 
140596e65783SUlrich Weigand   return false;
140696e65783SUlrich Weigand }
140796e65783SUlrich Weigand 
1408e0b4cb62SIain Sandoe /// ParseOperand
1409e0b4cb62SIain Sandoe /// This handles registers in the form 'NN', '%rNN' for ELF platforms and
1410e0b4cb62SIain Sandoe /// rNN for MachO.
ParseOperand(OperandVector & Operands)1411960ea3f0SDavid Blaikie bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
1412961d4694SRafael Espindola   MCAsmParser &Parser = getParser();
1413640192daSUlrich Weigand   SMLoc S = Parser.getTok().getLoc();
1414640192daSUlrich Weigand   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1415640192daSUlrich Weigand   const MCExpr *EVal;
1416640192daSUlrich Weigand 
1417640192daSUlrich Weigand   // Attempt to parse the next token as an immediate
1418640192daSUlrich Weigand   switch (getLexer().getKind()) {
1419640192daSUlrich Weigand   // Special handling for register names.  These are interpreted
1420640192daSUlrich Weigand   // as immediates corresponding to the register number.
1421b2f66307SBill Wendling   case AsmToken::Percent: {
1422640192daSUlrich Weigand     unsigned RegNo;
1423640192daSUlrich Weigand     int64_t IntVal;
1424d6642c11SNirav Dave     if (MatchRegisterName(RegNo, IntVal))
1425640192daSUlrich Weigand       return Error(S, "invalid register name");
1426640192daSUlrich Weigand 
1427960ea3f0SDavid Blaikie     Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
1428e0b4cb62SIain Sandoe     return false;
1429b2f66307SBill Wendling   }
1430d6642c11SNirav Dave   case AsmToken::Identifier:
1431640192daSUlrich Weigand   case AsmToken::LParen:
1432640192daSUlrich Weigand   case AsmToken::Plus:
1433640192daSUlrich Weigand   case AsmToken::Minus:
1434640192daSUlrich Weigand   case AsmToken::Integer:
1435640192daSUlrich Weigand   case AsmToken::Dot:
1436640192daSUlrich Weigand   case AsmToken::Dollar:
1437a26f9a6aSRoman Divacky   case AsmToken::Exclaim:
1438a26f9a6aSRoman Divacky   case AsmToken::Tilde:
143996e65783SUlrich Weigand     if (!ParseExpression(EVal))
1440640192daSUlrich Weigand       break;
1441d6642c11SNirav Dave     // Fall-through
1442d6642c11SNirav Dave     LLVM_FALLTHROUGH;
1443640192daSUlrich Weigand   default:
1444640192daSUlrich Weigand     return Error(S, "unknown operand");
1445640192daSUlrich Weigand   }
1446640192daSUlrich Weigand 
1447640192daSUlrich Weigand   // Push the parsed operand into the list of operands
1448960ea3f0SDavid Blaikie   Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));
1449640192daSUlrich Weigand 
145042a09dc1SUlrich Weigand   // Check whether this is a TLS call expression
145142a09dc1SUlrich Weigand   bool TLSCall = false;
145242a09dc1SUlrich Weigand   if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(EVal))
145342a09dc1SUlrich Weigand     TLSCall = Ref->getSymbol().getName() == "__tls_get_addr";
145442a09dc1SUlrich Weigand 
145542a09dc1SUlrich Weigand   if (TLSCall && getLexer().is(AsmToken::LParen)) {
145642a09dc1SUlrich Weigand     const MCExpr *TLSSym;
145742a09dc1SUlrich Weigand 
145842a09dc1SUlrich Weigand     Parser.Lex(); // Eat the '('.
145942a09dc1SUlrich Weigand     S = Parser.getTok().getLoc();
146042a09dc1SUlrich Weigand     if (ParseExpression(TLSSym))
146142a09dc1SUlrich Weigand       return Error(S, "invalid TLS call expression");
146242a09dc1SUlrich Weigand     if (getLexer().isNot(AsmToken::RParen))
146342a09dc1SUlrich Weigand       return Error(Parser.getTok().getLoc(), "missing ')'");
146442a09dc1SUlrich Weigand     E = Parser.getTok().getLoc();
146542a09dc1SUlrich Weigand     Parser.Lex(); // Eat the ')'.
146642a09dc1SUlrich Weigand 
1467960ea3f0SDavid Blaikie     Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));
146842a09dc1SUlrich Weigand   }
146942a09dc1SUlrich Weigand 
147042a09dc1SUlrich Weigand   // Otherwise, check for D-form memory operands
147142a09dc1SUlrich Weigand   if (!TLSCall && getLexer().is(AsmToken::LParen)) {
1472640192daSUlrich Weigand     Parser.Lex(); // Eat the '('.
1473640192daSUlrich Weigand     S = Parser.getTok().getLoc();
1474640192daSUlrich Weigand 
1475640192daSUlrich Weigand     int64_t IntVal;
1476640192daSUlrich Weigand     switch (getLexer().getKind()) {
1477b2f66307SBill Wendling     case AsmToken::Percent: {
1478640192daSUlrich Weigand       unsigned RegNo;
1479d6642c11SNirav Dave       if (MatchRegisterName(RegNo, IntVal))
1480640192daSUlrich Weigand         return Error(S, "invalid register name");
1481640192daSUlrich Weigand       break;
1482b2f66307SBill Wendling     }
1483640192daSUlrich Weigand     case AsmToken::Integer:
14847c4555f6SFangrui Song       if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
1485d6642c11SNirav Dave           IntVal > 31)
1486d6642c11SNirav Dave         return Error(S, "invalid register number");
1487640192daSUlrich Weigand       break;
1488e0b4cb62SIain Sandoe     case AsmToken::Identifier:
1489640192daSUlrich Weigand     default:
1490640192daSUlrich Weigand       return Error(S, "invalid memory operand");
1491640192daSUlrich Weigand     }
1492640192daSUlrich Weigand 
1493640192daSUlrich Weigand     E = Parser.getTok().getLoc();
1494d6642c11SNirav Dave     if (parseToken(AsmToken::RParen, "missing ')'"))
1495d6642c11SNirav Dave       return true;
1496960ea3f0SDavid Blaikie     Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
1497640192daSUlrich Weigand   }
1498640192daSUlrich Weigand 
1499640192daSUlrich Weigand   return false;
1500640192daSUlrich Weigand }
1501640192daSUlrich Weigand 
1502640192daSUlrich Weigand /// Parse an instruction mnemonic followed by its operands.
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)1503960ea3f0SDavid Blaikie bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1504960ea3f0SDavid Blaikie                                     SMLoc NameLoc, OperandVector &Operands) {
1505640192daSUlrich Weigand   // The first operand is the token for the instruction name.
150686247b6eSUlrich Weigand   // If the next character is a '+' or '-', we need to add it to the
150786247b6eSUlrich Weigand   // instruction name, to match what TableGen is doing.
150872d45cc8SBenjamin Kramer   std::string NewOpcode;
1509d6642c11SNirav Dave   if (parseOptionalToken(AsmToken::Plus)) {
1510adcd0268SBenjamin Kramer     NewOpcode = std::string(Name);
151172d45cc8SBenjamin Kramer     NewOpcode += '+';
151272d45cc8SBenjamin Kramer     Name = NewOpcode;
151386247b6eSUlrich Weigand   }
1514d6642c11SNirav Dave   if (parseOptionalToken(AsmToken::Minus)) {
1515adcd0268SBenjamin Kramer     NewOpcode = std::string(Name);
151672d45cc8SBenjamin Kramer     NewOpcode += '-';
151772d45cc8SBenjamin Kramer     Name = NewOpcode;
151886247b6eSUlrich Weigand   }
1519640192daSUlrich Weigand   // If the instruction ends in a '.', we need to create a separate
1520640192daSUlrich Weigand   // token for it, to match what TableGen is doing.
1521640192daSUlrich Weigand   size_t Dot = Name.find('.');
1522640192daSUlrich Weigand   StringRef Mnemonic = Name.slice(0, Dot);
152372d45cc8SBenjamin Kramer   if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
152472d45cc8SBenjamin Kramer     Operands.push_back(
152572d45cc8SBenjamin Kramer         PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
152672d45cc8SBenjamin Kramer   else
1527640192daSUlrich Weigand     Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
1528640192daSUlrich Weigand   if (Dot != StringRef::npos) {
1529640192daSUlrich Weigand     SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);
1530640192daSUlrich Weigand     StringRef DotStr = Name.slice(Dot, StringRef::npos);
153172d45cc8SBenjamin Kramer     if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
153272d45cc8SBenjamin Kramer       Operands.push_back(
153372d45cc8SBenjamin Kramer           PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
153472d45cc8SBenjamin Kramer     else
1535640192daSUlrich Weigand       Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
1536640192daSUlrich Weigand   }
1537640192daSUlrich Weigand 
1538640192daSUlrich Weigand   // If there are no more operands then finish
1539d6642c11SNirav Dave   if (parseOptionalToken(AsmToken::EndOfStatement))
1540640192daSUlrich Weigand     return false;
1541640192daSUlrich Weigand 
1542640192daSUlrich Weigand   // Parse the first operand
1543640192daSUlrich Weigand   if (ParseOperand(Operands))
1544640192daSUlrich Weigand     return true;
1545640192daSUlrich Weigand 
1546d6642c11SNirav Dave   while (!parseOptionalToken(AsmToken::EndOfStatement)) {
1547d6642c11SNirav Dave     if (parseToken(AsmToken::Comma) || ParseOperand(Operands))
1548640192daSUlrich Weigand       return true;
1549640192daSUlrich Weigand   }
1550640192daSUlrich Weigand 
1551fefcfffeSHal Finkel   // We'll now deal with an unfortunate special case: the syntax for the dcbt
1552fefcfffeSHal Finkel   // and dcbtst instructions differs for server vs. embedded cores.
1553fefcfffeSHal Finkel   //  The syntax for dcbt is:
1554fefcfffeSHal Finkel   //    dcbt ra, rb, th [server]
1555fefcfffeSHal Finkel   //    dcbt th, ra, rb [embedded]
1556fefcfffeSHal Finkel   //  where th can be omitted when it is 0. dcbtst is the same. We take the
1557fefcfffeSHal Finkel   //  server form to be the default, so swap the operands if we're parsing for
1558fefcfffeSHal Finkel   //  an embedded core (they'll be swapped again upon printing).
1559bd9fc284SAkira Hatanaka   if (getSTI().getFeatureBits()[PPC::FeatureBookE] &&
1560fefcfffeSHal Finkel       Operands.size() == 4 &&
1561fefcfffeSHal Finkel       (Name == "dcbt" || Name == "dcbtst")) {
1562fefcfffeSHal Finkel     std::swap(Operands[1], Operands[3]);
1563fefcfffeSHal Finkel     std::swap(Operands[2], Operands[1]);
1564fefcfffeSHal Finkel   }
1565fefcfffeSHal Finkel 
1566d6c0ef78SNemanja Ivanovic   // Handle base mnemonic for atomic loads where the EH bit is zero.
1567d6c0ef78SNemanja Ivanovic   if (Name == "lqarx" || Name == "ldarx" || Name == "lwarx" ||
1568d6c0ef78SNemanja Ivanovic       Name == "lharx" || Name == "lbarx") {
1569d6c0ef78SNemanja Ivanovic     if (Operands.size() != 5)
1570d6c0ef78SNemanja Ivanovic       return false;
1571d6c0ef78SNemanja Ivanovic     PPCOperand &EHOp = (PPCOperand &)*Operands[4];
1572d6c0ef78SNemanja Ivanovic     if (EHOp.isU1Imm() && EHOp.getImm() == 0)
1573d6c0ef78SNemanja Ivanovic       Operands.pop_back();
1574d6c0ef78SNemanja Ivanovic   }
1575d6c0ef78SNemanja Ivanovic 
1576640192daSUlrich Weigand   return false;
1577640192daSUlrich Weigand }
1578640192daSUlrich Weigand 
1579640192daSUlrich Weigand /// ParseDirective parses the PPC specific directives
ParseDirective(AsmToken DirectiveID)1580640192daSUlrich Weigand bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {
1581640192daSUlrich Weigand   StringRef IDVal = DirectiveID.getIdentifier();
15827c4555f6SFangrui Song   if (IDVal == ".word")
1583d6642c11SNirav Dave     ParseDirectiveWord(2, DirectiveID);
1584d6642c11SNirav Dave   else if (IDVal == ".llong")
1585d6642c11SNirav Dave     ParseDirectiveWord(8, DirectiveID);
1586d6642c11SNirav Dave   else if (IDVal == ".tc")
1587d6642c11SNirav Dave     ParseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);
1588d6642c11SNirav Dave   else if (IDVal == ".machine")
1589d6642c11SNirav Dave     ParseDirectiveMachine(DirectiveID.getLoc());
1590d6642c11SNirav Dave   else if (IDVal == ".abiversion")
1591d6642c11SNirav Dave     ParseDirectiveAbiVersion(DirectiveID.getLoc());
1592d6642c11SNirav Dave   else if (IDVal == ".localentry")
1593d6642c11SNirav Dave     ParseDirectiveLocalEntry(DirectiveID.getLoc());
159400d68c38SQiu Chaofan   else if (IDVal.startswith(".gnu_attribute"))
159500d68c38SQiu Chaofan     ParseGNUAttribute(DirectiveID.getLoc());
1596d6642c11SNirav Dave   else
1597d6642c11SNirav Dave     return true;
1598d6642c11SNirav Dave   return false;
1599640192daSUlrich Weigand }
1600640192daSUlrich Weigand 
1601640192daSUlrich Weigand /// ParseDirectiveWord
1602640192daSUlrich Weigand ///  ::= .word [ expression (, expression)* ]
ParseDirectiveWord(unsigned Size,AsmToken ID)1603d6642c11SNirav Dave bool PPCAsmParser::ParseDirectiveWord(unsigned Size, AsmToken ID) {
1604d6642c11SNirav Dave   auto parseOp = [&]() -> bool {
1605640192daSUlrich Weigand     const MCExpr *Value;
1606d6642c11SNirav Dave     SMLoc ExprLoc = getParser().getTok().getLoc();
1607640192daSUlrich Weigand     if (getParser().parseExpression(Value))
1608d6642c11SNirav Dave       return true;
1609a375b261SDavid Majnemer     if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
1610a375b261SDavid Majnemer       assert(Size <= 8 && "Invalid size");
1611a375b261SDavid Majnemer       uint64_t IntValue = MCE->getValue();
1612a375b261SDavid Majnemer       if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
1613d6642c11SNirav Dave         return Error(ExprLoc, "literal value out of range for '" +
1614d6642c11SNirav Dave                                   ID.getIdentifier() + "' directive");
161577497103SFangrui Song       getStreamer().emitIntValue(IntValue, Size);
1616d6642c11SNirav Dave     } else
161777497103SFangrui Song       getStreamer().emitValue(Value, Size, ExprLoc);
1618d6642c11SNirav Dave     return false;
1619d6642c11SNirav Dave   };
1620640192daSUlrich Weigand 
1621d6642c11SNirav Dave   if (parseMany(parseOp))
1622d6642c11SNirav Dave     return addErrorSuffix(" in '" + ID.getIdentifier() + "' directive");
1623640192daSUlrich Weigand   return false;
1624640192daSUlrich Weigand }
1625640192daSUlrich Weigand 
1626640192daSUlrich Weigand /// ParseDirectiveTC
1627640192daSUlrich Weigand ///  ::= .tc [ symbol (, expression)* ]
ParseDirectiveTC(unsigned Size,AsmToken ID)1628d6642c11SNirav Dave bool PPCAsmParser::ParseDirectiveTC(unsigned Size, AsmToken ID) {
1629961d4694SRafael Espindola   MCAsmParser &Parser = getParser();
1630640192daSUlrich Weigand   // Skip TC symbol, which is only used with XCOFF.
1631640192daSUlrich Weigand   while (getLexer().isNot(AsmToken::EndOfStatement)
1632640192daSUlrich Weigand          && getLexer().isNot(AsmToken::Comma))
1633640192daSUlrich Weigand     Parser.Lex();
1634d6642c11SNirav Dave   if (parseToken(AsmToken::Comma))
1635d6642c11SNirav Dave     return addErrorSuffix(" in '.tc' directive");
1636640192daSUlrich Weigand 
1637640192daSUlrich Weigand   // Align to word size.
16386d2d589bSFangrui Song   getParser().getStreamer().emitValueToAlignment(Size);
1639640192daSUlrich Weigand 
1640640192daSUlrich Weigand   // Emit expressions.
1641d6642c11SNirav Dave   return ParseDirectiveWord(Size, ID);
1642640192daSUlrich Weigand }
1643640192daSUlrich Weigand 
1644e0b4cb62SIain Sandoe /// ParseDirectiveMachine (ELF platforms)
164555daa779SUlrich Weigand ///  ::= .machine [ cpu | "push" | "pop" ]
ParseDirectiveMachine(SMLoc L)164655daa779SUlrich Weigand bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) {
1647961d4694SRafael Espindola   MCAsmParser &Parser = getParser();
1648d6642c11SNirav Dave   if (Parser.getTok().isNot(AsmToken::Identifier) &&
1649d6642c11SNirav Dave       Parser.getTok().isNot(AsmToken::String))
1650d6642c11SNirav Dave     return Error(L, "unexpected token in '.machine' directive");
165155daa779SUlrich Weigand 
165255daa779SUlrich Weigand   StringRef CPU = Parser.getTok().getIdentifier();
165355daa779SUlrich Weigand 
165455daa779SUlrich Weigand   // FIXME: Right now, the parser always allows any available
165555daa779SUlrich Weigand   // instruction, so the .machine directive is not useful.
1656f9312903SFangrui Song   // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen.
165755daa779SUlrich Weigand 
1658d6642c11SNirav Dave   Parser.Lex();
1659d6642c11SNirav Dave 
1660d6642c11SNirav Dave   if (parseToken(AsmToken::EndOfStatement))
1661d6642c11SNirav Dave     return addErrorSuffix(" in '.machine' directive");
1662d6642c11SNirav Dave 
1663500b4ad5SNg Zhi An   PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
16646b9ee9bcSRafael Espindola       getParser().getStreamer().getTargetStreamer());
1665500b4ad5SNg Zhi An   if (TStreamer != nullptr)
1666500b4ad5SNg Zhi An     TStreamer->emitMachine(CPU);
166755daa779SUlrich Weigand 
166855daa779SUlrich Weigand   return false;
166955daa779SUlrich Weigand }
167055daa779SUlrich Weigand 
16710daa5164SUlrich Weigand /// ParseDirectiveAbiVersion
16720daa5164SUlrich Weigand ///  ::= .abiversion constant-expression
ParseDirectiveAbiVersion(SMLoc L)16730daa5164SUlrich Weigand bool PPCAsmParser::ParseDirectiveAbiVersion(SMLoc L) {
16740daa5164SUlrich Weigand   int64_t AbiVersion;
1675d6642c11SNirav Dave   if (check(getParser().parseAbsoluteExpression(AbiVersion), L,
1676d6642c11SNirav Dave             "expected constant expression") ||
1677d6642c11SNirav Dave       parseToken(AsmToken::EndOfStatement))
1678d6642c11SNirav Dave     return addErrorSuffix(" in '.abiversion' directive");
16790daa5164SUlrich Weigand 
1680500b4ad5SNg Zhi An   PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
16810daa5164SUlrich Weigand       getParser().getStreamer().getTargetStreamer());
1682500b4ad5SNg Zhi An   if (TStreamer != nullptr)
1683500b4ad5SNg Zhi An     TStreamer->emitAbiVersion(AbiVersion);
16840daa5164SUlrich Weigand 
16850daa5164SUlrich Weigand   return false;
16860daa5164SUlrich Weigand }
16870daa5164SUlrich Weigand 
1688bb68610dSUlrich Weigand /// ParseDirectiveLocalEntry
1689bb68610dSUlrich Weigand ///  ::= .localentry symbol, expression
ParseDirectiveLocalEntry(SMLoc L)1690bb68610dSUlrich Weigand bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) {
1691bb68610dSUlrich Weigand   StringRef Name;
1692d6642c11SNirav Dave   if (getParser().parseIdentifier(Name))
1693d6642c11SNirav Dave     return Error(L, "expected identifier in '.localentry' directive");
1694d6642c11SNirav Dave 
169595fb9b93SRafael Espindola   MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
1696bb68610dSUlrich Weigand   const MCExpr *Expr;
1697bb68610dSUlrich Weigand 
1698d6642c11SNirav Dave   if (parseToken(AsmToken::Comma) ||
1699d6642c11SNirav Dave       check(getParser().parseExpression(Expr), L, "expected expression") ||
1700d6642c11SNirav Dave       parseToken(AsmToken::EndOfStatement))
1701d6642c11SNirav Dave     return addErrorSuffix(" in '.localentry' directive");
1702bb68610dSUlrich Weigand 
1703500b4ad5SNg Zhi An   PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
1704bb68610dSUlrich Weigand       getParser().getStreamer().getTargetStreamer());
1705500b4ad5SNg Zhi An   if (TStreamer != nullptr)
1706500b4ad5SNg Zhi An     TStreamer->emitLocalEntry(Sym, Expr);
1707bb68610dSUlrich Weigand 
1708bb68610dSUlrich Weigand   return false;
1709bb68610dSUlrich Weigand }
1710bb68610dSUlrich Weigand 
ParseGNUAttribute(SMLoc L)171100d68c38SQiu Chaofan bool PPCAsmParser::ParseGNUAttribute(SMLoc L) {
171200d68c38SQiu Chaofan   int64_t Tag;
171300d68c38SQiu Chaofan   int64_t IntegerValue;
171400d68c38SQiu Chaofan   if (!getParser().parseGNUAttribute(L, Tag, IntegerValue))
171500d68c38SQiu Chaofan     return false;
1716bb68610dSUlrich Weigand 
171700d68c38SQiu Chaofan   getParser().getStreamer().emitGNUAttribute(Tag, IntegerValue);
171800d68c38SQiu Chaofan 
171900d68c38SQiu Chaofan   return true;
172000d68c38SQiu Chaofan }
1721bb68610dSUlrich Weigand 
1722640192daSUlrich Weigand /// Force static initialization.
LLVMInitializePowerPCAsmParser()17230dbcb363STom Stellard extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() {
1724f42454b9SMehdi Amini   RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target());
17258f004471SBrandon Bergren   RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());
17268f004471SBrandon Bergren   RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());
17278f004471SBrandon Bergren   RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());
1728640192daSUlrich Weigand }
1729640192daSUlrich Weigand 
1730640192daSUlrich Weigand #define GET_REGISTER_MATCHER
1731640192daSUlrich Weigand #define GET_MATCHER_IMPLEMENTATION
1732e86a8b79SHal Finkel #define GET_MNEMONIC_SPELL_CHECKER
1733640192daSUlrich Weigand #include "PPCGenAsmMatcher.inc"
1734c0944b50SUlrich Weigand 
1735c0944b50SUlrich Weigand // Define this matcher function after the auto-generated include so we
1736c0944b50SUlrich Weigand // have the match class enum definitions.
validateTargetOperandClass(MCParsedAsmOperand & AsmOp,unsigned Kind)1737960ea3f0SDavid Blaikie unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1738c0944b50SUlrich Weigand                                                   unsigned Kind) {
1739c0944b50SUlrich Weigand   // If the kind is a token for a literal immediate, check if our asm
1740c0944b50SUlrich Weigand   // operand matches. This is for InstAliases which have a fixed-value
1741c0944b50SUlrich Weigand   // immediate in the syntax.
1742c0944b50SUlrich Weigand   int64_t ImmVal;
1743c0944b50SUlrich Weigand   switch (Kind) {
1744c0944b50SUlrich Weigand     case MCK_0: ImmVal = 0; break;
1745c0944b50SUlrich Weigand     case MCK_1: ImmVal = 1; break;
174662cb6354SRoman Divacky     case MCK_2: ImmVal = 2; break;
174762cb6354SRoman Divacky     case MCK_3: ImmVal = 3; break;
1748dda8e784SJoerg Sonnenberger     case MCK_4: ImmVal = 4; break;
1749dda8e784SJoerg Sonnenberger     case MCK_5: ImmVal = 5; break;
1750dda8e784SJoerg Sonnenberger     case MCK_6: ImmVal = 6; break;
1751dda8e784SJoerg Sonnenberger     case MCK_7: ImmVal = 7; break;
1752c0944b50SUlrich Weigand     default: return Match_InvalidOperand;
1753c0944b50SUlrich Weigand   }
1754c0944b50SUlrich Weigand 
1755960ea3f0SDavid Blaikie   PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
1756d6c0ef78SNemanja Ivanovic   if (Op.isU3Imm() && Op.getImm() == ImmVal)
1757c0944b50SUlrich Weigand     return Match_Success;
1758c0944b50SUlrich Weigand 
1759c0944b50SUlrich Weigand   return Match_InvalidOperand;
1760c0944b50SUlrich Weigand }
1761c0944b50SUlrich Weigand 
1762b822af47SJoerg Sonnenberger const MCExpr *
applyModifierToExpr(const MCExpr * E,MCSymbolRefExpr::VariantKind Variant,MCContext & Ctx)1763b822af47SJoerg Sonnenberger PPCAsmParser::applyModifierToExpr(const MCExpr *E,
1764b822af47SJoerg Sonnenberger                                   MCSymbolRefExpr::VariantKind Variant,
1765b822af47SJoerg Sonnenberger                                   MCContext &Ctx) {
1766b822af47SJoerg Sonnenberger   switch (Variant) {
1767b822af47SJoerg Sonnenberger   case MCSymbolRefExpr::VK_PPC_LO:
1768a50567a3SFangrui Song     return PPCMCExpr::create(PPCMCExpr::VK_PPC_LO, E, Ctx);
1769b822af47SJoerg Sonnenberger   case MCSymbolRefExpr::VK_PPC_HI:
1770a50567a3SFangrui Song     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HI, E, Ctx);
1771b822af47SJoerg Sonnenberger   case MCSymbolRefExpr::VK_PPC_HA:
1772a50567a3SFangrui Song     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HA, E, Ctx);
177380b8f82fSSean Fertile   case MCSymbolRefExpr::VK_PPC_HIGH:
1774a50567a3SFangrui Song     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGH, E, Ctx);
177580b8f82fSSean Fertile   case MCSymbolRefExpr::VK_PPC_HIGHA:
1776a50567a3SFangrui Song     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHA, E, Ctx);
1777b822af47SJoerg Sonnenberger   case MCSymbolRefExpr::VK_PPC_HIGHER:
1778a50567a3SFangrui Song     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHER, E, Ctx);
1779b822af47SJoerg Sonnenberger   case MCSymbolRefExpr::VK_PPC_HIGHERA:
1780a50567a3SFangrui Song     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHERA, E, Ctx);
1781b822af47SJoerg Sonnenberger   case MCSymbolRefExpr::VK_PPC_HIGHEST:
1782a50567a3SFangrui Song     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHEST, E, Ctx);
1783b822af47SJoerg Sonnenberger   case MCSymbolRefExpr::VK_PPC_HIGHESTA:
1784a50567a3SFangrui Song     return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHESTA, E, Ctx);
1785b822af47SJoerg Sonnenberger   default:
1786062a2baeSCraig Topper     return nullptr;
1787b822af47SJoerg Sonnenberger   }
1788b822af47SJoerg Sonnenberger }
1789