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