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; }
106 MCRegister matchRegisterName(int64_t &IntVal);
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"
146 IsPPC64(STI.getTargetTriple().isPPC64()) {
157 unsigned Kind)
override;
175 SMLoc StartLoc, EndLoc;
201 struct TLSRegOp TLSReg;
204 PPCOperand(KindTy K) :
Kind(
K) {}
209 StartLoc =
o.StartLoc;
217 case ContextImmediate:
231 void operator delete(
void *
p) { ::operator
delete(
p); }
234 SMLoc getStartLoc()
const override {
return StartLoc; }
237 SMLoc getEndLoc()
const override {
return EndLoc; }
244 bool isPPC64()
const {
return IsPPC64; }
247 bool isMemOpBase()
const {
return Kind == Immediate &&
Imm.IsMemOpBase; }
249 int64_t getImm()
const {
250 assert(Kind == Immediate &&
"Invalid access!");
253 int64_t getImmS16Context()
const {
254 assert((Kind == Immediate || Kind == ContextImmediate) &&
256 if (Kind == Immediate)
258 return static_cast<int16_t
>(
Imm.Val);
260 int64_t getImmU16Context()
const {
261 assert((Kind == Immediate || Kind == ContextImmediate) &&
271 int64_t getExprCRVal()
const {
276 const MCExpr *getTLSReg()
const {
277 assert(Kind == TLSRegister &&
"Invalid access!");
284 assert(isRegNumber() &&
"Invalid access!");
285 return (
unsigned)
Imm.Val;
288 unsigned getFpReg()
const {
289 assert(isEvenRegNumber() &&
"Invalid access!");
290 return (
unsigned)(
Imm.Val >> 1);
293 unsigned getVSReg()
const {
294 assert(isVSRegNumber() &&
"Invalid access!");
295 return (
unsigned)
Imm.Val;
298 unsigned getACCReg()
const {
299 assert(isACCRegNumber() &&
"Invalid access!");
300 return (
unsigned)
Imm.Val;
303 unsigned getDMRROWReg()
const {
304 assert(isDMRROWRegNumber() &&
"Invalid access!");
305 return (
unsigned)
Imm.Val;
308 unsigned getDMRROWpReg()
const {
309 assert(isDMRROWpRegNumber() &&
"Invalid access!");
310 return (
unsigned)
Imm.Val;
313 unsigned getDMRReg()
const {
314 assert(isDMRRegNumber() &&
"Invalid access!");
315 return (
unsigned)
Imm.Val;
318 unsigned getDMRpReg()
const {
319 assert(isDMRpRegNumber() &&
"Invalid access!");
320 return (
unsigned)
Imm.Val;
323 unsigned getVSRpEvenReg()
const {
324 assert(isVSRpEvenRegNumber() &&
"Invalid access!");
325 return (
unsigned)
Imm.Val >> 1;
328 unsigned getG8pReg()
const {
329 assert(isEvenRegNumber() &&
"Invalid access!");
330 return (
unsigned)
Imm.Val;
333 unsigned getCCReg()
const {
334 assert(isCCRegNumber() &&
"Invalid access!");
335 return (
unsigned) (
Kind == Immediate ?
Imm.Val : Expr.CRVal);
338 unsigned getCRBit()
const {
339 assert(isCRBitNumber() &&
"Invalid access!");
340 return (
unsigned) (
Kind == Immediate ?
Imm.Val : Expr.CRVal);
343 unsigned getCRBitMask()
const {
344 assert(isCRBitMask() &&
"Invalid access!");
345 return 7 - llvm::countr_zero<uint64_t>(
Imm.Val);
348 bool isToken()
const override {
return Kind == Token; }
349 bool isImm()
const override {
352 bool isU1Imm()
const {
return Kind == Immediate && isUInt<1>(getImm()); }
353 bool isU2Imm()
const {
return Kind == Immediate && isUInt<2>(getImm()); }
354 bool isU3Imm()
const {
return Kind == Immediate && isUInt<3>(getImm()); }
355 bool isU4Imm()
const {
return Kind == Immediate && isUInt<4>(getImm()); }
356 bool isU5Imm()
const {
return Kind == Immediate && isUInt<5>(getImm()); }
357 bool isS5Imm()
const {
return Kind == Immediate && isInt<5>(getImm()); }
358 bool isU6Imm()
const {
return Kind == Immediate && isUInt<6>(getImm()); }
359 bool isU6ImmX2()
const {
return Kind == Immediate &&
360 isUInt<6>(getImm()) &&
361 (getImm() & 1) == 0; }
362 bool isU7Imm()
const {
return Kind == Immediate && isUInt<7>(getImm()); }
363 bool isU7ImmX4()
const {
return Kind == Immediate &&
364 isUInt<7>(getImm()) &&
365 (getImm() & 3) == 0; }
366 bool isU8Imm()
const {
return Kind == Immediate && isUInt<8>(getImm()); }
367 bool isU8ImmX8()
const {
return Kind == Immediate &&
368 isUInt<8>(getImm()) &&
369 (getImm() & 7) == 0; }
371 bool isU10Imm()
const {
return Kind == Immediate && isUInt<10>(getImm()); }
372 bool isU12Imm()
const {
return Kind == Immediate && isUInt<12>(getImm()); }
373 bool isU16Imm()
const {
return isExtImm<16>(
false, 1); }
374 bool isS16Imm()
const {
return isExtImm<16>(
true, 1); }
375 bool isS16ImmX4()
const {
return isExtImm<16>(
true, 4); }
376 bool isS16ImmX16()
const {
return isExtImm<16>(
true, 16); }
377 bool isS17Imm()
const {
return isExtImm<17>(
true, 1); }
379 bool isHashImmX8()
const {
383 return (Kind == Immediate && getImm() <= -8 && getImm() >= -512 &&
384 (getImm() & 7) == 0);
387 bool isS34ImmX16()
const {
389 (
Kind == Immediate && isInt<34>(getImm()) && (getImm() & 15) == 0);
391 bool isS34Imm()
const {
397 bool isTLSReg()
const {
return Kind == TLSRegister; }
398 bool isDirectBr()
const {
401 if (Kind != Immediate)
404 if ((getImm() & 3) != 0)
406 if (isInt<26>(getImm()))
410 if (isUInt<32>(getImm()) && isInt<26>(
static_cast<int32_t
>(getImm())))
416 (
Kind == Immediate && isInt<16>(getImm()) &&
417 (getImm() & 3) == 0); }
418 bool isImmZero()
const {
return Kind == Immediate && getImm() == 0; }
419 bool isRegNumber()
const {
return Kind == Immediate && isUInt<5>(getImm()); }
420 bool isACCRegNumber()
const {
421 return Kind == Immediate && isUInt<3>(getImm());
423 bool isDMRROWRegNumber()
const {
424 return Kind == Immediate && isUInt<6>(getImm());
426 bool isDMRROWpRegNumber()
const {
427 return Kind == Immediate && isUInt<5>(getImm());
429 bool isDMRRegNumber()
const {
430 return Kind == Immediate && isUInt<3>(getImm());
432 bool isDMRpRegNumber()
const {
433 return Kind == Immediate && isUInt<2>(getImm());
435 bool isVSRpEvenRegNumber()
const {
436 return Kind == Immediate && isUInt<6>(getImm()) && ((getImm() & 1) == 0);
438 bool isVSRegNumber()
const {
439 return Kind == Immediate && isUInt<6>(getImm());
441 bool isCCRegNumber()
const {
return (Kind ==
Expression
442 && isUInt<3>(getExprCRVal())) ||
444 && isUInt<3>(getImm())); }
445 bool isCRBitNumber()
const {
return (Kind ==
Expression
446 && isUInt<5>(getExprCRVal())) ||
448 && isUInt<5>(getImm())); }
450 bool isEvenRegNumber()
const {
return isRegNumber() && (getImm() & 1) == 0; }
452 bool isCRBitMask()
const {
453 return Kind == Immediate && isUInt<8>(getImm()) &&
454 llvm::has_single_bit<uint32_t>(getImm());
456 bool isATBitsAsHint()
const {
return false; }
457 bool isMem()
const override {
return false; }
458 bool isReg()
const override {
return false; }
460 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
464 void addRegGPRCOperands(
MCInst &Inst,
unsigned N)
const {
465 assert(
N == 1 &&
"Invalid number of operands!");
469 void addRegGPRCNoR0Operands(
MCInst &Inst,
unsigned N)
const {
470 assert(
N == 1 &&
"Invalid number of operands!");
474 void addRegG8RCOperands(
MCInst &Inst,
unsigned N)
const {
475 assert(
N == 1 &&
"Invalid number of operands!");
479 void addRegG8RCNoX0Operands(
MCInst &Inst,
unsigned N)
const {
480 assert(
N == 1 &&
"Invalid number of operands!");
484 void addRegG8pRCOperands(
MCInst &Inst,
unsigned N)
const {
485 assert(
N == 1 &&
"Invalid number of operands!");
489 void addRegGxRCOperands(
MCInst &Inst,
unsigned N)
const {
491 addRegG8RCOperands(Inst,
N);
493 addRegGPRCOperands(Inst,
N);
496 void addRegGxRCNoR0Operands(
MCInst &Inst,
unsigned N)
const {
498 addRegG8RCNoX0Operands(Inst,
N);
500 addRegGPRCNoR0Operands(Inst,
N);
503 void addRegF4RCOperands(
MCInst &Inst,
unsigned N)
const {
504 assert(
N == 1 &&
"Invalid number of operands!");
508 void addRegF8RCOperands(
MCInst &Inst,
unsigned N)
const {
509 assert(
N == 1 &&
"Invalid number of operands!");
513 void addRegFpRCOperands(
MCInst &Inst,
unsigned N)
const {
514 assert(
N == 1 &&
"Invalid number of operands!");
518 void addRegVFRCOperands(
MCInst &Inst,
unsigned N)
const {
519 assert(
N == 1 &&
"Invalid number of operands!");
523 void addRegVRRCOperands(
MCInst &Inst,
unsigned N)
const {
524 assert(
N == 1 &&
"Invalid number of operands!");
528 void addRegVSRCOperands(
MCInst &Inst,
unsigned N)
const {
529 assert(
N == 1 &&
"Invalid number of operands!");
533 void addRegVSFRCOperands(
MCInst &Inst,
unsigned N)
const {
534 assert(
N == 1 &&
"Invalid number of operands!");
538 void addRegVSSRCOperands(
MCInst &Inst,
unsigned N)
const {
539 assert(
N == 1 &&
"Invalid number of operands!");
543 void addRegSPE4RCOperands(
MCInst &Inst,
unsigned N)
const {
544 assert(
N == 1 &&
"Invalid number of operands!");
548 void addRegSPERCOperands(
MCInst &Inst,
unsigned N)
const {
549 assert(
N == 1 &&
"Invalid number of operands!");
553 void addRegACCRCOperands(
MCInst &Inst,
unsigned N)
const {
554 assert(
N == 1 &&
"Invalid number of operands!");
558 void addRegDMRROWRCOperands(
MCInst &Inst,
unsigned N)
const {
559 assert(
N == 1 &&
"Invalid number of operands!");
563 void addRegDMRROWpRCOperands(
MCInst &Inst,
unsigned N)
const {
564 assert(
N == 1 &&
"Invalid number of operands!");
568 void addRegDMRRCOperands(
MCInst &Inst,
unsigned N)
const {
569 assert(
N == 1 &&
"Invalid number of operands!");
573 void addRegDMRpRCOperands(
MCInst &Inst,
unsigned N)
const {
574 assert(
N == 1 &&
"Invalid number of operands!");
578 void addRegWACCRCOperands(
MCInst &Inst,
unsigned N)
const {
579 assert(
N == 1 &&
"Invalid number of operands!");
583 void addRegWACC_HIRCOperands(
MCInst &Inst,
unsigned N)
const {
584 assert(
N == 1 &&
"Invalid number of operands!");
588 void addRegVSRpRCOperands(
MCInst &Inst,
unsigned N)
const {
589 assert(
N == 1 &&
"Invalid number of operands!");
593 void addRegVSRpEvenRCOperands(
MCInst &Inst,
unsigned N)
const {
594 assert(
N == 1 &&
"Invalid number of operands!");
598 void addRegCRBITRCOperands(
MCInst &Inst,
unsigned N)
const {
599 assert(
N == 1 &&
"Invalid number of operands!");
603 void addRegCRRCOperands(
MCInst &Inst,
unsigned N)
const {
604 assert(
N == 1 &&
"Invalid number of operands!");
608 void addCRBitMaskOperands(
MCInst &Inst,
unsigned N)
const {
609 assert(
N == 1 &&
"Invalid number of operands!");
613 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
614 assert(
N == 1 &&
"Invalid number of operands!");
615 if (Kind == Immediate)
621 void addS16ImmOperands(
MCInst &Inst,
unsigned N)
const {
622 assert(
N == 1 &&
"Invalid number of operands!");
627 case ContextImmediate:
636 void addU16ImmOperands(
MCInst &Inst,
unsigned N)
const {
637 assert(
N == 1 &&
"Invalid number of operands!");
642 case ContextImmediate:
651 void addBranchTargetOperands(
MCInst &Inst,
unsigned N)
const {
652 assert(
N == 1 &&
"Invalid number of operands!");
653 if (Kind == Immediate)
659 void addTLSRegOperands(
MCInst &Inst,
unsigned N)
const {
660 assert(
N == 1 &&
"Invalid number of operands!");
665 assert(Kind == Token &&
"Invalid access!");
671 static std::unique_ptr<PPCOperand> CreateToken(
StringRef Str,
SMLoc S,
673 auto Op = std::make_unique<PPCOperand>(Token);
674 Op->Tok.Data = Str.data();
675 Op->Tok.Length = Str.size();
678 Op->IsPPC64 = IsPPC64;
682 static std::unique_ptr<PPCOperand>
689 void *Mem = ::operator
new(
sizeof(PPCOperand) + Str.size());
690 std::unique_ptr<PPCOperand>
Op(
new (Mem) PPCOperand(Token));
691 Op->Tok.Data =
reinterpret_cast<const char *
>(
Op.get() + 1);
692 Op->Tok.Length = Str.size();
693 std::memcpy(
const_cast<char *
>(
Op->Tok.Data), Str.data(), Str.size());
696 Op->IsPPC64 = IsPPC64;
700 static std::unique_ptr<PPCOperand> CreateImm(int64_t Val,
SMLoc S,
SMLoc E,
702 bool IsMemOpBase =
false) {
703 auto Op = std::make_unique<PPCOperand>(Immediate);
705 Op->Imm.IsMemOpBase = IsMemOpBase;
708 Op->IsPPC64 = IsPPC64;
712 static std::unique_ptr<PPCOperand> CreateExpr(
const MCExpr *Val,
SMLoc S,
719 Op->IsPPC64 = IsPPC64;
723 static std::unique_ptr<PPCOperand>
725 auto Op = std::make_unique<PPCOperand>(TLSRegister);
726 Op->TLSReg.Sym =
Sym;
729 Op->IsPPC64 = IsPPC64;
733 static std::unique_ptr<PPCOperand>
734 CreateContextImm(int64_t Val,
SMLoc S,
SMLoc E,
bool IsPPC64) {
735 auto Op = std::make_unique<PPCOperand>(ContextImmediate);
739 Op->IsPPC64 = IsPPC64;
743 static std::unique_ptr<PPCOperand>
746 return CreateImm(
CE->getValue(), S,
E, IsPPC64);
751 return CreateTLSReg(SRE, S,
E, IsPPC64);
753 if (
const PPCMCExpr *TE = dyn_cast<PPCMCExpr>(Val)) {
755 if (
TE->evaluateAsConstant(Res))
756 return CreateContextImm(Res, S,
E, IsPPC64);
759 return CreateExpr(Val, S,
E, IsPPC64);
763 template <
unsigned W
idth>
764 bool isExtImm(
bool Signed,
unsigned Multiple)
const {
771 case ContextImmediate:
773 return isInt<Width>(getImmS16Context()) &&
774 (getImmS16Context() & (Multiple - 1)) == 0;
776 return isUInt<Width>(getImmU16Context()) &&
777 (getImmU16Context() & (Multiple - 1)) == 0;
787 OS <<
"'" << getToken() <<
"'";
790 case ContextImmediate:
809 if (
const MCUnaryExpr *UnExpr = dyn_cast<MCUnaryExpr>(Expr)) {
814 }
else if (
const MCBinaryExpr *BinExpr = dyn_cast<MCBinaryExpr>(Expr)) {
817 BinExpr->getLHS(), Ctx);
825void PPCAsmParser::processInstruction(
MCInst &Inst,
834 TmpInst.
setOpcode((Opcode == PPC::DCBTx || Opcode == PPC::DCBTT) ?
835 PPC::DCBT : PPC::DCBTST);
837 (Opcode == PPC::DCBTx || Opcode == PPC::DCBTSTx) ? 0 : 16));
854 case PPC::DCBTSTDS: {
869 if (Opcode == PPC::DCBFL)
871 else if (Opcode == PPC::DCBFLP)
873 else if (Opcode == PPC::DCBFPS)
875 else if (Opcode == PPC::DCBSTPS)
898 TmpInst.
setOpcode(Opcode == PPC::PLA ? PPC::PADDI : PPC::PADDI8);
908 TmpInst.
setOpcode(Opcode == PPC::PLApc ? PPC::PADDIpc : PPC::PADDI8pc);
951 case PPC::SUBIC_rec: {
961 case PPC::EXTLWI_rec: {
965 TmpInst.
setOpcode(Opcode == PPC::EXTLWI ? PPC::RLWINM : PPC::RLWINM_rec);
975 case PPC::EXTRWI_rec: {
979 TmpInst.
setOpcode(Opcode == PPC::EXTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
989 case PPC::INSLWI_rec: {
993 TmpInst.
setOpcode(Opcode == PPC::INSLWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
1004 case PPC::INSRWI_rec: {
1008 TmpInst.
setOpcode(Opcode == PPC::INSRWI ? PPC::RLWIMI : PPC::RLWIMI_rec);
1019 case PPC::ROTRWI_rec: {
1022 TmpInst.
setOpcode(Opcode == PPC::ROTRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1032 case PPC::SLWI_rec: {
1035 TmpInst.
setOpcode(Opcode == PPC::SLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1045 case PPC::SRWI_rec: {
1048 TmpInst.
setOpcode(Opcode == PPC::SRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1058 case PPC::CLRRWI_rec: {
1061 TmpInst.
setOpcode(Opcode == PPC::CLRRWI ? PPC::RLWINM : PPC::RLWINM_rec);
1071 case PPC::CLRLSLWI_rec: {
1075 TmpInst.
setOpcode(Opcode == PPC::CLRLSLWI ? PPC::RLWINM : PPC::RLWINM_rec);
1085 case PPC::EXTLDI_rec: {
1089 TmpInst.
setOpcode(Opcode == PPC::EXTLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1098 case PPC::EXTRDI_rec: {
1102 TmpInst.
setOpcode(Opcode == PPC::EXTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1111 case PPC::INSRDI_rec: {
1115 TmpInst.
setOpcode(Opcode == PPC::INSRDI ? PPC::RLDIMI : PPC::RLDIMI_rec);
1125 case PPC::ROTRDI_rec: {
1128 TmpInst.
setOpcode(Opcode == PPC::ROTRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1137 case PPC::SLDI_rec: {
1140 TmpInst.
setOpcode(Opcode == PPC::SLDI ? PPC::RLDICR : PPC::RLDICR_rec);
1148 case PPC::SUBPCIS: {
1158 case PPC::SRDI_rec: {
1161 TmpInst.
setOpcode(Opcode == PPC::SRDI ? PPC::RLDICL : PPC::RLDICL_rec);
1170 case PPC::CLRRDI_rec: {
1173 TmpInst.
setOpcode(Opcode == PPC::CLRRDI ? PPC::RLDICR : PPC::RLDICR_rec);
1182 case PPC::CLRLSLDI_rec: {
1186 TmpInst.
setOpcode(Opcode == PPC::CLRLSLDI ? PPC::RLDIC : PPC::RLDIC_rec);
1195 case PPC::RLWINMbm_rec: {
1202 TmpInst.
setOpcode(Opcode == PPC::RLWINMbm ? PPC::RLWINM : PPC::RLWINM_rec);
1212 case PPC::RLWIMIbm_rec: {
1219 TmpInst.
setOpcode(Opcode == PPC::RLWIMIbm ? PPC::RLWIMI : PPC::RLWIMI_rec);
1230 case PPC::RLWNMbm_rec: {
1237 TmpInst.
setOpcode(Opcode == PPC::RLWNMbm ? PPC::RLWNM : PPC::RLWNM_rec);
1247 if (getSTI().hasFeature(PPC::FeatureMFTB)) {
1257 unsigned VariantID = 0);
1263 for (
size_t idx = 0; idx <
Operands.size(); ++idx) {
1264 const PPCOperand &
Op =
static_cast<const PPCOperand &
>(*
Operands[idx]);
1265 if (
Op.isMemOpBase() != (idx == 3 && isMemriOp))
1271bool PPCAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1274 bool MatchingInlineAsm) {
1281 return Error(IDLoc,
"invalid operand for instruction");
1283 processInstruction(Inst,
Operands);
1287 case Match_MissingFeature:
1288 return Error(IDLoc,
"instruction use requires an option to be enabled");
1289 case Match_MnemonicFail: {
1290 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1292 ((PPCOperand &)*
Operands[0]).getToken(), FBS);
1293 return Error(IDLoc,
"invalid instruction" + Suggestion,
1294 ((PPCOperand &)*
Operands[0]).getLocRange());
1296 case Match_InvalidOperand: {
1297 SMLoc ErrorLoc = IDLoc;
1300 return Error(IDLoc,
"too few operands for instruction");
1303 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
1306 return Error(ErrorLoc,
"invalid operand for instruction");
1313#define GET_REGISTER_MATCHER
1314#include "PPCGenAsmMatcher.inc"
1316MCRegister PPCAsmParser::matchRegisterName(int64_t &IntVal) {
1328 Name.substr(
Name.find_first_of(
"1234567890")).getAsInteger(10, IntVal);
1332 if (
Name.equals_insensitive(
"lr")) {
1333 RegNo = isPPC64() ? PPC::LR8 : PPC::LR;
1335 }
else if (
Name.equals_insensitive(
"ctr")) {
1336 RegNo = isPPC64() ? PPC::CTR8 : PPC::CTR;
1338 }
else if (
Name.equals_insensitive(
"vrsave"))
1340 else if (
Name.starts_with_insensitive(
"r"))
1341 RegNo = isPPC64() ? XRegs[IntVal] : RRegs[IntVal];
1349 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1350 return TokError(
"invalid register name");
1356 const AsmToken &Tok = getParser().getTok();
1360 if (!(
Reg = matchRegisterName(IntVal)))
1372PPCAsmParser::extractModifierFromExpr(
const MCExpr *
E,
1374 MCContext &Context = getParser().getContext();
1377 switch (
E->getKind()) {
1431 const MCExpr *
LHS = extractModifierFromExpr(BE->
getLHS(), LHSVariant);
1432 const MCExpr *
RHS = extractModifierFromExpr(BE->
getRHS(), RHSVariant);
1444 else if (LHSVariant == RHSVariant)
1460const MCExpr *PPCAsmParser::fixupVariantKind(
const MCExpr *
E) {
1461 MCContext &Context = getParser().getContext();
1463 switch (
E->getKind()) {
1508bool PPCAsmParser::parseExpression(
const MCExpr *&EVal) {
1511 if (getParser().parseExpression(EVal))
1514 EVal = fixupVariantKind(EVal);
1517 const MCExpr *
E = extractModifierFromExpr(EVal, Variant);
1533 switch (getLexer().getKind()) {
1538 if (!matchRegisterName(IntVal))
1539 return Error(S,
"invalid register name");
1541 Operands.push_back(PPCOperand::CreateImm(IntVal, S,
E, isPPC64()));
1553 if (!parseExpression(EVal))
1558 return Error(S,
"unknown operand");
1562 Operands.push_back(PPCOperand::CreateFromMCExpr(EVal, S,
E, isPPC64()));
1565 const char TlsGetAddr[] =
"__tls_get_addr";
1566 bool TlsCall =
false;
1567 const MCExpr *TlsCallAddend =
nullptr;
1568 if (
auto *
Ref = dyn_cast<MCSymbolRefExpr>(EVal)) {
1569 TlsCall =
Ref->getSymbol().getName() == TlsGetAddr;
1570 }
else if (
auto *
Bin = dyn_cast<MCBinaryExpr>(EVal);
1572 if (
auto *
Ref = dyn_cast<MCSymbolRefExpr>(
Bin->getLHS())) {
1573 TlsCall =
Ref->getSymbol().getName() == TlsGetAddr;
1574 TlsCallAddend =
Bin->getRHS();
1581 if (parseExpression(TLSSym))
1582 return Error(S2,
"invalid TLS call expression");
1595 const MCExpr *Addend =
nullptr;
1597 if (parsePrimaryExpr(Addend, EndLoc))
1603 TlsCallAddend = Addend;
1608 Operands.back() = PPCOperand::CreateFromMCExpr(
1612 Operands.push_back(PPCOperand::CreateFromMCExpr(TLSSym, S,
E, isPPC64()));
1620 switch (getLexer().getKind()) {
1622 if (!matchRegisterName(IntVal))
1623 return Error(S,
"invalid register name");
1627 if (getParser().parseAbsoluteExpression(IntVal) || IntVal < 0 ||
1629 return Error(S,
"invalid register number");
1633 return Error(S,
"invalid memory operand");
1640 PPCOperand::CreateImm(IntVal, S,
E, isPPC64(),
true));
1652 std::string NewOpcode;
1654 NewOpcode = std::string(
Name);
1659 NewOpcode = std::string(
Name);
1665 size_t Dot =
Name.find(
'.');
1667 if (!NewOpcode.empty())
1669 PPCOperand::CreateTokenWithStringCopy(Mnemonic, NameLoc, isPPC64()));
1671 Operands.push_back(PPCOperand::CreateToken(Mnemonic, NameLoc, isPPC64()));
1675 if (!NewOpcode.empty())
1677 PPCOperand::CreateTokenWithStringCopy(DotStr, DotLoc, isPPC64()));
1679 Operands.push_back(PPCOperand::CreateToken(DotStr, DotLoc, isPPC64()));
1703 if (getSTI().hasFeature(PPC::FeatureBookE) &&
1705 (
Name ==
"dcbt" ||
Name ==
"dcbtst")) {
1711 if (
Name ==
"lqarx" ||
Name ==
"ldarx" ||
Name ==
"lwarx" ||
1712 Name ==
"lharx" ||
Name ==
"lbarx") {
1715 PPCOperand &EHOp = (PPCOperand &)*
Operands[4];
1716 if (EHOp.isU1Imm() && EHOp.getImm() == 0)
1724bool PPCAsmParser::ParseDirective(
AsmToken DirectiveID) {
1726 if (IDVal ==
".word")
1727 parseDirectiveWord(2, DirectiveID);
1728 else if (IDVal ==
".llong")
1729 parseDirectiveWord(8, DirectiveID);
1730 else if (IDVal ==
".tc")
1731 parseDirectiveTC(isPPC64() ? 8 : 4, DirectiveID);
1732 else if (IDVal ==
".machine")
1733 parseDirectiveMachine(DirectiveID.
getLoc());
1734 else if (IDVal ==
".abiversion")
1735 parseDirectiveAbiVersion(DirectiveID.
getLoc());
1736 else if (IDVal ==
".localentry")
1737 parseDirectiveLocalEntry(DirectiveID.
getLoc());
1739 parseGNUAttribute(DirectiveID.
getLoc());
1746bool PPCAsmParser::parseDirectiveWord(
unsigned Size,
AsmToken ID) {
1747 auto parseOp = [&]() ->
bool {
1749 SMLoc ExprLoc = getParser().getTok().getLoc();
1750 if (getParser().parseExpression(
Value))
1752 if (
const auto *MCE = dyn_cast<MCConstantExpr>(
Value)) {
1754 uint64_t IntValue = MCE->getValue();
1756 return Error(ExprLoc,
"literal value out of range for '" +
1757 ID.getIdentifier() +
"' directive");
1758 getStreamer().emitIntValue(IntValue,
Size);
1760 getStreamer().emitValue(
Value,
Size, ExprLoc);
1764 if (parseMany(parseOp))
1765 return addErrorSuffix(
" in '" +
ID.getIdentifier() +
"' directive");
1777 return addErrorSuffix(
" in '.tc' directive");
1780 getParser().getStreamer().emitValueToAlignment(
Align(
Size));
1783 return parseDirectiveWord(
Size,
ID);
1788bool PPCAsmParser::parseDirectiveMachine(
SMLoc L) {
1792 return Error(L,
"unexpected token in '.machine' directive");
1803 return addErrorSuffix(
" in '.machine' directive");
1806 getParser().getStreamer().getTargetStreamer());
1807 if (TStreamer !=
nullptr)
1814bool PPCAsmParser::parseDirectiveAbiVersion(
SMLoc L) {
1816 if (check(getParser().parseAbsoluteExpression(AbiVersion), L,
1817 "expected constant expression") ||
1819 return addErrorSuffix(
" in '.abiversion' directive");
1822 getParser().getStreamer().getTargetStreamer());
1823 if (TStreamer !=
nullptr)
1830bool PPCAsmParser::parseDirectiveLocalEntry(
SMLoc L) {
1832 if (getParser().parseIdentifier(
Name))
1833 return Error(L,
"expected identifier in '.localentry' directive");
1839 check(getParser().parseExpression(Expr), L,
"expected expression") ||
1841 return addErrorSuffix(
" in '.localentry' directive");
1844 getParser().getStreamer().getTargetStreamer());
1845 if (TStreamer !=
nullptr)
1851bool PPCAsmParser::parseGNUAttribute(
SMLoc L) {
1853 int64_t IntegerValue;
1854 if (!getParser().parseGNUAttribute(L, Tag, IntegerValue))
1857 getParser().getStreamer().emitGNUAttribute(Tag, IntegerValue);
1870#define GET_MATCHER_IMPLEMENTATION
1871#define GET_MNEMONIC_SPELL_CHECKER
1872#include "PPCGenAsmMatcher.inc"
1883 case MCK_0: ImmVal = 0;
break;
1884 case MCK_1: ImmVal = 1;
break;
1885 case MCK_2: ImmVal = 2;
break;
1886 case MCK_3: ImmVal = 3;
break;
1887 case MCK_4: ImmVal = 4;
break;
1888 case MCK_5: ImmVal = 5;
break;
1889 case MCK_6: ImmVal = 6;
break;
1890 case MCK_7: ImmVal = 7;
break;
1891 default:
return Match_InvalidOperand;
1894 PPCOperand &
Op =
static_cast<PPCOperand &
>(AsmOp);
1895 if (
Op.isU3Imm() &&
Op.getImm() == ImmVal)
1896 return Match_Success;
1898 return Match_InvalidOperand;
1902PPCAsmParser::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
const HexagonInstrInfo * TII
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static bool validateMemOp(const OperandVector &Operands, bool isMemriOp)
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 createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
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 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 parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
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
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
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...
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.
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,...