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 [=](){
return 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 ImmTyClamp:
OS <<
"Clamp";
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 void createConstantSymbol(
StringRef Id, int64_t Val);
1319 bool ParseAsAbsoluteExpression(
uint32_t &Ret);
1337 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1338 std::optional<bool> EnableWavefrontSize32,
1342 bool ParseDirectiveAMDGCNTarget();
1343 bool ParseDirectiveAMDHSACodeObjectVersion();
1344 bool ParseDirectiveAMDHSAKernel();
1346 bool ParseDirectiveAMDKernelCodeT();
1349 bool ParseDirectiveAMDGPUHsaKernel();
1351 bool ParseDirectiveISAVersion();
1352 bool ParseDirectiveHSAMetadata();
1353 bool ParseDirectivePALMetadataBegin();
1354 bool ParseDirectivePALMetadata();
1355 bool ParseDirectiveAMDGPULDS();
1359 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1360 const char *AssemblerDirectiveEnd,
1361 std::string &CollectString);
1363 bool AddNextRegisterToList(
unsigned& Reg,
unsigned& RegWidth,
1364 RegisterKind RegKind,
unsigned Reg1,
SMLoc Loc);
1365 bool ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
1366 unsigned &RegNum,
unsigned &RegWidth,
1367 bool RestoreOnFailure =
false);
1368 bool ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
1369 unsigned &RegNum,
unsigned &RegWidth,
1371 unsigned ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1374 unsigned ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1377 unsigned ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1379 bool ParseRegRange(
unsigned& Num,
unsigned& Width);
1380 unsigned getRegularReg(RegisterKind RegKind,
unsigned RegNum,
unsigned SubReg,
1381 unsigned RegWidth,
SMLoc Loc);
1385 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1386 void initializeGprCountSymbol(RegisterKind RegKind);
1387 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1394 OperandMode_Default,
1398 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1406 if (getFeatureBits().
none()) {
1412 if (!FB[AMDGPU::FeatureWavefrontSize64] &&
1413 !FB[AMDGPU::FeatureWavefrontSize32]) {
1424 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1425 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1426 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1428 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1429 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1430 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1433 initializeGprCountSymbol(IS_VGPR);
1434 initializeGprCountSymbol(IS_SGPR);
1439 createConstantSymbol(Symbol, Code);
1441 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1442 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1443 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1513 bool hasInv2PiInlineImm()
const {
1514 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1517 bool hasFlatOffsets()
const {
1518 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1522 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1525 bool hasSGPR102_SGPR103()
const {
1529 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1531 bool hasIntClamp()
const {
1532 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1535 bool hasPartialNSAEncoding()
const {
1536 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1568 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1569 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1570 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1572 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1573 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1574 bool isForcedDPP()
const {
return ForcedDPP; }
1575 bool isForcedSDWA()
const {
return ForcedSDWA; }
1577 StringRef getMatchedVariantName()
const;
1579 std::unique_ptr<AMDGPUOperand>
parseRegister(
bool RestoreOnFailure =
false);
1581 bool RestoreOnFailure);
1584 SMLoc &EndLoc)
override;
1587 unsigned Kind)
override;
1591 bool MatchingInlineAsm)
override;
1594 OperandMode Mode = OperandMode_Default);
1602 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1606 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1607 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1611 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1612 bool (*ConvertResult)(int64_t &) =
nullptr);
1616 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1625 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1626 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1627 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1628 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1629 bool parseSP3NegModifier();
1631 bool HasLit =
false);
1634 bool HasLit =
false);
1636 bool AllowImm =
true);
1638 bool AllowImm =
true);
1643 AMDGPUOperand::ImmTy ImmTy);
1654 ParseStatus parseSymbolicOrNumericFormat(int64_t &Format);
1659 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1660 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt,
StringRef FormatStr,
SMLoc Loc);
1664 bool parseCnt(int64_t &IntVal);
1667 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1671 bool parseDelay(int64_t &Delay);
1677 struct OperandInfoTy {
1680 bool IsSymbolic =
false;
1681 bool IsDefined =
false;
1683 OperandInfoTy(int64_t Val) : Val(Val) {}
1686 struct StructuredOpField : OperandInfoTy {
1690 bool IsDefined =
false;
1695 virtual ~StructuredOpField() =
default;
1697 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1698 Parser.Error(Loc,
"invalid " +
Desc +
": " + Err);
1702 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1704 return Error(Parser,
"not supported on this GPU");
1706 return Error(Parser,
"only " +
Twine(Width) +
"-bit values are legal");
1714 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1715 bool validateSendMsg(
const OperandInfoTy &Msg,
1716 const OperandInfoTy &
Op,
1717 const OperandInfoTy &Stream);
1720 OperandInfoTy &Width);
1726 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1731 bool SearchMandatoryLiterals =
false)
const;
1740 bool validateSOPLiteral(
const MCInst &Inst)
const;
1742 bool validateVOPDRegBankConstraints(
const MCInst &Inst,
1744 bool validateIntClampSupported(
const MCInst &Inst);
1745 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1746 bool validateMIMGGatherDMask(
const MCInst &Inst);
1748 bool validateMIMGDataSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1749 bool validateMIMGAddrSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1750 bool validateMIMGD16(
const MCInst &Inst);
1751 bool validateMIMGMSAA(
const MCInst &Inst);
1752 bool validateOpSel(
const MCInst &Inst);
1755 bool validateVccOperand(
unsigned Reg)
const;
1760 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1761 bool validateVGPRAlign(
const MCInst &Inst)
const;
1765 bool validateDivScale(
const MCInst &Inst);
1768 const SMLoc &IDLoc);
1770 const unsigned CPol);
1773 std::optional<StringRef> validateLdsDirect(
const MCInst &Inst);
1774 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1775 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1776 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1777 unsigned findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1803 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1805 SMLoc getLoc()
const;
1809 void onBeginOfFile()
override;
1810 bool parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc)
override;
1821 bool parseSwizzleOperand(int64_t &
Op,
1822 const unsigned MinVal,
1823 const unsigned MaxVal,
1826 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1827 const unsigned MinVal,
1828 const unsigned MaxVal,
1831 bool parseSwizzleOffset(int64_t &Imm);
1832 bool parseSwizzleMacro(int64_t &Imm);
1833 bool parseSwizzleQuadPerm(int64_t &Imm);
1834 bool parseSwizzleBitmaskPerm(int64_t &Imm);
1835 bool parseSwizzleBroadcast(int64_t &Imm);
1836 bool parseSwizzleSwap(int64_t &Imm);
1837 bool parseSwizzleReverse(int64_t &Imm);
1840 int64_t parseGPRIdxMacro();
1848 OptionalImmIndexMap &OptionalIdx);
1856 OptionalImmIndexMap &OptionalIdx);
1858 OptionalImmIndexMap &OptionalIdx);
1863 bool parseDimId(
unsigned &Encoding);
1865 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1869 int64_t parseDPPCtrlSel(
StringRef Ctrl);
1870 int64_t parseDPPCtrlPerm();
1876 bool IsDPP8 =
false);
1882 AMDGPUOperand::ImmTy
Type);
1891 bool SkipDstVcc =
false,
1892 bool SkipSrcVcc =
false);
1905 return &APFloat::IEEEsingle();
1907 return &APFloat::IEEEdouble();
1909 return &APFloat::IEEEhalf();
1942 return &APFloat::IEEEsingle();
1948 return &APFloat::IEEEdouble();
1957 return &APFloat::IEEEhalf();
1965 return &APFloat::BFloat();
1980 APFloat::rmNearestTiesToEven,
1983 if (
Status != APFloat::opOK &&
1985 ((
Status & APFloat::opOverflow) != 0 ||
1986 (
Status & APFloat::opUnderflow) != 0)) {
2009bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2019 if (!isImmTy(ImmTyNone)) {
2030 if (type == MVT::f64 || type == MVT::i64) {
2032 AsmParser->hasInv2PiInlineImm());
2054 APFloat::rmNearestTiesToEven, &Lost);
2061 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2063 AsmParser->hasInv2PiInlineImm());
2068 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2069 AsmParser->hasInv2PiInlineImm());
2073 if (type == MVT::f64 || type == MVT::i64) {
2075 AsmParser->hasInv2PiInlineImm());
2084 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2085 type, AsmParser->hasInv2PiInlineImm());
2089 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2090 AsmParser->hasInv2PiInlineImm());
2093bool AMDGPUOperand::isLiteralImm(
MVT type)
const {
2095 if (!isImmTy(ImmTyNone)) {
2102 if (type == MVT::f64 && hasFPModifiers()) {
2119 if (type == MVT::f64) {
2124 if (type == MVT::i64) {
2137 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2138 : (type == MVT::v2i16) ? MVT::f32
2139 : (type == MVT::v2f32) ? MVT::f32
2146bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2147 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2150bool AMDGPUOperand::isVRegWithInputMods()
const {
2151 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2153 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2154 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2157template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2158 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2159 : AMDGPU::VGPR_16_Lo128RegClassID);
2162bool AMDGPUOperand::isSDWAOperand(
MVT type)
const {
2163 if (AsmParser->isVI())
2165 else if (AsmParser->isGFX9Plus())
2166 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2171bool AMDGPUOperand::isSDWAFP16Operand()
const {
2172 return isSDWAOperand(MVT::f16);
2175bool AMDGPUOperand::isSDWAFP32Operand()
const {
2176 return isSDWAOperand(MVT::f32);
2179bool AMDGPUOperand::isSDWAInt16Operand()
const {
2180 return isSDWAOperand(MVT::i16);
2183bool AMDGPUOperand::isSDWAInt32Operand()
const {
2184 return isSDWAOperand(MVT::i32);
2187bool AMDGPUOperand::isBoolReg()
const {
2188 auto FB = AsmParser->getFeatureBits();
2189 return isReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrc_b64()) ||
2190 (FB[AMDGPU::FeatureWavefrontSize32] && isSCSrc_b32()));
2195 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2210void AMDGPUOperand::addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2218 addLiteralImmOperand(Inst,
Imm.Val,
2220 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2222 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2228void AMDGPUOperand::addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2229 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2234 if (ApplyModifiers) {
2237 Val = applyInputFPModifiers(Val,
Size);
2241 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2251 AsmParser->hasInv2PiInlineImm())) {
2260 if (
Literal.getLoBits(32) != 0) {
2261 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(Inst.
getLoc(),
2262 "Can't encode literal as exact 64-bit floating-point operand. "
2263 "Low 32-bits will be set to zero");
2264 Val &= 0xffffffff00000000u;
2268 setImmKindLiteral();
2284 if (AsmParser->hasInv2PiInlineImm() &&
Literal == 0x3fc45f306725feed) {
2290 setImmKindLiteral();
2326 APFloat::rmNearestTiesToEven, &lost);
2330 uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2333 setImmKindMandatoryLiteral();
2335 setImmKindLiteral();
2366 AsmParser->hasInv2PiInlineImm())) {
2373 setImmKindLiteral();
2391 setImmKindLiteral();
2405 setImmKindLiteral();
2414 AsmParser->hasInv2PiInlineImm())) {
2421 setImmKindLiteral();
2430 AsmParser->hasInv2PiInlineImm())) {
2437 setImmKindLiteral();
2451 AsmParser->hasInv2PiInlineImm()));
2461 AsmParser->hasInv2PiInlineImm()));
2469 setImmKindMandatoryLiteral();
2473 setImmKindMandatoryLiteral();
2480void AMDGPUOperand::addRegOperands(
MCInst &Inst,
unsigned N)
const {
2484bool AMDGPUOperand::isInlineValue()
const {
2492void AMDGPUAsmParser::createConstantSymbol(
StringRef Id, int64_t Val) {
2503 if (Is == IS_VGPR) {
2507 return AMDGPU::VGPR_32RegClassID;
2509 return AMDGPU::VReg_64RegClassID;
2511 return AMDGPU::VReg_96RegClassID;
2513 return AMDGPU::VReg_128RegClassID;
2515 return AMDGPU::VReg_160RegClassID;
2517 return AMDGPU::VReg_192RegClassID;
2519 return AMDGPU::VReg_224RegClassID;
2521 return AMDGPU::VReg_256RegClassID;
2523 return AMDGPU::VReg_288RegClassID;
2525 return AMDGPU::VReg_320RegClassID;
2527 return AMDGPU::VReg_352RegClassID;
2529 return AMDGPU::VReg_384RegClassID;
2531 return AMDGPU::VReg_512RegClassID;
2533 return AMDGPU::VReg_1024RegClassID;
2535 }
else if (Is == IS_TTMP) {
2539 return AMDGPU::TTMP_32RegClassID;
2541 return AMDGPU::TTMP_64RegClassID;
2543 return AMDGPU::TTMP_128RegClassID;
2545 return AMDGPU::TTMP_256RegClassID;
2547 return AMDGPU::TTMP_512RegClassID;
2549 }
else if (Is == IS_SGPR) {
2553 return AMDGPU::SGPR_32RegClassID;
2555 return AMDGPU::SGPR_64RegClassID;
2557 return AMDGPU::SGPR_96RegClassID;
2559 return AMDGPU::SGPR_128RegClassID;
2561 return AMDGPU::SGPR_160RegClassID;
2563 return AMDGPU::SGPR_192RegClassID;
2565 return AMDGPU::SGPR_224RegClassID;
2567 return AMDGPU::SGPR_256RegClassID;
2569 return AMDGPU::SGPR_288RegClassID;
2571 return AMDGPU::SGPR_320RegClassID;
2573 return AMDGPU::SGPR_352RegClassID;
2575 return AMDGPU::SGPR_384RegClassID;
2577 return AMDGPU::SGPR_512RegClassID;
2579 }
else if (Is == IS_AGPR) {
2583 return AMDGPU::AGPR_32RegClassID;
2585 return AMDGPU::AReg_64RegClassID;
2587 return AMDGPU::AReg_96RegClassID;
2589 return AMDGPU::AReg_128RegClassID;
2591 return AMDGPU::AReg_160RegClassID;
2593 return AMDGPU::AReg_192RegClassID;
2595 return AMDGPU::AReg_224RegClassID;
2597 return AMDGPU::AReg_256RegClassID;
2599 return AMDGPU::AReg_288RegClassID;
2601 return AMDGPU::AReg_320RegClassID;
2603 return AMDGPU::AReg_352RegClassID;
2605 return AMDGPU::AReg_384RegClassID;
2607 return AMDGPU::AReg_512RegClassID;
2609 return AMDGPU::AReg_1024RegClassID;
2617 .
Case(
"exec", AMDGPU::EXEC)
2618 .
Case(
"vcc", AMDGPU::VCC)
2619 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2620 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2621 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2622 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2623 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2624 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2625 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2626 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2627 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2628 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2629 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2630 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2631 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2632 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2633 .
Case(
"m0", AMDGPU::M0)
2634 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2635 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2636 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2637 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2638 .
Case(
"scc", AMDGPU::SRC_SCC)
2639 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2640 .
Case(
"tba", AMDGPU::TBA)
2641 .
Case(
"tma", AMDGPU::TMA)
2642 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2643 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2644 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2645 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2646 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2647 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2648 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2649 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2650 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2651 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2652 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2653 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2654 .
Case(
"pc", AMDGPU::PC_REG)
2655 .
Case(
"null", AMDGPU::SGPR_NULL)
2659bool AMDGPUAsmParser::ParseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
2660 SMLoc &EndLoc,
bool RestoreOnFailure) {
2661 auto R = parseRegister();
2662 if (!R)
return true;
2664 RegNo =
R->getReg();
2665 StartLoc =
R->getStartLoc();
2666 EndLoc =
R->getEndLoc();
2672 return ParseRegister(Reg, StartLoc, EndLoc,
false);
2677 bool Result = ParseRegister(Reg, StartLoc, EndLoc,
true);
2678 bool PendingErrors = getParser().hasPendingError();
2679 getParser().clearPendingErrors();
2687bool AMDGPUAsmParser::AddNextRegisterToList(
unsigned &Reg,
unsigned &RegWidth,
2688 RegisterKind RegKind,
unsigned Reg1,
2692 if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2697 if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2698 Reg = AMDGPU::FLAT_SCR;
2702 if (Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2703 Reg = AMDGPU::XNACK_MASK;
2707 if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2712 if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2717 if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2722 Error(Loc,
"register does not fit in the list");
2728 if (Reg1 != Reg + RegWidth / 32) {
2729 Error(Loc,
"registers in a list must have consecutive indices");
2747 {{
"ttmp"}, IS_TTMP},
2753 return Kind == IS_VGPR ||
2761 if (Str.starts_with(Reg.Name))
2767 return !Str.getAsInteger(10, Num);
2771AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2788 if (!RegSuffix.
empty()) {
2806AMDGPUAsmParser::isRegister()
2808 return isRegister(getToken(), peekToken());
2811unsigned AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2812 unsigned SubReg,
unsigned RegWidth,
2816 unsigned AlignSize = 1;
2817 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2823 if (RegNum % AlignSize != 0) {
2824 Error(Loc,
"invalid register alignment");
2825 return AMDGPU::NoRegister;
2828 unsigned RegIdx = RegNum / AlignSize;
2831 Error(Loc,
"invalid or unsupported register size");
2832 return AMDGPU::NoRegister;
2838 Error(Loc,
"register index is out of range");
2839 return AMDGPU::NoRegister;
2849 assert(Reg &&
"Invalid subregister!");
2855bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth) {
2856 int64_t RegLo, RegHi;
2860 SMLoc FirstIdxLoc = getLoc();
2867 SecondIdxLoc = getLoc();
2877 if (!isUInt<32>(RegLo)) {
2878 Error(FirstIdxLoc,
"invalid register index");
2882 if (!isUInt<32>(RegHi)) {
2883 Error(SecondIdxLoc,
"invalid register index");
2887 if (RegLo > RegHi) {
2888 Error(FirstIdxLoc,
"first register index should not exceed second index");
2892 Num =
static_cast<unsigned>(RegLo);
2893 RegWidth = 32 * ((RegHi - RegLo) + 1);
2897unsigned AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2898 unsigned &RegNum,
unsigned &RegWidth,
2905 RegKind = IS_SPECIAL;
2912unsigned AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2913 unsigned &RegNum,
unsigned &RegWidth,
2917 auto Loc = getLoc();
2921 Error(Loc,
"invalid register name");
2922 return AMDGPU::NoRegister;
2930 unsigned SubReg = NoSubRegister;
2931 if (!RegSuffix.
empty()) {
2943 Error(Loc,
"invalid register index");
2944 return AMDGPU::NoRegister;
2949 if (!ParseRegRange(RegNum, RegWidth))
2950 return AMDGPU::NoRegister;
2953 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
2956unsigned AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
2959 unsigned Reg = AMDGPU::NoRegister;
2960 auto ListLoc = getLoc();
2963 "expected a register or a list of registers")) {
2964 return AMDGPU::NoRegister;
2969 auto Loc = getLoc();
2970 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth))
2971 return AMDGPU::NoRegister;
2972 if (RegWidth != 32) {
2973 Error(Loc,
"expected a single 32-bit register");
2974 return AMDGPU::NoRegister;
2978 RegisterKind NextRegKind;
2979 unsigned NextReg, NextRegNum, NextRegWidth;
2982 if (!ParseAMDGPURegister(NextRegKind, NextReg,
2983 NextRegNum, NextRegWidth,
2985 return AMDGPU::NoRegister;
2987 if (NextRegWidth != 32) {
2988 Error(Loc,
"expected a single 32-bit register");
2989 return AMDGPU::NoRegister;
2991 if (NextRegKind != RegKind) {
2992 Error(Loc,
"registers in a list must be of the same kind");
2993 return AMDGPU::NoRegister;
2995 if (!AddNextRegisterToList(Reg, RegWidth, RegKind, NextReg, Loc))
2996 return AMDGPU::NoRegister;
3000 "expected a comma or a closing square bracket")) {
3001 return AMDGPU::NoRegister;
3005 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3010bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
3011 unsigned &RegNum,
unsigned &RegWidth,
3013 auto Loc = getLoc();
3014 Reg = AMDGPU::NoRegister;
3017 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3018 if (Reg == AMDGPU::NoRegister)
3019 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3021 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3025 if (Reg == AMDGPU::NoRegister) {
3026 assert(Parser.hasPendingError());
3030 if (!subtargetHasRegister(*
TRI, Reg)) {
3031 if (Reg == AMDGPU::SGPR_NULL) {
3032 Error(Loc,
"'null' operand is not supported on this GPU");
3034 Error(Loc,
"register not available on this GPU");
3042bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
3043 unsigned &RegNum,
unsigned &RegWidth,
3044 bool RestoreOnFailure ) {
3045 Reg = AMDGPU::NoRegister;
3048 if (ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, Tokens)) {
3049 if (RestoreOnFailure) {
3050 while (!Tokens.
empty()) {
3059std::optional<StringRef>
3060AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3063 return StringRef(
".amdgcn.next_free_vgpr");
3065 return StringRef(
".amdgcn.next_free_sgpr");
3067 return std::nullopt;
3071void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3072 auto SymbolName = getGprCountSymbolName(RegKind);
3073 assert(SymbolName &&
"initializing invalid register kind");
3074 MCSymbol *
Sym = getContext().getOrCreateSymbol(*SymbolName);
3078bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3079 unsigned DwordRegIndex,
3080 unsigned RegWidth) {
3085 auto SymbolName = getGprCountSymbolName(RegKind);
3088 MCSymbol *
Sym = getContext().getOrCreateSymbol(*SymbolName);
3090 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3093 if (!
Sym->isVariable())
3094 return !
Error(getLoc(),
3095 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3096 if (!
Sym->getVariableValue(
false)->evaluateAsAbsolute(OldCount))
3099 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3101 if (OldCount <= NewMax)
3107std::unique_ptr<AMDGPUOperand>
3108AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3109 const auto &Tok = getToken();
3110 SMLoc StartLoc = Tok.getLoc();
3111 SMLoc EndLoc = Tok.getEndLoc();
3112 RegisterKind RegKind;
3113 unsigned Reg, RegNum, RegWidth;
3115 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth)) {
3119 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3122 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3123 return AMDGPUOperand::CreateReg(
this, Reg, StartLoc, EndLoc);
3127 bool HasSP3AbsModifier,
bool HasLit) {
3135 HasLit = trySkipId(
"lit");
3147 const auto& Tok = getToken();
3148 const auto& NextTok = peekToken();
3151 bool Negate =
false;
3159 AMDGPUOperand::Modifiers Mods;
3170 APFloat RealVal(APFloat::IEEEdouble());
3171 auto roundMode = APFloat::rmNearestTiesToEven;
3172 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3175 RealVal.changeSign();
3178 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3179 AMDGPUOperand::ImmTyNone,
true));
3180 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3181 Op.setModifiers(Mods);
3190 if (HasSP3AbsModifier) {
3199 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3202 if (Parser.parseExpression(Expr))
3206 if (Expr->evaluateAsAbsolute(IntVal)) {
3207 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3208 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3209 Op.setModifiers(Mods);
3213 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3226 if (
auto R = parseRegister()) {
3235 bool HasSP3AbsMod,
bool HasLit) {
3241 return parseImm(
Operands, HasSP3AbsMod, HasLit);
3245AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3248 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3254AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3259AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3260 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3264AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3265 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3282AMDGPUAsmParser::isModifier() {
3286 peekTokens(NextToken);
3288 return isOperandModifier(Tok, NextToken[0]) ||
3289 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3290 isOpcodeModifierWithVal(Tok, NextToken[0]);
3316AMDGPUAsmParser::parseSP3NegModifier() {
3319 peekTokens(NextToken);
3322 (isRegister(NextToken[0], NextToken[1]) ||
3324 isId(NextToken[0],
"abs"))) {
3342 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3344 SP3Neg = parseSP3NegModifier();
3347 Neg = trySkipId(
"neg");
3349 return Error(Loc,
"expected register or immediate");
3353 Abs = trySkipId(
"abs");
3357 Lit = trySkipId(
"lit");
3364 return Error(Loc,
"expected register or immediate");
3368 Res = parseRegOrImm(
Operands, SP3Abs, Lit);
3375 if (Lit && !
Operands.back()->isImm())
3376 Error(Loc,
"expected immediate with lit modifier");
3378 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3387 AMDGPUOperand::Modifiers Mods;
3388 Mods.Abs = Abs || SP3Abs;
3389 Mods.Neg = Neg || SP3Neg;
3392 if (Mods.hasFPModifiers() || Lit) {
3393 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3395 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3396 Op.setModifiers(Mods);
3404 bool Sext = trySkipId(
"sext");
3405 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3420 AMDGPUOperand::Modifiers Mods;
3423 if (Mods.hasIntModifiers()) {
3424 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3426 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3427 Op.setModifiers(Mods);
3434 return parseRegOrImmWithFPInputMods(
Operands,
false);
3438 return parseRegOrImmWithIntInputMods(
Operands,
false);
3442 auto Loc = getLoc();
3443 if (trySkipId(
"off")) {
3444 Operands.push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3445 AMDGPUOperand::ImmTyOff,
false));
3452 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3454 Operands.push_back(std::move(Reg));
3461unsigned AMDGPUAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
3468 return Match_InvalidOperand;
3470 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3471 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3476 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3477 return Match_InvalidOperand;
3481 return Match_Success;
3485 static const unsigned Variants[] = {
3496 if (isForcedDPP() && isForcedVOP3()) {
3500 if (getForcedEncodingSize() == 32) {
3505 if (isForcedVOP3()) {
3510 if (isForcedSDWA()) {
3516 if (isForcedDPP()) {
3524StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3525 if (isForcedDPP() && isForcedVOP3())
3528 if (getForcedEncodingSize() == 32)
3543unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3547 case AMDGPU::FLAT_SCR:
3549 case AMDGPU::VCC_LO:
3550 case AMDGPU::VCC_HI:
3557 return AMDGPU::NoRegister;
3564bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3565 unsigned OpIdx)
const {
3575 int64_t Val = MO.
getImm();
3624unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3630 case AMDGPU::V_LSHLREV_B64_e64:
3631 case AMDGPU::V_LSHLREV_B64_gfx10:
3632 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3633 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3634 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3635 case AMDGPU::V_LSHRREV_B64_e64:
3636 case AMDGPU::V_LSHRREV_B64_gfx10:
3637 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3638 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3639 case AMDGPU::V_ASHRREV_I64_e64:
3640 case AMDGPU::V_ASHRREV_I64_gfx10:
3641 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3642 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3643 case AMDGPU::V_LSHL_B64_e64:
3644 case AMDGPU::V_LSHR_B64_e64:
3645 case AMDGPU::V_ASHR_I64_e64:
3658 bool AddMandatoryLiterals =
false) {
3664 int16_t ImmDeferredIdx =
3681bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3684 return !isInlineConstant(Inst, OpIdx);
3685 }
else if (MO.
isReg()) {
3692 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3704 const unsigned Opcode = Inst.
getOpcode();
3705 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3708 if (!LaneSelOp.
isReg())
3711 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3714bool AMDGPUAsmParser::validateConstantBusLimitations(
3716 const unsigned Opcode = Inst.
getOpcode();
3718 unsigned LastSGPR = AMDGPU::NoRegister;
3719 unsigned ConstantBusUseCount = 0;
3720 unsigned NumLiterals = 0;
3721 unsigned LiteralSize;
3723 if (!(
Desc.TSFlags &
3739 unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3740 if (SGPRUsed != AMDGPU::NoRegister) {
3741 SGPRsUsed.
insert(SGPRUsed);
3742 ++ConstantBusUseCount;
3747 for (
int OpIdx : OpIndices) {
3752 if (usesConstantBus(Inst, OpIdx)) {
3761 if (SGPRsUsed.
insert(LastSGPR).second) {
3762 ++ConstantBusUseCount;
3782 if (NumLiterals == 0) {
3785 }
else if (LiteralSize !=
Size) {
3791 ConstantBusUseCount += NumLiterals;
3793 if (ConstantBusUseCount <= getConstantBusLimit(Opcode))
3799 Error(Loc,
"invalid operand (violates constant bus restrictions)");
3803bool AMDGPUAsmParser::validateVOPDRegBankConstraints(
3806 const unsigned Opcode = Inst.
getOpcode();
3812 auto getVRegIdx = [&](
unsigned,
unsigned OperandIdx) {
3820 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12;
3823 auto InvalidCompOprIdx =
3824 InstInfo.getInvalidCompOperandIndex(getVRegIdx, SkipSrc);
3825 if (!InvalidCompOprIdx)
3828 auto CompOprIdx = *InvalidCompOprIdx;
3830 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3831 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3834 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
3835 if (CompOprIdx == VOPD::Component::DST) {
3836 Error(Loc,
"one dst register must be even and the other odd");
3838 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3840 " operands must use different VGPR banks");
3846bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
3863bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
3864 const SMLoc &IDLoc) {
3882 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
3887 bool IsPackedD16 =
false;
3892 IsPackedD16 = D16Idx >= 0;
3894 DataSize = (DataSize + 1) / 2;
3897 if ((VDataSize / 4) == DataSize + TFESize)
3902 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
3904 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
3906 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
3910bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst,
3911 const SMLoc &IDLoc) {
3924 : AMDGPU::OpName::rsrc;
3931 assert(SrsrcIdx > VAddr0Idx);
3934 if (BaseOpcode->
BVH) {
3935 if (IsA16 == BaseOpcode->
A16)
3937 Error(IDLoc,
"image address size does not match a16");
3943 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
3944 unsigned ActualAddrSize =
3945 IsNSA ? SrsrcIdx - VAddr0Idx
3948 unsigned ExpectedAddrSize =
3952 if (hasPartialNSAEncoding() &&
3955 int VAddrLastIdx = SrsrcIdx - 1;
3956 unsigned VAddrLastSize =
3959 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
3962 if (ExpectedAddrSize > 12)
3963 ExpectedAddrSize = 16;
3968 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
3972 if (ActualAddrSize == ExpectedAddrSize)
3975 Error(IDLoc,
"image address size does not match dim and a16");
3979bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
3986 if (!
Desc.mayLoad() || !
Desc.mayStore())
3996 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
3999bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4015 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4018bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4029 if (!BaseOpcode->
MSAA)
4038 return DimInfo->
MSAA;
4044 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4045 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4046 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4056bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4080 Error(ErrLoc,
"source operand must be a VGPR");
4084bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4089 if (Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4103 "source operand must be either a VGPR or an inline constant");
4110bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4116 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4123 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4125 "inline constants are not allowed for this operand");
4132bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4150 if (Src2Reg == DstReg)
4154 if (
TRI->getRegClass(
Desc.operands()[0].RegClass).getSizeInBits() <= 128)
4157 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4159 "source 2 operand must not partially overlap with dst");
4166bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4170 case V_DIV_SCALE_F32_gfx6_gfx7:
4171 case V_DIV_SCALE_F32_vi:
4172 case V_DIV_SCALE_F32_gfx10:
4173 case V_DIV_SCALE_F64_gfx6_gfx7:
4174 case V_DIV_SCALE_F64_vi:
4175 case V_DIV_SCALE_F64_gfx10:
4181 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4182 AMDGPU::OpName::src2_modifiers,
4183 AMDGPU::OpName::src2_modifiers}) {
4194bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4214 case AMDGPU::V_SUBREV_F32_e32:
4215 case AMDGPU::V_SUBREV_F32_e64:
4216 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4217 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4218 case AMDGPU::V_SUBREV_F32_e32_vi:
4219 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4220 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4221 case AMDGPU::V_SUBREV_F32_e64_vi:
4223 case AMDGPU::V_SUBREV_CO_U32_e32:
4224 case AMDGPU::V_SUBREV_CO_U32_e64:
4225 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4226 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4228 case AMDGPU::V_SUBBREV_U32_e32:
4229 case AMDGPU::V_SUBBREV_U32_e64:
4230 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4231 case AMDGPU::V_SUBBREV_U32_e32_vi:
4232 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4233 case AMDGPU::V_SUBBREV_U32_e64_vi:
4235 case AMDGPU::V_SUBREV_U32_e32:
4236 case AMDGPU::V_SUBREV_U32_e64:
4237 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4238 case AMDGPU::V_SUBREV_U32_e32_vi:
4239 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4240 case AMDGPU::V_SUBREV_U32_e64_vi:
4242 case AMDGPU::V_SUBREV_F16_e32:
4243 case AMDGPU::V_SUBREV_F16_e64:
4244 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4245 case AMDGPU::V_SUBREV_F16_e32_vi:
4246 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4247 case AMDGPU::V_SUBREV_F16_e64_vi:
4249 case AMDGPU::V_SUBREV_U16_e32:
4250 case AMDGPU::V_SUBREV_U16_e64:
4251 case AMDGPU::V_SUBREV_U16_e32_vi:
4252 case AMDGPU::V_SUBREV_U16_e64_vi:
4254 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4255 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4256 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4258 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4259 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4261 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4262 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4264 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4265 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4267 case AMDGPU::V_LSHRREV_B32_e32:
4268 case AMDGPU::V_LSHRREV_B32_e64:
4269 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4270 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4271 case AMDGPU::V_LSHRREV_B32_e32_vi:
4272 case AMDGPU::V_LSHRREV_B32_e64_vi:
4273 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4274 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4276 case AMDGPU::V_ASHRREV_I32_e32:
4277 case AMDGPU::V_ASHRREV_I32_e64:
4278 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4279 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4280 case AMDGPU::V_ASHRREV_I32_e32_vi:
4281 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4282 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4283 case AMDGPU::V_ASHRREV_I32_e64_vi:
4285 case AMDGPU::V_LSHLREV_B32_e32:
4286 case AMDGPU::V_LSHLREV_B32_e64:
4287 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4288 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4289 case AMDGPU::V_LSHLREV_B32_e32_vi:
4290 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4291 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4292 case AMDGPU::V_LSHLREV_B32_e64_vi:
4294 case AMDGPU::V_LSHLREV_B16_e32:
4295 case AMDGPU::V_LSHLREV_B16_e64:
4296 case AMDGPU::V_LSHLREV_B16_e32_vi:
4297 case AMDGPU::V_LSHLREV_B16_e64_vi:
4298 case AMDGPU::V_LSHLREV_B16_gfx10:
4300 case AMDGPU::V_LSHRREV_B16_e32:
4301 case AMDGPU::V_LSHRREV_B16_e64:
4302 case AMDGPU::V_LSHRREV_B16_e32_vi:
4303 case AMDGPU::V_LSHRREV_B16_e64_vi:
4304 case AMDGPU::V_LSHRREV_B16_gfx10:
4306 case AMDGPU::V_ASHRREV_I16_e32:
4307 case AMDGPU::V_ASHRREV_I16_e64:
4308 case AMDGPU::V_ASHRREV_I16_e32_vi:
4309 case AMDGPU::V_ASHRREV_I16_e64_vi:
4310 case AMDGPU::V_ASHRREV_I16_gfx10:
4312 case AMDGPU::V_LSHLREV_B64_e64:
4313 case AMDGPU::V_LSHLREV_B64_gfx10:
4314 case AMDGPU::V_LSHLREV_B64_vi:
4316 case AMDGPU::V_LSHRREV_B64_e64:
4317 case AMDGPU::V_LSHRREV_B64_gfx10:
4318 case AMDGPU::V_LSHRREV_B64_vi:
4320 case AMDGPU::V_ASHRREV_I64_e64:
4321 case AMDGPU::V_ASHRREV_I64_gfx10:
4322 case AMDGPU::V_ASHRREV_I64_vi:
4324 case AMDGPU::V_PK_LSHLREV_B16:
4325 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4326 case AMDGPU::V_PK_LSHLREV_B16_vi:
4328 case AMDGPU::V_PK_LSHRREV_B16:
4329 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4330 case AMDGPU::V_PK_LSHRREV_B16_vi:
4331 case AMDGPU::V_PK_ASHRREV_I16:
4332 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4333 case AMDGPU::V_PK_ASHRREV_I16_vi:
4340std::optional<StringRef>
4341AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst) {
4343 using namespace SIInstrFlags;
4344 const unsigned Opcode = Inst.
getOpcode();
4350 if ((
Desc.TSFlags & Enc) == 0)
4351 return std::nullopt;
4353 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4358 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4361 return StringRef(
"lds_direct is not supported on this GPU");
4364 return StringRef(
"lds_direct cannot be used with this instruction");
4366 if (SrcName != OpName::src0)
4367 return StringRef(
"lds_direct may be used as src0 only");
4371 return std::nullopt;
4375 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4376 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4377 if (
Op.isFlatOffset())
4378 return Op.getStartLoc();
4383bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4392 return validateFlatOffset(Inst,
Operands);
4395 return validateSMEMOffset(Inst,
Operands);
4400 const unsigned OffsetSize = 24;
4401 if (!
isIntN(OffsetSize,
Op.getImm())) {
4403 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit signed offset");
4407 const unsigned OffsetSize = 16;
4408 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4410 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit unsigned offset");
4417bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4428 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4430 "flat offset modifier is not supported on this GPU");
4437 bool AllowNegative =
4440 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4442 Twine(
"expected a ") +
4443 (AllowNegative ?
Twine(OffsetSize) +
"-bit signed offset"
4444 :
Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4453 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4454 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4455 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4456 return Op.getStartLoc();
4461bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4487 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4488 :
"expected a 21-bit signed offset");
4493bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst)
const {
4502 const int OpIndices[] = { Src0Idx, Src1Idx };
4504 unsigned NumExprs = 0;
4505 unsigned NumLiterals = 0;
4508 for (
int OpIdx : OpIndices) {
4509 if (OpIdx == -1)
break;
4514 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4516 if (NumLiterals == 0 || LiteralValue !=
Value) {
4520 }
else if (MO.
isExpr()) {
4526 return NumLiterals + NumExprs <= 1;
4529bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4543 if (OpSelIdx != -1) {
4548 if (OpSelHiIdx != -1) {
4566bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst,
int OpName) {
4591 int SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4592 AMDGPU::OpName::src1_modifiers,
4593 AMDGPU::OpName::src2_modifiers};
4595 for (
unsigned i = 0; i < 3; ++i) {
4605bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4609 if (DppCtrlIdx >= 0) {
4616 Error(S,
"DP ALU dpp only supports row_newbcast");
4622 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4632 Error(S,
"invalid operand for instruction");
4637 "src1 immediate operand invalid for instruction");
4647bool AMDGPUAsmParser::validateVccOperand(
unsigned Reg)
const {
4648 auto FB = getFeatureBits();
4649 return (FB[AMDGPU::FeatureWavefrontSize64] && Reg == AMDGPU::VCC) ||
4650 (FB[AMDGPU::FeatureWavefrontSize32] &&
Reg == AMDGPU::VCC_LO);
4654bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
4660 !HasMandatoryLiteral && !
isVOPD(Opcode))
4665 unsigned NumExprs = 0;
4666 unsigned NumLiterals = 0;
4669 for (
int OpIdx : OpIndices) {
4679 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4685 if (!IsValid32Op && !isInt<32>(
Value) && !isUInt<32>(
Value)) {
4686 Error(getLitLoc(
Operands),
"invalid operand for instruction");
4690 if (IsFP64 && IsValid32Op)
4693 if (NumLiterals == 0 || LiteralValue !=
Value) {
4697 }
else if (MO.
isExpr()) {
4701 NumLiterals += NumExprs;
4706 if (!HasMandatoryLiteral && !getFeatureBits()[FeatureVOP3Literal]) {
4707 Error(getLitLoc(
Operands),
"literal operands are not supported");
4711 if (NumLiterals > 1) {
4712 Error(getLitLoc(
Operands,
true),
"only one unique literal operand is allowed");
4730 unsigned Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
4731 auto Reg = Sub ? Sub :
Op.getReg();
4733 return AGPR32.
contains(Reg) ? 1 : 0;
4736bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
4744 : AMDGPU::OpName::vdata;
4752 if (Data2Areg >= 0 && Data2Areg != DataAreg)
4756 auto FB = getFeatureBits();
4757 if (FB[AMDGPU::FeatureGFX90AInsts]) {
4758 if (DataAreg < 0 || DstAreg < 0)
4760 return DstAreg == DataAreg;
4763 return DstAreg < 1 && DataAreg < 1;
4766bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
4767 auto FB = getFeatureBits();
4768 if (!FB[AMDGPU::FeatureGFX90AInsts])
4779 unsigned Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
4783 if (VGPR32.
contains(Sub) && ((Sub - AMDGPU::VGPR0) & 1))
4785 if (AGPR32.
contains(Sub) && ((Sub - AMDGPU::AGPR0) & 1))
4793 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4794 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4796 return Op.getStartLoc();
4801bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
4811 auto FB = getFeatureBits();
4812 bool UsesNeg =
false;
4813 if (FB[AMDGPU::FeatureGFX940Insts]) {
4815 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
4816 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
4817 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
4818 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
4823 if (IsNeg == UsesNeg)
4827 UsesNeg ?
"invalid modifier: blgp is not supported"
4828 :
"invalid modifier: neg is not supported");
4833bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
4839 if (Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
4840 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
4841 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
4842 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
4848 if (Reg == AMDGPU::SGPR_NULL)
4852 Error(RegLoc,
"src0 must be null");
4856bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
4862 return validateGWS(Inst,
Operands);
4873 Error(S,
"gds modifier is not supported on this GPU");
4881bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
4883 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
4887 if (Opc != AMDGPU::DS_GWS_INIT_vi && Opc != AMDGPU::DS_GWS_BARRIER_vi &&
4888 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
4897 auto RegIdx =
Reg - (VGPR32.
contains(Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
4900 Error(RegLoc,
"vgpr must be even aligned");
4907bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
4909 const SMLoc &IDLoc) {
4911 AMDGPU::OpName::cpol);
4918 return validateTHAndScopeBits(Inst,
Operands, CPol);
4924 Error(S,
"cache policy is not supported for SMRD instructions");
4928 Error(IDLoc,
"invalid cache policy for SMEM instruction");
4937 if (!(TSFlags & AllowSCCModifier)) {
4942 "scc modifier is not supported for this instruction on this GPU");
4953 :
"instruction must use glc");
4961 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
4963 :
"instruction must not use glc");
4971bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
4973 const unsigned CPol) {
4977 const unsigned Opcode = Inst.
getOpcode();
4989 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
4997 return PrintError(
"invalid th value for SMEM instruction");
5004 return PrintError(
"scope and th combination is not valid");
5013 return PrintError(
"invalid th value for atomic instructions");
5014 }
else if (IsStore) {
5016 return PrintError(
"invalid th value for store instructions");
5019 return PrintError(
"invalid th value for load instructions");
5029 if (!Operand->isReg())
5031 unsigned Reg = Operand->getReg();
5032 if (Reg == SRC_EXECZ || Reg == SRC_VCCZ) {
5034 "execz and vccz are not supported on this GPU");
5041bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5044 if (
Desc.mayStore() &&
5048 Error(Loc,
"TFE modifier has no meaning for store instructions");
5056bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst,
5059 if (
auto ErrMsg = validateLdsDirect(Inst)) {
5063 if (!validateSOPLiteral(Inst)) {
5065 "only one unique literal operand is allowed");
5068 if (!validateVOPLiteral(Inst,
Operands)) {
5071 if (!validateConstantBusLimitations(Inst,
Operands)) {
5074 if (!validateVOPDRegBankConstraints(Inst,
Operands)) {
5077 if (!validateIntClampSupported(Inst)) {
5079 "integer clamping is not supported on this GPU");
5082 if (!validateOpSel(Inst)) {
5084 "invalid op_sel operand");
5087 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5089 "invalid neg_lo operand");
5092 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5094 "invalid neg_hi operand");
5097 if (!validateDPP(Inst,
Operands)) {
5101 if (!validateMIMGD16(Inst)) {
5103 "d16 modifier is not supported on this GPU");
5106 if (!validateMIMGMSAA(Inst)) {
5108 "invalid dim; must be MSAA type");
5111 if (!validateMIMGDataSize(Inst, IDLoc)) {
5114 if (!validateMIMGAddrSize(Inst, IDLoc))
5116 if (!validateMIMGAtomicDMask(Inst)) {
5118 "invalid atomic image dmask");
5121 if (!validateMIMGGatherDMask(Inst)) {
5123 "invalid image_gather dmask: only one bit must be set");
5126 if (!validateMovrels(Inst,
Operands)) {
5129 if (!validateOffset(Inst,
Operands)) {
5132 if (!validateMAIAccWrite(Inst,
Operands)) {
5135 if (!validateMAISrc2(Inst,
Operands)) {
5138 if (!validateMFMA(Inst,
Operands)) {
5141 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5145 if (!validateAGPRLdSt(Inst)) {
5146 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5147 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5148 :
"invalid register class: agpr loads and stores not supported on this GPU"
5152 if (!validateVGPRAlign(Inst)) {
5154 "invalid register class: vgpr tuples must be 64 bit aligned");
5161 if (!validateBLGP(Inst,
Operands)) {
5165 if (!validateDivScale(Inst)) {
5166 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5169 if (!validateWaitCnt(Inst,
Operands)) {
5172 if (!validateExeczVcczOperands(
Operands)) {
5175 if (!validateTFE(Inst,
Operands)) {
5184 unsigned VariantID = 0);
5188 unsigned VariantID);
5190bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5195bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5198 for (
auto Variant : Variants) {
5206bool AMDGPUAsmParser::checkUnsupportedInstruction(
StringRef Mnemo,
5207 const SMLoc &IDLoc) {
5208 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5211 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5216 getParser().clearPendingErrors();
5220 StringRef VariantName = getMatchedVariantName();
5221 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5224 " variant of this instruction is not supported"));
5228 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5229 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5232 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5233 .
flip(AMDGPU::FeatureWavefrontSize32);
5235 ComputeAvailableFeatures(FeaturesWS32);
5237 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5238 return Error(IDLoc,
"instruction requires wavesize=32");
5243 return Error(IDLoc,
"instruction not supported on this GPU");
5248 return Error(IDLoc,
"invalid instruction" + Suggestion);
5254 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5255 if (
Op.isToken() && InvalidOprIdx > 1) {
5256 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5257 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5262bool AMDGPUAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
5266 bool MatchingInlineAsm) {
5268 unsigned Result = Match_Success;
5269 for (
auto Variant : getMatchedVariants()) {
5271 auto R = MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm,
5276 if (R == Match_Success || R == Match_MissingFeature ||
5277 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5278 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5279 Result != Match_MissingFeature)) {
5283 if (R == Match_Success)
5287 if (Result == Match_Success) {
5288 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5297 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5303 case Match_MissingFeature:
5307 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5309 case Match_InvalidOperand: {
5310 SMLoc ErrorLoc = IDLoc;
5313 return Error(IDLoc,
"too few operands for instruction");
5316 if (ErrorLoc ==
SMLoc())
5320 return Error(ErrorLoc,
"invalid VOPDY instruction");
5322 return Error(ErrorLoc,
"invalid operand for instruction");
5325 case Match_MnemonicFail:
5331bool AMDGPUAsmParser::ParseAsAbsoluteExpression(
uint32_t &Ret) {
5336 if (getParser().parseAbsoluteExpression(Tmp)) {
5343bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5345 return TokError(
"directive only supported for amdgcn architecture");
5347 std::string TargetIDDirective;
5348 SMLoc TargetStart = getTok().getLoc();
5349 if (getParser().parseEscapedString(TargetIDDirective))
5353 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5354 return getParser().Error(TargetRange.
Start,
5355 (
Twine(
".amdgcn_target directive's target id ") +
5356 Twine(TargetIDDirective) +
5357 Twine(
" does not match the specified target id ") +
5358 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5367bool AMDGPUAsmParser::calculateGPRBlocks(
5369 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5370 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5372 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5379 int64_t EvaluatedSGPRs;
5384 unsigned MaxAddressableNumSGPRs =
5387 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5388 !Features.
test(FeatureSGPRInitBug) &&
5389 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5390 return OutOfRangeError(SGPRRange);
5392 const MCExpr *ExtraSGPRs =
5396 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5397 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5398 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5399 return OutOfRangeError(SGPRRange);
5401 if (Features.
test(FeatureSGPRInitBug))
5408 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5409 unsigned Granule) ->
const MCExpr * {
5413 const MCExpr *AlignToGPR =
5421 VGPRBlocks = GetNumGPRBlocks(
5430bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5432 return TokError(
"directive only supported for amdgcn architecture");
5435 return TokError(
"directive only supported for amdhsa OS");
5438 if (getParser().parseIdentifier(KernelName))
5443 &getSTI(), getContext());
5453 const MCExpr *NextFreeVGPR = ZeroExpr;
5459 const MCExpr *NextFreeSGPR = ZeroExpr;
5462 unsigned ImpliedUserSGPRCount = 0;
5466 std::optional<unsigned> ExplicitUserSGPRCount;
5467 const MCExpr *ReserveVCC = OneExpr;
5468 const MCExpr *ReserveFlatScr = OneExpr;
5469 std::optional<bool> EnableWavefrontSize32;
5475 SMRange IDRange = getTok().getLocRange();
5476 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5479 if (
ID ==
".end_amdhsa_kernel")
5483 return TokError(
".amdhsa_ directives cannot be repeated");
5485 SMLoc ValStart = getLoc();
5487 if (getParser().parseExpression(ExprVal))
5489 SMLoc ValEnd = getLoc();
5494 bool EvaluatableExpr;
5495 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5497 return OutOfRangeError(ValRange);
5501#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5502 if (!isUInt<ENTRY##_WIDTH>(Val)) \
5503 return OutOfRangeError(RANGE); \
5504 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
5509#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
5511 return Error(IDRange.Start, "directive should have resolvable expression", \
5514 if (
ID ==
".amdhsa_group_segment_fixed_size") {
5517 return OutOfRangeError(ValRange);
5519 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
5522 return OutOfRangeError(ValRange);
5524 }
else if (
ID ==
".amdhsa_kernarg_size") {
5526 return OutOfRangeError(ValRange);
5528 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
5530 ExplicitUserSGPRCount = Val;
5531 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
5535 "directive is not supported with architected flat scratch",
5538 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
5541 ImpliedUserSGPRCount += 4;
5542 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
5545 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5548 return OutOfRangeError(ValRange);
5552 ImpliedUserSGPRCount += Val;
5553 PreloadLength = Val;
5555 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
5558 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5561 return OutOfRangeError(ValRange);
5565 PreloadOffset = Val;
5566 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
5569 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
5572 ImpliedUserSGPRCount += 2;
5573 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
5576 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
5579 ImpliedUserSGPRCount += 2;
5580 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
5583 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
5586 ImpliedUserSGPRCount += 2;
5587 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
5590 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
5593 ImpliedUserSGPRCount += 2;
5594 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
5597 "directive is not supported with architected flat scratch",
5601 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
5604 ImpliedUserSGPRCount += 2;
5605 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
5608 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
5611 ImpliedUserSGPRCount += 1;
5612 }
else if (
ID ==
".amdhsa_wavefront_size32") {
5614 if (IVersion.
Major < 10)
5615 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5616 EnableWavefrontSize32 = Val;
5618 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
5620 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
5622 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
5624 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
5627 "directive is not supported with architected flat scratch",
5630 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
5632 }
else if (
ID ==
".amdhsa_enable_private_segment") {
5636 "directive is not supported without architected flat scratch",
5639 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
5641 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
5643 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
5645 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
5647 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
5649 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
5651 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
5653 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
5655 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
5657 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
5659 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
5661 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
5662 VGPRRange = ValRange;
5663 NextFreeVGPR = ExprVal;
5664 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
5665 SGPRRange = ValRange;
5666 NextFreeSGPR = ExprVal;
5667 }
else if (
ID ==
".amdhsa_accum_offset") {
5669 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5670 AccumOffset = ExprVal;
5671 }
else if (
ID ==
".amdhsa_reserve_vcc") {
5672 if (EvaluatableExpr && !isUInt<1>(Val))
5673 return OutOfRangeError(ValRange);
5674 ReserveVCC = ExprVal;
5675 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
5676 if (IVersion.
Major < 7)
5677 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
5680 "directive is not supported with architected flat scratch",
5682 if (EvaluatableExpr && !isUInt<1>(Val))
5683 return OutOfRangeError(ValRange);
5684 ReserveFlatScr = ExprVal;
5685 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
5686 if (IVersion.
Major < 8)
5687 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
5688 if (!isUInt<1>(Val))
5689 return OutOfRangeError(ValRange);
5690 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
5691 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
5693 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
5695 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
5697 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
5699 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
5701 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
5703 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
5705 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
5707 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
5709 }
else if (
ID ==
".amdhsa_dx10_clamp") {
5710 if (IVersion.
Major >= 12)
5711 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
5713 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
5715 }
else if (
ID ==
".amdhsa_ieee_mode") {
5716 if (IVersion.
Major >= 12)
5717 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
5719 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
5721 }
else if (
ID ==
".amdhsa_fp16_overflow") {
5722 if (IVersion.
Major < 9)
5723 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
5725 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
5727 }
else if (
ID ==
".amdhsa_tg_split") {
5729 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5732 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
5733 if (IVersion.
Major < 10)
5734 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5736 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
5738 }
else if (
ID ==
".amdhsa_memory_ordered") {
5739 if (IVersion.
Major < 10)
5740 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5742 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
5744 }
else if (
ID ==
".amdhsa_forward_progress") {
5745 if (IVersion.
Major < 10)
5746 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5748 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
5750 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
5752 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
5753 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
5755 SharedVGPRCount = Val;
5757 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
5759 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
5762 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
5764 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
5766 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
5768 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
5771 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
5773 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
5775 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
5777 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
5779 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
5781 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
5783 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
5785 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
5787 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
5789 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
5790 if (IVersion.
Major < 12)
5791 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
5793 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
5796 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
5799#undef PARSE_BITS_ENTRY
5802 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
5803 return TokError(
".amdhsa_next_free_vgpr directive is required");
5805 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
5806 return TokError(
".amdhsa_next_free_sgpr directive is required");
5808 const MCExpr *VGPRBlocks;
5809 const MCExpr *SGPRBlocks;
5810 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
5811 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
5812 EnableWavefrontSize32, NextFreeVGPR,
5813 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
5817 int64_t EvaluatedVGPRBlocks;
5818 bool VGPRBlocksEvaluatable =
5819 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
5820 if (VGPRBlocksEvaluatable &&
5821 !isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_WIDTH>(
5822 static_cast<uint64_t>(EvaluatedVGPRBlocks))) {
5823 return OutOfRangeError(VGPRRange);
5827 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
5828 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT, getContext());
5830 int64_t EvaluatedSGPRBlocks;
5831 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
5832 !isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_WIDTH>(
5833 static_cast<uint64_t>(EvaluatedSGPRBlocks)))
5834 return OutOfRangeError(SGPRRange);
5837 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
5838 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT, getContext());
5840 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
5841 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
5842 "enabled user SGPRs");
5844 unsigned UserSGPRCount =
5845 ExplicitUserSGPRCount ? *ExplicitUserSGPRCount : ImpliedUserSGPRCount;
5847 if (!isUInt<COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_WIDTH>(UserSGPRCount))
5848 return TokError(
"too many user SGPRs enabled");
5851 COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_SHIFT,
5852 COMPUTE_PGM_RSRC2_USER_SGPR_COUNT, getContext());
5856 return TokError(
"Kernarg size should be resolvable");
5858 if (PreloadLength && kernarg_size &&
5859 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
5860 return TokError(
"Kernarg preload length + offset is larger than the "
5861 "kernarg segment size");
5864 if (!Seen.
contains(
".amdhsa_accum_offset"))
5865 return TokError(
".amdhsa_accum_offset directive is required");
5866 int64_t EvaluatedAccum;
5867 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
5868 uint64_t UEvaluatedAccum = EvaluatedAccum;
5869 if (AccumEvaluatable &&
5870 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
5871 return TokError(
"accum_offset should be in range [4..256] in "
5874 int64_t EvaluatedNumVGPR;
5875 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
5879 return TokError(
"accum_offset exceeds total VGPR allocation");
5885 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
5886 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
5890 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
5892 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
5893 return TokError(
"shared_vgpr_count directive not valid on "
5894 "wavefront size 32");
5897 if (VGPRBlocksEvaluatable &&
5898 (SharedVGPRCount * 2 +
static_cast<uint64_t>(EvaluatedVGPRBlocks) >
5900 return TokError(
"shared_vgpr_count*2 + "
5901 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
5906 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
5907 NextFreeVGPR, NextFreeSGPR,
5908 ReserveVCC, ReserveFlatScr);
5912bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
5914 if (ParseAsAbsoluteExpression(Version))
5917 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(Version);
5921bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(
StringRef ID,
5925 if (
ID ==
"max_scratch_backing_memory_byte_size") {
5926 Parser.eatToEndOfStatement();
5932 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
5933 return TokError(Err.str());
5937 if (
ID ==
"enable_wavefront_size32") {
5940 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
5941 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5942 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
5944 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5945 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
5949 if (
ID ==
"wavefront_size") {
5950 if (
C.wavefront_size == 5) {
5952 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
5953 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5954 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
5955 }
else if (
C.wavefront_size == 6) {
5956 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5957 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
5964bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
5974 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
5977 if (
ID ==
".end_amd_kernel_code_t")
5980 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
5984 KernelCode.
validate(&getSTI(), getContext());
5985 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
5990bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
5992 if (!parseId(KernelName,
"expected symbol name"))
5995 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
5998 KernelScope.initialize(getContext());
6002bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6004 return Error(getLoc(),
6005 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6009 auto TargetIDDirective = getLexer().getTok().getStringContents();
6010 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6011 return Error(getParser().getTok().getLoc(),
"target id must match options");
6013 getTargetStreamer().EmitISAVersion();
6019bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6022 std::string HSAMetadataString;
6027 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6028 return Error(getLoc(),
"invalid HSA metadata");
6035bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6036 const char *AssemblerDirectiveEnd,
6037 std::string &CollectString) {
6041 getLexer().setSkipSpace(
false);
6043 bool FoundEnd =
false;
6046 CollectStream << getTokenStr();
6050 if (trySkipId(AssemblerDirectiveEnd)) {
6055 CollectStream << Parser.parseStringToEndOfStatement()
6056 << getContext().getAsmInfo()->getSeparatorString();
6058 Parser.eatToEndOfStatement();
6061 getLexer().setSkipSpace(
true);
6064 return TokError(
Twine(
"expected directive ") +
6065 Twine(AssemblerDirectiveEnd) +
Twine(
" not found"));
6068 CollectStream.flush();
6073bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6079 auto PALMetadata = getTargetStreamer().getPALMetadata();
6080 if (!PALMetadata->setFromString(
String))
6081 return Error(getLoc(),
"invalid PAL metadata");
6086bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6088 return Error(getLoc(),
6090 "not available on non-amdpal OSes")).str());
6093 auto PALMetadata = getTargetStreamer().getPALMetadata();
6094 PALMetadata->setLegacy();
6097 if (ParseAsAbsoluteExpression(Key)) {
6098 return TokError(
Twine(
"invalid value in ") +
6102 return TokError(
Twine(
"expected an even number of values in ") +
6105 if (ParseAsAbsoluteExpression(
Value)) {
6106 return TokError(
Twine(
"invalid value in ") +
6109 PALMetadata->setRegister(Key,
Value);
6118bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6119 if (getParser().checkForValidSection())
6123 SMLoc NameLoc = getLoc();
6124 if (getParser().parseIdentifier(
Name))
6125 return TokError(
"expected identifier in directive");
6128 if (getParser().parseComma())
6134 SMLoc SizeLoc = getLoc();
6135 if (getParser().parseAbsoluteExpression(
Size))
6138 return Error(SizeLoc,
"size must be non-negative");
6139 if (
Size > LocalMemorySize)
6140 return Error(SizeLoc,
"size is too large");
6142 int64_t Alignment = 4;
6144 SMLoc AlignLoc = getLoc();
6145 if (getParser().parseAbsoluteExpression(Alignment))
6148 return Error(AlignLoc,
"alignment must be a power of two");
6153 if (Alignment >= 1u << 31)
6154 return Error(AlignLoc,
"alignment is too large");
6160 Symbol->redefineIfPossible();
6161 if (!
Symbol->isUndefined())
6162 return Error(NameLoc,
"invalid symbol redefinition");
6164 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6168bool AMDGPUAsmParser::ParseDirective(
AsmToken DirectiveID) {
6172 if (IDVal ==
".amdhsa_kernel")
6173 return ParseDirectiveAMDHSAKernel();
6175 if (IDVal ==
".amdhsa_code_object_version")
6176 return ParseDirectiveAMDHSACodeObjectVersion();
6180 return ParseDirectiveHSAMetadata();
6182 if (IDVal ==
".amd_kernel_code_t")
6183 return ParseDirectiveAMDKernelCodeT();
6185 if (IDVal ==
".amdgpu_hsa_kernel")
6186 return ParseDirectiveAMDGPUHsaKernel();
6188 if (IDVal ==
".amd_amdgpu_isa")
6189 return ParseDirectiveISAVersion();
6193 Twine(
" directive is "
6194 "not available on non-amdhsa OSes"))
6199 if (IDVal ==
".amdgcn_target")
6200 return ParseDirectiveAMDGCNTarget();
6202 if (IDVal ==
".amdgpu_lds")
6203 return ParseDirectiveAMDGPULDS();
6206 return ParseDirectivePALMetadataBegin();
6209 return ParseDirectivePALMetadata();
6217 if (
MRI.regsOverlap(AMDGPU::TTMP12_TTMP13_TTMP14_TTMP15, RegNo))
6221 if (
MRI.regsOverlap(AMDGPU::SGPR104_SGPR105, RegNo))
6222 return hasSGPR104_SGPR105();
6225 case AMDGPU::SRC_SHARED_BASE_LO:
6226 case AMDGPU::SRC_SHARED_BASE:
6227 case AMDGPU::SRC_SHARED_LIMIT_LO:
6228 case AMDGPU::SRC_SHARED_LIMIT:
6229 case AMDGPU::SRC_PRIVATE_BASE_LO:
6230 case AMDGPU::SRC_PRIVATE_BASE:
6231 case AMDGPU::SRC_PRIVATE_LIMIT_LO:
6232 case AMDGPU::SRC_PRIVATE_LIMIT:
6234 case AMDGPU::SRC_POPS_EXITING_WAVE_ID:
6237 case AMDGPU::TBA_LO:
6238 case AMDGPU::TBA_HI:
6240 case AMDGPU::TMA_LO:
6241 case AMDGPU::TMA_HI:
6243 case AMDGPU::XNACK_MASK:
6244 case AMDGPU::XNACK_MASK_LO:
6245 case AMDGPU::XNACK_MASK_HI:
6246 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6247 case AMDGPU::SGPR_NULL:
6261 case AMDGPU::FLAT_SCR:
6262 case AMDGPU::FLAT_SCR_LO:
6263 case AMDGPU::FLAT_SCR_HI:
6272 if (
MRI.regsOverlap(AMDGPU::SGPR102_SGPR103, RegNo))
6273 return hasSGPR102_SGPR103();
6286 Res = MatchOperandParserImpl(
Operands, Mnemonic);
6298 SMLoc LBraceLoc = getLoc();
6303 auto Loc = getLoc();
6306 Error(Loc,
"expected a register");
6310 RBraceLoc = getLoc();
6315 "expected a comma or a closing square bracket"))
6319 if (
Operands.size() - Prefix > 1) {
6321 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6322 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6333 setForcedEncodingSize(0);
6334 setForcedDPP(
false);
6335 setForcedSDWA(
false);
6337 if (
Name.ends_with(
"_e64_dpp")) {
6339 setForcedEncodingSize(64);
6340 return Name.substr(0,
Name.size() - 8);
6341 }
else if (
Name.ends_with(
"_e64")) {
6342 setForcedEncodingSize(64);
6343 return Name.substr(0,
Name.size() - 4);
6344 }
else if (
Name.ends_with(
"_e32")) {
6345 setForcedEncodingSize(32);
6346 return Name.substr(0,
Name.size() - 4);
6347 }
else if (
Name.ends_with(
"_dpp")) {
6349 return Name.substr(0,
Name.size() - 4);
6350 }
else if (
Name.ends_with(
"_sdwa")) {
6351 setForcedSDWA(
true);
6352 return Name.substr(0,
Name.size() - 5);
6359 unsigned VariantID);
6371 Operands.push_back(AMDGPUOperand::CreateToken(
this,
Name, NameLoc));
6373 bool IsMIMG =
Name.starts_with(
"image_");
6376 OperandMode Mode = OperandMode_Default;
6378 Mode = OperandMode_NSA;
6382 checkUnsupportedInstruction(
Name, NameLoc);
6383 if (!Parser.hasPendingError()) {
6386 :
"not a valid operand.";
6387 Error(getLoc(), Msg);
6409 if (!trySkipId(
Name))
6412 Operands.push_back(AMDGPUOperand::CreateToken(
this,
Name, S));
6416ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6427 std::function<
bool(int64_t &)> ConvertResult) {
6435 if (ConvertResult && !ConvertResult(
Value)) {
6439 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6443ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6445 bool (*ConvertResult)(int64_t &)) {
6454 const unsigned MaxSize = 4;
6458 for (
int I = 0; ; ++
I) {
6460 SMLoc Loc = getLoc();
6464 if (
Op != 0 &&
Op != 1)
6472 if (
I + 1 == MaxSize)
6473 return Error(getLoc(),
"expected a closing square bracket");
6479 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
6485 AMDGPUOperand::ImmTy ImmTy) {
6489 if (trySkipId(
Name)) {
6491 }
else if (trySkipId(
"no",
Name)) {
6498 return Error(S,
"r128 modifier is not supported on this GPU");
6500 return Error(S,
"a16 modifier is not supported on this GPU");
6502 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
6503 ImmTy = AMDGPUOperand::ImmTyR128A16;
6505 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
6510 bool &Disabling)
const {
6511 Disabling =
Id.consume_front(
"no");
6531 SMLoc StringLoc = getLoc();
6533 int64_t CPolVal = 0;
6551 ResScope = parseScope(
Operands, Scope);
6566 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
6567 AMDGPUOperand::ImmTyCPol));
6572 SMLoc OpLoc = getLoc();
6573 unsigned Enabled = 0, Seen = 0;
6577 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
6584 return Error(S,
"dlc modifier is not supported on this GPU");
6587 return Error(S,
"scc modifier is not supported on this GPU");
6590 return Error(S,
"duplicate cache policy modifier");
6602 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
6614 Res = parseStringWithPrefix(
"scope",
Value, StringLoc);
6625 if (Scope == 0xffffffff)
6626 return Error(StringLoc,
"invalid scope value");
6640 if (
Value ==
"TH_DEFAULT")
6642 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_RT_WB" ||
6643 Value ==
"TH_LOAD_NT_WB") {
6644 return Error(StringLoc,
"invalid th value");
6645 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
6647 }
else if (
Value.consume_front(
"TH_LOAD_")) {
6649 }
else if (
Value.consume_front(
"TH_STORE_")) {
6652 return Error(StringLoc,
"invalid th value");
6655 if (
Value ==
"BYPASS")
6686 if (TH == 0xffffffff)
6687 return Error(StringLoc,
"invalid th value");
6694 AMDGPUAsmParser::OptionalImmIndexMap& OptionalIdx,
6695 AMDGPUOperand::ImmTy ImmT,
6697 auto i = OptionalIdx.find(ImmT);
6698 if (i != OptionalIdx.end()) {
6699 unsigned Idx = i->second;
6700 ((AMDGPUOperand &)*
Operands[
Idx]).addImmOperands(Inst, 1);
6712 StringLoc = getLoc();
6721bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
6725 SMLoc Loc = getLoc();
6727 auto Res = parseIntWithPrefix(Pref, Val);
6733 if (Val < 0 || Val > MaxVal) {
6743 AMDGPUOperand::ImmTy ImmTy) {
6744 const char *Pref =
"index_key";
6746 SMLoc Loc = getLoc();
6747 auto Res = parseIntWithPrefix(Pref, ImmVal);
6751 if (ImmTy == AMDGPUOperand::ImmTyIndexKey16bit && (ImmVal < 0 || ImmVal > 1))
6754 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
6757 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
6762 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
6766 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
6771ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &Format) {
6778 for (
int I = 0;
I < 2; ++
I) {
6779 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
6782 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
6787 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
6793 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
6796 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6797 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6803ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &Format) {
6808 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
6811 if (Fmt == UFMT_UNDEF)
6818bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
6826 if (Format != DFMT_UNDEF) {
6832 if (Format != NFMT_UNDEF) {
6837 Error(Loc,
"unsupported format");
6848 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
6853 SMLoc Loc = getLoc();
6854 if (!parseId(Str,
"expected a format string") ||
6855 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
6857 if (Dfmt == DFMT_UNDEF)
6858 return Error(Loc,
"duplicate numeric format");
6859 if (Nfmt == NFMT_UNDEF)
6860 return Error(Loc,
"duplicate data format");
6863 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6864 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6868 if (Ufmt == UFMT_UNDEF)
6869 return Error(FormatLoc,
"unsupported format");
6884 if (Id == UFMT_UNDEF)
6888 return Error(Loc,
"unified format is not supported on this GPU");
6894ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &Format) {
6896 SMLoc Loc = getLoc();
6901 return Error(Loc,
"out of range format");
6906ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &Format) {
6914 SMLoc Loc = getLoc();
6915 if (!parseId(FormatStr,
"expected a format string"))
6918 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc, Format);
6920 Res = parseSymbolicSplitFormat(FormatStr, Loc, Format);
6930 return parseNumericFormat(Format);
6938 SMLoc Loc = getLoc();
6948 AMDGPUOperand::CreateImm(
this, Format, Loc, AMDGPUOperand::ImmTyFORMAT));
6967 Res = parseSymbolicOrNumericFormat(Format);
6972 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
6973 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
6980 return Error(getLoc(),
"duplicate format");
6986 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
6988 Res = parseIntWithPrefix(
"inst_offset",
Operands,
6989 AMDGPUOperand::ImmTyInstOffset);
6996 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
6998 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
7004 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
7007 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
7017 OptionalImmIndexMap OptionalIdx;
7019 unsigned OperandIdx[4];
7020 unsigned EnMask = 0;
7023 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
7024 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7029 OperandIdx[SrcIdx] = Inst.
size();
7030 Op.addRegOperands(Inst, 1);
7037 OperandIdx[SrcIdx] = Inst.
size();
7043 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7044 Op.addImmOperands(Inst, 1);
7048 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7052 OptionalIdx[
Op.getImmTy()] = i;
7058 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7065 for (
auto i = 0; i < SrcIdx; ++i) {
7067 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7092 IntVal =
encode(ISA, IntVal, CntVal);
7093 if (CntVal !=
decode(ISA, IntVal)) {
7095 IntVal =
encode(ISA, IntVal, -1);
7103bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7105 SMLoc CntLoc = getLoc();
7113 SMLoc ValLoc = getLoc();
7122 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7124 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7126 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7129 Error(CntLoc,
"invalid counter name " + CntName);
7134 Error(ValLoc,
"too large value for " + CntName);
7143 Error(getLoc(),
"expected a counter name");
7170bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7171 SMLoc FieldLoc = getLoc();
7177 SMLoc ValueLoc = getLoc();
7184 if (FieldName ==
"instid0") {
7186 }
else if (FieldName ==
"instskip") {
7188 }
else if (FieldName ==
"instid1") {
7191 Error(FieldLoc,
"invalid field name " + FieldName);
7210 .
Case(
"VALU_DEP_1", 1)
7211 .
Case(
"VALU_DEP_2", 2)
7212 .
Case(
"VALU_DEP_3", 3)
7213 .
Case(
"VALU_DEP_4", 4)
7214 .
Case(
"TRANS32_DEP_1", 5)
7215 .
Case(
"TRANS32_DEP_2", 6)
7216 .
Case(
"TRANS32_DEP_3", 7)
7217 .
Case(
"FMA_ACCUM_CYCLE_1", 8)
7218 .
Case(
"SALU_CYCLE_1", 9)
7219 .
Case(
"SALU_CYCLE_2", 10)
7220 .
Case(
"SALU_CYCLE_3", 11)
7228 Delay |=
Value << Shift;
7238 if (!parseDelay(Delay))
7246 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7251AMDGPUOperand::isSWaitCnt()
const {
7255bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7261void AMDGPUAsmParser::depCtrError(
SMLoc Loc,
int ErrorId,
7265 Error(Loc,
Twine(
"invalid counter name ", DepCtrName));
7268 Error(Loc,
Twine(DepCtrName,
" is not supported on this GPU"));
7271 Error(Loc,
Twine(
"duplicate counter name ", DepCtrName));
7274 Error(Loc,
Twine(
"invalid value for ", DepCtrName));
7281bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7285 SMLoc DepCtrLoc = getLoc();
7296 unsigned PrevOprMask = UsedOprMask;
7297 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7300 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7309 Error(getLoc(),
"expected a counter name");
7314 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7315 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7323 SMLoc Loc = getLoc();
7326 unsigned UsedOprMask = 0;
7328 if (!parseDepCtr(DepCtr, UsedOprMask))
7336 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
7340bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
7346ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
7348 OperandInfoTy &Width) {
7355 HwReg.Loc = getLoc();
7358 HwReg.IsSymbolic =
true;
7360 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
7368 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
7378 Width.Loc = getLoc();
7390 SMLoc Loc = getLoc();
7392 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
7394 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
7395 HwregOffset::Default);
7396 struct : StructuredOpField {
7397 using StructuredOpField::StructuredOpField;
7398 bool validate(AMDGPUAsmParser &Parser)
const override {
7400 return Error(Parser,
"only values from 1 to 32 are legal");
7403 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
7407 Res = parseHwregFunc(HwReg,
Offset, Width);
7410 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
7412 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
7416 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
7422 if (!isUInt<16>(ImmVal))
7423 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
7425 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
7429bool AMDGPUOperand::isHwreg()
const {
7430 return isImmTy(ImmTyHwreg);
7438AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
7440 OperandInfoTy &Stream) {
7446 Msg.IsSymbolic =
true;
7448 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
7453 Op.IsDefined =
true;
7456 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
7459 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
7464 Stream.IsDefined =
true;
7465 Stream.Loc = getLoc();
7475AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
7476 const OperandInfoTy &
Op,
7477 const OperandInfoTy &Stream) {
7483 bool Strict = Msg.IsSymbolic;
7487 Error(Msg.Loc,
"specified message id is not supported on this GPU");
7492 Error(Msg.Loc,
"invalid message id");
7498 Error(
Op.Loc,
"message does not support operations");
7500 Error(Msg.Loc,
"missing message operation");
7506 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
7508 Error(
Op.Loc,
"invalid operation id");
7513 Error(Stream.Loc,
"message operation does not support streams");
7517 Error(Stream.Loc,
"invalid message stream id");
7527 SMLoc Loc = getLoc();
7531 OperandInfoTy
Op(OP_NONE_);
7532 OperandInfoTy Stream(STREAM_ID_NONE_);
7533 if (parseSendMsgBody(Msg,
Op, Stream) &&
7534 validateSendMsg(Msg,
Op, Stream)) {
7539 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
7540 if (ImmVal < 0 || !isUInt<16>(ImmVal))
7541 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
7546 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
7550bool AMDGPUOperand::isSendMsg()
const {
7551 return isImmTy(ImmTySendMsg);
7572 return Error(S,
"invalid interpolation slot");
7574 Operands.push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
7575 AMDGPUOperand::ImmTyInterpSlot));
7586 if (!Str.starts_with(
"attr"))
7587 return Error(S,
"invalid interpolation attribute");
7597 return Error(S,
"invalid or missing interpolation attribute channel");
7599 Str = Str.drop_back(2).drop_front(4);
7602 if (Str.getAsInteger(10, Attr))
7603 return Error(S,
"invalid or missing interpolation attribute number");
7606 return Error(S,
"out of bounds interpolation attribute number");
7610 Operands.push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
7611 AMDGPUOperand::ImmTyInterpAttr));
7612 Operands.push_back(AMDGPUOperand::CreateImm(
7613 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
7632 return Error(S, (
Id == ET_INVALID)
7633 ?
"invalid exp target"
7634 :
"exp target is not supported on this GPU");
7636 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Id, S,
7637 AMDGPUOperand::ImmTyExpTgt));
7652 return isId(getToken(),
Id);
7657 return getTokenKind() ==
Kind;
7660StringRef AMDGPUAsmParser::getId()
const {
7687 if (isId(
Id) && peekToken().is(Kind)) {
7697 if (isToken(Kind)) {
7707 if (!trySkipToken(Kind)) {
7708 Error(getLoc(), ErrMsg);
7719 if (Parser.parseExpression(Expr))
7722 if (Expr->evaluateAsAbsolute(Imm))
7726 Error(S,
"expected absolute expression");
7729 Twine(
" or an absolute expression"));
7739 if (Parser.parseExpression(Expr))
7743 if (Expr->evaluateAsAbsolute(IntVal)) {
7744 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
7746 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
7754 Val = getToken().getStringContents();
7758 Error(getLoc(), ErrMsg);
7766 Val = getTokenStr();
7770 if (!ErrMsg.
empty())
7771 Error(getLoc(), ErrMsg);
7777AMDGPUAsmParser::getToken()
const {
7778 return Parser.getTok();
7781AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
7784 : getLexer().peekTok(ShouldSkipSpace);
7789 auto TokCount = getLexer().peekTokens(Tokens);
7796AMDGPUAsmParser::getTokenKind()
const {
7801AMDGPUAsmParser::getLoc()
const {
7802 return getToken().getLoc();
7806AMDGPUAsmParser::getTokenStr()
const {
7807 return getToken().getString();
7811AMDGPUAsmParser::lex() {
7816 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
7820AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
7822 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
7823 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7825 return Op.getStartLoc();
7831AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
7833 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
7838AMDGPUAsmParser::getRegLoc(
unsigned Reg,
7840 auto Test = [=](
const AMDGPUOperand&
Op) {
7841 return Op.isRegKind() &&
Op.getReg() ==
Reg;
7847 bool SearchMandatoryLiterals)
const {
7848 auto Test = [](
const AMDGPUOperand&
Op) {
7849 return Op.IsImmKindLiteral() ||
Op.isExpr();
7852 if (SearchMandatoryLiterals && Loc == getInstLoc(
Operands))
7853 Loc = getMandatoryLitLoc(
Operands);
7858 auto Test = [](
const AMDGPUOperand &
Op) {
7859 return Op.IsImmKindMandatoryLiteral();
7866 auto Test = [](
const AMDGPUOperand&
Op) {
7867 return Op.isImmKindConst();
7884 SMLoc IdLoc = getLoc();
7890 find_if(Fields, [
Id](StructuredOpField *
F) {
return F->Id ==
Id; });
7891 if (
I == Fields.
end())
7892 return Error(IdLoc,
"unknown field");
7893 if ((*I)->IsDefined)
7894 return Error(IdLoc,
"duplicate field");
7897 (*I)->Loc = getLoc();
7900 (*I)->IsDefined =
true;
7907bool AMDGPUAsmParser::validateStructuredOpFields(
7909 return all_of(Fields, [
this](
const StructuredOpField *
F) {
7910 return F->validate(*
this);
7921 const unsigned OrMask,
7922 const unsigned XorMask) {
7925 return BITMASK_PERM_ENC |
7926 (AndMask << BITMASK_AND_SHIFT) |
7927 (OrMask << BITMASK_OR_SHIFT) |
7928 (XorMask << BITMASK_XOR_SHIFT);
7932AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
7933 const unsigned MinVal,
7934 const unsigned MaxVal,
7944 if (Op < MinVal || Op > MaxVal) {
7953AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
7954 const unsigned MinVal,
7955 const unsigned MaxVal,
7958 for (
unsigned i = 0; i < OpNum; ++i) {
7959 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
7967AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &Imm) {
7971 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
7972 "expected a 2-bit lane id")) {
7983AMDGPUAsmParser::parseSwizzleBroadcast(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");
8000 if (parseSwizzleOperand(LaneIdx,
8002 "lane id must be in the interval [0,group size - 1]",
8011AMDGPUAsmParser::parseSwizzleReverse(int64_t &Imm) {
8017 if (!parseSwizzleOperand(GroupSize,
8019 "group size must be in the interval [2,32]",
8024 Error(Loc,
"group size must be a power of two");
8033AMDGPUAsmParser::parseSwizzleSwap(int64_t &Imm) {
8039 if (!parseSwizzleOperand(GroupSize,
8041 "group size must be in the interval [1,16]",
8046 Error(Loc,
"group size must be a power of two");
8055AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &Imm) {
8063 SMLoc StrLoc = getLoc();
8064 if (!parseString(Ctl)) {
8067 if (Ctl.
size() != BITMASK_WIDTH) {
8068 Error(StrLoc,
"expected a 5-character mask");
8072 unsigned AndMask = 0;
8073 unsigned OrMask = 0;
8074 unsigned XorMask = 0;
8076 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8080 Error(StrLoc,
"invalid mask");
8102AMDGPUAsmParser::parseSwizzleOffset(int64_t &Imm) {
8104 SMLoc OffsetLoc = getLoc();
8106 if (!
parseExpr(Imm,
"a swizzle macro")) {
8109 if (!isUInt<16>(Imm)) {
8110 Error(OffsetLoc,
"expected a 16-bit offset");
8117AMDGPUAsmParser::parseSwizzleMacro(int64_t &Imm) {
8122 SMLoc ModeLoc = getLoc();
8125 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8126 Ok = parseSwizzleQuadPerm(Imm);
8127 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8128 Ok = parseSwizzleBitmaskPerm(Imm);
8129 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8130 Ok = parseSwizzleBroadcast(Imm);
8131 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8132 Ok = parseSwizzleSwap(Imm);
8133 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8134 Ok = parseSwizzleReverse(Imm);
8136 Error(ModeLoc,
"expected a swizzle mode");
8139 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8149 if (trySkipId(
"offset")) {
8153 if (trySkipId(
"swizzle")) {
8154 Ok = parseSwizzleMacro(Imm);
8156 Ok = parseSwizzleOffset(Imm);
8160 Operands.push_back(AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTySwizzle));
8168AMDGPUOperand::isSwizzle()
const {
8169 return isImmTy(ImmTySwizzle);
8176int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8190 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8191 if (trySkipId(IdSymbolic[ModeId])) {
8198 Error(S, (Imm == 0)?
8199 "expected a VGPR index mode or a closing parenthesis" :
8200 "expected a VGPR index mode");
8205 Error(S,
"duplicate VGPR index mode");
8213 "expected a comma or a closing parenthesis"))
8228 Imm = parseGPRIdxMacro();
8232 if (getParser().parseAbsoluteExpression(Imm))
8234 if (Imm < 0 || !isUInt<4>(Imm))
8235 return Error(S,
"invalid immediate: only 4-bit values are legal");
8239 AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8243bool AMDGPUOperand::isGPRIdxMode()
const {
8244 return isImmTy(ImmTyGprIdxMode);
8256 if (isRegister() || isModifier())
8263 assert(Opr.isImm() || Opr.isExpr());
8264 SMLoc Loc = Opr.getStartLoc();
8268 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8269 Error(Loc,
"expected an absolute expression or a label");
8270 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8271 Error(Loc,
"expected a 16-bit signed jump offset");
8289void AMDGPUAsmParser::cvtMubufImpl(
MCInst &Inst,
8292 OptionalImmIndexMap OptionalIdx;
8293 unsigned FirstOperandIdx = 1;
8294 bool IsAtomicReturn =
false;
8301 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
8302 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8306 Op.addRegOperands(Inst, 1);
8310 if (IsAtomicReturn && i == FirstOperandIdx)
8311 Op.addRegOperands(Inst, 1);
8316 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
8317 Op.addImmOperands(Inst, 1);
8329 OptionalIdx[
Op.getImmTy()] = i;
8340bool AMDGPUOperand::isSMRDOffset8()
const {
8341 return isImmLiteral() && isUInt<8>(getImm());
8344bool AMDGPUOperand::isSMEMOffset()
const {
8346 return isImmLiteral();
8349bool AMDGPUOperand::isSMRDLiteralOffset()
const {
8352 return isImmLiteral() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
8384bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
8385 if (BoundCtrl == 0 || BoundCtrl == 1) {
8393void AMDGPUAsmParser::onBeginOfFile() {
8394 if (!getParser().getStreamer().getTargetStreamer() ||
8398 if (!getTargetStreamer().getTargetID())
8399 getTargetStreamer().initializeTargetID(getSTI(),
8400 getSTI().getFeatureString());
8403 getTargetStreamer().EmitDirectiveAMDGCNTarget();
8411bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
8417 .
Case(
"max", AGVK::AGVK_Max)
8418 .
Case(
"or", AGVK::AGVK_Or)
8419 .
Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
8420 .
Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
8421 .
Case(
"alignto", AGVK::AGVK_AlignTo)
8422 .
Case(
"occupancy", AGVK::AGVK_Occupancy)
8432 if (Exprs.
empty()) {
8433 Error(getToken().getLoc(),
8434 "empty " +
Twine(TokenId) +
" expression");
8437 if (CommaCount + 1 != Exprs.
size()) {
8438 Error(getToken().getLoc(),
8439 "mismatch of commas in " +
Twine(TokenId) +
" expression");
8446 if (getParser().parseExpression(Expr, EndLoc))
8450 if (LastTokenWasComma)
8453 Error(getToken().getLoc(),
8454 "unexpected token in " +
Twine(TokenId) +
" expression");
8460 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
8465 if (
Name ==
"mul") {
8466 return parseIntWithPrefix(
"mul",
Operands,
8470 if (
Name ==
"div") {
8471 return parseIntWithPrefix(
"div",
Operands,
8487 const int Ops[] = { AMDGPU::OpName::src0,
8488 AMDGPU::OpName::src1,
8489 AMDGPU::OpName::src2 };
8504 if (
DstOp.isReg() &&
8505 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
8509 if ((OpSel & (1 << SrcNum)) != 0)
8515void AMDGPUAsmParser::cvtVOP3OpSel(
MCInst &Inst,
8522 OptionalImmIndexMap &OptionalIdx) {
8523 cvtVOP3P(Inst,
Operands, OptionalIdx);
8532 &&
Desc.NumOperands > (OpNum + 1)
8534 &&
Desc.operands()[OpNum + 1].RegClass != -1
8536 &&
Desc.getOperandConstraint(OpNum + 1,
8537 MCOI::OperandConstraint::TIED_TO) == -1;
8542 OptionalImmIndexMap OptionalIdx;
8547 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8548 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8551 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8552 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8554 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8555 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
8556 Op.isInterpAttrChan()) {
8558 }
else if (
Op.isImmModifier()) {
8559 OptionalIdx[
Op.getImmTy()] =
I;
8567 AMDGPUOperand::ImmTyHigh);
8571 AMDGPUOperand::ImmTyClamp);
8575 AMDGPUOperand::ImmTyOModSI);
8580 OptionalImmIndexMap OptionalIdx;
8585 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8586 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8589 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8590 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8592 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8593 }
else if (
Op.isImmModifier()) {
8594 OptionalIdx[
Op.getImmTy()] =
I;
8611 const int Ops[] = { AMDGPU::OpName::src0,
8612 AMDGPU::OpName::src1,
8613 AMDGPU::OpName::src2 };
8614 const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8615 AMDGPU::OpName::src1_modifiers,
8616 AMDGPU::OpName::src2_modifiers };
8620 for (
int J = 0; J < 3; ++J) {
8628 if ((OpSel & (1 << J)) != 0)
8630 if (ModOps[J] == AMDGPU::OpName::src0_modifiers &&
8631 (OpSel & (1 << 3)) != 0)
8639 OptionalImmIndexMap &OptionalIdx) {
8644 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8645 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8648 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8649 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8651 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8652 }
else if (
Op.isImmModifier()) {
8653 OptionalIdx[
Op.getImmTy()] =
I;
8654 }
else if (
Op.isRegOrImm()) {
8655 Op.addRegOrImmOperands(Inst, 1);
8665 AMDGPUOperand::ImmTyByteSel);
8670 AMDGPUOperand::ImmTyClamp);
8674 AMDGPUOperand::ImmTyOModSI);
8681 auto it = Inst.
begin();
8691 OptionalImmIndexMap OptionalIdx;
8692 cvtVOP3(Inst,
Operands, OptionalIdx);
8696 OptionalImmIndexMap &OptIdx) {
8702 if (Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
8703 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
8704 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
8705 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
8713 !(Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp_gfx12 ||
8714 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp_gfx12 ||
8715 Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp8_gfx12 ||
8716 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp8_gfx12 ||
8717 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
8718 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
8719 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
8720 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12)) {
8729 if (OpSelIdx != -1) {
8734 if (OpSelHiIdx != -1) {
8748 const int Ops[] = { AMDGPU::OpName::src0,
8749 AMDGPU::OpName::src1,
8750 AMDGPU::OpName::src2 };
8751 const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8752 AMDGPU::OpName::src1_modifiers,
8753 AMDGPU::OpName::src2_modifiers };
8756 unsigned OpSelHi = 0;
8763 if (OpSelHiIdx != -1)
8772 for (
int J = 0; J < 3; ++J) {
8785 if (
SrcOp.isReg() && getMRI()
8792 if ((OpSel & (1 << J)) != 0)
8796 if ((OpSelHi & (1 << J)) != 0)
8799 if ((NegLo & (1 << J)) != 0)
8802 if ((NegHi & (1 << J)) != 0)
8810 OptionalImmIndexMap OptIdx;
8816 unsigned i,
unsigned Opc,
unsigned OpName) {
8818 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
8820 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
8826 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
8829 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
8830 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
8832 OptionalImmIndexMap OptIdx;
8833 for (
unsigned i = 5; i <
Operands.size(); ++i) {
8834 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8835 OptIdx[
Op.getImmTy()] = i;
8840 AMDGPUOperand::ImmTyIndexKey8bit);
8844 AMDGPUOperand::ImmTyIndexKey16bit);
8864 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
8865 SMLoc OpYLoc = getLoc();
8868 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
8871 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
8878 auto addOp = [&](
uint16_t ParsedOprIdx) {
8879 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
8881 Op.addRegOperands(Inst, 1);
8885 Op.addImmOperands(Inst, 1);
8897 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
8901 const auto &CInfo = InstInfo[CompIdx];
8902 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
8903 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
8904 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
8905 if (CInfo.hasSrc2Acc())
8906 addOp(CInfo.getIndexOfDstInParsedOperands());
8914bool AMDGPUOperand::isDPP8()
const {
8915 return isImmTy(ImmTyDPP8);
8918bool AMDGPUOperand::isDPPCtrl()
const {
8919 using namespace AMDGPU::DPP;
8921 bool result =
isImm() && getImmTy() == ImmTyDppCtrl && isUInt<9>(getImm());
8923 int64_t
Imm = getImm();
8924 return (Imm >= DppCtrl::QUAD_PERM_FIRST && Imm <= DppCtrl::QUAD_PERM_LAST) ||
8925 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
8926 (Imm >= DppCtrl::ROW_SHR_FIRST && Imm <= DppCtrl::ROW_SHR_LAST) ||
8927 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
8928 (Imm == DppCtrl::WAVE_SHL1) ||
8929 (
Imm == DppCtrl::WAVE_ROL1) ||
8930 (Imm == DppCtrl::WAVE_SHR1) ||
8931 (
Imm == DppCtrl::WAVE_ROR1) ||
8932 (Imm == DppCtrl::ROW_MIRROR) ||
8933 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
8934 (Imm == DppCtrl::BCAST15) ||
8935 (
Imm == DppCtrl::BCAST31) ||
8936 (Imm >= DppCtrl::ROW_SHARE_FIRST && Imm <= DppCtrl::ROW_SHARE_LAST) ||
8937 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
8946bool AMDGPUOperand::isBLGP()
const {
8947 return isImm() && getImmTy() == ImmTyBLGP && isUInt<3>(getImm());
8950bool AMDGPUOperand::isS16Imm()
const {
8951 return isImmLiteral() && (isInt<16>(getImm()) || isUInt<16>(getImm()));
8954bool AMDGPUOperand::isU16Imm()
const {
8955 return isImmLiteral() && isUInt<16>(getImm());
8962bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
8967 SMLoc Loc = getToken().getEndLoc();
8968 Token = std::string(getTokenStr());
8970 if (getLoc() != Loc)
8975 if (!parseId(Suffix))
9001 SMLoc Loc = getLoc();
9002 if (!parseDimId(Encoding))
9003 return Error(Loc,
"invalid dim value");
9005 Operands.push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9006 AMDGPUOperand::ImmTyDim));
9024 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9027 for (
size_t i = 0; i < 8; ++i) {
9031 SMLoc Loc = getLoc();
9032 if (getParser().parseAbsoluteExpression(Sels[i]))
9034 if (0 > Sels[i] || 7 < Sels[i])
9035 return Error(Loc,
"expected a 3-bit value");
9042 for (
size_t i = 0; i < 8; ++i)
9043 DPP8 |= (Sels[i] << (i * 3));
9045 Operands.push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9050AMDGPUAsmParser::isSupportedDPPCtrl(
StringRef Ctrl,
9052 if (Ctrl ==
"row_newbcast")
9055 if (Ctrl ==
"row_share" ||
9056 Ctrl ==
"row_xmask")
9059 if (Ctrl ==
"wave_shl" ||
9060 Ctrl ==
"wave_shr" ||
9061 Ctrl ==
"wave_rol" ||
9062 Ctrl ==
"wave_ror" ||
9063 Ctrl ==
"row_bcast")
9066 return Ctrl ==
"row_mirror" ||
9067 Ctrl ==
"row_half_mirror" ||
9068 Ctrl ==
"quad_perm" ||
9069 Ctrl ==
"row_shl" ||
9070 Ctrl ==
"row_shr" ||
9075AMDGPUAsmParser::parseDPPCtrlPerm() {
9078 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9082 for (
int i = 0; i < 4; ++i) {
9087 SMLoc Loc = getLoc();
9088 if (getParser().parseAbsoluteExpression(Temp))
9090 if (Temp < 0 || Temp > 3) {
9091 Error(Loc,
"expected a 2-bit value");
9095 Val += (Temp << i * 2);
9105AMDGPUAsmParser::parseDPPCtrlSel(
StringRef Ctrl) {
9106 using namespace AMDGPU::DPP;
9111 SMLoc Loc = getLoc();
9113 if (getParser().parseAbsoluteExpression(Val))
9116 struct DppCtrlCheck {
9123 .
Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
9124 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
9125 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
9126 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
9127 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
9128 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
9129 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
9130 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
9131 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
9132 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
9136 if (
Check.Ctrl == -1) {
9137 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
9138 Val = (Val == 15)? DppCtrl::BCAST15 : DppCtrl::BCAST31;
9153 using namespace AMDGPU::DPP;
9156 !isSupportedDPPCtrl(getTokenStr(),
Operands))
9165 if (Ctrl ==
"row_mirror") {
9166 Val = DppCtrl::ROW_MIRROR;
9167 }
else if (Ctrl ==
"row_half_mirror") {
9168 Val = DppCtrl::ROW_HALF_MIRROR;
9171 if (Ctrl ==
"quad_perm") {
9172 Val = parseDPPCtrlPerm();
9174 Val = parseDPPCtrlSel(Ctrl);
9183 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
9189 OptionalImmIndexMap OptionalIdx;
9199 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
9203 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9204 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9208 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9212 if (OldIdx == NumOperands) {
9214 constexpr int DST_IDX = 0;
9216 }
else if (Src2ModIdx == NumOperands) {
9227 bool IsVOP3CvtSrDpp =
9228 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9229 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9230 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9231 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
9232 if (IsVOP3CvtSrDpp) {
9246 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9248 if (IsDPP8 &&
Op.isDppFI()) {
9251 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9252 }
else if (
Op.isReg()) {
9253 Op.addRegOperands(Inst, 1);
9254 }
else if (
Op.isImm() &&
9256 assert(!
Op.IsImmKindLiteral() &&
"Cannot use literal with DPP");
9257 Op.addImmOperands(Inst, 1);
9258 }
else if (
Op.isImm()) {
9259 OptionalIdx[
Op.getImmTy()] =
I;
9267 AMDGPUOperand::ImmTyByteSel);
9271 AMDGPUOperand::ImmTyClamp);
9277 cvtVOP3P(Inst,
Operands, OptionalIdx);
9279 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
9296 AMDGPUOperand::ImmTyDppFI);
9301 OptionalImmIndexMap OptionalIdx;
9305 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9306 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9310 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9318 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9320 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
9328 Op.addImmOperands(Inst, 1);
9330 Op.addRegWithFPInputModsOperands(Inst, 2);
9331 }
else if (
Op.isDppFI()) {
9333 }
else if (
Op.isReg()) {
9334 Op.addRegOperands(Inst, 1);
9340 Op.addRegWithFPInputModsOperands(Inst, 2);
9341 }
else if (
Op.isReg()) {
9342 Op.addRegOperands(Inst, 1);
9343 }
else if (
Op.isDPPCtrl()) {
9344 Op.addImmOperands(Inst, 1);
9345 }
else if (
Op.isImm()) {
9347 OptionalIdx[
Op.getImmTy()] =
I;
9363 AMDGPUOperand::ImmTyDppFI);
9374 AMDGPUOperand::ImmTy
Type) {
9387 .
Case(
"BYTE_0", SdwaSel::BYTE_0)
9388 .
Case(
"BYTE_1", SdwaSel::BYTE_1)
9389 .
Case(
"BYTE_2", SdwaSel::BYTE_2)
9390 .
Case(
"BYTE_3", SdwaSel::BYTE_3)
9391 .
Case(
"WORD_0", SdwaSel::WORD_0)
9392 .
Case(
"WORD_1", SdwaSel::WORD_1)
9393 .
Case(
"DWORD", SdwaSel::DWORD)
9396 if (
Int == 0xffffffff)
9397 return Error(StringLoc,
"invalid " +
Twine(Prefix) +
" value");
9416 .
Case(
"UNUSED_PAD", DstUnused::UNUSED_PAD)
9417 .
Case(
"UNUSED_SEXT", DstUnused::UNUSED_SEXT)
9418 .
Case(
"UNUSED_PRESERVE", DstUnused::UNUSED_PRESERVE)
9421 if (
Int == 0xffffffff)
9422 return Error(StringLoc,
"invalid dst_unused value");
9424 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Int, S, AMDGPUOperand::ImmTySDWADstUnused));
9454 OptionalImmIndexMap OptionalIdx;
9455 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
9456 bool SkippedVcc =
false;
9460 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9461 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9464 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9465 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9466 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
9467 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
9485 Op.addRegOrImmWithInputModsOperands(Inst, 2);
9486 }
else if (
Op.isImm()) {
9488 OptionalIdx[
Op.getImmTy()] =
I;
9496 if (Opc != AMDGPU::V_NOP_sdwa_gfx10 && Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
9497 Opc != AMDGPU::V_NOP_sdwa_vi) {
9499 switch (BasicInstType) {
9503 AMDGPUOperand::ImmTyClamp, 0);
9507 AMDGPUOperand::ImmTyOModSI, 0);
9511 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
9515 AMDGPUOperand::ImmTySDWADstUnused,
9516 DstUnused::UNUSED_PRESERVE);
9523 AMDGPUOperand::ImmTyClamp, 0);
9537 AMDGPUOperand::ImmTyClamp, 0);
9543 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
9549 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
9550 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
9551 auto it = Inst.
begin();
9564#define GET_REGISTER_MATCHER
9565#define GET_MATCHER_IMPLEMENTATION
9566#define GET_MNEMONIC_SPELL_CHECKER
9567#define GET_MNEMONIC_CHECKER
9568#include "AMDGPUGenAsmMatcher.inc"
9574 return parseTokenOp(
"addr64",
Operands);
9576 return parseTokenOp(
"done",
Operands);
9578 return parseTokenOp(
"idxen",
Operands);
9580 return parseTokenOp(
"lds",
Operands);
9582 return parseTokenOp(
"offen",
Operands);
9584 return parseTokenOp(
"off",
Operands);
9586 return parseTokenOp(
"row_en",
Operands);
9588 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
9590 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
9592 return tryCustomParseOperand(
Operands, MCK);
9603 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
9606 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
9608 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
9610 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
9612 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
9614 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
9616 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
9624 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
9626 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
9627 case MCK_SOPPBrTarget:
9628 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
9629 case MCK_VReg32OrOff:
9630 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
9631 case MCK_InterpSlot:
9632 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
9633 case MCK_InterpAttr:
9634 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
9635 case MCK_InterpAttrChan:
9636 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
9638 case MCK_SReg_64_XEXEC:
9644 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
9646 return Match_InvalidOperand;
9663 if (!isUInt<16>(Imm))
9664 return Error(S,
"expected a 16-bit value");
9667 AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTyEndpgm));
9671bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
9677bool 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.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static 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)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
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 AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
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 MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static 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 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 getVGPREncodingGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI)
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
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)
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.
@ C
The default llvm calling convention, compatible with C.
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.
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.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
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.
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
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