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