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