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!");
282 assert(isRegNumber() &&
"Invalid access!");
283 return (
unsigned)
Imm.Val;
286 unsigned getFpReg()
const {
287 assert(isEvenRegNumber() &&
"Invalid access!");
288 return (
unsigned)(
Imm.Val >> 1);
291 unsigned getVSReg()
const {
292 assert(isVSRegNumber() &&
"Invalid access!");
293 return (
unsigned)
Imm.Val;
296 unsigned getACCReg()
const {
297 assert(isACCRegNumber() &&
"Invalid access!");
298 return (
unsigned)
Imm.Val;
301 unsigned getDMRROWReg()
const {
302 assert(isDMRROWRegNumber() &&
"Invalid access!");
303 return (
unsigned)
Imm.Val;
306 unsigned getDMRROWpReg()
const {
307 assert(isDMRROWpRegNumber() &&
"Invalid access!");
308 return (
unsigned)
Imm.Val;
311 unsigned getDMRReg()
const {
312 assert(isDMRRegNumber() &&
"Invalid access!");
313 return (
unsigned)
Imm.Val;
316 unsigned getDMRpReg()
const {
317 assert(isDMRpRegNumber() &&
"Invalid access!");
318 return (
unsigned)
Imm.Val;
321 unsigned getVSRpEvenReg()
const {
322 assert(isVSRpEvenRegNumber() &&
"Invalid access!");
323 return (
unsigned)
Imm.Val >> 1;
326 unsigned getG8pReg()
const {
327 assert(isEvenRegNumber() &&
"Invalid access!");
328 return (
unsigned)
Imm.Val;
331 unsigned getCCReg()
const {
332 assert(isCCRegNumber() &&
"Invalid access!");
333 return (
unsigned) (
Kind == Immediate ?
Imm.Val : Expr.CRVal);
336 unsigned getCRBit()
const {
337 assert(isCRBitNumber() &&
"Invalid access!");
338 return (
unsigned) (
Kind == Immediate ?
Imm.Val : Expr.CRVal);
341 unsigned getCRBitMask()
const {
342 assert(isCRBitMask() &&
"Invalid access!");
343 return 7 - llvm::countr_zero<uint64_t>(
Imm.Val);
346 bool isToken()
const override {
return Kind == Token; }
347 bool isImm()
const override {
350 bool isU1Imm()
const {
return Kind == Immediate && isUInt<1>(getImm()); }
351 bool isU2Imm()
const {
return Kind == Immediate && isUInt<2>(getImm()); }
352 bool isU3Imm()
const {
return Kind == Immediate && isUInt<3>(getImm()); }
353 bool isU4Imm()
const {
return Kind == Immediate && isUInt<4>(getImm()); }
354 bool isU5Imm()
const {
return Kind == Immediate && isUInt<5>(getImm()); }
355 bool isS5Imm()
const {
return Kind == Immediate && isInt<5>(getImm()); }
356 bool isU6Imm()
const {
return Kind == Immediate && isUInt<6>(getImm()); }
357 bool isU6ImmX2()
const {
return Kind == Immediate &&
358 isUInt<6>(getImm()) &&
359 (getImm() & 1) == 0; }
360 bool isU7Imm()
const {
return Kind == Immediate && isUInt<7>(getImm()); }
361 bool isU7ImmX4()
const {
return Kind == Immediate &&
362 isUInt<7>(getImm()) &&
363 (getImm() & 3) == 0; }
364 bool isU8Imm()
const {
return Kind == Immediate && isUInt<8>(getImm()); }
365 bool isU8ImmX8()
const {
return Kind == Immediate &&
366 isUInt<8>(getImm()) &&
367 (getImm() & 7) == 0; }
369 bool isU10Imm()
const {
return Kind == Immediate && isUInt<10>(getImm()); }
370 bool isU12Imm()
const {
return Kind == Immediate && isUInt<12>(getImm()); }
371 bool isU16Imm()
const {
return isExtImm<16>(
false, 1); }
372 bool isS16Imm()
const {
return isExtImm<16>(
true, 1); }
373 bool isS16ImmX4()
const {
return isExtImm<16>(
true, 4); }
374 bool isS16ImmX16()
const {
return isExtImm<16>(
true, 16); }
375 bool isS17Imm()
const {
return isExtImm<17>(
true, 1); }
377 bool isHashImmX8()
const {
381 return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&
382 (getImm() & 7) == 0);
385 bool isS34ImmX16()
const {
387 (
Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
389 bool isS34Imm()
const {
395 bool isTLSReg()
const {
return Kind == TLSRegister; }
396 bool isDirectBr()
const {
399 if (Kind != Immediate)
402 if ((getImm() & 3) != 0)
404 if (isInt<26>(getImm()))
408 if (isUInt<32>(getImm()) && isInt<26>(
static_cast<int32_t
>(getImm())))
414 (
Kind == Immediate && isInt<16>(getImm()) &&
415 (getImm() & 3) == 0); }
416 bool isImmZero()
const {
return Kind == Immediate && getImm() == 0; }
417 bool isRegNumber()
const {
return Kind == Immediate && isUInt<5>(getImm()); }
418 bool isACCRegNumber()
const {
419 return Kind == Immediate && isUInt<3>(getImm());
421 bool isDMRROWRegNumber()
const {
422 return Kind == Immediate && isUInt<6>(getImm());
424 bool isDMRROWpRegNumber()
const {
425 return Kind == Immediate && isUInt<5>(getImm());
427 bool isDMRRegNumber()
const {
428 return Kind == Immediate && isUInt<3>(getImm());
430 bool isDMRpRegNumber()
const {
431 return Kind == Immediate && isUInt<2>(getImm());
433 bool isVSRpEvenRegNumber()
const {
434 return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
436 bool isVSRegNumber()
const {
437 return Kind == Immediate && isUInt<6>(getImm());
439 bool isCCRegNumber()
const {
return (Kind ==
Expression
440 && isUInt<3>(getExprCRVal())) ||
442 && isUInt<3>(getImm())); }
443 bool isCRBitNumber()
const {
return (Kind ==
Expression
444 && isUInt<5>(getExprCRVal())) ||
446 && isUInt<5>(getImm())); }
448 bool isEvenRegNumber()
const {
return isRegNumber() && (getImm() & 1) == 0; }
450 bool isCRBitMask()
const {
451 return Kind == Immediate && isUInt<8>(getImm()) &&
452 llvm::has_single_bit<uint32_t>(getImm());
454 bool isATBitsAsHint()
const {
return false; }
455 bool isMem()
const override {
return false; }
456 bool isReg()
const override {
return false; }
458 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
462 void addRegGPRCOperands(
MCInst &Inst,
unsigned N)
const {
463 assert(
N == 1 &&
"Invalid number of operands!");
467 void addRegGPRCNoR0Operands(
MCInst &Inst,
unsigned N)
const {
468 assert(
N == 1 &&
"Invalid number of operands!");
472 void addRegG8RCOperands(
MCInst &Inst,
unsigned N)
const {
473 assert(
N == 1 &&
"Invalid number of operands!");
477 void addRegG8RCNoX0Operands(
MCInst &Inst,
unsigned N)
const {
478 assert(
N == 1 &&
"Invalid number of operands!");
482 void addRegG8pRCOperands(
MCInst &Inst,
unsigned N)
const {
483 assert(
N == 1 &&
"Invalid number of operands!");
487 void addRegGxRCOperands(
MCInst &Inst,
unsigned N)
const {
489 addRegG8RCOperands(Inst,
N);
491 addRegGPRCOperands(Inst,
N);
494 void addRegGxRCNoR0Operands(
MCInst &Inst,
unsigned N)
const {
496 addRegG8RCNoX0Operands(Inst,
N);
498 addRegGPRCNoR0Operands(Inst,
N);
501 void addRegF4RCOperands(
MCInst &Inst,
unsigned N)
const {
502 assert(
N == 1 &&
"Invalid number of operands!");
506 void addRegF8RCOperands(
MCInst &Inst,
unsigned N)
const {
507 assert(
N == 1 &&
"Invalid number of operands!");
511 void addRegFpRCOperands(
MCInst &Inst,
unsigned N)
const {
512 assert(
N == 1 &&
"Invalid number of operands!");
516 void addRegVFRCOperands(
MCInst &Inst,
unsigned N)
const {
517 assert(
N == 1 &&
"Invalid number of operands!");
521 void addRegVRRCOperands(
MCInst &Inst,
unsigned N)
const {
522 assert(
N == 1 &&
"Invalid number of operands!");
526 void addRegVSRCOperands(
MCInst &Inst,
unsigned N)
const {
527 assert(
N == 1 &&
"Invalid number of operands!");
531 void addRegVSFRCOperands(
MCInst &Inst,
unsigned N)
const {
532 assert(
N == 1 &&
"Invalid number of operands!");
536 void addRegVSSRCOperands(
MCInst &Inst,
unsigned N)
const {
537 assert(
N == 1 &&
"Invalid number of operands!");
541 void addRegSPE4RCOperands(
MCInst &Inst,
unsigned N)
const {
542 assert(
N == 1 &&
"Invalid number of operands!");
546 void addRegSPERCOperands(
MCInst &Inst,
unsigned N)
const {
547 assert(
N == 1 &&
"Invalid number of operands!");
551 void addRegACCRCOperands(
MCInst &Inst,
unsigned N)
const {
552 assert(
N == 1 &&
"Invalid number of operands!");
556 void addRegDMRROWRCOperands(
MCInst &Inst,
unsigned N)
const {
557 assert(
N == 1 &&
"Invalid number of operands!");
561 void addRegDMRROWpRCOperands(
MCInst &Inst,
unsigned N)
const {
562 assert(
N == 1 &&
"Invalid number of operands!");
566 void addRegDMRRCOperands(
MCInst &Inst,
unsigned N)
const {
567 assert(
N == 1 &&
"Invalid number of operands!");
571 void addRegDMRpRCOperands(
MCInst &Inst,
unsigned N)
const {
572 assert(
N == 1 &&
"Invalid number of operands!");
576 void addRegWACCRCOperands(
MCInst &Inst,
unsigned N)
const {
577 assert(
N == 1 &&
"Invalid number of operands!");
581 void addRegWACC_HIRCOperands(
MCInst &Inst,
unsigned N)
const {
582 assert(
N == 1 &&
"Invalid number of operands!");
586 void addRegVSRpRCOperands(
MCInst &Inst,
unsigned N)
const {
587 assert(
N == 1 &&
"Invalid number of operands!");
591 void addRegVSRpEvenRCOperands(
MCInst &Inst,
unsigned N)
const {
592 assert(
N == 1 &&
"Invalid number of operands!");
596 void addRegCRBITRCOperands(
MCInst &Inst,
unsigned N)
const {
597 assert(
N == 1 &&
"Invalid number of operands!");
601 void addRegCRRCOperands(
MCInst &Inst,
unsigned N)
const {
602 assert(
N == 1 &&
"Invalid number of operands!");
606 void addCRBitMaskOperands(
MCInst &Inst,
unsigned N)
const {
607 assert(
N == 1 &&
"Invalid number of operands!");
611 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
612 assert(
N == 1 &&
"Invalid number of operands!");
613 if (Kind == Immediate)
619 void addS16ImmOperands(
MCInst &Inst,
unsigned N)
const {
620 assert(
N == 1 &&
"Invalid number of operands!");
625 case ContextImmediate:
634 void addU16ImmOperands(
MCInst &Inst,
unsigned N)
const {
635 assert(
N == 1 &&
"Invalid number of operands!");
640 case ContextImmediate:
649 void addBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
650 assert(
N == 1 &&
"Invalid number of operands!");
651 if (Kind == Immediate)
657 void addTLSRegOperands(
MCInst &Inst,
unsigned N)
const {
658 assert(
N == 1 &&
"Invalid number of operands!");
663 assert(Kind == Token &&
"Invalid access!");
669 static std::unique_ptr<PPCOperand> CreateToken(
StringRef Str,
SMLoc S,
671 auto Op = std::make_unique<PPCOperand>(Token);
672 Op->Tok.Data = Str.data();
673 Op->Tok.Length = Str.size();
676 Op->IsPPC64 = IsPPC64;
680 static std::unique_ptr<PPCOperand>
687 void *Mem = ::operator
new(
sizeof(PPCOperand) + Str.size());
688 std::unique_ptr<PPCOperand>
Op(
new (Mem) PPCOperand(Token));
689 Op->Tok.Data =
reinterpret_cast<const char *
>(
Op.get() + 1);
690 Op->Tok.Length = Str.size();
691 std::memcpy(
const_cast<char *
>(
Op->Tok.Data), Str.data(), Str.size());
694 Op->IsPPC64 = IsPPC64;
698 static std::unique_ptr<PPCOperand> CreateImm(int64_t Val,
SMLoc S,
SMLoc E,
700 auto Op = std::make_unique<PPCOperand>(Immediate);
704 Op->IsPPC64 = IsPPC64;
708 static std::unique_ptr<PPCOperand> CreateExpr(
const MCExpr *Val,
SMLoc S,
715 Op->IsPPC64 = IsPPC64;
719 static std::unique_ptr<PPCOperand>
721 auto Op = std::make_unique<PPCOperand>(TLSRegister);
722 Op->TLSReg.Sym =
Sym;
725 Op->IsPPC64 = IsPPC64;
729 static std::unique_ptr<PPCOperand>
730 CreateContextImm(int64_t Val,
SMLoc S,
SMLoc E,
bool IsPPC64) {
731 auto Op = std::make_unique<PPCOperand>(ContextImmediate);
735 Op->IsPPC64 = IsPPC64;
739 static std::unique_ptr<PPCOperand>
742 return CreateImm(
CE->getValue(), S,
E, IsPPC64);
747 return CreateTLSReg(SRE, S,
E, IsPPC64);
749 if (
const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
751 if (
TE->evaluateAsConstant(Res))
752 return CreateContextImm(Res, S,
E, IsPPC64);
755 return CreateExpr(Val, S,
E, IsPPC64);
759 template <
unsigned W
idth>
760 bool isExtImm(
bool Signed,
unsigned Multiple)
const {
767 case ContextImmediate:
769 return isInt<Width>(getImmS16Context()) &&
770 (getImmS16Context() & (Multiple - 1)) == 0;
772 return isUInt<Width>(getImmU16Context()) &&
773 (getImmU16Context() & (Multiple - 1)) == 0;
783 OS <<
"'" << getToken() <<
"'";
786 case ContextImmediate:
805 if (
const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
810 }
else if (
const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
813 BinExpr->getLHS(), Ctx);
821void PPCAsmParser::ProcessInstruction(
MCInst &Inst,
830 TmpInst.
setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
831 PPC::DCBT : PPC::DCBTST);
833 (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
850 case PPC::DCBTSTDS: {
865 if (Opcode == PPC::DCBFL)
867 else if (Opcode == PPC::DCBFLP)
869 else if (Opcode == PPC::DCBFPS)
871 else if (Opcode == PPC::DCBSTPS)
894 TmpInst.
setOpcode(Opcode == PPC::PLA ? PPC::PADDI : PPC::PADDI8);
904 TmpInst.
setOpcode(Opcode == PPC::PLApc ? PPC::PADDIpc : PPC::PADDI8pc);
947 case PPC::SUBIC_rec: {
957 case PPC::EXTLWI_rec: {
961 TmpInst.
setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
971 case PPC::EXTRWI_rec: {
975 TmpInst.
setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
985 case PPC::INSLWI_rec: {
989 TmpInst.
setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
1000 case PPC::INSRWI_rec: {
1004 TmpInst.
setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
1015 case PPC::ROTRWI_rec: {
1018 TmpInst.
setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1028 case PPC::SLWI_rec: {
1031 TmpInst.
setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1041 case PPC::SRWI_rec: {
1044 TmpInst.
setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1054 case PPC::CLRRWI_rec: {
1057 TmpInst.
setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1067 case PPC::CLRLSLWI_rec: {
1071 TmpInst.
setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1081 case PPC::EXTLDI_rec: {
1085 TmpInst.
setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1094 case PPC::EXTRDI_rec: {
1098 TmpInst.
setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1107 case PPC::INSRDI_rec: {
1111 TmpInst.
setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
1121 case PPC::ROTRDI_rec: {
1124 TmpInst.
setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1133 case PPC::SLDI_rec: {
1136 TmpInst.
setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1144 case PPC::SUBPCIS: {
1154 case PPC::SRDI_rec: {
1157 TmpInst.
setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1166 case PPC::CLRRDI_rec: {
1169 TmpInst.
setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
1178 case PPC::CLRLSLDI_rec: {
1182 TmpInst.
setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
1191 case PPC::RLWINMbm_rec: {
1198 TmpInst.
setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
1208 case PPC::RLWIMIbm_rec: {
1215 TmpInst.
setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
1226 case PPC::RLWNMbm_rec: {
1233 TmpInst.
setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
1243 if (getSTI().hasFeature(PPC::FeatureMFTB)) {
1253 unsigned VariantID = 0);
1255bool PPCAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1258 bool MatchingInlineAsm) {
1264 ProcessInstruction(Inst,
Operands);
1268 case Match_MissingFeature:
1269 return Error(IDLoc,
"instruction use requires an option to be enabled");
1270 case Match_MnemonicFail: {
1271 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1273 ((PPCOperand &)*
Operands[0]).getToken(), FBS);
1274 return Error(IDLoc,
"invalid instruction" + Suggestion,
1275 ((PPCOperand &)*
Operands[0]).getLocRange());
1277 case Match_InvalidOperand: {
1278 SMLoc ErrorLoc = IDLoc;
1281 return Error(IDLoc,
"too few operands for instruction");
1284 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
1287 return Error(ErrorLoc,
"invalid operand for instruction");
1294bool PPCAsmParser::MatchRegisterName(
MCRegister &RegNo, int64_t &IntVal) {
1302 if (
Name.equals_insensitive(
"lr")) {
1303 RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
1305 }
else if (
Name.equals_insensitive(
"ctr")) {
1306 RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
1308 }
else if (
Name.equals_insensitive(
"vrsave")) {
1309 RegNo = PPC::VRSAVE;
1311 }
else if (
Name.starts_with_insensitive(
"r") &&
1312 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1314 }
else if (
Name.starts_with_insensitive(
"f") &&
1315 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1317 }
else if (
Name.starts_with_insensitive(
"vs") &&
1318 !
Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
1320 }
else if (
Name.starts_with_insensitive(
"v") &&
1321 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1323 }
else if (
Name.starts_with_insensitive(
"cr") &&
1324 !
Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
1326 }
else if (
Name.starts_with_insensitive(
"acc") &&
1327 !
Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1329 }
else if (
Name.starts_with_insensitive(
"wacc_hi") &&
1330 !
Name.substr(7).getAsInteger(10, IntVal) && IntVal < 8) {
1332 }
else if (
Name.starts_with_insensitive(
"wacc") &&
1333 !
Name.substr(4).getAsInteger(10, IntVal) && IntVal < 8) {
1334 RegNo = WACCRegs[
IntVal];
1335 }
else if (
Name.starts_with_insensitive(
"dmrrowp") &&
1336 !
Name.substr(7).getAsInteger(10, IntVal) && IntVal < 32) {
1337 RegNo = DMRROWpRegs[
IntVal];
1338 }
else if (
Name.starts_with_insensitive(
"dmrrow") &&
1339 !
Name.substr(6).getAsInteger(10, IntVal) && IntVal < 64) {
1340 RegNo = DMRROWRegs[
IntVal];
1341 }
else if (
Name.starts_with_insensitive(
"dmrp") &&
1342 !
Name.substr(4).getAsInteger(10, IntVal) && IntVal < 4) {
1343 RegNo = DMRROWpRegs[
IntVal];
1344 }
else if (
Name.starts_with_insensitive(
"dmr") &&
1345 !
Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1355 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1356 return TokError(
"invalid register name");
1362 const AsmToken &Tok = getParser().getTok();
1365 Reg = PPC::NoRegister;
1378const MCExpr *PPCAsmParser::
1379ExtractModifierFromExpr(
const MCExpr *
E,
1381 MCContext &Context = getParser().getContext();
1384 switch (
E->getKind()) {
1438 const MCExpr *
LHS = ExtractModifierFromExpr(BE->
getLHS(), LHSVariant);
1439 const MCExpr *
RHS = ExtractModifierFromExpr(BE->
getRHS(), RHSVariant);
1451 else if (LHSVariant == RHSVariant)
1467const MCExpr *PPCAsmParser::
1468FixupVariantKind(
const MCExpr *
E) {
1469 MCContext &Context = getParser().getContext();
1471 switch (
E->getKind()) {
1517ParseExpression(
const MCExpr *&EVal) {
1520 if (getParser().parseExpression(EVal))
1523 EVal = FixupVariantKind(EVal);
1526 const MCExpr *
E = ExtractModifierFromExpr(EVal, Variant);
1543 switch (getLexer().getKind()) {
1550 return Error(S,
"invalid register name");
1552 Operands.push_back(PPCOperand::CreateImm(IntVal, S,
E, isPPC64()));
1564 if (!ParseExpression(EVal))
1569 return Error(S,
"unknown operand");
1573 Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S,
E, isPPC64()));
1576 const char TlsGetAddr[] =
"__tls_get_addr";
1577 bool TlsCall =
false;
1578 const MCExpr *TlsCallAddend =
nullptr;
1579 if (
auto *
Ref = dyn_cast<MCSymbolRefExpr>(EVal)) {
1580 TlsCall =
Ref->getSymbol().getName() == TlsGetAddr;
1581 }
else if (
auto *
Bin = dyn_cast<MCBinaryExpr>(EVal);
1583 if (
auto *
Ref = dyn_cast<MCSymbolRefExpr>(
Bin->getLHS())) {
1584 TlsCall =
Ref->getSymbol().getName() == TlsGetAddr;
1585 TlsCallAddend =
Bin->getRHS();
1592 if (ParseExpression(TLSSym))
1593 return Error(S2,
"invalid TLS call expression");
1606 const MCExpr *Addend =
nullptr;
1608 if (parsePrimaryExpr(Addend, EndLoc))
1614 TlsCallAddend = Addend;
1619 Operands.back() = PPCOperand::CreateFromMCExpr(
1623 Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S,
E, isPPC64()));
1631 switch (getLexer().getKind()) {
1635 return Error(S,
"invalid register name");
1639 if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
1641 return Error(S,
"invalid register number");
1645 return Error(S,
"invalid memory operand");
1651 Operands.push_back(PPCOperand::CreateImm(IntVal, S,
E, isPPC64()));
1663 std::string NewOpcode;
1665 NewOpcode = std::string(
Name);
1670 NewOpcode = std::string(
Name);
1676 size_t Dot =
Name.find(
'.');
1678 if (!NewOpcode.empty())
1680 PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
1682 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
1686 if (!NewOpcode.empty())
1688 PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
1690 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
1714 if (getSTI().hasFeature(PPC::FeatureBookE) &&
1716 (
Name ==
"dcbt" ||
Name ==
"dcbtst")) {
1722 if (
Name ==
"lqarx" ||
Name ==
"ldarx" ||
Name ==
"lwarx" ||
1723 Name ==
"lharx" ||
Name ==
"lbarx") {
1726 PPCOperand &EHOp = (PPCOperand &)*
Operands[4];
1727 if (EHOp.isU1Imm() && EHOp.getImm() == 0)
1735bool PPCAsmParser::ParseDirective(
AsmToken DirectiveID) {
1737 if (IDVal ==
".word")
1738 ParseDirectiveWord(2, DirectiveID);
1739 else if (IDVal ==
".llong")
1740 ParseDirectiveWord(8, DirectiveID);
1741 else if (IDVal ==
".tc")
1742 ParseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);
1743 else if (IDVal ==
".machine")
1744 ParseDirectiveMachine(DirectiveID.
getLoc());
1745 else if (IDVal ==
".abiversion")
1746 ParseDirectiveAbiVersion(DirectiveID.
getLoc());
1747 else if (IDVal ==
".localentry")
1748 ParseDirectiveLocalEntry(DirectiveID.
getLoc());
1750 ParseGNUAttribute(DirectiveID.
getLoc());
1758bool PPCAsmParser::ParseDirectiveWord(
unsigned Size,
AsmToken ID) {
1759 auto parseOp = [&]() ->
bool {
1761 SMLoc ExprLoc = getParser().getTok().getLoc();
1762 if (getParser().parseExpression(
Value))
1764 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value)) {
1766 uint64_t IntValue = MCE->getValue();
1768 return Error(ExprLoc,
"literal value out of range for '" +
1769 ID.getIdentifier() +
"' directive");
1770 getStreamer().emitIntValue(IntValue,
Size);
1772 getStreamer().emitValue(
Value,
Size, ExprLoc);
1776 if (parseMany(parseOp))
1777 return addErrorSuffix(
" in '" +
ID.getIdentifier() +
"' directive");
1790 return addErrorSuffix(
" in '.tc' directive");
1793 getParser().getStreamer().emitValueToAlignment(
Align(
Size));
1796 return ParseDirectiveWord(
Size,
ID);
1801bool PPCAsmParser::ParseDirectiveMachine(
SMLoc L) {
1805 return Error(L,
"unexpected token in '.machine' directive");
1816 return addErrorSuffix(
" in '.machine' directive");
1819 getParser().getStreamer().getTargetStreamer());
1820 if (TStreamer !=
nullptr)
1828bool PPCAsmParser::ParseDirectiveAbiVersion(
SMLoc L) {
1830 if (check(getParser().parseAbsoluteExpression(AbiVersion), L,
1831 "expected constant expression") ||
1833 return addErrorSuffix(
" in '.abiversion' directive");
1836 getParser().getStreamer().getTargetStreamer());
1837 if (TStreamer !=
nullptr)
1845bool PPCAsmParser::ParseDirectiveLocalEntry(
SMLoc L) {
1847 if (getParser().parseIdentifier(
Name))
1848 return Error(L,
"expected identifier in '.localentry' directive");
1854 check(getParser().parseExpression(Expr), L,
"expected expression") ||
1856 return addErrorSuffix(
" in '.localentry' directive");
1859 getParser().getStreamer().getTargetStreamer());
1860 if (TStreamer !=
nullptr)
1866bool PPCAsmParser::ParseGNUAttribute(
SMLoc L) {
1868 int64_t IntegerValue;
1869 if (!getParser().parseGNUAttribute(L,
Tag, IntegerValue))
1872 getParser().getStreamer().emitGNUAttribute(
Tag, IntegerValue);
1885#define GET_REGISTER_MATCHER
1886#define GET_MATCHER_IMPLEMENTATION
1887#define GET_MNEMONIC_SPELL_CHECKER
1888#include "PPCGenAsmMatcher.inc"
1899 case MCK_0: ImmVal = 0;
break;
1900 case MCK_1: ImmVal = 1;
break;
1901 case MCK_2: ImmVal = 2;
break;
1902 case MCK_3: ImmVal = 3;
break;
1903 case MCK_4: ImmVal = 4;
break;
1904 case MCK_5: ImmVal = 5;
break;
1905 case MCK_6: ImmVal = 6;
break;
1906 case MCK_7: ImmVal = 7;
break;
1907 default:
return Match_InvalidOperand;
1910 PPCOperand &
Op =
static_cast<PPCOperand &
>(AsmOp);
1911 if (
Op.isU3Imm() &&
Op.getImm() == ImmVal)
1912 return Match_Success;
1914 return Match_InvalidOperand;
1918PPCAsmParser::applyModifierToExpr(
const MCExpr *
E,
static MCRegister MatchRegisterName(StringRef Name)
static bool getRegNum(StringRef Str, unsigned &Num)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#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 starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
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,...