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