70 enum KindTy { Token, Immediate, Register, Expression } Kind;
72 SMLoc StartLoc, EndLoc;
73 const AMDGPUAsmParser *AsmParser;
76 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
77 : Kind(Kind_), AsmParser(AsmParser_) {}
79 using Ptr = std::unique_ptr<AMDGPUOperand>;
87 bool hasFPModifiers()
const {
return Abs || Neg; }
88 bool hasIntModifiers()
const {
return Sext; }
89 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
90 bool isForcedLit()
const {
return Lit == LitModifier::Lit; }
91 bool isForcedLit64()
const {
return Lit == LitModifier::Lit64; }
93 int64_t getFPModifiersOperand()
const {
100 int64_t getIntModifiersOperand()
const {
106 int64_t getModifiersOperand()
const {
107 assert(!(hasFPModifiers() && hasIntModifiers()) &&
108 "fp and int modifiers should not be used simultaneously");
109 if (hasFPModifiers())
110 return getFPModifiersOperand();
111 if (hasIntModifiers())
112 return getIntModifiersOperand();
116 friend raw_ostream &
operator<<(raw_ostream &OS,
117 AMDGPUOperand::Modifiers Mods);
191 ImmTyMatrixAScaleFmt,
192 ImmTyMatrixBScaleFmt,
225 mutable int MCOpIdx = -1;
228 bool isToken()
const override {
return Kind == Token; }
230 bool isSymbolRefExpr()
const {
234 bool isImm()
const override {
return Kind == Immediate; }
236 bool isInlinableImm(MVT type)
const;
237 bool isLiteralImm(MVT type)
const;
239 bool isRegKind()
const {
return Kind == Register; }
241 bool isReg()
const override {
return isRegKind() && !hasModifiers(); }
243 bool isRegOrInline(
unsigned RCID, MVT type)
const {
244 return isRegClass(RCID) || isInlinableImm(type);
247 bool isRegOrInlineTarget(
unsigned TargetRCIdx, MVT type)
const {
248 return isRegClassTarget(TargetRCIdx) || isInlinableImm(type);
252 return isRegOrInline(RCID, type) || isLiteralImm(type);
255 bool isRegOrImmWithInputModsTarget(
unsigned TargetRCIdx, MVT type)
const {
256 return isRegOrInlineTarget(TargetRCIdx, type) || isLiteralImm(type);
259 bool isRegOrImmWithInt16InputMods()
const {
263 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
265 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
268 bool isRegOrImmWithInt32InputMods()
const {
272 bool isRegOrInlineImmWithInt16InputMods()
const {
273 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
276 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
277 return isRegOrInline(
278 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
281 bool isRegOrInlineImmWithInt32InputMods()
const {
282 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
285 bool isRegOrImmWithInt64InputMods()
const {
286 return isRegOrImmWithInputModsTarget(AMDGPU::VS_64_AlignTarget, MVT::i64);
289 bool isRegOrImmWithFP16InputMods()
const {
293 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
295 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
298 bool isRegOrImmWithFP32InputMods()
const {
302 bool isRegOrImmWithFP64InputMods()
const {
303 return isRegOrImmWithInputModsTarget(AMDGPU::VS_64_AlignTarget, MVT::f64);
306 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
307 return isRegOrInline(
308 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
311 bool isRegOrInlineImmWithFP32InputMods()
const {
312 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
315 bool isRegOrInlineImmWithFP64InputMods()
const {
316 return isRegOrInlineTarget(AMDGPU::VS_64_AlignTarget, MVT::f64);
319 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
321 bool isVRegWithFP32InputMods()
const {
322 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
325 bool isVRegWithFP64InputMods()
const {
326 return isRegClassTarget(AMDGPU::VReg_64_AlignTarget);
329 bool isPackedFP16InputMods()
const {
333 bool isPackedVGPRFP32InputMods()
const {
337 bool isVReg()
const {
338 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
339 isRegClass(AMDGPU::VReg_64RegClassID) ||
340 isRegClass(AMDGPU::VReg_96RegClassID) ||
341 isRegClass(AMDGPU::VReg_128RegClassID) ||
342 isRegClass(AMDGPU::VReg_160RegClassID) ||
343 isRegClass(AMDGPU::VReg_192RegClassID) ||
344 isRegClass(AMDGPU::VReg_256RegClassID) ||
345 isRegClass(AMDGPU::VReg_512RegClassID) ||
346 isRegClass(AMDGPU::VReg_1024RegClassID);
349 bool isVReg32()
const {
return isRegClass(AMDGPU::VGPR_32RegClassID); }
351 bool isVReg32OrOff()
const {
return isOff() || isVReg32(); }
353 bool isRsrcReg32()
const {
return isRegClass(AMDGPU::RsrcReg32RegClassID); }
355 bool isNull()
const {
return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL; }
357 bool isAV_LdSt_32_Align2_RegOp()
const {
358 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
359 isRegClass(AMDGPU::AGPR_32RegClassID);
362 bool isVRegWithInputMods()
const;
363 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
364 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
366 bool isSDWAOperand(MVT type)
const;
367 bool isSDWAFP16Operand()
const;
368 bool isSDWAFP32Operand()
const;
369 bool isSDWAInt16Operand()
const;
370 bool isSDWAInt32Operand()
const;
372 bool isImmTy(ImmTy ImmT)
const {
return isImm() &&
Imm.Type == ImmT; }
374 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
376 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
378 bool isImmModifier()
const {
return isImm() &&
Imm.Type != ImmTyNone; }
380 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
381 bool isDim()
const {
return isImmTy(ImmTyDim); }
382 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
383 bool isOff()
const {
return isImmTy(ImmTyOff); }
384 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
385 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
386 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
387 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
388 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
389 bool isFlatOffset()
const {
390 return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset);
392 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
393 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
394 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
395 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
396 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
397 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
398 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
399 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
400 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
401 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
402 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
403 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
404 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
405 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
406 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
407 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
408 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
409 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
410 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
411 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
412 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
413 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
414 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
415 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
416 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
417 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
418 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
419 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
420 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
421 bool isDone()
const {
return isImmTy(ImmTyDone); }
422 bool isRowEn()
const {
return isImmTy(ImmTyRowEn); }
424 bool isRegOrImm()
const {
return isReg() || isImm(); }
426 bool isRegClass(
unsigned RCID)
const;
429 bool isRegClassTarget(
unsigned TargetRCIdx)
const;
433 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
434 return isRegOrInline(RCID, type) && !hasModifiers();
437 bool isSCSrcB16()
const {
438 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
441 bool isSCSrcV2B16()
const {
return isSCSrcB16(); }
443 bool isSCSrc_b32()
const {
444 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
447 bool isSCSrc_b64()
const {
448 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
451 bool isBoolReg()
const;
453 bool isSCSrcF16()
const {
454 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
457 bool isSCSrcV2F16()
const {
return isSCSrcF16(); }
459 bool isSCSrcF32()
const {
460 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
463 bool isSCSrcF64()
const {
464 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
467 bool isSSrc_b32()
const {
468 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
471 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
473 bool isSSrcV2B16()
const {
478 bool isSSrc_b64()
const {
481 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
482 (((
const MCTargetAsmParser *)AsmParser)
483 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
487 bool isSSrc_f32()
const {
488 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
491 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
493 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
495 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
497 bool isSSrc_NoInline_f16()
const {
return isSSrc_f16(); }
499 bool isSSrcV2F16()
const {
504 bool isSSrcV2FP32()
const {
509 bool isSCSrcV2FP32()
const {
514 bool isSSrcV2INT32()
const {
519 bool isSCSrcV2INT32()
const {
521 return isSCSrc_b32();
524 bool isSSrcOrLds_b32()
const {
525 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
526 isLiteralImm(MVT::i32) || isExpr();
529 bool isVCSrc_b32()
const {
530 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
533 bool isVCSrc_b32_Lo256()
const {
534 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
537 bool isVCSrc_b64_Lo256()
const {
538 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
541 bool isVCSrc_b64()
const {
542 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
545 bool isVCSrcT_b16()
const {
546 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
549 bool isVCSrcTB16_Lo128()
const {
550 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
553 bool isVCSrcFake16B16_Lo128()
const {
554 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
557 bool isVCSrc_b16()
const {
558 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
561 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
563 bool isVCSrc_f32()
const {
564 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
567 bool isVCSrc_f64()
const {
568 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
571 bool isVCSrcTBF16()
const {
572 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
575 bool isVCSrcT_f16()
const {
576 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
579 bool isVCSrcT_bf16()
const {
580 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
583 bool isVCSrcTBF16_Lo128()
const {
584 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
587 bool isVCSrcTF16_Lo128()
const {
588 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
591 bool isVCSrcFake16BF16_Lo128()
const {
592 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
595 bool isVCSrcFake16F16_Lo128()
const {
596 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
599 bool isVCSrc_bf16()
const {
600 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
603 bool isVCSrc_f16()
const {
604 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
607 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
609 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
611 bool isVSrc_b32()
const {
612 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
615 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
617 bool isVSrc_v2b64()
const {
618 return isRegOrInlineNoMods(AMDGPU::VS_128RegClassID, MVT::i64) ||
619 isLiteralImm(MVT::i64);
622 bool isVSrc_v2f64()
const {
623 return isRegOrInlineNoMods(AMDGPU::VS_128RegClassID, MVT::f64) ||
624 isLiteralImm(MVT::f64);
627 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
629 bool isVSrcT_b16_Lo128()
const {
630 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
633 bool isVSrcFake16_b16_Lo128()
const {
634 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
637 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
639 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
641 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
643 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
645 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
647 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
649 bool isVSrc_f32()
const {
650 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
653 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
655 bool isVSrcT_bf16()
const {
656 return isVCSrcTBF16() || isLiteralImm(MVT::bf16);
659 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
661 bool isVSrcT_bf16_Lo128()
const {
662 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
665 bool isVSrcT_f16_Lo128()
const {
666 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
669 bool isVSrcFake16_bf16_Lo128()
const {
670 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
673 bool isVSrcFake16_f16_Lo128()
const {
674 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
677 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
679 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
681 bool isVSrc_v2bf16()
const {
682 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
685 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
687 bool isVSrc_v2f16_splat()
const {
return isVSrc_v2f16(); }
689 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
691 bool isVISrcB32()
const {
692 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
695 bool isVISrcB16()
const {
696 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
699 bool isVISrcV2B16()
const {
return isVISrcB16(); }
701 bool isVISrcF32()
const {
702 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
705 bool isVISrcF16()
const {
706 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
709 bool isVISrcV2F16()
const {
return isVISrcF16() || isVISrcB32(); }
711 bool isVISrc_64_bf16()
const {
712 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
715 bool isVISrc_64_f16()
const {
716 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
719 bool isVISrc_64_b32()
const {
720 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
723 bool isVISrc_64B64()
const {
724 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
727 bool isVISrc_64_f64()
const {
728 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
731 bool isVISrc_64V2FP32()
const {
732 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
735 bool isVISrc_64V2INT32()
const {
736 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
739 bool isVISrc_256_b32()
const {
740 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
743 bool isVISrc_256_f32()
const {
744 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
747 bool isVISrc_256B64()
const {
748 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
751 bool isVISrc_256_f64()
const {
752 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
755 bool isVISrc_512_f64()
const {
756 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
759 bool isVISrc_128B16()
const {
760 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
763 bool isVISrc_128V2B16()
const {
return isVISrc_128B16(); }
765 bool isVISrc_128_b32()
const {
766 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
769 bool isVISrc_128_f32()
const {
770 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
773 bool isVISrc_256V2FP32()
const {
774 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
777 bool isVISrc_256V2INT32()
const {
778 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
781 bool isVISrc_512_b32()
const {
782 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
785 bool isVISrc_512B16()
const {
786 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
789 bool isVISrc_512V2B16()
const {
return isVISrc_512B16(); }
791 bool isVISrc_512_f32()
const {
792 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
795 bool isVISrc_512F16()
const {
796 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
799 bool isVISrc_512V2F16()
const {
800 return isVISrc_512F16() || isVISrc_512_b32();
803 bool isVISrc_1024_b32()
const {
804 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
807 bool isVISrc_1024B16()
const {
808 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
811 bool isVISrc_1024V2B16()
const {
return isVISrc_1024B16(); }
813 bool isVISrc_1024_f32()
const {
814 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
817 bool isVISrc_1024F16()
const {
818 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
821 bool isVISrc_1024V2F16()
const {
822 return isVISrc_1024F16() || isVISrc_1024_b32();
825 bool isAISrcB32()
const {
826 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
829 bool isAISrcB16()
const {
830 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
833 bool isAISrcV2B16()
const {
return isAISrcB16(); }
835 bool isAISrcF32()
const {
836 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
839 bool isAISrcF16()
const {
840 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
843 bool isAISrcV2F16()
const {
return isAISrcF16() || isAISrcB32(); }
845 bool isAISrc_64B64()
const {
846 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
849 bool isAISrc_64_f64()
const {
850 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
853 bool isAISrc_128_b32()
const {
854 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
857 bool isAISrc_128B16()
const {
858 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
861 bool isAISrc_128V2B16()
const {
return isAISrc_128B16(); }
863 bool isAISrc_128_f32()
const {
864 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
867 bool isAISrc_128F16()
const {
868 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
871 bool isAISrc_128V2F16()
const {
872 return isAISrc_128F16() || isAISrc_128_b32();
875 bool isVISrc_128_bf16()
const {
876 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
879 bool isVISrc_128_f16()
const {
880 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
883 bool isVISrc_128V2F16()
const {
884 return isVISrc_128_f16() || isVISrc_128_b32();
887 bool isAISrc_256B64()
const {
888 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
891 bool isAISrc_256_f64()
const {
892 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
895 bool isAISrc_512_b32()
const {
896 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
899 bool isAISrc_512B16()
const {
900 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
903 bool isAISrc_512V2B16()
const {
return isAISrc_512B16(); }
905 bool isAISrc_512_f32()
const {
906 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
909 bool isAISrc_512F16()
const {
910 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
913 bool isAISrc_512V2F16()
const {
914 return isAISrc_512F16() || isAISrc_512_b32();
917 bool isAISrc_1024_b32()
const {
918 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
921 bool isAISrc_1024B16()
const {
922 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
925 bool isAISrc_1024V2B16()
const {
return isAISrc_1024B16(); }
927 bool isAISrc_1024_f32()
const {
928 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
931 bool isAISrc_1024F16()
const {
932 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
935 bool isAISrc_1024V2F16()
const {
936 return isAISrc_1024F16() || isAISrc_1024_b32();
939 bool isKImmFP32()
const {
return isLiteralImm(MVT::f32); }
941 bool isKImmFP16()
const {
return isLiteralImm(MVT::f16); }
943 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
945 bool isMem()
const override {
return false; }
947 bool isExpr()
const {
return Kind == Expression; }
949 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
951 bool isSWaitCnt()
const;
952 bool isDepCtr()
const;
953 bool isSDelayALU()
const;
954 bool isHwreg()
const;
955 bool isSendMsg()
const;
956 bool isWaitEvent()
const;
957 bool isSplitBarrier()
const;
958 bool isSwizzle()
const;
959 bool isSMRDOffset8()
const;
960 bool isSMEMOffset()
const;
961 bool isSMRDLiteralOffset()
const;
963 bool isDPPCtrl()
const;
965 bool isGPRIdxMode()
const;
966 bool isS16Imm()
const;
967 bool isU16Imm()
const;
968 bool isEndpgm()
const;
970 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
971 return [
this,
P]() {
return P(*
this); };
976 return StringRef(Tok.Data, Tok.Length);
984 void setImm(int64_t Val) {
989 ImmTy getImmTy()
const {
994 MCRegister
getReg()
const override {
999 SMLoc getStartLoc()
const override {
return StartLoc; }
1001 SMLoc getEndLoc()
const override {
return EndLoc; }
1003 SMRange getLocRange()
const {
return SMRange(StartLoc, EndLoc); }
1005 int getMCOpIdx()
const {
return MCOpIdx; }
1007 Modifiers getModifiers()
const {
1008 assert(isRegKind() || isImmTy(ImmTyNone));
1009 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1012 void setModifiers(Modifiers Mods) {
1013 assert(isRegKind() || isImmTy(ImmTyNone));
1020 bool hasModifiers()
const {
return getModifiers().hasModifiers(); }
1022 bool hasFPModifiers()
const {
return getModifiers().hasFPModifiers(); }
1024 bool hasIntModifiers()
const {
return getModifiers().hasIntModifiers(); }
1026 bool isForcedLit()
const {
1027 return isImmLiteral() && getModifiers().isForcedLit();
1030 bool isForcedLit64()
const {
1031 return isImmLiteral() && getModifiers().isForcedLit64();
1036 void addImmOperands(MCInst &Inst,
unsigned N,
1037 bool ApplyModifiers =
true)
const;
1039 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
1040 bool ApplyModifiers)
const;
1042 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1044 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1046 addRegOperands(Inst,
N);
1048 addImmOperands(Inst,
N);
1051 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1052 Modifiers Mods = getModifiers();
1055 addRegOperands(Inst,
N);
1057 addImmOperands(Inst,
N,
false);
1061 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1062 assert(!hasIntModifiers());
1063 addRegOrImmWithInputModsOperands(Inst,
N);
1066 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1067 assert(!hasFPModifiers());
1068 addRegOrImmWithInputModsOperands(Inst,
N);
1071 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1072 Modifiers Mods = getModifiers();
1075 addRegOperands(Inst,
N);
1078 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1079 assert(!hasIntModifiers());
1080 addRegWithInputModsOperands(Inst,
N);
1083 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1084 assert(!hasFPModifiers());
1085 addRegWithInputModsOperands(Inst,
N);
1088 static void printImmTy(raw_ostream &OS, ImmTy
Type) {
1091 case ImmTyNone: OS <<
"None";
break;
1092 case ImmTyGDS: OS <<
"GDS";
break;
1093 case ImmTyLDS: OS <<
"LDS";
break;
1094 case ImmTyOffen: OS <<
"Offen";
break;
1095 case ImmTyIdxen: OS <<
"Idxen";
break;
1096 case ImmTyAddr64: OS <<
"Addr64";
break;
1097 case ImmTyOffset: OS <<
"Offset";
break;
1098 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1099 case ImmTyOffset0: OS <<
"Offset0";
break;
1100 case ImmTyOffset1: OS <<
"Offset1";
break;
1101 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1102 case ImmTyCPol: OS <<
"CPol";
break;
1103 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1104 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1105 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1106 case ImmTyTFE: OS <<
"TFE";
break;
1107 case ImmTyIsAsync: OS <<
"IsAsync";
break;
1108 case ImmTyD16: OS <<
"D16";
break;
1109 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1110 case ImmTyClamp: OS <<
"Clamp";
break;
1111 case ImmTyOModSI: OS <<
"OModSI";
break;
1112 case ImmTyDPP8: OS <<
"DPP8";
break;
1113 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1114 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1115 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1116 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1117 case ImmTyDppFI: OS <<
"DppFI";
break;
1118 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1119 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1120 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1121 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1122 case ImmTyDMask: OS <<
"DMask";
break;
1123 case ImmTyDim: OS <<
"Dim";
break;
1124 case ImmTyUNorm: OS <<
"UNorm";
break;
1125 case ImmTyDA: OS <<
"DA";
break;
1126 case ImmTyR128A16: OS <<
"R128A16";
break;
1127 case ImmTyA16: OS <<
"A16";
break;
1128 case ImmTyLWE: OS <<
"LWE";
break;
1129 case ImmTyOff: OS <<
"Off";
break;
1130 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1131 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1132 case ImmTyExpVM: OS <<
"ExpVM";
break;
1133 case ImmTyDone: OS <<
"Done";
break;
1134 case ImmTyRowEn: OS <<
"RowEn";
break;
1135 case ImmTyHwreg: OS <<
"Hwreg";
break;
1136 case ImmTySendMsg: OS <<
"SendMsg";
break;
1137 case ImmTyWaitEvent: OS <<
"WaitEvent";
break;
1138 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1139 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1140 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1141 case ImmTyOpSel: OS <<
"OpSel";
break;
1142 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1143 case ImmTyNegLo: OS <<
"NegLo";
break;
1144 case ImmTyNegHi: OS <<
"NegHi";
break;
1145 case ImmTySwizzle: OS <<
"Swizzle";
break;
1146 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1147 case ImmTyHigh: OS <<
"High";
break;
1148 case ImmTyBLGP: OS <<
"BLGP";
break;
1149 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1150 case ImmTyABID: OS <<
"ABID";
break;
1151 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1152 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1153 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1154 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1155 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1156 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1157 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1158 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1159 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1160 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1161 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1162 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1163 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1164 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1165 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1166 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1171 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1175 <<
" mods: " <<
Reg.Mods <<
'>';
1179 if (getImmTy() != ImmTyNone) {
1181 printImmTy(OS, getImmTy());
1183 OS <<
" mods: " <<
Imm.Mods <<
'>';
1196 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1197 int64_t Val, SMLoc Loc,
1198 ImmTy
Type = ImmTyNone,
1199 bool IsFPImm =
false) {
1200 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1202 Op->Imm.IsFPImm = IsFPImm;
1204 Op->Imm.Mods = Modifiers();
1210 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1211 StringRef Str, SMLoc Loc,
1212 bool HasExplicitEncodingSize =
true) {
1213 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1214 Res->Tok.Data = Str.data();
1215 Res->Tok.Length = Str.size();
1216 Res->StartLoc = Loc;
1221 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1222 MCRegister
Reg, SMLoc S, SMLoc
E) {
1223 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1224 Op->Reg.RegNo =
Reg;
1225 Op->Reg.Mods = Modifiers();
1231 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1232 const class MCExpr *Expr, SMLoc S) {
1233 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1242 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1251#define GET_REGISTER_MATCHER
1252#include "AMDGPUGenAsmMatcher.inc"
1253#undef GET_REGISTER_MATCHER
1254#undef GET_SUBTARGET_FEATURE_NAME
1259class KernelScopeInfo {
1260 int SgprIndexUnusedMin = -1;
1261 int VgprIndexUnusedMin = -1;
1262 int AgprIndexUnusedMin = -1;
1266 void usesSgprAt(
int i) {
1267 if (i >= SgprIndexUnusedMin) {
1268 SgprIndexUnusedMin = ++i;
1271 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1277 void usesVgprAt(
int i) {
1278 if (i >= VgprIndexUnusedMin) {
1279 VgprIndexUnusedMin = ++i;
1282 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1284 VgprIndexUnusedMin);
1290 void usesAgprAt(
int i) {
1295 if (i >= AgprIndexUnusedMin) {
1296 AgprIndexUnusedMin = ++i;
1299 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1304 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1306 VgprIndexUnusedMin);
1313 KernelScopeInfo() =
default;
1317 MSTI = Ctx->getSubtargetInfo();
1319 usesSgprAt(SgprIndexUnusedMin = -1);
1320 usesVgprAt(VgprIndexUnusedMin = -1);
1322 usesAgprAt(AgprIndexUnusedMin = -1);
1326 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1327 unsigned RegWidth) {
1330 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1333 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1336 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1345 MCAsmParser &Parser;
1347 unsigned ForcedEncodingSize = 0;
1348 bool ForcedDPP =
false;
1349 bool ForcedSDWA =
false;
1350 KernelScopeInfo KernelScope;
1351 const unsigned HwMode;
1353 const AMDGPU::IsaVersion ISA;
1358#define GET_ASSEMBLER_HEADER
1359#include "AMDGPUGenAsmMatcher.inc"
1364 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1366 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1370 std::optional<AMDGPU::InfoSectionData> InfoData;
1377 bool TargetDirectiveEmitted =
false;
1386 SmallVector<unsigned> OpcodeStream;
1388 OpcodeStreamSymbols;
1389 SmallPtrSet<const MCSymbol *, 8> AMDHSAKernelSymbols;
1392 void checkKernelPrologues();
1395 void createConstantSymbol(StringRef Id, int64_t Val);
1397 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1398 bool OutOfRangeError(SMRange
Range);
1414 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1415 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1416 std::optional<bool> EnableWavefrontSize32,
1417 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1418 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1419 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1420 bool ParseDirectiveAMDGCNTarget();
1421 bool ParseDirectiveAMDHSACodeObjectVersion();
1422 bool ParseDirectiveAMDHSAKernel();
1423 bool ParseAMDKernelCodeTValue(StringRef ID, AMDGPUMCKernelCodeT &Header);
1424 bool ParseDirectiveAMDKernelCodeT();
1426 bool subtargetHasRegister(
const MCRegisterInfo &MRI, MCRegister
Reg);
1427 bool ParseDirectiveAMDGPUHsaKernel();
1429 bool ParseDirectiveISAVersion();
1430 bool ParseDirectiveHSAMetadata();
1431 bool ParseDirectivePALMetadataBegin();
1432 bool ParseDirectivePALMetadata();
1433 bool ParseDirectiveAMDGPULDS();
1434 bool ParseDirectiveAMDGPUInfo();
1438 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1439 const char *AssemblerDirectiveEnd,
1440 std::string &CollectString);
1442 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1443 RegisterKind RegKind, MCRegister Reg1,
1444 RegisterKind RegKind1, SMLoc Loc);
1445 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1446 unsigned &RegNum,
unsigned &RegWidth,
1447 bool RestoreOnFailure =
false);
1448 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1449 unsigned &RegNum,
unsigned &RegWidth,
1450 SmallVectorImpl<AsmToken> &Tokens);
1451 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1453 SmallVectorImpl<AsmToken> &Tokens);
1454 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1456 SmallVectorImpl<AsmToken> &Tokens);
1457 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1459 SmallVectorImpl<AsmToken> &Tokens);
1460 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &SubReg);
1461 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1462 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1465 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1466 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1467 void initializeGprCountSymbol(RegisterKind RegKind);
1468 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1474 OperandMode_Default,
1478 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1480 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1481 const MCInstrInfo &MII)
1482 : MCTargetAsmParser(STI, MII), Parser(_Parser),
1483 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)),
1488 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1490 if (ISA.Major >= 6 &&
isHsaAbi(getSTI())) {
1491 createConstantSymbol(
".amdgcn.gfx_generation_number", ISA.Major);
1492 createConstantSymbol(
".amdgcn.gfx_generation_minor", ISA.Minor);
1493 createConstantSymbol(
".amdgcn.gfx_generation_stepping", ISA.Stepping);
1495 createConstantSymbol(
".option.machine_version_major", ISA.Major);
1496 createConstantSymbol(
".option.machine_version_minor", ISA.Minor);
1497 createConstantSymbol(
".option.machine_version_stepping", ISA.Stepping);
1499 if (ISA.Major >= 6 &&
isHsaAbi(getSTI())) {
1500 initializeGprCountSymbol(IS_VGPR);
1501 initializeGprCountSymbol(IS_SGPR);
1506 createConstantSymbol(Symbol, Code);
1508 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1509 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1510 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1558 bool hasBVHRayTracingInsts()
const {
1559 return getFeatureBits()[AMDGPU::FeatureBVHRayTracingInsts];
1564 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1566 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1568 bool hasInv2PiInlineImm()
const {
1569 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1572 bool has64BitLiterals()
const {
1573 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1576 bool hasFlatOffsets()
const {
1577 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1580 bool hasTrue16Insts()
const {
1581 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1585 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1588 bool hasSGPR102_SGPR103()
const {
return !
isVI() && !
isGFX9(); }
1590 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1592 bool hasIntClamp()
const {
return getFeatureBits()[AMDGPU::FeatureIntClamp]; }
1594 bool hasPartialNSAEncoding()
const {
1595 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1598 bool hasGloballyAddressableScratch()
const {
1599 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1612 AMDGPUTargetStreamer &getTargetStreamer() {
1613 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1614 return static_cast<AMDGPUTargetStreamer &
>(TS);
1620 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1623 const MCRegisterInfo *getMRI()
const {
1627 const MCInstrInfo *getMII()
const {
return &MII; }
1631 int16_t getTargetRegClass(
unsigned TargetRCIdx)
const {
1637 const FeatureBitset &getFeatureBits()
const {
1638 return getSTI().getFeatureBits();
1641 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1642 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1643 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1645 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1646 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1647 bool isForcedDPP()
const {
return ForcedDPP; }
1648 bool isForcedSDWA()
const {
return ForcedSDWA; }
1649 ArrayRef<unsigned> getMatchedVariants()
const;
1650 StringRef getMatchedVariantName()
const;
1652 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1653 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1654 bool RestoreOnFailure);
1655 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1656 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1657 SMLoc &EndLoc)
override;
1658 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1659 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1660 unsigned Kind)
override;
1661 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1664 bool MatchingInlineAsm)
override;
1665 bool ParseDirective(AsmToken DirectiveID)
override;
1666 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override;
1667 void onEndOfFile()
override;
1669 OperandMode
Mode = OperandMode_Default);
1670 StringRef parseMnemonicSuffix(StringRef Name);
1671 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1677 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1681 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1682 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1684 ParseStatus parseOperandArrayWithPrefix(
1686 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1687 bool (*ConvertResult)(int64_t &) =
nullptr);
1691 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1692 bool IgnoreNegative =
false);
1693 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1697 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1701 ArrayRef<const char *> Ids,
1705 ArrayRef<const char *> Ids,
1706 AMDGPUOperand::ImmTy
Type);
1709 bool isOperandModifier(
const AsmToken &Token,
1710 const AsmToken &NextToken)
const;
1711 bool isRegOrOperandModifier(
const AsmToken &Token,
1712 const AsmToken &NextToken)
const;
1713 bool isNamedOperandModifier(
const AsmToken &Token,
1714 const AsmToken &NextToken)
const;
1715 bool isOpcodeModifierWithVal(
const AsmToken &Token,
1716 const AsmToken &NextToken)
const;
1717 bool parseSP3NegModifier();
1724 bool AllowImm =
true);
1726 bool AllowImm =
true);
1732 AMDGPUOperand::ImmTy ImmTy);
1737 AMDGPUOperand::ImmTy
Type);
1741 AMDGPUOperand::ImmTy
Type);
1745 AMDGPUOperand::ImmTy
Type);
1749 ParseStatus parseDfmtNfmt(int64_t &
Format);
1750 ParseStatus parseUfmt(int64_t &
Format);
1751 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1753 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1756 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1757 ParseStatus parseNumericFormat(int64_t &
Format);
1761 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1762 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr,
1767 bool parseCnt(int64_t &IntVal);
1770 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1771 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1774 bool parseDelay(int64_t &Delay);
1780 struct OperandInfoTy {
1783 bool IsSymbolic =
false;
1784 bool IsDefined =
false;
1786 constexpr OperandInfoTy(int64_t Val) : Val(Val) {}
1789 struct StructuredOpField : OperandInfoTy {
1793 bool IsDefined =
false;
1795 constexpr StructuredOpField(StringLiteral Id, StringLiteral Desc,
1796 unsigned Width, int64_t
Default)
1797 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1798 virtual ~StructuredOpField() =
default;
1800 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1801 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1805 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1807 return Error(Parser,
"not supported on this GPU");
1809 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1817 bool parseSendMsgBody(OperandInfoTy &
Msg, OperandInfoTy &
Op,
1818 OperandInfoTy &Stream);
1819 bool validateSendMsg(
const OperandInfoTy &
Msg,
const OperandInfoTy &
Op,
1820 const OperandInfoTy &Stream);
1822 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1823 OperandInfoTy &Width);
1828 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1835 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand &)>
Test,
1837 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1841 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1846 bool validateBF16InlineConst(
const MCInst &Inst,
1849 bool validateConstantBusLimitations(
const MCInst &Inst,
1851 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1854 bool tryVOPD(
const MCInst &Inst);
1855 bool tryVOPD3(
const MCInst &Inst);
1856 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1858 bool validateIntClampSupported(
const MCInst &Inst);
1859 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1860 bool validateMIMGGatherDMask(
const MCInst &Inst);
1862 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1863 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1864 bool validateMIMGD16(
const MCInst &Inst);
1866 bool validateTensorR128(
const MCInst &Inst);
1867 bool validateMIMGMSAA(
const MCInst &Inst);
1868 bool validateOpSel(
const MCInst &Inst);
1869 bool validateTrue16OpSel(
const MCInst &Inst);
1870 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1872 bool validateVccOperand(MCRegister
Reg)
const;
1877 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1878 bool validateVGPRAlign(
const MCInst &Inst)
const;
1882 bool validateDivScale(
const MCInst &Inst);
1887 const unsigned CPol);
1892 bool validateClusterBarrierIsFirst(
const MCInst &Inst,
1894 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1895 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1896 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1897 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1899 bool isSupportedMnemo(StringRef Mnemo,
const FeatureBitset &FBS);
1900 bool isSupportedMnemo(StringRef Mnemo,
const FeatureBitset &FBS,
1901 ArrayRef<unsigned> Variants);
1902 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1904 bool isId(
const StringRef Id)
const;
1905 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1907 StringRef getId()
const;
1908 bool trySkipId(
const StringRef Id);
1909 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1913 bool parseString(StringRef &Val,
1914 const StringRef ErrMsg =
"expected a string");
1915 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1921 StringRef getTokenStr()
const;
1922 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1924 SMLoc getLoc()
const;
1928 void onBeginOfFile()
override;
1932 void emitTargetDirective();
1933 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1945 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1946 const unsigned MaxVal,
const Twine &ErrMsg,
1948 bool parseSwizzleOperands(
const unsigned OpNum, int64_t *
Op,
1949 const unsigned MinVal,
const unsigned MaxVal,
1950 const StringRef ErrMsg);
1952 bool parseSwizzleOffset(int64_t &
Imm);
1953 bool parseSwizzleMacro(int64_t &
Imm);
1954 bool parseSwizzleQuadPerm(int64_t &
Imm);
1955 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1956 bool parseSwizzleBroadcast(int64_t &
Imm);
1957 bool parseSwizzleSwap(int64_t &
Imm);
1958 bool parseSwizzleReverse(int64_t &
Imm);
1959 bool parseSwizzleFFT(int64_t &
Imm);
1960 bool parseSwizzleRotate(int64_t &
Imm);
1963 int64_t parseGPRIdxMacro();
1966 cvtMubufImpl(Inst,
Operands,
false);
1969 cvtMubufImpl(Inst,
Operands,
true);
1975 OptionalImmIndexMap &OptionalIdx);
1984 OptionalImmIndexMap &OptionalIdx);
1986 OptionalImmIndexMap &OptionalIdx);
1990 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1992 bool parseDimId(
unsigned &Encoding);
1994 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1998 int64_t parseDPPCtrlSel(StringRef Ctrl);
1999 int64_t parseDPPCtrlPerm();
2005 bool IsDPP8 =
false);
2011 AMDGPUOperand::ImmTy
Type);
2019 enum class SDWAInstType :
unsigned {
VOP1 = 0,
VOP2 = 1,
VOPC = 2 };
2022 SDWAInstType BasicInstType,
bool SkipDstVcc =
false,
2023 bool SkipSrcVcc =
false);
2133bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2143 if (!isImmTy(ImmTyNone)) {
2148 if (getModifiers().
Lit != LitModifier::None)
2158 if (type == MVT::f64 || type == MVT::i64) {
2160 AsmParser->hasInv2PiInlineImm());
2163 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2182 APFloat::rmNearestTiesToEven, &Lost);
2189 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2191 AsmParser->hasInv2PiInlineImm());
2196 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2197 AsmParser->hasInv2PiInlineImm());
2201 if (type == MVT::f64 || type == MVT::i64) {
2203 AsmParser->hasInv2PiInlineImm());
2212 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()), type,
2213 AsmParser->hasInv2PiInlineImm());
2217 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2218 AsmParser->hasInv2PiInlineImm());
2221bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2223 if (!isImmTy(ImmTyNone)) {
2228 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2233 if (type == MVT::f64 && hasFPModifiers()) {
2253 if (type == MVT::f64) {
2258 if (type == MVT::i64) {
2271 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2272 : (type == MVT::v2i16) ? MVT::f32
2273 : (type == MVT::v2f32) ? MVT::f32
2276 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2280bool AMDGPUOperand::isRegClassTarget(
unsigned TargetRCIdx)
const {
2283 int16_t RCID = AsmParser->getTargetRegClass(TargetRCIdx);
2284 return RCID >= 0 && isRegClass(RCID);
2287bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2288 return isRegKind() &&
2289 AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2292bool AMDGPUOperand::isVRegWithInputMods()
const {
2293 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2295 (AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP] &&
2296 isRegClassTarget(AMDGPU::VReg_64_AlignTarget));
2299template <
bool IsFake16>
2300bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2301 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2302 : AMDGPU::VGPR_16_Lo128RegClassID);
2305template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2306 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2307 : AMDGPU::VGPR_16RegClassID);
2310bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2311 if (AsmParser->isVI())
2313 if (AsmParser->isGFX9Plus())
2314 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2318bool AMDGPUOperand::isSDWAFP16Operand()
const {
2319 return isSDWAOperand(MVT::f16);
2322bool AMDGPUOperand::isSDWAFP32Operand()
const {
2323 return isSDWAOperand(MVT::f32);
2326bool AMDGPUOperand::isSDWAInt16Operand()
const {
2327 return isSDWAOperand(MVT::i16);
2330bool AMDGPUOperand::isSDWAInt32Operand()
const {
2331 return isSDWAOperand(MVT::i32);
2334bool AMDGPUOperand::isBoolReg()
const {
2335 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2336 (AsmParser->isWave32() && isSCSrc_b32()));
2340 unsigned Size)
const {
2341 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2356void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
2357 bool ApplyModifiers)
const {
2367 addLiteralImmOperand(Inst,
Imm.Val,
2368 ApplyModifiers & isImmTy(ImmTyNone) &&
2369 Imm.Mods.hasFPModifiers());
2371 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2376void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
2377 bool ApplyModifiers)
const {
2378 const auto &InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2383 if (ApplyModifiers) {
2385 const unsigned Size =
2387 Val = applyInputFPModifiers(Val,
Size);
2391 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2393 bool CanUse64BitLiterals =
2396 MCContext &Ctx = AsmParser->getContext();
2407 if (
Lit == LitModifier::None &&
2409 AsmParser->hasInv2PiInlineImm())) {
2417 bool HasMandatoryLiteral =
2420 if (
Literal.getLoBits(32) != 0 &&
2421 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2422 !HasMandatoryLiteral) {
2423 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2425 "Can't encode literal as exact 64-bit floating-point operand. "
2426 "Low 32-bits will be set to zero");
2427 Val &= 0xffffffff00000000u;
2433 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2439 Lit = LitModifier::Lit64;
2440 }
else if (
Lit == LitModifier::Lit) {
2454 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2456 Lit = LitModifier::Lit64;
2463 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2464 Literal == 0x3fc45f306725feed) {
2504 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2511 if (
Lit != LitModifier::None) {
2542 if (
Lit == LitModifier::None &&
2552 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2560 if (
Lit == LitModifier::None &&
2568 if (!AsmParser->has64BitLiterals()) {
2569 Val =
static_cast<uint64_t>(Val) << 32;
2576 if (
Lit == LitModifier::Lit ||
2578 Val =
static_cast<uint64_t>(Val) << 32;
2582 if (
Lit == LitModifier::Lit)
2609 if (
Lit != LitModifier::None) {
2617void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2623bool AMDGPUOperand::isInlineValue()
const {
2631void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2642 if (Is == IS_VGPR) {
2647 return AMDGPU::VGPR_32RegClassID;
2649 return AMDGPU::VReg_64RegClassID;
2651 return AMDGPU::VReg_96RegClassID;
2653 return AMDGPU::VReg_128RegClassID;
2655 return AMDGPU::VReg_160RegClassID;
2657 return AMDGPU::VReg_192RegClassID;
2659 return AMDGPU::VReg_224RegClassID;
2661 return AMDGPU::VReg_256RegClassID;
2663 return AMDGPU::VReg_288RegClassID;
2665 return AMDGPU::VReg_320RegClassID;
2667 return AMDGPU::VReg_352RegClassID;
2669 return AMDGPU::VReg_384RegClassID;
2671 return AMDGPU::VReg_512RegClassID;
2673 return AMDGPU::VReg_1024RegClassID;
2675 }
else if (Is == IS_TTMP) {
2680 return AMDGPU::TTMP_32RegClassID;
2682 return AMDGPU::TTMP_64RegClassID;
2684 return AMDGPU::TTMP_128RegClassID;
2686 return AMDGPU::TTMP_256RegClassID;
2688 return AMDGPU::TTMP_512RegClassID;
2690 }
else if (Is == IS_SGPR) {
2695 return AMDGPU::SGPR_32RegClassID;
2697 return AMDGPU::SGPR_64RegClassID;
2699 return AMDGPU::SGPR_96RegClassID;
2701 return AMDGPU::SGPR_128RegClassID;
2703 return AMDGPU::SGPR_160RegClassID;
2705 return AMDGPU::SGPR_192RegClassID;
2707 return AMDGPU::SGPR_224RegClassID;
2709 return AMDGPU::SGPR_256RegClassID;
2711 return AMDGPU::SGPR_288RegClassID;
2713 return AMDGPU::SGPR_320RegClassID;
2715 return AMDGPU::SGPR_352RegClassID;
2717 return AMDGPU::SGPR_384RegClassID;
2719 return AMDGPU::SGPR_512RegClassID;
2721 }
else if (Is == IS_AGPR) {
2726 return AMDGPU::AGPR_32RegClassID;
2728 return AMDGPU::AReg_64RegClassID;
2730 return AMDGPU::AReg_96RegClassID;
2732 return AMDGPU::AReg_128RegClassID;
2734 return AMDGPU::AReg_160RegClassID;
2736 return AMDGPU::AReg_192RegClassID;
2738 return AMDGPU::AReg_224RegClassID;
2740 return AMDGPU::AReg_256RegClassID;
2742 return AMDGPU::AReg_288RegClassID;
2744 return AMDGPU::AReg_320RegClassID;
2746 return AMDGPU::AReg_352RegClassID;
2748 return AMDGPU::AReg_384RegClassID;
2750 return AMDGPU::AReg_512RegClassID;
2752 return AMDGPU::AReg_1024RegClassID;
2760 .
Case(
"exec", AMDGPU::EXEC)
2761 .
Case(
"vcc", AMDGPU::VCC)
2762 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2763 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2764 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2765 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2766 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2767 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2768 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2769 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2770 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2771 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2772 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2773 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2774 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2775 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2776 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2777 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2778 .
Case(
"m0", AMDGPU::M0)
2779 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2780 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2781 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2782 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2783 .
Case(
"scc", AMDGPU::SRC_SCC)
2784 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2785 .
Case(
"tba", AMDGPU::TBA)
2786 .
Case(
"tma", AMDGPU::TMA)
2787 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2788 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2789 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2790 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2791 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2792 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2793 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2794 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2795 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2796 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2797 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2798 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2799 .
Case(
"pc", AMDGPU::PC_REG)
2800 .
Case(
"null", AMDGPU::SGPR_NULL)
2804bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2805 SMLoc &EndLoc,
bool RestoreOnFailure) {
2806 auto R = parseRegister();
2810 RegNo =
R->getReg();
2811 StartLoc =
R->getStartLoc();
2812 EndLoc =
R->getEndLoc();
2816bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2818 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2821ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2823 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2824 bool PendingErrors = getParser().hasPendingError();
2825 getParser().clearPendingErrors();
2833bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2834 RegisterKind RegKind,
2836 RegisterKind RegKind1, SMLoc Loc) {
2838 if (RegKind == IS_SGPR) {
2839 unsigned RegIdx = (
Reg - AMDGPU::SGPR0) + RegWidth / 32;
2840 if ((RegIdx == 106 && Reg1 == AMDGPU::VCC_LO) ||
2841 (RegIdx == 107 && Reg1 == AMDGPU::VCC_HI)) {
2847 if (RegKind != RegKind1) {
2848 Error(Loc,
"registers in a list must be of the same kind");
2854 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2859 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2860 Reg = AMDGPU::FLAT_SCR;
2864 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2865 Reg = AMDGPU::XNACK_MASK;
2869 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2874 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2879 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2884 Error(Loc,
"register does not fit in the list");
2890 if (Reg1 !=
Reg + RegWidth / 32) {
2891 Error(Loc,
"registers in a list must have consecutive indices");
2907 {{
"v"}, IS_VGPR}, {{
"s"}, IS_SGPR}, {{
"ttmp"}, IS_TTMP},
2908 {{
"acc"}, IS_AGPR}, {{
"a"}, IS_AGPR},
2912 return Kind == IS_VGPR || Kind == IS_SGPR || Kind == IS_TTMP ||
2918 if (Str.starts_with(
Reg.Name))
2924 return !Str.getAsInteger(10, Num);
2927bool AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2928 const AsmToken &NextToken)
const {
2943 StringRef RegSuffix = Str.substr(
RegName.size());
2944 if (!RegSuffix.
empty()) {
2961bool AMDGPUAsmParser::isRegister() {
2962 return isRegister(
getToken(), peekToken());
2965MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2966 unsigned SubReg,
unsigned RegWidth,
2970 unsigned AlignSize = 1;
2971 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2977 if (RegNum % AlignSize != 0) {
2978 Error(Loc,
"invalid register alignment");
2979 return MCRegister();
2982 unsigned RegIdx = RegNum / AlignSize;
2985 Error(Loc,
"invalid or unsupported register size");
2986 return MCRegister();
2990 const MCRegisterClass &RC =
TRI->getRegClass(RCID);
2991 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2992 Error(Loc,
"register index is out of range");
2993 return AMDGPU::NoRegister;
2996 if (RegKind == IS_VGPR && !
isGFX1250Plus() && RegIdx + RegWidth / 32 > 256) {
2997 Error(Loc,
"register index is out of range");
2998 return MCRegister();
3014bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
3016 int64_t RegLo, RegHi;
3020 SMLoc FirstIdxLoc = getLoc();
3027 SecondIdxLoc = getLoc();
3038 Error(FirstIdxLoc,
"invalid register index");
3043 Error(SecondIdxLoc,
"invalid register index");
3047 if (RegLo > RegHi) {
3048 Error(FirstIdxLoc,
"first register index should not exceed second index");
3052 if (RegHi == RegLo) {
3053 StringRef RegSuffix = getTokenStr();
3054 if (RegSuffix ==
".l") {
3055 SubReg = AMDGPU::lo16;
3057 }
else if (RegSuffix ==
".h") {
3058 SubReg = AMDGPU::hi16;
3063 Num =
static_cast<unsigned>(RegLo);
3064 RegWidth = 32 * ((RegHi - RegLo) + 1);
3069MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3072 SmallVectorImpl<AsmToken> &Tokens) {
3078 RegKind = IS_SPECIAL;
3085MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3088 SmallVectorImpl<AsmToken> &Tokens) {
3090 StringRef
RegName = getTokenStr();
3091 auto Loc = getLoc();
3095 Error(Loc,
"invalid register name");
3096 return MCRegister();
3104 unsigned SubReg = NoSubRegister;
3105 bool IsRange =
false;
3106 if (!RegSuffix.
empty()) {
3108 SubReg = AMDGPU::lo16;
3110 SubReg = AMDGPU::hi16;
3114 Error(Loc,
"invalid register index");
3115 return MCRegister();
3121 if (!ParseRegRange(RegNum, RegWidth, SubReg))
3122 return MCRegister();
3126 MCRegister
Reg = getRegularReg(RegKind, RegNum, SubReg, RegWidth, Loc);
3127 const MCRegisterInfo &
TRI = *
getContext().getRegisterInfo();
3128 if (RegKind == IS_SGPR && IsRange
3129 ? (
TRI.isSubRegister(
Reg, VCC_LO) ||
TRI.isSubRegister(
Reg, VCC_HI))
3130 : (
Reg == VCC_LO ||
Reg == VCC_HI)) {
3131 Error(Loc,
"register index is out of range");
3132 return MCRegister();
3138MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3139 unsigned &RegNum,
unsigned &RegWidth,
3140 SmallVectorImpl<AsmToken> &Tokens) {
3142 auto ListLoc = getLoc();
3145 "expected a register or a list of registers")) {
3146 return MCRegister();
3151 auto Loc = getLoc();
3152 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3153 return MCRegister();
3154 if (RegWidth != 32) {
3155 Error(Loc,
"expected a single 32-bit register");
3156 return MCRegister();
3160 RegisterKind NextRegKind;
3162 unsigned NextRegNum, NextRegWidth;
3165 if (!ParseAMDGPURegister(NextRegKind, NextReg, NextRegNum, NextRegWidth,
3167 return MCRegister();
3169 if (NextRegWidth != 32) {
3170 Error(Loc,
"expected a single 32-bit register");
3171 return MCRegister();
3173 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, NextRegKind,
3175 return MCRegister();
3179 "expected a comma or a closing square bracket")) {
3180 return MCRegister();
3184 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3189bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3190 MCRegister &
Reg,
unsigned &RegNum,
3192 SmallVectorImpl<AsmToken> &Tokens) {
3193 auto Loc = getLoc();
3197 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3199 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3201 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3206 assert(Parser.hasPendingError());
3210 if (!subtargetHasRegister(*
TRI,
Reg)) {
3211 if (
Reg == AMDGPU::SGPR_NULL) {
3212 Error(Loc,
"'null' operand is not supported on this GPU");
3215 " register not available on this GPU");
3223bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3224 MCRegister &
Reg,
unsigned &RegNum,
3226 bool RestoreOnFailure ) {
3230 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3231 if (RestoreOnFailure) {
3232 while (!Tokens.
empty()) {
3241std::optional<StringRef>
3242AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3245 return StringRef(
".amdgcn.next_free_vgpr");
3247 return StringRef(
".amdgcn.next_free_sgpr");
3249 return std::nullopt;
3253void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3254 auto SymbolName = getGprCountSymbolName(RegKind);
3255 assert(SymbolName &&
"initializing invalid register kind");
3261bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3262 unsigned DwordRegIndex,
3263 unsigned RegWidth) {
3268 auto SymbolName = getGprCountSymbolName(RegKind);
3273 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3277 return !
Error(getLoc(),
3278 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3282 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3284 if (OldCount <= NewMax)
3290std::unique_ptr<AMDGPUOperand>
3291AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3293 SMLoc StartLoc = Tok.getLoc();
3294 SMLoc EndLoc = Tok.getEndLoc();
3295 RegisterKind RegKind;
3297 unsigned RegNum, RegWidth;
3299 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3303 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3306 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3307 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3314 if (isRegister() || isModifier())
3317 if (
Lit == LitModifier::None) {
3318 if (trySkipId(
"lit"))
3319 Lit = LitModifier::Lit;
3320 else if (trySkipId(
"lit64"))
3321 Lit = LitModifier::Lit64;
3323 if (
Lit != LitModifier::None) {
3326 ParseStatus S = parseImm(
Operands, HasSP3AbsModifier,
Lit);
3335 const auto &NextTok = peekToken();
3338 bool Negate =
false;
3346 AMDGPUOperand::Modifiers Mods;
3354 StringRef Num = getTokenStr();
3357 APFloat RealVal(APFloat::IEEEdouble());
3358 auto roundMode = APFloat::rmNearestTiesToEven;
3359 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3362 RealVal.changeSign();
3365 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(),
3366 S, AMDGPUOperand::ImmTyNone,
true));
3367 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3368 Op.setModifiers(Mods);
3377 if (HasSP3AbsModifier) {
3386 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3389 if (Parser.parseExpression(Expr))
3393 if (Expr->evaluateAsAbsolute(IntVal)) {
3395 return Error(S,
"literal value out of range");
3396 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3397 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3398 Op.setModifiers(Mods);
3400 if (
Lit != LitModifier::None)
3402 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3415 if (
auto R = parseRegister()) {
3425 ParseStatus Res = parseReg(
Operands);
3433bool AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
3434 const AsmToken &NextToken)
const {
3437 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3442bool AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
3443 const AsmToken &NextToken)
const {
3447bool AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
3448 const AsmToken &NextToken)
const {
3449 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3452bool AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
3453 const AsmToken &NextToken)
const {
3454 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3470bool AMDGPUAsmParser::isModifier() {
3473 AsmToken NextToken[2];
3474 peekTokens(NextToken);
3476 return isOperandModifier(Tok, NextToken[0]) ||
3478 isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3479 isOpcodeModifierWithVal(Tok, NextToken[0]);
3504bool AMDGPUAsmParser::parseSP3NegModifier() {
3506 AsmToken NextToken[2];
3507 peekTokens(NextToken);
3510 (isRegister(NextToken[0], NextToken[1]) ||
3528 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3530 SP3Neg = parseSP3NegModifier();
3533 Neg = trySkipId(
"neg");
3535 return Error(Loc,
"expected register or immediate");
3539 Abs = trySkipId(
"abs");
3544 if (trySkipId(
"lit")) {
3545 Lit = LitModifier::Lit;
3548 }
else if (trySkipId(
"lit64")) {
3549 Lit = LitModifier::Lit64;
3552 if (!has64BitLiterals())
3553 return Error(Loc,
"lit64 is not supported on this GPU");
3559 return Error(Loc,
"expected register or immediate");
3568 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3572 if (
Lit != LitModifier::None && !
Operands.back()->isImm())
3573 Error(Loc,
"expected immediate with lit modifier");
3575 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3581 if (
Lit != LitModifier::None &&
3585 AMDGPUOperand::Modifiers Mods;
3586 Mods.Abs = Abs || SP3Abs;
3587 Mods.Neg = Neg || SP3Neg;
3590 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3591 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3593 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3594 Op.setModifiers(Mods);
3602 bool Sext = trySkipId(
"sext");
3603 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3618 AMDGPUOperand::Modifiers Mods;
3621 if (Mods.hasIntModifiers()) {
3622 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3624 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3625 Op.setModifiers(Mods);
3632 return parseRegOrImmWithFPInputMods(
Operands,
false);
3636 return parseRegOrImmWithIntInputMods(
Operands,
false);
3643 if (!trySkipId(
"rsrcidx"))
3649 SMLoc RegLoc = getLoc();
3650 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3658 if (!
Reg->isRsrcReg32())
3659 return Error(RegLoc,
"rsrcidx operand must be a 32-bit SGPR or VGPR");
3669 auto Loc = getLoc();
3670 if (trySkipId(
"off")) {
3672 AMDGPUOperand::CreateImm(
this, 0, Loc, AMDGPUOperand::ImmTyOff,
false));
3679 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3688unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3693 return Match_InvalidOperand;
3695 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3696 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3699 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3701 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3702 return Match_InvalidOperand;
3710 if (tryAnotherVOPDEncoding(Inst))
3711 return Match_InvalidOperand;
3713 return Match_Success;
3717 static const unsigned Variants[] = {
3726ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3727 if (isForcedDPP() && isForcedVOP3()) {
3731 if (getForcedEncodingSize() == 32) {
3736 if (isForcedVOP3()) {
3741 if (isForcedSDWA()) {
3747 if (isForcedDPP()) {
3755StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3756 if (isForcedDPP() && isForcedVOP3())
3759 if (getForcedEncodingSize() == 32)
3775AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3779 case AMDGPU::FLAT_SCR:
3781 case AMDGPU::VCC_LO:
3782 case AMDGPU::VCC_HI:
3789 return MCRegister();
3796bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3797 unsigned OpIdx)
const {
3805 const MCOperand &MO = Inst.
getOperand(OpIdx);
3855unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3861 case AMDGPU::V_LSHLREV_B64_e64:
3862 case AMDGPU::V_LSHLREV_B64_gfx10:
3863 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3864 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3865 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3866 case AMDGPU::V_LSHRREV_B64_e64:
3867 case AMDGPU::V_LSHRREV_B64_gfx10:
3868 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3869 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3870 case AMDGPU::V_ASHRREV_I64_e64:
3871 case AMDGPU::V_ASHRREV_I64_gfx10:
3872 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3873 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3874 case AMDGPU::V_LSHL_B64_e64:
3875 case AMDGPU::V_LSHR_B64_e64:
3876 case AMDGPU::V_ASHR_I64_e64:
3889 bool AddMandatoryLiterals =
false) {
3892 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3896 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3898 return {getNamedOperandIdx(Opcode, OpName::src0X),
3899 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3900 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3901 getNamedOperandIdx(Opcode, OpName::src0Y),
3902 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3903 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3908 return {getNamedOperandIdx(Opcode, OpName::src0),
3909 getNamedOperandIdx(Opcode, OpName::src1),
3910 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3913bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3914 const MCOperand &MO = Inst.
getOperand(OpIdx);
3916 return !isInlineConstant(Inst, OpIdx);
3923 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3934 const unsigned Opcode = Inst.
getOpcode();
3935 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3938 if (!LaneSelOp.
isReg())
3941 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3944bool AMDGPUAsmParser::validateConstantBusLimitations(
3946 const unsigned Opcode = Inst.
getOpcode();
3947 const MCInstrDesc &
Desc = MII.
get(Opcode);
3948 MCRegister LastSGPR;
3949 unsigned ConstantBusUseCount = 0;
3950 unsigned NumLiterals = 0;
3951 unsigned LiteralSize;
3967 SmallDenseSet<MCRegister> SGPRsUsed;
3968 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3970 SGPRsUsed.
insert(SGPRUsed);
3971 ++ConstantBusUseCount;
3976 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3978 for (
int OpIdx : OpIndices) {
3982 const MCOperand &MO = Inst.
getOperand(OpIdx);
3983 if (usesConstantBus(Inst, OpIdx)) {
3992 if (SGPRsUsed.
insert(LastSGPR).second) {
3993 ++ConstantBusUseCount;
4013 if (NumLiterals == 0) {
4016 }
else if (LiteralSize !=
Size) {
4022 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
4024 "invalid operand (violates constant bus restrictions)");
4031std::optional<unsigned>
4032AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
4034 const unsigned Opcode = Inst.
getOpcode();
4040 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
4041 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
4050 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1170 ||
4051 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
4052 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
4053 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx13 ||
4054 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250 ||
4055 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx13;
4059 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
4060 int I = getNamedOperandIdx(Opcode, OpName);
4064 int64_t
Imm =
Op.getImm();
4070 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
4071 OpName::vsrc2Y, OpName::imm}) {
4072 int I = getNamedOperandIdx(Opcode, OpName);
4082 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
4083 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
4085 return InvalidCompOprIdx;
4088bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
4095 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand :
Operands) {
4096 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
4097 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
4099 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
4103 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
4104 if (!InvalidCompOprIdx.has_value())
4107 auto CompOprIdx = *InvalidCompOprIdx;
4110 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4111 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4114 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
4115 if (CompOprIdx == VOPD::Component::DST) {
4117 Error(Loc,
"dst registers must be distinct");
4119 Error(Loc,
"one dst register must be even and the other odd");
4121 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4122 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4123 " operands must use different VGPR banks");
4131bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4133 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4134 if (!InvalidCompOprIdx.has_value())
4138 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4139 if (InvalidCompOprIdx.has_value()) {
4144 if (*InvalidCompOprIdx == VOPD::Component::DST)
4157bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4158 const unsigned Opcode = Inst.
getOpcode();
4173 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4174 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4175 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4176 int I = getNamedOperandIdx(Opcode, OpName);
4183 return !tryVOPD3(Inst);
4188bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4193 return tryVOPD(Inst);
4194 return tryVOPD3(Inst);
4197bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4202 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4210bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc) {
4218 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4219 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4220 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4225 if ((DMaskIdx == -1 || TFEIdx == -1) &&
4226 hasBVHRayTracingInsts())
4229 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4230 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4235 bool IsPackedD16 =
false;
4238 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4239 IsPackedD16 = D16Idx >= 0;
4241 DataSize = (DataSize + 1) / 2;
4244 if ((VDataSize / 4) == DataSize + TFESize)
4249 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4251 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4253 Error(IDLoc, Twine(
"image data size does not match ") + Modifiers);
4257bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4266 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4268 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4269 AMDGPU::OpName RSrcOpName =
4271 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4272 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4273 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4277 assert(SrsrcIdx > VAddr0Idx);
4280 if (BaseOpcode->
BVH) {
4281 if (IsA16 == BaseOpcode->
A16)
4283 Error(IDLoc,
"image address size does not match a16");
4289 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4290 unsigned ActualAddrSize =
4291 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4293 unsigned ExpectedAddrSize =
4297 if (hasPartialNSAEncoding() &&
4299 int VAddrLastIdx = SrsrcIdx - 1;
4300 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4302 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4305 if (ExpectedAddrSize > 12)
4306 ExpectedAddrSize = 16;
4311 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4315 if (ActualAddrSize == ExpectedAddrSize)
4318 Error(IDLoc,
"image address size does not match dim and a16");
4322bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4329 if (!
Desc.mayLoad() || !
Desc.mayStore())
4332 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4339 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4342bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4349 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4357 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4360bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4374 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4375 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4382bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4389 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4392 if (!BaseOpcode->
MSAA)
4395 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4401 return DimInfo->
MSAA;
4406 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4407 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4408 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4418bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4426 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4429 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4437 Error(getOperandLoc(
Operands, Src0Idx),
"source operand must be a VGPR");
4441bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4446 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4449 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4452 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4460 "source operand must be either a VGPR or an inline constant");
4467bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4472 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4475 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4479 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4481 "inline constants are not allowed for this operand");
4488bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4496 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4497 if (BlgpIdx != -1) {
4498 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4499 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4509 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4511 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4516 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4518 "wrong register tuple size for blgp value " + Twine(BLGP));
4526 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4530 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4534 MCRegister Src2Reg = Src2.
getReg();
4536 if (Src2Reg == DstReg)
4541 .getSizeInBits() <= 128)
4544 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4546 "source 2 operand must not partially overlap with dst");
4553bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4557 case V_DIV_SCALE_F32_gfx6_gfx7:
4558 case V_DIV_SCALE_F32_vi:
4559 case V_DIV_SCALE_F32_gfx10:
4560 case V_DIV_SCALE_F64_gfx6_gfx7:
4561 case V_DIV_SCALE_F64_vi:
4562 case V_DIV_SCALE_F64_gfx10:
4569 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src2_modifiers,
4570 AMDGPU::OpName::src2_modifiers}) {
4581bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4588 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4597bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4603 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4610 case AMDGPU::V_SUBREV_F32_e32:
4611 case AMDGPU::V_SUBREV_F32_e64:
4612 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4613 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4614 case AMDGPU::V_SUBREV_F32_e32_vi:
4615 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4616 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4617 case AMDGPU::V_SUBREV_F32_e64_vi:
4619 case AMDGPU::V_SUBREV_CO_U32_e32:
4620 case AMDGPU::V_SUBREV_CO_U32_e64:
4621 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4622 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4624 case AMDGPU::V_SUBBREV_U32_e32:
4625 case AMDGPU::V_SUBBREV_U32_e64:
4626 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4627 case AMDGPU::V_SUBBREV_U32_e32_vi:
4628 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4629 case AMDGPU::V_SUBBREV_U32_e64_vi:
4631 case AMDGPU::V_SUBREV_U32_e32:
4632 case AMDGPU::V_SUBREV_U32_e64:
4633 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4634 case AMDGPU::V_SUBREV_U32_e32_vi:
4635 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4636 case AMDGPU::V_SUBREV_U32_e64_vi:
4638 case AMDGPU::V_SUBREV_F16_e32:
4639 case AMDGPU::V_SUBREV_F16_e64:
4640 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4641 case AMDGPU::V_SUBREV_F16_e32_vi:
4642 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4643 case AMDGPU::V_SUBREV_F16_e64_vi:
4645 case AMDGPU::V_SUBREV_U16_e32:
4646 case AMDGPU::V_SUBREV_U16_e64:
4647 case AMDGPU::V_SUBREV_U16_e32_vi:
4648 case AMDGPU::V_SUBREV_U16_e64_vi:
4650 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4651 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4652 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4654 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4655 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4657 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4658 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4660 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4661 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4663 case AMDGPU::V_LSHRREV_B32_e32:
4664 case AMDGPU::V_LSHRREV_B32_e64:
4665 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4666 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4667 case AMDGPU::V_LSHRREV_B32_e32_vi:
4668 case AMDGPU::V_LSHRREV_B32_e64_vi:
4669 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4670 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4672 case AMDGPU::V_ASHRREV_I32_e32:
4673 case AMDGPU::V_ASHRREV_I32_e64:
4674 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4675 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4676 case AMDGPU::V_ASHRREV_I32_e32_vi:
4677 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4678 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4679 case AMDGPU::V_ASHRREV_I32_e64_vi:
4681 case AMDGPU::V_LSHLREV_B32_e32:
4682 case AMDGPU::V_LSHLREV_B32_e64:
4683 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4684 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4685 case AMDGPU::V_LSHLREV_B32_e32_vi:
4686 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4687 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4688 case AMDGPU::V_LSHLREV_B32_e64_vi:
4690 case AMDGPU::V_LSHLREV_B16_e32:
4691 case AMDGPU::V_LSHLREV_B16_e64:
4692 case AMDGPU::V_LSHLREV_B16_e32_vi:
4693 case AMDGPU::V_LSHLREV_B16_e64_vi:
4694 case AMDGPU::V_LSHLREV_B16_gfx10:
4696 case AMDGPU::V_LSHRREV_B16_e32:
4697 case AMDGPU::V_LSHRREV_B16_e64:
4698 case AMDGPU::V_LSHRREV_B16_e32_vi:
4699 case AMDGPU::V_LSHRREV_B16_e64_vi:
4700 case AMDGPU::V_LSHRREV_B16_gfx10:
4702 case AMDGPU::V_ASHRREV_I16_e32:
4703 case AMDGPU::V_ASHRREV_I16_e64:
4704 case AMDGPU::V_ASHRREV_I16_e32_vi:
4705 case AMDGPU::V_ASHRREV_I16_e64_vi:
4706 case AMDGPU::V_ASHRREV_I16_gfx10:
4708 case AMDGPU::V_LSHLREV_B64_e64:
4709 case AMDGPU::V_LSHLREV_B64_gfx10:
4710 case AMDGPU::V_LSHLREV_B64_vi:
4712 case AMDGPU::V_LSHRREV_B64_e64:
4713 case AMDGPU::V_LSHRREV_B64_gfx10:
4714 case AMDGPU::V_LSHRREV_B64_vi:
4716 case AMDGPU::V_ASHRREV_I64_e64:
4717 case AMDGPU::V_ASHRREV_I64_gfx10:
4718 case AMDGPU::V_ASHRREV_I64_vi:
4720 case AMDGPU::V_PK_LSHLREV_B16:
4721 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4722 case AMDGPU::V_PK_LSHLREV_B16_vi:
4724 case AMDGPU::V_PK_LSHRREV_B16:
4725 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4726 case AMDGPU::V_PK_LSHRREV_B16_vi:
4727 case AMDGPU::V_PK_ASHRREV_I16:
4728 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4729 case AMDGPU::V_PK_ASHRREV_I16_vi:
4736bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4738 const unsigned Opcode = Inst.
getOpcode();
4747 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4748 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4752 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4756 "lds_direct is not supported on this GPU");
4762 "lds_direct cannot be used with this instruction");
4766 if (SrcName != OpName::src0) {
4768 "lds_direct may be used as src0 only");
4778 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4779 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4780 if (
Op.isFlatOffset())
4781 return Op.getStartLoc();
4786bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4789 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4794 return validateFlatOffset(Inst,
Operands);
4797 return validateSMEMOffset(Inst,
Operands);
4802 const unsigned OffsetSize = 24;
4803 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4805 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4806 "-bit unsigned offset for buffer ops");
4810 const unsigned OffsetSize = 16;
4811 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4813 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4820bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4826 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4830 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4832 "flat offset modifier is not supported on this GPU");
4839 bool AllowNegative =
4841 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4843 Twine(
"expected a ") +
4844 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4845 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4854 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4855 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4856 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4857 return Op.getStartLoc();
4862bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4871 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4887 ?
"expected a 23-bit unsigned offset for buffer ops"
4888 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4889 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4890 :
"expected a 21-bit signed offset");
4900bool AMDGPUAsmParser::validateBF16InlineConst(
const MCInst &Inst,
4902 if (!getFeatureBits()[AMDGPU::FeatureBF16InlineConstFromUpperFP32])
4917 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4921 const MCOperandInfo &Src0Info =
Desc.operands()[Src0Idx];
4925 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4926 if (!Src0.
isImm() ||
4928 hasInv2PiInlineImm()))
4933 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
4934 if (ModsIdx != -1 &&
4940 "bf16 inline constant is read from the high half of the fp32 inline "
4941 "constant on this GPU; use the e64 encoding with op_sel:[1,0]");
4945bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4948 const MCInstrDesc &
Desc = MII.
get(Opcode);
4952 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4953 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4955 const int OpIndices[] = {Src0Idx, Src1Idx};
4957 unsigned NumExprs = 0;
4958 unsigned NumLiterals = 0;
4961 for (
int OpIdx : OpIndices) {
4965 const MCOperand &MO = Inst.
getOperand(OpIdx);
4969 std::optional<int64_t>
Imm;
4972 }
else if (MO.
isExpr()) {
4981 if (!
Imm.has_value()) {
4983 }
else if (!isInlineConstant(Inst, OpIdx)) {
4987 if (NumLiterals == 0 || LiteralValue !=
Value) {
4995 if (NumLiterals + NumExprs <= 1)
4999 "only one unique literal operand is allowed");
5003bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
5006 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5014 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5015 if (OpSelIdx != -1) {
5019 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
5020 if (OpSelHiIdx != -1) {
5029 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5039 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
5040 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5041 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5042 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
5044 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
5045 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5051 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
5053 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
5063 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
5064 if (Src2Idx != -1) {
5065 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
5075bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
5076 if (!hasTrue16Insts())
5078 const MCRegisterInfo *MRI = getMRI();
5080 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5086 if (OpSelOpValue == 0)
5088 unsigned OpCount = 0;
5089 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
5090 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
5091 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
5098 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
5099 if (OpSelOpIsHi != VGPRSuffixIsHi)
5108bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
5109 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
5121 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
5132 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
5133 AMDGPU::OpName::src1_modifiers,
5134 AMDGPU::OpName::src2_modifiers};
5136 for (
unsigned i = 0; i < 3; ++i) {
5146bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5149 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5150 if (DppCtrlIdx >= 0) {
5157 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl,
Operands);
5158 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5159 :
"DP ALU dpp only supports row_newbcast");
5164 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5165 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5168 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5170 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5174 "invalid operand for instruction");
5179 "src1 immediate operand invalid for instruction");
5189bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5190 return (
Reg == AMDGPU::VCC && isWave64()) ||
5191 (
Reg == AMDGPU::VCC_LO && isWave32());
5195bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5198 const MCInstrDesc &
Desc = MII.
get(Opcode);
5199 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5206 std::optional<unsigned> LiteralOpIdx;
5209 for (
int OpIdx : OpIndices) {
5213 const MCOperand &MO = Inst.
getOperand(OpIdx);
5219 std::optional<int64_t>
Imm;
5225 bool IsAnotherLiteral =
false;
5226 bool IsForcedLit = findMCOperand(
Operands, OpIdx).isForcedLit();
5227 bool IsForcedLit64 = findMCOperand(
Operands, OpIdx).isForcedLit64();
5228 if (!
Imm.has_value()) {
5230 IsAnotherLiteral =
true;
5231 }
else if (IsForcedLit || IsForcedLit64 || !isInlineConstant(Inst, OpIdx)) {
5236 HasMandatoryLiteral);
5248 (IsForcedLit64 && !HasMandatoryLiteral)) &&
5249 (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5251 "invalid operand for instruction");
5256 if (!IsForcedFP64 && (IsForcedLit64 || !IsValid32Op) &&
5257 OpIdx != getNamedOperandIdx(Opcode, OpName::src0)) {
5259 "invalid operand for instruction");
5264 if (IsValid32Op && !IsForcedFP64 && !IsForcedLit64) {
5265 Value =
static_cast<uint32_t
>(
5273 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5274 !getFeatureBits()[FeatureVOP3Literal]) {
5276 "literal operands are not supported");
5280 if (LiteralOpIdx && IsAnotherLiteral) {
5282 getOperandLoc(
Operands, *LiteralOpIdx)),
5283 "only one unique literal operand is allowed");
5287 if (IsAnotherLiteral)
5288 LiteralOpIdx = OpIdx;
5297 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), Name);
5311bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5317 ? AMDGPU::OpName::data0
5318 : AMDGPU::OpName::vdata;
5320 const MCRegisterInfo *MRI = getMRI();
5321 int DstAreg =
IsAGPROperand(Inst, AMDGPU::OpName::vdst, MRI);
5325 int Data2Areg =
IsAGPROperand(Inst, AMDGPU::OpName::data1, MRI);
5326 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5330 auto FB = getFeatureBits();
5331 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5332 if (DataAreg < 0 || DstAreg < 0)
5334 return DstAreg == DataAreg;
5337 return DstAreg < 1 && DataAreg < 1;
5340bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5341 auto FB = getFeatureBits();
5342 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5346 const MCRegisterInfo *MRI = getMRI();
5349 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5352 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5356 case AMDGPU::DS_LOAD_TR6_B96:
5357 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5361 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5362 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5366 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5367 if (VAddrIdx != -1) {
5370 if ((
Sub - AMDGPU::VGPR0) & 1)
5375 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5376 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5381 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5382 const MCRegisterClass &AGPR32 = MRI->
getRegClass(AMDGPU::AGPR_32RegClassID);
5402 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
5403 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
5405 return Op.getStartLoc();
5410bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5413 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5416 SMLoc BLGPLoc = getBLGPLoc(
Operands);
5419 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5420 auto FB = getFeatureBits();
5421 bool UsesNeg =
false;
5422 if (FB[AMDGPU::FeatureGFX940Insts]) {
5424 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5425 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5426 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5427 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5432 if (IsNeg == UsesNeg)
5435 Error(BLGPLoc, UsesNeg ?
"invalid modifier: blgp is not supported"
5436 :
"invalid modifier: neg is not supported");
5441bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5447 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5448 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5449 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5450 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5453 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5456 if (
Reg == AMDGPU::SGPR_NULL)
5459 Error(getOperandLoc(
Operands, Src0Idx),
"src0 must be null");
5463bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5468 return validateGWS(Inst,
Operands);
5473 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5478 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS,
Operands);
5479 Error(S,
"gds modifier is not supported on this GPU");
5487bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5489 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5493 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5494 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5497 const MCRegisterInfo *MRI = getMRI();
5498 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5500 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5503 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5505 Error(getOperandLoc(
Operands, Data0Pos),
"vgpr must be even aligned");
5512bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5516 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::cpol);
5524 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5527 Error(S,
"scale_offset is not supported on this GPU");
5530 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5533 Error(S,
"nv is not supported on this GPU");
5538 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5541 Error(S,
"scale_offset is not supported for this instruction");
5545 return validateTHAndScopeBits(Inst,
Operands, CPol);
5549 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5550 Error(S,
"cache policy is not supported for SMRD instructions");
5554 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5561 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5565 "scc modifier is not supported for this instruction on this GPU");
5576 :
"instruction must use glc");
5581 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5584 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5586 :
"instruction must not use glc");
5594bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5596 const unsigned CPol) {
5601 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5608 return PrintError(
"th:TH_ATOMIC_RETURN requires a destination operand");
5613 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5621 return PrintError(
"invalid th value for SMEM instruction");
5628 return PrintError(
"scope and th combination is not valid");
5634 return PrintError(
"invalid th value for atomic instructions");
5637 return PrintError(
"invalid th value for store instructions");
5640 return PrintError(
"invalid th value for load instructions");
5646bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5650 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE,
Operands);
5652 Error(Loc,
"TFE modifier has no meaning for store instructions");
5660bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5666 int AFmtIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
5670 int BFmtIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
5673 auto validateFmt = [&](
unsigned Fmt, AMDGPU::OpName SrcOp) ->
bool {
5674 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5683 "wrong register tuple size for " +
5688 if (!validateFmt(AFmt, AMDGPU::OpName::src0) ||
5689 !validateFmt(BFmt, AMDGPU::OpName::src1))
5693 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
5694 if (AScaleIdx == -1)
5698 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
5702 "invalid matrix and scale format combination");
5709bool AMDGPUAsmParser::validateMonitorSleep(
const MCInst &Inst,
5712 if (
Opc != AMDGPU::S_MONITOR_SLEEP_gfx12 ||
5713 !getSTI().
hasFeature(AMDGPU::FeatureNoSleepForever))
5716 int ImmIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::simm16);
5719 "sleep forever is unsuported on the target");
5726bool AMDGPUAsmParser::validateClusterBarrierIsFirst(
5729 if (
Opc != AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM_gfx12 &&
5730 Opc != AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM_gfx13)
5733 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
5740 "s_barrier_signal_isfirst does not support user_cluster_barrier_id (-3)");
5744bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5746 if (!validateLdsDirect(Inst,
Operands))
5748 if (!validateTrue16OpSel(Inst)) {
5750 "op_sel operand conflicts with 16-bit operand suffix");
5753 if (!validateSOPLiteral(Inst,
Operands))
5755 if (!validateVOPLiteral(Inst,
Operands)) {
5758 if (!validateConstantBusLimitations(Inst,
Operands)) {
5761 if (!validateVOPD(Inst,
Operands)) {
5764 if (!validateIntClampSupported(Inst)) {
5766 "integer clamping is not supported on this GPU");
5769 if (!validateOpSel(Inst)) {
5771 "invalid op_sel operand");
5774 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5776 "invalid neg_lo operand");
5779 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5781 "invalid neg_hi operand");
5784 if (!validateDPP(Inst,
Operands)) {
5788 if (!validateMIMGD16(Inst)) {
5790 "d16 modifier is not supported on this GPU");
5793 if (!validateMIMGDim(Inst,
Operands)) {
5794 Error(IDLoc,
"missing dim operand");
5797 if (!validateTensorR128(Inst)) {
5799 "instruction must set modifier r128=0");
5802 if (!validateMIMGMSAA(Inst)) {
5804 "invalid dim; must be MSAA type");
5807 if (!validateMIMGDataSize(Inst, IDLoc)) {
5810 if (!validateMIMGAddrSize(Inst, IDLoc))
5812 if (!validateMIMGAtomicDMask(Inst)) {
5814 "invalid atomic image dmask");
5817 if (!validateMIMGGatherDMask(Inst)) {
5819 "invalid image_gather dmask: only one bit must be set");
5822 if (!validateMovrels(Inst,
Operands)) {
5825 if (!validateOffset(Inst,
Operands)) {
5828 if (!validateBF16InlineConst(Inst,
Operands)) {
5831 if (!validateMAIAccWrite(Inst,
Operands)) {
5834 if (!validateMAISrc2(Inst,
Operands)) {
5837 if (!validateMFMA(Inst,
Operands)) {
5840 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5844 if (!validateAGPRLdSt(Inst)) {
5847 getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5848 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5849 :
"invalid register class: agpr loads and stores not supported on "
5853 if (!validateVGPRAlign(Inst)) {
5854 Error(IDLoc,
"invalid register class: vgpr tuples must be 64 bit aligned");
5861 if (!validateBLGP(Inst,
Operands)) {
5865 if (!validateDivScale(Inst)) {
5866 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5869 if (!validateWaitCnt(Inst,
Operands)) {
5872 if (!validateTFE(Inst,
Operands)) {
5875 if (!validateWMMA(Inst,
Operands)) {
5878 if (!validateMonitorSleep(Inst,
Operands)) {
5881 if (!validateClusterBarrierIsFirst(Inst,
Operands)) {
5890 unsigned VariantID = 0);
5894 unsigned VariantID);
5896bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5901bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5902 const FeatureBitset &FBS,
5903 ArrayRef<unsigned> Variants) {
5904 for (
auto Variant : Variants) {
5912bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5914 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5917 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5922 getParser().clearPendingErrors();
5926 StringRef VariantName = getMatchedVariantName();
5927 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5928 return Error(IDLoc, Twine(VariantName,
5929 " variant of this instruction is not supported"));
5933 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5934 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5936 FeatureBitset FeaturesWS32 = getFeatureBits();
5937 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5938 .
flip(AMDGPU::FeatureWavefrontSize32);
5939 FeatureBitset AvailableFeaturesWS32 =
5940 ComputeAvailableFeatures(FeaturesWS32);
5942 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5943 return Error(IDLoc,
"instruction requires wavesize=32");
5947 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5948 return Error(IDLoc,
"instruction not supported on this GPU (" +
5949 getSTI().
getCPU() +
")" +
": " + Mnemo);
5954 return Error(IDLoc,
"invalid instruction" + Suggestion);
5960 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5961 if (
Op.isToken() && InvalidOprIdx > 1) {
5962 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5963 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5968bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5972 bool MatchingInlineAsm) {
5975 unsigned Result = Match_Success;
5980 auto atLeastAsSpecific = [](
unsigned New,
unsigned Cur) {
5981 auto rank = [](
unsigned M) {
5982 return M == Match_MnemonicFail ? 1
5983 :
M == Match_InvalidOperand ? 2
5984 :
M == Match_MissingFeature ? 3
5987 return rank(New) >= rank(Cur);
5990 for (
auto Variant : getMatchedVariants()) {
5993 MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm, Variant);
5994 if (R == Match_Success || atLeastAsSpecific(R, Result)) {
5998 if (R == Match_Success)
6002 if (Result == Match_Success) {
6003 if (!validateInstruction(Inst, IDLoc,
Operands)) {
6006 emitTargetDirective();
6007 Out.emitInstruction(Inst, getSTI());
6014 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
6021 case Match_MissingFeature:
6025 return Error(IDLoc,
"operands are not valid for this GPU or mode");
6027 case Match_InvalidOperand: {
6028 SMLoc ErrorLoc = IDLoc;
6029 if (ErrorInfo != ~0ULL) {
6030 if (ErrorInfo >=
Operands.size()) {
6031 return Error(IDLoc,
"too few operands for instruction");
6033 AMDGPUOperand &ErrorOp = (AMDGPUOperand &)*
Operands[ErrorInfo];
6034 ErrorLoc = ErrorOp.getStartLoc();
6035 if (ErrorLoc == SMLoc())
6039 return Error(ErrorLoc,
"invalid VOPDY instruction");
6041 return Error(ErrorLoc,
"invalid operand for instruction");
6044 case Match_MnemonicFail:
6050bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
6055 if (getParser().parseAbsoluteExpression(Tmp)) {
6058 Ret =
static_cast<uint32_t
>(Tmp);
6062bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
6063 if (!getSTI().getTargetTriple().isAMDGCN())
6064 return TokError(
"directive only supported for amdgcn architecture");
6066 std::string TargetIDDirective;
6067 SMLoc TargetStart = getTok().getLoc();
6068 if (getParser().parseEscapedString(TargetIDDirective))
6071 std::optional<AMDGPU::TargetID> MaybeParsed =
6074 return getParser().Error(TargetStart,
6075 "malformed target id '" + TargetIDDirective +
"'");
6078 const Triple &
TT = getSTI().getTargetTriple();
6084 return getParser().Error(
6085 TargetStart,
"target id '" + TargetIDDirective +
6086 "' specifies a processor that is not valid for "
6088 TT.getArchName() +
"'");
6091 const std::optional<AMDGPU::TargetID> &CurrentTargetID =
6092 getTargetStreamer().getTargetID();
6095 const Triple &STITriple = getSTI().getTargetTriple();
6096 if (!DirectiveTriple.isCompatibleWith(STITriple)) {
6097 return getParser().Error(
6098 TargetStart,
".amdgcn_target " + Twine(ParsedTargetID.
toString()) +
6099 " is incompatible with " +
6100 Twine(CurrentTargetID->toString()));
6104 StringRef DirectiveProcessor =
6107 if (DirectiveISA != ISA) {
6108 return getParser().Error(TargetStart,
6109 ".amdgcn_target directive processor " +
6110 Twine(DirectiveProcessor) +
6111 " does not match the specified processor " +
6112 Twine(getSTI().
getCPU()));
6118 CurrentTargetID->getXnackSetting())) {
6120 ".amdgcn_target directive has conflicting xnack settings");
6124 CurrentTargetID->getSramEccSetting())) {
6126 ".amdgcn_target directive has conflicting sramecc settings");
6132 getTargetStreamer().getTargetID()->setXnackSetting(
6134 getTargetStreamer().getTargetID()->setSramEccSetting(
6140bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
6144bool AMDGPUAsmParser::calculateGPRBlocks(
6145 const FeatureBitset &Features,
const MCExpr *VCCUsed,
6146 const MCExpr *FlatScrUsed,
bool XNACKUsed,
6147 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
6148 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
6149 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
6154 const MCExpr *
NumSGPRs = NextFreeSGPR;
6155 int64_t EvaluatedSGPRs;
6157 if (
ISA.Major >= 10)
6162 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
ISA.Major >= 8 &&
6163 !Features.
test(FeatureSGPRInitBug) &&
6164 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
6165 return OutOfRangeError(SGPRRange);
6167 const MCExpr *ExtraSGPRs =
6171 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
6172 (
ISA.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
6173 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
6174 return OutOfRangeError(SGPRRange);
6176 if (Features.
test(FeatureSGPRInitBug))
6183 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
6184 unsigned Granule) ->
const MCExpr * {
6188 const MCExpr *AlignToGPR =
6190 const MCExpr *DivGPR =
6196 VGPRBlocks = GetNumGPRBlocks(
6205bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
6206 if (!getSTI().getTargetTriple().isAMDGCN())
6207 return TokError(
"directive only supported for amdgcn architecture");
6210 return TokError(
"directive only supported for amdhsa OS");
6212 StringRef KernelName;
6213 if (getParser().parseIdentifier(KernelName))
6220 AMDGPU::MCKernelDescriptor KD =
6230 const MCExpr *NextFreeVGPR = ZeroExpr;
6232 const MCExpr *NamedBarCnt = ZeroExpr;
6237 const MCExpr *NextFreeSGPR = ZeroExpr;
6240 unsigned ImpliedUserSGPRCount = 0;
6244 std::optional<unsigned> ExplicitUserSGPRCount;
6245 const MCExpr *ReserveVCC = OneExpr;
6246 const MCExpr *ReserveFlatScr = OneExpr;
6247 std::optional<bool> EnableWavefrontSize32;
6254 SMRange IDRange = getTok().getLocRange();
6255 if (!parseId(ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6258 if (ID ==
".end_amdhsa_kernel")
6261 if (!Seen.
insert(ID).second)
6262 return TokError(
".amdhsa_ directives cannot be repeated");
6264 SMLoc ValStart = getLoc();
6265 const MCExpr *ExprVal;
6266 if (getParser().parseExpression(ExprVal))
6268 SMLoc ValEnd = getLoc();
6269 SMRange ValRange = SMRange(ValStart, ValEnd);
6273 bool EvaluatableExpr;
6274 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6276 return OutOfRangeError(ValRange);
6280#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6281 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6282 return OutOfRangeError(RANGE); \
6283 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6288#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6290 return Error(IDRange.Start, "directive should have resolvable expression", \
6293 if (ID ==
".amdhsa_group_segment_fixed_size") {
6296 return OutOfRangeError(ValRange);
6298 }
else if (ID ==
".amdhsa_private_segment_fixed_size") {
6301 return OutOfRangeError(ValRange);
6303 }
else if (ID ==
".amdhsa_kernarg_size") {
6305 return OutOfRangeError(ValRange);
6307 }
else if (ID ==
".amdhsa_user_sgpr_count") {
6309 ExplicitUserSGPRCount = Val;
6310 }
else if (ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6314 "directive is not supported with architected flat scratch",
6317 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6320 ImpliedUserSGPRCount += 4;
6321 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6324 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6327 return OutOfRangeError(ValRange);
6331 ImpliedUserSGPRCount += Val;
6332 PreloadLength = Val;
6334 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6337 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6340 return OutOfRangeError(ValRange);
6344 PreloadOffset = Val;
6345 }
else if (ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6348 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6351 ImpliedUserSGPRCount += 2;
6352 }
else if (ID ==
".amdhsa_user_sgpr_queue_ptr") {
6355 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6358 ImpliedUserSGPRCount += 2;
6359 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6362 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6365 ImpliedUserSGPRCount += 2;
6366 }
else if (ID ==
".amdhsa_user_sgpr_dispatch_id") {
6369 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6372 ImpliedUserSGPRCount += 2;
6373 }
else if (ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6376 "directive is not supported with architected flat scratch",
6380 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6383 ImpliedUserSGPRCount += 2;
6384 }
else if (ID ==
".amdhsa_user_sgpr_private_segment_size") {
6387 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6390 ImpliedUserSGPRCount += 1;
6391 }
else if (ID ==
".amdhsa_wavefront_size32") {
6394 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6395 EnableWavefrontSize32 = Val;
6397 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6399 }
else if (ID ==
".amdhsa_uses_dynamic_stack") {
6401 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6403 }
else if (ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6406 "directive is not supported with architected flat scratch",
6409 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6411 }
else if (ID ==
".amdhsa_enable_private_segment") {
6415 "directive is not supported without architected flat scratch",
6418 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6420 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6422 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6424 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6426 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6428 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6430 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6432 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_info") {
6434 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6436 }
else if (ID ==
".amdhsa_system_vgpr_workitem_id") {
6438 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6440 }
else if (ID ==
".amdhsa_next_free_vgpr") {
6441 VGPRRange = ValRange;
6442 NextFreeVGPR = ExprVal;
6443 }
else if (ID ==
".amdhsa_next_free_sgpr") {
6444 SGPRRange = ValRange;
6445 NextFreeSGPR = ExprVal;
6446 }
else if (ID ==
".amdhsa_accum_offset") {
6448 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6449 AccumOffset = ExprVal;
6450 }
else if (ID ==
".amdhsa_named_barrier_count") {
6452 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6453 NamedBarCnt = ExprVal;
6454 }
else if (ID ==
".amdhsa_reserve_vcc") {
6456 return OutOfRangeError(ValRange);
6457 ReserveVCC = ExprVal;
6458 }
else if (ID ==
".amdhsa_reserve_flat_scratch") {
6460 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6463 "directive is not supported with architected flat scratch",
6466 return OutOfRangeError(ValRange);
6467 ReserveFlatScr = ExprVal;
6468 }
else if (ID ==
".amdhsa_reserve_xnack_mask") {
6470 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6472 return OutOfRangeError(ValRange);
6473 bool XnackOn = getTargetStreamer().getTargetID()->isXnackOnOrAny();
6474 if (Val != XnackOn) {
6475 return getParser().Error(
6477 ".amdhsa_reserve_xnack_mask does not match target id", IDRange);
6479 }
else if (ID ==
".amdhsa_float_round_mode_32") {
6481 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6483 }
else if (ID ==
".amdhsa_float_round_mode_16_64") {
6485 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6487 }
else if (ID ==
".amdhsa_float_denorm_mode_32") {
6489 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6491 }
else if (ID ==
".amdhsa_float_denorm_mode_16_64") {
6493 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6495 }
else if (ID ==
".amdhsa_dx10_clamp") {
6496 if (!getSTI().
hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6497 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6500 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6502 }
else if (ID ==
".amdhsa_ieee_mode") {
6503 if (!getSTI().
hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6504 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6507 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6509 }
else if (ID ==
".amdhsa_fp16_overflow") {
6511 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6513 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6515 }
else if (ID ==
".amdhsa_tg_split") {
6517 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6520 }
else if (ID ==
".amdhsa_workgroup_processor_mode") {
6523 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6525 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6527 }
else if (ID ==
".amdhsa_memory_ordered") {
6529 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6531 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6533 }
else if (ID ==
".amdhsa_forward_progress") {
6535 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6537 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6539 }
else if (ID ==
".amdhsa_shared_vgpr_count") {
6541 if (
ISA.Major < 10 ||
ISA.Major >= 12)
6542 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6544 SharedVGPRCount = Val;
6546 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6548 }
else if (ID ==
".amdhsa_inst_pref_size") {
6550 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6551 if (
ISA.Major == 11) {
6553 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6557 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6560 }
else if (ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6563 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6565 }
else if (ID ==
".amdhsa_exception_fp_denorm_src") {
6567 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6569 }
else if (ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6572 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6574 }
else if (ID ==
".amdhsa_exception_fp_ieee_overflow") {
6576 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6578 }
else if (ID ==
".amdhsa_exception_fp_ieee_underflow") {
6580 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6582 }
else if (ID ==
".amdhsa_exception_fp_ieee_inexact") {
6584 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6586 }
else if (ID ==
".amdhsa_exception_int_div_zero") {
6588 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6590 }
else if (ID ==
".amdhsa_round_robin_scheduling") {
6592 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6594 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6597 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6600#undef PARSE_BITS_ENTRY
6603 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6604 return TokError(
".amdhsa_next_free_vgpr directive is required");
6606 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6607 return TokError(
".amdhsa_next_free_sgpr directive is required");
6609 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6611 return TokError(
"too many user SGPRs enabled, found " +
6612 Twine(UserSGPRCount) +
", but only " +
6618 if (PreloadLength) {
6624 const MCExpr *VGPRBlocks;
6625 const MCExpr *SGPRBlocks;
6626 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6627 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6628 EnableWavefrontSize32, NextFreeVGPR, VGPRRange,
6629 NextFreeSGPR, SGPRRange, VGPRBlocks, SGPRBlocks))
6632 int64_t EvaluatedVGPRBlocks;
6633 bool VGPRBlocksEvaluatable =
6634 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6635 if (VGPRBlocksEvaluatable &&
6637 static_cast<uint64_t>(EvaluatedVGPRBlocks))) {
6638 return OutOfRangeError(VGPRRange);
6642 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6643 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6645 int64_t EvaluatedSGPRBlocks;
6646 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6648 static_cast<uint64_t>(EvaluatedSGPRBlocks)))
6649 return OutOfRangeError(SGPRRange);
6652 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6653 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6655 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6656 return TokError(
"amdgpu_user_sgpr_count smaller than implied by "
6657 "enabled user SGPRs");
6663 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6664 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6669 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6670 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6675 return TokError(
"Kernarg size should be resolvable");
6677 if (PreloadLength && kernarg_size &&
6678 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6679 return TokError(
"Kernarg preload length + offset is larger than the "
6680 "kernarg segment size");
6683 if (!Seen.
contains(
".amdhsa_accum_offset"))
6684 return TokError(
".amdhsa_accum_offset directive is required");
6685 int64_t EvaluatedAccum;
6686 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6687 uint64_t UEvaluatedAccum = EvaluatedAccum;
6688 if (AccumEvaluatable &&
6689 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6690 return TokError(
"accum_offset should be in range [4..256] in "
6693 int64_t EvaluatedNumVGPR;
6694 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6698 return TokError(
"accum_offset exceeds total VGPR allocation");
6704 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6705 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6711 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6712 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6715 if (
ISA.Major >= 10 &&
ISA.Major < 12) {
6717 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6718 return TokError(
"shared_vgpr_count directive not valid on "
6719 "wavefront size 32");
6722 if (VGPRBlocksEvaluatable &&
6723 (SharedVGPRCount * 2 +
static_cast<uint64_t>(EvaluatedVGPRBlocks) >
6725 return TokError(
"shared_vgpr_count*2 + "
6726 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6731 emitTargetDirective();
6732 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6733 NextFreeVGPR, NextFreeSGPR,
6734 ReserveVCC, ReserveFlatScr);
6738bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6740 if (ParseAsAbsoluteExpression(
Version))
6743 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6744 emitTargetDirective();
6748bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
6749 AMDGPUMCKernelCodeT &
C) {
6752 if (ID ==
"max_scratch_backing_memory_byte_size") {
6753 Parser.eatToEndOfStatement();
6757 SmallString<40> ErrStr;
6758 raw_svector_ostream Err(ErrStr);
6759 if (!
C.ParseKernelCodeT(ID, getParser(), Err)) {
6760 return TokError(Err.
str());
6764 if (ID ==
"enable_wavefront_size32") {
6767 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6769 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6772 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6776 if (ID ==
"wavefront_size") {
6777 if (
C.wavefront_size == 5) {
6779 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6781 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6782 }
else if (
C.wavefront_size == 6) {
6784 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6791bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6792 AMDGPUMCKernelCodeT KernelCode;
6802 if (!parseId(ID,
"expected value identifier or .end_amd_kernel_code_t"))
6805 if (ID ==
".end_amd_kernel_code_t")
6808 if (ParseAMDKernelCodeTValue(ID, KernelCode))
6813 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6818bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6819 StringRef KernelName;
6820 if (!parseId(KernelName,
"expected symbol name"))
6823 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6830bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6831 if (!getSTI().getTargetTriple().isAMDGCN()) {
6832 return Error(getLoc(),
6833 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6837 StringRef TargetIDDirective = getLexer().getTok().getStringContents();
6839 std::optional<AMDGPU::TargetID> MaybeParsed =
6842 return Error(getParser().getTok().getLoc(),
6843 "malformed target id '" + TargetIDDirective +
"'");
6846 const Triple &
TT = getSTI().getTargetTriple();
6852 return Error(getParser().getTok().getLoc(),
6853 "target id '" + TargetIDDirective +
6854 "' specifies a processor that is not valid for subarch '" +
6855 TT.getArchName() +
"'");
6858 const std::optional<AMDGPU::TargetID> &CurrentTargetID =
6859 getTargetStreamer().getTargetID();
6862 const Triple &STITriple = getSTI().getTargetTriple();
6863 if (!DirectiveTriple.isCompatibleWith(STITriple)) {
6864 return Error(getParser().getTok().getLoc(),
6865 ".amd_amdgpu_isa " + Twine(ParsedTargetID.
toString()) +
6866 " is incompatible with " +
6867 Twine(CurrentTargetID->toString()));
6871 StringRef DirectiveProcessor =
6874 if (DirectiveISA != ISA) {
6875 return Error(getParser().getTok().getLoc(),
6876 ".amd_amdgpu_isa directive processor " +
6877 Twine(DirectiveProcessor) +
6878 " does not match the specified processor " +
6879 Twine(getSTI().
getCPU()));
6882 getTargetStreamer().EmitISAVersion();
6888bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6891 std::string HSAMetadataString;
6896 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6897 return Error(getLoc(),
"invalid HSA metadata");
6904bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6905 const char *AssemblerDirectiveEnd,
6906 std::string &CollectString) {
6908 raw_string_ostream CollectStream(CollectString);
6910 getLexer().setSkipSpace(
false);
6912 bool FoundEnd =
false;
6915 CollectStream << getTokenStr();
6919 if (trySkipId(AssemblerDirectiveEnd)) {
6924 CollectStream << Parser.parseStringToEndOfStatement()
6925 <<
getContext().getAsmInfo().getSeparatorString();
6927 Parser.eatToEndOfStatement();
6930 getLexer().setSkipSpace(
true);
6933 return TokError(Twine(
"expected directive ") +
6934 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6941bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6947 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6948 if (!PALMetadata->setFromString(
String))
6949 return Error(getLoc(),
"invalid PAL metadata");
6954bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6957 Twine(
" directive is "
6958 "not available on non-amdpal OSes"))
6962 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6963 PALMetadata->setLegacy();
6966 if (ParseAsAbsoluteExpression(
Key)) {
6967 return TokError(Twine(
"invalid value in ") +
6971 return TokError(Twine(
"expected an even number of values in ") +
6974 if (ParseAsAbsoluteExpression(
Value)) {
6975 return TokError(Twine(
"invalid value in ") +
6978 PALMetadata->setRegister(
Key,
Value);
6987bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6988 if (getParser().checkForValidSection())
6992 SMLoc NameLoc = getLoc();
6993 if (getParser().parseIdentifier(Name))
6994 return TokError(
"expected identifier in directive");
6997 if (getParser().parseComma())
7003 SMLoc SizeLoc = getLoc();
7004 if (getParser().parseAbsoluteExpression(
Size))
7007 return Error(SizeLoc,
"size must be non-negative");
7008 if (
Size > LocalMemorySize)
7009 return Error(SizeLoc,
"size is too large");
7013 SMLoc AlignLoc = getLoc();
7014 if (getParser().parseAbsoluteExpression(Alignment))
7017 return Error(AlignLoc,
"alignment must be a power of two");
7022 if (Alignment >= 1u << 31)
7023 return Error(AlignLoc,
"alignment is too large");
7029 Symbol->redefineIfPossible();
7030 if (!
Symbol->isUndefined())
7031 return Error(NameLoc,
"invalid symbol redefinition");
7033 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
7037bool AMDGPUAsmParser::ParseDirectiveAMDGPUInfo() {
7038 if (getParser().checkForValidSection())
7042 if (getParser().parseIdentifier(FuncName))
7043 return TokError(
"expected symbol name after .amdgpu_info");
7046 AMDGPU::InfoSectionData ParsedInfoData;
7047 AMDGPU::FuncInfo FI;
7049 bool HasScalarAttrs =
false;
7056 SMLoc IDLoc = getLoc();
7057 if (!parseId(ID,
"expected directive or .end_amdgpu_info"))
7060 if (ID ==
".end_amdgpu_info")
7068 return Error(IDLoc,
"unknown .amdgpu_info directive '" + ID +
"'");
7070 if (Dir ==
"flags") {
7072 if (getParser().parseAbsoluteExpression(Val))
7075 FI.
UsesVCC = !!(
Flags & AMDGPU::FuncInfoFlags::FUNC_USES_VCC);
7077 !!(
Flags & AMDGPU::FuncInfoFlags::FUNC_USES_FLAT_SCRATCH);
7079 HasScalarAttrs =
true;
7080 }
else if (Dir ==
"num_sgpr") {
7082 if (getParser().parseAbsoluteExpression(Val))
7084 FI.
NumSGPR =
static_cast<uint32_t
>(Val);
7085 HasScalarAttrs =
true;
7086 }
else if (Dir ==
"num_vgpr") {
7088 if (getParser().parseAbsoluteExpression(Val))
7091 HasScalarAttrs =
true;
7092 }
else if (Dir ==
"num_agpr") {
7094 if (getParser().parseAbsoluteExpression(Val))
7097 HasScalarAttrs =
true;
7098 }
else if (Dir ==
"private_segment_size") {
7100 if (getParser().parseAbsoluteExpression(Val))
7103 HasScalarAttrs =
true;
7104 }
else if (Dir ==
"use") {
7106 if (getParser().parseIdentifier(ResName))
7107 return TokError(
"expected resource symbol for .amdgpu_use");
7108 ParsedInfoData.
Uses.push_back(
7109 {FuncSym,
getContext().getOrCreateSymbol(ResName)});
7110 }
else if (Dir ==
"call") {
7112 if (getParser().parseIdentifier(DstName))
7113 return TokError(
"expected callee symbol for .amdgpu_call");
7114 ParsedInfoData.
Calls.push_back(
7115 {FuncSym,
getContext().getOrCreateSymbol(DstName)});
7116 }
else if (Dir ==
"indirect_call") {
7118 if (getParser().parseEscapedString(TypeId))
7119 return TokError(
"expected type ID string for .amdgpu_indirect_call");
7120 ParsedInfoData.
IndirectCalls.push_back({FuncSym, std::move(TypeId)});
7121 }
else if (Dir ==
"typeid") {
7123 if (getParser().parseEscapedString(TypeId))
7124 return TokError(
"expected type ID string for .amdgpu_typeid");
7125 ParsedInfoData.
TypeIds.push_back({FuncSym, std::move(TypeId)});
7127 return Error(IDLoc,
"unknown .amdgpu_info directive '" + ID +
"'");
7132 ParsedInfoData.
Funcs.push_back(std::move(FI));
7134 AMDGPU::InfoSectionData &
Data = InfoData ? *InfoData : InfoData.emplace();
7135 for (AMDGPU::FuncInfo &Func : ParsedInfoData.
Funcs)
7136 Data.Funcs.push_back(std::move(Func));
7137 for (std::pair<MCSymbol *, MCSymbol *> &Use : ParsedInfoData.
Uses)
7138 Data.Uses.push_back(Use);
7139 for (std::pair<MCSymbol *, MCSymbol *> &
Call : ParsedInfoData.
Calls)
7141 for (std::pair<MCSymbol *, std::string> &
IndirectCall :
7144 for (std::pair<MCSymbol *, std::string> &TypeId : ParsedInfoData.
TypeIds)
7145 Data.TypeIds.push_back(std::move(TypeId));
7150void AMDGPUAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
7157void AMDGPUAsmParser::checkKernelPrologues() {
7158 if (getFeatureBits()[AMDGPU::FeatureRequiresInitialUnclausedVmem]) {
7159 static const unsigned Required[] = {S_MOV_B64_gfx12, V_NOP_e32_gfx12,
7160 GLOBAL_PREFETCH_B8_SADDR_gfx1250};
7161 for (
auto [Sym, Loc,
Offset] : OpcodeStreamSymbols) {
7162 if (!AMDHSAKernelSymbols.
contains(Sym))
7164 ArrayRef<unsigned> Prologue =
ArrayRef(OpcodeStream).drop_front(
Offset);
7165 if (!Prologue.
empty() && Prologue.
front() == S_SETREG_IMM32_B32_gfx12)
7169 "' does not begin with the required prologue "
7170 "sequence: s_mov_b64 followed by v_nop and "
7171 "global_prefetch_b8");
7175 OpcodeStream.
clear();
7176 OpcodeStreamSymbols.clear();
7177 AMDHSAKernelSymbols.
clear();
7180void AMDGPUAsmParser::onEndOfFile() {
7181 emitTargetDirective();
7182 checkKernelPrologues();
7184 getTargetStreamer().emitAMDGPUInfo(*InfoData);
7187bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
7188 StringRef IDVal = DirectiveID.
getString();
7191 if (IDVal ==
".amdhsa_kernel")
7192 return ParseDirectiveAMDHSAKernel();
7194 if (IDVal ==
".amdhsa_code_object_version")
7195 return ParseDirectiveAMDHSACodeObjectVersion();
7199 return ParseDirectiveHSAMetadata();
7201 if (IDVal ==
".amd_kernel_code_t")
7202 return ParseDirectiveAMDKernelCodeT();
7204 if (IDVal ==
".amdgpu_hsa_kernel")
7205 return ParseDirectiveAMDGPUHsaKernel();
7207 if (IDVal ==
".amd_amdgpu_isa")
7208 return ParseDirectiveISAVersion();
7212 Twine(
" directive is "
7213 "not available on non-amdhsa OSes"))
7218 if (IDVal ==
".amdgcn_target")
7219 return ParseDirectiveAMDGCNTarget();
7221 if (IDVal ==
".amdgpu_lds")
7222 return ParseDirectiveAMDGPULDS();
7224 if (IDVal ==
".amdgpu_info")
7225 return ParseDirectiveAMDGPUInfo();
7228 return ParseDirectivePALMetadataBegin();
7231 return ParseDirectivePALMetadata();
7236bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &MRI,
7243 return hasSGPR104_SGPR105();
7246 case SRC_SHARED_BASE_LO:
7247 case SRC_SHARED_BASE:
7248 case SRC_SHARED_LIMIT_LO:
7249 case SRC_SHARED_LIMIT:
7251 case SRC_PRIVATE_BASE_LO:
7252 case SRC_PRIVATE_BASE:
7253 case SRC_PRIVATE_LIMIT_LO:
7254 case SRC_PRIVATE_LIMIT:
7256 case SRC_FLAT_SCRATCH_BASE_LO:
7257 case SRC_FLAT_SCRATCH_BASE_HI:
7258 return hasGloballyAddressableScratch();
7259 case SRC_POPS_EXITING_WAVE_ID:
7272 getTargetStreamer().getTargetID()->isXnackSupported();
7302 return hasSGPR102_SGPR103();
7310 ParseStatus Res = parseVOPD(
Operands);
7315 Res = MatchOperandParserImpl(
Operands, Mnemonic);
7327 SMLoc LBraceLoc = getLoc();
7332 auto Loc = getLoc();
7335 Error(Loc,
"expected a register");
7339 RBraceLoc = getLoc();
7344 "expected a comma or a closing square bracket"))
7348 if (
Operands.size() - Prefix > 1) {
7350 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
7351 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
7360StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
7362 setForcedEncodingSize(0);
7363 setForcedDPP(
false);
7364 setForcedSDWA(
false);
7366 if (
Name.consume_back(
"_e64_dpp")) {
7368 setForcedEncodingSize(64);
7371 if (
Name.consume_back(
"_e64")) {
7372 setForcedEncodingSize(64);
7375 if (
Name.consume_back(
"_e32")) {
7376 setForcedEncodingSize(32);
7379 if (
Name.consume_back(
"_dpp")) {
7383 if (
Name.consume_back(
"_sdwa")) {
7384 setForcedSDWA(
true);
7392 unsigned VariantID);
7398 Name = parseMnemonicSuffix(Name);
7404 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
7406 bool IsMIMG = Name.starts_with(
"image_");
7409 OperandMode
Mode = OperandMode_Default;
7411 Mode = OperandMode_NSA;
7415 checkUnsupportedInstruction(Name, NameLoc);
7416 if (!Parser.hasPendingError()) {
7419 :
"not a valid operand.";
7439ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
7442 if (!trySkipId(Name))
7445 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, S));
7449ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7458ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7460 std::function<
bool(int64_t &)> ConvertResult) {
7464 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7468 if (ConvertResult && !ConvertResult(
Value)) {
7469 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7472 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7476ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7478 bool (*ConvertResult)(int64_t &)) {
7487 const unsigned MaxSize = 4;
7491 for (
int I = 0;; ++
I) {
7493 SMLoc Loc = getLoc();
7497 if (
Op != 0 &&
Op != 1)
7498 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7505 if (
I + 1 == MaxSize)
7506 return Error(getLoc(),
"expected a closing square bracket");
7512 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7516ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7518 AMDGPUOperand::ImmTy ImmTy,
7519 bool IgnoreNegative) {
7523 if (trySkipId(Name)) {
7525 }
else if (trySkipId(
"no", Name)) {
7534 return Error(S,
"r128 modifier is not supported on this GPU");
7535 if (Name ==
"a16" && !
hasA16())
7536 return Error(S,
"a16 modifier is not supported on this GPU");
7538 if (Bit == 0 && Name ==
"gds") {
7541 return Error(S,
"nogds is not allowed");
7544 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7545 ImmTy = AMDGPUOperand::ImmTyR128A16;
7547 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7551unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7552 bool &Disabling)
const {
7553 Disabling =
Id.consume_front(
"no");
7556 return StringSwitch<unsigned>(Id)
7563 return StringSwitch<unsigned>(Id)
7573 SMLoc StringLoc = getLoc();
7575 int64_t CPolVal = 0;
7595 ResScope = parseScope(
Operands, Scope);
7608 if (trySkipId(
"nv")) {
7612 }
else if (trySkipId(
"no",
"nv")) {
7619 if (trySkipId(
"scale_offset")) {
7623 }
else if (trySkipId(
"no",
"scale_offset")) {
7636 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7637 AMDGPUOperand::ImmTyCPol));
7642 SMLoc OpLoc = getLoc();
7643 unsigned Enabled = 0, Seen = 0;
7647 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7654 return Error(S,
"dlc modifier is not supported on this GPU");
7657 return Error(S,
"scc modifier is not supported on this GPU");
7660 return Error(S,
"duplicate cache policy modifier");
7672 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7681 ParseStatus Res = parseStringOrIntWithPrefix(
7682 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7696 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7700 if (
Value ==
"TH_DEFAULT")
7702 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7703 Value ==
"TH_LOAD_NT_WB") {
7704 return Error(StringLoc,
"invalid th value");
7705 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7707 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7709 }
else if (
Value.consume_front(
"TH_STORE_")) {
7712 return Error(StringLoc,
"invalid th value");
7715 if (
Value ==
"BYPASS")
7720 TH |= StringSwitch<int64_t>(
Value)
7730 .Default(0xffffffff);
7732 TH |= StringSwitch<int64_t>(
Value)
7743 .Default(0xffffffff);
7746 if (TH == 0xffffffff)
7747 return Error(StringLoc,
"invalid th value");
7754 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7755 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7756 std::optional<unsigned> InsertAt = std::nullopt) {
7757 auto i = OptionalIdx.find(ImmT);
7758 if (i != OptionalIdx.end()) {
7759 unsigned Idx = i->second;
7760 const AMDGPUOperand &
Op =
7761 static_cast<const AMDGPUOperand &
>(*
Operands[Idx]);
7765 Op.addImmOperands(Inst, 1);
7767 if (InsertAt.has_value())
7774ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7780 StringLoc = getLoc();
7785ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7791 SMLoc StringLoc = getLoc();
7795 Value = getTokenStr();
7799 if (
Value == Ids[IntVal])
7804 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7805 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7810ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7812 AMDGPUOperand::ImmTy
Type) {
7816 ParseStatus Res = parseStringOrIntWithPrefix(
Operands, Name, Ids, IntVal);
7818 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7827bool AMDGPUAsmParser::tryParseFmt(
const char *Pref, int64_t MaxVal,
7830 SMLoc Loc = getLoc();
7832 auto Res = parseIntWithPrefix(Pref, Val);
7838 if (Val < 0 || Val > MaxVal) {
7839 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7848 AMDGPUOperand::ImmTy ImmTy) {
7849 const char *Pref =
"index_key";
7851 SMLoc Loc = getLoc();
7852 auto Res = parseIntWithPrefix(Pref, ImmVal);
7856 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7857 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7858 (ImmVal < 0 || ImmVal > 1))
7859 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7861 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7862 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7864 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7869 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7873 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7877 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7882 AMDGPUOperand::ImmTy
Type) {
7888 return tryParseMatrixFMT(
Operands,
"matrix_a_fmt",
7889 AMDGPUOperand::ImmTyMatrixAFMT);
7893 return tryParseMatrixFMT(
Operands,
"matrix_b_fmt",
7894 AMDGPUOperand::ImmTyMatrixBFMT);
7899 AMDGPUOperand::ImmTy
Type) {
7905 return tryParseMatrixScale(
Operands,
"matrix_a_scale",
7906 AMDGPUOperand::ImmTyMatrixAScale);
7910 return tryParseMatrixScale(
Operands,
"matrix_b_scale",
7911 AMDGPUOperand::ImmTyMatrixBScale);
7916 AMDGPUOperand::ImmTy
Type) {
7922 return tryParseMatrixScaleFmt(
Operands,
"matrix_a_scale_fmt",
7923 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7927 return tryParseMatrixScaleFmt(
Operands,
"matrix_b_scale_fmt",
7928 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7933ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7934 using namespace llvm::AMDGPU::MTBUFFormat;
7940 for (
int I = 0;
I < 2; ++
I) {
7941 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7944 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7949 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7955 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7958 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7959 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7965ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7966 using namespace llvm::AMDGPU::MTBUFFormat;
7970 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7973 if (Fmt == UFMT_UNDEF)
7980bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt,
7981 StringRef FormatStr, SMLoc Loc) {
7982 using namespace llvm::AMDGPU::MTBUFFormat;
7986 if (
Format != DFMT_UNDEF) {
7992 if (
Format != NFMT_UNDEF) {
7997 Error(Loc,
"unsupported format");
8001ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
8004 using namespace llvm::AMDGPU::MTBUFFormat;
8008 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
8013 SMLoc Loc = getLoc();
8014 if (!parseId(Str,
"expected a format string") ||
8015 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
8017 if (Dfmt == DFMT_UNDEF)
8018 return Error(Loc,
"duplicate numeric format");
8019 if (Nfmt == NFMT_UNDEF)
8020 return Error(Loc,
"duplicate data format");
8023 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
8024 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
8028 if (Ufmt == UFMT_UNDEF)
8029 return Error(FormatLoc,
"unsupported format");
8038ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
8041 using namespace llvm::AMDGPU::MTBUFFormat;
8044 if (Id == UFMT_UNDEF)
8048 return Error(Loc,
"unified format is not supported on this GPU");
8054ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
8055 using namespace llvm::AMDGPU::MTBUFFormat;
8056 SMLoc Loc = getLoc();
8061 return Error(Loc,
"out of range format");
8066ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
8067 using namespace llvm::AMDGPU::MTBUFFormat;
8073 StringRef FormatStr;
8074 SMLoc Loc = getLoc();
8075 if (!parseId(FormatStr,
"expected a format string"))
8078 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
8080 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
8090 return parseNumericFormat(
Format);
8094 using namespace llvm::AMDGPU::MTBUFFormat;
8098 SMLoc Loc = getLoc();
8108 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
8127 Res = parseSymbolicOrNumericFormat(
Format);
8132 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
8133 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
8140 return Error(getLoc(),
"duplicate format");
8146 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
8148 Res = parseIntWithPrefix(
"inst_offset",
Operands,
8149 AMDGPUOperand::ImmTyInstOffset);
8156 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
8158 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
8164 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
8167 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
8177 OptionalImmIndexMap OptionalIdx;
8179 unsigned OperandIdx[4];
8180 unsigned EnMask = 0;
8183 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
8184 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8189 OperandIdx[SrcIdx] = Inst.
size();
8190 Op.addRegOperands(Inst, 1);
8197 OperandIdx[SrcIdx] = Inst.
size();
8203 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
8204 Op.addImmOperands(Inst, 1);
8208 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
8212 OptionalIdx[
Op.getImmTy()] = i;
8218 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
8225 for (
auto i = 0; i < SrcIdx; ++i) {
8227 EnMask |= Compr ? (0x3 << i * 2) : (0x1 << i);
8233 AMDGPUOperand::ImmTyExpCompr);
8243 int64_t CntVal,
bool Saturate,
8249 IntVal =
encode(ISA, IntVal, CntVal);
8250 if (CntVal !=
decode(ISA, IntVal)) {
8252 IntVal =
encode(ISA, IntVal, -1);
8260bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
8262 SMLoc CntLoc = getLoc();
8263 StringRef CntName = getTokenStr();
8270 SMLoc ValLoc = getLoc();
8277 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
8279 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
8281 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
8284 Error(CntLoc,
"invalid counter name " + CntName);
8289 Error(ValLoc,
"too large value for " + CntName);
8298 Error(getLoc(),
"expected a counter name");
8312 if (!parseCnt(Waitcnt))
8320 Operands.push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
8324bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
8325 SMLoc FieldLoc = getLoc();
8326 StringRef FieldName = getTokenStr();
8331 SMLoc ValueLoc = getLoc();
8338 if (FieldName ==
"instid0") {
8340 }
else if (FieldName ==
"instskip") {
8342 }
else if (FieldName ==
"instid1") {
8345 Error(FieldLoc,
"invalid field name " + FieldName);
8364 .Case(
"VALU_DEP_1", 1)
8365 .Case(
"VALU_DEP_2", 2)
8366 .Case(
"VALU_DEP_3", 3)
8367 .Case(
"VALU_DEP_4", 4)
8368 .Case(
"TRANS32_DEP_1", 5)
8369 .Case(
"TRANS32_DEP_2", 6)
8370 .Case(
"TRANS32_DEP_3", 7)
8371 .Case(
"FMA_ACCUM_CYCLE_1", 8)
8372 .Case(
"SALU_CYCLE_1", 9)
8373 .Case(
"SALU_CYCLE_2", 10)
8374 .Case(
"SALU_CYCLE_3", 11)
8382 Delay |=
Value << Shift;
8392 if (!parseDelay(Delay))
8400 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
8404bool AMDGPUOperand::isSWaitCnt()
const {
return isImm(); }
8406bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
8412void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
8413 StringRef DepCtrName) {
8416 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
8419 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
8422 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
8425 Error(Loc, Twine(
"invalid value for ", DepCtrName));
8432bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
8434 using namespace llvm::AMDGPU::DepCtr;
8436 SMLoc DepCtrLoc = getLoc();
8437 StringRef DepCtrName = getTokenStr();
8447 unsigned PrevOprMask = UsedOprMask;
8448 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8451 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8460 Error(getLoc(),
"expected a counter name");
8465 int64_t CntValMask = PrevOprMask ^ UsedOprMask;
8466 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8471 using namespace llvm::AMDGPU::DepCtr;
8474 SMLoc Loc = getLoc();
8477 unsigned UsedOprMask = 0;
8479 if (!parseDepCtr(DepCtr, UsedOprMask))
8487 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8491bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8497ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8499 OperandInfoTy &Width) {
8500 using namespace llvm::AMDGPU::Hwreg;
8506 HwReg.Loc = getLoc();
8509 HwReg.IsSymbolic =
true;
8511 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8519 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8529 Width.Loc = getLoc();
8538 using namespace llvm::AMDGPU::Hwreg;
8541 SMLoc Loc = getLoc();
8543 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8545 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8546 HwregOffset::Default);
8547 struct : StructuredOpField {
8548 using StructuredOpField::StructuredOpField;
8549 bool validate(AMDGPUAsmParser &Parser)
const override {
8551 return Error(Parser,
"only values from 1 to 32 are legal");
8554 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8555 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8558 Res = parseHwregFunc(HwReg,
Offset, Width);
8561 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8563 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8567 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8574 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8576 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8580bool AMDGPUOperand::isHwreg()
const {
return isImmTy(ImmTyHwreg); }
8586bool AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &
Msg, OperandInfoTy &
Op,
8587 OperandInfoTy &Stream) {
8588 using namespace llvm::AMDGPU::SendMsg;
8593 Msg.IsSymbolic =
true;
8600 Op.IsDefined =
true;
8606 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8611 Stream.IsDefined =
true;
8612 Stream.Loc = getLoc();
8621bool AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &
Msg,
8622 const OperandInfoTy &
Op,
8623 const OperandInfoTy &Stream) {
8624 using namespace llvm::AMDGPU::SendMsg;
8633 Error(
Msg.Loc,
"specified message id is not supported on this GPU");
8638 Error(
Msg.Loc,
"invalid message id");
8644 Error(
Op.Loc,
"message does not support operations");
8646 Error(
Msg.Loc,
"missing message operation");
8652 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8654 Error(
Op.Loc,
"invalid operation id");
8659 Error(Stream.Loc,
"message operation does not support streams");
8663 Error(Stream.Loc,
"invalid message stream id");
8670 using namespace llvm::AMDGPU::SendMsg;
8673 SMLoc Loc = getLoc();
8677 OperandInfoTy
Op(OP_NONE_);
8678 OperandInfoTy Stream(STREAM_ID_NONE_);
8679 if (parseSendMsgBody(
Msg,
Op, Stream) && validateSendMsg(
Msg,
Op, Stream)) {
8684 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8686 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8692 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8696bool AMDGPUOperand::isSendMsg()
const {
return isImmTy(ImmTySendMsg); }
8699 using namespace llvm::AMDGPU::WaitEvent;
8701 SMLoc Loc = getLoc();
8704 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8706 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8708 StructuredOpField *TargetBitfield =
8709 isGFX11() ? &DontWaitExportReady : &ExportReady;
8711 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8715 if (!validateStructuredOpFields({TargetBitfield}))
8717 ImmVal = TargetBitfield->Val;
8724 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8726 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8727 AMDGPUOperand::ImmTyWaitEvent));
8731bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8744 int Slot = StringSwitch<int>(Str)
8751 return Error(S,
"invalid interpolation slot");
8754 AMDGPUOperand::CreateImm(
this, Slot, S, AMDGPUOperand::ImmTyInterpSlot));
8765 if (!Str.starts_with(
"attr"))
8766 return Error(S,
"invalid interpolation attribute");
8768 StringRef Chan = Str.take_back(2);
8769 int AttrChan = StringSwitch<int>(Chan)
8776 return Error(S,
"invalid or missing interpolation attribute channel");
8778 Str = Str.drop_back(2).drop_front(4);
8781 if (Str.getAsInteger(10, Attr))
8782 return Error(S,
"invalid or missing interpolation attribute number");
8785 return Error(S,
"out of bounds interpolation attribute number");
8790 AMDGPUOperand::CreateImm(
this, Attr, S, AMDGPUOperand::ImmTyInterpAttr));
8791 Operands.push_back(AMDGPUOperand::CreateImm(
8792 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8801 using namespace llvm::AMDGPU::Exp;
8811 return Error(S, (Id == ET_INVALID)
8812 ?
"invalid exp target"
8813 :
"exp target is not supported on this GPU");
8816 AMDGPUOperand::CreateImm(
this, Id, S, AMDGPUOperand::ImmTyExpTgt));
8824bool AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8828bool AMDGPUAsmParser::isId(
const StringRef Id)
const {
8833 return getTokenKind() ==
Kind;
8836StringRef AMDGPUAsmParser::getId()
const {
8840bool AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8848bool AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8850 StringRef Tok = getTokenStr();
8859bool AMDGPUAsmParser::trySkipId(
const StringRef Id,
8861 if (isId(Id) && peekToken().is(Kind)) {
8870 if (isToken(Kind)) {
8878 const StringRef ErrMsg) {
8879 if (!trySkipToken(Kind)) {
8880 Error(getLoc(), ErrMsg);
8886bool AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8890 if (Parser.parseExpression(Expr))
8893 if (Expr->evaluateAsAbsolute(
Imm))
8896 if (Expected.empty()) {
8897 Error(S,
"expected absolute expression");
8900 Twine(
"expected ", Expected) + Twine(
" or an absolute expression"));
8909 if (Parser.parseExpression(Expr))
8913 if (Expr->evaluateAsAbsolute(IntVal)) {
8914 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8916 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8921bool AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8923 Val =
getToken().getStringContents();
8927 Error(getLoc(), ErrMsg);
8931bool AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8933 Val = getTokenStr();
8937 if (!ErrMsg.
empty())
8938 Error(getLoc(), ErrMsg);
8942AsmToken AMDGPUAsmParser::getToken()
const {
return Parser.getTok(); }
8944AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8947 : getLexer().peekTok(ShouldSkipSpace);
8951 auto TokCount = getLexer().peekTokens(Tokens);
8953 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8958 return getLexer().getKind();
8961SMLoc AMDGPUAsmParser::getLoc()
const {
return getToken().getLoc(); }
8963StringRef AMDGPUAsmParser::getTokenStr()
const {
8967void AMDGPUAsmParser::lex() { Parser.Lex(); }
8969const AMDGPUOperand &
8971 int MCOpIdx)
const {
8973 const AMDGPUOperand &TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8974 if (TargetOp.getMCOpIdx() == MCOpIdx)
8981 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
8985SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8990 int MCOpIdx)
const {
8991 return findMCOperand(
Operands, MCOpIdx).getStartLoc();
8994SMLoc AMDGPUAsmParser::getOperandLoc(
8995 std::function<
bool(
const AMDGPUOperand &)>
Test,
8997 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
8998 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
9000 return Op.getStartLoc();
9005SMLoc AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
9007 auto Test = [=](
const AMDGPUOperand &
Op) {
return Op.isImmTy(
Type); };
9022 StringRef
Id = getTokenStr();
9023 SMLoc IdLoc = getLoc();
9029 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
9030 if (
I == Fields.
end())
9031 return Error(IdLoc,
"unknown field");
9032 if ((*I)->IsDefined)
9033 return Error(IdLoc,
"duplicate field");
9036 (*I)->Loc = getLoc();
9039 (*I)->IsDefined =
true;
9046bool AMDGPUAsmParser::validateStructuredOpFields(
9048 return all_of(Fields, [
this](
const StructuredOpField *
F) {
9049 return F->validate(*
this);
9059 const unsigned XorMask) {
9066bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
9067 const unsigned MaxVal,
9068 const Twine &ErrMsg, SMLoc &Loc) {
9084bool AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t *
Op,
9085 const unsigned MinVal,
9086 const unsigned MaxVal,
9087 const StringRef ErrMsg) {
9089 for (
unsigned i = 0; i < OpNum; ++i) {
9090 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
9097bool AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
9098 using namespace llvm::AMDGPU::Swizzle;
9101 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
9102 "expected a 2-bit lane id")) {
9112bool AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
9113 using namespace llvm::AMDGPU::Swizzle;
9119 if (!parseSwizzleOperand(GroupSize, 2, 32,
9120 "group size must be in the interval [2,32]", Loc)) {
9124 Error(Loc,
"group size must be a power of two");
9127 if (parseSwizzleOperand(LaneIdx, 0, GroupSize - 1,
9128 "lane id must be in the interval [0,group size - 1]",
9136bool AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
9137 using namespace llvm::AMDGPU::Swizzle;
9142 if (!parseSwizzleOperand(GroupSize, 2, 32,
9143 "group size must be in the interval [2,32]", Loc)) {
9147 Error(Loc,
"group size must be a power of two");
9155bool AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
9156 using namespace llvm::AMDGPU::Swizzle;
9161 if (!parseSwizzleOperand(GroupSize, 1, 16,
9162 "group size must be in the interval [1,16]", Loc)) {
9166 Error(Loc,
"group size must be a power of two");
9174bool AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
9175 using namespace llvm::AMDGPU::Swizzle;
9182 SMLoc StrLoc = getLoc();
9183 if (!parseString(Ctl)) {
9186 if (Ctl.
size() != BITMASK_WIDTH) {
9187 Error(StrLoc,
"expected a 5-character mask");
9191 unsigned AndMask = 0;
9192 unsigned OrMask = 0;
9193 unsigned XorMask = 0;
9195 for (
size_t i = 0; i < Ctl.
size(); ++i) {
9199 Error(StrLoc,
"invalid mask");
9220bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
9221 using namespace llvm::AMDGPU::Swizzle;
9224 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
9230 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
9231 "FFT swizzle must be in the interval [0," +
9232 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
9240bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
9241 using namespace llvm::AMDGPU::Swizzle;
9244 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
9251 if (!parseSwizzleOperand(
Direction, 0, 1,
9252 "direction must be 0 (left) or 1 (right)", Loc))
9256 if (!parseSwizzleOperand(
9257 RotateSize, 0, ROTATE_MAX_SIZE,
9258 "number of threads to rotate must be in the interval [0," +
9259 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
9264 (RotateSize << ROTATE_SIZE_SHIFT);
9268bool AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
9270 SMLoc OffsetLoc = getLoc();
9276 Error(OffsetLoc,
"expected a 16-bit offset");
9282bool AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
9283 using namespace llvm::AMDGPU::Swizzle;
9287 SMLoc ModeLoc = getLoc();
9290 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
9291 Ok = parseSwizzleQuadPerm(
Imm);
9292 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
9293 Ok = parseSwizzleBitmaskPerm(
Imm);
9294 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
9295 Ok = parseSwizzleBroadcast(
Imm);
9296 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
9297 Ok = parseSwizzleSwap(
Imm);
9298 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
9299 Ok = parseSwizzleReverse(
Imm);
9300 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
9301 Ok = parseSwizzleFFT(
Imm);
9302 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
9303 Ok = parseSwizzleRotate(
Imm);
9305 Error(ModeLoc,
"expected a swizzle mode");
9308 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
9318 if (trySkipId(
"offset")) {
9322 if (trySkipId(
"swizzle")) {
9323 Ok = parseSwizzleMacro(
Imm);
9325 Ok = parseSwizzleOffset(
Imm);
9330 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
9337bool AMDGPUOperand::isSwizzle()
const {
return isImmTy(ImmTySwizzle); }
9343int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
9345 using namespace llvm::AMDGPU::VGPRIndexMode;
9357 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
9358 if (trySkipId(IdSymbolic[ModeId])) {
9366 ?
"expected a VGPR index mode or a closing parenthesis"
9367 :
"expected a VGPR index mode");
9372 Error(S,
"duplicate VGPR index mode");
9380 "expected a comma or a closing parenthesis"))
9389 using namespace llvm::AMDGPU::VGPRIndexMode;
9395 Imm = parseGPRIdxMacro();
9399 if (getParser().parseAbsoluteExpression(
Imm))
9402 return Error(S,
"invalid immediate: only 4-bit values are legal");
9406 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9410bool AMDGPUOperand::isGPRIdxMode()
const {
return isImmTy(ImmTyGprIdxMode); }
9421 if (isRegister() || isModifier())
9428 assert(Opr.isImm() || Opr.isExpr());
9429 SMLoc Loc = Opr.getStartLoc();
9433 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9434 Error(Loc,
"expected an absolute expression or a label");
9435 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9436 Error(Loc,
"expected a 16-bit signed jump offset");
9456 OptionalImmIndexMap OptionalIdx;
9457 unsigned FirstOperandIdx = 1;
9458 bool IsAtomicReturn =
false;
9464 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
9465 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
9469 Op.addRegOperands(Inst, 1);
9473 if (IsAtomicReturn && i == FirstOperandIdx)
9474 Op.addRegOperands(Inst, 1);
9479 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9480 Op.addImmOperands(Inst, 1);
9492 OptionalIdx[
Op.getImmTy()] = i;
9496 AMDGPUOperand::ImmTyOffset);
9512bool AMDGPUOperand::isSMRDOffset8()
const {
9516bool AMDGPUOperand::isSMEMOffset()
const {
9518 return isImmLiteral();
9521bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9556bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9557 if (BoundCtrl == 0 || BoundCtrl == 1) {
9565void AMDGPUAsmParser::onBeginOfFile() {
9566 if (!getParser().getStreamer().getTargetStreamer())
9569 if (!getTargetStreamer().getTargetID())
9570 getTargetStreamer().initializeTargetID(getSTI(),
9574void AMDGPUAsmParser::emitTargetDirective() {
9575 if (TargetDirectiveEmitted)
9577 TargetDirectiveEmitted =
true;
9579 if (!getParser().getStreamer().getTargetStreamer() ||
9584 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9593bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9597 StringRef TokenId = getTokenStr();
9598 AGVK VK = StringSwitch<AGVK>(TokenId)
9599 .Case(
"max", AGVK::AGVK_Max)
9600 .Case(
"min", AGVK::AGVK_Min)
9601 .Case(
"or", AGVK::AGVK_Or)
9602 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9603 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9604 .Case(
"alignto", AGVK::AGVK_AlignTo)
9605 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9606 .Case(
"instprefsize", AGVK::AGVK_InstPrefSize)
9607 .Default(AGVK::AGVK_None);
9616 if (Exprs.
empty()) {
9618 "empty " + Twine(TokenId) +
" expression");
9621 if (CommaCount + 1 != Exprs.
size()) {
9623 "mismatch of commas in " + Twine(TokenId) +
" expression");
9627 Expected && Exprs.
size() != Expected) {
9628 Error(
getToken().getLoc(), Twine(TokenId) +
" expression expects " +
9629 Twine(Expected) +
" operands");
9636 if (getParser().parseExpression(Expr, EndLoc))
9640 if (LastTokenWasComma)
9644 "unexpected token in " + Twine(TokenId) +
" expression");
9650 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9654 StringRef
Name = getTokenStr();
9655 if (Name ==
"mul") {
9656 return parseIntWithPrefix(
"mul",
Operands, AMDGPUOperand::ImmTyOModSI,
9660 if (Name ==
"div") {
9661 return parseIntWithPrefix(
"div",
Operands, AMDGPUOperand::ImmTyOModSI,
9672 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9677 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9678 AMDGPU::OpName::src2};
9686 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9691 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9693 if (
DstOp.isReg() &&
9698 if ((OpSel & (1 << SrcNum)) != 0)
9704void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9711 OptionalImmIndexMap &OptionalIdx) {
9712 cvtVOP3P(Inst,
Operands, OptionalIdx);
9721 &&
Desc.NumOperands > (OpNum + 1)
9723 &&
Desc.operands()[OpNum + 1].RegClass != -1
9725 &&
Desc.getOperandConstraint(OpNum + 1,
9729void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9731 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9732 AMDGPU::OpName::src2};
9733 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9734 AMDGPU::OpName::src1_modifiers,
9735 AMDGPU::OpName::src2_modifiers};
9736 for (
int J = 0; J < 3; ++J) {
9737 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9743 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9746 if ((OpSel & (1 << J)) != 0)
9749 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9756void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
9758 OptionalImmIndexMap OptionalIdx;
9763 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9764 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9768 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9770 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9771 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9772 Op.isInterpAttrChan()) {
9774 }
else if (
Op.isImmModifier()) {
9775 OptionalIdx[
Op.getImmTy()] =
I;
9783 AMDGPUOperand::ImmTyHigh);
9787 AMDGPUOperand::ImmTyClamp);
9791 AMDGPUOperand::ImmTyOModSI);
9796 AMDGPUOperand::ImmTyOpSel);
9797 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9800 cvtOpSelHelper(Inst, OpSel);
9805 OptionalImmIndexMap OptionalIdx;
9810 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9811 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9815 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9817 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9818 }
else if (
Op.isImmModifier()) {
9819 OptionalIdx[
Op.getImmTy()] =
I;
9827 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9830 AMDGPUOperand::ImmTyOpSel);
9833 AMDGPUOperand::ImmTyWaitEXP);
9839 cvtOpSelHelper(Inst, OpSel);
9842void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9844 OptionalImmIndexMap OptionalIdx;
9847 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9851 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9852 static_cast<AMDGPUOperand &
>(*
Operands[
I++]).addRegOperands(Inst, 1);
9855 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
I]);
9860 if (NumOperands == CbszOpIdx) {
9865 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9866 }
else if (
Op.isImmModifier()) {
9867 OptionalIdx[
Op.getImmTy()] =
I;
9869 Op.addRegOrImmOperands(Inst, 1);
9874 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9875 if (CbszIdx != OptionalIdx.end()) {
9876 int CbszVal = ((AMDGPUOperand &)*
Operands[CbszIdx->second]).
getImm();
9880 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9881 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9882 if (BlgpIdx != OptionalIdx.end()) {
9883 int BlgpVal = ((AMDGPUOperand &)*
Operands[BlgpIdx->second]).
getImm();
9894 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9895 if (OpselIdx != OptionalIdx.end()) {
9896 OpSel =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselIdx->second])
9900 unsigned OpSelHi = 0;
9901 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9902 if (OpselHiIdx != OptionalIdx.end()) {
9903 OpSelHi =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselHiIdx->second])
9906 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9907 AMDGPU::OpName::src1_modifiers};
9909 for (
unsigned J = 0; J < 2; ++J) {
9910 unsigned ModVal = 0;
9911 if (OpSel & (1 << J))
9913 if (OpSelHi & (1 << J))
9916 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9922 OptionalImmIndexMap &OptionalIdx) {
9927 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9928 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9932 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9934 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9935 }
else if (
Op.isImmModifier()) {
9936 OptionalIdx[
Op.getImmTy()] =
I;
9938 Op.addRegOrImmOperands(Inst, 1);
9944 AMDGPUOperand::ImmTyScaleSel);
9948 AMDGPUOperand::ImmTyClamp);
9954 AMDGPUOperand::ImmTyByteSel);
9959 AMDGPUOperand::ImmTyOModSI);
9966 auto *it = Inst.
begin();
9968 it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9977 OptionalImmIndexMap OptionalIdx;
9978 cvtVOP3(Inst,
Operands, OptionalIdx);
9982 OptionalImmIndexMap &OptIdx) {
9987 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9988 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9989 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9990 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9991 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9992 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9993 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9994 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12 ||
9995 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx13 ||
9996 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx13) {
10005 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10006 if (VdstInIdx != -1 && VdstInIdx ==
static_cast<int>(Inst.
getNumOperands()))
10009 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
10010 if (BitOp3Idx != -1) {
10017 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
10018 if (OpSelIdx != -1) {
10022 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
10023 if (OpSelHiIdx != -1) {
10024 int DefaultVal =
IsPacked ? -1 : 0;
10029 int MatrixAFMTIdx =
10030 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
10031 if (MatrixAFMTIdx != -1) {
10033 AMDGPUOperand::ImmTyMatrixAFMT, 0);
10036 int MatrixBFMTIdx =
10037 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
10038 if (MatrixBFMTIdx != -1) {
10040 AMDGPUOperand::ImmTyMatrixBFMT, 0);
10043 int MatrixAScaleIdx =
10044 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
10045 if (MatrixAScaleIdx != -1) {
10047 AMDGPUOperand::ImmTyMatrixAScale, 0);
10050 int MatrixBScaleIdx =
10051 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
10052 if (MatrixBScaleIdx != -1) {
10054 AMDGPUOperand::ImmTyMatrixBScale, 0);
10057 int MatrixAScaleFmtIdx =
10058 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
10059 if (MatrixAScaleFmtIdx != -1) {
10061 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
10064 int MatrixBScaleFmtIdx =
10065 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
10066 if (MatrixBScaleFmtIdx != -1) {
10068 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
10073 AMDGPUOperand::ImmTyMatrixAReuse, 0);
10077 AMDGPUOperand::ImmTyMatrixBReuse, 0);
10079 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
10080 if (NegLoIdx != -1)
10083 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
10084 if (NegHiIdx != -1)
10087 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
10088 AMDGPU::OpName::src2};
10089 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
10090 AMDGPU::OpName::src1_modifiers,
10091 AMDGPU::OpName::src2_modifiers};
10093 unsigned OpSel = 0;
10094 unsigned OpSelHi = 0;
10095 unsigned NegLo = 0;
10096 unsigned NegHi = 0;
10098 if (OpSelIdx != -1)
10101 if (OpSelHiIdx != -1)
10104 if (NegLoIdx != -1)
10107 if (NegHiIdx != -1)
10110 for (
int J = 0; J < 3; ++J) {
10111 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
10115 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
10125 uint32_t ModVal = 0;
10127 const MCOperand &SrcOp = Inst.
getOperand(OpIdx);
10128 if (SrcOp.
isReg() && getMRI()
10132 if (VGPRSuffixIsHi)
10135 if ((OpSel & (1 << J)) != 0)
10139 if ((OpSelHi & (1 << J)) != 0)
10142 if ((NegLo & (1 << J)) != 0)
10145 if ((NegHi & (1 << J)) != 0)
10153 OptionalImmIndexMap OptIdx;
10159 unsigned i,
unsigned Opc,
10160 AMDGPU::OpName
OpName) {
10161 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
10162 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
10164 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
10170 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
10173 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
10174 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
10176 OptionalImmIndexMap OptIdx;
10177 for (
unsigned i = 5; i <
Operands.size(); ++i) {
10178 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
10179 OptIdx[
Op.getImmTy()] = i;
10184 AMDGPUOperand::ImmTyIndexKey8bit);
10188 AMDGPUOperand::ImmTyIndexKey16bit);
10192 AMDGPUOperand::ImmTyIndexKey32bit);
10209 SMLoc S = getLoc();
10212 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
10213 SMLoc OpYLoc = getLoc();
10216 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
10219 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
10228 auto addOp = [&](uint16_t ParsedOprIdx) {
10229 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
10231 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10235 Op.addRegOperands(Inst, 1);
10239 Op.addImmOperands(Inst, 1);
10251 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
10255 const auto &CInfo = InstInfo[CompIdx];
10256 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
10257 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
10258 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
10259 if (CInfo.hasSrc2Acc())
10260 addOp(CInfo.getIndexOfDstInParsedOperands());
10264 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
10265 if (BitOp3Idx != -1) {
10266 OptionalImmIndexMap OptIdx;
10267 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands.back());
10269 OptIdx[
Op.getImmTy()] =
Operands.size() - 1;
10279bool AMDGPUOperand::isDPP8()
const {
return isImmTy(ImmTyDPP8); }
10281bool AMDGPUOperand::isDPPCtrl()
const {
10282 using namespace AMDGPU::DPP;
10284 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
10287 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
10288 Imm <= DppCtrl::QUAD_PERM_LAST) ||
10289 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
10290 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
10291 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
10292 (
Imm == DppCtrl::WAVE_SHL1) || (
Imm == DppCtrl::WAVE_ROL1) ||
10293 (
Imm == DppCtrl::WAVE_SHR1) || (
Imm == DppCtrl::WAVE_ROR1) ||
10294 (
Imm == DppCtrl::ROW_MIRROR) || (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
10295 (
Imm == DppCtrl::BCAST15) || (
Imm == DppCtrl::BCAST31) ||
10296 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
10297 Imm <= DppCtrl::ROW_SHARE_LAST) ||
10298 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
10307bool AMDGPUOperand::isBLGP()
const {
10311bool AMDGPUOperand::isS16Imm()
const {
10315bool AMDGPUOperand::isU16Imm()
const {
10323bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
10328 SMLoc Loc =
getToken().getEndLoc();
10329 Token = std::string(getTokenStr());
10331 if (getLoc() != Loc)
10336 if (!parseId(Suffix))
10340 StringRef DimId = Token;
10355 SMLoc S = getLoc();
10361 SMLoc Loc = getLoc();
10362 if (!parseDimId(Encoding))
10363 return Error(Loc,
"invalid dim value");
10366 AMDGPUOperand::CreateImm(
this, Encoding, S, AMDGPUOperand::ImmTyDim));
10375 SMLoc S = getLoc();
10384 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10387 for (
size_t i = 0; i < 8; ++i) {
10391 SMLoc Loc = getLoc();
10392 if (getParser().parseAbsoluteExpression(Sels[i]))
10394 if (0 > Sels[i] || 7 < Sels[i])
10395 return Error(Loc,
"expected a 3-bit value");
10398 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10402 for (
size_t i = 0; i < 8; ++i)
10403 DPP8 |= (Sels[i] << (i * 3));
10406 AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10410bool AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10412 if (Ctrl ==
"row_newbcast")
10415 if (Ctrl ==
"row_share" || Ctrl ==
"row_xmask")
10418 if (Ctrl ==
"wave_shl" || Ctrl ==
"wave_shr" || Ctrl ==
"wave_rol" ||
10419 Ctrl ==
"wave_ror" || Ctrl ==
"row_bcast")
10422 return Ctrl ==
"row_mirror" ||
Ctrl ==
"row_half_mirror" ||
10423 Ctrl ==
"quad_perm" ||
Ctrl ==
"row_shl" ||
Ctrl ==
"row_shr" ||
10427int64_t AMDGPUAsmParser::parseDPPCtrlPerm() {
10430 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10434 for (
int i = 0; i < 4; ++i) {
10439 SMLoc Loc = getLoc();
10440 if (getParser().parseAbsoluteExpression(Temp))
10442 if (Temp < 0 || Temp > 3) {
10443 Error(Loc,
"expected a 2-bit value");
10447 Val += (Temp << i * 2);
10450 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10456int64_t AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10457 using namespace AMDGPU::DPP;
10462 SMLoc Loc = getLoc();
10464 if (getParser().parseAbsoluteExpression(Val))
10467 struct DppCtrlCheck {
10473 DppCtrlCheck
Check =
10474 StringSwitch<DppCtrlCheck>(Ctrl)
10475 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10476 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10477 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10478 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10479 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10480 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10481 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10482 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10483 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10484 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10488 if (
Check.Ctrl == -1) {
10489 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10497 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10505 using namespace AMDGPU::DPP;
10508 !isSupportedDPPCtrl(getTokenStr(),
Operands))
10511 SMLoc S = getLoc();
10517 if (Ctrl ==
"row_mirror") {
10518 Val = DppCtrl::ROW_MIRROR;
10519 }
else if (Ctrl ==
"row_half_mirror") {
10520 Val = DppCtrl::ROW_HALF_MIRROR;
10523 if (Ctrl ==
"quad_perm") {
10524 Val = parseDPPCtrlPerm();
10526 Val = parseDPPCtrlSel(Ctrl);
10535 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10541 OptionalImmIndexMap OptionalIdx;
10548 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10550 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10551 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10555 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10556 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10560 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10561 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10562 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx13 ||
10563 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10564 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx13 ||
10565 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10566 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx13 ||
10567 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
10568 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx13;
10574 if (OldIdx == NumOperands) {
10576 constexpr int DST_IDX = 0;
10578 }
else if (Src2ModIdx == NumOperands) {
10588 if (IsVOP3CvtSrDpp) {
10597 if (TiedTo != -1) {
10602 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10604 if (IsDPP8 &&
Op.isDppFI()) {
10607 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10608 }
else if (
Op.isReg()) {
10609 Op.addRegOperands(Inst, 1);
10610 }
else if (
Op.isImm() &&
10612 Op.addImmOperands(Inst, 1);
10613 }
else if (
Op.isImm()) {
10614 OptionalIdx[
Op.getImmTy()] =
I;
10622 AMDGPUOperand::ImmTyClamp);
10628 AMDGPUOperand::ImmTyByteSel);
10633 AMDGPUOperand::ImmTyOModSI);
10636 cvtVOP3P(Inst,
Operands, OptionalIdx);
10638 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
10641 AMDGPUOperand::ImmTyOpSel);
10646 AMDGPUOperand::ImmTyDPP8);
10647 using namespace llvm::AMDGPU::DPP;
10651 AMDGPUOperand::ImmTyDppCtrl, 0xe4);
10653 AMDGPUOperand::ImmTyDppRowMask, 0xf);
10655 AMDGPUOperand::ImmTyDppBankMask, 0xf);
10657 AMDGPUOperand::ImmTyDppBoundCtrl);
10661 AMDGPUOperand::ImmTyDppFI);
10667 OptionalImmIndexMap OptionalIdx;
10671 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10672 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10679 if (TiedTo != -1) {
10684 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10686 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10694 Op.addImmOperands(Inst, 1);
10696 Op.addRegWithFPInputModsOperands(Inst, 2);
10697 }
else if (
Op.isDppFI()) {
10699 }
else if (
Op.isReg()) {
10700 Op.addRegOperands(Inst, 1);
10706 Op.addRegWithFPInputModsOperands(Inst, 2);
10707 }
else if (
Op.isReg()) {
10708 Op.addRegOperands(Inst, 1);
10709 }
else if (
Op.isDPPCtrl()) {
10710 Op.addImmOperands(Inst, 1);
10711 }
else if (
Op.isImm()) {
10713 OptionalIdx[
Op.getImmTy()] =
I;
10721 using namespace llvm::AMDGPU::DPP;
10725 AMDGPUOperand::ImmTyDppRowMask, 0xf);
10727 AMDGPUOperand::ImmTyDppBankMask, 0xf);
10729 AMDGPUOperand::ImmTyDppBoundCtrl);
10732 AMDGPUOperand::ImmTyDppFI);
10743 AMDGPUOperand::ImmTy
Type) {
10744 return parseStringOrIntWithPrefix(
10746 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10751 return parseStringOrIntWithPrefix(
10752 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10753 AMDGPUOperand::ImmTySDWADstUnused);
10757 cvtSDWA(Inst,
Operands, SDWAInstType::VOP1);
10761 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2);
10764void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
10766 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2,
true,
true);
10769void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
10771 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2,
false,
true);
10779 SDWAInstType BasicInstType,
bool SkipDstVcc,
10781 using namespace llvm::AMDGPU::SDWA;
10783 OptionalImmIndexMap OptionalIdx;
10784 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10785 bool SkippedVcc =
false;
10789 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10790 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10794 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10795 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10796 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10802 if (BasicInstType == SDWAInstType::VOP2 &&
10808 if (BasicInstType == SDWAInstType::VOPC && Inst.
getNumOperands() == 0) {
10814 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10815 }
else if (
Op.isImm()) {
10817 OptionalIdx[
Op.getImmTy()] =
I;
10821 SkippedVcc =
false;
10825 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10826 Opc != AMDGPU::V_NOP_sdwa_vi) {
10828 switch (BasicInstType) {
10829 case SDWAInstType::VOP1:
10832 AMDGPUOperand::ImmTyClamp, 0);
10836 AMDGPUOperand::ImmTyOModSI, 0);
10840 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10844 AMDGPUOperand::ImmTySDWADstUnused,
10845 DstUnused::UNUSED_PRESERVE);
10848 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10851 case SDWAInstType::VOP2:
10853 AMDGPUOperand::ImmTyClamp, 0);
10857 AMDGPUOperand::ImmTyOModSI, 0);
10860 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10862 AMDGPUOperand::ImmTySDWADstUnused,
10863 DstUnused::UNUSED_PRESERVE);
10865 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10867 AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10870 case SDWAInstType::VOPC:
10873 AMDGPUOperand::ImmTyClamp, 0);
10875 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10877 AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10884 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10885 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10886 auto *it = Inst.
begin();
10888 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10901#define GET_MATCHER_IMPLEMENTATION
10902#define GET_MNEMONIC_SPELL_CHECKER
10903#define GET_MNEMONIC_CHECKER
10904#include "AMDGPUGenAsmMatcher.inc"
10910 return parseTokenOp(
"addr64",
Operands);
10912 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10914 return parseTokenOp(
"idxen",
Operands);
10916 return parseNamedBit(
"lds",
Operands, AMDGPUOperand::ImmTyLDS,
10919 return parseTokenOp(
"offen",
Operands);
10921 return parseTokenOp(
"off",
Operands);
10922 case MCK_row_95_en:
10923 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10925 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10927 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10929 return tryCustomParseOperand(
Operands, MCK);
10934unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10940 AMDGPUOperand &Operand = (AMDGPUOperand &)
Op;
10943 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10945 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10947 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10949 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10951 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10953 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10955 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10956 case MCK_row_95_en:
10957 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10965 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10967 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10968 case MCK_SOPPBrTarget:
10969 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10970 case MCK_VReg32OrOff:
10971 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10972 case MCK_InterpSlot:
10973 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10974 case MCK_InterpAttr:
10975 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10976 case MCK_InterpAttrChan:
10977 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10979 case MCK_SReg_64_XEXEC:
10989 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10991 return Match_InvalidOperand;
11000 SMLoc S = getLoc();
11009 return Error(S,
"expected a 16-bit value");
11012 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
11016bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
11022bool AMDGPUOperand::isSplitBarrier()
const {
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, AMDGPU::OpName OpName)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static int IsAGPROperand(const MCInst &Inst, AMDGPU::OpName Name, const MCRegisterInfo *MRI)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static bool IsRevOpcode(const unsigned Opcode)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static MCRegister getSpecialRegForName(StringRef RegName)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0, std::optional< unsigned > InsertAt=std::nullopt)
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
Enums shared between the AMDGPU backend (LLVM) and the ELF linker (LLD) for the .amdgpu....
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(GsymDataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Loop::LoopBounds::Direction Direction
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static unsigned getNumExpectedArgs(VariantKind Kind)
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
static std::optional< TargetID > parseTargetIDString(StringRef TargetIDDirective)
Parse and validate a TargetID from a full "<triple>-<processor>:<features>" directive string.
TargetIDSetting getXnackSetting() const
GPUKind getGPUKind() const
StringRef getTargetTripleString() const
std::string toString() const
TargetIDSetting getSramEccSetting() const
static const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
const T & front() const
Get the first element.
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
const int16_t * getRegClassByHwModeTable(unsigned ModeId) const
int16_t getOpRegClassID(const MCOperandInfo &OpInfo, unsigned HwModeId) const
Return the ID of the register class to use for OpInfo, for the active HwMode HwModeId.
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)
void setReg(MCRegister Reg)
Set the register number.
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterClass - Base class of TargetRegisterClass.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool regsOverlap(MCRegister RegA, MCRegister RegB) const
Returns true if the two registers are equal or alias each other.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
LLVM_ABI void setVariableValue(const MCExpr *Value)
void setRedefinable(bool Value)
Mark this symbol as redefinable.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
uint64_t getScalarSizeInBits() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
std::pair< iterator, bool > insert(const ValueT &V)
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.
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
unsigned getTgtId(const StringRef Name)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getVGPREncodingGranule(const MCSubtargetInfo &STI, std::optional< bool > EnableWavefrontSize32)
unsigned getSGPREncodingGranule(const MCSubtargetInfo &STI)
bool targetIDSettingsConflict(TargetIDSetting Lhs, TargetIDSetting Rhs)
Returns true if Lhs and Rhs are incompatible (both specific but different).
unsigned getLocalMemorySize(const MCSubtargetInfo &STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
constexpr const char *const ModMatrixFmt[]
constexpr const char *const ModMatrixScaleFmt[]
constexpr const char *const ModMatrixScale[]
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
bool isInlineValue(MCRegister Reg)
bool isPKFMACF16InlineConstant(uint32_t Literal, bool IsGFX11Plus)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
bool isSGPR(MCRegister Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
FuncInfoFlags
Per-function flags packed into INFO_FLAGS entries.
uint8_t wmmaScaleF8F6F4FormatToNumRegs(unsigned Fmt)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
unsigned getTemporalHintType(const MCInstrDesc TID)
bool isGFX10(const MCSubtargetInfo &STI)
LLVM_READONLY bool isLitExpr(const MCExpr *Expr)
bool isInlinableLiteralV2BF16(uint32_t Literal)
LLVM_ABI bool isCPUValidForSubArch(Triple::SubArchType SubArch, GPUKind AK)
Return true if the GPU AK is usable with the triple subarch SubArch.
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
bool hasA16(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset, bool IsBuffer)
bool isGFX12Plus(const MCSubtargetInfo &STI)
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool isHsaAbi(const MCSubtargetInfo &STI)
bool isGFX11(const MCSubtargetInfo &STI)
const int OPR_VAL_INVALID
bool getSMEMIsBuffer(unsigned Opc)
bool isPackedSingleSGPRFP32Inst(unsigned Opc)
The opcode is a packed fp32 instruction which only reads low 32 bits of a scalar operand and propagat...
bool isGFX13(const MCSubtargetInfo &STI)
LLVM_ABI unsigned getAddressableNumSGPRs(GPUKind AK)
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
LLVM_ABI unsigned getTotalNumVGPRs(GPUKind AK, bool IsWave32)
CanBeVOPD getCanBeVOPD(unsigned Opc, unsigned EncodingFamily, bool VOPD3)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
bool isSI(const MCSubtargetInfo &STI)
bool hasPrivateApertureRegs(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isGFX9(const MCSubtargetInfo &STI)
unsigned getVOPDEncodingFamily(const MCSubtargetInfo &ST)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
GPUKind
GPU kinds supported by the AMDGPU target.
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool hasMAIInsts(const MCSubtargetInfo &STI)
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
LLVM_ABI GPUKind parseArchAMDGCN(StringRef CPU)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool isGFX13Plus(const MCSubtargetInfo &STI)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
AMDGPU::TargetID TargetID
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
bool isValidWMMAScaleFmtCombination(unsigned AFmt, unsigned AScale, unsigned BFmt, unsigned BScale)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_IMM_NOINLINE_FP16
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT64
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_IMM_V2FP16_SPLAT
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
constexpr bool isBF16SrcOperand(const MCOperandInfo &OpInfo)
Is this a scalar (i.e. not packed) bf16 source operand?
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
LLVM_ABI StringRef getArchNameAMDGCN(GPUKind AK)
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
bool isGFX1250Plus(const MCSubtargetInfo &STI)
bool hasPopsExitingWaveID(const MCSubtargetInfo &STI)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
constexpr bool isAtomicRet(const T &...O)
constexpr bool isVOPC(const T &...O)
constexpr bool isVOP3(const T &...O)
constexpr bool isVOP1(const T &...O)
constexpr bool usesTENSOR_CNT(const T &...O)
constexpr bool isMAI(const T &...O)
constexpr bool isVOP2(const T &...O)
constexpr bool isSWMMAC(const T &...O)
constexpr bool isSOP2(const T &...O)
constexpr bool isFLAT(const T &...O)
constexpr bool isVOP3P(const T &...O)
constexpr bool isBuffer(const T &...O)
constexpr bool hasIntClamp(const T &...O)
constexpr bool isAtomicNoRet(const T &...O)
constexpr bool isSMRD(const T &...O)
constexpr bool isVOP3Like(const T &...O)
constexpr bool isMIMG(const T &...O)
constexpr bool isVMEM(const T &...O)
constexpr bool isImage(const T &...O)
constexpr bool isWMMA(const T &...O)
constexpr bool isVOPD3(const T &...O)
constexpr bool isGWS(const T &...O)
constexpr bool isMUBUF(const T &...O)
constexpr bool isSDWA(const T &...O)
constexpr bool isSOPC(const T &...O)
constexpr bool isDOT(const T &...O)
constexpr bool isVSAMPLE(const T &...O)
constexpr bool isDS(const T &...O)
constexpr bool isAtomic(const T &...O)
constexpr bool isGather4(const T &...O)
constexpr bool isPacked(const T &...O)
constexpr bool isDPP(const T &...O)
constexpr bool isSegmentSpecificFLAT(const T &...O)
@ Valid
The data is already valid.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
EnumSet< Modifier, Modifier_enumSize > Modifiers
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
LLVM_ABI void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target & getTheGCNLegacyTarget()
The target for GCN GPUs, registered under the legacy "amdgcn" architecture name for use with -march.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ Default
The result value is uniform if and only if all operands are uniform.
void initDefault(const MCSubtargetInfo &STI, MCContext &Ctx, bool InitMCExpr=true)
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
uint32_t PrivateSegmentSize
SmallVector< std::pair< MCSymbol *, std::string >, 4 > IndirectCalls
SmallVector< std::pair< MCSymbol *, MCSymbol * >, 8 > Calls
SmallVector< FuncInfo, 8 > Funcs
SmallVector< std::pair< MCSymbol *, std::string >, 4 > TypeIds
SmallVector< std::pair< MCSymbol *, MCSymbol * >, 4 > Uses
Instruction set architecture version.
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
const MCExpr * compute_pgm_rsrc1
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * group_segment_fixed_size
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * kernel_code_properties
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size