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)
892 TmpInst.
setOpcode(Opcode == PPC::PLA ? PPC::PADDI : PPC::PADDI8);
902 TmpInst.
setOpcode(Opcode == PPC::PLApc ? PPC::PADDIpc : PPC::PADDI8pc);
945 case PPC::SUBIC_rec: {
955 case PPC::EXTLWI_rec: {
959 TmpInst.
setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
969 case PPC::EXTRWI_rec: {
973 TmpInst.
setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
983 case PPC::INSLWI_rec: {
987 TmpInst.
setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
998 case PPC::INSRWI_rec: {
1002 TmpInst.
setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
1013 case PPC::ROTRWI_rec: {
1016 TmpInst.
setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1026 case PPC::SLWI_rec: {
1029 TmpInst.
setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1039 case PPC::SRWI_rec: {
1042 TmpInst.
setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1052 case PPC::CLRRWI_rec: {
1055 TmpInst.
setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1065 case PPC::CLRLSLWI_rec: {
1069 TmpInst.
setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1079 case PPC::EXTLDI_rec: {
1083 TmpInst.
setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1092 case PPC::EXTRDI_rec: {
1096 TmpInst.
setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1105 case PPC::INSRDI_rec: {
1109 TmpInst.
setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
1119 case PPC::ROTRDI_rec: {
1122 TmpInst.
setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1131 case PPC::SLDI_rec: {
1134 TmpInst.
setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1142 case PPC::SUBPCIS: {
1152 case PPC::SRDI_rec: {
1155 TmpInst.
setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1164 case PPC::CLRRDI_rec: {
1167 TmpInst.
setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
1176 case PPC::CLRLSLDI_rec: {
1180 TmpInst.
setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
1189 case PPC::RLWINMbm_rec: {
1196 TmpInst.
setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
1206 case PPC::RLWIMIbm_rec: {
1213 TmpInst.
setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
1224 case PPC::RLWNMbm_rec: {
1231 TmpInst.
setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
1241 if (getSTI().hasFeature(PPC::FeatureMFTB)) {
1251 unsigned VariantID = 0);
1253bool PPCAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1256 bool MatchingInlineAsm) {
1262 ProcessInstruction(Inst,
Operands);
1266 case Match_MissingFeature:
1267 return Error(IDLoc,
"instruction use requires an option to be enabled");
1268 case Match_MnemonicFail: {
1269 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1271 ((PPCOperand &)*
Operands[0]).getToken(), FBS);
1272 return Error(IDLoc,
"invalid instruction" + Suggestion,
1273 ((PPCOperand &)*
Operands[0]).getLocRange());
1275 case Match_InvalidOperand: {
1276 SMLoc ErrorLoc = IDLoc;
1279 return Error(IDLoc,
"too few operands for instruction");
1282 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
1285 return Error(ErrorLoc,
"invalid operand for instruction");
1292bool PPCAsmParser::MatchRegisterName(
MCRegister &RegNo, int64_t &IntVal) {
1300 if (
Name.equals_insensitive(
"lr")) {
1301 RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
1303 }
else if (
Name.equals_insensitive(
"ctr")) {
1304 RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
1306 }
else if (
Name.equals_insensitive(
"vrsave")) {
1307 RegNo = PPC::VRSAVE;
1309 }
else if (
Name.starts_with_insensitive(
"r") &&
1310 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1312 }
else if (
Name.starts_with_insensitive(
"f") &&
1313 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1315 }
else if (
Name.starts_with_insensitive(
"vs") &&
1316 !
Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
1318 }
else if (
Name.starts_with_insensitive(
"v") &&
1319 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1321 }
else if (
Name.starts_with_insensitive(
"cr") &&
1322 !
Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
1324 }
else if (
Name.starts_with_insensitive(
"acc") &&
1325 !
Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1327 }
else if (
Name.starts_with_insensitive(
"wacc_hi") &&
1328 !
Name.substr(7).getAsInteger(10, IntVal) && IntVal < 8) {
1330 }
else if (
Name.starts_with_insensitive(
"wacc") &&
1331 !
Name.substr(4).getAsInteger(10, IntVal) && IntVal < 8) {
1332 RegNo = WACCRegs[
IntVal];
1333 }
else if (
Name.starts_with_insensitive(
"dmrrowp") &&
1334 !
Name.substr(7).getAsInteger(10, IntVal) && IntVal < 32) {
1335 RegNo = DMRROWpRegs[
IntVal];
1336 }
else if (
Name.starts_with_insensitive(
"dmrrow") &&
1337 !
Name.substr(6).getAsInteger(10, IntVal) && IntVal < 64) {
1338 RegNo = DMRROWRegs[
IntVal];
1339 }
else if (
Name.starts_with_insensitive(
"dmrp") &&
1340 !
Name.substr(4).getAsInteger(10, IntVal) && IntVal < 4) {
1341 RegNo = DMRROWpRegs[
IntVal];
1342 }
else if (
Name.starts_with_insensitive(
"dmr") &&
1343 !
Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1353 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1354 return TokError(
"invalid register name");
1360 const AsmToken &Tok = getParser().getTok();
1363 Reg = PPC::NoRegister;
1376const MCExpr *PPCAsmParser::
1377ExtractModifierFromExpr(
const MCExpr *
E,
1382 switch (
E->getKind()) {
1436 const MCExpr *
LHS = ExtractModifierFromExpr(BE->
getLHS(), LHSVariant);
1437 const MCExpr *
RHS = ExtractModifierFromExpr(BE->
getRHS(), RHSVariant);
1449 else if (LHSVariant == RHSVariant)
1465const MCExpr *PPCAsmParser::
1466FixupVariantKind(
const MCExpr *
E) {
1469 switch (
E->getKind()) {
1515ParseExpression(
const MCExpr *&EVal) {
1518 if (getParser().parseExpression(EVal))
1521 EVal = FixupVariantKind(EVal);
1524 const MCExpr *
E = ExtractModifierFromExpr(EVal, Variant);
1541 switch (getLexer().getKind()) {
1548 return Error(S,
"invalid register name");
1550 Operands.push_back(PPCOperand::CreateImm(IntVal, S,
E, isPPC64()));
1562 if (!ParseExpression(EVal))
1567 return Error(S,
"unknown operand");
1571 Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S,
E, isPPC64()));
1574 const char TlsGetAddr[] =
"__tls_get_addr";
1575 bool TlsCall =
false;
1576 const MCExpr *TlsCallAddend =
nullptr;
1577 if (
auto *
Ref = dyn_cast<MCSymbolRefExpr>(EVal)) {
1578 TlsCall =
Ref->getSymbol().getName() == TlsGetAddr;
1579 }
else if (
auto *
Bin = dyn_cast<MCBinaryExpr>(EVal);
1581 if (
auto *
Ref = dyn_cast<MCSymbolRefExpr>(
Bin->getLHS())) {
1582 TlsCall =
Ref->getSymbol().getName() == TlsGetAddr;
1583 TlsCallAddend =
Bin->getRHS();
1590 if (ParseExpression(TLSSym))
1591 return Error(S2,
"invalid TLS call expression");
1604 const MCExpr *Addend =
nullptr;
1606 if (parsePrimaryExpr(Addend, EndLoc))
1612 TlsCallAddend = Addend;
1617 Operands.back() = PPCOperand::CreateFromMCExpr(
1621 Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S,
E, isPPC64()));
1629 switch (getLexer().getKind()) {
1633 return Error(S,
"invalid register name");
1637 if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
1639 return Error(S,
"invalid register number");
1643 return Error(S,
"invalid memory operand");
1649 Operands.push_back(PPCOperand::CreateImm(IntVal, S,
E, isPPC64()));
1661 std::string NewOpcode;
1663 NewOpcode = std::string(
Name);
1668 NewOpcode = std::string(
Name);
1674 size_t Dot =
Name.find(
'.');
1676 if (!NewOpcode.empty())
1678 PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
1680 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
1684 if (!NewOpcode.empty())
1686 PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
1688 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
1712 if (getSTI().hasFeature(PPC::FeatureBookE) &&
1714 (
Name ==
"dcbt" ||
Name ==
"dcbtst")) {
1720 if (
Name ==
"lqarx" ||
Name ==
"ldarx" ||
Name ==
"lwarx" ||
1721 Name ==
"lharx" ||
Name ==
"lbarx") {
1724 PPCOperand &EHOp = (PPCOperand &)*
Operands[4];
1725 if (EHOp.isU1Imm() && EHOp.getImm() == 0)
1733bool PPCAsmParser::ParseDirective(
AsmToken DirectiveID) {
1735 if (IDVal ==
".word")
1736 ParseDirectiveWord(2, DirectiveID);
1737 else if (IDVal ==
".llong")
1738 ParseDirectiveWord(8, DirectiveID);
1739 else if (IDVal ==
".tc")
1740 ParseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);
1741 else if (IDVal ==
".machine")
1742 ParseDirectiveMachine(DirectiveID.
getLoc());
1743 else if (IDVal ==
".abiversion")
1744 ParseDirectiveAbiVersion(DirectiveID.
getLoc());
1745 else if (IDVal ==
".localentry")
1746 ParseDirectiveLocalEntry(DirectiveID.
getLoc());
1748 ParseGNUAttribute(DirectiveID.
getLoc());
1756bool PPCAsmParser::ParseDirectiveWord(
unsigned Size,
AsmToken ID) {
1757 auto parseOp = [&]() ->
bool {
1759 SMLoc ExprLoc = getParser().getTok().getLoc();
1760 if (getParser().parseExpression(
Value))
1762 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value)) {
1764 uint64_t IntValue = MCE->getValue();
1766 return Error(ExprLoc,
"literal value out of range for '" +
1767 ID.getIdentifier() +
"' directive");
1768 getStreamer().emitIntValue(IntValue,
Size);
1770 getStreamer().emitValue(
Value,
Size, ExprLoc);
1774 if (parseMany(parseOp))
1775 return addErrorSuffix(
" in '" +
ID.getIdentifier() +
"' directive");
1788 return addErrorSuffix(
" in '.tc' directive");
1791 getParser().getStreamer().emitValueToAlignment(
Align(
Size));
1794 return ParseDirectiveWord(
Size,
ID);
1799bool PPCAsmParser::ParseDirectiveMachine(
SMLoc L) {
1803 return Error(L,
"unexpected token in '.machine' directive");
1814 return addErrorSuffix(
" in '.machine' directive");
1817 getParser().getStreamer().getTargetStreamer());
1818 if (TStreamer !=
nullptr)
1826bool PPCAsmParser::ParseDirectiveAbiVersion(
SMLoc L) {
1828 if (
check(getParser().parseAbsoluteExpression(AbiVersion), L,
1829 "expected constant expression") ||
1831 return addErrorSuffix(
" in '.abiversion' directive");
1834 getParser().getStreamer().getTargetStreamer());
1835 if (TStreamer !=
nullptr)
1843bool PPCAsmParser::ParseDirectiveLocalEntry(
SMLoc L) {
1845 if (getParser().parseIdentifier(
Name))
1846 return Error(L,
"expected identifier in '.localentry' directive");
1852 check(getParser().parseExpression(Expr), L,
"expected expression") ||
1854 return addErrorSuffix(
" in '.localentry' directive");
1857 getParser().getStreamer().getTargetStreamer());
1858 if (TStreamer !=
nullptr)
1864bool PPCAsmParser::ParseGNUAttribute(
SMLoc L) {
1866 int64_t IntegerValue;
1867 if (!getParser().parseGNUAttribute(L,
Tag, IntegerValue))
1870 getParser().getStreamer().emitGNUAttribute(
Tag, IntegerValue);
1883#define GET_REGISTER_MATCHER
1884#define GET_MATCHER_IMPLEMENTATION
1885#define GET_MNEMONIC_SPELL_CHECKER
1886#include "PPCGenAsmMatcher.inc"
1897 case MCK_0: ImmVal = 0;
break;
1898 case MCK_1: ImmVal = 1;
break;
1899 case MCK_2: ImmVal = 2;
break;
1900 case MCK_3: ImmVal = 3;
break;
1901 case MCK_4: ImmVal = 4;
break;
1902 case MCK_5: ImmVal = 5;
break;
1903 case MCK_6: ImmVal = 6;
break;
1904 case MCK_7: ImmVal = 7;
break;
1905 default:
return Match_InvalidOperand;
1908 PPCOperand &
Op =
static_cast<PPCOperand &
>(AsmOp);
1909 if (
Op.isU3Imm() &&
Op.getImm() == ImmVal)
1910 return Match_Success;
1912 return Match_InvalidOperand;
1916PPCAsmParser::applyModifierToExpr(
const MCExpr *
E,
static MCRegister 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 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,...