53enum RegisterKind { IS_UNKNOWN,
IS_VGPR, IS_SGPR, IS_AGPR, IS_TTMP, IS_SPECIAL };
67 SMLoc StartLoc, EndLoc;
68 const AMDGPUAsmParser *AsmParser;
71 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
72 :
Kind(Kind_), AsmParser(AsmParser_) {}
74 using Ptr = std::unique_ptr<AMDGPUOperand>;
82 bool hasFPModifiers()
const {
return Abs || Neg; }
83 bool hasIntModifiers()
const {
return Sext; }
84 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
86 int64_t getFPModifiersOperand()
const {
93 int64_t getIntModifiersOperand()
const {
99 int64_t getModifiersOperand()
const {
100 assert(!(hasFPModifiers() && hasIntModifiers())
101 &&
"fp and int modifiers should not be used simultaneously");
102 if (hasFPModifiers()) {
103 return getFPModifiersOperand();
104 }
else if (hasIntModifiers()) {
105 return getIntModifiersOperand();
188 ImmKindTyMandatoryLiteral,
202 mutable ImmKindTy
Kind;
219 bool isToken()
const override {
return Kind == Token; }
221 bool isSymbolRefExpr()
const {
222 return isExpr() && Expr && isa<MCSymbolRefExpr>(Expr);
225 bool isImm()
const override {
226 return Kind == Immediate;
229 void setImmKindNone()
const {
231 Imm.Kind = ImmKindTyNone;
234 void setImmKindLiteral()
const {
236 Imm.Kind = ImmKindTyLiteral;
239 void setImmKindMandatoryLiteral()
const {
241 Imm.Kind = ImmKindTyMandatoryLiteral;
244 void setImmKindConst()
const {
246 Imm.Kind = ImmKindTyConst;
249 bool IsImmKindLiteral()
const {
250 return isImm() &&
Imm.Kind == ImmKindTyLiteral;
253 bool IsImmKindMandatoryLiteral()
const {
254 return isImm() &&
Imm.Kind == ImmKindTyMandatoryLiteral;
257 bool isImmKindConst()
const {
258 return isImm() &&
Imm.Kind == ImmKindTyConst;
261 bool isInlinableImm(
MVT type)
const;
262 bool isLiteralImm(
MVT type)
const;
264 bool isRegKind()
const {
268 bool isReg()
const override {
269 return isRegKind() && !hasModifiers();
272 bool isRegOrInline(
unsigned RCID,
MVT type)
const {
273 return isRegClass(RCID) || isInlinableImm(type);
277 return isRegOrInline(RCID, type) || isLiteralImm(type);
280 bool isRegOrImmWithInt16InputMods()
const {
284 bool isRegOrImmWithIntT16InputMods()
const {
288 bool isRegOrImmWithInt32InputMods()
const {
292 bool isRegOrInlineImmWithInt16InputMods()
const {
293 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
296 bool isRegOrInlineImmWithInt32InputMods()
const {
297 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
300 bool isRegOrImmWithInt64InputMods()
const {
304 bool isRegOrImmWithFP16InputMods()
const {
308 bool isRegOrImmWithFPT16InputMods()
const {
312 bool isRegOrImmWithFP32InputMods()
const {
316 bool isRegOrImmWithFP64InputMods()
const {
320 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
321 return isRegOrInline(
322 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
325 bool isRegOrInlineImmWithFP32InputMods()
const {
326 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
329 bool isPackedFP16InputMods()
const {
333 bool isVReg()
const {
334 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
335 isRegClass(AMDGPU::VReg_64RegClassID) ||
336 isRegClass(AMDGPU::VReg_96RegClassID) ||
337 isRegClass(AMDGPU::VReg_128RegClassID) ||
338 isRegClass(AMDGPU::VReg_160RegClassID) ||
339 isRegClass(AMDGPU::VReg_192RegClassID) ||
340 isRegClass(AMDGPU::VReg_256RegClassID) ||
341 isRegClass(AMDGPU::VReg_512RegClassID) ||
342 isRegClass(AMDGPU::VReg_1024RegClassID);
345 bool isVReg32()
const {
346 return isRegClass(AMDGPU::VGPR_32RegClassID);
349 bool isVReg32OrOff()
const {
350 return isOff() || isVReg32();
353 bool isNull()
const {
354 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
357 bool isVRegWithInputMods()
const;
358 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
360 bool isSDWAOperand(
MVT type)
const;
361 bool isSDWAFP16Operand()
const;
362 bool isSDWAFP32Operand()
const;
363 bool isSDWAInt16Operand()
const;
364 bool isSDWAInt32Operand()
const;
366 bool isImmTy(ImmTy ImmT)
const {
370 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
372 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
374 bool isImmModifier()
const {
375 return isImm() &&
Imm.Type != ImmTyNone;
378 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
379 bool isDim()
const {
return isImmTy(ImmTyDim); }
380 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
381 bool isOff()
const {
return isImmTy(ImmTyOff); }
382 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
383 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
384 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
385 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
386 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
387 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
388 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
389 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
390 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
391 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
392 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
393 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
394 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) && isUInt<7>(getImm()); }
395 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
396 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
397 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
398 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
399 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
400 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
401 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
402 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
403 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
404 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
405 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
406 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
408 bool isRegOrImm()
const {
412 bool isRegClass(
unsigned RCID)
const;
416 bool isRegOrInlineNoMods(
unsigned RCID,
MVT type)
const {
417 return isRegOrInline(RCID, type) && !hasModifiers();
420 bool isSCSrcB16()
const {
421 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
424 bool isSCSrcV2B16()
const {
428 bool isSCSrc_b32()
const {
429 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
432 bool isSCSrc_b64()
const {
433 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
436 bool isBoolReg()
const;
438 bool isSCSrcF16()
const {
439 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
442 bool isSCSrcV2F16()
const {
446 bool isSCSrcF32()
const {
447 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
450 bool isSCSrcF64()
const {
451 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
454 bool isSSrc_b32()
const {
455 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
458 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
460 bool isSSrcV2B16()
const {
465 bool isSSrc_b64()
const {
468 return isSCSrc_b64() || isLiteralImm(MVT::i64);
471 bool isSSrc_f32()
const {
472 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
475 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
477 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
479 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
481 bool isSSrcV2F16()
const {
486 bool isSSrcV2FP32()
const {
491 bool isSCSrcV2FP32()
const {
496 bool isSSrcV2INT32()
const {
501 bool isSCSrcV2INT32()
const {
503 return isSCSrc_b32();
506 bool isSSrcOrLds_b32()
const {
507 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
508 isLiteralImm(MVT::i32) || isExpr();
511 bool isVCSrc_b32()
const {
512 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
515 bool isVCSrcB64()
const {
516 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
519 bool isVCSrcTB16()
const {
520 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
523 bool isVCSrcTB16_Lo128()
const {
524 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
527 bool isVCSrcFake16B16_Lo128()
const {
528 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
531 bool isVCSrc_b16()
const {
532 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
535 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
537 bool isVCSrc_f32()
const {
538 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
541 bool isVCSrcF64()
const {
542 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
545 bool isVCSrcTBF16()
const {
546 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
549 bool isVCSrcTF16()
const {
550 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
553 bool isVCSrcTBF16_Lo128()
const {
554 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
557 bool isVCSrcTF16_Lo128()
const {
558 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
561 bool isVCSrcFake16BF16_Lo128()
const {
562 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
565 bool isVCSrcFake16F16_Lo128()
const {
566 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
569 bool isVCSrc_bf16()
const {
570 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
573 bool isVCSrc_f16()
const {
574 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
577 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
579 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
581 bool isVSrc_b32()
const {
582 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
585 bool isVSrc_b64()
const {
return isVCSrcF64() || isLiteralImm(MVT::i64); }
587 bool isVSrcT_b16()
const {
return isVCSrcTB16() || isLiteralImm(MVT::i16); }
589 bool isVSrcT_b16_Lo128()
const {
590 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
593 bool isVSrcFake16_b16_Lo128()
const {
594 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
597 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
599 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
601 bool isVCSrcV2FP32()
const {
605 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
607 bool isVCSrcV2INT32()
const {
611 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
613 bool isVSrc_f32()
const {
614 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
617 bool isVSrc_f64()
const {
return isVCSrcF64() || isLiteralImm(MVT::f64); }
619 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
621 bool isVSrcT_f16()
const {
return isVCSrcTF16() || isLiteralImm(MVT::f16); }
623 bool isVSrcT_bf16_Lo128()
const {
624 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
627 bool isVSrcT_f16_Lo128()
const {
628 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
631 bool isVSrcFake16_bf16_Lo128()
const {
632 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
635 bool isVSrcFake16_f16_Lo128()
const {
636 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
639 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
641 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
643 bool isVSrc_v2bf16()
const {
644 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
647 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
649 bool isVISrcB32()
const {
650 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
653 bool isVISrcB16()
const {
654 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
657 bool isVISrcV2B16()
const {
661 bool isVISrcF32()
const {
662 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
665 bool isVISrcF16()
const {
666 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
669 bool isVISrcV2F16()
const {
670 return isVISrcF16() || isVISrcB32();
673 bool isVISrc_64_bf16()
const {
674 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
677 bool isVISrc_64_f16()
const {
678 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
681 bool isVISrc_64_b32()
const {
682 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
685 bool isVISrc_64B64()
const {
686 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
689 bool isVISrc_64_f64()
const {
690 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
693 bool isVISrc_64V2FP32()
const {
694 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
697 bool isVISrc_64V2INT32()
const {
698 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
701 bool isVISrc_256_b32()
const {
702 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
705 bool isVISrc_256_f32()
const {
706 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
709 bool isVISrc_256B64()
const {
710 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
713 bool isVISrc_256_f64()
const {
714 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
717 bool isVISrc_128B16()
const {
718 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
721 bool isVISrc_128V2B16()
const {
722 return isVISrc_128B16();
725 bool isVISrc_128_b32()
const {
726 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
729 bool isVISrc_128_f32()
const {
730 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
733 bool isVISrc_256V2FP32()
const {
734 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
737 bool isVISrc_256V2INT32()
const {
738 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
741 bool isVISrc_512_b32()
const {
742 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
745 bool isVISrc_512B16()
const {
746 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
749 bool isVISrc_512V2B16()
const {
750 return isVISrc_512B16();
753 bool isVISrc_512_f32()
const {
754 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
757 bool isVISrc_512F16()
const {
758 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
761 bool isVISrc_512V2F16()
const {
762 return isVISrc_512F16() || isVISrc_512_b32();
765 bool isVISrc_1024_b32()
const {
766 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
769 bool isVISrc_1024B16()
const {
770 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
773 bool isVISrc_1024V2B16()
const {
774 return isVISrc_1024B16();
777 bool isVISrc_1024_f32()
const {
778 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
781 bool isVISrc_1024F16()
const {
782 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
785 bool isVISrc_1024V2F16()
const {
786 return isVISrc_1024F16() || isVISrc_1024_b32();
789 bool isAISrcB32()
const {
790 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
793 bool isAISrcB16()
const {
794 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
797 bool isAISrcV2B16()
const {
801 bool isAISrcF32()
const {
802 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
805 bool isAISrcF16()
const {
806 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
809 bool isAISrcV2F16()
const {
810 return isAISrcF16() || isAISrcB32();
813 bool isAISrc_64B64()
const {
814 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
817 bool isAISrc_64_f64()
const {
818 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
821 bool isAISrc_128_b32()
const {
822 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
825 bool isAISrc_128B16()
const {
826 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
829 bool isAISrc_128V2B16()
const {
830 return isAISrc_128B16();
833 bool isAISrc_128_f32()
const {
834 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
837 bool isAISrc_128F16()
const {
838 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
841 bool isAISrc_128V2F16()
const {
842 return isAISrc_128F16() || isAISrc_128_b32();
845 bool isVISrc_128_bf16()
const {
846 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
849 bool isVISrc_128_f16()
const {
850 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
853 bool isVISrc_128V2F16()
const {
854 return isVISrc_128_f16() || isVISrc_128_b32();
857 bool isAISrc_256B64()
const {
858 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
861 bool isAISrc_256_f64()
const {
862 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
865 bool isAISrc_512_b32()
const {
866 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
869 bool isAISrc_512B16()
const {
870 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
873 bool isAISrc_512V2B16()
const {
874 return isAISrc_512B16();
877 bool isAISrc_512_f32()
const {
878 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
881 bool isAISrc_512F16()
const {
882 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
885 bool isAISrc_512V2F16()
const {
886 return isAISrc_512F16() || isAISrc_512_b32();
889 bool isAISrc_1024_b32()
const {
890 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
893 bool isAISrc_1024B16()
const {
894 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
897 bool isAISrc_1024V2B16()
const {
898 return isAISrc_1024B16();
901 bool isAISrc_1024_f32()
const {
902 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
905 bool isAISrc_1024F16()
const {
906 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
909 bool isAISrc_1024V2F16()
const {
910 return isAISrc_1024F16() || isAISrc_1024_b32();
913 bool isKImmFP32()
const {
914 return isLiteralImm(MVT::f32);
917 bool isKImmFP16()
const {
918 return isLiteralImm(MVT::f16);
921 bool isMem()
const override {
925 bool isExpr()
const {
929 bool isSOPPBrTarget()
const {
return isExpr() ||
isImm(); }
931 bool isSWaitCnt()
const;
932 bool isDepCtr()
const;
933 bool isSDelayALU()
const;
934 bool isHwreg()
const;
935 bool isSendMsg()
const;
936 bool isSplitBarrier()
const;
937 bool isSwizzle()
const;
938 bool isSMRDOffset8()
const;
939 bool isSMEMOffset()
const;
940 bool isSMRDLiteralOffset()
const;
942 bool isDPPCtrl()
const;
944 bool isGPRIdxMode()
const;
945 bool isS16Imm()
const;
946 bool isU16Imm()
const;
947 bool isEndpgm()
const;
949 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
950 return std::bind(
P, *
this);
958 int64_t getImm()
const {
963 void setImm(int64_t Val) {
968 ImmTy getImmTy()
const {
978 SMLoc getStartLoc()
const override {
982 SMLoc getEndLoc()
const override {
987 return SMRange(StartLoc, EndLoc);
990 Modifiers getModifiers()
const {
991 assert(isRegKind() || isImmTy(ImmTyNone));
992 return isRegKind() ?
Reg.Mods :
Imm.Mods;
995 void setModifiers(Modifiers Mods) {
996 assert(isRegKind() || isImmTy(ImmTyNone));
1003 bool hasModifiers()
const {
1004 return getModifiers().hasModifiers();
1007 bool hasFPModifiers()
const {
1008 return getModifiers().hasFPModifiers();
1011 bool hasIntModifiers()
const {
1012 return getModifiers().hasIntModifiers();
1017 void addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1019 void addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1021 void addRegOperands(
MCInst &Inst,
unsigned N)
const;
1023 void addRegOrImmOperands(
MCInst &Inst,
unsigned N)
const {
1025 addRegOperands(Inst,
N);
1027 addImmOperands(Inst,
N);
1030 void addRegOrImmWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1031 Modifiers Mods = getModifiers();
1034 addRegOperands(Inst,
N);
1036 addImmOperands(Inst,
N,
false);
1040 void addRegOrImmWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1041 assert(!hasIntModifiers());
1042 addRegOrImmWithInputModsOperands(Inst,
N);
1045 void addRegOrImmWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1046 assert(!hasFPModifiers());
1047 addRegOrImmWithInputModsOperands(Inst,
N);
1050 void addRegWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1051 Modifiers Mods = getModifiers();
1054 addRegOperands(Inst,
N);
1057 void addRegWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1058 assert(!hasIntModifiers());
1059 addRegWithInputModsOperands(Inst,
N);
1062 void addRegWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1063 assert(!hasFPModifiers());
1064 addRegWithInputModsOperands(Inst,
N);
1070 case ImmTyNone:
OS <<
"None";
break;
1071 case ImmTyGDS:
OS <<
"GDS";
break;
1072 case ImmTyLDS:
OS <<
"LDS";
break;
1073 case ImmTyOffen:
OS <<
"Offen";
break;
1074 case ImmTyIdxen:
OS <<
"Idxen";
break;
1075 case ImmTyAddr64:
OS <<
"Addr64";
break;
1076 case ImmTyOffset:
OS <<
"Offset";
break;
1077 case ImmTyInstOffset:
OS <<
"InstOffset";
break;
1078 case ImmTyOffset0:
OS <<
"Offset0";
break;
1079 case ImmTyOffset1:
OS <<
"Offset1";
break;
1080 case ImmTySMEMOffsetMod:
OS <<
"SMEMOffsetMod";
break;
1081 case ImmTyCPol:
OS <<
"CPol";
break;
1082 case ImmTyIndexKey8bit:
OS <<
"index_key";
break;
1083 case ImmTyIndexKey16bit:
OS <<
"index_key";
break;
1084 case ImmTyTFE:
OS <<
"TFE";
break;
1085 case ImmTyD16:
OS <<
"D16";
break;
1086 case ImmTyFORMAT:
OS <<
"FORMAT";
break;
1087 case ImmTyClampSI:
OS <<
"ClampSI";
break;
1088 case ImmTyOModSI:
OS <<
"OModSI";
break;
1089 case ImmTyDPP8:
OS <<
"DPP8";
break;
1090 case ImmTyDppCtrl:
OS <<
"DppCtrl";
break;
1091 case ImmTyDppRowMask:
OS <<
"DppRowMask";
break;
1092 case ImmTyDppBankMask:
OS <<
"DppBankMask";
break;
1093 case ImmTyDppBoundCtrl:
OS <<
"DppBoundCtrl";
break;
1094 case ImmTyDppFI:
OS <<
"DppFI";
break;
1095 case ImmTySDWADstSel:
OS <<
"SDWADstSel";
break;
1096 case ImmTySDWASrc0Sel:
OS <<
"SDWASrc0Sel";
break;
1097 case ImmTySDWASrc1Sel:
OS <<
"SDWASrc1Sel";
break;
1098 case ImmTySDWADstUnused:
OS <<
"SDWADstUnused";
break;
1099 case ImmTyDMask:
OS <<
"DMask";
break;
1100 case ImmTyDim:
OS <<
"Dim";
break;
1101 case ImmTyUNorm:
OS <<
"UNorm";
break;
1102 case ImmTyDA:
OS <<
"DA";
break;
1103 case ImmTyR128A16:
OS <<
"R128A16";
break;
1104 case ImmTyA16:
OS <<
"A16";
break;
1105 case ImmTyLWE:
OS <<
"LWE";
break;
1106 case ImmTyOff:
OS <<
"Off";
break;
1107 case ImmTyExpTgt:
OS <<
"ExpTgt";
break;
1108 case ImmTyExpCompr:
OS <<
"ExpCompr";
break;
1109 case ImmTyExpVM:
OS <<
"ExpVM";
break;
1110 case ImmTyHwreg:
OS <<
"Hwreg";
break;
1111 case ImmTySendMsg:
OS <<
"SendMsg";
break;
1112 case ImmTyInterpSlot:
OS <<
"InterpSlot";
break;
1113 case ImmTyInterpAttr:
OS <<
"InterpAttr";
break;
1114 case ImmTyInterpAttrChan:
OS <<
"InterpAttrChan";
break;
1115 case ImmTyOpSel:
OS <<
"OpSel";
break;
1116 case ImmTyOpSelHi:
OS <<
"OpSelHi";
break;
1117 case ImmTyNegLo:
OS <<
"NegLo";
break;
1118 case ImmTyNegHi:
OS <<
"NegHi";
break;
1119 case ImmTySwizzle:
OS <<
"Swizzle";
break;
1120 case ImmTyGprIdxMode:
OS <<
"GprIdxMode";
break;
1121 case ImmTyHigh:
OS <<
"High";
break;
1122 case ImmTyBLGP:
OS <<
"BLGP";
break;
1123 case ImmTyCBSZ:
OS <<
"CBSZ";
break;
1124 case ImmTyABID:
OS <<
"ABID";
break;
1125 case ImmTyEndpgm:
OS <<
"Endpgm";
break;
1126 case ImmTyWaitVDST:
OS <<
"WaitVDST";
break;
1127 case ImmTyWaitEXP:
OS <<
"WaitEXP";
break;
1128 case ImmTyWaitVAVDst:
OS <<
"WaitVAVDst";
break;
1129 case ImmTyWaitVMVSrc:
OS <<
"WaitVMVSrc";
break;
1130 case ImmTyByteSel:
OS <<
"ByteSel" ;
break;
1138 OS <<
"<register " <<
getReg() <<
" mods: " <<
Reg.Mods <<
'>';
1141 OS <<
'<' << getImm();
1142 if (getImmTy() != ImmTyNone) {
1143 OS <<
" type: "; printImmTy(
OS, getImmTy());
1145 OS <<
" mods: " <<
Imm.Mods <<
'>';
1148 OS <<
'\'' << getToken() <<
'\'';
1151 OS <<
"<expr " << *Expr <<
'>';
1156 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1157 int64_t Val,
SMLoc Loc,
1158 ImmTy
Type = ImmTyNone,
1159 bool IsFPImm =
false) {
1160 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1162 Op->Imm.IsFPImm = IsFPImm;
1163 Op->Imm.Kind = ImmKindTyNone;
1165 Op->Imm.Mods = Modifiers();
1171 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1173 bool HasExplicitEncodingSize =
true) {
1174 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1175 Res->Tok.Data = Str.data();
1176 Res->Tok.Length = Str.size();
1177 Res->StartLoc = Loc;
1182 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1183 unsigned RegNo,
SMLoc S,
1185 auto Op = std::make_unique<AMDGPUOperand>(
Register, AsmParser);
1186 Op->Reg.RegNo = RegNo;
1187 Op->Reg.Mods = Modifiers();
1193 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1195 auto Op = std::make_unique<AMDGPUOperand>(
Expression, AsmParser);
1204 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1215class KernelScopeInfo {
1216 int SgprIndexUnusedMin = -1;
1217 int VgprIndexUnusedMin = -1;
1218 int AgprIndexUnusedMin = -1;
1222 void usesSgprAt(
int i) {
1223 if (i >= SgprIndexUnusedMin) {
1224 SgprIndexUnusedMin = ++i;
1233 void usesVgprAt(
int i) {
1234 if (i >= VgprIndexUnusedMin) {
1235 VgprIndexUnusedMin = ++i;
1240 VgprIndexUnusedMin);
1246 void usesAgprAt(
int i) {
1251 if (i >= AgprIndexUnusedMin) {
1252 AgprIndexUnusedMin = ++i;
1262 VgprIndexUnusedMin);
1269 KernelScopeInfo() =
default;
1275 usesSgprAt(SgprIndexUnusedMin = -1);
1276 usesVgprAt(VgprIndexUnusedMin = -1);
1278 usesAgprAt(AgprIndexUnusedMin = -1);
1282 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1283 unsigned RegWidth) {
1286 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1289 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1292 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1303 unsigned ForcedEncodingSize = 0;
1304 bool ForcedDPP =
false;
1305 bool ForcedSDWA =
false;
1306 KernelScopeInfo KernelScope;
1311#define GET_ASSEMBLER_HEADER
1312#include "AMDGPUGenAsmMatcher.inc"
1317 bool ParseAsAbsoluteExpression(
uint32_t &Ret);
1318 bool OutOfRangeError(
SMRange Range);
1334 bool calculateGPRBlocks(
const FeatureBitset &Features,
bool VCCUsed,
1335 bool FlatScrUsed,
bool XNACKUsed,
1336 std::optional<bool> EnableWavefrontSize32,
1337 unsigned NextFreeVGPR,
SMRange VGPRRange,
1338 unsigned NextFreeSGPR,
SMRange SGPRRange,
1339 unsigned &VGPRBlocks,
unsigned &SGPRBlocks);
1340 bool ParseDirectiveAMDGCNTarget();
1341 bool ParseDirectiveAMDHSACodeObjectVersion();
1342 bool ParseDirectiveAMDHSAKernel();
1344 bool ParseDirectiveAMDKernelCodeT();
1347 bool ParseDirectiveAMDGPUHsaKernel();
1349 bool ParseDirectiveISAVersion();
1350 bool ParseDirectiveHSAMetadata();
1351 bool ParseDirectivePALMetadataBegin();
1352 bool ParseDirectivePALMetadata();
1353 bool ParseDirectiveAMDGPULDS();
1357 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1358 const char *AssemblerDirectiveEnd,
1359 std::string &CollectString);
1361 bool AddNextRegisterToList(
unsigned& Reg,
unsigned& RegWidth,
1362 RegisterKind RegKind,
unsigned Reg1,
SMLoc Loc);
1363 bool ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
1364 unsigned &RegNum,
unsigned &RegWidth,
1365 bool RestoreOnFailure =
false);
1366 bool ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
1367 unsigned &RegNum,
unsigned &RegWidth,
1369 unsigned ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1372 unsigned ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1375 unsigned ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1377 bool ParseRegRange(
unsigned& Num,
unsigned& Width);
1378 unsigned getRegularReg(RegisterKind RegKind,
unsigned RegNum,
unsigned SubReg,
1379 unsigned RegWidth,
SMLoc Loc);
1383 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1384 void initializeGprCountSymbol(RegisterKind RegKind);
1385 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1392 OperandMode_Default,
1396 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1404 if (getFeatureBits().
none()) {
1436 initializeGprCountSymbol(IS_VGPR);
1437 initializeGprCountSymbol(IS_SGPR);
1510 bool hasInv2PiInlineImm()
const {
1511 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1514 bool hasFlatOffsets()
const {
1515 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1519 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1522 bool hasSGPR102_SGPR103()
const {
1526 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1528 bool hasIntClamp()
const {
1529 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1532 bool hasPartialNSAEncoding()
const {
1533 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1565 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1566 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1567 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1569 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1570 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1571 bool isForcedDPP()
const {
return ForcedDPP; }
1572 bool isForcedSDWA()
const {
return ForcedSDWA; }
1574 StringRef getMatchedVariantName()
const;
1576 std::unique_ptr<AMDGPUOperand>
parseRegister(
bool RestoreOnFailure =
false);
1578 bool RestoreOnFailure);
1581 SMLoc &EndLoc)
override;
1584 unsigned Kind)
override;
1588 bool MatchingInlineAsm)
override;
1591 OperandMode Mode = OperandMode_Default);
1599 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1603 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1604 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1608 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1609 bool (*ConvertResult)(int64_t &) =
nullptr);
1613 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1622 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1623 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1624 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1625 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1626 bool parseSP3NegModifier();
1628 bool HasLit =
false);
1631 bool HasLit =
false);
1633 bool AllowImm =
true);
1635 bool AllowImm =
true);
1640 AMDGPUOperand::ImmTy ImmTy);
1651 ParseStatus parseSymbolicOrNumericFormat(int64_t &Format);
1656 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1657 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt,
StringRef FormatStr,
SMLoc Loc);
1661 bool parseCnt(int64_t &IntVal);
1664 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1668 bool parseDelay(int64_t &Delay);
1674 struct OperandInfoTy {
1677 bool IsSymbolic =
false;
1678 bool IsDefined =
false;
1680 OperandInfoTy(int64_t Val) : Val(Val) {}
1683 struct StructuredOpField : OperandInfoTy {
1687 bool IsDefined =
false;
1692 virtual ~StructuredOpField() =
default;
1694 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1695 Parser.Error(Loc,
"invalid " +
Desc +
": " + Err);
1699 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1701 return Error(Parser,
"not supported on this GPU");
1703 return Error(Parser,
"only " +
Twine(Width) +
"-bit values are legal");
1711 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1712 bool validateSendMsg(
const OperandInfoTy &Msg,
1713 const OperandInfoTy &
Op,
1714 const OperandInfoTy &Stream);
1717 OperandInfoTy &Width);
1723 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1728 bool SearchMandatoryLiterals =
false)
const;
1737 bool validateSOPLiteral(
const MCInst &Inst)
const;
1739 bool validateVOPDRegBankConstraints(
const MCInst &Inst,
1741 bool validateIntClampSupported(
const MCInst &Inst);
1742 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1743 bool validateMIMGGatherDMask(
const MCInst &Inst);
1745 bool validateMIMGDataSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1746 bool validateMIMGAddrSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1747 bool validateMIMGD16(
const MCInst &Inst);
1748 bool validateMIMGMSAA(
const MCInst &Inst);
1749 bool validateOpSel(
const MCInst &Inst);
1752 bool validateVccOperand(
unsigned Reg)
const;
1757 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1758 bool validateVGPRAlign(
const MCInst &Inst)
const;
1762 bool validateDivScale(
const MCInst &Inst);
1765 const SMLoc &IDLoc);
1767 const unsigned CPol);
1770 std::optional<StringRef> validateLdsDirect(
const MCInst &Inst);
1771 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1772 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1773 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1774 unsigned findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1800 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1802 SMLoc getLoc()
const;
1806 void onBeginOfFile()
override;
1807 bool parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc)
override;
1818 bool parseSwizzleOperand(int64_t &
Op,
1819 const unsigned MinVal,
1820 const unsigned MaxVal,
1823 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1824 const unsigned MinVal,
1825 const unsigned MaxVal,
1828 bool parseSwizzleOffset(int64_t &Imm);
1829 bool parseSwizzleMacro(int64_t &Imm);
1830 bool parseSwizzleQuadPerm(int64_t &Imm);
1831 bool parseSwizzleBitmaskPerm(int64_t &Imm);
1832 bool parseSwizzleBroadcast(int64_t &Imm);
1833 bool parseSwizzleSwap(int64_t &Imm);
1834 bool parseSwizzleReverse(int64_t &Imm);
1837 int64_t parseGPRIdxMacro();
1845 OptionalImmIndexMap &OptionalIdx);
1853 OptionalImmIndexMap &OptionalIdx);
1855 OptionalImmIndexMap &OptionalIdx);
1860 bool parseDimId(
unsigned &Encoding);
1862 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1866 int64_t parseDPPCtrlSel(
StringRef Ctrl);
1867 int64_t parseDPPCtrlPerm();
1873 bool IsDPP8 =
false);
1879 AMDGPUOperand::ImmTy
Type);
1888 bool SkipDstVcc =
false,
1889 bool SkipSrcVcc =
false);
1902 return &APFloat::IEEEsingle();
1904 return &APFloat::IEEEdouble();
1906 return &APFloat::IEEEhalf();
1939 return &APFloat::IEEEsingle();
1945 return &APFloat::IEEEdouble();
1954 return &APFloat::IEEEhalf();
1962 return &APFloat::BFloat();
1977 APFloat::rmNearestTiesToEven,
1980 if (
Status != APFloat::opOK &&
1982 ((
Status & APFloat::opOverflow) != 0 ||
1983 (
Status & APFloat::opUnderflow) != 0)) {
2006bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2016 if (!isImmTy(ImmTyNone)) {
2027 if (type == MVT::f64 || type == MVT::i64) {
2029 AsmParser->hasInv2PiInlineImm());
2051 APFloat::rmNearestTiesToEven, &Lost);
2058 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2060 AsmParser->hasInv2PiInlineImm());
2065 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2066 AsmParser->hasInv2PiInlineImm());
2070 if (type == MVT::f64 || type == MVT::i64) {
2072 AsmParser->hasInv2PiInlineImm());
2081 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2082 type, AsmParser->hasInv2PiInlineImm());
2086 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2087 AsmParser->hasInv2PiInlineImm());
2090bool AMDGPUOperand::isLiteralImm(
MVT type)
const {
2092 if (!isImmTy(ImmTyNone)) {
2099 if (type == MVT::f64 && hasFPModifiers()) {
2116 if (type == MVT::f64) {
2121 if (type == MVT::i64) {
2134 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2135 : (type == MVT::v2i16) ? MVT::f32
2136 : (type == MVT::v2f32) ? MVT::f32
2143bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2144 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2147bool AMDGPUOperand::isVRegWithInputMods()
const {
2148 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2150 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2151 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2154template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2155 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2156 : AMDGPU::VGPR_16_Lo128RegClassID);
2159bool AMDGPUOperand::isSDWAOperand(
MVT type)
const {
2160 if (AsmParser->isVI())
2162 else if (AsmParser->isGFX9Plus())
2163 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2168bool AMDGPUOperand::isSDWAFP16Operand()
const {
2169 return isSDWAOperand(MVT::f16);
2172bool AMDGPUOperand::isSDWAFP32Operand()
const {
2173 return isSDWAOperand(MVT::f32);
2176bool AMDGPUOperand::isSDWAInt16Operand()
const {
2177 return isSDWAOperand(MVT::i16);
2180bool AMDGPUOperand::isSDWAInt32Operand()
const {
2181 return isSDWAOperand(MVT::i32);
2184bool AMDGPUOperand::isBoolReg()
const {
2185 auto FB = AsmParser->getFeatureBits();
2186 return isReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrc_b64()) ||
2187 (FB[AMDGPU::FeatureWavefrontSize32] && isSCSrc_b32()));
2192 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2207void AMDGPUOperand::addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2215 addLiteralImmOperand(Inst,
Imm.Val,
2217 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2219 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2225void AMDGPUOperand::addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2226 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2231 if (ApplyModifiers) {
2234 Val = applyInputFPModifiers(Val,
Size);
2238 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2248 AsmParser->hasInv2PiInlineImm())) {
2257 if (
Literal.getLoBits(32) != 0) {
2258 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(Inst.
getLoc(),
2259 "Can't encode literal as exact 64-bit floating-point operand. "
2260 "Low 32-bits will be set to zero");
2261 Val &= 0xffffffff00000000u;
2265 setImmKindLiteral();
2281 if (AsmParser->hasInv2PiInlineImm() &&
Literal == 0x3fc45f306725feed) {
2287 setImmKindLiteral();
2323 APFloat::rmNearestTiesToEven, &lost);
2327 uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2330 setImmKindMandatoryLiteral();
2332 setImmKindLiteral();
2363 AsmParser->hasInv2PiInlineImm())) {
2370 setImmKindLiteral();
2388 setImmKindLiteral();
2402 setImmKindLiteral();
2411 AsmParser->hasInv2PiInlineImm())) {
2418 setImmKindLiteral();
2427 AsmParser->hasInv2PiInlineImm())) {
2434 setImmKindLiteral();
2448 AsmParser->hasInv2PiInlineImm()));
2458 AsmParser->hasInv2PiInlineImm()));
2466 setImmKindMandatoryLiteral();
2470 setImmKindMandatoryLiteral();
2477void AMDGPUOperand::addRegOperands(
MCInst &Inst,
unsigned N)
const {
2481bool AMDGPUOperand::isInlineValue()
const {
2490 if (Is == IS_VGPR) {
2494 return AMDGPU::VGPR_32RegClassID;
2496 return AMDGPU::VReg_64RegClassID;
2498 return AMDGPU::VReg_96RegClassID;
2500 return AMDGPU::VReg_128RegClassID;
2502 return AMDGPU::VReg_160RegClassID;
2504 return AMDGPU::VReg_192RegClassID;
2506 return AMDGPU::VReg_224RegClassID;
2508 return AMDGPU::VReg_256RegClassID;
2510 return AMDGPU::VReg_288RegClassID;
2512 return AMDGPU::VReg_320RegClassID;
2514 return AMDGPU::VReg_352RegClassID;
2516 return AMDGPU::VReg_384RegClassID;
2518 return AMDGPU::VReg_512RegClassID;
2520 return AMDGPU::VReg_1024RegClassID;
2522 }
else if (Is == IS_TTMP) {
2526 return AMDGPU::TTMP_32RegClassID;
2528 return AMDGPU::TTMP_64RegClassID;
2530 return AMDGPU::TTMP_128RegClassID;
2532 return AMDGPU::TTMP_256RegClassID;
2534 return AMDGPU::TTMP_512RegClassID;
2536 }
else if (Is == IS_SGPR) {
2540 return AMDGPU::SGPR_32RegClassID;
2542 return AMDGPU::SGPR_64RegClassID;
2544 return AMDGPU::SGPR_96RegClassID;
2546 return AMDGPU::SGPR_128RegClassID;
2548 return AMDGPU::SGPR_160RegClassID;
2550 return AMDGPU::SGPR_192RegClassID;
2552 return AMDGPU::SGPR_224RegClassID;
2554 return AMDGPU::SGPR_256RegClassID;
2556 return AMDGPU::SGPR_288RegClassID;
2558 return AMDGPU::SGPR_320RegClassID;
2560 return AMDGPU::SGPR_352RegClassID;
2562 return AMDGPU::SGPR_384RegClassID;
2564 return AMDGPU::SGPR_512RegClassID;
2566 }
else if (Is == IS_AGPR) {
2570 return AMDGPU::AGPR_32RegClassID;
2572 return AMDGPU::AReg_64RegClassID;
2574 return AMDGPU::AReg_96RegClassID;
2576 return AMDGPU::AReg_128RegClassID;
2578 return AMDGPU::AReg_160RegClassID;
2580 return AMDGPU::AReg_192RegClassID;
2582 return AMDGPU::AReg_224RegClassID;
2584 return AMDGPU::AReg_256RegClassID;
2586 return AMDGPU::AReg_288RegClassID;
2588 return AMDGPU::AReg_320RegClassID;
2590 return AMDGPU::AReg_352RegClassID;
2592 return AMDGPU::AReg_384RegClassID;
2594 return AMDGPU::AReg_512RegClassID;
2596 return AMDGPU::AReg_1024RegClassID;
2604 .
Case(
"exec", AMDGPU::EXEC)
2605 .
Case(
"vcc", AMDGPU::VCC)
2606 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2607 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2608 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2609 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2610 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2611 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2612 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2613 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2614 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2615 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2616 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2617 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2618 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2619 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2620 .
Case(
"m0", AMDGPU::M0)
2621 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2622 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2623 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2624 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2625 .
Case(
"scc", AMDGPU::SRC_SCC)
2626 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2627 .
Case(
"tba", AMDGPU::TBA)
2628 .
Case(
"tma", AMDGPU::TMA)
2629 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2630 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2631 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2632 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2633 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2634 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2635 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2636 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2637 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2638 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2639 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2640 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2641 .
Case(
"pc", AMDGPU::PC_REG)
2642 .
Case(
"null", AMDGPU::SGPR_NULL)
2646bool AMDGPUAsmParser::ParseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
2647 SMLoc &EndLoc,
bool RestoreOnFailure) {
2648 auto R = parseRegister();
2649 if (!R)
return true;
2651 RegNo =
R->getReg();
2652 StartLoc =
R->getStartLoc();
2653 EndLoc =
R->getEndLoc();
2659 return ParseRegister(Reg, StartLoc, EndLoc,
false);
2664 bool Result = ParseRegister(Reg, StartLoc, EndLoc,
true);
2665 bool PendingErrors = getParser().hasPendingError();
2666 getParser().clearPendingErrors();
2674bool AMDGPUAsmParser::AddNextRegisterToList(
unsigned &Reg,
unsigned &RegWidth,
2675 RegisterKind RegKind,
unsigned Reg1,
2679 if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2684 if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2685 Reg = AMDGPU::FLAT_SCR;
2689 if (Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2690 Reg = AMDGPU::XNACK_MASK;
2694 if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2699 if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2704 if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2709 Error(Loc,
"register does not fit in the list");
2715 if (Reg1 != Reg + RegWidth / 32) {
2716 Error(Loc,
"registers in a list must have consecutive indices");
2734 {{
"ttmp"}, IS_TTMP},
2740 return Kind == IS_VGPR ||
2748 if (Str.starts_with(Reg.Name))
2754 return !Str.getAsInteger(10, Num);
2758AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2775 if (!RegSuffix.
empty()) {
2793AMDGPUAsmParser::isRegister()
2795 return isRegister(getToken(), peekToken());
2798unsigned AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2799 unsigned SubReg,
unsigned RegWidth,
2803 unsigned AlignSize = 1;
2804 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2810 if (RegNum % AlignSize != 0) {
2811 Error(Loc,
"invalid register alignment");
2812 return AMDGPU::NoRegister;
2815 unsigned RegIdx = RegNum / AlignSize;
2818 Error(Loc,
"invalid or unsupported register size");
2819 return AMDGPU::NoRegister;
2825 Error(Loc,
"register index is out of range");
2826 return AMDGPU::NoRegister;
2836 assert(Reg &&
"Invalid subregister!");
2842bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth) {
2843 int64_t RegLo, RegHi;
2847 SMLoc FirstIdxLoc = getLoc();
2850 if (!parseExpr(RegLo))
2854 SecondIdxLoc = getLoc();
2855 if (!parseExpr(RegHi))
2864 if (!isUInt<32>(RegLo)) {
2865 Error(FirstIdxLoc,
"invalid register index");
2869 if (!isUInt<32>(RegHi)) {
2870 Error(SecondIdxLoc,
"invalid register index");
2874 if (RegLo > RegHi) {
2875 Error(FirstIdxLoc,
"first register index should not exceed second index");
2879 Num =
static_cast<unsigned>(RegLo);
2880 RegWidth = 32 * ((RegHi - RegLo) + 1);
2884unsigned AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2885 unsigned &RegNum,
unsigned &RegWidth,
2892 RegKind = IS_SPECIAL;
2899unsigned AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2900 unsigned &RegNum,
unsigned &RegWidth,
2904 auto Loc = getLoc();
2908 Error(Loc,
"invalid register name");
2909 return AMDGPU::NoRegister;
2917 unsigned SubReg = NoSubRegister;
2918 if (!RegSuffix.
empty()) {
2930 Error(Loc,
"invalid register index");
2931 return AMDGPU::NoRegister;
2936 if (!ParseRegRange(RegNum, RegWidth))
2937 return AMDGPU::NoRegister;
2940 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
2943unsigned AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
2946 unsigned Reg = AMDGPU::NoRegister;
2947 auto ListLoc = getLoc();
2950 "expected a register or a list of registers")) {
2951 return AMDGPU::NoRegister;
2956 auto Loc = getLoc();
2957 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth))
2958 return AMDGPU::NoRegister;
2959 if (RegWidth != 32) {
2960 Error(Loc,
"expected a single 32-bit register");
2961 return AMDGPU::NoRegister;
2965 RegisterKind NextRegKind;
2966 unsigned NextReg, NextRegNum, NextRegWidth;
2969 if (!ParseAMDGPURegister(NextRegKind, NextReg,
2970 NextRegNum, NextRegWidth,
2972 return AMDGPU::NoRegister;
2974 if (NextRegWidth != 32) {
2975 Error(Loc,
"expected a single 32-bit register");
2976 return AMDGPU::NoRegister;
2978 if (NextRegKind != RegKind) {
2979 Error(Loc,
"registers in a list must be of the same kind");
2980 return AMDGPU::NoRegister;
2982 if (!AddNextRegisterToList(Reg, RegWidth, RegKind, NextReg, Loc))
2983 return AMDGPU::NoRegister;
2987 "expected a comma or a closing square bracket")) {
2988 return AMDGPU::NoRegister;
2992 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
2997bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
2998 unsigned &RegNum,
unsigned &RegWidth,
3000 auto Loc = getLoc();
3001 Reg = AMDGPU::NoRegister;
3004 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3005 if (Reg == AMDGPU::NoRegister)
3006 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3008 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3012 if (Reg == AMDGPU::NoRegister) {
3013 assert(Parser.hasPendingError());
3017 if (!subtargetHasRegister(*
TRI, Reg)) {
3018 if (Reg == AMDGPU::SGPR_NULL) {
3019 Error(Loc,
"'null' operand is not supported on this GPU");
3021 Error(Loc,
"register not available on this GPU");
3029bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
3030 unsigned &RegNum,
unsigned &RegWidth,
3031 bool RestoreOnFailure ) {
3032 Reg = AMDGPU::NoRegister;
3035 if (ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, Tokens)) {
3036 if (RestoreOnFailure) {
3037 while (!Tokens.
empty()) {
3046std::optional<StringRef>
3047AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3050 return StringRef(
".amdgcn.next_free_vgpr");
3052 return StringRef(
".amdgcn.next_free_sgpr");
3054 return std::nullopt;
3058void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3059 auto SymbolName = getGprCountSymbolName(RegKind);
3060 assert(SymbolName &&
"initializing invalid register kind");
3061 MCSymbol *
Sym = getContext().getOrCreateSymbol(*SymbolName);
3065bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3066 unsigned DwordRegIndex,
3067 unsigned RegWidth) {
3072 auto SymbolName = getGprCountSymbolName(RegKind);
3075 MCSymbol *
Sym = getContext().getOrCreateSymbol(*SymbolName);
3077 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3080 if (!
Sym->isVariable())
3081 return !
Error(getLoc(),
3082 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3083 if (!
Sym->getVariableValue(
false)->evaluateAsAbsolute(OldCount))
3086 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3088 if (OldCount <= NewMax)
3094std::unique_ptr<AMDGPUOperand>
3095AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3096 const auto &Tok = getToken();
3097 SMLoc StartLoc = Tok.getLoc();
3098 SMLoc EndLoc = Tok.getEndLoc();
3099 RegisterKind RegKind;
3100 unsigned Reg, RegNum, RegWidth;
3102 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth)) {
3106 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3109 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3110 return AMDGPUOperand::CreateReg(
this, Reg, StartLoc, EndLoc);
3114 bool HasSP3AbsModifier,
bool HasLit) {
3122 HasLit = trySkipId(
"lit");
3134 const auto& Tok = getToken();
3135 const auto& NextTok = peekToken();
3138 bool Negate =
false;
3146 AMDGPUOperand::Modifiers Mods;
3157 APFloat RealVal(APFloat::IEEEdouble());
3158 auto roundMode = APFloat::rmNearestTiesToEven;
3159 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3162 RealVal.changeSign();
3165 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3166 AMDGPUOperand::ImmTyNone,
true));
3167 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3168 Op.setModifiers(Mods);
3177 if (HasSP3AbsModifier) {
3186 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3189 if (Parser.parseExpression(Expr))
3193 if (Expr->evaluateAsAbsolute(IntVal)) {
3194 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3195 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3196 Op.setModifiers(Mods);
3200 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3213 if (
auto R = parseRegister()) {
3222 bool HasSP3AbsMod,
bool HasLit) {
3228 return parseImm(
Operands, HasSP3AbsMod, HasLit);
3232AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3235 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3241AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3246AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3247 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3251AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3252 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3269AMDGPUAsmParser::isModifier() {
3273 peekTokens(NextToken);
3275 return isOperandModifier(Tok, NextToken[0]) ||
3276 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3277 isOpcodeModifierWithVal(Tok, NextToken[0]);
3303AMDGPUAsmParser::parseSP3NegModifier() {
3306 peekTokens(NextToken);
3309 (isRegister(NextToken[0], NextToken[1]) ||
3311 isId(NextToken[0],
"abs"))) {
3329 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3331 SP3Neg = parseSP3NegModifier();
3334 Neg = trySkipId(
"neg");
3336 return Error(Loc,
"expected register or immediate");
3340 Abs = trySkipId(
"abs");
3344 Lit = trySkipId(
"lit");
3351 return Error(Loc,
"expected register or immediate");
3355 Res = parseRegOrImm(
Operands, SP3Abs, Lit);
3362 if (Lit && !
Operands.back()->isImm())
3363 Error(Loc,
"expected immediate with lit modifier");
3365 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3374 AMDGPUOperand::Modifiers Mods;
3375 Mods.Abs = Abs || SP3Abs;
3376 Mods.Neg = Neg || SP3Neg;
3379 if (Mods.hasFPModifiers() || Lit) {
3380 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3382 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3383 Op.setModifiers(Mods);
3391 bool Sext = trySkipId(
"sext");
3392 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3407 AMDGPUOperand::Modifiers Mods;
3410 if (Mods.hasIntModifiers()) {
3411 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3413 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3414 Op.setModifiers(Mods);
3421 return parseRegOrImmWithFPInputMods(
Operands,
false);
3425 return parseRegOrImmWithIntInputMods(
Operands,
false);
3429 auto Loc = getLoc();
3430 if (trySkipId(
"off")) {
3431 Operands.push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3432 AMDGPUOperand::ImmTyOff,
false));
3439 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3441 Operands.push_back(std::move(Reg));
3448unsigned AMDGPUAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
3455 return Match_InvalidOperand;
3457 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3458 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3463 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3464 return Match_InvalidOperand;
3468 return Match_Success;
3472 static const unsigned Variants[] = {
3483 if (isForcedDPP() && isForcedVOP3()) {
3487 if (getForcedEncodingSize() == 32) {
3492 if (isForcedVOP3()) {
3497 if (isForcedSDWA()) {
3503 if (isForcedDPP()) {
3511StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3512 if (isForcedDPP() && isForcedVOP3())
3515 if (getForcedEncodingSize() == 32)
3530unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3534 case AMDGPU::FLAT_SCR:
3536 case AMDGPU::VCC_LO:
3537 case AMDGPU::VCC_HI:
3544 return AMDGPU::NoRegister;
3551bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3552 unsigned OpIdx)
const {
3562 int64_t Val = MO.
getImm();
3611unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3617 case AMDGPU::V_LSHLREV_B64_e64:
3618 case AMDGPU::V_LSHLREV_B64_gfx10:
3619 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3620 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3621 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3622 case AMDGPU::V_LSHRREV_B64_e64:
3623 case AMDGPU::V_LSHRREV_B64_gfx10:
3624 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3625 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3626 case AMDGPU::V_ASHRREV_I64_e64:
3627 case AMDGPU::V_ASHRREV_I64_gfx10:
3628 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3629 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3630 case AMDGPU::V_LSHL_B64_e64:
3631 case AMDGPU::V_LSHR_B64_e64:
3632 case AMDGPU::V_ASHR_I64_e64:
3645 bool AddMandatoryLiterals =
false) {
3651 int16_t ImmDeferredIdx =
3668bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3671 return !isInlineConstant(Inst, OpIdx);
3672 }
else if (MO.
isReg()) {
3679 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3691 const unsigned Opcode = Inst.
getOpcode();
3692 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3695 if (!LaneSelOp.
isReg())
3698 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3701bool AMDGPUAsmParser::validateConstantBusLimitations(
3703 const unsigned Opcode = Inst.
getOpcode();
3705 unsigned LastSGPR = AMDGPU::NoRegister;
3706 unsigned ConstantBusUseCount = 0;
3707 unsigned NumLiterals = 0;
3708 unsigned LiteralSize;
3710 if (!(
Desc.TSFlags &
3726 unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3727 if (SGPRUsed != AMDGPU::NoRegister) {
3728 SGPRsUsed.
insert(SGPRUsed);
3729 ++ConstantBusUseCount;
3734 for (
int OpIdx : OpIndices) {
3739 if (usesConstantBus(Inst, OpIdx)) {
3748 if (SGPRsUsed.
insert(LastSGPR).second) {
3749 ++ConstantBusUseCount;
3769 if (NumLiterals == 0) {
3772 }
else if (LiteralSize !=
Size) {
3778 ConstantBusUseCount += NumLiterals;
3780 if (ConstantBusUseCount <= getConstantBusLimit(Opcode))
3786 Error(Loc,
"invalid operand (violates constant bus restrictions)");
3790bool AMDGPUAsmParser::validateVOPDRegBankConstraints(
3793 const unsigned Opcode = Inst.
getOpcode();
3799 auto getVRegIdx = [&](
unsigned,
unsigned OperandIdx) {
3807 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12;
3810 auto InvalidCompOprIdx =
3811 InstInfo.getInvalidCompOperandIndex(getVRegIdx, SkipSrc);
3812 if (!InvalidCompOprIdx)
3815 auto CompOprIdx = *InvalidCompOprIdx;
3817 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3818 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3821 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
3822 if (CompOprIdx == VOPD::Component::DST) {
3823 Error(Loc,
"one dst register must be even and the other odd");
3825 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3827 " operands must use different VGPR banks");
3833bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
3850bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
3851 const SMLoc &IDLoc) {
3869 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
3874 bool IsPackedD16 =
false;
3879 IsPackedD16 = D16Idx >= 0;
3881 DataSize = (DataSize + 1) / 2;
3884 if ((VDataSize / 4) == DataSize + TFESize)
3889 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
3891 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
3893 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
3897bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst,
3898 const SMLoc &IDLoc) {
3911 : AMDGPU::OpName::rsrc;
3918 assert(SrsrcIdx > VAddr0Idx);
3921 if (BaseOpcode->
BVH) {
3922 if (IsA16 == BaseOpcode->
A16)
3924 Error(IDLoc,
"image address size does not match a16");
3930 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
3931 unsigned ActualAddrSize =
3932 IsNSA ? SrsrcIdx - VAddr0Idx
3935 unsigned ExpectedAddrSize =
3939 if (hasPartialNSAEncoding() &&
3942 int VAddrLastIdx = SrsrcIdx - 1;
3943 unsigned VAddrLastSize =
3946 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
3949 if (ExpectedAddrSize > 12)
3950 ExpectedAddrSize = 16;
3955 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
3959 if (ActualAddrSize == ExpectedAddrSize)
3962 Error(IDLoc,
"image address size does not match dim and a16");
3966bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
3973 if (!
Desc.mayLoad() || !
Desc.mayStore())
3983 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
3986bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4002 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4005bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4016 if (!BaseOpcode->
MSAA)
4025 return DimInfo->
MSAA;
4031 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4032 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4033 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4043bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4067 Error(ErrLoc,
"source operand must be a VGPR");
4071bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4076 if (Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4090 "source operand must be either a VGPR or an inline constant");
4097bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4103 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4110 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4112 "inline constants are not allowed for this operand");
4119bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4137 if (Src2Reg == DstReg)
4141 if (
TRI->getRegClass(
Desc.operands()[0].RegClass).getSizeInBits() <= 128)
4144 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4146 "source 2 operand must not partially overlap with dst");
4153bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4157 case V_DIV_SCALE_F32_gfx6_gfx7:
4158 case V_DIV_SCALE_F32_vi:
4159 case V_DIV_SCALE_F32_gfx10:
4160 case V_DIV_SCALE_F64_gfx6_gfx7:
4161 case V_DIV_SCALE_F64_vi:
4162 case V_DIV_SCALE_F64_gfx10:
4168 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4169 AMDGPU::OpName::src2_modifiers,
4170 AMDGPU::OpName::src2_modifiers}) {
4181bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4201 case AMDGPU::V_SUBREV_F32_e32:
4202 case AMDGPU::V_SUBREV_F32_e64:
4203 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4204 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4205 case AMDGPU::V_SUBREV_F32_e32_vi:
4206 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4207 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4208 case AMDGPU::V_SUBREV_F32_e64_vi:
4210 case AMDGPU::V_SUBREV_CO_U32_e32:
4211 case AMDGPU::V_SUBREV_CO_U32_e64:
4212 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4213 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4215 case AMDGPU::V_SUBBREV_U32_e32:
4216 case AMDGPU::V_SUBBREV_U32_e64:
4217 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4218 case AMDGPU::V_SUBBREV_U32_e32_vi:
4219 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4220 case AMDGPU::V_SUBBREV_U32_e64_vi:
4222 case AMDGPU::V_SUBREV_U32_e32:
4223 case AMDGPU::V_SUBREV_U32_e64:
4224 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4225 case AMDGPU::V_SUBREV_U32_e32_vi:
4226 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4227 case AMDGPU::V_SUBREV_U32_e64_vi:
4229 case AMDGPU::V_SUBREV_F16_e32:
4230 case AMDGPU::V_SUBREV_F16_e64:
4231 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4232 case AMDGPU::V_SUBREV_F16_e32_vi:
4233 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4234 case AMDGPU::V_SUBREV_F16_e64_vi:
4236 case AMDGPU::V_SUBREV_U16_e32:
4237 case AMDGPU::V_SUBREV_U16_e64:
4238 case AMDGPU::V_SUBREV_U16_e32_vi:
4239 case AMDGPU::V_SUBREV_U16_e64_vi:
4241 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4242 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4243 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4245 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4246 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4248 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4249 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4251 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4252 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4254 case AMDGPU::V_LSHRREV_B32_e32:
4255 case AMDGPU::V_LSHRREV_B32_e64:
4256 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4257 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4258 case AMDGPU::V_LSHRREV_B32_e32_vi:
4259 case AMDGPU::V_LSHRREV_B32_e64_vi:
4260 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4261 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4263 case AMDGPU::V_ASHRREV_I32_e32:
4264 case AMDGPU::V_ASHRREV_I32_e64:
4265 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4266 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4267 case AMDGPU::V_ASHRREV_I32_e32_vi:
4268 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4269 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4270 case AMDGPU::V_ASHRREV_I32_e64_vi:
4272 case AMDGPU::V_LSHLREV_B32_e32:
4273 case AMDGPU::V_LSHLREV_B32_e64:
4274 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4275 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4276 case AMDGPU::V_LSHLREV_B32_e32_vi:
4277 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4278 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4279 case AMDGPU::V_LSHLREV_B32_e64_vi:
4281 case AMDGPU::V_LSHLREV_B16_e32:
4282 case AMDGPU::V_LSHLREV_B16_e64:
4283 case AMDGPU::V_LSHLREV_B16_e32_vi:
4284 case AMDGPU::V_LSHLREV_B16_e64_vi:
4285 case AMDGPU::V_LSHLREV_B16_gfx10:
4287 case AMDGPU::V_LSHRREV_B16_e32:
4288 case AMDGPU::V_LSHRREV_B16_e64:
4289 case AMDGPU::V_LSHRREV_B16_e32_vi:
4290 case AMDGPU::V_LSHRREV_B16_e64_vi:
4291 case AMDGPU::V_LSHRREV_B16_gfx10:
4293 case AMDGPU::V_ASHRREV_I16_e32:
4294 case AMDGPU::V_ASHRREV_I16_e64:
4295 case AMDGPU::V_ASHRREV_I16_e32_vi:
4296 case AMDGPU::V_ASHRREV_I16_e64_vi:
4297 case AMDGPU::V_ASHRREV_I16_gfx10:
4299 case AMDGPU::V_LSHLREV_B64_e64:
4300 case AMDGPU::V_LSHLREV_B64_gfx10:
4301 case AMDGPU::V_LSHLREV_B64_vi:
4303 case AMDGPU::V_LSHRREV_B64_e64:
4304 case AMDGPU::V_LSHRREV_B64_gfx10:
4305 case AMDGPU::V_LSHRREV_B64_vi:
4307 case AMDGPU::V_ASHRREV_I64_e64:
4308 case AMDGPU::V_ASHRREV_I64_gfx10:
4309 case AMDGPU::V_ASHRREV_I64_vi:
4311 case AMDGPU::V_PK_LSHLREV_B16:
4312 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4313 case AMDGPU::V_PK_LSHLREV_B16_vi:
4315 case AMDGPU::V_PK_LSHRREV_B16:
4316 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4317 case AMDGPU::V_PK_LSHRREV_B16_vi:
4318 case AMDGPU::V_PK_ASHRREV_I16:
4319 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4320 case AMDGPU::V_PK_ASHRREV_I16_vi:
4327std::optional<StringRef>
4328AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst) {
4330 using namespace SIInstrFlags;
4331 const unsigned Opcode = Inst.
getOpcode();
4337 if ((
Desc.TSFlags & Enc) == 0)
4338 return std::nullopt;
4340 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4345 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4348 return StringRef(
"lds_direct is not supported on this GPU");
4351 return StringRef(
"lds_direct cannot be used with this instruction");
4353 if (SrcName != OpName::src0)
4354 return StringRef(
"lds_direct may be used as src0 only");
4358 return std::nullopt;
4362 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4363 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4364 if (
Op.isFlatOffset())
4365 return Op.getStartLoc();
4370bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4379 return validateFlatOffset(Inst,
Operands);
4382 return validateSMEMOffset(Inst,
Operands);
4387 const unsigned OffsetSize = 24;
4388 if (!
isIntN(OffsetSize,
Op.getImm())) {
4390 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit signed offset");
4394 const unsigned OffsetSize = 16;
4395 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4397 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit unsigned offset");
4404bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4415 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4417 "flat offset modifier is not supported on this GPU");
4424 bool AllowNegative =
4427 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4429 Twine(
"expected a ") +
4430 (AllowNegative ?
Twine(OffsetSize) +
"-bit signed offset"
4431 :
Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4440 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4441 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4442 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4443 return Op.getStartLoc();
4448bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4474 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4475 :
"expected a 21-bit signed offset");
4480bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst)
const {
4489 const int OpIndices[] = { Src0Idx, Src1Idx };
4491 unsigned NumExprs = 0;
4492 unsigned NumLiterals = 0;
4495 for (
int OpIdx : OpIndices) {
4496 if (OpIdx == -1)
break;
4501 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4503 if (NumLiterals == 0 || LiteralValue !=
Value) {
4507 }
else if (MO.
isExpr()) {
4513 return NumLiterals + NumExprs <= 1;
4516bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4530 if (OpSelIdx != -1) {
4535 if (OpSelHiIdx != -1) {
4553bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst,
int OpName) {
4578 int SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4579 AMDGPU::OpName::src1_modifiers,
4580 AMDGPU::OpName::src2_modifiers};
4582 for (
unsigned i = 0; i < 3; ++i) {
4592bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4596 if (DppCtrlIdx >= 0) {
4603 Error(S,
"DP ALU dpp only supports row_newbcast");
4609 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4619 Error(S,
"invalid operand for instruction");
4624 "src1 immediate operand invalid for instruction");
4634bool AMDGPUAsmParser::validateVccOperand(
unsigned Reg)
const {
4635 auto FB = getFeatureBits();
4636 return (FB[AMDGPU::FeatureWavefrontSize64] && Reg == AMDGPU::VCC) ||
4637 (FB[AMDGPU::FeatureWavefrontSize32] &&
Reg == AMDGPU::VCC_LO);
4641bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
4647 !HasMandatoryLiteral && !
isVOPD(Opcode))
4652 unsigned NumExprs = 0;
4653 unsigned NumLiterals = 0;
4656 for (
int OpIdx : OpIndices) {
4666 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4672 if (!IsValid32Op && !isInt<32>(
Value) && !isUInt<32>(
Value)) {
4673 Error(getLitLoc(
Operands),
"invalid operand for instruction");
4677 if (IsFP64 && IsValid32Op)
4680 if (NumLiterals == 0 || LiteralValue !=
Value) {
4684 }
else if (MO.
isExpr()) {
4688 NumLiterals += NumExprs;
4693 if (!HasMandatoryLiteral && !getFeatureBits()[FeatureVOP3Literal]) {
4694 Error(getLitLoc(
Operands),
"literal operands are not supported");
4698 if (NumLiterals > 1) {
4699 Error(getLitLoc(
Operands,
true),
"only one unique literal operand is allowed");
4717 unsigned Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
4718 auto Reg = Sub ? Sub :
Op.getReg();
4720 return AGPR32.
contains(Reg) ? 1 : 0;
4723bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
4731 : AMDGPU::OpName::vdata;
4739 if (Data2Areg >= 0 && Data2Areg != DataAreg)
4743 auto FB = getFeatureBits();
4744 if (FB[AMDGPU::FeatureGFX90AInsts]) {
4745 if (DataAreg < 0 || DstAreg < 0)
4747 return DstAreg == DataAreg;
4750 return DstAreg < 1 && DataAreg < 1;
4753bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
4754 auto FB = getFeatureBits();
4755 if (!FB[AMDGPU::FeatureGFX90AInsts])
4766 unsigned Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
4770 if (VGPR32.
contains(Sub) && ((Sub - AMDGPU::VGPR0) & 1))
4772 if (AGPR32.
contains(Sub) && ((Sub - AMDGPU::AGPR0) & 1))
4780 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4781 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4783 return Op.getStartLoc();
4788bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
4798 auto FB = getFeatureBits();
4799 bool UsesNeg =
false;
4800 if (FB[AMDGPU::FeatureGFX940Insts]) {
4802 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
4803 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
4804 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
4805 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
4810 if (IsNeg == UsesNeg)
4814 UsesNeg ?
"invalid modifier: blgp is not supported"
4815 :
"invalid modifier: neg is not supported");
4820bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
4826 if (Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
4827 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
4828 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
4829 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
4835 if (Reg == AMDGPU::SGPR_NULL)
4839 Error(RegLoc,
"src0 must be null");
4843bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
4849 return validateGWS(Inst,
Operands);
4860 Error(S,
"gds modifier is not supported on this GPU");
4868bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
4870 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
4874 if (Opc != AMDGPU::DS_GWS_INIT_vi && Opc != AMDGPU::DS_GWS_BARRIER_vi &&
4875 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
4884 auto RegIdx =
Reg - (VGPR32.
contains(Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
4887 Error(RegLoc,
"vgpr must be even aligned");
4894bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
4896 const SMLoc &IDLoc) {
4898 AMDGPU::OpName::cpol);
4905 return validateTHAndScopeBits(Inst,
Operands, CPol);
4911 Error(S,
"cache policy is not supported for SMRD instructions");
4915 Error(IDLoc,
"invalid cache policy for SMEM instruction");
4924 if (!(TSFlags & AllowSCCModifier)) {
4929 "scc modifier is not supported for this instruction on this GPU");
4940 :
"instruction must use glc");
4948 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
4950 :
"instruction must not use glc");
4958bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
4960 const unsigned CPol) {
4964 const unsigned Opcode = Inst.
getOpcode();
4976 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
4984 return PrintError(
"invalid th value for SMEM instruction");
4991 return PrintError(
"scope and th combination is not valid");
5000 return PrintError(
"invalid th value for atomic instructions");
5001 }
else if (IsStore) {
5003 return PrintError(
"invalid th value for store instructions");
5006 return PrintError(
"invalid th value for load instructions");
5016 if (!Operand->isReg())
5018 unsigned Reg = Operand->getReg();
5019 if (Reg == SRC_EXECZ || Reg == SRC_VCCZ) {
5021 "execz and vccz are not supported on this GPU");
5028bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5031 if (
Desc.mayStore() &&
5035 Error(Loc,
"TFE modifier has no meaning for store instructions");
5043bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst,
5046 if (
auto ErrMsg = validateLdsDirect(Inst)) {
5050 if (!validateSOPLiteral(Inst)) {
5052 "only one unique literal operand is allowed");
5055 if (!validateVOPLiteral(Inst,
Operands)) {
5058 if (!validateConstantBusLimitations(Inst,
Operands)) {
5061 if (!validateVOPDRegBankConstraints(Inst,
Operands)) {
5064 if (!validateIntClampSupported(Inst)) {
5066 "integer clamping is not supported on this GPU");
5069 if (!validateOpSel(Inst)) {
5071 "invalid op_sel operand");
5074 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5076 "invalid neg_lo operand");
5079 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5081 "invalid neg_hi operand");
5084 if (!validateDPP(Inst,
Operands)) {
5088 if (!validateMIMGD16(Inst)) {
5090 "d16 modifier is not supported on this GPU");
5093 if (!validateMIMGMSAA(Inst)) {
5095 "invalid dim; must be MSAA type");
5098 if (!validateMIMGDataSize(Inst, IDLoc)) {
5101 if (!validateMIMGAddrSize(Inst, IDLoc))
5103 if (!validateMIMGAtomicDMask(Inst)) {
5105 "invalid atomic image dmask");
5108 if (!validateMIMGGatherDMask(Inst)) {
5110 "invalid image_gather dmask: only one bit must be set");
5113 if (!validateMovrels(Inst,
Operands)) {
5116 if (!validateOffset(Inst,
Operands)) {
5119 if (!validateMAIAccWrite(Inst,
Operands)) {
5122 if (!validateMAISrc2(Inst,
Operands)) {
5125 if (!validateMFMA(Inst,
Operands)) {
5128 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5132 if (!validateAGPRLdSt(Inst)) {
5133 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5134 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5135 :
"invalid register class: agpr loads and stores not supported on this GPU"
5139 if (!validateVGPRAlign(Inst)) {
5141 "invalid register class: vgpr tuples must be 64 bit aligned");
5148 if (!validateBLGP(Inst,
Operands)) {
5152 if (!validateDivScale(Inst)) {
5153 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5156 if (!validateWaitCnt(Inst,
Operands)) {
5159 if (!validateExeczVcczOperands(
Operands)) {
5162 if (!validateTFE(Inst,
Operands)) {
5171 unsigned VariantID = 0);
5175 unsigned VariantID);
5177bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5182bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5185 for (
auto Variant : Variants) {
5193bool AMDGPUAsmParser::checkUnsupportedInstruction(
StringRef Mnemo,
5194 const SMLoc &IDLoc) {
5195 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5198 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5203 getParser().clearPendingErrors();
5207 StringRef VariantName = getMatchedVariantName();
5208 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5211 " variant of this instruction is not supported"));
5215 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5216 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5219 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5220 .
flip(AMDGPU::FeatureWavefrontSize32);
5222 ComputeAvailableFeatures(FeaturesWS32);
5224 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5225 return Error(IDLoc,
"instruction requires wavesize=32");
5230 return Error(IDLoc,
"instruction not supported on this GPU");
5235 return Error(IDLoc,
"invalid instruction" + Suggestion);
5241 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5242 if (
Op.isToken() && InvalidOprIdx > 1) {
5243 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5244 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5249bool AMDGPUAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
5253 bool MatchingInlineAsm) {
5255 unsigned Result = Match_Success;
5256 for (
auto Variant : getMatchedVariants()) {
5258 auto R = MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm,
5263 if (R == Match_Success || R == Match_MissingFeature ||
5264 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5265 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5266 Result != Match_MissingFeature)) {
5270 if (R == Match_Success)
5274 if (Result == Match_Success) {
5275 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5284 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5290 case Match_MissingFeature:
5294 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5296 case Match_InvalidOperand: {
5297 SMLoc ErrorLoc = IDLoc;
5300 return Error(IDLoc,
"too few operands for instruction");
5303 if (ErrorLoc ==
SMLoc())
5307 return Error(ErrorLoc,
"invalid VOPDY instruction");
5309 return Error(ErrorLoc,
"invalid operand for instruction");
5312 case Match_MnemonicFail:
5318bool AMDGPUAsmParser::ParseAsAbsoluteExpression(
uint32_t &Ret) {
5323 if (getParser().parseAbsoluteExpression(Tmp)) {
5330bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5332 return TokError(
"directive only supported for amdgcn architecture");
5334 std::string TargetIDDirective;
5335 SMLoc TargetStart = getTok().getLoc();
5336 if (getParser().parseEscapedString(TargetIDDirective))
5340 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5341 return getParser().Error(TargetRange.
Start,
5342 (
Twine(
".amdgcn_target directive's target id ") +
5343 Twine(TargetIDDirective) +
5344 Twine(
" does not match the specified target id ") +
5345 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5350bool AMDGPUAsmParser::OutOfRangeError(
SMRange Range) {
5351 return Error(
Range.Start,
"value out of range", Range);
5354bool AMDGPUAsmParser::calculateGPRBlocks(
5355 const FeatureBitset &Features,
bool VCCUsed,
bool FlatScrUsed,
5356 bool XNACKUsed, std::optional<bool> EnableWavefrontSize32,
5357 unsigned NextFreeVGPR,
SMRange VGPRRange,
unsigned NextFreeSGPR,
5358 SMRange SGPRRange,
unsigned &VGPRBlocks,
unsigned &SGPRBlocks) {
5369 unsigned MaxAddressableNumSGPRs =
5372 if (
Version.Major >= 8 && !Features.
test(FeatureSGPRInitBug) &&
5373 NumSGPRs > MaxAddressableNumSGPRs)
5374 return OutOfRangeError(SGPRRange);
5379 if ((
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5380 NumSGPRs > MaxAddressableNumSGPRs)
5381 return OutOfRangeError(SGPRRange);
5383 if (Features.
test(FeatureSGPRInitBug))
5388 EnableWavefrontSize32);
5394bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5396 return TokError(
"directive only supported for amdgcn architecture");
5399 return TokError(
"directive only supported for amdhsa OS");
5402 if (getParser().parseIdentifier(KernelName))
5407 &getSTI(), getContext());
5423 unsigned ImpliedUserSGPRCount = 0;
5427 std::optional<unsigned> ExplicitUserSGPRCount;
5428 bool ReserveVCC =
true;
5429 bool ReserveFlatScr =
true;
5430 std::optional<bool> EnableWavefrontSize32;
5436 SMRange IDRange = getTok().getLocRange();
5437 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5440 if (
ID ==
".end_amdhsa_kernel")
5444 return TokError(
".amdhsa_ directives cannot be repeated");
5446 SMLoc ValStart = getLoc();
5448 if (getParser().parseExpression(ExprVal))
5450 SMLoc ValEnd = getLoc();
5455 bool EvaluatableExpr;
5456 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5458 return OutOfRangeError(ValRange);
5462#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5463 if (!isUInt<ENTRY##_WIDTH>(Val)) \
5464 return OutOfRangeError(RANGE); \
5465 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
5470#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
5472 return Error(IDRange.Start, "directive should have resolvable expression", \
5475 if (
ID ==
".amdhsa_group_segment_fixed_size") {
5478 return OutOfRangeError(ValRange);
5480 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
5483 return OutOfRangeError(ValRange);
5485 }
else if (
ID ==
".amdhsa_kernarg_size") {
5487 return OutOfRangeError(ValRange);
5489 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
5491 ExplicitUserSGPRCount = Val;
5492 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
5496 "directive is not supported with architected flat scratch",
5499 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
5502 ImpliedUserSGPRCount += 4;
5503 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
5506 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5509 return OutOfRangeError(ValRange);
5513 ImpliedUserSGPRCount += Val;
5514 PreloadLength = Val;
5516 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
5519 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5522 return OutOfRangeError(ValRange);
5526 PreloadOffset = Val;
5527 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
5530 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
5533 ImpliedUserSGPRCount += 2;
5534 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
5537 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
5540 ImpliedUserSGPRCount += 2;
5541 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
5544 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
5547 ImpliedUserSGPRCount += 2;
5548 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
5551 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
5554 ImpliedUserSGPRCount += 2;
5555 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
5558 "directive is not supported with architected flat scratch",
5562 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
5565 ImpliedUserSGPRCount += 2;
5566 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
5569 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
5572 ImpliedUserSGPRCount += 1;
5573 }
else if (
ID ==
".amdhsa_wavefront_size32") {
5575 if (IVersion.
Major < 10)
5576 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5577 EnableWavefrontSize32 = Val;
5579 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
5581 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
5583 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
5585 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
5588 "directive is not supported with architected flat scratch",
5591 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
5593 }
else if (
ID ==
".amdhsa_enable_private_segment") {
5597 "directive is not supported without architected flat scratch",
5600 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
5602 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
5604 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
5606 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
5608 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
5610 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
5612 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
5614 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
5616 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
5618 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
5620 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
5622 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
5624 VGPRRange = ValRange;
5626 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
5628 SGPRRange = ValRange;
5630 }
else if (
ID ==
".amdhsa_accum_offset") {
5632 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5635 }
else if (
ID ==
".amdhsa_reserve_vcc") {
5637 if (!isUInt<1>(Val))
5638 return OutOfRangeError(ValRange);
5640 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
5642 if (IVersion.
Major < 7)
5643 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
5646 "directive is not supported with architected flat scratch",
5648 if (!isUInt<1>(Val))
5649 return OutOfRangeError(ValRange);
5650 ReserveFlatScr = Val;
5651 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
5652 if (IVersion.
Major < 8)
5653 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
5654 if (!isUInt<1>(Val))
5655 return OutOfRangeError(ValRange);
5656 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
5657 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
5659 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
5661 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
5663 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
5665 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
5667 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
5669 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
5671 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
5673 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
5675 }
else if (
ID ==
".amdhsa_dx10_clamp") {
5676 if (IVersion.
Major >= 12)
5677 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
5679 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
5681 }
else if (
ID ==
".amdhsa_ieee_mode") {
5682 if (IVersion.
Major >= 12)
5683 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
5685 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
5687 }
else if (
ID ==
".amdhsa_fp16_overflow") {
5688 if (IVersion.
Major < 9)
5689 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
5691 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
5693 }
else if (
ID ==
".amdhsa_tg_split") {
5695 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5698 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
5699 if (IVersion.
Major < 10)
5700 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5702 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
5704 }
else if (
ID ==
".amdhsa_memory_ordered") {
5705 if (IVersion.
Major < 10)
5706 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5708 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
5710 }
else if (
ID ==
".amdhsa_forward_progress") {
5711 if (IVersion.
Major < 10)
5712 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5714 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
5716 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
5718 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
5719 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
5721 SharedVGPRCount = Val;
5723 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
5725 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
5728 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
5730 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
5732 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
5734 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
5737 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
5739 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
5741 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
5743 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
5745 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
5747 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
5749 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
5751 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
5753 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
5755 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
5756 if (IVersion.
Major < 12)
5757 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
5759 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
5762 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
5765#undef PARSE_BITS_ENTRY
5768 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
5769 return TokError(
".amdhsa_next_free_vgpr directive is required");
5771 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
5772 return TokError(
".amdhsa_next_free_sgpr directive is required");
5774 unsigned VGPRBlocks;
5775 unsigned SGPRBlocks;
5776 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
5777 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
5778 EnableWavefrontSize32, NextFreeVGPR,
5779 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
5783 if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_WIDTH>(
5785 return OutOfRangeError(VGPRRange);
5788 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
5789 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT, getContext());
5791 if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_WIDTH>(
5793 return OutOfRangeError(SGPRRange);
5796 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
5797 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT, getContext());
5799 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
5800 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
5801 "enabled user SGPRs");
5803 unsigned UserSGPRCount =
5804 ExplicitUserSGPRCount ? *ExplicitUserSGPRCount : ImpliedUserSGPRCount;
5806 if (!isUInt<COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_WIDTH>(UserSGPRCount))
5807 return TokError(
"too many user SGPRs enabled");
5810 COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_SHIFT,
5811 COMPUTE_PGM_RSRC2_USER_SGPR_COUNT, getContext());
5815 return TokError(
"Kernarg size should be resolvable");
5817 if (PreloadLength && kernarg_size &&
5818 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
5819 return TokError(
"Kernarg preload length + offset is larger than the "
5820 "kernarg segment size");
5823 if (!Seen.
contains(
".amdhsa_accum_offset"))
5824 return TokError(
".amdhsa_accum_offset directive is required");
5825 if (AccumOffset < 4 || AccumOffset > 256 || (AccumOffset & 3))
5826 return TokError(
"accum_offset should be in range [4..256] in "
5829 return TokError(
"accum_offset exceeds total VGPR allocation");
5833 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
5834 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET, getContext());
5837 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
5839 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
5840 return TokError(
"shared_vgpr_count directive not valid on "
5841 "wavefront size 32");
5843 if (SharedVGPRCount * 2 + VGPRBlocks > 63) {
5844 return TokError(
"shared_vgpr_count*2 + "
5845 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
5850 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
5851 NextFreeVGPR, NextFreeSGPR,
5852 ReserveVCC, ReserveFlatScr);
5856bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
5858 if (ParseAsAbsoluteExpression(Version))
5861 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(Version);
5865bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(
StringRef ID,
5869 if (
ID ==
"max_scratch_backing_memory_byte_size") {
5870 Parser.eatToEndOfStatement();
5877 return TokError(Err.str());
5881 if (
ID ==
"enable_dx10_clamp") {
5884 return TokError(
"enable_dx10_clamp=1 is not allowed on GFX12+");
5887 if (
ID ==
"enable_ieee_mode") {
5890 return TokError(
"enable_ieee_mode=1 is not allowed on GFX12+");
5893 if (
ID ==
"enable_wavefront_size32") {
5896 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
5897 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5898 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
5900 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5901 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
5905 if (
ID ==
"wavefront_size") {
5906 if (Header.wavefront_size == 5) {
5908 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
5909 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5910 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
5911 }
else if (Header.wavefront_size == 6) {
5912 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5913 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
5917 if (
ID ==
"enable_wgp_mode") {
5920 return TokError(
"enable_wgp_mode=1 is only allowed on GFX10+");
5923 if (
ID ==
"enable_mem_ordered") {
5926 return TokError(
"enable_mem_ordered=1 is only allowed on GFX10+");
5929 if (
ID ==
"enable_fwd_progress") {
5932 return TokError(
"enable_fwd_progress=1 is only allowed on GFX10+");
5938bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
5948 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
5951 if (
ID ==
".end_amd_kernel_code_t")
5954 if (ParseAMDKernelCodeTValue(
ID, Header))
5958 getTargetStreamer().EmitAMDKernelCodeT(Header);
5963bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
5965 if (!parseId(KernelName,
"expected symbol name"))
5968 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
5971 KernelScope.initialize(getContext());
5975bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
5977 return Error(getLoc(),
5978 ".amd_amdgpu_isa directive is not available on non-amdgcn "
5982 auto TargetIDDirective = getLexer().getTok().getStringContents();
5983 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5984 return Error(getParser().getTok().getLoc(),
"target id must match options");
5986 getTargetStreamer().EmitISAVersion();
5992bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
5995 std::string HSAMetadataString;
6000 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6001 return Error(getLoc(),
"invalid HSA metadata");
6008bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6009 const char *AssemblerDirectiveEnd,
6010 std::string &CollectString) {
6014 getLexer().setSkipSpace(
false);
6016 bool FoundEnd =
false;
6019 CollectStream << getTokenStr();
6023 if (trySkipId(AssemblerDirectiveEnd)) {
6028 CollectStream << Parser.parseStringToEndOfStatement()
6029 << getContext().getAsmInfo()->getSeparatorString();
6031 Parser.eatToEndOfStatement();
6034 getLexer().setSkipSpace(
true);
6037 return TokError(
Twine(
"expected directive ") +
6038 Twine(AssemblerDirectiveEnd) +
Twine(
" not found"));
6041 CollectStream.flush();
6046bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6052 auto PALMetadata = getTargetStreamer().getPALMetadata();
6053 if (!PALMetadata->setFromString(
String))
6054 return Error(getLoc(),
"invalid PAL metadata");
6059bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6061 return Error(getLoc(),
6063 "not available on non-amdpal OSes")).str());
6066 auto PALMetadata = getTargetStreamer().getPALMetadata();
6067 PALMetadata->setLegacy();
6070 if (ParseAsAbsoluteExpression(Key)) {
6071 return TokError(
Twine(
"invalid value in ") +
6075 return TokError(
Twine(
"expected an even number of values in ") +
6078 if (ParseAsAbsoluteExpression(
Value)) {
6079 return TokError(
Twine(
"invalid value in ") +
6082 PALMetadata->setRegister(Key,
Value);
6091bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6092 if (getParser().checkForValidSection())
6096 SMLoc NameLoc = getLoc();
6097 if (getParser().parseIdentifier(
Name))
6098 return TokError(
"expected identifier in directive");
6101 if (getParser().parseComma())
6107 SMLoc SizeLoc = getLoc();
6108 if (getParser().parseAbsoluteExpression(
Size))
6111 return Error(SizeLoc,
"size must be non-negative");
6112 if (
Size > LocalMemorySize)
6113 return Error(SizeLoc,
"size is too large");
6115 int64_t Alignment = 4;
6117 SMLoc AlignLoc = getLoc();
6118 if (getParser().parseAbsoluteExpression(Alignment))
6121 return Error(AlignLoc,
"alignment must be a power of two");
6126 if (Alignment >= 1u << 31)
6127 return Error(AlignLoc,
"alignment is too large");
6133 Symbol->redefineIfPossible();
6134 if (!
Symbol->isUndefined())
6135 return Error(NameLoc,
"invalid symbol redefinition");
6137 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6141bool AMDGPUAsmParser::ParseDirective(
AsmToken DirectiveID) {
6145 if (IDVal ==
".amdhsa_kernel")
6146 return ParseDirectiveAMDHSAKernel();
6148 if (IDVal ==
".amdhsa_code_object_version")
6149 return ParseDirectiveAMDHSACodeObjectVersion();
6153 return ParseDirectiveHSAMetadata();
6155 if (IDVal ==
".amd_kernel_code_t")
6156 return ParseDirectiveAMDKernelCodeT();
6158 if (IDVal ==
".amdgpu_hsa_kernel")
6159 return ParseDirectiveAMDGPUHsaKernel();
6161 if (IDVal ==
".amd_amdgpu_isa")
6162 return ParseDirectiveISAVersion();
6166 Twine(
" directive is "
6167 "not available on non-amdhsa OSes"))
6172 if (IDVal ==
".amdgcn_target")
6173 return ParseDirectiveAMDGCNTarget();
6175 if (IDVal ==
".amdgpu_lds")
6176 return ParseDirectiveAMDGPULDS();
6179 return ParseDirectivePALMetadataBegin();
6182 return ParseDirectivePALMetadata();
6190 if (
MRI.regsOverlap(AMDGPU::TTMP12_TTMP13_TTMP14_TTMP15, RegNo))
6194 if (
MRI.regsOverlap(AMDGPU::SGPR104_SGPR105, RegNo))
6195 return hasSGPR104_SGPR105();
6198 case AMDGPU::SRC_SHARED_BASE_LO:
6199 case AMDGPU::SRC_SHARED_BASE:
6200 case AMDGPU::SRC_SHARED_LIMIT_LO:
6201 case AMDGPU::SRC_SHARED_LIMIT:
6202 case AMDGPU::SRC_PRIVATE_BASE_LO:
6203 case AMDGPU::SRC_PRIVATE_BASE:
6204 case AMDGPU::SRC_PRIVATE_LIMIT_LO:
6205 case AMDGPU::SRC_PRIVATE_LIMIT:
6207 case AMDGPU::SRC_POPS_EXITING_WAVE_ID:
6210 case AMDGPU::TBA_LO:
6211 case AMDGPU::TBA_HI:
6213 case AMDGPU::TMA_LO:
6214 case AMDGPU::TMA_HI:
6216 case AMDGPU::XNACK_MASK:
6217 case AMDGPU::XNACK_MASK_LO:
6218 case AMDGPU::XNACK_MASK_HI:
6219 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6220 case AMDGPU::SGPR_NULL:
6234 case AMDGPU::FLAT_SCR:
6235 case AMDGPU::FLAT_SCR_LO:
6236 case AMDGPU::FLAT_SCR_HI:
6245 if (
MRI.regsOverlap(AMDGPU::SGPR102_SGPR103, RegNo))
6246 return hasSGPR102_SGPR103();
6259 Res = MatchOperandParserImpl(
Operands, Mnemonic);
6271 SMLoc LBraceLoc = getLoc();
6276 auto Loc = getLoc();
6279 Error(Loc,
"expected a register");
6283 RBraceLoc = getLoc();
6288 "expected a comma or a closing square bracket"))
6292 if (
Operands.size() - Prefix > 1) {
6294 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6295 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6306 setForcedEncodingSize(0);
6307 setForcedDPP(
false);
6308 setForcedSDWA(
false);
6310 if (
Name.ends_with(
"_e64_dpp")) {
6312 setForcedEncodingSize(64);
6313 return Name.substr(0,
Name.size() - 8);
6314 }
else if (
Name.ends_with(
"_e64")) {
6315 setForcedEncodingSize(64);
6316 return Name.substr(0,
Name.size() - 4);
6317 }
else if (
Name.ends_with(
"_e32")) {
6318 setForcedEncodingSize(32);
6319 return Name.substr(0,
Name.size() - 4);
6320 }
else if (
Name.ends_with(
"_dpp")) {
6322 return Name.substr(0,
Name.size() - 4);
6323 }
else if (
Name.ends_with(
"_sdwa")) {
6324 setForcedSDWA(
true);
6325 return Name.substr(0,
Name.size() - 5);
6332 unsigned VariantID);
6344 Operands.push_back(AMDGPUOperand::CreateToken(
this,
Name, NameLoc));
6346 bool IsMIMG =
Name.starts_with(
"image_");
6349 OperandMode Mode = OperandMode_Default;
6351 Mode = OperandMode_NSA;
6355 checkUnsupportedInstruction(
Name, NameLoc);
6356 if (!Parser.hasPendingError()) {
6359 :
"not a valid operand.";
6360 Error(getLoc(), Msg);
6382 if (!trySkipId(
Name))
6385 Operands.push_back(AMDGPUOperand::CreateToken(
this,
Name, S));
6389ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6400 std::function<
bool(int64_t &)> ConvertResult) {
6408 if (ConvertResult && !ConvertResult(
Value)) {
6412 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6416ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6418 bool (*ConvertResult)(int64_t &)) {
6427 const unsigned MaxSize = 4;
6431 for (
int I = 0; ; ++
I) {
6433 SMLoc Loc = getLoc();
6437 if (
Op != 0 &&
Op != 1)
6445 if (
I + 1 == MaxSize)
6446 return Error(getLoc(),
"expected a closing square bracket");
6452 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
6458 AMDGPUOperand::ImmTy ImmTy) {
6462 if (trySkipId(
Name)) {
6464 }
else if (trySkipId(
"no",
Name)) {
6471 return Error(S,
"r128 modifier is not supported on this GPU");
6473 return Error(S,
"a16 modifier is not supported on this GPU");
6475 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
6476 ImmTy = AMDGPUOperand::ImmTyR128A16;
6478 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
6483 bool &Disabling)
const {
6484 Disabling =
Id.consume_front(
"no");
6504 SMLoc StringLoc = getLoc();
6506 int64_t CPolVal = 0;
6524 ResScope = parseScope(
Operands, Scope);
6539 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
6540 AMDGPUOperand::ImmTyCPol));
6545 SMLoc OpLoc = getLoc();
6546 unsigned Enabled = 0, Seen = 0;
6550 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
6557 return Error(S,
"dlc modifier is not supported on this GPU");
6560 return Error(S,
"scc modifier is not supported on this GPU");
6563 return Error(S,
"duplicate cache policy modifier");
6575 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
6587 Res = parseStringWithPrefix(
"scope",
Value, StringLoc);
6598 if (Scope == 0xffffffff)
6599 return Error(StringLoc,
"invalid scope value");
6613 if (
Value ==
"TH_DEFAULT")
6615 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_RT_WB" ||
6616 Value ==
"TH_LOAD_NT_WB") {
6617 return Error(StringLoc,
"invalid th value");
6618 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
6620 }
else if (
Value.consume_front(
"TH_LOAD_")) {
6622 }
else if (
Value.consume_front(
"TH_STORE_")) {
6625 return Error(StringLoc,
"invalid th value");
6628 if (
Value ==
"BYPASS")
6659 if (TH == 0xffffffff)
6660 return Error(StringLoc,
"invalid th value");
6667 AMDGPUAsmParser::OptionalImmIndexMap& OptionalIdx,
6668 AMDGPUOperand::ImmTy ImmT,
6670 auto i = OptionalIdx.find(ImmT);
6671 if (i != OptionalIdx.end()) {
6672 unsigned Idx = i->second;
6673 ((AMDGPUOperand &)*
Operands[
Idx]).addImmOperands(Inst, 1);
6685 StringLoc = getLoc();
6694bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
6698 SMLoc Loc = getLoc();
6700 auto Res = parseIntWithPrefix(Pref, Val);
6706 if (Val < 0 || Val > MaxVal) {
6716 AMDGPUOperand::ImmTy ImmTy) {
6717 const char *Pref =
"index_key";
6719 SMLoc Loc = getLoc();
6720 auto Res = parseIntWithPrefix(Pref, ImmVal);
6724 if (ImmTy == AMDGPUOperand::ImmTyIndexKey16bit && (ImmVal < 0 || ImmVal > 1))
6727 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
6730 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
6735 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
6739 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
6744ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &Format) {
6751 for (
int I = 0;
I < 2; ++
I) {
6752 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
6755 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
6760 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
6766 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
6769 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6770 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6776ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &Format) {
6781 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
6784 if (Fmt == UFMT_UNDEF)
6791bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
6799 if (Format != DFMT_UNDEF) {
6805 if (Format != NFMT_UNDEF) {
6810 Error(Loc,
"unsupported format");
6821 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
6826 SMLoc Loc = getLoc();
6827 if (!parseId(Str,
"expected a format string") ||
6828 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
6830 if (Dfmt == DFMT_UNDEF)
6831 return Error(Loc,
"duplicate numeric format");
6832 if (Nfmt == NFMT_UNDEF)
6833 return Error(Loc,
"duplicate data format");
6836 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6837 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6841 if (Ufmt == UFMT_UNDEF)
6842 return Error(FormatLoc,
"unsupported format");
6857 if (Id == UFMT_UNDEF)
6861 return Error(Loc,
"unified format is not supported on this GPU");
6867ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &Format) {
6869 SMLoc Loc = getLoc();
6871 if (!parseExpr(Format))
6874 return Error(Loc,
"out of range format");
6879ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &Format) {
6887 SMLoc Loc = getLoc();
6888 if (!parseId(FormatStr,
"expected a format string"))
6891 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc, Format);
6893 Res = parseSymbolicSplitFormat(FormatStr, Loc, Format);
6903 return parseNumericFormat(Format);
6911 SMLoc Loc = getLoc();
6921 AMDGPUOperand::CreateImm(
this, Format, Loc, AMDGPUOperand::ImmTyFORMAT));
6940 Res = parseSymbolicOrNumericFormat(Format);
6945 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
6946 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
6953 return Error(getLoc(),
"duplicate format");
6959 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
6961 Res = parseIntWithPrefix(
"inst_offset",
Operands,
6962 AMDGPUOperand::ImmTyInstOffset);
6969 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
6971 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
6977 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
6980 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
6990 OptionalImmIndexMap OptionalIdx;
6992 unsigned OperandIdx[4];
6993 unsigned EnMask = 0;
6996 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
6997 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7002 OperandIdx[SrcIdx] = Inst.
size();
7003 Op.addRegOperands(Inst, 1);
7010 OperandIdx[SrcIdx] = Inst.
size();
7016 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7017 Op.addImmOperands(Inst, 1);
7021 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7025 OptionalIdx[
Op.getImmTy()] = i;
7031 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7038 for (
auto i = 0; i < SrcIdx; ++i) {
7040 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7065 IntVal =
encode(ISA, IntVal, CntVal);
7066 if (CntVal !=
decode(ISA, IntVal)) {
7068 IntVal =
encode(ISA, IntVal, -1);
7076bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7078 SMLoc CntLoc = getLoc();
7086 SMLoc ValLoc = getLoc();
7087 if (!parseExpr(CntVal))
7095 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7097 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7099 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7102 Error(CntLoc,
"invalid counter name " + CntName);
7107 Error(ValLoc,
"too large value for " + CntName);
7116 Error(getLoc(),
"expected a counter name");
7143bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7144 SMLoc FieldLoc = getLoc();
7150 SMLoc ValueLoc = getLoc();
7157 if (FieldName ==
"instid0") {
7159 }
else if (FieldName ==
"instskip") {
7161 }
else if (FieldName ==
"instid1") {
7164 Error(FieldLoc,
"invalid field name " + FieldName);
7183 .
Case(
"VALU_DEP_1", 1)
7184 .
Case(
"VALU_DEP_2", 2)
7185 .
Case(
"VALU_DEP_3", 3)
7186 .
Case(
"VALU_DEP_4", 4)
7187 .
Case(
"TRANS32_DEP_1", 5)
7188 .
Case(
"TRANS32_DEP_2", 6)
7189 .
Case(
"TRANS32_DEP_3", 7)
7190 .
Case(
"FMA_ACCUM_CYCLE_1", 8)
7191 .
Case(
"SALU_CYCLE_1", 9)
7192 .
Case(
"SALU_CYCLE_2", 10)
7193 .
Case(
"SALU_CYCLE_3", 11)
7201 Delay |=
Value << Shift;
7211 if (!parseDelay(Delay))
7215 if (!parseExpr(Delay))
7219 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7224AMDGPUOperand::isSWaitCnt()
const {
7228bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7234void AMDGPUAsmParser::depCtrError(
SMLoc Loc,
int ErrorId,
7238 Error(Loc,
Twine(
"invalid counter name ", DepCtrName));
7241 Error(Loc,
Twine(DepCtrName,
" is not supported on this GPU"));
7244 Error(Loc,
Twine(
"duplicate counter name ", DepCtrName));
7247 Error(Loc,
Twine(
"invalid value for ", DepCtrName));
7254bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7258 SMLoc DepCtrLoc = getLoc();
7266 if (!parseExpr(ExprVal))
7269 unsigned PrevOprMask = UsedOprMask;
7270 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7273 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7282 Error(getLoc(),
"expected a counter name");
7287 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7288 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7296 SMLoc Loc = getLoc();
7299 unsigned UsedOprMask = 0;
7301 if (!parseDepCtr(DepCtr, UsedOprMask))
7305 if (!parseExpr(DepCtr))
7309 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
7313bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
7319ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
7321 OperandInfoTy &Width) {
7328 HwReg.Loc = getLoc();
7331 HwReg.IsSymbolic =
true;
7333 }
else if (!parseExpr(HwReg.Val,
"a register name")) {
7341 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
7345 if (!parseExpr(
Offset.Val))
7351 Width.Loc = getLoc();
7352 if (!parseExpr(Width.Val) ||
7363 SMLoc Loc = getLoc();
7365 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
7367 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
7368 HwregOffset::Default);
7369 struct : StructuredOpField {
7370 using StructuredOpField::StructuredOpField;
7371 bool validate(AMDGPUAsmParser &Parser)
const override {
7373 return Error(Parser,
"only values from 1 to 32 are legal");
7376 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
7380 Res = parseHwregFunc(HwReg,
Offset, Width);
7383 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
7385 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
7389 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
7395 if (!isUInt<16>(ImmVal))
7396 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
7398 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
7402bool AMDGPUOperand::isHwreg()
const {
7403 return isImmTy(ImmTyHwreg);
7411AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
7413 OperandInfoTy &Stream) {
7419 Msg.IsSymbolic =
true;
7421 }
else if (!parseExpr(Msg.Val,
"a message name")) {
7426 Op.IsDefined =
true;
7429 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
7432 }
else if (!parseExpr(
Op.Val,
"an operation name")) {
7437 Stream.IsDefined =
true;
7438 Stream.Loc = getLoc();
7439 if (!parseExpr(Stream.Val))
7448AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
7449 const OperandInfoTy &
Op,
7450 const OperandInfoTy &Stream) {
7456 bool Strict = Msg.IsSymbolic;
7460 Error(Msg.Loc,
"specified message id is not supported on this GPU");
7465 Error(Msg.Loc,
"invalid message id");
7471 Error(
Op.Loc,
"message does not support operations");
7473 Error(Msg.Loc,
"missing message operation");
7479 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
7481 Error(
Op.Loc,
"invalid operation id");
7486 Error(Stream.Loc,
"message operation does not support streams");
7490 Error(Stream.Loc,
"invalid message stream id");
7500 SMLoc Loc = getLoc();
7504 OperandInfoTy
Op(OP_NONE_);
7505 OperandInfoTy Stream(STREAM_ID_NONE_);
7506 if (parseSendMsgBody(Msg,
Op, Stream) &&
7507 validateSendMsg(Msg,
Op, Stream)) {
7512 }
else if (parseExpr(ImmVal,
"a sendmsg macro")) {
7513 if (ImmVal < 0 || !isUInt<16>(ImmVal))
7514 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
7519 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
7523bool AMDGPUOperand::isSendMsg()
const {
7524 return isImmTy(ImmTySendMsg);
7545 return Error(S,
"invalid interpolation slot");
7547 Operands.push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
7548 AMDGPUOperand::ImmTyInterpSlot));
7559 if (!Str.starts_with(
"attr"))
7560 return Error(S,
"invalid interpolation attribute");
7570 return Error(S,
"invalid or missing interpolation attribute channel");
7572 Str = Str.drop_back(2).drop_front(4);
7575 if (Str.getAsInteger(10, Attr))
7576 return Error(S,
"invalid or missing interpolation attribute number");
7579 return Error(S,
"out of bounds interpolation attribute number");
7583 Operands.push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
7584 AMDGPUOperand::ImmTyInterpAttr));
7585 Operands.push_back(AMDGPUOperand::CreateImm(
7586 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
7605 return Error(S, (
Id == ET_INVALID)
7606 ?
"invalid exp target"
7607 :
"exp target is not supported on this GPU");
7609 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Id, S,
7610 AMDGPUOperand::ImmTyExpTgt));
7625 return isId(getToken(),
Id);
7630 return getTokenKind() ==
Kind;
7633StringRef AMDGPUAsmParser::getId()
const {
7660 if (isId(
Id) && peekToken().is(Kind)) {
7670 if (isToken(Kind)) {
7680 if (!trySkipToken(Kind)) {
7681 Error(getLoc(), ErrMsg);
7692 if (Parser.parseExpression(Expr))
7695 if (Expr->evaluateAsAbsolute(Imm))
7699 Error(S,
"expected absolute expression");
7702 Twine(
" or an absolute expression"));
7712 if (Parser.parseExpression(Expr))
7716 if (Expr->evaluateAsAbsolute(IntVal)) {
7717 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
7719 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
7727 Val = getToken().getStringContents();
7731 Error(getLoc(), ErrMsg);
7739 Val = getTokenStr();
7743 if (!ErrMsg.
empty())
7744 Error(getLoc(), ErrMsg);
7750AMDGPUAsmParser::getToken()
const {
7751 return Parser.getTok();
7754AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
7757 : getLexer().peekTok(ShouldSkipSpace);
7762 auto TokCount = getLexer().peekTokens(Tokens);
7769AMDGPUAsmParser::getTokenKind()
const {
7774AMDGPUAsmParser::getLoc()
const {
7775 return getToken().getLoc();
7779AMDGPUAsmParser::getTokenStr()
const {
7780 return getToken().getString();
7784AMDGPUAsmParser::lex() {
7789 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
7793AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
7795 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
7796 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7798 return Op.getStartLoc();
7804AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
7806 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
7811AMDGPUAsmParser::getRegLoc(
unsigned Reg,
7813 auto Test = [=](
const AMDGPUOperand&
Op) {
7814 return Op.isRegKind() &&
Op.getReg() ==
Reg;
7820 bool SearchMandatoryLiterals)
const {
7821 auto Test = [](
const AMDGPUOperand&
Op) {
7822 return Op.IsImmKindLiteral() ||
Op.isExpr();
7825 if (SearchMandatoryLiterals && Loc == getInstLoc(
Operands))
7826 Loc = getMandatoryLitLoc(
Operands);
7831 auto Test = [](
const AMDGPUOperand &
Op) {
7832 return Op.IsImmKindMandatoryLiteral();
7839 auto Test = [](
const AMDGPUOperand&
Op) {
7840 return Op.isImmKindConst();
7857 SMLoc IdLoc = getLoc();
7863 find_if(Fields, [
Id](StructuredOpField *
F) {
return F->Id ==
Id; });
7864 if (
I == Fields.
end())
7865 return Error(IdLoc,
"unknown field");
7866 if ((*I)->IsDefined)
7867 return Error(IdLoc,
"duplicate field");
7870 (*I)->Loc = getLoc();
7871 if (!parseExpr((*I)->Val))
7873 (*I)->IsDefined =
true;
7880bool AMDGPUAsmParser::validateStructuredOpFields(
7882 return all_of(Fields, [
this](
const StructuredOpField *
F) {
7883 return F->validate(*
this);
7894 const unsigned OrMask,
7895 const unsigned XorMask) {
7898 return BITMASK_PERM_ENC |
7899 (AndMask << BITMASK_AND_SHIFT) |
7900 (OrMask << BITMASK_OR_SHIFT) |
7901 (XorMask << BITMASK_XOR_SHIFT);
7905AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
7906 const unsigned MinVal,
7907 const unsigned MaxVal,
7914 if (!parseExpr(
Op)) {
7917 if (Op < MinVal || Op > MaxVal) {
7926AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
7927 const unsigned MinVal,
7928 const unsigned MaxVal,
7931 for (
unsigned i = 0; i < OpNum; ++i) {
7932 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
7940AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &Imm) {
7944 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
7945 "expected a 2-bit lane id")) {
7956AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &Imm) {
7963 if (!parseSwizzleOperand(GroupSize,
7965 "group size must be in the interval [2,32]",
7970 Error(Loc,
"group size must be a power of two");
7973 if (parseSwizzleOperand(LaneIdx,
7975 "lane id must be in the interval [0,group size - 1]",
7984AMDGPUAsmParser::parseSwizzleReverse(int64_t &Imm) {
7990 if (!parseSwizzleOperand(GroupSize,
7992 "group size must be in the interval [2,32]",
7997 Error(Loc,
"group size must be a power of two");
8006AMDGPUAsmParser::parseSwizzleSwap(int64_t &Imm) {
8012 if (!parseSwizzleOperand(GroupSize,
8014 "group size must be in the interval [1,16]",
8019 Error(Loc,
"group size must be a power of two");
8028AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &Imm) {
8036 SMLoc StrLoc = getLoc();
8037 if (!parseString(Ctl)) {
8040 if (Ctl.
size() != BITMASK_WIDTH) {
8041 Error(StrLoc,
"expected a 5-character mask");
8045 unsigned AndMask = 0;
8046 unsigned OrMask = 0;
8047 unsigned XorMask = 0;
8049 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8053 Error(StrLoc,
"invalid mask");
8075AMDGPUAsmParser::parseSwizzleOffset(int64_t &Imm) {
8077 SMLoc OffsetLoc = getLoc();
8079 if (!parseExpr(Imm,
"a swizzle macro")) {
8082 if (!isUInt<16>(Imm)) {
8083 Error(OffsetLoc,
"expected a 16-bit offset");
8090AMDGPUAsmParser::parseSwizzleMacro(int64_t &Imm) {
8095 SMLoc ModeLoc = getLoc();
8098 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8099 Ok = parseSwizzleQuadPerm(Imm);
8100 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8101 Ok = parseSwizzleBitmaskPerm(Imm);
8102 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8103 Ok = parseSwizzleBroadcast(Imm);
8104 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8105 Ok = parseSwizzleSwap(Imm);
8106 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8107 Ok = parseSwizzleReverse(Imm);
8109 Error(ModeLoc,
"expected a swizzle mode");
8112 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8122 if (trySkipId(
"offset")) {
8126 if (trySkipId(
"swizzle")) {
8127 Ok = parseSwizzleMacro(Imm);
8129 Ok = parseSwizzleOffset(Imm);
8133 Operands.push_back(AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTySwizzle));
8141AMDGPUOperand::isSwizzle()
const {
8142 return isImmTy(ImmTySwizzle);
8149int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8163 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8164 if (trySkipId(IdSymbolic[ModeId])) {
8171 Error(S, (Imm == 0)?
8172 "expected a VGPR index mode or a closing parenthesis" :
8173 "expected a VGPR index mode");
8178 Error(S,
"duplicate VGPR index mode");
8186 "expected a comma or a closing parenthesis"))
8201 Imm = parseGPRIdxMacro();
8205 if (getParser().parseAbsoluteExpression(Imm))
8207 if (Imm < 0 || !isUInt<4>(Imm))
8208 return Error(S,
"invalid immediate: only 4-bit values are legal");
8212 AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8216bool AMDGPUOperand::isGPRIdxMode()
const {
8217 return isImmTy(ImmTyGprIdxMode);
8229 if (isRegister() || isModifier())
8236 assert(Opr.isImm() || Opr.isExpr());
8237 SMLoc Loc = Opr.getStartLoc();
8241 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8242 Error(Loc,
"expected an absolute expression or a label");
8243 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8244 Error(Loc,
"expected a 16-bit signed jump offset");
8262void AMDGPUAsmParser::cvtMubufImpl(
MCInst &Inst,
8265 OptionalImmIndexMap OptionalIdx;
8266 unsigned FirstOperandIdx = 1;
8267 bool IsAtomicReturn =
false;
8274 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
8275 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8279 Op.addRegOperands(Inst, 1);
8283 if (IsAtomicReturn && i == FirstOperandIdx)
8284 Op.addRegOperands(Inst, 1);
8289 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
8290 Op.addImmOperands(Inst, 1);
8302 OptionalIdx[
Op.getImmTy()] = i;
8313bool AMDGPUOperand::isSMRDOffset8()
const {
8314 return isImmLiteral() && isUInt<8>(getImm());
8317bool AMDGPUOperand::isSMEMOffset()
const {
8319 return isImmLiteral();
8322bool AMDGPUOperand::isSMRDLiteralOffset()
const {
8325 return isImmLiteral() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
8357bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
8358 if (BoundCtrl == 0 || BoundCtrl == 1) {
8366void AMDGPUAsmParser::onBeginOfFile() {
8367 if (!getParser().getStreamer().getTargetStreamer() ||
8371 if (!getTargetStreamer().getTargetID())
8372 getTargetStreamer().initializeTargetID(getSTI(),
8373 getSTI().getFeatureString());
8376 getTargetStreamer().EmitDirectiveAMDGCNTarget();
8384bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
8390 .
Case(
"max", AGVK::AGVK_Max)
8391 .
Case(
"or", AGVK::AGVK_Or)
8392 .
Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
8393 .
Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
8394 .
Case(
"alignto", AGVK::AGVK_AlignTo)
8395 .
Case(
"occupancy", AGVK::AGVK_Occupancy)
8405 if (Exprs.
empty()) {
8406 Error(getToken().getLoc(),
8407 "empty " +
Twine(TokenId) +
" expression");
8410 if (CommaCount + 1 != Exprs.
size()) {
8411 Error(getToken().getLoc(),
8412 "mismatch of commas in " +
Twine(TokenId) +
" expression");
8419 if (getParser().parseExpression(Expr, EndLoc))
8423 if (LastTokenWasComma)
8426 Error(getToken().getLoc(),
8427 "unexpected token in " +
Twine(TokenId) +
" expression");
8433 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
8438 if (
Name ==
"mul") {
8439 return parseIntWithPrefix(
"mul",
Operands,
8443 if (
Name ==
"div") {
8444 return parseIntWithPrefix(
"div",
Operands,
8460 const int Ops[] = { AMDGPU::OpName::src0,
8461 AMDGPU::OpName::src1,
8462 AMDGPU::OpName::src2 };
8477 if (
DstOp.isReg() &&
8478 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
8482 if ((OpSel & (1 << SrcNum)) != 0)
8488void AMDGPUAsmParser::cvtVOP3OpSel(
MCInst &Inst,
8495 OptionalImmIndexMap &OptionalIdx) {
8496 cvtVOP3P(Inst,
Operands, OptionalIdx);
8505 &&
Desc.NumOperands > (OpNum + 1)
8507 &&
Desc.operands()[OpNum + 1].RegClass != -1
8509 &&
Desc.getOperandConstraint(OpNum + 1,
8510 MCOI::OperandConstraint::TIED_TO) == -1;
8515 OptionalImmIndexMap OptionalIdx;
8520 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8521 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8524 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8525 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8527 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8528 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
8529 Op.isInterpAttrChan()) {
8531 }
else if (
Op.isImmModifier()) {
8532 OptionalIdx[
Op.getImmTy()] =
I;
8540 AMDGPUOperand::ImmTyHigh);
8544 AMDGPUOperand::ImmTyClampSI);
8548 AMDGPUOperand::ImmTyOModSI);
8553 OptionalImmIndexMap OptionalIdx;
8558 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8559 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8562 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8563 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8565 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8566 }
else if (
Op.isImmModifier()) {
8567 OptionalIdx[
Op.getImmTy()] =
I;
8584 const int Ops[] = { AMDGPU::OpName::src0,
8585 AMDGPU::OpName::src1,
8586 AMDGPU::OpName::src2 };
8587 const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8588 AMDGPU::OpName::src1_modifiers,
8589 AMDGPU::OpName::src2_modifiers };
8593 for (
int J = 0; J < 3; ++J) {
8601 if ((OpSel & (1 << J)) != 0)
8603 if (ModOps[J] == AMDGPU::OpName::src0_modifiers &&
8604 (OpSel & (1 << 3)) != 0)
8612 OptionalImmIndexMap &OptionalIdx) {
8617 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8618 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8621 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8622 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8624 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8625 }
else if (
Op.isImmModifier()) {
8626 OptionalIdx[
Op.getImmTy()] =
I;
8627 }
else if (
Op.isRegOrImm()) {
8628 Op.addRegOrImmOperands(Inst, 1);
8638 AMDGPUOperand::ImmTyByteSel);
8643 AMDGPUOperand::ImmTyClampSI);
8647 AMDGPUOperand::ImmTyOModSI);
8654 auto it = Inst.
begin();
8664 OptionalImmIndexMap OptionalIdx;
8665 cvtVOP3(Inst,
Operands, OptionalIdx);
8669 OptionalImmIndexMap &OptIdx) {
8675 if (Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
8676 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
8677 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
8678 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
8686 !(Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp_gfx12 ||
8687 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp_gfx12 ||
8688 Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp8_gfx12 ||
8689 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp8_gfx12 ||
8690 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
8691 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
8692 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
8693 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12)) {
8702 if (OpSelIdx != -1) {
8707 if (OpSelHiIdx != -1) {
8721 const int Ops[] = { AMDGPU::OpName::src0,
8722 AMDGPU::OpName::src1,
8723 AMDGPU::OpName::src2 };
8724 const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8725 AMDGPU::OpName::src1_modifiers,
8726 AMDGPU::OpName::src2_modifiers };
8729 unsigned OpSelHi = 0;
8736 if (OpSelHiIdx != -1)
8745 for (
int J = 0; J < 3; ++J) {
8758 if (
SrcOp.isReg() && getMRI()
8765 if ((OpSel & (1 << J)) != 0)
8769 if ((OpSelHi & (1 << J)) != 0)
8772 if ((NegLo & (1 << J)) != 0)
8775 if ((NegHi & (1 << J)) != 0)
8783 OptionalImmIndexMap OptIdx;
8789 unsigned i,
unsigned Opc,
unsigned OpName) {
8791 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
8793 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
8799 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
8802 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
8803 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
8805 OptionalImmIndexMap OptIdx;
8806 for (
unsigned i = 5; i <
Operands.size(); ++i) {
8807 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8808 OptIdx[
Op.getImmTy()] = i;
8813 AMDGPUOperand::ImmTyIndexKey8bit);
8817 AMDGPUOperand::ImmTyIndexKey16bit);
8837 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
8838 SMLoc OpYLoc = getLoc();
8841 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
8844 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
8851 auto addOp = [&](
uint16_t ParsedOprIdx) {
8852 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
8854 Op.addRegOperands(Inst, 1);
8858 Op.addImmOperands(Inst, 1);
8870 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
8874 const auto &CInfo = InstInfo[CompIdx];
8875 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
8876 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
8877 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
8878 if (CInfo.hasSrc2Acc())
8879 addOp(CInfo.getIndexOfDstInParsedOperands());
8887bool AMDGPUOperand::isDPP8()
const {
8888 return isImmTy(ImmTyDPP8);
8891bool AMDGPUOperand::isDPPCtrl()
const {
8892 using namespace AMDGPU::DPP;
8894 bool result =
isImm() && getImmTy() == ImmTyDppCtrl && isUInt<9>(getImm());
8896 int64_t
Imm = getImm();
8897 return (Imm >= DppCtrl::QUAD_PERM_FIRST && Imm <= DppCtrl::QUAD_PERM_LAST) ||
8898 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
8899 (Imm >= DppCtrl::ROW_SHR_FIRST && Imm <= DppCtrl::ROW_SHR_LAST) ||
8900 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
8901 (Imm == DppCtrl::WAVE_SHL1) ||
8902 (
Imm == DppCtrl::WAVE_ROL1) ||
8903 (Imm == DppCtrl::WAVE_SHR1) ||
8904 (
Imm == DppCtrl::WAVE_ROR1) ||
8905 (Imm == DppCtrl::ROW_MIRROR) ||
8906 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
8907 (Imm == DppCtrl::BCAST15) ||
8908 (
Imm == DppCtrl::BCAST31) ||
8909 (Imm >= DppCtrl::ROW_SHARE_FIRST && Imm <= DppCtrl::ROW_SHARE_LAST) ||
8910 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
8919bool AMDGPUOperand::isBLGP()
const {
8920 return isImm() && getImmTy() == ImmTyBLGP && isUInt<3>(getImm());
8923bool AMDGPUOperand::isS16Imm()
const {
8924 return isImmLiteral() && (isInt<16>(getImm()) || isUInt<16>(getImm()));
8927bool AMDGPUOperand::isU16Imm()
const {
8928 return isImmLiteral() && isUInt<16>(getImm());
8935bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
8940 SMLoc Loc = getToken().getEndLoc();
8941 Token = std::string(getTokenStr());
8943 if (getLoc() != Loc)
8948 if (!parseId(Suffix))
8974 SMLoc Loc = getLoc();
8975 if (!parseDimId(Encoding))
8976 return Error(Loc,
"invalid dim value");
8978 Operands.push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
8979 AMDGPUOperand::ImmTyDim));
8997 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9000 for (
size_t i = 0; i < 8; ++i) {
9004 SMLoc Loc = getLoc();
9005 if (getParser().parseAbsoluteExpression(Sels[i]))
9007 if (0 > Sels[i] || 7 < Sels[i])
9008 return Error(Loc,
"expected a 3-bit value");
9015 for (
size_t i = 0; i < 8; ++i)
9016 DPP8 |= (Sels[i] << (i * 3));
9018 Operands.push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9023AMDGPUAsmParser::isSupportedDPPCtrl(
StringRef Ctrl,
9025 if (Ctrl ==
"row_newbcast")
9028 if (Ctrl ==
"row_share" ||
9029 Ctrl ==
"row_xmask")
9032 if (Ctrl ==
"wave_shl" ||
9033 Ctrl ==
"wave_shr" ||
9034 Ctrl ==
"wave_rol" ||
9035 Ctrl ==
"wave_ror" ||
9036 Ctrl ==
"row_bcast")
9039 return Ctrl ==
"row_mirror" ||
9040 Ctrl ==
"row_half_mirror" ||
9041 Ctrl ==
"quad_perm" ||
9042 Ctrl ==
"row_shl" ||
9043 Ctrl ==
"row_shr" ||
9048AMDGPUAsmParser::parseDPPCtrlPerm() {
9051 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9055 for (
int i = 0; i < 4; ++i) {
9060 SMLoc Loc = getLoc();
9061 if (getParser().parseAbsoluteExpression(Temp))
9063 if (Temp < 0 || Temp > 3) {
9064 Error(Loc,
"expected a 2-bit value");
9068 Val += (Temp << i * 2);
9078AMDGPUAsmParser::parseDPPCtrlSel(
StringRef Ctrl) {
9079 using namespace AMDGPU::DPP;
9084 SMLoc Loc = getLoc();
9086 if (getParser().parseAbsoluteExpression(Val))
9089 struct DppCtrlCheck {
9096 .
Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
9097 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
9098 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
9099 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
9100 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
9101 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
9102 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
9103 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
9104 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
9105 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
9109 if (
Check.Ctrl == -1) {
9110 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
9111 Val = (Val == 15)? DppCtrl::BCAST15 : DppCtrl::BCAST31;
9126 using namespace AMDGPU::DPP;
9129 !isSupportedDPPCtrl(getTokenStr(),
Operands))
9138 if (Ctrl ==
"row_mirror") {
9139 Val = DppCtrl::ROW_MIRROR;
9140 }
else if (Ctrl ==
"row_half_mirror") {
9141 Val = DppCtrl::ROW_HALF_MIRROR;
9144 if (Ctrl ==
"quad_perm") {
9145 Val = parseDPPCtrlPerm();
9147 Val = parseDPPCtrlSel(Ctrl);
9156 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
9162 OptionalImmIndexMap OptionalIdx;
9172 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
9176 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9177 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9181 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9185 if (OldIdx == NumOperands) {
9187 constexpr int DST_IDX = 0;
9189 }
else if (Src2ModIdx == NumOperands) {
9200 bool IsVOP3CvtSrDpp =
9201 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9202 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9203 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9204 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
9205 if (IsVOP3CvtSrDpp) {
9219 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9221 if (IsDPP8 &&
Op.isDppFI()) {
9224 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9225 }
else if (
Op.isReg()) {
9226 Op.addRegOperands(Inst, 1);
9227 }
else if (
Op.isImm() &&
9229 assert(!
Op.IsImmKindLiteral() &&
"Cannot use literal with DPP");
9230 Op.addImmOperands(Inst, 1);
9231 }
else if (
Op.isImm()) {
9232 OptionalIdx[
Op.getImmTy()] =
I;
9240 AMDGPUOperand::ImmTyByteSel);
9249 cvtVOP3P(Inst,
Operands, OptionalIdx);
9251 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
9268 AMDGPUOperand::ImmTyDppFI);
9273 OptionalImmIndexMap OptionalIdx;
9277 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9278 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9282 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9290 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9292 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
9300 Op.addImmOperands(Inst, 1);
9302 Op.addRegWithFPInputModsOperands(Inst, 2);
9303 }
else if (
Op.isDppFI()) {
9305 }
else if (
Op.isReg()) {
9306 Op.addRegOperands(Inst, 1);
9312 Op.addRegWithFPInputModsOperands(Inst, 2);
9313 }
else if (
Op.isReg()) {
9314 Op.addRegOperands(Inst, 1);
9315 }
else if (
Op.isDPPCtrl()) {
9316 Op.addImmOperands(Inst, 1);
9317 }
else if (
Op.isImm()) {
9319 OptionalIdx[
Op.getImmTy()] =
I;
9335 AMDGPUOperand::ImmTyDppFI);
9346 AMDGPUOperand::ImmTy
Type) {
9359 .
Case(
"BYTE_0", SdwaSel::BYTE_0)
9360 .
Case(
"BYTE_1", SdwaSel::BYTE_1)
9361 .
Case(
"BYTE_2", SdwaSel::BYTE_2)
9362 .
Case(
"BYTE_3", SdwaSel::BYTE_3)
9363 .
Case(
"WORD_0", SdwaSel::WORD_0)
9364 .
Case(
"WORD_1", SdwaSel::WORD_1)
9365 .
Case(
"DWORD", SdwaSel::DWORD)
9368 if (
Int == 0xffffffff)
9369 return Error(StringLoc,
"invalid " +
Twine(Prefix) +
" value");
9388 .
Case(
"UNUSED_PAD", DstUnused::UNUSED_PAD)
9389 .
Case(
"UNUSED_SEXT", DstUnused::UNUSED_SEXT)
9390 .
Case(
"UNUSED_PRESERVE", DstUnused::UNUSED_PRESERVE)
9393 if (
Int == 0xffffffff)
9394 return Error(StringLoc,
"invalid dst_unused value");
9396 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Int, S, AMDGPUOperand::ImmTySDWADstUnused));
9426 OptionalImmIndexMap OptionalIdx;
9427 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
9428 bool SkippedVcc =
false;
9432 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9433 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9436 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9437 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9438 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
9439 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
9457 Op.addRegOrImmWithInputModsOperands(Inst, 2);
9458 }
else if (
Op.isImm()) {
9460 OptionalIdx[
Op.getImmTy()] =
I;
9468 if (Opc != AMDGPU::V_NOP_sdwa_gfx10 && Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
9469 Opc != AMDGPU::V_NOP_sdwa_vi) {
9471 switch (BasicInstType) {
9475 AMDGPUOperand::ImmTyClampSI, 0);
9479 AMDGPUOperand::ImmTyOModSI, 0);
9483 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
9487 AMDGPUOperand::ImmTySDWADstUnused,
9488 DstUnused::UNUSED_PRESERVE);
9513 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
9519 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
9520 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
9521 auto it = Inst.
begin();
9534#define GET_REGISTER_MATCHER
9535#define GET_MATCHER_IMPLEMENTATION
9536#define GET_MNEMONIC_SPELL_CHECKER
9537#define GET_MNEMONIC_CHECKER
9538#include "AMDGPUGenAsmMatcher.inc"
9544 return parseTokenOp(
"addr64",
Operands);
9546 return parseTokenOp(
"done",
Operands);
9548 return parseTokenOp(
"idxen",
Operands);
9550 return parseTokenOp(
"lds",
Operands);
9552 return parseTokenOp(
"offen",
Operands);
9554 return parseTokenOp(
"off",
Operands);
9556 return parseTokenOp(
"row_en",
Operands);
9558 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
9560 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
9562 return tryCustomParseOperand(
Operands, MCK);
9573 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
9576 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
9578 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
9580 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
9582 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
9584 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
9586 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
9594 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
9596 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
9597 case MCK_SOPPBrTarget:
9598 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
9599 case MCK_VReg32OrOff:
9600 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
9601 case MCK_InterpSlot:
9602 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
9603 case MCK_InterpAttr:
9604 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
9605 case MCK_InterpAttrChan:
9606 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
9608 case MCK_SReg_64_XEXEC:
9614 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
9616 return Match_InvalidOperand;
9628 if (!parseExpr(Imm)) {
9633 if (!isUInt<16>(Imm))
9634 return Error(S,
"expected a 16-bit value");
9637 AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTyEndpgm));
9641bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
9647bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
unsigned const MachineRegisterInfo * MRI
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
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)
constexpr uint64_t MIMGFlags
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 unsigned getSpecialRegForName(StringRef RegName)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, unsigned OpName)
static bool IsRevOpcode(const unsigned Opcode)
static int getRegClass(RegisterKind Is, unsigned RegWidth)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0)
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 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)
static int IsAGPROperand(const MCInst &Inst, uint16_t NameIdx, const MCRegisterInfo *MRI)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static unsigned getOperandSize(MachineInstr &MI, unsigned Idx, MachineRegisterInfo &MRI)
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
mir Rename Register Operands
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
#define G_00B848_FWD_PROGRESS(x)
#define G_00B848_MEM_ORDERED(x)
#define G_00B848_IEEE_MODE(x)
#define G_00B848_DX10_CLAMP(x)
#define G_00B848_WGP_MODE(x)
Interface definition for SIInstrInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Interface definition for SIRegisterInfo.
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
unsigned unsigned DefaultVal
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
support::ulittle16_t & Lo
support::ulittle16_t & Hi
static const AMDGPUVariadicMCExpr * create(VariadicKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Target independent representation for an assembler token.
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
TokenKind getKind() const
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Class representing an expression and its matching format.
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCRegisterInfo * getRegisterInfo() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCSubtargetInfo * getSubtargetInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
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.
bool mayStore() const
Return true if this instruction could possibly modify memory.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
void setReg(unsigned Reg)
Set the register number.
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the 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...
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NoRegister
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void setVariableValue(const MCExpr *Value)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
Target specific streamer interface.
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.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
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
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
Represents a range in source code.
Implements a dense probed hash-table based set with some number of buckets stored inline.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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...
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - 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.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - 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
size - Get the string size.
constexpr const char * data() const
data - 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.
StringSet - A wrapper for StringMap that provides set-like functionality.
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...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
#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 NumVGPRs[]
Key for Kernel::CodeProps::Metadata::mNumVGPRs.
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)
unsigned getNumExtraSGPRs(const MCSubtargetInfo *STI, bool VCCUsed, bool FlatScrUsed, bool XNACKUsed)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
unsigned getNumSGPRBlocks(const MCSubtargetInfo *STI, unsigned NumSGPRs)
unsigned getEncodedNumVGPRBlocks(const MCSubtargetInfo *STI, unsigned NumVGPRs, std::optional< bool > EnableWavefrontSize32)
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)
constexpr unsigned COMPONENTS[]
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc, unsigned OpNo)
Get size of register operand.
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
LLVM_READNONE bool isLegalDPALU_DPPControl(unsigned DC)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
bool isGFX10(const MCSubtargetInfo &STI)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header, const MCSubtargetInfo *STI)
bool isInlinableLiteralV2BF16(uint32_t Literal)
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.
unsigned mc2PseudoReg(unsigned Reg)
Convert hardware register Reg to a pseudo register.
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)
IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
bool isDPALU_DPP(const MCInstrDesc &OpDesc)
bool isSI(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
bool isGFX9(const MCSubtargetInfo &STI)
bool isGFX10_AEncoding(const MCSubtargetInfo &STI)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
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 isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this an AMDGPU specific source operand? These include registers, inline constants,...
bool hasMAIInsts(const MCSubtargetInfo &STI)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, uint64_t NamedIdx)
LLVM_READNONE bool isInlinableIntLiteral(int64_t Literal)
Is this literal inlinable, and not one of the values intended for floating point values.
bool isSGPR(unsigned Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
bool isHi(unsigned Reg, const MCRegisterInfo &MRI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isInlineValue(unsigned Reg)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_V2INT32
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_INLINE_AC_V2FP16
@ OPERAND_REG_IMM_INT32
Operands with register or 32-bit immediate.
@ OPERAND_REG_IMM_BF16_DEFERRED
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_AC_BF16
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_INLINE_AC_INT16
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_V2INT16
@ OPERAND_REG_INLINE_AC_FP16
@ OPERAND_REG_INLINE_AC_INT32
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_INLINE_AC_V2BF16
@ 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_REG_INLINE_C_V2FP32
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
@ OPERAND_REG_IMM_FP32_DEFERRED
@ OPERAND_REG_IMM_FP16_DEFERRED
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 isVI(const MCSubtargetInfo &STI)
unsigned hasKernargPreload(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)
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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)
Reg
All possible values of the reg field in the ModR/M byte.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
int popcount(T Value) noexcept
Count the number of set bits in a value.
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator)
Returns the integer ceil(Numerator / Denominator).
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
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 uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool parseAmdKernelCodeField(StringRef ID, MCAsmParser &Parser, amd_kernel_code_t &C, raw_ostream &Err)
AMD Kernel Code Object (amd_kernel_code_t).
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
Represents the counter values to wait for in an s_waitcnt instruction.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static const fltSemantics & IEEEhalf() LLVM_READNONE
static const fltSemantics & BFloat() LLVM_READNONE
opStatus
IEEE-754R 7: Default exception handling.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Description of the encoding of one expression Op.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size