LLVM 20.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
11#include "PPCInstrInfo.h"
12#include "PPCTargetStreamer.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"
29
30using namespace llvm;
31
33
34// Evaluate an expression containing condition register
35// or condition register field symbols. Returns positive
36// value on success, or -1 on error.
37static int64_t
39 switch (E->getKind()) {
40 case MCExpr::Target:
41 return -1;
42
43 case MCExpr::Constant: {
44 int64_t Res = cast<MCConstantExpr>(E)->getValue();
45 return Res < 0 ? -1 : Res;
46 }
47
48 case MCExpr::SymbolRef: {
49 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
51
52 if (Name == "lt") return 0;
53 if (Name == "gt") return 1;
54 if (Name == "eq") return 2;
55 if (Name == "so") return 3;
56 if (Name == "un") return 3;
57
58 if (Name == "cr0") return 0;
59 if (Name == "cr1") return 1;
60 if (Name == "cr2") return 2;
61 if (Name == "cr3") return 3;
62 if (Name == "cr4") return 4;
63 if (Name == "cr5") return 5;
64 if (Name == "cr6") return 6;
65 if (Name == "cr7") return 7;
66
67 return -1;
68 }
69
70 case MCExpr::Unary:
71 return -1;
72
73 case MCExpr::Binary: {
74 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
75 int64_t LHSVal = EvaluateCRExpr(BE->getLHS());
76 int64_t RHSVal = EvaluateCRExpr(BE->getRHS());
77 int64_t Res;
78
79 if (LHSVal < 0 || RHSVal < 0)
80 return -1;
81
82 switch (BE->getOpcode()) {
83 default: return -1;
84 case MCBinaryExpr::Add: Res = LHSVal + RHSVal; break;
85 case MCBinaryExpr::Mul: Res = LHSVal * RHSVal; break;
86 }
87
88 return Res < 0 ? -1 : Res;
89 }
90 }
91
92 llvm_unreachable("Invalid expression kind!");
93}
94
95namespace {
96
97struct PPCOperand;
98
99class PPCAsmParser : public MCTargetAsmParser {
100 const bool IsPPC64;
101
102 void Warning(SMLoc L, const Twine &Msg) { getParser().Warning(L, Msg); }
103
104 bool isPPC64() const { return IsPPC64; }
105
106 MCRegister matchRegisterName(int64_t &IntVal);
107
108 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
110 SMLoc &EndLoc) override;
111
112 const MCExpr *extractModifierFromExpr(const MCExpr *E,
113 PPCMCExpr::VariantKind &Variant);
114 const MCExpr *fixupVariantKind(const MCExpr *E);
115 bool parseExpression(const MCExpr *&EVal);
116
117 bool parseOperand(OperandVector &Operands);
118
119 bool parseDirectiveWord(unsigned Size, AsmToken ID);
120 bool parseDirectiveTC(unsigned Size, AsmToken ID);
121 bool parseDirectiveMachine(SMLoc L);
122 bool parseDirectiveAbiVersion(SMLoc L);
123 bool parseDirectiveLocalEntry(SMLoc L);
124 bool parseGNUAttribute(SMLoc L);
125
126 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
129 bool MatchingInlineAsm) override;
130
131 void processInstruction(MCInst &Inst, const OperandVector &Ops);
132
133 /// @name Auto-generated Match Functions
134 /// {
135
136#define GET_ASSEMBLER_HEADER
137#include "PPCGenAsmMatcher.inc"
138
139 /// }
140
141
142public:
143 PPCAsmParser(const MCSubtargetInfo &STI, MCAsmParser &,
144 const MCInstrInfo &MII, const MCTargetOptions &Options)
145 : MCTargetAsmParser(Options, STI, MII),
146 IsPPC64(STI.getTargetTriple().isPPC64()) {
147 // Initialize the set of available features.
148 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
149 }
150
152 SMLoc NameLoc, OperandVector &Operands) override;
153
154 bool ParseDirective(AsmToken DirectiveID) override;
155
157 unsigned Kind) override;
158
159 const MCExpr *applyModifierToExpr(const MCExpr *E,
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,
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 bool isU1Imm() const { return Kind == Immediate && isUInt<1>(getImm()); }
353 bool isU2Imm() const { return Kind == Immediate && isUInt<2>(getImm()); }
354 bool isU3Imm() const { return Kind == Immediate && isUInt<3>(getImm()); }
355 bool isU4Imm() const { return Kind == Immediate && isUInt<4>(getImm()); }
356 bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
357 bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }
358 bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); }
359 bool isU6ImmX2() const { return Kind == Immediate &&
360 isUInt<6>(getImm()) &&
361 (getImm() & 1) == 0; }
362 bool isU7Imm() const { return Kind == Immediate && isUInt<7>(getImm()); }
363 bool isU7ImmX4() const { return Kind == Immediate &&
364 isUInt<7>(getImm()) &&
365 (getImm() & 3) == 0; }
366 bool isU8Imm() const { return Kind == Immediate && isUInt<8>(getImm()); }
367 bool isU8ImmX8() const { return Kind == Immediate &&
368 isUInt<8>(getImm()) &&
369 (getImm() & 7) == 0; }
370
371 bool isU10Imm() const { return Kind == Immediate && isUInt<10>(getImm()); }
372 bool isU12Imm() const { return Kind == Immediate && isUInt<12>(getImm()); }
373 bool isU16Imm() const { return isExtImm<16>(/*Signed*/ false, 1); }
374 bool isS16Imm() const { return isExtImm<16>(/*Signed*/ true, 1); }
375 bool isS16ImmX4() const { return isExtImm<16>(/*Signed*/ true, 4); }
376 bool isS16ImmX16() const { return isExtImm<16>(/*Signed*/ true, 16); }
377 bool isS17Imm() const { return isExtImm<17>(/*Signed*/ true, 1); }
378
379 bool isHashImmX8() const {
380 // The Hash Imm form is used for instructions that check or store a hash.
381 // These instructions have a small immediate range that spans between
382 // -8 and -512.
383 return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&
384 (getImm() & 7) == 0);
385 }
386
387 bool isS34ImmX16() const {
388 return Kind == Expression ||
389 (Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
390 }
391 bool isS34Imm() const {
392 // Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
393 // ContextImmediate is needed.
394 return Kind == Expression || (Kind == Immediate && isInt<34>(getImm()));
395 }
396
397 bool isTLSReg() const { return Kind == TLSRegister; }
398 bool isDirectBr() const {
399 if (Kind == Expression)
400 return true;
401 if (Kind != Immediate)
402 return false;
403 // Operand must be 64-bit aligned, signed 27-bit immediate.
404 if ((getImm() & 3) != 0)
405 return false;
406 if (isInt<26>(getImm()))
407 return true;
408 if (!IsPPC64) {
409 // In 32-bit mode, large 32-bit quantities wrap around.
410 if (isUInt<32>(getImm()) && isInt<26>(static_cast<int32_t>(getImm())))
411 return true;
412 }
413 return false;
414 }
415 bool isCondBr() const { return Kind == Expression ||
416 (Kind == Immediate && isInt<16>(getImm()) &&
417 (getImm() & 3) == 0); }
418 bool isImmZero() const { return Kind == Immediate && getImm() == 0; }
419 bool isRegNumber() const { return Kind == Immediate && isUInt<5>(getImm()); }
420 bool isACCRegNumber() const {
421 return Kind == Immediate && isUInt<3>(getImm());
422 }
423 bool isDMRROWRegNumber() const {
424 return Kind == Immediate && isUInt<6>(getImm());
425 }
426 bool isDMRROWpRegNumber() const {
427 return Kind == Immediate && isUInt<5>(getImm());
428 }
429 bool isDMRRegNumber() const {
430 return Kind == Immediate && isUInt<3>(getImm());
431 }
432 bool isDMRpRegNumber() const {
433 return Kind == Immediate && isUInt<2>(getImm());
434 }
435 bool isVSRpEvenRegNumber() const {
436 return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
437 }
438 bool isVSRegNumber() const {
439 return Kind == Immediate && isUInt<6>(getImm());
440 }
441 bool isCCRegNumber() const { return (Kind == Expression
442 && isUInt<3>(getExprCRVal())) ||
443 (Kind == Immediate
444 && isUInt<3>(getImm())); }
445 bool isCRBitNumber() const { return (Kind == Expression
446 && isUInt<5>(getExprCRVal())) ||
447 (Kind == Immediate
448 && isUInt<5>(getImm())); }
449
450 bool isEvenRegNumber() const { return isRegNumber() && (getImm() & 1) == 0; }
451
452 bool isCRBitMask() const {
453 return Kind == Immediate && isUInt<8>(getImm()) &&
454 llvm::has_single_bit<uint32_t>(getImm());
455 }
456 bool isATBitsAsHint() const { return false; }
457 bool isMem() const override { return false; }
458 bool isReg() const override { return false; }
459
460 void addRegOperands(MCInst &Inst, unsigned N) const {
461 llvm_unreachable("addRegOperands");
462 }
463
464 void addRegGPRCOperands(MCInst &Inst, unsigned N) const {
465 assert(N == 1 && "Invalid number of operands!");
467 }
468
469 void addRegGPRCNoR0Operands(MCInst &Inst, unsigned N) const {
470 assert(N == 1 && "Invalid number of operands!");
471 Inst.addOperand(MCOperand::createReg(RRegsNoR0[getRegNum()]));
472 }
473
474 void addRegG8RCOperands(MCInst &Inst, unsigned N) const {
475 assert(N == 1 && "Invalid number of operands!");
477 }
478
479 void addRegG8RCNoX0Operands(MCInst &Inst, unsigned N) const {
480 assert(N == 1 && "Invalid number of operands!");
481 Inst.addOperand(MCOperand::createReg(XRegsNoX0[getRegNum()]));
482 }
483
484 void addRegG8pRCOperands(MCInst &Inst, unsigned N) const {
485 assert(N == 1 && "Invalid number of operands!");
486 Inst.addOperand(MCOperand::createReg(XRegs[getG8pReg()]));
487 }
488
489 void addRegGxRCOperands(MCInst &Inst, unsigned N) const {
490 if (isPPC64())
491 addRegG8RCOperands(Inst, N);
492 else
493 addRegGPRCOperands(Inst, N);
494 }
495
496 void addRegGxRCNoR0Operands(MCInst &Inst, unsigned N) const {
497 if (isPPC64())
498 addRegG8RCNoX0Operands(Inst, N);
499 else
500 addRegGPRCNoR0Operands(Inst, N);
501 }
502
503 void addRegF4RCOperands(MCInst &Inst, unsigned N) const {
504 assert(N == 1 && "Invalid number of operands!");
506 }
507
508 void addRegF8RCOperands(MCInst &Inst, unsigned N) const {
509 assert(N == 1 && "Invalid number of operands!");
511 }
512
513 void addRegFpRCOperands(MCInst &Inst, unsigned N) const {
514 assert(N == 1 && "Invalid number of operands!");
515 Inst.addOperand(MCOperand::createReg(FpRegs[getFpReg()]));
516 }
517
518 void addRegVFRCOperands(MCInst &Inst, unsigned N) const {
519 assert(N == 1 && "Invalid number of operands!");
521 }
522
523 void addRegVRRCOperands(MCInst &Inst, unsigned N) const {
524 assert(N == 1 && "Invalid number of operands!");
526 }
527
528 void addRegVSRCOperands(MCInst &Inst, unsigned N) const {
529 assert(N == 1 && "Invalid number of operands!");
530 Inst.addOperand(MCOperand::createReg(VSRegs[getVSReg()]));
531 }
532
533 void addRegVSFRCOperands(MCInst &Inst, unsigned N) const {
534 assert(N == 1 && "Invalid number of operands!");
535 Inst.addOperand(MCOperand::createReg(VSFRegs[getVSReg()]));
536 }
537
538 void addRegVSSRCOperands(MCInst &Inst, unsigned N) const {
539 assert(N == 1 && "Invalid number of operands!");
540 Inst.addOperand(MCOperand::createReg(VSSRegs[getVSReg()]));
541 }
542
543 void addRegSPE4RCOperands(MCInst &Inst, unsigned N) const {
544 assert(N == 1 && "Invalid number of operands!");
546 }
547
548 void addRegSPERCOperands(MCInst &Inst, unsigned N) const {
549 assert(N == 1 && "Invalid number of operands!");
550 Inst.addOperand(MCOperand::createReg(SPERegs[getRegNum()]));
551 }
552
553 void addRegACCRCOperands(MCInst &Inst, unsigned N) const {
554 assert(N == 1 && "Invalid number of operands!");
555 Inst.addOperand(MCOperand::createReg(ACCRegs[getACCReg()]));
556 }
557
558 void addRegDMRROWRCOperands(MCInst &Inst, unsigned N) const {
559 assert(N == 1 && "Invalid number of operands!");
560 Inst.addOperand(MCOperand::createReg(DMRROWRegs[getDMRROWReg()]));
561 }
562
563 void addRegDMRROWpRCOperands(MCInst &Inst, unsigned N) const {
564 assert(N == 1 && "Invalid number of operands!");
565 Inst.addOperand(MCOperand::createReg(DMRROWpRegs[getDMRROWpReg()]));
566 }
567
568 void addRegDMRRCOperands(MCInst &Inst, unsigned N) const {
569 assert(N == 1 && "Invalid number of operands!");
570 Inst.addOperand(MCOperand::createReg(DMRRegs[getDMRReg()]));
571 }
572
573 void addRegDMRpRCOperands(MCInst &Inst, unsigned N) const {
574 assert(N == 1 && "Invalid number of operands!");
575 Inst.addOperand(MCOperand::createReg(DMRpRegs[getDMRpReg()]));
576 }
577
578 void addRegWACCRCOperands(MCInst &Inst, unsigned N) const {
579 assert(N == 1 && "Invalid number of operands!");
580 Inst.addOperand(MCOperand::createReg(WACCRegs[getACCReg()]));
581 }
582
583 void addRegWACC_HIRCOperands(MCInst &Inst, unsigned N) const {
584 assert(N == 1 && "Invalid number of operands!");
585 Inst.addOperand(MCOperand::createReg(WACC_HIRegs[getACCReg()]));
586 }
587
588 void addRegVSRpRCOperands(MCInst &Inst, unsigned N) const {
589 assert(N == 1 && "Invalid number of operands!");
590 Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
591 }
592
593 void addRegVSRpEvenRCOperands(MCInst &Inst, unsigned N) const {
594 assert(N == 1 && "Invalid number of operands!");
595 Inst.addOperand(MCOperand::createReg(VSRpRegs[getVSRpEvenReg()]));
596 }
597
598 void addRegCRBITRCOperands(MCInst &Inst, unsigned N) const {
599 assert(N == 1 && "Invalid number of operands!");
600 Inst.addOperand(MCOperand::createReg(CRBITRegs[getCRBit()]));
601 }
602
603 void addRegCRRCOperands(MCInst &Inst, unsigned N) const {
604 assert(N == 1 && "Invalid number of operands!");
605 Inst.addOperand(MCOperand::createReg(CRRegs[getCCReg()]));
606 }
607
608 void addCRBitMaskOperands(MCInst &Inst, unsigned N) const {
609 assert(N == 1 && "Invalid number of operands!");
610 Inst.addOperand(MCOperand::createReg(CRRegs[getCRBitMask()]));
611 }
612
613 void addImmOperands(MCInst &Inst, unsigned N) const {
614 assert(N == 1 && "Invalid number of operands!");
615 if (Kind == Immediate)
616 Inst.addOperand(MCOperand::createImm(getImm()));
617 else
619 }
620
621 void addS16ImmOperands(MCInst &Inst, unsigned N) const {
622 assert(N == 1 && "Invalid number of operands!");
623 switch (Kind) {
624 case Immediate:
625 Inst.addOperand(MCOperand::createImm(getImm()));
626 break;
627 case ContextImmediate:
628 Inst.addOperand(MCOperand::createImm(getImmS16Context()));
629 break;
630 default:
632 break;
633 }
634 }
635
636 void addU16ImmOperands(MCInst &Inst, unsigned N) const {
637 assert(N == 1 && "Invalid number of operands!");
638 switch (Kind) {
639 case Immediate:
640 Inst.addOperand(MCOperand::createImm(getImm()));
641 break;
642 case ContextImmediate:
643 Inst.addOperand(MCOperand::createImm(getImmU16Context()));
644 break;
645 default:
647 break;
648 }
649 }
650
651 void addBranchTargetOperands(MCInst &Inst, unsigned N) const {
652 assert(N == 1 && "Invalid number of operands!");
653 if (Kind == Immediate)
654 Inst.addOperand(MCOperand::createImm(getImm() / 4));
655 else
657 }
658
659 void addTLSRegOperands(MCInst &Inst, unsigned N) const {
660 assert(N == 1 && "Invalid number of operands!");
661 Inst.addOperand(MCOperand::createExpr(getTLSReg()));
662 }
663
664 StringRef getToken() const {
665 assert(Kind == Token && "Invalid access!");
666 return StringRef(Tok.Data, Tok.Length);
667 }
668
669 void print(raw_ostream &OS) const override;
670
671 static std::unique_ptr<PPCOperand> CreateToken(StringRef Str, SMLoc S,
672 bool IsPPC64) {
673 auto Op = std::make_unique<PPCOperand>(Token);
674 Op->Tok.Data = Str.data();
675 Op->Tok.Length = Str.size();
676 Op->StartLoc = S;
677 Op->EndLoc = S;
678 Op->IsPPC64 = IsPPC64;
679 return Op;
680 }
681
682 static std::unique_ptr<PPCOperand>
683 CreateTokenWithStringCopy(StringRef Str, SMLoc S, bool IsPPC64) {
684 // Allocate extra memory for the string and copy it.
685 // FIXME: This is incorrect, Operands are owned by unique_ptr with a default
686 // deleter which will destroy them by simply using "delete", not correctly
687 // calling operator delete on this extra memory after calling the dtor
688 // explicitly.
689 void *Mem = ::operator new(sizeof(PPCOperand) + Str.size());
690 std::unique_ptr<PPCOperand> Op(new (Mem) PPCOperand(Token));
691 Op->Tok.Data = reinterpret_cast<const char *>(Op.get() + 1);
692 Op->Tok.Length = Str.size();
693 std::memcpy(const_cast<char *>(Op->Tok.Data), Str.data(), Str.size());
694 Op->StartLoc = S;
695 Op->EndLoc = S;
696 Op->IsPPC64 = IsPPC64;
697 return Op;
698 }
699
700 static std::unique_ptr<PPCOperand> CreateImm(int64_t Val, SMLoc S, SMLoc E,
701 bool IsPPC64,
702 bool IsMemOpBase = false) {
703 auto Op = std::make_unique<PPCOperand>(Immediate);
704 Op->Imm.Val = Val;
705 Op->Imm.IsMemOpBase = IsMemOpBase;
706 Op->StartLoc = S;
707 Op->EndLoc = E;
708 Op->IsPPC64 = IsPPC64;
709 return Op;
710 }
711
712 static std::unique_ptr<PPCOperand> CreateExpr(const MCExpr *Val, SMLoc S,
713 SMLoc E, bool IsPPC64) {
714 auto Op = std::make_unique<PPCOperand>(Expression);
715 Op->Expr.Val = Val;
716 Op->Expr.CRVal = EvaluateCRExpr(Val);
717 Op->StartLoc = S;
718 Op->EndLoc = E;
719 Op->IsPPC64 = IsPPC64;
720 return Op;
721 }
722
723 static std::unique_ptr<PPCOperand>
724 CreateTLSReg(const MCSymbolRefExpr *Sym, SMLoc S, SMLoc E, bool IsPPC64) {
725 auto Op = std::make_unique<PPCOperand>(TLSRegister);
726 Op->TLSReg.Sym = Sym;
727 Op->StartLoc = S;
728 Op->EndLoc = E;
729 Op->IsPPC64 = IsPPC64;
730 return Op;
731 }
732
733 static std::unique_ptr<PPCOperand>
734 CreateContextImm(int64_t Val, SMLoc S, SMLoc E, bool IsPPC64) {
735 auto Op = std::make_unique<PPCOperand>(ContextImmediate);
736 Op->Imm.Val = Val;
737 Op->StartLoc = S;
738 Op->EndLoc = E;
739 Op->IsPPC64 = IsPPC64;
740 return Op;
741 }
742
743 static std::unique_ptr<PPCOperand>
744 CreateFromMCExpr(const MCExpr *Val, SMLoc S, SMLoc E, bool IsPPC64) {
745 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Val))
746 return CreateImm(CE->getValue(), S, E, IsPPC64);
747
748 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Val))
749 if (SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS ||
750 SRE->getKind() == MCSymbolRefExpr::VK_PPC_TLS_PCREL)
751 return CreateTLSReg(SRE, S, E, IsPPC64);
752
753 if (const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
754 int64_t Res;
755 if (TE->evaluateAsConstant(Res))
756 return CreateContextImm(Res, S, E, IsPPC64);
757 }
758
759 return CreateExpr(Val, S, E, IsPPC64);
760 }
761
762private:
763 template <unsigned Width>
764 bool isExtImm(bool Signed, unsigned Multiple) const {
765 switch (Kind) {
766 default:
767 return false;
768 case Expression:
769 return true;
770 case Immediate:
771 case ContextImmediate:
772 if (Signed)
773 return isInt<Width>(getImmS16Context()) &&
774 (getImmS16Context() & (Multiple - 1)) == 0;
775 else
776 return isUInt<Width>(getImmU16Context()) &&
777 (getImmU16Context() & (Multiple - 1)) == 0;
778 }
779 }
780};
781
782} // end anonymous namespace.
783
784void PPCOperand::print(raw_ostream &OS) const {
785 switch (Kind) {
786 case Token:
787 OS << "'" << getToken() << "'";
788 break;
789 case Immediate:
790 case ContextImmediate:
791 OS << getImm();
792 break;
793 case Expression:
794 OS << *getExpr();
795 break;
796 case TLSRegister:
797 OS << *getTLSReg();
798 break;
799 }
800}
801
802static void
804 if (Op.isImm()) {
805 Inst.addOperand(MCOperand::createImm(-Op.getImm()));
806 return;
807 }
808 const MCExpr *Expr = Op.getExpr();
809 if (const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
810 if (UnExpr->getOpcode() == MCUnaryExpr::Minus) {
811 Inst.addOperand(MCOperand::createExpr(UnExpr->getSubExpr()));
812 return;
813 }
814 } else if (const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
815 if (BinExpr->getOpcode() == MCBinaryExpr::Sub) {
816 const MCExpr *NE = MCBinaryExpr::createSub(BinExpr->getRHS(),
817 BinExpr->getLHS(), Ctx);
819 return;
820 }
821 }
823}
824
825void PPCAsmParser::processInstruction(MCInst &Inst,
826 const OperandVector &Operands) {
827 int Opcode = Inst.getOpcode();
828 switch (Opcode) {
829 case PPC::DCBTx:
830 case PPC::DCBTT:
831 case PPC::DCBTSTx:
832 case PPC::DCBTSTT: {
833 MCInst TmpInst;
834 TmpInst.setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
835 PPC::DCBT : PPC::DCBTST);
837 (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
838 TmpInst.addOperand(Inst.getOperand(0));
839 TmpInst.addOperand(Inst.getOperand(1));
840 Inst = TmpInst;
841 break;
842 }
843 case PPC::DCBTCT:
844 case PPC::DCBTDS: {
845 MCInst TmpInst;
846 TmpInst.setOpcode(PPC::DCBT);
847 TmpInst.addOperand(Inst.getOperand(2));
848 TmpInst.addOperand(Inst.getOperand(0));
849 TmpInst.addOperand(Inst.getOperand(1));
850 Inst = TmpInst;
851 break;
852 }
853 case PPC::DCBTSTCT:
854 case PPC::DCBTSTDS: {
855 MCInst TmpInst;
856 TmpInst.setOpcode(PPC::DCBTST);
857 TmpInst.addOperand(Inst.getOperand(2));
858 TmpInst.addOperand(Inst.getOperand(0));
859 TmpInst.addOperand(Inst.getOperand(1));
860 Inst = TmpInst;
861 break;
862 }
863 case PPC::DCBFx:
864 case PPC::DCBFL:
865 case PPC::DCBFLP:
866 case PPC::DCBFPS:
867 case PPC::DCBSTPS: {
868 int L = 0;
869 if (Opcode == PPC::DCBFL)
870 L = 1;
871 else if (Opcode == PPC::DCBFLP)
872 L = 3;
873 else if (Opcode == PPC::DCBFPS)
874 L = 4;
875 else if (Opcode == PPC::DCBSTPS)
876 L = 6;
877
878 MCInst TmpInst;
879 TmpInst.setOpcode(PPC::DCBF);
881 TmpInst.addOperand(Inst.getOperand(0));
882 TmpInst.addOperand(Inst.getOperand(1));
883 Inst = TmpInst;
884 break;
885 }
886 case PPC::LAx: {
887 MCInst TmpInst;
888 TmpInst.setOpcode(PPC::LA);
889 TmpInst.addOperand(Inst.getOperand(0));
890 TmpInst.addOperand(Inst.getOperand(2));
891 TmpInst.addOperand(Inst.getOperand(1));
892 Inst = TmpInst;
893 break;
894 }
895 case PPC::PLA8:
896 case PPC::PLA: {
897 MCInst TmpInst;
898 TmpInst.setOpcode(Opcode == PPC::PLA ? PPC::PADDI : PPC::PADDI8);
899 TmpInst.addOperand(Inst.getOperand(0));
900 TmpInst.addOperand(Inst.getOperand(1));
901 TmpInst.addOperand(Inst.getOperand(2));
902 Inst = TmpInst;
903 break;
904 }
905 case PPC::PLA8pc:
906 case PPC::PLApc: {
907 MCInst TmpInst;
908 TmpInst.setOpcode(Opcode == PPC::PLApc ? PPC::PADDIpc : PPC::PADDI8pc);
909 TmpInst.addOperand(Inst.getOperand(0));
911 TmpInst.addOperand(Inst.getOperand(1));
912 Inst = TmpInst;
913 break;
914 }
915 case PPC::SUBI: {
916 MCInst TmpInst;
917 TmpInst.setOpcode(PPC::ADDI);
918 TmpInst.addOperand(Inst.getOperand(0));
919 TmpInst.addOperand(Inst.getOperand(1));
920 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
921 Inst = TmpInst;
922 break;
923 }
924 case PPC::PSUBI: {
925 MCInst TmpInst;
926 TmpInst.setOpcode(PPC::PADDI);
927 TmpInst.addOperand(Inst.getOperand(0));
928 TmpInst.addOperand(Inst.getOperand(1));
929 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
930 Inst = TmpInst;
931 break;
932 }
933 case PPC::SUBIS: {
934 MCInst TmpInst;
935 TmpInst.setOpcode(PPC::ADDIS);
936 TmpInst.addOperand(Inst.getOperand(0));
937 TmpInst.addOperand(Inst.getOperand(1));
938 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
939 Inst = TmpInst;
940 break;
941 }
942 case PPC::SUBIC: {
943 MCInst TmpInst;
944 TmpInst.setOpcode(PPC::ADDIC);
945 TmpInst.addOperand(Inst.getOperand(0));
946 TmpInst.addOperand(Inst.getOperand(1));
947 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
948 Inst = TmpInst;
949 break;
950 }
951 case PPC::SUBIC_rec: {
952 MCInst TmpInst;
953 TmpInst.setOpcode(PPC::ADDIC_rec);
954 TmpInst.addOperand(Inst.getOperand(0));
955 TmpInst.addOperand(Inst.getOperand(1));
956 addNegOperand(TmpInst, Inst.getOperand(2), getContext());
957 Inst = TmpInst;
958 break;
959 }
960 case PPC::EXTLWI:
961 case PPC::EXTLWI_rec: {
962 MCInst TmpInst;
963 int64_t N = Inst.getOperand(2).getImm();
964 int64_t B = Inst.getOperand(3).getImm();
965 TmpInst.setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
966 TmpInst.addOperand(Inst.getOperand(0));
967 TmpInst.addOperand(Inst.getOperand(1));
970 TmpInst.addOperand(MCOperand::createImm(N - 1));
971 Inst = TmpInst;
972 break;
973 }
974 case PPC::EXTRWI:
975 case PPC::EXTRWI_rec: {
976 MCInst TmpInst;
977 int64_t N = Inst.getOperand(2).getImm();
978 int64_t B = Inst.getOperand(3).getImm();
979 TmpInst.setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
980 TmpInst.addOperand(Inst.getOperand(0));
981 TmpInst.addOperand(Inst.getOperand(1));
983 TmpInst.addOperand(MCOperand::createImm(32 - N));
984 TmpInst.addOperand(MCOperand::createImm(31));
985 Inst = TmpInst;
986 break;
987 }
988 case PPC::INSLWI:
989 case PPC::INSLWI_rec: {
990 MCInst TmpInst;
991 int64_t N = Inst.getOperand(2).getImm();
992 int64_t B = Inst.getOperand(3).getImm();
993 TmpInst.setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
994 TmpInst.addOperand(Inst.getOperand(0));
995 TmpInst.addOperand(Inst.getOperand(0));
996 TmpInst.addOperand(Inst.getOperand(1));
997 TmpInst.addOperand(MCOperand::createImm(32 - B));
999 TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
1000 Inst = TmpInst;
1001 break;
1002 }
1003 case PPC::INSRWI:
1004 case PPC::INSRWI_rec: {
1005 MCInst TmpInst;
1006 int64_t N = Inst.getOperand(2).getImm();
1007 int64_t B = Inst.getOperand(3).getImm();
1008 TmpInst.setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
1009 TmpInst.addOperand(Inst.getOperand(0));
1010 TmpInst.addOperand(Inst.getOperand(0));
1011 TmpInst.addOperand(Inst.getOperand(1));
1012 TmpInst.addOperand(MCOperand::createImm(32 - (B + N)));
1014 TmpInst.addOperand(MCOperand::createImm((B + N) - 1));
1015 Inst = TmpInst;
1016 break;
1017 }
1018 case PPC::ROTRWI:
1019 case PPC::ROTRWI_rec: {
1020 MCInst TmpInst;
1021 int64_t N = Inst.getOperand(2).getImm();
1022 TmpInst.setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1023 TmpInst.addOperand(Inst.getOperand(0));
1024 TmpInst.addOperand(Inst.getOperand(1));
1025 TmpInst.addOperand(MCOperand::createImm(32 - N));
1026 TmpInst.addOperand(MCOperand::createImm(0));
1027 TmpInst.addOperand(MCOperand::createImm(31));
1028 Inst = TmpInst;
1029 break;
1030 }
1031 case PPC::SLWI:
1032 case PPC::SLWI_rec: {
1033 MCInst TmpInst;
1034 int64_t N = Inst.getOperand(2).getImm();
1035 TmpInst.setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1036 TmpInst.addOperand(Inst.getOperand(0));
1037 TmpInst.addOperand(Inst.getOperand(1));
1039 TmpInst.addOperand(MCOperand::createImm(0));
1040 TmpInst.addOperand(MCOperand::createImm(31 - N));
1041 Inst = TmpInst;
1042 break;
1043 }
1044 case PPC::SRWI:
1045 case PPC::SRWI_rec: {
1046 MCInst TmpInst;
1047 int64_t N = Inst.getOperand(2).getImm();
1048 TmpInst.setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1049 TmpInst.addOperand(Inst.getOperand(0));
1050 TmpInst.addOperand(Inst.getOperand(1));
1051 TmpInst.addOperand(MCOperand::createImm(32 - N));
1053 TmpInst.addOperand(MCOperand::createImm(31));
1054 Inst = TmpInst;
1055 break;
1056 }
1057 case PPC::CLRRWI:
1058 case PPC::CLRRWI_rec: {
1059 MCInst TmpInst;
1060 int64_t N = Inst.getOperand(2).getImm();
1061 TmpInst.setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1062 TmpInst.addOperand(Inst.getOperand(0));
1063 TmpInst.addOperand(Inst.getOperand(1));
1064 TmpInst.addOperand(MCOperand::createImm(0));
1065 TmpInst.addOperand(MCOperand::createImm(0));
1066 TmpInst.addOperand(MCOperand::createImm(31 - N));
1067 Inst = TmpInst;
1068 break;
1069 }
1070 case PPC::CLRLSLWI:
1071 case PPC::CLRLSLWI_rec: {
1072 MCInst TmpInst;
1073 int64_t B = Inst.getOperand(2).getImm();
1074 int64_t N = Inst.getOperand(3).getImm();
1075 TmpInst.setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1076 TmpInst.addOperand(Inst.getOperand(0));
1077 TmpInst.addOperand(Inst.getOperand(1));
1079 TmpInst.addOperand(MCOperand::createImm(B - N));
1080 TmpInst.addOperand(MCOperand::createImm(31 - N));
1081 Inst = TmpInst;
1082 break;
1083 }
1084 case PPC::EXTLDI:
1085 case PPC::EXTLDI_rec: {
1086 MCInst TmpInst;
1087 int64_t N = Inst.getOperand(2).getImm();
1088 int64_t B = Inst.getOperand(3).getImm();
1089 TmpInst.setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1090 TmpInst.addOperand(Inst.getOperand(0));
1091 TmpInst.addOperand(Inst.getOperand(1));
1093 TmpInst.addOperand(MCOperand::createImm(N - 1));
1094 Inst = TmpInst;
1095 break;
1096 }
1097 case PPC::EXTRDI:
1098 case PPC::EXTRDI_rec: {
1099 MCInst TmpInst;
1100 int64_t N = Inst.getOperand(2).getImm();
1101 int64_t B = Inst.getOperand(3).getImm();
1102 TmpInst.setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1103 TmpInst.addOperand(Inst.getOperand(0));
1104 TmpInst.addOperand(Inst.getOperand(1));
1105 TmpInst.addOperand(MCOperand::createImm(B + N));
1106 TmpInst.addOperand(MCOperand::createImm(64 - N));
1107 Inst = TmpInst;
1108 break;
1109 }
1110 case PPC::INSRDI:
1111 case PPC::INSRDI_rec: {
1112 MCInst TmpInst;
1113 int64_t N = Inst.getOperand(2).getImm();
1114 int64_t B = Inst.getOperand(3).getImm();
1115 TmpInst.setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
1116 TmpInst.addOperand(Inst.getOperand(0));
1117 TmpInst.addOperand(Inst.getOperand(0));
1118 TmpInst.addOperand(Inst.getOperand(1));
1119 TmpInst.addOperand(MCOperand::createImm(64 - (B + N)));
1121 Inst = TmpInst;
1122 break;
1123 }
1124 case PPC::ROTRDI:
1125 case PPC::ROTRDI_rec: {
1126 MCInst TmpInst;
1127 int64_t N = Inst.getOperand(2).getImm();
1128 TmpInst.setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1129 TmpInst.addOperand(Inst.getOperand(0));
1130 TmpInst.addOperand(Inst.getOperand(1));
1131 TmpInst.addOperand(MCOperand::createImm(64 - N));
1132 TmpInst.addOperand(MCOperand::createImm(0));
1133 Inst = TmpInst;
1134 break;
1135 }
1136 case PPC::SLDI:
1137 case PPC::SLDI_rec: {
1138 MCInst TmpInst;
1139 int64_t N = Inst.getOperand(2).getImm();
1140 TmpInst.setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1141 TmpInst.addOperand(Inst.getOperand(0));
1142 TmpInst.addOperand(Inst.getOperand(1));
1144 TmpInst.addOperand(MCOperand::createImm(63 - N));
1145 Inst = TmpInst;
1146 break;
1147 }
1148 case PPC::SUBPCIS: {
1149 MCInst TmpInst;
1150 int64_t N = Inst.getOperand(1).getImm();
1151 TmpInst.setOpcode(PPC::ADDPCIS);
1152 TmpInst.addOperand(Inst.getOperand(0));
1154 Inst = TmpInst;
1155 break;
1156 }
1157 case PPC::SRDI:
1158 case PPC::SRDI_rec: {
1159 MCInst TmpInst;
1160 int64_t N = Inst.getOperand(2).getImm();
1161 TmpInst.setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1162 TmpInst.addOperand(Inst.getOperand(0));
1163 TmpInst.addOperand(Inst.getOperand(1));
1164 TmpInst.addOperand(MCOperand::createImm(64 - N));
1166 Inst = TmpInst;
1167 break;
1168 }
1169 case PPC::CLRRDI:
1170 case PPC::CLRRDI_rec: {
1171 MCInst TmpInst;
1172 int64_t N = Inst.getOperand(2).getImm();
1173 TmpInst.setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
1174 TmpInst.addOperand(Inst.getOperand(0));
1175 TmpInst.addOperand(Inst.getOperand(1));
1176 TmpInst.addOperand(MCOperand::createImm(0));
1177 TmpInst.addOperand(MCOperand::createImm(63 - N));
1178 Inst = TmpInst;
1179 break;
1180 }
1181 case PPC::CLRLSLDI:
1182 case PPC::CLRLSLDI_rec: {
1183 MCInst TmpInst;
1184 int64_t B = Inst.getOperand(2).getImm();
1185 int64_t N = Inst.getOperand(3).getImm();
1186 TmpInst.setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
1187 TmpInst.addOperand(Inst.getOperand(0));
1188 TmpInst.addOperand(Inst.getOperand(1));
1190 TmpInst.addOperand(MCOperand::createImm(B - N));
1191 Inst = TmpInst;
1192 break;
1193 }
1194 case PPC::RLWINMbm:
1195 case PPC::RLWINMbm_rec: {
1196 unsigned MB, ME;
1197 int64_t BM = Inst.getOperand(3).getImm();
1198 if (!isRunOfOnes(BM, MB, ME))
1199 break;
1200
1201 MCInst TmpInst;
1202 TmpInst.setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
1203 TmpInst.addOperand(Inst.getOperand(0));
1204 TmpInst.addOperand(Inst.getOperand(1));
1205 TmpInst.addOperand(Inst.getOperand(2));
1206 TmpInst.addOperand(MCOperand::createImm(MB));
1207 TmpInst.addOperand(MCOperand::createImm(ME));
1208 Inst = TmpInst;
1209 break;
1210 }
1211 case PPC::RLWIMIbm:
1212 case PPC::RLWIMIbm_rec: {
1213 unsigned MB, ME;
1214 int64_t BM = Inst.getOperand(3).getImm();
1215 if (!isRunOfOnes(BM, MB, ME))
1216 break;
1217
1218 MCInst TmpInst;
1219 TmpInst.setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
1220 TmpInst.addOperand(Inst.getOperand(0));
1221 TmpInst.addOperand(Inst.getOperand(0)); // The tied operand.
1222 TmpInst.addOperand(Inst.getOperand(1));
1223 TmpInst.addOperand(Inst.getOperand(2));
1224 TmpInst.addOperand(MCOperand::createImm(MB));
1225 TmpInst.addOperand(MCOperand::createImm(ME));
1226 Inst = TmpInst;
1227 break;
1228 }
1229 case PPC::RLWNMbm:
1230 case PPC::RLWNMbm_rec: {
1231 unsigned MB, ME;
1232 int64_t BM = Inst.getOperand(3).getImm();
1233 if (!isRunOfOnes(BM, MB, ME))
1234 break;
1235
1236 MCInst TmpInst;
1237 TmpInst.setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
1238 TmpInst.addOperand(Inst.getOperand(0));
1239 TmpInst.addOperand(Inst.getOperand(1));
1240 TmpInst.addOperand(Inst.getOperand(2));
1241 TmpInst.addOperand(MCOperand::createImm(MB));
1242 TmpInst.addOperand(MCOperand::createImm(ME));
1243 Inst = TmpInst;
1244 break;
1245 }
1246 case PPC::MFTB: {
1247 if (getSTI().hasFeature(PPC::FeatureMFTB)) {
1248 assert(Inst.getNumOperands() == 2 && "Expecting two operands");
1249 Inst.setOpcode(PPC::MFSPR);
1250 }
1251 break;
1252 }
1253 }
1254}
1255
1256static std::string PPCMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
1257 unsigned VariantID = 0);
1258
1259// Check that the register+immediate memory operand is in the right position and
1260// is expected by the instruction. Returns true if the memory operand syntax is
1261// valid; otherwise, returns false.
1262static bool validateMemOp(const OperandVector &Operands, bool isMemriOp) {
1263 for (size_t idx = 0; idx < Operands.size(); ++idx) {
1264 const PPCOperand &Op = static_cast<const PPCOperand &>(*Operands[idx]);
1265 if (Op.isMemOpBase() != (idx == 3 && isMemriOp))
1266 return false;
1267 }
1268 return true;
1269}
1270
1271bool PPCAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1274 bool MatchingInlineAsm) {
1275 MCInst Inst;
1276 const PPCInstrInfo *TII = static_cast<const PPCInstrInfo *>(&MII);
1277
1278 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
1279 case Match_Success:
1280 if (!validateMemOp(Operands, TII->isMemriOp(Inst.getOpcode())))
1281 return Error(IDLoc, "invalid operand for instruction");
1282 // Post-process instructions (typically extended mnemonics)
1283 processInstruction(Inst, Operands);
1284 Inst.setLoc(IDLoc);
1285 Out.emitInstruction(Inst, getSTI());
1286 return false;
1287 case Match_MissingFeature:
1288 return Error(IDLoc, "instruction use requires an option to be enabled");
1289 case Match_MnemonicFail: {
1290 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1291 std::string Suggestion = PPCMnemonicSpellCheck(
1292 ((PPCOperand &)*Operands[0]).getToken(), FBS);
1293 return Error(IDLoc, "invalid instruction" + Suggestion,
1294 ((PPCOperand &)*Operands[0]).getLocRange());
1295 }
1296 case Match_InvalidOperand: {
1297 SMLoc ErrorLoc = IDLoc;
1298 if (ErrorInfo != ~0ULL) {
1299 if (ErrorInfo >= Operands.size())
1300 return Error(IDLoc, "too few operands for instruction");
1301
1302 ErrorLoc = ((PPCOperand &)*Operands[ErrorInfo]).getStartLoc();
1303 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
1304 }
1305
1306 return Error(ErrorLoc, "invalid operand for instruction");
1307 }
1308 }
1309
1310 llvm_unreachable("Implement any new match types added!");
1311}
1312
1313#define GET_REGISTER_MATCHER
1314#include "PPCGenAsmMatcher.inc"
1315
1316MCRegister PPCAsmParser::matchRegisterName(int64_t &IntVal) {
1317 if (getParser().getTok().is(AsmToken::Percent))
1318 getParser().Lex(); // Eat the '%'.
1319
1320 if (!getParser().getTok().is(AsmToken::Identifier))
1321 return MCRegister();
1322
1323 StringRef Name = getParser().getTok().getString();
1325 if (!RegNo)
1326 return RegNo;
1327
1328 Name.substr(Name.find_first_of("1234567890")).getAsInteger(10, IntVal);
1329
1330 // MatchRegisterName doesn't seem to have special handling for 64bit vs 32bit
1331 // register types.
1332 if (Name.equals_insensitive("lr")) {
1333 RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
1334 IntVal = 8;
1335 } else if (Name.equals_insensitive("ctr")) {
1336 RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
1337 IntVal = 9;
1338 } else if (Name.equals_insensitive("vrsave"))
1339 IntVal = 256;
1340 else if (Name.starts_with_insensitive("r"))
1341 RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];
1342
1343 getParser().Lex();
1344 return RegNo;
1345}
1346
1347bool PPCAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
1348 SMLoc &EndLoc) {
1349 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
1350 return TokError("invalid register name");
1351 return false;
1352}
1353
1354ParseStatus PPCAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1355 SMLoc &EndLoc) {
1356 const AsmToken &Tok = getParser().getTok();
1357 StartLoc = Tok.getLoc();
1358 EndLoc = Tok.getEndLoc();
1359 int64_t IntVal;
1360 if (!(Reg = matchRegisterName(IntVal)))
1361 return ParseStatus::NoMatch;
1362 return ParseStatus::Success;
1363}
1364
1365/// Extract \code @l/@ha \endcode modifier from expression. Recursively scan
1366/// the expression and check for VK_PPC_LO/HI/HA
1367/// symbol variants. If all symbols with modifier use the same
1368/// variant, return the corresponding PPCMCExpr::VariantKind,
1369/// and a modified expression using the default symbol variant.
1370/// Otherwise, return NULL.
1371const MCExpr *
1372PPCAsmParser::extractModifierFromExpr(const MCExpr *E,
1373 PPCMCExpr::VariantKind &Variant) {
1374 MCContext &Context = getParser().getContext();
1376
1377 switch (E->getKind()) {
1378 case MCExpr::Target:
1379 case MCExpr::Constant:
1380 return nullptr;
1381
1382 case MCExpr::SymbolRef: {
1383 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1384
1385 switch (SRE->getKind()) {
1388 break;
1391 break;
1394 break;
1397 break;
1400 break;
1403 break;
1406 break;
1409 break;
1412 break;
1413 default:
1414 return nullptr;
1415 }
1416
1417 return MCSymbolRefExpr::create(&SRE->getSymbol(), Context);
1418 }
1419
1420 case MCExpr::Unary: {
1421 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1422 const MCExpr *Sub = extractModifierFromExpr(UE->getSubExpr(), Variant);
1423 if (!Sub)
1424 return nullptr;
1425 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
1426 }
1427
1428 case MCExpr::Binary: {
1429 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1430 PPCMCExpr::VariantKind LHSVariant, RHSVariant;
1431 const MCExpr *LHS = extractModifierFromExpr(BE->getLHS(), LHSVariant);
1432 const MCExpr *RHS = extractModifierFromExpr(BE->getRHS(), RHSVariant);
1433
1434 if (!LHS && !RHS)
1435 return nullptr;
1436
1437 if (!LHS) LHS = BE->getLHS();
1438 if (!RHS) RHS = BE->getRHS();
1439
1440 if (LHSVariant == PPCMCExpr::VK_PPC_None)
1441 Variant = RHSVariant;
1442 else if (RHSVariant == PPCMCExpr::VK_PPC_None)
1443 Variant = LHSVariant;
1444 else if (LHSVariant == RHSVariant)
1445 Variant = LHSVariant;
1446 else
1447 return nullptr;
1448
1449 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
1450 }
1451 }
1452
1453 llvm_unreachable("Invalid expression kind!");
1454}
1455
1456/// Find all VK_TLSGD/VK_TLSLD symbol references in expression and replace
1457/// them by VK_PPC_TLSGD/VK_PPC_TLSLD. This is necessary to avoid having
1458/// _GLOBAL_OFFSET_TABLE_ created via ELFObjectWriter::RelocNeedsGOT.
1459/// FIXME: This is a hack.
1460const MCExpr *PPCAsmParser::fixupVariantKind(const MCExpr *E) {
1461 MCContext &Context = getParser().getContext();
1462
1463 switch (E->getKind()) {
1464 case MCExpr::Target:
1465 case MCExpr::Constant:
1466 return E;
1467
1468 case MCExpr::SymbolRef: {
1469 const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(E);
1471
1472 switch (SRE->getKind()) {
1475 break;
1478 break;
1479 default:
1480 return E;
1481 }
1482 return MCSymbolRefExpr::create(&SRE->getSymbol(), Variant, Context);
1483 }
1484
1485 case MCExpr::Unary: {
1486 const MCUnaryExpr *UE = cast<MCUnaryExpr>(E);
1487 const MCExpr *Sub = fixupVariantKind(UE->getSubExpr());
1488 if (Sub == UE->getSubExpr())
1489 return E;
1490 return MCUnaryExpr::create(UE->getOpcode(), Sub, Context);
1491 }
1492
1493 case MCExpr::Binary: {
1494 const MCBinaryExpr *BE = cast<MCBinaryExpr>(E);
1495 const MCExpr *LHS = fixupVariantKind(BE->getLHS());
1496 const MCExpr *RHS = fixupVariantKind(BE->getRHS());
1497 if (LHS == BE->getLHS() && RHS == BE->getRHS())
1498 return E;
1499 return MCBinaryExpr::create(BE->getOpcode(), LHS, RHS, Context);
1500 }
1501 }
1502
1503 llvm_unreachable("Invalid expression kind!");
1504}
1505
1506/// This differs from the default "parseExpression" in that it handles
1507/// modifiers.
1508bool PPCAsmParser::parseExpression(const MCExpr *&EVal) {
1509 // (ELF Platforms)
1510 // Handle \code @l/@ha \endcode
1511 if (getParser().parseExpression(EVal))
1512 return true;
1513
1514 EVal = fixupVariantKind(EVal);
1515
1517 const MCExpr *E = extractModifierFromExpr(EVal, Variant);
1518 if (E)
1519 EVal = PPCMCExpr::create(Variant, E, getParser().getContext());
1520
1521 return false;
1522}
1523
1524/// This handles registers in the form 'NN', '%rNN' for ELF platforms and
1525/// rNN for MachO.
1526bool PPCAsmParser::parseOperand(OperandVector &Operands) {
1527 MCAsmParser &Parser = getParser();
1528 SMLoc S = Parser.getTok().getLoc();
1530 const MCExpr *EVal;
1531
1532 // Attempt to parse the next token as an immediate
1533 switch (getLexer().getKind()) {
1534 // Special handling for register names. These are interpreted
1535 // as immediates corresponding to the register number.
1536 case AsmToken::Percent: {
1537 int64_t IntVal;
1538 if (!matchRegisterName(IntVal))
1539 return Error(S, "invalid register name");
1540
1541 Operands.push_back(PPCOperand::CreateImm(IntVal, S, E, isPPC64()));
1542 return false;
1543 }
1545 case AsmToken::LParen:
1546 case AsmToken::Plus:
1547 case AsmToken::Minus:
1548 case AsmToken::Integer:
1549 case AsmToken::Dot:
1550 case AsmToken::Dollar:
1551 case AsmToken::Exclaim:
1552 case AsmToken::Tilde:
1553 if (!parseExpression(EVal))
1554 break;
1555 // Fall-through
1556 [[fallthrough]];
1557 default:
1558 return Error(S, "unknown operand");
1559 }
1560
1561 // Push the parsed operand into the list of operands
1562 Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S, E, isPPC64()));
1563
1564 // Check whether this is a TLS call expression
1565 const char TlsGetAddr[] = "__tls_get_addr";
1566 bool TlsCall = false;
1567 const MCExpr *TlsCallAddend = nullptr;
1568 if (auto *Ref = dyn_cast<MCSymbolRefExpr>(EVal)) {
1569 TlsCall = Ref->getSymbol().getName() == TlsGetAddr;
1570 } else if (auto *Bin = dyn_cast<MCBinaryExpr>(EVal);
1571 Bin && Bin->getOpcode() == MCBinaryExpr::Add) {
1572 if (auto *Ref = dyn_cast<MCSymbolRefExpr>(Bin->getLHS())) {
1573 TlsCall = Ref->getSymbol().getName() == TlsGetAddr;
1574 TlsCallAddend = Bin->getRHS();
1575 }
1576 }
1577
1578 if (TlsCall && parseOptionalToken(AsmToken::LParen)) {
1579 const MCExpr *TLSSym;
1580 const SMLoc S2 = Parser.getTok().getLoc();
1581 if (parseExpression(TLSSym))
1582 return Error(S2, "invalid TLS call expression");
1583 E = Parser.getTok().getLoc();
1584 if (parseToken(AsmToken::RParen, "expected ')'"))
1585 return true;
1586 // PPC32 allows bl __tls_get_addr[+a](x@tlsgd)@plt+b. Parse "@plt[+b]".
1587 if (!isPPC64() && parseOptionalToken(AsmToken::At)) {
1588 AsmToken Tok = getTok();
1589 if (!(parseOptionalToken(AsmToken::Identifier) &&
1590 Tok.getString().compare_insensitive("plt") == 0))
1591 return Error(Tok.getLoc(), "expected 'plt'");
1593 getContext());
1594 if (parseOptionalToken(AsmToken::Plus)) {
1595 const MCExpr *Addend = nullptr;
1596 SMLoc EndLoc;
1597 if (parsePrimaryExpr(Addend, EndLoc))
1598 return true;
1599 if (TlsCallAddend) // __tls_get_addr+a(x@tlsgd)@plt+b
1600 TlsCallAddend =
1601 MCBinaryExpr::createAdd(TlsCallAddend, Addend, getContext());
1602 else // __tls_get_addr(x@tlsgd)@plt+b
1603 TlsCallAddend = Addend;
1604 }
1605 if (TlsCallAddend)
1606 EVal = MCBinaryExpr::createAdd(EVal, TlsCallAddend, getContext());
1607 // Add a __tls_get_addr operand with addend a, b, or a+b.
1608 Operands.back() = PPCOperand::CreateFromMCExpr(
1609 EVal, S, Parser.getTok().getLoc(), false);
1610 }
1611
1612 Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S, E, isPPC64()));
1613 }
1614
1615 // Otherwise, check for D-form memory operands
1616 if (!TlsCall && parseOptionalToken(AsmToken::LParen)) {
1617 S = Parser.getTok().getLoc();
1618
1619 int64_t IntVal;
1620 switch (getLexer().getKind()) {
1621 case AsmToken::Percent: {
1622 if (!matchRegisterName(IntVal))
1623 return Error(S, "invalid register name");
1624 break;
1625 }
1626 case AsmToken::Integer:
1627 if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
1628 IntVal > 31)
1629 return Error(S, "invalid register number");
1630 break;
1632 default:
1633 return Error(S, "invalid memory operand");
1634 }
1635
1636 E = Parser.getTok().getLoc();
1637 if (parseToken(AsmToken::RParen, "missing ')'"))
1638 return true;
1639 Operands.push_back(
1640 PPCOperand::CreateImm(IntVal, S, E, isPPC64(), /*IsMemOpBase=*/true));
1641 }
1642
1643 return false;
1644}
1645
1646/// Parse an instruction mnemonic followed by its operands.
1647bool PPCAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1648 SMLoc NameLoc, OperandVector &Operands) {
1649 // The first operand is the token for the instruction name.
1650 // If the next character is a '+' or '-', we need to add it to the
1651 // instruction name, to match what TableGen is doing.
1652 std::string NewOpcode;
1653 if (parseOptionalToken(AsmToken::Plus)) {
1654 NewOpcode = std::string(Name);
1655 NewOpcode += '+';
1656 Name = NewOpcode;
1657 }
1658 if (parseOptionalToken(AsmToken::Minus)) {
1659 NewOpcode = std::string(Name);
1660 NewOpcode += '-';
1661 Name = NewOpcode;
1662 }
1663 // If the instruction ends in a '.', we need to create a separate
1664 // token for it, to match what TableGen is doing.
1665 size_t Dot = Name.find('.');
1666 StringRef Mnemonic = Name.slice(0, Dot);
1667 if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
1668 Operands.push_back(
1669 PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
1670 else
1671 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
1672 if (Dot != StringRef::npos) {
1673 SMLoc DotLoc = SMLoc::getFromPointer(NameLoc.getPointer() + Dot);
1674 StringRef DotStr = Name.substr(Dot);
1675 if (!NewOpcode.empty()) // Underlying memory for Name is volatile.
1676 Operands.push_back(
1677 PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
1678 else
1679 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
1680 }
1681
1682 // If there are no more operands then finish
1683 if (parseOptionalToken(AsmToken::EndOfStatement))
1684 return false;
1685
1686 // Parse the first operand
1687 if (parseOperand(Operands))
1688 return true;
1689
1690 while (!parseOptionalToken(AsmToken::EndOfStatement)) {
1691 if (parseToken(AsmToken::Comma) || parseOperand(Operands))
1692 return true;
1693 }
1694
1695 // We'll now deal with an unfortunate special case: the syntax for the dcbt
1696 // and dcbtst instructions differs for server vs. embedded cores.
1697 // The syntax for dcbt is:
1698 // dcbt ra, rb, th [server]
1699 // dcbt th, ra, rb [embedded]
1700 // where th can be omitted when it is 0. dcbtst is the same. We take the
1701 // server form to be the default, so swap the operands if we're parsing for
1702 // an embedded core (they'll be swapped again upon printing).
1703 if (getSTI().hasFeature(PPC::FeatureBookE) &&
1704 Operands.size() == 4 &&
1705 (Name == "dcbt" || Name == "dcbtst")) {
1706 std::swap(Operands[1], Operands[3]);
1707 std::swap(Operands[2], Operands[1]);
1708 }
1709
1710 // Handle base mnemonic for atomic loads where the EH bit is zero.
1711 if (Name == "lqarx" || Name == "ldarx" || Name == "lwarx" ||
1712 Name == "lharx" || Name == "lbarx") {
1713 if (Operands.size() != 5)
1714 return false;
1715 PPCOperand &EHOp = (PPCOperand &)*Operands[4];
1716 if (EHOp.isU1Imm() && EHOp.getImm() == 0)
1717 Operands.pop_back();
1718 }
1719
1720 return false;
1721}
1722
1723/// Parses the PPC specific directives
1724bool PPCAsmParser::ParseDirective(AsmToken DirectiveID) {
1725 StringRef IDVal = DirectiveID.getIdentifier();
1726 if (IDVal == ".word")
1727 parseDirectiveWord(2, DirectiveID);
1728 else if (IDVal == ".llong")
1729 parseDirectiveWord(8, DirectiveID);
1730 else if (IDVal == ".tc")
1731 parseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);
1732 else if (IDVal == ".machine")
1733 parseDirectiveMachine(DirectiveID.getLoc());
1734 else if (IDVal == ".abiversion")
1735 parseDirectiveAbiVersion(DirectiveID.getLoc());
1736 else if (IDVal == ".localentry")
1737 parseDirectiveLocalEntry(DirectiveID.getLoc());
1738 else if (IDVal.starts_with(".gnu_attribute"))
1739 parseGNUAttribute(DirectiveID.getLoc());
1740 else
1741 return true;
1742 return false;
1743}
1744
1745/// ::= .word [ expression (, expression)* ]
1746bool PPCAsmParser::parseDirectiveWord(unsigned Size, AsmToken ID) {
1747 auto parseOp = [&]() -> bool {
1748 const MCExpr *Value;
1749 SMLoc ExprLoc = getParser().getTok().getLoc();
1750 if (getParser().parseExpression(Value))
1751 return true;
1752 if (const auto *MCE = dyn_cast<MCConstantExpr>(Value)) {
1753 assert(Size <= 8 && "Invalid size");
1754 uint64_t IntValue = MCE->getValue();
1755 if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
1756 return Error(ExprLoc, "literal value out of range for '" +
1757 ID.getIdentifier() + "' directive");
1758 getStreamer().emitIntValue(IntValue, Size);
1759 } else
1760 getStreamer().emitValue(Value, Size, ExprLoc);
1761 return false;
1762 };
1763
1764 if (parseMany(parseOp))
1765 return addErrorSuffix(" in '" + ID.getIdentifier() + "' directive");
1766 return false;
1767}
1768
1769/// ::= .tc [ symbol (, expression)* ]
1770bool PPCAsmParser::parseDirectiveTC(unsigned Size, AsmToken ID) {
1771 MCAsmParser &Parser = getParser();
1772 // Skip TC symbol, which is only used with XCOFF.
1773 while (getLexer().isNot(AsmToken::EndOfStatement)
1774 && getLexer().isNot(AsmToken::Comma))
1775 Parser.Lex();
1776 if (parseToken(AsmToken::Comma))
1777 return addErrorSuffix(" in '.tc' directive");
1778
1779 // Align to word size.
1780 getParser().getStreamer().emitValueToAlignment(Align(Size));
1781
1782 // Emit expressions.
1783 return parseDirectiveWord(Size, ID);
1784}
1785
1786/// ELF platforms.
1787/// ::= .machine [ cpu | "push" | "pop" ]
1788bool PPCAsmParser::parseDirectiveMachine(SMLoc L) {
1789 MCAsmParser &Parser = getParser();
1790 if (Parser.getTok().isNot(AsmToken::Identifier) &&
1791 Parser.getTok().isNot(AsmToken::String))
1792 return Error(L, "unexpected token in '.machine' directive");
1793
1794 StringRef CPU = Parser.getTok().getIdentifier();
1795
1796 // FIXME: Right now, the parser always allows any available
1797 // instruction, so the .machine directive is not useful.
1798 // In the wild, any/push/pop/ppc64/altivec/power[4-9] are seen.
1799
1800 Parser.Lex();
1801
1802 if (parseToken(AsmToken::EndOfStatement))
1803 return addErrorSuffix(" in '.machine' directive");
1804
1805 PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
1806 getParser().getStreamer().getTargetStreamer());
1807 if (TStreamer != nullptr)
1808 TStreamer->emitMachine(CPU);
1809
1810 return false;
1811}
1812
1813/// ::= .abiversion constant-expression
1814bool PPCAsmParser::parseDirectiveAbiVersion(SMLoc L) {
1815 int64_t AbiVersion;
1816 if (check(getParser().parseAbsoluteExpression(AbiVersion), L,
1817 "expected constant expression") ||
1818 parseToken(AsmToken::EndOfStatement))
1819 return addErrorSuffix(" in '.abiversion' directive");
1820
1821 PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
1822 getParser().getStreamer().getTargetStreamer());
1823 if (TStreamer != nullptr)
1824 TStreamer->emitAbiVersion(AbiVersion);
1825
1826 return false;
1827}
1828
1829/// ::= .localentry symbol, expression
1830bool PPCAsmParser::parseDirectiveLocalEntry(SMLoc L) {
1832 if (getParser().parseIdentifier(Name))
1833 return Error(L, "expected identifier in '.localentry' directive");
1834
1835 MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
1836 const MCExpr *Expr;
1837
1838 if (parseToken(AsmToken::Comma) ||
1839 check(getParser().parseExpression(Expr), L, "expected expression") ||
1840 parseToken(AsmToken::EndOfStatement))
1841 return addErrorSuffix(" in '.localentry' directive");
1842
1843 PPCTargetStreamer *TStreamer = static_cast<PPCTargetStreamer *>(
1844 getParser().getStreamer().getTargetStreamer());
1845 if (TStreamer != nullptr)
1846 TStreamer->emitLocalEntry(Sym, Expr);
1847
1848 return false;
1849}
1850
1851bool PPCAsmParser::parseGNUAttribute(SMLoc L) {
1852 int64_t Tag;
1853 int64_t IntegerValue;
1854 if (!getParser().parseGNUAttribute(L, Tag, IntegerValue))
1855 return false;
1856
1857 getParser().getStreamer().emitGNUAttribute(Tag, IntegerValue);
1858
1859 return true;
1860}
1861
1862/// Force static initialization.
1868}
1869
1870#define GET_MATCHER_IMPLEMENTATION
1871#define GET_MNEMONIC_SPELL_CHECKER
1872#include "PPCGenAsmMatcher.inc"
1873
1874// Define this matcher function after the auto-generated include so we
1875// have the match class enum definitions.
1876unsigned PPCAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1877 unsigned Kind) {
1878 // If the kind is a token for a literal immediate, check if our asm
1879 // operand matches. This is for InstAliases which have a fixed-value
1880 // immediate in the syntax.
1881 int64_t ImmVal;
1882 switch (Kind) {
1883 case MCK_0: ImmVal = 0; break;
1884 case MCK_1: ImmVal = 1; break;
1885 case MCK_2: ImmVal = 2; break;
1886 case MCK_3: ImmVal = 3; break;
1887 case MCK_4: ImmVal = 4; break;
1888 case MCK_5: ImmVal = 5; break;
1889 case MCK_6: ImmVal = 6; break;
1890 case MCK_7: ImmVal = 7; break;
1891 default: return Match_InvalidOperand;
1892 }
1893
1894 PPCOperand &Op = static_cast<PPCOperand &>(AsmOp);
1895 if (Op.isU3Imm() && Op.getImm() == ImmVal)
1896 return Match_Success;
1897
1898 return Match_InvalidOperand;
1899}
1900
1901const MCExpr *
1902PPCAsmParser::applyModifierToExpr(const MCExpr *E,
1904 MCContext &Ctx) {
1905 switch (Variant) {
1924 default:
1925 return nullptr;
1926 }
1927}
static MCRegister MatchRegisterName(StringRef Name)
static bool getRegNum(StringRef Str, unsigned &Num)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:128
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
const HexagonInstrInfo * TII
static LVOptions Options
Definition: LVOptions.cpp:25
mir Rename Register Operands
unsigned 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)
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)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmParser()
Force static initialization.
#define DEFINE_PPC_REGCLASSES
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
raw_pwrite_stream & OS
Value * RHS
Value * LHS
Target independent representation for an assembler token.
Definition: MCAsmMacro.h:21
SMLoc getLoc() const
Definition: MCAsmLexer.cpp:26
bool isNot(TokenKind K) const
Definition: MCAsmMacro.h:83
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition: MCAsmMacro.h:110
SMLoc getEndLoc() const
Definition: MCAsmLexer.cpp:30
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Definition: MCAsmMacro.h:99
This class represents an Operation in the Expression.
Base class for user error types.
Definition: Error.h:355
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Class representing an expression and its matching format.
Container class for subtarget features.
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:123
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Definition: MCAsmParser.cpp:40
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)=0
Emit a warning at the location L, with the message Msg.
Binary assembler expressions.
Definition: MCExpr.h:493
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
Definition: MCExpr.h:640
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:643
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:537
Opcode getOpcode() const
Get the kind of this binary expression.
Definition: MCExpr.h:637
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.cpp:211
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:622
@ Sub
Subtraction.
Definition: MCExpr.h:518
@ Mul
Multiplication.
Definition: MCExpr.h:511
@ Add
Addition.
Definition: MCExpr.h:496
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:40
@ Constant
Constant expressions.
Definition: MCExpr.h:38
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:39
@ Target
Target specific expression.
Definition: MCExpr.h:41
@ Binary
Binary expressions.
Definition: MCExpr.h:37
ExprKind getKind() const
Definition: MCExpr.h:78
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
unsigned getNumOperands() const
Definition: MCInst.h:209
void setLoc(SMLoc loc)
Definition: MCInst.h:204
unsigned getOpcode() const
Definition: MCInst.h:199
void addOperand(const MCOperand Op)
Definition: MCInst.h:211
void setOpcode(unsigned Op)
Definition: MCInst.h:198
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:207
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:37
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:163
int64_t getImm() const
Definition: MCInst.h:81
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:135
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:142
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
Streaming machine code generation interface.
Definition: MCStreamer.h:213
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:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:411
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:398
VariantKind getKind() const
Definition: MCExpr.h:413
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
void setAvailableFeatures(const FeatureBitset &Value)
virtual const MCExpr * applyModifierToExpr(const MCExpr *E, MCSymbolRefExpr::VariantKind, MCContext &Ctx)
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
Unary assembler expressions.
Definition: MCExpr.h:437
Opcode getOpcode() const
Get the kind of this unary expression.
Definition: MCExpr.h:480
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.cpp:217
@ Minus
Unary minus.
Definition: MCExpr.h:441
const MCExpr * getSubExpr() const
Get the child of this unary expression.
Definition: MCExpr.h:483
static const MCUnaryExpr * createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.h:463
static const PPCMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
Definition: PPCMCExpr.cpp:20
virtual void emitAbiVersion(int AbiVersion)
virtual void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset)
virtual void emitMachine(StringRef CPU)
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
Definition: SMLoc.h:23
static SMLoc getFromPointer(const char *Ptr)
Definition: SMLoc.h:36
constexpr const char * getPointer() const
Definition: SMLoc.h:34
Represents a range in source code.
Definition: SMLoc.h:48
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:265
static constexpr size_t npos
Definition: StringRef.h:53
int compare_insensitive(StringRef RHS) const
Compare two strings, ignoring case.
Definition: StringRef.cpp:37
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
MCExpr const & getExpr(MCExpr const &Expr)
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
Definition: DwarfDebug.h:190
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Length
Definition: DWP.cpp:480
Target & getThePPC64LETarget()
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:255
static bool isMem(const MachineInstr &MI, unsigned Op)
Definition: X86InstrInfo.h:170
Target & getThePPC32Target()
@ Ref
The access may reference the value stored in memory.
Target & getThePPC64Target()
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:260
DWARFExpression::Operation Op
Target & getThePPC32LETarget()
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:860
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...