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; }
109 SMLoc &EndLoc)
override;
111 SMLoc &EndLoc)
override;
116 bool ParseExpression(
const MCExpr *&EVal);
122 bool ParseDirectiveMachine(
SMLoc L);
123 bool ParseDirectiveAbiVersion(
SMLoc L);
124 bool ParseDirectiveLocalEntry(
SMLoc L);
125 bool ParseGNUAttribute(
SMLoc L);
130 bool MatchingInlineAsm)
override;
137#define GET_ASSEMBLER_HEADER
138#include "PPCGenAsmMatcher.inc"
160 unsigned Kind)
override;
178 SMLoc StartLoc, EndLoc;
203 struct TLSRegOp TLSReg;
206 PPCOperand(KindTy K) :
Kind(
K) {}
211 StartLoc =
o.StartLoc;
219 case ContextImmediate:
233 void operator delete(
void *
p) { ::operator
delete(
p); }
236 SMLoc getStartLoc()
const override {
return StartLoc; }
239 SMLoc getEndLoc()
const override {
return EndLoc; }
246 bool isPPC64()
const {
return IsPPC64; }
248 int64_t getImm()
const {
249 assert(Kind == Immediate &&
"Invalid access!");
252 int64_t getImmS16Context()
const {
253 assert((Kind == Immediate || Kind == ContextImmediate) &&
255 if (Kind == Immediate)
257 return static_cast<int16_t
>(
Imm.Val);
259 int64_t getImmU16Context()
const {
260 assert((Kind == Immediate || Kind == ContextImmediate) &&
270 int64_t getExprCRVal()
const {
275 const MCExpr *getTLSReg()
const {
276 assert(Kind == TLSRegister &&
"Invalid access!");
280 unsigned getReg()
const override {
281 assert(isRegNumber() &&
"Invalid access!");
282 return (
unsigned)
Imm.Val;
285 unsigned getVSReg()
const {
286 assert(isVSRegNumber() &&
"Invalid access!");
287 return (
unsigned)
Imm.Val;
290 unsigned getACCReg()
const {
291 assert(isACCRegNumber() &&
"Invalid access!");
292 return (
unsigned)
Imm.Val;
295 unsigned getDMRROWReg()
const {
296 assert(isDMRROWRegNumber() &&
"Invalid access!");
297 return (
unsigned)
Imm.Val;
300 unsigned getDMRROWpReg()
const {
301 assert(isDMRROWpRegNumber() &&
"Invalid access!");
302 return (
unsigned)
Imm.Val;
305 unsigned getDMRReg()
const {
306 assert(isDMRRegNumber() &&
"Invalid access!");
307 return (
unsigned)
Imm.Val;
310 unsigned getDMRpReg()
const {
311 assert(isDMRpRegNumber() &&
"Invalid access!");
312 return (
unsigned)
Imm.Val;
315 unsigned getVSRpEvenReg()
const {
316 assert(isVSRpEvenRegNumber() &&
"Invalid access!");
317 return (
unsigned)
Imm.Val >> 1;
320 unsigned getG8pReg()
const {
321 assert(isEvenRegNumber() &&
"Invalid access!");
322 return (
unsigned)
Imm.Val;
325 unsigned getCCReg()
const {
326 assert(isCCRegNumber() &&
"Invalid access!");
327 return (
unsigned) (
Kind == Immediate ?
Imm.Val : Expr.CRVal);
330 unsigned getCRBit()
const {
331 assert(isCRBitNumber() &&
"Invalid access!");
332 return (
unsigned) (
Kind == Immediate ?
Imm.Val : Expr.CRVal);
335 unsigned getCRBitMask()
const {
336 assert(isCRBitMask() &&
"Invalid access!");
337 return 7 - llvm::countr_zero<uint64_t>(
Imm.Val);
340 bool isToken()
const override {
return Kind == Token; }
341 bool isImm()
const override {
344 bool isU1Imm()
const {
return Kind == Immediate && isUInt<1>(getImm()); }
345 bool isU2Imm()
const {
return Kind == Immediate && isUInt<2>(getImm()); }
346 bool isU3Imm()
const {
return Kind == Immediate && isUInt<3>(getImm()); }
347 bool isU4Imm()
const {
return Kind == Immediate && isUInt<4>(getImm()); }
348 bool isU5Imm()
const {
return Kind == Immediate && isUInt<5>(getImm()); }
349 bool isS5Imm()
const {
return Kind == Immediate && isInt<5>(getImm()); }
350 bool isU6Imm()
const {
return Kind == Immediate && isUInt<6>(getImm()); }
351 bool isU6ImmX2()
const {
return Kind == Immediate &&
352 isUInt<6>(getImm()) &&
353 (getImm() & 1) == 0; }
354 bool isU7Imm()
const {
return Kind == Immediate && isUInt<7>(getImm()); }
355 bool isU7ImmX4()
const {
return Kind == Immediate &&
356 isUInt<7>(getImm()) &&
357 (getImm() & 3) == 0; }
358 bool isU8Imm()
const {
return Kind == Immediate && isUInt<8>(getImm()); }
359 bool isU8ImmX8()
const {
return Kind == Immediate &&
360 isUInt<8>(getImm()) &&
361 (getImm() & 7) == 0; }
363 bool isU10Imm()
const {
return Kind == Immediate && isUInt<10>(getImm()); }
364 bool isU12Imm()
const {
return Kind == Immediate && isUInt<12>(getImm()); }
365 bool isU16Imm()
const {
return isExtImm<16>(
false, 1); }
366 bool isS16Imm()
const {
return isExtImm<16>(
true, 1); }
367 bool isS16ImmX4()
const {
return isExtImm<16>(
true, 4); }
368 bool isS16ImmX16()
const {
return isExtImm<16>(
true, 16); }
369 bool isS17Imm()
const {
return isExtImm<17>(
true, 1); }
371 bool isHashImmX8()
const {
375 return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&
376 (getImm() & 7) == 0);
379 bool isS34ImmX16()
const {
381 (
Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
383 bool isS34Imm()
const {
389 bool isTLSReg()
const {
return Kind == TLSRegister; }
390 bool isDirectBr()
const {
393 if (Kind != Immediate)
396 if ((getImm() & 3) != 0)
398 if (isInt<26>(getImm()))
402 if (isUInt<32>(getImm()) && isInt<26>(
static_cast<int32_t
>(getImm())))
408 (
Kind == Immediate && isInt<16>(getImm()) &&
409 (getImm() & 3) == 0); }
410 bool isImmZero()
const {
return Kind == Immediate && getImm() == 0; }
411 bool isRegNumber()
const {
return Kind == Immediate && isUInt<5>(getImm()); }
412 bool isACCRegNumber()
const {
413 return Kind == Immediate && isUInt<3>(getImm());
415 bool isDMRROWRegNumber()
const {
416 return Kind == Immediate && isUInt<6>(getImm());
418 bool isDMRROWpRegNumber()
const {
419 return Kind == Immediate && isUInt<5>(getImm());
421 bool isDMRRegNumber()
const {
422 return Kind == Immediate && isUInt<3>(getImm());
424 bool isDMRpRegNumber()
const {
425 return Kind == Immediate && isUInt<2>(getImm());
427 bool isVSRpEvenRegNumber()
const {
428 return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
430 bool isVSRegNumber()
const {
431 return Kind == Immediate && isUInt<6>(getImm());
433 bool isCCRegNumber()
const {
return (Kind ==
Expression
434 && isUInt<3>(getExprCRVal())) ||
436 && isUInt<3>(getImm())); }
437 bool isCRBitNumber()
const {
return (Kind ==
Expression
438 && isUInt<5>(getExprCRVal())) ||
440 && isUInt<5>(getImm())); }
442 bool isEvenRegNumber()
const {
return isRegNumber() && (getImm() & 1) == 0; }
444 bool isCRBitMask()
const {
445 return Kind == Immediate && isUInt<8>(getImm()) &&
446 llvm::has_single_bit<uint32_t>(getImm());
448 bool isATBitsAsHint()
const {
return false; }
449 bool isMem()
const override {
return false; }
450 bool isReg()
const override {
return false; }
452 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
456 void addRegGPRCOperands(
MCInst &Inst,
unsigned N)
const {
457 assert(
N == 1 &&
"Invalid number of operands!");
461 void addRegGPRCNoR0Operands(
MCInst &Inst,
unsigned N)
const {
462 assert(
N == 1 &&
"Invalid number of operands!");
466 void addRegG8RCOperands(
MCInst &Inst,
unsigned N)
const {
467 assert(
N == 1 &&
"Invalid number of operands!");
471 void addRegG8RCNoX0Operands(
MCInst &Inst,
unsigned N)
const {
472 assert(
N == 1 &&
"Invalid number of operands!");
476 void addRegG8pRCOperands(
MCInst &Inst,
unsigned N)
const {
477 assert(
N == 1 &&
"Invalid number of operands!");
481 void addRegGxRCOperands(
MCInst &Inst,
unsigned N)
const {
483 addRegG8RCOperands(Inst,
N);
485 addRegGPRCOperands(Inst,
N);
488 void addRegGxRCNoR0Operands(
MCInst &Inst,
unsigned N)
const {
490 addRegG8RCNoX0Operands(Inst,
N);
492 addRegGPRCNoR0Operands(Inst,
N);
495 void addRegF4RCOperands(
MCInst &Inst,
unsigned N)
const {
496 assert(
N == 1 &&
"Invalid number of operands!");
500 void addRegF8RCOperands(
MCInst &Inst,
unsigned N)
const {
501 assert(
N == 1 &&
"Invalid number of operands!");
505 void addRegVFRCOperands(
MCInst &Inst,
unsigned N)
const {
506 assert(
N == 1 &&
"Invalid number of operands!");
510 void addRegVRRCOperands(
MCInst &Inst,
unsigned N)
const {
511 assert(
N == 1 &&
"Invalid number of operands!");
515 void addRegVSRCOperands(
MCInst &Inst,
unsigned N)
const {
516 assert(
N == 1 &&
"Invalid number of operands!");
520 void addRegVSFRCOperands(
MCInst &Inst,
unsigned N)
const {
521 assert(
N == 1 &&
"Invalid number of operands!");
525 void addRegVSSRCOperands(
MCInst &Inst,
unsigned N)
const {
526 assert(
N == 1 &&
"Invalid number of operands!");
530 void addRegSPE4RCOperands(
MCInst &Inst,
unsigned N)
const {
531 assert(
N == 1 &&
"Invalid number of operands!");
535 void addRegSPERCOperands(
MCInst &Inst,
unsigned N)
const {
536 assert(
N == 1 &&
"Invalid number of operands!");
540 void addRegACCRCOperands(
MCInst &Inst,
unsigned N)
const {
541 assert(
N == 1 &&
"Invalid number of operands!");
545 void addRegDMRROWRCOperands(
MCInst &Inst,
unsigned N)
const {
546 assert(
N == 1 &&
"Invalid number of operands!");
550 void addRegDMRROWpRCOperands(
MCInst &Inst,
unsigned N)
const {
551 assert(
N == 1 &&
"Invalid number of operands!");
555 void addRegDMRRCOperands(
MCInst &Inst,
unsigned N)
const {
556 assert(
N == 1 &&
"Invalid number of operands!");
560 void addRegDMRpRCOperands(
MCInst &Inst,
unsigned N)
const {
561 assert(
N == 1 &&
"Invalid number of operands!");
565 void addRegWACCRCOperands(
MCInst &Inst,
unsigned N)
const {
566 assert(
N == 1 &&
"Invalid number of operands!");
570 void addRegWACC_HIRCOperands(
MCInst &Inst,
unsigned N)
const {
571 assert(
N == 1 &&
"Invalid number of operands!");
575 void addRegVSRpRCOperands(
MCInst &Inst,
unsigned N)
const {
576 assert(
N == 1 &&
"Invalid number of operands!");
580 void addRegVSRpEvenRCOperands(
MCInst &Inst,
unsigned N)
const {
581 assert(
N == 1 &&
"Invalid number of operands!");
585 void addRegCRBITRCOperands(
MCInst &Inst,
unsigned N)
const {
586 assert(
N == 1 &&
"Invalid number of operands!");
590 void addRegCRRCOperands(
MCInst &Inst,
unsigned N)
const {
591 assert(
N == 1 &&
"Invalid number of operands!");
595 void addCRBitMaskOperands(
MCInst &Inst,
unsigned N)
const {
596 assert(
N == 1 &&
"Invalid number of operands!");
600 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
601 assert(
N == 1 &&
"Invalid number of operands!");
602 if (Kind == Immediate)
608 void addS16ImmOperands(
MCInst &Inst,
unsigned N)
const {
609 assert(
N == 1 &&
"Invalid number of operands!");
614 case ContextImmediate:
623 void addU16ImmOperands(
MCInst &Inst,
unsigned N)
const {
624 assert(
N == 1 &&
"Invalid number of operands!");
629 case ContextImmediate:
638 void addBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
639 assert(
N == 1 &&
"Invalid number of operands!");
640 if (Kind == Immediate)
646 void addTLSRegOperands(
MCInst &Inst,
unsigned N)
const {
647 assert(
N == 1 &&
"Invalid number of operands!");
652 assert(Kind == Token &&
"Invalid access!");
658 static std::unique_ptr<PPCOperand> CreateToken(
StringRef Str,
SMLoc S,
660 auto Op = std::make_unique<PPCOperand>(Token);
661 Op->Tok.Data = Str.data();
662 Op->Tok.Length = Str.size();
665 Op->IsPPC64 = IsPPC64;
669 static std::unique_ptr<PPCOperand>
676 void *Mem = ::operator
new(
sizeof(PPCOperand) + Str.size());
677 std::unique_ptr<PPCOperand>
Op(
new (Mem) PPCOperand(Token));
678 Op->Tok.Data =
reinterpret_cast<const char *
>(
Op.get() + 1);
679 Op->Tok.Length = Str.size();
680 std::memcpy(
const_cast<char *
>(
Op->Tok.Data), Str.data(), Str.size());
683 Op->IsPPC64 = IsPPC64;
687 static std::unique_ptr<PPCOperand> CreateImm(int64_t Val,
SMLoc S,
SMLoc E,
689 auto Op = std::make_unique<PPCOperand>(Immediate);
693 Op->IsPPC64 = IsPPC64;
697 static std::unique_ptr<PPCOperand> CreateExpr(
const MCExpr *Val,
SMLoc S,
704 Op->IsPPC64 = IsPPC64;
708 static std::unique_ptr<PPCOperand>
710 auto Op = std::make_unique<PPCOperand>(TLSRegister);
711 Op->TLSReg.Sym = Sym;
714 Op->IsPPC64 = IsPPC64;
718 static std::unique_ptr<PPCOperand>
719 CreateContextImm(int64_t Val,
SMLoc S,
SMLoc E,
bool IsPPC64) {
720 auto Op = std::make_unique<PPCOperand>(ContextImmediate);
724 Op->IsPPC64 = IsPPC64;
728 static std::unique_ptr<PPCOperand>
731 return CreateImm(
CE->getValue(), S,
E, IsPPC64);
736 return CreateTLSReg(SRE, S,
E, IsPPC64);
738 if (
const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
740 if (
TE->evaluateAsConstant(Res))
741 return CreateContextImm(Res, S,
E, IsPPC64);
744 return CreateExpr(Val, S,
E, IsPPC64);
748 template <
unsigned W
idth>
749 bool isExtImm(
bool Signed,
unsigned Multiple)
const {
756 case ContextImmediate:
758 return isInt<Width>(getImmS16Context()) &&
759 (getImmS16Context() & (Multiple - 1)) == 0;
761 return isUInt<Width>(getImmU16Context()) &&
762 (getImmU16Context() & (Multiple - 1)) == 0;
772 OS <<
"'" << getToken() <<
"'";
775 case ContextImmediate:
793 const MCExpr *Expr = Op.getExpr();
794 if (
const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
799 }
else if (
const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
802 BinExpr->getLHS(), Ctx);
810void PPCAsmParser::ProcessInstruction(
MCInst &Inst,
819 TmpInst.
setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
820 PPC::DCBT : PPC::DCBTST);
822 (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
839 case PPC::DCBTSTDS: {
854 if (Opcode == PPC::DCBFL)
856 else if (Opcode == PPC::DCBFLP)
858 else if (Opcode == PPC::DCBFPS)
860 else if (Opcode == PPC::DCBSTPS)
907 case PPC::SUBIC_rec: {
917 case PPC::EXTLWI_rec: {
921 TmpInst.
setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
931 case PPC::EXTRWI_rec: {
935 TmpInst.
setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
945 case PPC::INSLWI_rec: {
949 TmpInst.
setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
960 case PPC::INSRWI_rec: {
964 TmpInst.
setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
975 case PPC::ROTRWI_rec: {
978 TmpInst.
setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
988 case PPC::SLWI_rec: {
991 TmpInst.
setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1001 case PPC::SRWI_rec: {
1004 TmpInst.
setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1014 case PPC::CLRRWI_rec: {
1017 TmpInst.
setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1027 case PPC::CLRLSLWI_rec: {
1031 TmpInst.
setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1041 case PPC::EXTLDI_rec: {
1045 TmpInst.
setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1054 case PPC::EXTRDI_rec: {
1058 TmpInst.
setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1067 case PPC::INSRDI_rec: {
1071 TmpInst.
setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
1081 case PPC::ROTRDI_rec: {
1084 TmpInst.
setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1093 case PPC::SLDI_rec: {
1096 TmpInst.
setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1104 case PPC::SUBPCIS: {
1114 case PPC::SRDI_rec: {
1117 TmpInst.
setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1126 case PPC::CLRRDI_rec: {
1129 TmpInst.
setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
1138 case PPC::CLRLSLDI_rec: {
1142 TmpInst.
setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
1151 case PPC::RLWINMbm_rec: {
1158 TmpInst.
setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
1168 case PPC::RLWIMIbm_rec: {
1175 TmpInst.
setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
1186 case PPC::RLWNMbm_rec: {
1193 TmpInst.
setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
1203 if (getSTI().hasFeature(PPC::FeatureMFTB)) {
1213 unsigned VariantID = 0);
1215bool PPCAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1218 bool MatchingInlineAsm) {
1224 ProcessInstruction(Inst,
Operands);
1228 case Match_MissingFeature:
1229 return Error(IDLoc,
"instruction use requires an option to be enabled");
1230 case Match_MnemonicFail: {
1231 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1233 ((PPCOperand &)*
Operands[0]).getToken(), FBS);
1234 return Error(IDLoc,
"invalid instruction" + Suggestion,
1235 ((PPCOperand &)*
Operands[0]).getLocRange());
1237 case Match_InvalidOperand: {
1238 SMLoc ErrorLoc = IDLoc;
1241 return Error(IDLoc,
"too few operands for instruction");
1244 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
1247 return Error(ErrorLoc,
"invalid operand for instruction");
1254bool PPCAsmParser::MatchRegisterName(
MCRegister &RegNo, int64_t &IntVal) {
1262 if (
Name.equals_insensitive(
"lr")) {
1263 RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
1265 }
else if (
Name.equals_insensitive(
"ctr")) {
1266 RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
1268 }
else if (
Name.equals_insensitive(
"vrsave")) {
1269 RegNo = PPC::VRSAVE;
1271 }
else if (
Name.startswith_insensitive(
"r") &&
1272 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1274 }
else if (
Name.startswith_insensitive(
"f") &&
1275 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1277 }
else if (
Name.startswith_insensitive(
"vs") &&
1278 !
Name.substr(2).getAsInteger(10, IntVal) && IntVal < 64) {
1280 }
else if (
Name.startswith_insensitive(
"v") &&
1281 !
Name.substr(1).getAsInteger(10, IntVal) && IntVal < 32) {
1283 }
else if (
Name.startswith_insensitive(
"cr") &&
1284 !
Name.substr(2).getAsInteger(10, IntVal) && IntVal < 8) {
1286 }
else if (
Name.startswith_insensitive(
"acc") &&
1287 !
Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1289 }
else if (
Name.startswith_insensitive(
"wacc_hi") &&
1290 !
Name.substr(7).getAsInteger(10, IntVal) && IntVal < 8) {
1292 }
else if (
Name.startswith_insensitive(
"wacc") &&
1293 !
Name.substr(4).getAsInteger(10, IntVal) && IntVal < 8) {
1294 RegNo = WACCRegs[
IntVal];
1295 }
else if (
Name.startswith_insensitive(
"dmrrowp") &&
1296 !
Name.substr(7).getAsInteger(10, IntVal) && IntVal < 32) {
1297 RegNo = DMRROWpRegs[
IntVal];
1298 }
else if (
Name.startswith_insensitive(
"dmrrow") &&
1299 !
Name.substr(6).getAsInteger(10, IntVal) && IntVal < 64) {
1300 RegNo = DMRROWRegs[
IntVal];
1301 }
else if (
Name.startswith_insensitive(
"dmrp") &&
1302 !
Name.substr(4).getAsInteger(10, IntVal) && IntVal < 4) {
1303 RegNo = DMRROWpRegs[
IntVal];
1304 }
else if (
Name.startswith_insensitive(
"dmr") &&
1305 !
Name.substr(3).getAsInteger(10, IntVal) && IntVal < 8) {
1316 return TokError(
"invalid register name");
1323 const AsmToken &Tok = getParser().getTok();
1339const MCExpr *PPCAsmParser::
1340ExtractModifierFromExpr(
const MCExpr *
E,
1345 switch (
E->getKind()) {
1399 const MCExpr *
LHS = ExtractModifierFromExpr(BE->
getLHS(), LHSVariant);
1400 const MCExpr *
RHS = ExtractModifierFromExpr(BE->
getRHS(), RHSVariant);
1412 else if (LHSVariant == RHSVariant)
1428const MCExpr *PPCAsmParser::
1429FixupVariantKind(
const MCExpr *
E) {
1432 switch (
E->getKind()) {
1478ParseExpression(
const MCExpr *&EVal) {
1481 if (getParser().parseExpression(EVal))
1484 EVal = FixupVariantKind(EVal);
1487 const MCExpr *
E = ExtractModifierFromExpr(EVal, Variant);
1504 switch (getLexer().getKind()) {
1511 return Error(S,
"invalid register name");
1513 Operands.push_back(PPCOperand::CreateImm(IntVal, S,
E, isPPC64()));
1525 if (!ParseExpression(EVal))
1530 return Error(S,
"unknown operand");
1534 Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S,
E, isPPC64()));
1537 bool TLSCall =
false;
1539 TLSCall =
Ref->getSymbol().getName() ==
"__tls_get_addr";
1546 if (ParseExpression(TLSSym))
1547 return Error(S,
"invalid TLS call expression");
1553 Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S,
E, isPPC64()));
1562 switch (getLexer().getKind()) {
1566 return Error(S,
"invalid register name");
1570 if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
1572 return Error(S,
"invalid register number");
1576 return Error(S,
"invalid memory operand");
1582 Operands.push_back(PPCOperand::CreateImm(IntVal, S,
E, isPPC64()));
1594 std::string NewOpcode;
1596 NewOpcode = std::string(
Name);
1601 NewOpcode = std::string(
Name);
1607 size_t Dot =
Name.find(
'.');
1609 if (!NewOpcode.empty())
1611 PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
1613 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
1617 if (!NewOpcode.empty())
1619 PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
1621 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
1645 if (getSTI().hasFeature(PPC::FeatureBookE) &&
1647 (
Name ==
"dcbt" ||
Name ==
"dcbtst")) {
1653 if (
Name ==
"lqarx" ||
Name ==
"ldarx" ||
Name ==
"lwarx" ||
1654 Name ==
"lharx" ||
Name ==
"lbarx") {
1657 PPCOperand &EHOp = (PPCOperand &)*
Operands[4];
1658 if (EHOp.isU1Imm() && EHOp.getImm() == 0)
1666bool PPCAsmParser::ParseDirective(
AsmToken DirectiveID) {
1668 if (IDVal ==
".word")
1669 ParseDirectiveWord(2, DirectiveID);
1670 else if (IDVal ==
".llong")
1671 ParseDirectiveWord(8, DirectiveID);
1672 else if (IDVal ==
".tc")
1673 ParseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);
1674 else if (IDVal ==
".machine")
1675 ParseDirectiveMachine(DirectiveID.
getLoc());
1676 else if (IDVal ==
".abiversion")
1677 ParseDirectiveAbiVersion(DirectiveID.
getLoc());
1678 else if (IDVal ==
".localentry")
1679 ParseDirectiveLocalEntry(DirectiveID.
getLoc());
1681 ParseGNUAttribute(DirectiveID.
getLoc());
1689bool PPCAsmParser::ParseDirectiveWord(
unsigned Size,
AsmToken ID) {
1690 auto parseOp = [&]() ->
bool {
1692 SMLoc ExprLoc = getParser().getTok().getLoc();
1693 if (getParser().parseExpression(
Value))
1695 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value)) {
1697 uint64_t IntValue = MCE->getValue();
1699 return Error(ExprLoc,
"literal value out of range for '" +
1700 ID.getIdentifier() +
"' directive");
1701 getStreamer().emitIntValue(IntValue,
Size);
1703 getStreamer().emitValue(
Value,
Size, ExprLoc);
1707 if (parseMany(parseOp))
1708 return addErrorSuffix(
" in '" +
ID.getIdentifier() +
"' directive");
1721 return addErrorSuffix(
" in '.tc' directive");
1724 getParser().getStreamer().emitValueToAlignment(
Align(
Size));
1727 return ParseDirectiveWord(
Size,
ID);
1732bool PPCAsmParser::ParseDirectiveMachine(
SMLoc L) {
1736 return Error(L,
"unexpected token in '.machine' directive");
1747 return addErrorSuffix(
" in '.machine' directive");
1750 getParser().getStreamer().getTargetStreamer());
1751 if (TStreamer !=
nullptr)
1759bool PPCAsmParser::ParseDirectiveAbiVersion(
SMLoc L) {
1761 if (
check(getParser().parseAbsoluteExpression(AbiVersion), L,
1762 "expected constant expression") ||
1764 return addErrorSuffix(
" in '.abiversion' directive");
1767 getParser().getStreamer().getTargetStreamer());
1768 if (TStreamer !=
nullptr)
1776bool PPCAsmParser::ParseDirectiveLocalEntry(
SMLoc L) {
1778 if (getParser().parseIdentifier(
Name))
1779 return Error(L,
"expected identifier in '.localentry' directive");
1781 MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
Name));
1785 check(getParser().parseExpression(Expr), L,
"expected expression") ||
1787 return addErrorSuffix(
" in '.localentry' directive");
1790 getParser().getStreamer().getTargetStreamer());
1791 if (TStreamer !=
nullptr)
1797bool PPCAsmParser::ParseGNUAttribute(
SMLoc L) {
1799 int64_t IntegerValue;
1800 if (!getParser().parseGNUAttribute(L,
Tag, IntegerValue))
1803 getParser().getStreamer().emitGNUAttribute(
Tag, IntegerValue);
1816#define GET_REGISTER_MATCHER
1817#define GET_MATCHER_IMPLEMENTATION
1818#define GET_MNEMONIC_SPELL_CHECKER
1819#include "PPCGenAsmMatcher.inc"
1830 case MCK_0: ImmVal = 0;
break;
1831 case MCK_1: ImmVal = 1;
break;
1832 case MCK_2: ImmVal = 2;
break;
1833 case MCK_3: ImmVal = 3;
break;
1834 case MCK_4: ImmVal = 4;
break;
1835 case MCK_5: ImmVal = 5;
break;
1836 case MCK_6: ImmVal = 6;
break;
1837 case MCK_7: ImmVal = 7;
break;
1838 default:
return Match_InvalidOperand;
1841 PPCOperand &Op =
static_cast<PPCOperand &
>(AsmOp);
1842 if (Op.isU3Imm() && Op.getImm() == ImmVal)
1843 return Match_Success;
1845 return Match_InvalidOperand;
1849PPCAsmParser::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 getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
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.
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 ParseDirective(AsmToken DirectiveID)=0
ParseDirective - Parse a target specific assembler directive.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
void setAvailableFeatures(const FeatureBitset &Value)
virtual const MCExpr * applyModifierToExpr(const MCExpr *E, MCSymbolRefExpr::VariantKind, MCContext &Ctx)
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
virtual OperandMatchResultTy tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
Unary assembler expressions.
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)
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
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
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)
@ 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.
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,...