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