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