39 switch (
E->getKind()) {
44 int64_t Res = cast<MCConstantExpr>(
E)->getValue();
45 return Res < 0 ? -1 : Res;
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;
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;
79 if (LHSVal < 0 || RHSVal < 0)
88 return Res < 0 ? -1 : Res;
104 bool isPPC64()
const {
return IsPPC64; }
110 SMLoc &EndLoc)
override;
115 bool ParseExpression(
const MCExpr *&EVal);
121 bool ParseDirectiveMachine(
SMLoc L);
122 bool ParseDirectiveAbiVersion(
SMLoc L);
123 bool ParseDirectiveLocalEntry(
SMLoc L);
124 bool ParseGNUAttribute(
SMLoc L);
129 bool MatchingInlineAsm)
override;
136#define GET_ASSEMBLER_HEADER
137#include "PPCGenAsmMatcher.inc"
159 unsigned Kind)
override;
177 SMLoc StartLoc, EndLoc;
202 struct TLSRegOp TLSReg;
205 PPCOperand(KindTy K) :
Kind(
K) {}
210 StartLoc =
o.StartLoc;
218 case ContextImmediate:
232 void operator delete(
void *
p) { ::operator
delete(
p); }
235 SMLoc getStartLoc()
const override {
return StartLoc; }
238 SMLoc getEndLoc()
const override {
return EndLoc; }
245 bool isPPC64()
const {
return IsPPC64; }
247 int64_t getImm()
const {
248 assert(Kind == Immediate &&
"Invalid access!");
251 int64_t getImmS16Context()
const {
252 assert((Kind == Immediate || Kind == ContextImmediate) &&
254 if (Kind == Immediate)
256 return static_cast<int16_t
>(
Imm.Val);
258 int64_t getImmU16Context()
const {
259 assert((Kind == Immediate || Kind == ContextImmediate) &&
269 int64_t getExprCRVal()
const {
274 const MCExpr *getTLSReg()
const {
275 assert(Kind == TLSRegister &&
"Invalid access!");
279 unsigned getReg()
const override {
280 assert(isRegNumber() &&
"Invalid access!");
281 return (
unsigned)
Imm.Val;
284 unsigned getFpReg()
const {
285 assert(isEvenRegNumber() &&
"Invalid access!");
286 return (
unsigned)(
Imm.Val >> 1);
289 unsigned getVSReg()
const {
290 assert(isVSRegNumber() &&
"Invalid access!");
291 return (
unsigned)
Imm.Val;
294 unsigned getACCReg()
const {
295 assert(isACCRegNumber() &&
"Invalid access!");
296 return (
unsigned)
Imm.Val;
299 unsigned getDMRROWReg()
const {
300 assert(isDMRROWRegNumber() &&
"Invalid access!");
301 return (
unsigned)
Imm.Val;
304 unsigned getDMRROWpReg()
const {
305 assert(isDMRROWpRegNumber() &&
"Invalid access!");
306 return (
unsigned)
Imm.Val;
309 unsigned getDMRReg()
const {
310 assert(isDMRRegNumber() &&
"Invalid access!");
311 return (
unsigned)
Imm.Val;
314 unsigned getDMRpReg()
const {
315 assert(isDMRpRegNumber() &&
"Invalid access!");
316 return (
unsigned)
Imm.Val;
319 unsigned getVSRpEvenReg()
const {
320 assert(isVSRpEvenRegNumber() &&
"Invalid access!");
321 return (
unsigned)
Imm.Val >> 1;
324 unsigned getG8pReg()
const {
325 assert(isEvenRegNumber() &&
"Invalid access!");
326 return (
unsigned)
Imm.Val;
329 unsigned getCCReg()
const {
330 assert(isCCRegNumber() &&
"Invalid access!");
331 return (
unsigned) (
Kind == Immediate ?
Imm.Val : Expr.CRVal);
334 unsigned getCRBit()
const {
335 assert(isCRBitNumber() &&
"Invalid access!");
336 return (
unsigned) (
Kind == Immediate ?
Imm.Val : Expr.CRVal);
339 unsigned getCRBitMask()
const {
340 assert(isCRBitMask() &&
"Invalid access!");
341 return 7 - llvm::countr_zero<uint64_t>(
Imm.Val);
344 bool isToken()
const override {
return Kind == Token; }
345 bool isImm()
const override {
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; }
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>(
false, 1); }
370 bool isS16Imm()
const {
return isExtImm<16>(
true, 1); }
371 bool isS16ImmX4()
const {
return isExtImm<16>(
true, 4); }
372 bool isS16ImmX16()
const {
return isExtImm<16>(
true, 16); }
373 bool isS17Imm()
const {
return isExtImm<17>(
true, 1); }
375 bool isHashImmX8()
const {
379 return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&
380 (getImm() & 7) == 0);
383 bool isS34ImmX16()
const {
385 (
Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
387 bool isS34Imm()
const {
393 bool isTLSReg()
const {
return Kind == TLSRegister; }
394 bool isDirectBr()
const {
397 if (Kind != Immediate)
400 if ((getImm() & 3) != 0)
402 if (isInt<26>(getImm()))
406 if (isUInt<32>(getImm()) && isInt<26>(
static_cast<int32_t
>(getImm())))
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());
419 bool isDMRROWRegNumber()
const {
420 return Kind == Immediate && isUInt<6>(getImm());
422 bool isDMRROWpRegNumber()
const {
423 return Kind == Immediate && isUInt<5>(getImm());
425 bool isDMRRegNumber()
const {
426 return Kind == Immediate && isUInt<3>(getImm());
428 bool isDMRpRegNumber()
const {
429 return Kind == Immediate && isUInt<2>(getImm());
431 bool isVSRpEvenRegNumber()
const {
432 return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
434 bool isVSRegNumber()
const {
435 return Kind == Immediate && isUInt<6>(getImm());
437 bool isCCRegNumber()
const {
return (Kind ==
Expression
438 && isUInt<3>(getExprCRVal())) ||
440 && isUInt<3>(getImm())); }
441 bool isCRBitNumber()
const {
return (Kind ==
Expression
442 && isUInt<5>(getExprCRVal())) ||
444 && isUInt<5>(getImm())); }
446 bool isEvenRegNumber()
const {
return isRegNumber() && (getImm() & 1) == 0; }
448 bool isCRBitMask()
const {
449 return Kind == Immediate && isUInt<8>(getImm()) &&
450 llvm::has_single_bit<uint32_t>(getImm());
452 bool isATBitsAsHint()
const {
return false; }
453 bool isMem()
const override {
return false; }
454 bool isReg()
const override {
return false; }
456 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
460 void addRegGPRCOperands(
MCInst &Inst,
unsigned N)
const {
461 assert(
N == 1 &&
"Invalid number of operands!");
465 void addRegGPRCNoR0Operands(
MCInst &Inst,
unsigned N)
const {
466 assert(
N == 1 &&
"Invalid number of operands!");
470 void addRegG8RCOperands(
MCInst &Inst,
unsigned N)
const {
471 assert(
N == 1 &&
"Invalid number of operands!");
475 void addRegG8RCNoX0Operands(
MCInst &Inst,
unsigned N)
const {
476 assert(
N == 1 &&
"Invalid number of operands!");
480 void addRegG8pRCOperands(
MCInst &Inst,
unsigned N)
const {
481 assert(
N == 1 &&
"Invalid number of operands!");
485 void addRegGxRCOperands(
MCInst &Inst,
unsigned N)
const {
487 addRegG8RCOperands(Inst,
N);
489 addRegGPRCOperands(Inst,
N);
492 void addRegGxRCNoR0Operands(
MCInst &Inst,
unsigned N)
const {
494 addRegG8RCNoX0Operands(Inst,
N);
496 addRegGPRCNoR0Operands(Inst,
N);
499 void addRegF4RCOperands(
MCInst &Inst,
unsigned N)
const {
500 assert(
N == 1 &&
"Invalid number of operands!");
504 void addRegF8RCOperands(
MCInst &Inst,
unsigned N)
const {
505 assert(
N == 1 &&
"Invalid number of operands!");
509 void addRegFpRCOperands(
MCInst &Inst,
unsigned N)
const {
510 assert(
N == 1 &&
"Invalid number of operands!");
514 void addRegVFRCOperands(
MCInst &Inst,
unsigned N)
const {
515 assert(
N == 1 &&
"Invalid number of operands!");
519 void addRegVRRCOperands(
MCInst &Inst,
unsigned N)
const {
520 assert(
N == 1 &&
"Invalid number of operands!");
524 void addRegVSRCOperands(
MCInst &Inst,
unsigned N)
const {
525 assert(
N == 1 &&
"Invalid number of operands!");
529 void addRegVSFRCOperands(
MCInst &Inst,
unsigned N)
const {
530 assert(
N == 1 &&
"Invalid number of operands!");
534 void addRegVSSRCOperands(
MCInst &Inst,
unsigned N)
const {
535 assert(
N == 1 &&
"Invalid number of operands!");
539 void addRegSPE4RCOperands(
MCInst &Inst,
unsigned N)
const {
540 assert(
N == 1 &&
"Invalid number of operands!");
544 void addRegSPERCOperands(
MCInst &Inst,
unsigned N)
const {
545 assert(
N == 1 &&
"Invalid number of operands!");
549 void addRegACCRCOperands(
MCInst &Inst,
unsigned N)
const {
550 assert(
N == 1 &&
"Invalid number of operands!");
554 void addRegDMRROWRCOperands(
MCInst &Inst,
unsigned N)
const {
555 assert(
N == 1 &&
"Invalid number of operands!");
559 void addRegDMRROWpRCOperands(
MCInst &Inst,
unsigned N)
const {
560 assert(
N == 1 &&
"Invalid number of operands!");
564 void addRegDMRRCOperands(
MCInst &Inst,
unsigned N)
const {
565 assert(
N == 1 &&
"Invalid number of operands!");
569 void addRegDMRpRCOperands(
MCInst &Inst,
unsigned N)
const {
570 assert(
N == 1 &&
"Invalid number of operands!");
574 void addRegWACCRCOperands(
MCInst &Inst,
unsigned N)
const {
575 assert(
N == 1 &&
"Invalid number of operands!");
579 void addRegWACC_HIRCOperands(
MCInst &Inst,
unsigned N)
const {
580 assert(
N == 1 &&
"Invalid number of operands!");
584 void addRegVSRpRCOperands(
MCInst &Inst,
unsigned N)
const {
585 assert(
N == 1 &&
"Invalid number of operands!");
589 void addRegVSRpEvenRCOperands(
MCInst &Inst,
unsigned N)
const {
590 assert(
N == 1 &&
"Invalid number of operands!");
594 void addRegCRBITRCOperands(
MCInst &Inst,
unsigned N)
const {
595 assert(
N == 1 &&
"Invalid number of operands!");
599 void addRegCRRCOperands(
MCInst &Inst,
unsigned N)
const {
600 assert(
N == 1 &&
"Invalid number of operands!");
604 void addCRBitMaskOperands(
MCInst &Inst,
unsigned N)
const {
605 assert(
N == 1 &&
"Invalid number of operands!");
609 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
610 assert(
N == 1 &&
"Invalid number of operands!");
611 if (Kind == Immediate)
617 void addS16ImmOperands(
MCInst &Inst,
unsigned N)
const {
618 assert(
N == 1 &&
"Invalid number of operands!");
623 case ContextImmediate:
632 void addU16ImmOperands(
MCInst &Inst,
unsigned N)
const {
633 assert(
N == 1 &&
"Invalid number of operands!");
638 case ContextImmediate:
647 void addBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
648 assert(
N == 1 &&
"Invalid number of operands!");
649 if (Kind == Immediate)
655 void addTLSRegOperands(
MCInst &Inst,
unsigned N)
const {
656 assert(
N == 1 &&
"Invalid number of operands!");
661 assert(Kind == Token &&
"Invalid access!");
667 static std::unique_ptr<PPCOperand> CreateToken(
StringRef Str,
SMLoc S,
669 auto Op = std::make_unique<PPCOperand>(Token);
670 Op->Tok.Data = Str.data();
671 Op->Tok.Length = Str.size();
674 Op->IsPPC64 = IsPPC64;
678 static std::unique_ptr<PPCOperand>
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());
692 Op->IsPPC64 = IsPPC64;
696 static std::unique_ptr<PPCOperand> CreateImm(int64_t Val,
SMLoc S,
SMLoc E,
698 auto Op = std::make_unique<PPCOperand>(Immediate);
702 Op->IsPPC64 = IsPPC64;
706 static std::unique_ptr<PPCOperand> CreateExpr(
const MCExpr *Val,
SMLoc S,
713 Op->IsPPC64 = IsPPC64;
717 static std::unique_ptr<PPCOperand>
719 auto Op = std::make_unique<PPCOperand>(TLSRegister);
720 Op->TLSReg.Sym =
Sym;
723 Op->IsPPC64 = IsPPC64;
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);
733 Op->IsPPC64 = IsPPC64;
737 static std::unique_ptr<PPCOperand>
740 return CreateImm(
CE->getValue(), S,
E, IsPPC64);
745 return CreateTLSReg(SRE, S,
E, IsPPC64);
747 if (
const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
749 if (
TE->evaluateAsConstant(Res))
750 return CreateContextImm(Res, S,
E, IsPPC64);
753 return CreateExpr(Val, S,
E, IsPPC64);
757 template <
unsigned W
idth>
758 bool isExtImm(
bool Signed,
unsigned Multiple)
const {
765 case ContextImmediate:
767 return isInt<Width>(getImmS16Context()) &&
768 (getImmS16Context() & (Multiple - 1)) == 0;
770 return isUInt<Width>(getImmU16Context()) &&
771 (getImmU16Context() & (Multiple - 1)) == 0;
781 OS <<
"'" << getToken() <<
"'";
784 case ContextImmediate:
803 if (
const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
808 }
else if (
const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
811 BinExpr->getLHS(), Ctx);
819void PPCAsmParser::ProcessInstruction(
MCInst &Inst,
828 TmpInst.
setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
829 PPC::DCBT : PPC::DCBTST);
831 (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
848 case PPC::DCBTSTDS: {
863 if (Opcode == PPC::DCBFL)
865 else if (Opcode == PPC::DCBFLP)
867 else if (Opcode == PPC::DCBFPS)
869 else if (Opcode == PPC::DCBSTPS)
916 case PPC::SUBIC_rec: {
926 case PPC::EXTLWI_rec: {
930 TmpInst.
setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
940 case PPC::EXTRWI_rec: {
944 TmpInst.
setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
954 case PPC::INSLWI_rec: {
958 TmpInst.
setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
969 case PPC::INSRWI_rec: {
973 TmpInst.
setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
984 case PPC::ROTRWI_rec: {
987 TmpInst.
setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
997 case PPC::SLWI_rec: {
1000 TmpInst.
setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1010 case PPC::SRWI_rec: {
1013 TmpInst.
setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1023 case PPC::CLRRWI_rec: {
1026 TmpInst.
setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1036 case PPC::CLRLSLWI_rec: {
1040 TmpInst.
setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1050 case PPC::EXTLDI_rec: {
1054 TmpInst.
setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1063 case PPC::EXTRDI_rec: {
1067 TmpInst.
setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1076 case PPC::INSRDI_rec: {
1080 TmpInst.
setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
1090 case PPC::ROTRDI_rec: {
1093 TmpInst.
setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1102 case PPC::SLDI_rec: {
1105 TmpInst.
setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1113 case PPC::SUBPCIS: {
1123 case PPC::SRDI_rec: {
1126 TmpInst.
setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1135 case PPC::CLRRDI_rec: {
1138 TmpInst.
setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
1147 case PPC::CLRLSLDI_rec: {
1151 TmpInst.
setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
1160 case PPC::RLWINMbm_rec: {
1167 TmpInst.
setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
1177 case PPC::RLWIMIbm_rec: {
1184 TmpInst.
setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
1195 case PPC::RLWNMbm_rec: {
1202 TmpInst.
setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
1212 if (getSTI().hasFeature(PPC::FeatureMFTB)) {
1222 unsigned VariantID = 0);
1224bool PPCAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1227 bool MatchingInlineAsm) {
1233 ProcessInstruction(Inst,
Operands);
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());
1242 ((PPCOperand &)*
Operands[0]).getToken(), FBS);
1243 return Error(IDLoc,
"invalid instruction" + Suggestion,
1244 ((PPCOperand &)*
Operands[0]).getLocRange());
1246 case Match_InvalidOperand: {
1247 SMLoc ErrorLoc = IDLoc;
1250 return Error(IDLoc,
"too few operands for instruction");
1253 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
1256 return Error(ErrorLoc,
"invalid operand for instruction");
1263bool PPCAsmParser::MatchRegisterName(
MCRegister &RegNo, int64_t &IntVal) {
1271 if (
Name.equals_insensitive(
"lr")) {
1272 RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
1274 }
else if (
Name.equals_insensitive(
"ctr")) {
1275 RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
1277 }
else if (
Name.equals_insensitive(
"vrsave")) {
1278 RegNo = PPC::VRSAVE;
1280 }
else if (
Name.starts_with_insensitive(
"r") &&
1281 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1283 }
else if (
Name.starts_with_insensitive(
"f") &&
1284 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1286 }
else if (
Name.starts_with_insensitive(
"vs") &&
1287 !
Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
1289 }
else if (
Name.starts_with_insensitive(
"v") &&
1290 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1292 }
else if (
Name.starts_with_insensitive(
"cr") &&
1293 !
Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
1295 }
else if (
Name.starts_with_insensitive(
"acc") &&
1296 !
Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1298 }
else if (
Name.starts_with_insensitive(
"wacc_hi") &&
1299 !
Name.substr(7).getAsInteger(10, IntVal) && IntVal < 8) {
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) {
1324 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1325 return TokError(
"invalid register name");
1331 const AsmToken &Tok = getParser().getTok();
1334 Reg = PPC::NoRegister;
1347const MCExpr *PPCAsmParser::
1348ExtractModifierFromExpr(
const MCExpr *
E,
1353 switch (
E->getKind()) {
1407 const MCExpr *
LHS = ExtractModifierFromExpr(BE->
getLHS(), LHSVariant);
1408 const MCExpr *
RHS = ExtractModifierFromExpr(BE->
getRHS(), RHSVariant);
1420 else if (LHSVariant == RHSVariant)
1436const MCExpr *PPCAsmParser::
1437FixupVariantKind(
const MCExpr *
E) {
1440 switch (
E->getKind()) {
1486ParseExpression(
const MCExpr *&EVal) {
1489 if (getParser().parseExpression(EVal))
1492 EVal = FixupVariantKind(EVal);
1495 const MCExpr *
E = ExtractModifierFromExpr(EVal, Variant);
1512 switch (getLexer().getKind()) {
1519 return Error(S,
"invalid register name");
1521 Operands.push_back(PPCOperand::CreateImm(IntVal, S,
E, isPPC64()));
1533 if (!ParseExpression(EVal))
1538 return Error(S,
"unknown operand");
1542 Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S,
E, isPPC64()));
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);
1552 if (
auto *
Ref = dyn_cast<MCSymbolRefExpr>(
Bin->getLHS())) {
1553 TlsCall =
Ref->getSymbol().getName() == TlsGetAddr;
1554 TlsCallAddend =
Bin->getRHS();
1561 if (ParseExpression(TLSSym))
1562 return Error(S2,
"invalid TLS call expression");
1575 const MCExpr *Addend =
nullptr;
1577 if (parsePrimaryExpr(Addend, EndLoc))
1583 TlsCallAddend = Addend;
1588 Operands.back() = PPCOperand::CreateFromMCExpr(
1592 Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S,
E, isPPC64()));
1600 switch (getLexer().getKind()) {
1604 return Error(S,
"invalid register name");
1608 if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
1610 return Error(S,
"invalid register number");
1614 return Error(S,
"invalid memory operand");
1620 Operands.push_back(PPCOperand::CreateImm(IntVal, S,
E, isPPC64()));
1632 std::string NewOpcode;
1634 NewOpcode = std::string(
Name);
1639 NewOpcode = std::string(
Name);
1645 size_t Dot =
Name.find(
'.');
1647 if (!NewOpcode.empty())
1649 PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
1651 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
1655 if (!NewOpcode.empty())
1657 PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
1659 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
1683 if (getSTI().hasFeature(PPC::FeatureBookE) &&
1685 (
Name ==
"dcbt" ||
Name ==
"dcbtst")) {
1691 if (
Name ==
"lqarx" ||
Name ==
"ldarx" ||
Name ==
"lwarx" ||
1692 Name ==
"lharx" ||
Name ==
"lbarx") {
1695 PPCOperand &EHOp = (PPCOperand &)*
Operands[4];
1696 if (EHOp.isU1Imm() && EHOp.getImm() == 0)
1704bool PPCAsmParser::ParseDirective(
AsmToken DirectiveID) {
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());
1719 ParseGNUAttribute(DirectiveID.
getLoc());
1727bool PPCAsmParser::ParseDirectiveWord(
unsigned Size,
AsmToken ID) {
1728 auto parseOp = [&]() ->
bool {
1730 SMLoc ExprLoc = getParser().getTok().getLoc();
1731 if (getParser().parseExpression(
Value))
1733 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value)) {
1735 uint64_t IntValue = MCE->getValue();
1737 return Error(ExprLoc,
"literal value out of range for '" +
1738 ID.getIdentifier() +
"' directive");
1739 getStreamer().emitIntValue(IntValue,
Size);
1741 getStreamer().emitValue(
Value,
Size, ExprLoc);
1745 if (parseMany(parseOp))
1746 return addErrorSuffix(
" in '" +
ID.getIdentifier() +
"' directive");
1759 return addErrorSuffix(
" in '.tc' directive");
1762 getParser().getStreamer().emitValueToAlignment(
Align(
Size));
1765 return ParseDirectiveWord(
Size,
ID);
1770bool PPCAsmParser::ParseDirectiveMachine(
SMLoc L) {
1774 return Error(L,
"unexpected token in '.machine' directive");
1785 return addErrorSuffix(
" in '.machine' directive");
1788 getParser().getStreamer().getTargetStreamer());
1789 if (TStreamer !=
nullptr)
1797bool PPCAsmParser::ParseDirectiveAbiVersion(
SMLoc L) {
1799 if (
check(getParser().parseAbsoluteExpression(AbiVersion), L,
1800 "expected constant expression") ||
1802 return addErrorSuffix(
" in '.abiversion' directive");
1805 getParser().getStreamer().getTargetStreamer());
1806 if (TStreamer !=
nullptr)
1814bool PPCAsmParser::ParseDirectiveLocalEntry(
SMLoc L) {
1816 if (getParser().parseIdentifier(
Name))
1817 return Error(L,
"expected identifier in '.localentry' directive");
1823 check(getParser().parseExpression(Expr), L,
"expected expression") ||
1825 return addErrorSuffix(
" in '.localentry' directive");
1828 getParser().getStreamer().getTargetStreamer());
1829 if (TStreamer !=
nullptr)
1835bool PPCAsmParser::ParseGNUAttribute(
SMLoc L) {
1837 int64_t IntegerValue;
1838 if (!getParser().parseGNUAttribute(L,
Tag, IntegerValue))
1841 getParser().getStreamer().emitGNUAttribute(
Tag, IntegerValue);
1854#define GET_REGISTER_MATCHER
1855#define GET_MATCHER_IMPLEMENTATION
1856#define GET_MNEMONIC_SPELL_CHECKER
1857#include "PPCGenAsmMatcher.inc"
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;
1879 PPCOperand &
Op =
static_cast<PPCOperand &
>(AsmOp);
1880 if (
Op.isU3Imm() &&
Op.getImm() == ImmVal)
1881 return Match_Success;
1883 return Match_InvalidOperand;
1887PPCAsmParser::applyModifierToExpr(
const MCExpr *
E,
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
#define LLVM_EXTERNAL_VISIBILITY
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
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)
Target independent representation for an assembler token.
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Class representing an expression and its matching format.
Container class for subtarget features.
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
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.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Opcode getOpcode() const
Get the kind of this binary expression.
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Interface to description of machine instruction set.
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
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.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
StringRef getName() const
getName - Get the symbol name.
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.
Opcode getOpcode() const
Get the kind of this unary expression.
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
const MCExpr * getSubExpr() const
Get the child of this unary expression.
static const MCUnaryExpr * createMinus(const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
static const PPCMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
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.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
bool startswith(StringRef Prefix) const
static constexpr size_t npos
int compare_insensitive(StringRef RHS) const
Compare two strings, ignoring case.
Triple - Helper class for working with autoconf configuration names.
bool isPPC64() const
Tests whether the target is 64-bit PowerPC (little and big endian).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
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.
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Target & getThePPC64LETarget()
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
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.
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.
This struct is a compact representation of a valid (non-zero power of two) alignment.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...