1 //===-- PPCAsmParser.cpp - Parse PowerPC asm to MCInst instructions -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "MCTargetDesc/PPCMCExpr.h"
10 #include "MCTargetDesc/PPCMCTargetDesc.h"
11 #include "PPCTargetStreamer.h"
12 #include "TargetInfo/PowerPCTargetInfo.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstrInfo.h"
19 #include "llvm/MC/MCParser/MCAsmLexer.h"
20 #include "llvm/MC/MCParser/MCAsmParser.h"
21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbolELF.h"
26 #include "llvm/MC/TargetRegistry.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include "llvm/Support/raw_ostream.h"
29
30 using namespace llvm;
31
32 DEFINE_PPC_REGCLASSES
33
34 // Evaluate an expression containing condition register
35 // or condition register field symbols. Returns positive
36 // value on success, or -1 on error.
37 static int64_t
EvaluateCRExpr(const MCExpr * E)38 EvaluateCRExpr(const MCExpr *E) {
39 switch (E->getKind()) {
40 case MCExpr::Target:
41 return -1;
42
43 case MCExpr::Constant: {
44 int64_t Res = cast<MCConstantExpr>(E)->getValue();
45 return Res < 0 ? -1 : Res;
46 }
47
48 case MCExpr::SymbolRef: {
49 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
50 StringRef Name = SRE->getSymbol().getName();
51
52 if (Name == "lt") return 0;
53 if (Name == "gt") return 1;
54 if (Name == "eq") return 2;
55 if (Name == "so") return 3;
56 if (Name == "un") return 3;
57
58 if (Name == "cr0") return 0;
59 if (Name == "cr1") return 1;
60 if (Name == "cr2") return 2;
61 if (Name == "cr3") return 3;
62 if (Name == "cr4") return 4;
63 if (Name == "cr5") return 5;
64 if (Name == "cr6") return 6;
65 if (Name == "cr7") return 7;
66
67 return -1;
68 }
69
70 case MCExpr::Unary:
71 return -1;
72
73 case MCExpr::Binary: {
74 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
75 int64_t LHSVal = EvaluateCRExpr(BE->getLHS());
76 int64_t RHSVal = EvaluateCRExpr(BE->getRHS());
77 int64_t Res;
78
79 if (LHSVal < 0 || RHSVal < 0)
80 return -1;
81
82 switch (BE->getOpcode()) {
83 default: return -1;
84 case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;
85 case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;
86 }
87
88 return Res < 0 ? -1 : Res;
89 }
90 }
91
92 llvm_unreachable("Invalid expression kind!");
93 }
94
95 namespace {
96
97 struct PPCOperand;
98
99 class PPCAsmParser : public MCTargetAsmParser {
100 bool IsPPC64;
101
Warning(SMLoc L,const Twine & Msg)102 void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
103
isPPC64() const104 bool isPPC64() const { return IsPPC64; }
105
106 bool MatchRegisterName(MCRegister &RegNo, int64_t &IntVal);
107
108 bool parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
109 SMLoc &EndLoc) override;
110 OperandMatchResultTy tryParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
111 SMLoc &EndLoc) override;
112
113 const MCExpr *ExtractModifierFromExpr(const MCExpr *E,
114 PPCMCExpr::VariantKind &Variant);
115 const MCExpr *FixupVariantKind(const MCExpr *E);
116 bool ParseExpression(const MCExpr *&EVal);
117
118 bool ParseOperand(OperandVector &Operands);
119
120 bool ParseDirectiveWord(unsigned Size, AsmToken ID);
121 bool ParseDirectiveTC(unsigned Size, AsmToken ID);
122 bool ParseDirectiveMachine(SMLoc L);
123 bool ParseDirectiveAbiVersion(SMLoc L);
124 bool ParseDirectiveLocalEntry(SMLoc L);
125 bool ParseGNUAttribute(SMLoc L);
126
127 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
128 OperandVector &Operands, MCStreamer &Out,
129 uint64_t &ErrorInfo,
130 bool MatchingInlineAsm) override;
131
132 void ProcessInstruction(MCInst &Inst, const OperandVector &Ops);
133
134 /// @name Auto-generated Match Functions
135 /// {
136
137 #define GET_ASSEMBLER_HEADER
138 #include "PPCGenAsmMatcher.inc"
139
140 /// }
141
142
143 public:
PPCAsmParser(const MCSubtargetInfo & STI,MCAsmParser &,const MCInstrInfo & MII,const MCTargetOptions & Options)144 PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &,
145 const MCInstrInfo &MII, const MCTargetOptions &Options)
146 : MCTargetAsmParser(Options, STI, MII) {
147 // Check for 64-bit vs. 32-bit pointer mode.
148 const Triple &TheTriple = STI.getTargetTriple();
149 IsPPC64 = TheTriple.isPPC64();
150 // Initialize the set of available features.
151 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
152 }
153
154 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
155 SMLoc NameLoc, OperandVector &Operands) override;
156
157 bool ParseDirective(AsmToken DirectiveID) override;
158
159 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
160 unsigned Kind) override;
161
162 const MCExpr *applyModifierToExpr(const MCExpr *E,
163 MCSymbolRefExpr::VariantKind,
164 MCContext &Ctx) override;
165 };
166
167 /// PPCOperand - Instances of this class represent a parsed PowerPC machine
168 /// instruction.
169 struct PPCOperand : public MCParsedAsmOperand {
170 enum KindTy {
171 Token,
172 Immediate,
173 ContextImmediate,
174 Expression,
175 TLSRegister
176 } Kind;
177
178 SMLoc StartLoc, EndLoc;
179 bool IsPPC64;
180
181 struct TokOp {
182 const char *Data;
183 unsigned Length;
184 };
185
186 struct ImmOp {
187 int64_t Val;
188 };
189
190 struct ExprOp {
191 const MCExpr *Val;
192 int64_t CRVal; // Cached result of EvaluateCRExpr(Val)
193 };
194
195 struct TLSRegOp {
196 const MCSymbolRefExpr *Sym;
197 };
198
199 union {
200 struct TokOp Tok;
201 struct ImmOp Imm;
202 struct ExprOp Expr;
203 struct TLSRegOp TLSReg;
204 };
205
PPCOperand__anona917cc7a0111::PPCOperand206 PPCOperand(KindTy K) : Kind(K) {}
207
208 public:
PPCOperand__anona917cc7a0111::PPCOperand209 PPCOperand(const PPCOperand &o) : MCParsedAsmOperand() {
210 Kind = o.Kind;
211 StartLoc = o.StartLoc;
212 EndLoc = o.EndLoc;
213 IsPPC64 = o.IsPPC64;
214 switch (Kind) {
215 case Token:
216 Tok = o.Tok;
217 break;
218 case Immediate:
219 case ContextImmediate:
220 Imm = o.Imm;
221 break;
222 case Expression:
223 Expr = o.Expr;
224 break;
225 case TLSRegister:
226 TLSReg = o.TLSReg;
227 break;
228 }
229 }
230
231 // Disable use of sized deallocation due to overallocation of PPCOperand
232 // objects in CreateTokenWithStringCopy.
operator delete__anona917cc7a0111::PPCOperand233 void operator delete(void *p) { ::operator delete(p); }
234
235 /// getStartLoc - Get the location of the first token of this operand.
getStartLoc__anona917cc7a0111::PPCOperand236 SMLoc getStartLoc() const override { return StartLoc; }
237
238 /// getEndLoc - Get the location of the last token of this operand.
getEndLoc__anona917cc7a0111::PPCOperand239 SMLoc getEndLoc() const override { return EndLoc; }
240
241 /// getLocRange - Get the range between the first and last token of this
242 /// operand.
getLocRange__anona917cc7a0111::PPCOperand243 SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
244
245 /// isPPC64 - True if this operand is for an instruction in 64-bit mode.
isPPC64__anona917cc7a0111::PPCOperand246 bool isPPC64() const { return IsPPC64; }
247
getImm__anona917cc7a0111::PPCOperand248 int64_t getImm() const {
249 assert(Kind == Immediate && "Invalid access!");
250 return Imm.Val;
251 }
getImmS16Context__anona917cc7a0111::PPCOperand252 int64_t getImmS16Context() const {
253 assert((Kind == Immediate || Kind == ContextImmediate) &&
254 "Invalid access!");
255 if (Kind == Immediate)
256 return Imm.Val;
257 return static_cast<int16_t>(Imm.Val);
258 }
getImmU16Context__anona917cc7a0111::PPCOperand259 int64_t getImmU16Context() const {
260 assert((Kind == Immediate || Kind == ContextImmediate) &&
261 "Invalid access!");
262 return Imm.Val;
263 }
264
getExpr__anona917cc7a0111::PPCOperand265 const MCExpr *getExpr() const {
266 assert(Kind == Expression && "Invalid access!");
267 return Expr.Val;
268 }
269
getExprCRVal__anona917cc7a0111::PPCOperand270 int64_t getExprCRVal() const {
271 assert(Kind == Expression && "Invalid access!");
272 return Expr.CRVal;
273 }
274
getTLSReg__anona917cc7a0111::PPCOperand275 const MCExpr *getTLSReg() const {
276 assert(Kind == TLSRegister && "Invalid access!");
277 return TLSReg.Sym;
278 }
279
getReg__anona917cc7a0111::PPCOperand280 unsigned getReg() const override {
281 assert(isRegNumber() && "Invalid access!");
282 return (unsigned) Imm.Val;
283 }
284
getVSReg__anona917cc7a0111::PPCOperand285 unsigned getVSReg() const {
286 assert(isVSRegNumber() && "Invalid access!");
287 return (unsigned) Imm.Val;
288 }
289
getACCReg__anona917cc7a0111::PPCOperand290 unsigned getACCReg() const {
291 assert(isACCRegNumber() && "Invalid access!");
292 return (unsigned) Imm.Val;
293 }
294
getDMRROWReg__anona917cc7a0111::PPCOperand295 unsigned getDMRROWReg() const {
296 assert(isDMRROWRegNumber() && "Invalid access!");
297 return (unsigned)Imm.Val;
298 }
299
getDMRROWpReg__anona917cc7a0111::PPCOperand300 unsigned getDMRROWpReg() const {
301 assert(isDMRROWpRegNumber() && "Invalid access!");
302 return (unsigned)Imm.Val;
303 }
304
getDMRReg__anona917cc7a0111::PPCOperand305 unsigned getDMRReg() const {
306 assert(isDMRRegNumber() && "Invalid access!");
307 return (unsigned)Imm.Val;
308 }
309
getDMRpReg__anona917cc7a0111::PPCOperand310 unsigned getDMRpReg() const {
311 assert(isDMRpRegNumber() && "Invalid access!");
312 return (unsigned)Imm.Val;
313 }
314
getVSRpEvenReg__anona917cc7a0111::PPCOperand315 unsigned getVSRpEvenReg() const {
316 assert(isVSRpEvenRegNumber() && "Invalid access!");
317 return (unsigned) Imm.Val >> 1;
318 }
319
getG8pReg__anona917cc7a0111::PPCOperand320 unsigned getG8pReg() const {
321 assert(isEvenRegNumber() && "Invalid access!");
322 return (unsigned)Imm.Val;
323 }
324
getCCReg__anona917cc7a0111::PPCOperand325 unsigned getCCReg() const {
326 assert(isCCRegNumber() && "Invalid access!");
327 return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
328 }
329
getCRBit__anona917cc7a0111::PPCOperand330 unsigned getCRBit() const {
331 assert(isCRBitNumber() && "Invalid access!");
332 return (unsigned) (Kind == Immediate ? Imm.Val : Expr.CRVal);
333 }
334
getCRBitMask__anona917cc7a0111::PPCOperand335 unsigned getCRBitMask() const {
336 assert(isCRBitMask() && "Invalid access!");
337 return 7 - countTrailingZeros<uint64_t>(Imm.Val);
338 }
339
isToken__anona917cc7a0111::PPCOperand340 bool isToken() const override { return Kind == Token; }
isImm__anona917cc7a0111::PPCOperand341 bool isImm() const override {
342 return Kind == Immediate || Kind == Expression;
343 }
isU1Imm__anona917cc7a0111::PPCOperand344 bool isU1Imm() const { return Kind == Immediate && isUInt<1>(getImm()); }
isU2Imm__anona917cc7a0111::PPCOperand345 bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); }
isU3Imm__anona917cc7a0111::PPCOperand346 bool isU3Imm() const { return Kind == Immediate && isUInt<3>(getImm()); }
isU4Imm__anona917cc7a0111::PPCOperand347 bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); }
isU5Imm__anona917cc7a0111::PPCOperand348 bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
isS5Imm__anona917cc7a0111::PPCOperand349 bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }
isU6Imm__anona917cc7a0111::PPCOperand350 bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); }
isU6ImmX2__anona917cc7a0111::PPCOperand351 bool isU6ImmX2() const { return Kind == Immediate &&
352 isUInt<6>(getImm()) &&
353 (getImm() & 1) == 0; }
isU7Imm__anona917cc7a0111::PPCOperand354 bool isU7Imm() const { return Kind == Immediate && isUInt<7>(getImm()); }
isU7ImmX4__anona917cc7a0111::PPCOperand355 bool isU7ImmX4() const { return Kind == Immediate &&
356 isUInt<7>(getImm()) &&
357 (getImm() & 3) == 0; }
isU8Imm__anona917cc7a0111::PPCOperand358 bool isU8Imm() const { return Kind == Immediate && isUInt<8>(getImm()); }
isU8ImmX8__anona917cc7a0111::PPCOperand359 bool isU8ImmX8() const { return Kind == Immediate &&
360 isUInt<8>(getImm()) &&
361 (getImm() & 7) == 0; }
362
isU10Imm__anona917cc7a0111::PPCOperand363 bool isU10Imm() const { return Kind == Immediate && isUInt<10>(getImm()); }
isU12Imm__anona917cc7a0111::PPCOperand364 bool isU12Imm() const { return Kind == Immediate && isUInt<12>(getImm()); }
isU16Imm__anona917cc7a0111::PPCOperand365 bool isU16Imm() const { return isExtImm<16>(/*Signed*/ false, 1); }
isS16Imm__anona917cc7a0111::PPCOperand366 bool isS16Imm() const { return isExtImm<16>(/*Signed*/ true, 1); }
isS16ImmX4__anona917cc7a0111::PPCOperand367 bool isS16ImmX4() const { return isExtImm<16>(/*Signed*/ true, 4); }
isS16ImmX16__anona917cc7a0111::PPCOperand368 bool isS16ImmX16() const { return isExtImm<16>(/*Signed*/ true, 16); }
isS17Imm__anona917cc7a0111::PPCOperand369 bool isS17Imm() const { return isExtImm<17>(/*Signed*/ true, 1); }
370
isHashImmX8__anona917cc7a0111::PPCOperand371 bool isHashImmX8() const {
372 // The Hash Imm form is used for instructions that check or store a hash.
373 // These instructions have a small immediate range that spans between
374 // -8 and -512.
375 return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&
376 (getImm() & 7) == 0);
377 }
378
isS34ImmX16__anona917cc7a0111::PPCOperand379 bool isS34ImmX16() const {
380 return Kind == Expression ||
381 (Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
382 }
isS34Imm__anona917cc7a0111::PPCOperand383 bool isS34Imm() const {
384 // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
385 // ContextImmediate is needed.
386 return Kind == Expression || (Kind == Immediate && isInt<34>(getImm()));
387 }
388
isTLSReg__anona917cc7a0111::PPCOperand389 bool isTLSReg() const { return Kind == TLSRegister; }
isDirectBr__anona917cc7a0111::PPCOperand390 bool isDirectBr() const {
391 if (Kind == Expression)
392 return true;
393 if (Kind != Immediate)
394 return false;
395 // Operand must be 64-bit aligned, signed 27-bit immediate.
396 if ((getImm() & 3) != 0)
397 return false;
398 if (isInt<26>(getImm()))
399 return true;
400 if (!IsPPC64) {
401 // In 32-bit mode, large 32-bit quantities wrap around.
402 if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))
403 return true;
404 }
405 return false;
406 }
isCondBr__anona917cc7a0111::PPCOperand407 bool isCondBr() const { return Kind == Expression ||
408 (Kind == Immediate && isInt<16>(getImm()) &&
409 (getImm() & 3) == 0); }
isImmZero__anona917cc7a0111::PPCOperand410 bool isImmZero() const { return Kind == Immediate && getImm() == 0; }
isRegNumber__anona917cc7a0111::PPCOperand411 bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
isACCRegNumber__anona917cc7a0111::PPCOperand412 bool isACCRegNumber() const {
413 return Kind == Immediate && isUInt<3>(getImm());
414 }
isDMRROWRegNumber__anona917cc7a0111::PPCOperand415 bool isDMRROWRegNumber() const {
416 return Kind == Immediate && isUInt<6>(getImm());
417 }
isDMRROWpRegNumber__anona917cc7a0111::PPCOperand418 bool isDMRROWpRegNumber() const {
419 return Kind == Immediate && isUInt<5>(getImm());
420 }
isDMRRegNumber__anona917cc7a0111::PPCOperand421 bool isDMRRegNumber() const {
422 return Kind == Immediate && isUInt<3>(getImm());
423 }
isDMRpRegNumber__anona917cc7a0111::PPCOperand424 bool isDMRpRegNumber() const {
425 return Kind == Immediate && isUInt<2>(getImm());
426 }
isVSRpEvenRegNumber__anona917cc7a0111::PPCOperand427 bool isVSRpEvenRegNumber() const {
428 return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
429 }
isVSRegNumber__anona917cc7a0111::PPCOperand430 bool isVSRegNumber() const {
431 return Kind == Immediate && isUInt<6>(getImm());
432 }
isCCRegNumber__anona917cc7a0111::PPCOperand433 bool isCCRegNumber() const { return (Kind == Expression
434 && isUInt<3>(getExprCRVal())) ||
435 (Kind == Immediate
436 && isUInt<3>(getImm())); }
isCRBitNumber__anona917cc7a0111::PPCOperand437 bool isCRBitNumber() const { return (Kind == Expression
438 && isUInt<5>(getExprCRVal())) ||
439 (Kind == Immediate
440 && isUInt<5>(getImm())); }
441
isEvenRegNumber__anona917cc7a0111::PPCOperand442 bool isEvenRegNumber() const { return isRegNumber() && (getImm() & 1) == 0; }
443
isCRBitMask__anona917cc7a0111::PPCOperand444 bool isCRBitMask() const { return Kind == Immediate && isUInt<8>(getImm()) &&
445 isPowerOf2_32(getImm()); }
isATBitsAsHint__anona917cc7a0111::PPCOperand446 bool isATBitsAsHint() const { return false; }
isMem__anona917cc7a0111::PPCOperand447 bool isMem() const override { return false; }
isReg__anona917cc7a0111::PPCOperand448 bool isReg() const override { return false; }
449
addRegOperands__anona917cc7a0111::PPCOperand450 void addRegOperands(MCInst &Inst, unsigned N) const {
451 llvm_unreachable("addRegOperands");
452 }
453
addRegGPRCOperands__anona917cc7a0111::PPCOperand454 void addRegGPRCOperands(MCInst &Inst, unsigned N) const {
455 assert(N == 1 && "Invalid number of operands!");
456 Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
457 }
458
addRegGPRCNoR0Operands__anona917cc7a0111::PPCOperand459 void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {
460 assert(N == 1 && "Invalid number of operands!");
461 Inst.addOperand(MCOperand::createReg(RRegsNoR0[getReg()]));
462 }
463
addRegG8RCOperands__anona917cc7a0111::PPCOperand464 void addRegG8RCOperands(MCInst &Inst, unsigned N) const {
465 assert(N == 1 && "Invalid number of operands!");
466 Inst.addOperand(MCOperand::createReg(XRegs[getReg()]));
467 }
468
addRegG8RCNoX0Operands__anona917cc7a0111::PPCOperand469 void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {
470 assert(N == 1 && "Invalid number of operands!");
471 Inst.addOperand(MCOperand::createReg(XRegsNoX0[getReg()]));
472 }
473
addRegG8pRCOperands__anona917cc7a0111::PPCOperand474 void addRegG8pRCOperands(MCInst &Inst, unsigned N) const {
475 assert(N == 1 && "Invalid number of operands!");
476 Inst.addOperand(MCOperand::createReg(XRegs[getG8pReg()]));
477 }
478
addRegGxRCOperands__anona917cc7a0111::PPCOperand479 void addRegGxRCOperands(MCInst &Inst, unsigned N) const {
480 if (isPPC64())
481 addRegG8RCOperands(Inst, N);
482 else
483 addRegGPRCOperands(Inst, N);
484 }
485
addRegGxRCNoR0Operands__anona917cc7a0111::PPCOperand486 void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {
487 if (isPPC64())
488 addRegG8RCNoX0Operands(Inst, N);
489 else
490 addRegGPRCNoR0Operands(Inst, N);
491 }
492
addRegF4RCOperands__anona917cc7a0111::PPCOperand493 void addRegF4RCOperands(MCInst &Inst, unsigned N) const {
494 assert(N == 1 && "Invalid number of operands!");
495 Inst.addOperand(MCOperand::createReg(FRegs[getReg()]));
496 }
497
addRegF8RCOperands__anona917cc7a0111::PPCOperand498 void addRegF8RCOperands(MCInst &Inst, unsigned N) const {
499 assert(N == 1 && "Invalid number of operands!");
500 Inst.addOperand(MCOperand::createReg(FRegs[getReg()]));
501 }
502
addRegVFRCOperands__anona917cc7a0111::PPCOperand503 void addRegVFRCOperands(MCInst &Inst, unsigned N) const {
504 assert(N == 1 && "Invalid number of operands!");
505 Inst.addOperand(MCOperand::createReg(VFRegs[getReg()]));
506 }
507
addRegVRRCOperands__anona917cc7a0111::PPCOperand508 void addRegVRRCOperands(MCInst &Inst, unsigned N) const {
509 assert(N == 1 && "Invalid number of operands!");
510 Inst.addOperand(MCOperand::createReg(VRegs[getReg()]));
511 }
512
addRegVSRCOperands__anona917cc7a0111::PPCOperand513 void addRegVSRCOperands(MCInst &Inst, unsigned N) const {
514 assert(N == 1 && "Invalid number of operands!");
515 Inst.addOperand(MCOperand::createReg(VSRegs[getVSReg()]));
516 }
517
addRegVSFRCOperands__anona917cc7a0111::PPCOperand518 void addRegVSFRCOperands(MCInst &Inst, unsigned N) const {
519 assert(N == 1 && "Invalid number of operands!");
520 Inst.addOperand(MCOperand::createReg(VSFRegs[getVSReg()]));
521 }
522
addRegVSSRCOperands__anona917cc7a0111::PPCOperand523 void addRegVSSRCOperands(MCInst &Inst, unsigned N) const {
524 assert(N == 1 && "Invalid number of operands!");
525 Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()]));
526 }
527
addRegSPE4RCOperands__anona917cc7a0111::PPCOperand528 void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {
529 assert(N == 1 && "Invalid number of operands!");
530 Inst.addOperand(MCOperand::createReg(RRegs[getReg()]));
531 }
532
addRegSPERCOperands__anona917cc7a0111::PPCOperand533 void addRegSPERCOperands(MCInst &Inst, unsigned N) const {
534 assert(N == 1 && "Invalid number of operands!");
535 Inst.addOperand(MCOperand::createReg(SPERegs[getReg()]));
536 }
537
addRegACCRCOperands__anona917cc7a0111::PPCOperand538 void addRegACCRCOperands(MCInst &Inst, unsigned N) const {
539 assert(N == 1 && "Invalid number of operands!");
540 Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()]));
541 }
542
addRegDMRROWRCOperands__anona917cc7a0111::PPCOperand543 void addRegDMRROWRCOperands(MCInst &Inst, unsigned N) const {
544 assert(N == 1 && "Invalid number of operands!");
545 Inst.addOperand(MCOperand::createReg(DMRROWRegs[getDMRROWReg()]));
546 }
547
addRegDMRROWpRCOperands__anona917cc7a0111::PPCOperand548 void addRegDMRROWpRCOperands(MCInst &Inst, unsigned N) const {
549 assert(N == 1 && "Invalid number of operands!");
550 Inst.addOperand(MCOperand::createReg(DMRROWpRegs[getDMRROWpReg()]));
551 }
552
addRegDMRRCOperands__anona917cc7a0111::PPCOperand553 void addRegDMRRCOperands(MCInst &Inst, unsigned N) const {
554 assert(N == 1 && "Invalid number of operands!");
555 Inst.addOperand(MCOperand::createReg(DMRRegs[getDMRReg()]));
556 }
557
addRegDMRpRCOperands__anona917cc7a0111::PPCOperand558 void addRegDMRpRCOperands(MCInst &Inst, unsigned N) const {
559 assert(N == 1 && "Invalid number of operands!");
560 Inst.addOperand(MCOperand::createReg(DMRpRegs[getDMRpReg()]));
561 }
562
addRegWACCRCOperands__anona917cc7a0111::PPCOperand563 void addRegWACCRCOperands(MCInst &Inst, unsigned N) const {
564 assert(N == 1 && "Invalid number of operands!");
565 Inst.addOperand(MCOperand::createReg(WACCRegs[getACCReg()]));
566 }
567
addRegWACC_HIRCOperands__anona917cc7a0111::PPCOperand568 void addRegWACC_HIRCOperands(MCInst &Inst, unsigned N) const {
569 assert(N == 1 && "Invalid number of operands!");
570 Inst.addOperand(MCOperand::createReg(WACC_HIRegs[getACCReg()]));
571 }
572
addRegVSRpRCOperands__anona917cc7a0111::PPCOperand573 void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {
574 assert(N == 1 && "Invalid number of operands!");
575 Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
576 }
577
addRegVSRpEvenRCOperands__anona917cc7a0111::PPCOperand578 void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const {
579 assert(N == 1 && "Invalid number of operands!");
580 Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
581 }
582
addRegCRBITRCOperands__anona917cc7a0111::PPCOperand583 void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
584 assert(N == 1 && "Invalid number of operands!");
585 Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));
586 }
587
addRegCRRCOperands__anona917cc7a0111::PPCOperand588 void addRegCRRCOperands(MCInst &Inst, unsigned N) const {
589 assert(N == 1 && "Invalid number of operands!");
590 Inst.addOperand(MCOperand::createReg(CRRegs[getCCReg()]));
591 }
592
addCRBitMaskOperands__anona917cc7a0111::PPCOperand593 void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {
594 assert(N == 1 && "Invalid number of operands!");
595 Inst.addOperand(MCOperand::createReg(CRRegs[getCRBitMask()]));
596 }
597
addImmOperands__anona917cc7a0111::PPCOperand598 void addImmOperands(MCInst &Inst, unsigned N) const {
599 assert(N == 1 && "Invalid number of operands!");
600 if (Kind == Immediate)
601 Inst.addOperand(MCOperand::createImm(getImm()));
602 else
603 Inst.addOperand(MCOperand::createExpr(getExpr()));
604 }
605
addS16ImmOperands__anona917cc7a0111::PPCOperand606 void addS16ImmOperands(MCInst &Inst, unsigned N) const {
607 assert(N == 1 && "Invalid number of operands!");
608 switch (Kind) {
609 case Immediate:
610 Inst.addOperand(MCOperand::createImm(getImm()));
611 break;
612 case ContextImmediate:
613 Inst.addOperand(MCOperand::createImm(getImmS16Context()));
614 break;
615 default:
616 Inst.addOperand(MCOperand::createExpr(getExpr()));
617 break;
618 }
619 }
620
addU16ImmOperands__anona917cc7a0111::PPCOperand621 void addU16ImmOperands(MCInst &Inst, unsigned N) const {
622 assert(N == 1 && "Invalid number of operands!");
623 switch (Kind) {
624 case Immediate:
625 Inst.addOperand(MCOperand::createImm(getImm()));
626 break;
627 case ContextImmediate:
628 Inst.addOperand(MCOperand::createImm(getImmU16Context()));
629 break;
630 default:
631 Inst.addOperand(MCOperand::createExpr(getExpr()));
632 break;
633 }
634 }
635
addBranchTargetOperands__anona917cc7a0111::PPCOperand636 void addBranchTargetOperands(MCInst &Inst, unsigned N) const {
637 assert(N == 1 && "Invalid number of operands!");
638 if (Kind == Immediate)
639 Inst.addOperand(MCOperand::createImm(getImm() / 4));
640 else
641 Inst.addOperand(MCOperand::createExpr(getExpr()));
642 }
643
addTLSRegOperands__anona917cc7a0111::PPCOperand644 void addTLSRegOperands(MCInst &Inst, unsigned N) const {
645 assert(N == 1 && "Invalid number of operands!");
646 Inst.addOperand(MCOperand::createExpr(getTLSReg()));
647 }
648
getToken__anona917cc7a0111::PPCOperand649 StringRef getToken() const {
650 assert(Kind == Token && "Invalid access!");
651 return StringRef(Tok.Data, Tok.Length);
652 }
653
654 void print(raw_ostream &OS) const override;
655
CreateToken__anona917cc7a0111::PPCOperand656 static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,
657 bool IsPPC64) {
658 auto Op = std::make_unique<PPCOperand>(Token);
659 Op->Tok.Data = Str.data();
660 Op->Tok.Length = Str.size();
661 Op->StartLoc = S;
662 Op->EndLoc = S;
663 Op->IsPPC64 = IsPPC64;
664 return Op;
665 }
666
667 static std::unique_ptr<PPCOperand>
CreateTokenWithStringCopy__anona917cc7a0111::PPCOperand668 CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {
669 // Allocate extra memory for the string and copy it.
670 // FIXME: This is incorrect, Operands are owned by unique_ptr with a default
671 // deleter which will destroy them by simply using "delete", not correctly
672 // calling operator delete on this extra memory after calling the dtor
673 // explicitly.
674 void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());
675 std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));
676 Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1);
677 Op->Tok.Length = Str.size();
678 std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size());
679 Op->StartLoc = S;
680 Op->EndLoc = S;
681 Op->IsPPC64 = IsPPC64;
682 return Op;
683 }
684
CreateImm__anona917cc7a0111::PPCOperand685 static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,
686 bool IsPPC64) {
687 auto Op = std::make_unique<PPCOperand>(Immediate);
688 Op->Imm.Val = Val;
689 Op->StartLoc = S;
690 Op->EndLoc = E;
691 Op->IsPPC64 = IsPPC64;
692 return Op;
693 }
694
CreateExpr__anona917cc7a0111::PPCOperand695 static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,
696 SMLoc E, bool IsPPC64) {
697 auto Op = std::make_unique<PPCOperand>(Expression);
698 Op->Expr.Val = Val;
699 Op->Expr.CRVal = EvaluateCRExpr(Val);
700 Op->StartLoc = S;
701 Op->EndLoc = E;
702 Op->IsPPC64 = IsPPC64;
703 return Op;
704 }
705
706 static std::unique_ptr<PPCOperand>
CreateTLSReg__anona917cc7a0111::PPCOperand707 CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {
708 auto Op = std::make_unique<PPCOperand>(TLSRegister);
709 Op->TLSReg.Sym = Sym;
710 Op->StartLoc = S;
711 Op->EndLoc = E;
712 Op->IsPPC64 = IsPPC64;
713 return Op;
714 }
715
716 static std::unique_ptr<PPCOperand>
CreateContextImm__anona917cc7a0111::PPCOperand717 CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
718 auto Op = std::make_unique<PPCOperand>(ContextImmediate);
719 Op->Imm.Val = Val;
720 Op->StartLoc = S;
721 Op->EndLoc = E;
722 Op->IsPPC64 = IsPPC64;
723 return Op;
724 }
725
726 static std::unique_ptr<PPCOperand>
CreateFromMCExpr__anona917cc7a0111::PPCOperand727 CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {
728 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
729 return CreateImm(CE->getValue(), S, E, IsPPC64);
730
731 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
732 if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS ||
733 SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL)
734 return CreateTLSReg(SRE, S, E, IsPPC64);
735
736 if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
737 int64_t Res;
738 if (TE->evaluateAsConstant(Res))
739 return CreateContextImm(Res, S, E, IsPPC64);
740 }
741
742 return CreateExpr(Val, S, E, IsPPC64);
743 }
744
745 private:
746 template <unsigned Width>
isExtImm__anona917cc7a0111::PPCOperand747 bool isExtImm(bool Signed, unsigned Multiple) const {
748 switch (Kind) {
749 default:
750 return false;
751 case Expression:
752 return true;
753 case Immediate:
754 case ContextImmediate:
755 if (Signed)
756 return isInt<Width>(getImmS16Context()) &&
757 (getImmS16Context() & (Multiple - 1)) == 0;
758 else
759 return isUInt<Width>(getImmU16Context()) &&
760 (getImmU16Context() & (Multiple - 1)) == 0;
761 }
762 }
763 };
764
765 } // end anonymous namespace.
766
print(raw_ostream & OS) const767 void PPCOperand::print(raw_ostream &OS) const {
768 switch (Kind) {
769 case Token:
770 OS << "'" << getToken() << "'";
771 break;
772 case Immediate:
773 case ContextImmediate:
774 OS << getImm();
775 break;
776 case Expression:
777 OS << *getExpr();
778 break;
779 case TLSRegister:
780 OS << *getTLSReg();
781 break;
782 }
783 }
784
785 static void
addNegOperand(MCInst & Inst,MCOperand & Op,MCContext & Ctx)786 addNegOperand(MCInst &Inst, MCOperand &Op, MCContext &Ctx) {
787 if (Op.isImm()) {
788 Inst.addOperand(MCOperand::createImm(-Op.getImm()));
789 return;
790 }
791 const MCExpr *Expr = Op.getExpr();
792 if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
793 if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {
794 Inst.addOperand(MCOperand::createExpr(UnExpr->getSubExpr()));
795 return;
796 }
797 } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
798 if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {
799 const MCExpr *NE = MCBinaryExpr::createSub(BinExpr->getRHS(),
800 BinExpr->getLHS(), Ctx);
801 Inst.addOperand(MCOperand::createExpr(NE));
802 return;
803 }
804 }
805 Inst.addOperand(MCOperand::createExpr(MCUnaryExpr::createMinus(Expr, Ctx)));
806 }
807
ProcessInstruction(MCInst & Inst,const OperandVector & Operands)808 void PPCAsmParser::ProcessInstruction(MCInst &Inst,
809 const OperandVector &Operands) {
810 int Opcode = Inst.getOpcode();
811 switch (Opcode) {
812 case PPC::DCBTx:
813 case PPC::DCBTT:
814 case PPC::DCBTSTx:
815 case PPC::DCBTSTT: {
816 MCInst TmpInst;
817 TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
818 PPC::DCBT : PPC::DCBTST);
819 TmpInst.addOperand(MCOperand::createImm(
820 (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
821 TmpInst.addOperand(Inst.getOperand(0));
822 TmpInst.addOperand(Inst.getOperand(1));
823 Inst = TmpInst;
824 break;
825 }
826 case PPC::DCBTCT:
827 case PPC::DCBTDS: {
828 MCInst TmpInst;
829 TmpInst.setOpcode(PPC::DCBT);
830 TmpInst.addOperand(Inst.getOperand(2));
831 TmpInst.addOperand(Inst.getOperand(0));
832 TmpInst.addOperand(Inst.getOperand(1));
833 Inst = TmpInst;
834 break;
835 }
836 case PPC::DCBTSTCT:
837 case PPC::DCBTSTDS: {
838 MCInst TmpInst;
839 TmpInst.setOpcode(PPC::DCBTST);
840 TmpInst.addOperand(Inst.getOperand(2));
841 TmpInst.addOperand(Inst.getOperand(0));
842 TmpInst.addOperand(Inst.getOperand(1));
843 Inst = TmpInst;
844 break;
845 }
846 case PPC::DCBFx:
847 case PPC::DCBFL:
848 case PPC::DCBFLP:
849 case PPC::DCBFPS:
850 case PPC::DCBSTPS: {
851 int L = 0;
852 if (Opcode == PPC::DCBFL)
853 L = 1;
854 else if (Opcode == PPC::DCBFLP)
855 L = 3;
856 else if (Opcode == PPC::DCBFPS)
857 L = 4;
858 else if (Opcode == PPC::DCBSTPS)
859 L = 6;
860
861 MCInst TmpInst;
862 TmpInst.setOpcode(PPC::DCBF);
863 TmpInst.addOperand(MCOperand::createImm(L));
864 TmpInst.addOperand(Inst.getOperand(0));
865 TmpInst.addOperand(Inst.getOperand(1));
866 Inst = TmpInst;
867 break;
868 }
869 case PPC::LAx: {
870 MCInst TmpInst;
871 TmpInst.setOpcode(PPC::LA);
872 TmpInst.addOperand(Inst.getOperand(0));
873 TmpInst.addOperand(Inst.getOperand(2));
874 TmpInst.addOperand(Inst.getOperand(1));
875 Inst = TmpInst;
876 break;
877 }
878 case PPC::SUBI: {
879 MCInst TmpInst;
880 TmpInst.setOpcode(PPC::ADDI);
881 TmpInst.addOperand(Inst.getOperand(0));
882 TmpInst.addOperand(Inst.getOperand(1));
883 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
884 Inst = TmpInst;
885 break;
886 }
887 case PPC::SUBIS: {
888 MCInst TmpInst;
889 TmpInst.setOpcode(PPC::ADDIS);
890 TmpInst.addOperand(Inst.getOperand(0));
891 TmpInst.addOperand(Inst.getOperand(1));
892 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
893 Inst = TmpInst;
894 break;
895 }
896 case PPC::SUBIC: {
897 MCInst TmpInst;
898 TmpInst.setOpcode(PPC::ADDIC);
899 TmpInst.addOperand(Inst.getOperand(0));
900 TmpInst.addOperand(Inst.getOperand(1));
901 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
902 Inst = TmpInst;
903 break;
904 }
905 case PPC::SUBIC_rec: {
906 MCInst TmpInst;
907 TmpInst.setOpcode(PPC::ADDIC_rec);
908 TmpInst.addOperand(Inst.getOperand(0));
909 TmpInst.addOperand(Inst.getOperand(1));
910 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
911 Inst = TmpInst;
912 break;
913 }
914 case PPC::EXTLWI:
915 case PPC::EXTLWI_rec: {
916 MCInst TmpInst;
917 int64_t N = Inst.getOperand(2).getImm();
918 int64_t B = Inst.getOperand(3).getImm();
919 TmpInst.setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
920 TmpInst.addOperand(Inst.getOperand(0));
921 TmpInst.addOperand(Inst.getOperand(1));
922 TmpInst.addOperand(MCOperand::createImm(B));
923 TmpInst.addOperand(MCOperand::createImm(0));
924 TmpInst.addOperand(MCOperand::createImm(N - 1));
925 Inst = TmpInst;
926 break;
927 }
928 case PPC::EXTRWI:
929 case PPC::EXTRWI_rec: {
930 MCInst TmpInst;
931 int64_t N = Inst.getOperand(2).getImm();
932 int64_t B = Inst.getOperand(3).getImm();
933 TmpInst.setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
934 TmpInst.addOperand(Inst.getOperand(0));
935 TmpInst.addOperand(Inst.getOperand(1));
936 TmpInst.addOperand(MCOperand::createImm(B + N));
937 TmpInst.addOperand(MCOperand::createImm(32 - N));
938 TmpInst.addOperand(MCOperand::createImm(31));
939 Inst = TmpInst;
940 break;
941 }
942 case PPC::INSLWI:
943 case PPC::INSLWI_rec: {
944 MCInst TmpInst;
945 int64_t N = Inst.getOperand(2).getImm();
946 int64_t B = Inst.getOperand(3).getImm();
947 TmpInst.setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
948 TmpInst.addOperand(Inst.getOperand(0));
949 TmpInst.addOperand(Inst.getOperand(0));
950 TmpInst.addOperand(Inst.getOperand(1));
951 TmpInst.addOperand(MCOperand::createImm(32 - B));
952 TmpInst.addOperand(MCOperand::createImm(B));
953 TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
954 Inst = TmpInst;
955 break;
956 }
957 case PPC::INSRWI:
958 case PPC::INSRWI_rec: {
959 MCInst TmpInst;
960 int64_t N = Inst.getOperand(2).getImm();
961 int64_t B = Inst.getOperand(3).getImm();
962 TmpInst.setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
963 TmpInst.addOperand(Inst.getOperand(0));
964 TmpInst.addOperand(Inst.getOperand(0));
965 TmpInst.addOperand(Inst.getOperand(1));
966 TmpInst.addOperand(MCOperand::createImm(32 - (B + N)));
967 TmpInst.addOperand(MCOperand::createImm(B));
968 TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
969 Inst = TmpInst;
970 break;
971 }
972 case PPC::ROTRWI:
973 case PPC::ROTRWI_rec: {
974 MCInst TmpInst;
975 int64_t N = Inst.getOperand(2).getImm();
976 TmpInst.setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
977 TmpInst.addOperand(Inst.getOperand(0));
978 TmpInst.addOperand(Inst.getOperand(1));
979 TmpInst.addOperand(MCOperand::createImm(32 - N));
980 TmpInst.addOperand(MCOperand::createImm(0));
981 TmpInst.addOperand(MCOperand::createImm(31));
982 Inst = TmpInst;
983 break;
984 }
985 case PPC::SLWI:
986 case PPC::SLWI_rec: {
987 MCInst TmpInst;
988 int64_t N = Inst.getOperand(2).getImm();
989 TmpInst.setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
990 TmpInst.addOperand(Inst.getOperand(0));
991 TmpInst.addOperand(Inst.getOperand(1));
992 TmpInst.addOperand(MCOperand::createImm(N));
993 TmpInst.addOperand(MCOperand::createImm(0));
994 TmpInst.addOperand(MCOperand::createImm(31 - N));
995 Inst = TmpInst;
996 break;
997 }
998 case PPC::SRWI:
999 case PPC::SRWI_rec: {
1000 MCInst TmpInst;
1001 int64_t N = Inst.getOperand(2).getImm();
1002 TmpInst.setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1003 TmpInst.addOperand(Inst.getOperand(0));
1004 TmpInst.addOperand(Inst.getOperand(1));
1005 TmpInst.addOperand(MCOperand::createImm(32 - N));
1006 TmpInst.addOperand(MCOperand::createImm(N));
1007 TmpInst.addOperand(MCOperand::createImm(31));
1008 Inst = TmpInst;
1009 break;
1010 }
1011 case PPC::CLRRWI:
1012 case PPC::CLRRWI_rec: {
1013 MCInst TmpInst;
1014 int64_t N = Inst.getOperand(2).getImm();
1015 TmpInst.setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1016 TmpInst.addOperand(Inst.getOperand(0));
1017 TmpInst.addOperand(Inst.getOperand(1));
1018 TmpInst.addOperand(MCOperand::createImm(0));
1019 TmpInst.addOperand(MCOperand::createImm(0));
1020 TmpInst.addOperand(MCOperand::createImm(31 - N));
1021 Inst = TmpInst;
1022 break;
1023 }
1024 case PPC::CLRLSLWI:
1025 case PPC::CLRLSLWI_rec: {
1026 MCInst TmpInst;
1027 int64_t B = Inst.getOperand(2).getImm();
1028 int64_t N = Inst.getOperand(3).getImm();
1029 TmpInst.setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1030 TmpInst.addOperand(Inst.getOperand(0));
1031 TmpInst.addOperand(Inst.getOperand(1));
1032 TmpInst.addOperand(MCOperand::createImm(N));
1033 TmpInst.addOperand(MCOperand::createImm(B - N));
1034 TmpInst.addOperand(MCOperand::createImm(31 - N));
1035 Inst = TmpInst;
1036 break;
1037 }
1038 case PPC::EXTLDI:
1039 case PPC::EXTLDI_rec: {
1040 MCInst TmpInst;
1041 int64_t N = Inst.getOperand(2).getImm();
1042 int64_t B = Inst.getOperand(3).getImm();
1043 TmpInst.setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1044 TmpInst.addOperand(Inst.getOperand(0));
1045 TmpInst.addOperand(Inst.getOperand(1));
1046 TmpInst.addOperand(MCOperand::createImm(B));
1047 TmpInst.addOperand(MCOperand::createImm(N - 1));
1048 Inst = TmpInst;
1049 break;
1050 }
1051 case PPC::EXTRDI:
1052 case PPC::EXTRDI_rec: {
1053 MCInst TmpInst;
1054 int64_t N = Inst.getOperand(2).getImm();
1055 int64_t B = Inst.getOperand(3).getImm();
1056 TmpInst.setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1057 TmpInst.addOperand(Inst.getOperand(0));
1058 TmpInst.addOperand(Inst.getOperand(1));
1059 TmpInst.addOperand(MCOperand::createImm(B + N));
1060 TmpInst.addOperand(MCOperand::createImm(64 - N));
1061 Inst = TmpInst;
1062 break;
1063 }
1064 case PPC::INSRDI:
1065 case PPC::INSRDI_rec: {
1066 MCInst TmpInst;
1067 int64_t N = Inst.getOperand(2).getImm();
1068 int64_t B = Inst.getOperand(3).getImm();
1069 TmpInst.setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
1070 TmpInst.addOperand(Inst.getOperand(0));
1071 TmpInst.addOperand(Inst.getOperand(0));
1072 TmpInst.addOperand(Inst.getOperand(1));
1073 TmpInst.addOperand(MCOperand::createImm(64 - (B + N)));
1074 TmpInst.addOperand(MCOperand::createImm(B));
1075 Inst = TmpInst;
1076 break;
1077 }
1078 case PPC::ROTRDI:
1079 case PPC::ROTRDI_rec: {
1080 MCInst TmpInst;
1081 int64_t N = Inst.getOperand(2).getImm();
1082 TmpInst.setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1083 TmpInst.addOperand(Inst.getOperand(0));
1084 TmpInst.addOperand(Inst.getOperand(1));
1085 TmpInst.addOperand(MCOperand::createImm(64 - N));
1086 TmpInst.addOperand(MCOperand::createImm(0));
1087 Inst = TmpInst;
1088 break;
1089 }
1090 case PPC::SLDI:
1091 case PPC::SLDI_rec: {
1092 MCInst TmpInst;
1093 int64_t N = Inst.getOperand(2).getImm();
1094 TmpInst.setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1095 TmpInst.addOperand(Inst.getOperand(0));
1096 TmpInst.addOperand(Inst.getOperand(1));
1097 TmpInst.addOperand(MCOperand::createImm(N));
1098 TmpInst.addOperand(MCOperand::createImm(63 - N));
1099 Inst = TmpInst;
1100 break;
1101 }
1102 case PPC::SUBPCIS: {
1103 MCInst TmpInst;
1104 int64_t N = Inst.getOperand(1).getImm();
1105 TmpInst.setOpcode(PPC::ADDPCIS);
1106 TmpInst.addOperand(Inst.getOperand(0));
1107 TmpInst.addOperand(MCOperand::createImm(-N));
1108 Inst = TmpInst;
1109 break;
1110 }
1111 case PPC::SRDI:
1112 case PPC::SRDI_rec: {
1113 MCInst TmpInst;
1114 int64_t N = Inst.getOperand(2).getImm();
1115 TmpInst.setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1116 TmpInst.addOperand(Inst.getOperand(0));
1117 TmpInst.addOperand(Inst.getOperand(1));
1118 TmpInst.addOperand(MCOperand::createImm(64 - N));
1119 TmpInst.addOperand(MCOperand::createImm(N));
1120 Inst = TmpInst;
1121 break;
1122 }
1123 case PPC::CLRRDI:
1124 case PPC::CLRRDI_rec: {
1125 MCInst TmpInst;
1126 int64_t N = Inst.getOperand(2).getImm();
1127 TmpInst.setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
1128 TmpInst.addOperand(Inst.getOperand(0));
1129 TmpInst.addOperand(Inst.getOperand(1));
1130 TmpInst.addOperand(MCOperand::createImm(0));
1131 TmpInst.addOperand(MCOperand::createImm(63 - N));
1132 Inst = TmpInst;
1133 break;
1134 }
1135 case PPC::CLRLSLDI:
1136 case PPC::CLRLSLDI_rec: {
1137 MCInst TmpInst;
1138 int64_t B = Inst.getOperand(2).getImm();
1139 int64_t N = Inst.getOperand(3).getImm();
1140 TmpInst.setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
1141 TmpInst.addOperand(Inst.getOperand(0));
1142 TmpInst.addOperand(Inst.getOperand(1));
1143 TmpInst.addOperand(MCOperand::createImm(N));
1144 TmpInst.addOperand(MCOperand::createImm(B - N));
1145 Inst = TmpInst;
1146 break;
1147 }
1148 case PPC::RLWINMbm:
1149 case PPC::RLWINMbm_rec: {
1150 unsigned MB, ME;
1151 int64_t BM = Inst.getOperand(3).getImm();
1152 if (!isRunOfOnes(BM, MB, ME))
1153 break;
1154
1155 MCInst TmpInst;
1156 TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
1157 TmpInst.addOperand(Inst.getOperand(0));
1158 TmpInst.addOperand(Inst.getOperand(1));
1159 TmpInst.addOperand(Inst.getOperand(2));
1160 TmpInst.addOperand(MCOperand::createImm(MB));
1161 TmpInst.addOperand(MCOperand::createImm(ME));
1162 Inst = TmpInst;
1163 break;
1164 }
1165 case PPC::RLWIMIbm:
1166 case PPC::RLWIMIbm_rec: {
1167 unsigned MB, ME;
1168 int64_t BM = Inst.getOperand(3).getImm();
1169 if (!isRunOfOnes(BM, MB, ME))
1170 break;
1171
1172 MCInst TmpInst;
1173 TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
1174 TmpInst.addOperand(Inst.getOperand(0));
1175 TmpInst.addOperand(Inst.getOperand(0)); // The tied operand.
1176 TmpInst.addOperand(Inst.getOperand(1));
1177 TmpInst.addOperand(Inst.getOperand(2));
1178 TmpInst.addOperand(MCOperand::createImm(MB));
1179 TmpInst.addOperand(MCOperand::createImm(ME));
1180 Inst = TmpInst;
1181 break;
1182 }
1183 case PPC::RLWNMbm:
1184 case PPC::RLWNMbm_rec: {
1185 unsigned MB, ME;
1186 int64_t BM = Inst.getOperand(3).getImm();
1187 if (!isRunOfOnes(BM, MB, ME))
1188 break;
1189
1190 MCInst TmpInst;
1191 TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
1192 TmpInst.addOperand(Inst.getOperand(0));
1193 TmpInst.addOperand(Inst.getOperand(1));
1194 TmpInst.addOperand(Inst.getOperand(2));
1195 TmpInst.addOperand(MCOperand::createImm(MB));
1196 TmpInst.addOperand(MCOperand::createImm(ME));
1197 Inst = TmpInst;
1198 break;
1199 }
1200 case PPC::MFTB: {
1201 if (getSTI().getFeatureBits()[PPC::FeatureMFTB]) {
1202 assert(Inst.getNumOperands() == 2 && "Expecting two operands");
1203 Inst.setOpcode(PPC::MFSPR);
1204 }
1205 break;
1206 }
1207 }
1208 }
1209
1210 static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
1211 unsigned VariantID = 0);
1212
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)1213 bool PPCAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1214 OperandVector &Operands,
1215 MCStreamer &Out, uint64_t &ErrorInfo,
1216 bool MatchingInlineAsm) {
1217 MCInst Inst;
1218
1219 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
1220 case Match_Success:
1221 // Post-process instructions (typically extended mnemonics)
1222 ProcessInstruction(Inst, Operands);
1223 Inst.setLoc(IDLoc);
1224 Out.emitInstruction(Inst, getSTI());
1225 return false;
1226 case Match_MissingFeature:
1227 return Error(IDLoc, "instruction use requires an option to be enabled");
1228 case Match_MnemonicFail: {
1229 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1230 std::string Suggestion = PPCMnemonicSpellCheck(
1231 ((PPCOperand &)*Operands[0]).getToken(), FBS);
1232 return Error(IDLoc, "invalid instruction" + Suggestion,
1233 ((PPCOperand &)*Operands[0]).getLocRange());
1234 }
1235 case Match_InvalidOperand: {
1236 SMLoc ErrorLoc = IDLoc;
1237 if (ErrorInfo != ~0ULL) {
1238 if (ErrorInfo >= Operands.size())
1239 return Error(IDLoc, "too few operands for instruction");
1240
1241 ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();
1242 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1243 }
1244
1245 return Error(ErrorLoc, "invalid operand for instruction");
1246 }
1247 }
1248
1249 llvm_unreachable("Implement any new match types added!");
1250 }
1251
MatchRegisterName(MCRegister & RegNo,int64_t & IntVal)1252 bool PPCAsmParser::MatchRegisterName(MCRegister &RegNo, int64_t &IntVal) {
1253 if (getParser().getTok().is(AsmToken::Percent))
1254 getParser().Lex(); // Eat the '%'.
1255
1256 if (!getParser().getTok().is(AsmToken::Identifier))
1257 return true;
1258
1259 StringRef Name = getParser().getTok().getString();
1260 if (Name.equals_insensitive("lr")) {
1261 RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
1262 IntVal = 8;
1263 } else if (Name.equals_insensitive("ctr")) {
1264 RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
1265 IntVal = 9;
1266 } else if (Name.equals_insensitive("vrsave")) {
1267 RegNo = PPC::VRSAVE;
1268 IntVal = 256;
1269 } else if (Name.startswith_insensitive("r") &&
1270 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1271 RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];
1272 } else if (Name.startswith_insensitive("f") &&
1273 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1274 RegNo = FRegs[IntVal];
1275 } else if (Name.startswith_insensitive("vs") &&
1276 !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
1277 RegNo = VSRegs[IntVal];
1278 } else if (Name.startswith_insensitive("v") &&
1279 !Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1280 RegNo = VRegs[IntVal];
1281 } else if (Name.startswith_insensitive("cr") &&
1282 !Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
1283 RegNo = CRRegs[IntVal];
1284 } else if (Name.startswith_insensitive("acc") &&
1285 !Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1286 RegNo = ACCRegs[IntVal];
1287 } else if (Name.startswith_insensitive("wacc_hi") &&
1288 !Name.substr(7).getAsInteger(10, IntVal) && IntVal < 8) {
1289 RegNo = ACCRegs[IntVal];
1290 } else if (Name.startswith_insensitive("wacc") &&
1291 !Name.substr(4).getAsInteger(10, IntVal) && IntVal < 8) {
1292 RegNo = WACCRegs[IntVal];
1293 } else if (Name.startswith_insensitive("dmrrowp") &&
1294 !Name.substr(7).getAsInteger(10, IntVal) && IntVal < 32) {
1295 RegNo = DMRROWpRegs[IntVal];
1296 } else if (Name.startswith_insensitive("dmrrow") &&
1297 !Name.substr(6).getAsInteger(10, IntVal) && IntVal < 64) {
1298 RegNo = DMRROWRegs[IntVal];
1299 } else if (Name.startswith_insensitive("dmrp") &&
1300 !Name.substr(4).getAsInteger(10, IntVal) && IntVal < 4) {
1301 RegNo = DMRROWpRegs[IntVal];
1302 } else if (Name.startswith_insensitive("dmr") &&
1303 !Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1304 RegNo = DMRRegs[IntVal];
1305 } else
1306 return true;
1307 getParser().Lex();
1308 return false;
1309 }
1310
parseRegister(MCRegister & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)1311 bool PPCAsmParser::parseRegister(MCRegister &RegNo, SMLoc &StartLoc,
1312 SMLoc &EndLoc) {
1313 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success)
1314 return TokError("invalid register name");
1315 return false;
1316 }
1317
tryParseRegister(MCRegister & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)1318 OperandMatchResultTy PPCAsmParser::tryParseRegister(MCRegister &RegNo,
1319 SMLoc &StartLoc,
1320 SMLoc &EndLoc) {
1321 const AsmToken &Tok = getParser().getTok();
1322 StartLoc = Tok.getLoc();
1323 EndLoc = Tok.getEndLoc();
1324 RegNo = 0;
1325 int64_t IntVal;
1326 if (MatchRegisterName(RegNo, IntVal))
1327 return MatchOperand_NoMatch;
1328 return MatchOperand_Success;
1329 }
1330
1331 /// Extract \code @l/@ha \endcode modifier from expression. Recursively scan
1332 /// the expression and check for VK_PPC_LO/HI/HA
1333 /// symbol variants. If all symbols with modifier use the same
1334 /// variant, return the corresponding PPCMCExpr::VariantKind,
1335 /// and a modified expression using the default symbol variant.
1336 /// Otherwise, return NULL.
1337 const MCExpr *PPCAsmParser::
ExtractModifierFromExpr(const MCExpr * E,PPCMCExpr::VariantKind & Variant)1338 ExtractModifierFromExpr(const MCExpr *E,
1339 PPCMCExpr::VariantKind &Variant) {
1340 MCContext &Context = getParser().getContext();
1341 Variant = PPCMCExpr::VK_PPC_None;
1342
1343 switch (E->getKind()) {
1344 case MCExpr::Target:
1345 case MCExpr::Constant:
1346 return nullptr;
1347
1348 case MCExpr::SymbolRef: {
1349 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1350
1351 switch (SRE->getKind()) {
1352 case MCSymbolRefExpr::VK_PPC_LO:
1353 Variant = PPCMCExpr::VK_PPC_LO;
1354 break;
1355 case MCSymbolRefExpr::VK_PPC_HI:
1356 Variant = PPCMCExpr::VK_PPC_HI;
1357 break;
1358 case MCSymbolRefExpr::VK_PPC_HA:
1359 Variant = PPCMCExpr::VK_PPC_HA;
1360 break;
1361 case MCSymbolRefExpr::VK_PPC_HIGH:
1362 Variant = PPCMCExpr::VK_PPC_HIGH;
1363 break;
1364 case MCSymbolRefExpr::VK_PPC_HIGHA:
1365 Variant = PPCMCExpr::VK_PPC_HIGHA;
1366 break;
1367 case MCSymbolRefExpr::VK_PPC_HIGHER:
1368 Variant = PPCMCExpr::VK_PPC_HIGHER;
1369 break;
1370 case MCSymbolRefExpr::VK_PPC_HIGHERA:
1371 Variant = PPCMCExpr::VK_PPC_HIGHERA;
1372 break;
1373 case MCSymbolRefExpr::VK_PPC_HIGHEST:
1374 Variant = PPCMCExpr::VK_PPC_HIGHEST;
1375 break;
1376 case MCSymbolRefExpr::VK_PPC_HIGHESTA:
1377 Variant = PPCMCExpr::VK_PPC_HIGHESTA;
1378 break;
1379 default:
1380 return nullptr;
1381 }
1382
1383 return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);
1384 }
1385
1386 case MCExpr::Unary: {
1387 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1388 const MCExpr *Sub = ExtractModifierFromExpr(UE->getSubExpr(), Variant);
1389 if (!Sub)
1390 return nullptr;
1391 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
1392 }
1393
1394 case MCExpr::Binary: {
1395 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1396 PPCMCExpr::VariantKind LHSVariant, RHSVariant;
1397 const MCExpr *LHS = ExtractModifierFromExpr(BE->getLHS(), LHSVariant);
1398 const MCExpr *RHS = ExtractModifierFromExpr(BE->getRHS(), RHSVariant);
1399
1400 if (!LHS && !RHS)
1401 return nullptr;
1402
1403 if (!LHS) LHS = BE->getLHS();
1404 if (!RHS) RHS = BE->getRHS();
1405
1406 if (LHSVariant == PPCMCExpr::VK_PPC_None)
1407 Variant = RHSVariant;
1408 else if (RHSVariant == PPCMCExpr::VK_PPC_None)
1409 Variant = LHSVariant;
1410 else if (LHSVariant == RHSVariant)
1411 Variant = LHSVariant;
1412 else
1413 return nullptr;
1414
1415 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
1416 }
1417 }
1418
1419 llvm_unreachable("Invalid expression kind!");
1420 }
1421
1422 /// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace
1423 /// them by VK_PPC_TLSGD/VK_PPC_TLSLD. This is necessary to avoid having
1424 /// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT.
1425 /// FIXME: This is a hack.
1426 const MCExpr *PPCAsmParser::
FixupVariantKind(const MCExpr * E)1427 FixupVariantKind(const MCExpr *E) {
1428 MCContext &Context = getParser().getContext();
1429
1430 switch (E->getKind()) {
1431 case MCExpr::Target:
1432 case MCExpr::Constant:
1433 return E;
1434
1435 case MCExpr::SymbolRef: {
1436 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1437 MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
1438
1439 switch (SRE->getKind()) {
1440 case MCSymbolRefExpr::VK_TLSGD:
1441 Variant = MCSymbolRefExpr::VK_PPC_TLSGD;
1442 break;
1443 case MCSymbolRefExpr::VK_TLSLD:
1444 Variant = MCSymbolRefExpr::VK_PPC_TLSLD;
1445 break;
1446 default:
1447 return E;
1448 }
1449 return MCSymbolRefExpr::create(&SRE->getSymbol(), Variant, Context);
1450 }
1451
1452 case MCExpr::Unary: {
1453 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1454 const MCExpr *Sub = FixupVariantKind(UE->getSubExpr());
1455 if (Sub == UE->getSubExpr())
1456 return E;
1457 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
1458 }
1459
1460 case MCExpr::Binary: {
1461 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1462 const MCExpr *LHS = FixupVariantKind(BE->getLHS());
1463 const MCExpr *RHS = FixupVariantKind(BE->getRHS());
1464 if (LHS == BE->getLHS() && RHS == BE->getRHS())
1465 return E;
1466 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
1467 }
1468 }
1469
1470 llvm_unreachable("Invalid expression kind!");
1471 }
1472
1473 /// ParseExpression. This differs from the default "parseExpression" in that
1474 /// it handles modifiers.
1475 bool PPCAsmParser::
ParseExpression(const MCExpr * & EVal)1476 ParseExpression(const MCExpr *&EVal) {
1477 // (ELF Platforms)
1478 // Handle \code @l/@ha \endcode
1479 if (getParser().parseExpression(EVal))
1480 return true;
1481
1482 EVal = FixupVariantKind(EVal);
1483
1484 PPCMCExpr::VariantKind Variant;
1485 const MCExpr *E = ExtractModifierFromExpr(EVal, Variant);
1486 if (E)
1487 EVal = PPCMCExpr::create(Variant, E, getParser().getContext());
1488
1489 return false;
1490 }
1491
1492 /// ParseOperand
1493 /// This handles registers in the form 'NN', '%rNN' for ELF platforms and
1494 /// rNN for MachO.
ParseOperand(OperandVector & Operands)1495 bool PPCAsmParser::ParseOperand(OperandVector &Operands) {
1496 MCAsmParser &Parser = getParser();
1497 SMLoc S = Parser.getTok().getLoc();
1498 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1499 const MCExpr *EVal;
1500
1501 // Attempt to parse the next token as an immediate
1502 switch (getLexer().getKind()) {
1503 // Special handling for register names. These are interpreted
1504 // as immediates corresponding to the register number.
1505 case AsmToken::Percent: {
1506 MCRegister RegNo;
1507 int64_t IntVal;
1508 if (MatchRegisterName(RegNo, IntVal))
1509 return Error(S, "invalid register name");
1510
1511 Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
1512 return false;
1513 }
1514 case AsmToken::Identifier:
1515 case AsmToken::LParen:
1516 case AsmToken::Plus:
1517 case AsmToken::Minus:
1518 case AsmToken::Integer:
1519 case AsmToken::Dot:
1520 case AsmToken::Dollar:
1521 case AsmToken::Exclaim:
1522 case AsmToken::Tilde:
1523 if (!ParseExpression(EVal))
1524 break;
1525 // Fall-through
1526 [[fallthrough]];
1527 default:
1528 return Error(S, "unknown operand");
1529 }
1530
1531 // Push the parsed operand into the list of operands
1532 Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));
1533
1534 // Check whether this is a TLS call expression
1535 bool TLSCall = false;
1536 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(EVal))
1537 TLSCall = Ref->getSymbol().getName() == "__tls_get_addr";
1538
1539 if (TLSCall && getLexer().is(AsmToken::LParen)) {
1540 const MCExpr *TLSSym;
1541
1542 Parser.Lex(); // Eat the '('.
1543 S = Parser.getTok().getLoc();
1544 if (ParseExpression(TLSSym))
1545 return Error(S, "invalid TLS call expression");
1546 if (getLexer().isNot(AsmToken::RParen))
1547 return Error(Parser.getTok().getLoc(), "missing ')'");
1548 E = Parser.getTok().getLoc();
1549 Parser.Lex(); // Eat the ')'.
1550
1551 Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));
1552 }
1553
1554 // Otherwise, check for D-form memory operands
1555 if (!TLSCall && getLexer().is(AsmToken::LParen)) {
1556 Parser.Lex(); // Eat the '('.
1557 S = Parser.getTok().getLoc();
1558
1559 int64_t IntVal;
1560 switch (getLexer().getKind()) {
1561 case AsmToken::Percent: {
1562 MCRegister RegNo;
1563 if (MatchRegisterName(RegNo, IntVal))
1564 return Error(S, "invalid register name");
1565 break;
1566 }
1567 case AsmToken::Integer:
1568 if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
1569 IntVal > 31)
1570 return Error(S, "invalid register number");
1571 break;
1572 case AsmToken::Identifier:
1573 default:
1574 return Error(S, "invalid memory operand");
1575 }
1576
1577 E = Parser.getTok().getLoc();
1578 if (parseToken(AsmToken::RParen, "missing ')'"))
1579 return true;
1580 Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
1581 }
1582
1583 return false;
1584 }
1585
1586 /// Parse an instruction mnemonic followed by its operands.
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)1587 bool PPCAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1588 SMLoc NameLoc, OperandVector &Operands) {
1589 // The first operand is the token for the instruction name.
1590 // If the next character is a '+' or '-', we need to add it to the
1591 // instruction name, to match what TableGen is doing.
1592 std::string NewOpcode;
1593 if (parseOptionalToken(AsmToken::Plus)) {
1594 NewOpcode = std::string(Name);
1595 NewOpcode += '+';
1596 Name = NewOpcode;
1597 }
1598 if (parseOptionalToken(AsmToken::Minus)) {
1599 NewOpcode = std::string(Name);
1600 NewOpcode += '-';
1601 Name = NewOpcode;
1602 }
1603 // If the instruction ends in a '.', we need to create a separate
1604 // token for it, to match what TableGen is doing.
1605 size_t Dot = Name.find('.');
1606 StringRef Mnemonic = Name.slice(0, Dot);
1607 if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
1608 Operands.push_back(
1609 PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
1610 else
1611 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
1612 if (Dot != StringRef::npos) {
1613 SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);
1614 StringRef DotStr = Name.slice(Dot, StringRef::npos);
1615 if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
1616 Operands.push_back(
1617 PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
1618 else
1619 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
1620 }
1621
1622 // If there are no more operands then finish
1623 if (parseOptionalToken(AsmToken::EndOfStatement))
1624 return false;
1625
1626 // Parse the first operand
1627 if (ParseOperand(Operands))
1628 return true;
1629
1630 while (!parseOptionalToken(AsmToken::EndOfStatement)) {
1631 if (parseToken(AsmToken::Comma) || ParseOperand(Operands))
1632 return true;
1633 }
1634
1635 // We'll now deal with an unfortunate special case: the syntax for the dcbt
1636 // and dcbtst instructions differs for server vs. embedded cores.
1637 // The syntax for dcbt is:
1638 // dcbt ra, rb, th [server]
1639 // dcbt th, ra, rb [embedded]
1640 // where th can be omitted when it is 0. dcbtst is the same. We take the
1641 // server form to be the default, so swap the operands if we're parsing for
1642 // an embedded core (they'll be swapped again upon printing).
1643 if (getSTI().getFeatureBits()[PPC::FeatureBookE] &&
1644 Operands.size() == 4 &&
1645 (Name == "dcbt" || Name == "dcbtst")) {
1646 std::swap(Operands[1], Operands[3]);
1647 std::swap(Operands[2], Operands[1]);
1648 }
1649
1650 // Handle base mnemonic for atomic loads where the EH bit is zero.
1651 if (Name == "lqarx" || Name == "ldarx" || Name == "lwarx" ||
1652 Name == "lharx" || Name == "lbarx") {
1653 if (Operands.size() != 5)
1654 return false;
1655 PPCOperand &EHOp = (PPCOperand &)*Operands[4];
1656 if (EHOp.isU1Imm() && EHOp.getImm() == 0)
1657 Operands.pop_back();
1658 }
1659
1660 return false;
1661 }
1662
1663 /// ParseDirective parses the PPC specific directives
ParseDirective(AsmToken DirectiveID)1664 bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {
1665 StringRef IDVal = DirectiveID.getIdentifier();
1666 if (IDVal == ".word")
1667 ParseDirectiveWord(2, DirectiveID);
1668 else if (IDVal == ".llong")
1669 ParseDirectiveWord(8, DirectiveID);
1670 else if (IDVal == ".tc")
1671 ParseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);
1672 else if (IDVal == ".machine")
1673 ParseDirectiveMachine(DirectiveID.getLoc());
1674 else if (IDVal == ".abiversion")
1675 ParseDirectiveAbiVersion(DirectiveID.getLoc());
1676 else if (IDVal == ".localentry")
1677 ParseDirectiveLocalEntry(DirectiveID.getLoc());
1678 else if (IDVal.startswith(".gnu_attribute"))
1679 ParseGNUAttribute(DirectiveID.getLoc());
1680 else
1681 return true;
1682 return false;
1683 }
1684
1685 /// ParseDirectiveWord
1686 /// ::= .word [ expression (, expression)* ]
ParseDirectiveWord(unsigned Size,AsmToken ID)1687 bool PPCAsmParser::ParseDirectiveWord(unsigned Size, AsmToken ID) {
1688 auto parseOp = [&]() -> bool {
1689 const MCExpr *Value;
1690 SMLoc ExprLoc = getParser().getTok().getLoc();
1691 if (getParser().parseExpression(Value))
1692 return true;
1693 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
1694 assert(Size <= 8 && "Invalid size");
1695 uint64_t IntValue = MCE->getValue();
1696 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
1697 return Error(ExprLoc, "literal value out of range for '" +
1698 ID.getIdentifier() + "' directive");
1699 getStreamer().emitIntValue(IntValue, Size);
1700 } else
1701 getStreamer().emitValue(Value, Size, ExprLoc);
1702 return false;
1703 };
1704
1705 if (parseMany(parseOp))
1706 return addErrorSuffix(" in '" + ID.getIdentifier() + "' directive");
1707 return false;
1708 }
1709
1710 /// ParseDirectiveTC
1711 /// ::= .tc [ symbol (, expression)* ]
ParseDirectiveTC(unsigned Size,AsmToken ID)1712 bool PPCAsmParser::ParseDirectiveTC(unsigned Size, AsmToken ID) {
1713 MCAsmParser &Parser = getParser();
1714 // Skip TC symbol, which is only used with XCOFF.
1715 while (getLexer().isNot(AsmToken::EndOfStatement)
1716 && getLexer().isNot(AsmToken::Comma))
1717 Parser.Lex();
1718 if (parseToken(AsmToken::Comma))
1719 return addErrorSuffix(" in '.tc' directive");
1720
1721 // Align to word size.
1722 getParser().getStreamer().emitValueToAlignment(Align(Size));
1723
1724 // Emit expressions.
1725 return ParseDirectiveWord(Size, ID);
1726 }
1727
1728 /// ParseDirectiveMachine (ELF platforms)
1729 /// ::= .machine [ cpu | "push" | "pop" ]
ParseDirectiveMachine(SMLoc L)1730 bool PPCAsmParser::ParseDirectiveMachine(SMLoc L) {
1731 MCAsmParser &Parser = getParser();
1732 if (Parser.getTok().isNot(AsmToken::Identifier) &&
1733 Parser.getTok().isNot(AsmToken::String))
1734 return Error(L, "unexpected token in '.machine' directive");
1735
1736 StringRef CPU = Parser.getTok().getIdentifier();
1737
1738 // FIXME: Right now, the parser always allows any available
1739 // instruction, so the .machine directive is not useful.
1740 // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen.
1741
1742 Parser.Lex();
1743
1744 if (parseToken(AsmToken::EndOfStatement))
1745 return addErrorSuffix(" in '.machine' directive");
1746
1747 PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
1748 getParser().getStreamer().getTargetStreamer());
1749 if (TStreamer != nullptr)
1750 TStreamer->emitMachine(CPU);
1751
1752 return false;
1753 }
1754
1755 /// ParseDirectiveAbiVersion
1756 /// ::= .abiversion constant-expression
ParseDirectiveAbiVersion(SMLoc L)1757 bool PPCAsmParser::ParseDirectiveAbiVersion(SMLoc L) {
1758 int64_t AbiVersion;
1759 if (check(getParser().parseAbsoluteExpression(AbiVersion), L,
1760 "expected constant expression") ||
1761 parseToken(AsmToken::EndOfStatement))
1762 return addErrorSuffix(" in '.abiversion' directive");
1763
1764 PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
1765 getParser().getStreamer().getTargetStreamer());
1766 if (TStreamer != nullptr)
1767 TStreamer->emitAbiVersion(AbiVersion);
1768
1769 return false;
1770 }
1771
1772 /// ParseDirectiveLocalEntry
1773 /// ::= .localentry symbol, expression
ParseDirectiveLocalEntry(SMLoc L)1774 bool PPCAsmParser::ParseDirectiveLocalEntry(SMLoc L) {
1775 StringRef Name;
1776 if (getParser().parseIdentifier(Name))
1777 return Error(L, "expected identifier in '.localentry' directive");
1778
1779 MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
1780 const MCExpr *Expr;
1781
1782 if (parseToken(AsmToken::Comma) ||
1783 check(getParser().parseExpression(Expr), L, "expected expression") ||
1784 parseToken(AsmToken::EndOfStatement))
1785 return addErrorSuffix(" in '.localentry' directive");
1786
1787 PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
1788 getParser().getStreamer().getTargetStreamer());
1789 if (TStreamer != nullptr)
1790 TStreamer->emitLocalEntry(Sym, Expr);
1791
1792 return false;
1793 }
1794
ParseGNUAttribute(SMLoc L)1795 bool PPCAsmParser::ParseGNUAttribute(SMLoc L) {
1796 int64_t Tag;
1797 int64_t IntegerValue;
1798 if (!getParser().parseGNUAttribute(L, Tag, IntegerValue))
1799 return false;
1800
1801 getParser().getStreamer().emitGNUAttribute(Tag, IntegerValue);
1802
1803 return true;
1804 }
1805
1806 /// Force static initialization.
LLVMInitializePowerPCAsmParser()1807 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser() {
1808 RegisterMCAsmParser<PPCAsmParser> A(getThePPC32Target());
1809 RegisterMCAsmParser<PPCAsmParser> B(getThePPC32LETarget());
1810 RegisterMCAsmParser<PPCAsmParser> C(getThePPC64Target());
1811 RegisterMCAsmParser<PPCAsmParser> D(getThePPC64LETarget());
1812 }
1813
1814 #define GET_REGISTER_MATCHER
1815 #define GET_MATCHER_IMPLEMENTATION
1816 #define GET_MNEMONIC_SPELL_CHECKER
1817 #include "PPCGenAsmMatcher.inc"
1818
1819 // Define this matcher function after the auto-generated include so we
1820 // have the match class enum definitions.
validateTargetOperandClass(MCParsedAsmOperand & AsmOp,unsigned Kind)1821 unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1822 unsigned Kind) {
1823 // If the kind is a token for a literal immediate, check if our asm
1824 // operand matches. This is for InstAliases which have a fixed-value
1825 // immediate in the syntax.
1826 int64_t ImmVal;
1827 switch (Kind) {
1828 case MCK_0: ImmVal = 0; break;
1829 case MCK_1: ImmVal = 1; break;
1830 case MCK_2: ImmVal = 2; break;
1831 case MCK_3: ImmVal = 3; break;
1832 case MCK_4: ImmVal = 4; break;
1833 case MCK_5: ImmVal = 5; break;
1834 case MCK_6: ImmVal = 6; break;
1835 case MCK_7: ImmVal = 7; break;
1836 default: return Match_InvalidOperand;
1837 }
1838
1839 PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
1840 if (Op.isU3Imm() && Op.getImm() == ImmVal)
1841 return Match_Success;
1842
1843 return Match_InvalidOperand;
1844 }
1845
1846 const MCExpr *
applyModifierToExpr(const MCExpr * E,MCSymbolRefExpr::VariantKind Variant,MCContext & Ctx)1847 PPCAsmParser::applyModifierToExpr(const MCExpr *E,
1848 MCSymbolRefExpr::VariantKind Variant,
1849 MCContext &Ctx) {
1850 switch (Variant) {
1851 case MCSymbolRefExpr::VK_PPC_LO:
1852 return PPCMCExpr::create(PPCMCExpr::VK_PPC_LO, E, Ctx);
1853 case MCSymbolRefExpr::VK_PPC_HI:
1854 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HI, E, Ctx);
1855 case MCSymbolRefExpr::VK_PPC_HA:
1856 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HA, E, Ctx);
1857 case MCSymbolRefExpr::VK_PPC_HIGH:
1858 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGH, E, Ctx);
1859 case MCSymbolRefExpr::VK_PPC_HIGHA:
1860 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHA, E, Ctx);
1861 case MCSymbolRefExpr::VK_PPC_HIGHER:
1862 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHER, E, Ctx);
1863 case MCSymbolRefExpr::VK_PPC_HIGHERA:
1864 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHERA, E, Ctx);
1865 case MCSymbolRefExpr::VK_PPC_HIGHEST:
1866 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHEST, E, Ctx);
1867 case MCSymbolRefExpr::VK_PPC_HIGHESTA:
1868 return PPCMCExpr::create(PPCMCExpr::VK_PPC_HIGHESTA, E, Ctx);
1869 default:
1870 return nullptr;
1871 }
1872 }
1873