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