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 isDMask()
const {
return isImmTy(ImmTyDMask); }
380 bool isDim()
const {
return isImmTy(ImmTyDim); }
381 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
382 bool isOff()
const {
return isImmTy(ImmTyOff); }
383 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
384 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
385 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
386 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
387 bool isOffset()
const {
return isImmTy(ImmTyOffset); }
388 bool isOffset0()
const {
return isImmTy(ImmTyOffset0) && isUInt<8>(getImm()); }
389 bool isOffset1()
const {
return isImmTy(ImmTyOffset1) && isUInt<8>(getImm()); }
390 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
391 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
392 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
393 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
394 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
395 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
396 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
397 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
398 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) && isUInt<7>(getImm()); }
399 bool isDppBankMask()
const {
return isImmTy(ImmTyDppBankMask); }
400 bool isDppRowMask()
const {
return isImmTy(ImmTyDppRowMask); }
401 bool isDppBoundCtrl()
const {
return isImmTy(ImmTyDppBoundCtrl); }
402 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
403 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
404 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
405 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
406 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
407 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
408 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
409 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
410 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
411 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
412 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
413 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
414 bool isByteSel()
const {
415 return isImmTy(ImmTyByteSel) && isUInt<2>(getImm());
418 bool isRegOrImm()
const {
422 bool isRegClass(
unsigned RCID)
const;
426 bool isRegOrInlineNoMods(
unsigned RCID,
MVT type)
const {
427 return isRegOrInline(RCID, type) && !hasModifiers();
430 bool isSCSrcB16()
const {
431 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
434 bool isSCSrcV2B16()
const {
438 bool isSCSrc_b32()
const {
439 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
442 bool isSCSrc_b64()
const {
443 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
446 bool isBoolReg()
const;
448 bool isSCSrcF16()
const {
449 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
452 bool isSCSrcV2F16()
const {
456 bool isSCSrcF32()
const {
457 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
460 bool isSCSrcF64()
const {
461 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
464 bool isSSrc_b32()
const {
465 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
468 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
470 bool isSSrcV2B16()
const {
475 bool isSSrc_b64()
const {
478 return isSCSrc_b64() || isLiteralImm(MVT::i64);
481 bool isSSrc_f32()
const {
482 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
485 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
487 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
489 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
491 bool isSSrcV2F16()
const {
496 bool isSSrcV2FP32()
const {
501 bool isSCSrcV2FP32()
const {
506 bool isSSrcV2INT32()
const {
511 bool isSCSrcV2INT32()
const {
513 return isSCSrc_b32();
516 bool isSSrcOrLds_b32()
const {
517 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
518 isLiteralImm(MVT::i32) || isExpr();
521 bool isVCSrc_b32()
const {
522 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
525 bool isVCSrcB64()
const {
526 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
529 bool isVCSrcTB16()
const {
530 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
533 bool isVCSrcTB16_Lo128()
const {
534 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
537 bool isVCSrcFake16B16_Lo128()
const {
538 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
541 bool isVCSrc_b16()
const {
542 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
545 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
547 bool isVCSrc_f32()
const {
548 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
551 bool isVCSrcF64()
const {
552 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
555 bool isVCSrcTBF16()
const {
556 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
559 bool isVCSrcTF16()
const {
560 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
563 bool isVCSrcTBF16_Lo128()
const {
564 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
567 bool isVCSrcTF16_Lo128()
const {
568 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
571 bool isVCSrcFake16BF16_Lo128()
const {
572 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
575 bool isVCSrcFake16F16_Lo128()
const {
576 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
579 bool isVCSrc_bf16()
const {
580 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
583 bool isVCSrc_f16()
const {
584 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
587 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
589 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
591 bool isVSrc_b32()
const {
592 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
595 bool isVSrc_b64()
const {
return isVCSrcF64() || isLiteralImm(MVT::i64); }
597 bool isVSrcT_b16()
const {
return isVCSrcTB16() || isLiteralImm(MVT::i16); }
599 bool isVSrcT_b16_Lo128()
const {
600 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
603 bool isVSrcFake16_b16_Lo128()
const {
604 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
607 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
609 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
611 bool isVCSrcV2FP32()
const {
615 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
617 bool isVCSrcV2INT32()
const {
621 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
623 bool isVSrc_f32()
const {
624 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
627 bool isVSrc_f64()
const {
return isVCSrcF64() || isLiteralImm(MVT::f64); }
629 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
631 bool isVSrcT_f16()
const {
return isVCSrcTF16() || isLiteralImm(MVT::f16); }
633 bool isVSrcT_bf16_Lo128()
const {
634 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
637 bool isVSrcT_f16_Lo128()
const {
638 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
641 bool isVSrcFake16_bf16_Lo128()
const {
642 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
645 bool isVSrcFake16_f16_Lo128()
const {
646 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
649 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
651 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
653 bool isVSrc_v2bf16()
const {
654 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
657 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
659 bool isVISrcB32()
const {
660 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
663 bool isVISrcB16()
const {
664 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
667 bool isVISrcV2B16()
const {
671 bool isVISrcF32()
const {
672 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
675 bool isVISrcF16()
const {
676 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
679 bool isVISrcV2F16()
const {
680 return isVISrcF16() || isVISrcB32();
683 bool isVISrc_64_bf16()
const {
684 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
687 bool isVISrc_64_f16()
const {
688 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
691 bool isVISrc_64_b32()
const {
692 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
695 bool isVISrc_64B64()
const {
696 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
699 bool isVISrc_64_f64()
const {
700 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
703 bool isVISrc_64V2FP32()
const {
704 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
707 bool isVISrc_64V2INT32()
const {
708 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
711 bool isVISrc_256_b32()
const {
712 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
715 bool isVISrc_256_f32()
const {
716 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
719 bool isVISrc_256B64()
const {
720 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
723 bool isVISrc_256_f64()
const {
724 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
727 bool isVISrc_128B16()
const {
728 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
731 bool isVISrc_128V2B16()
const {
732 return isVISrc_128B16();
735 bool isVISrc_128_b32()
const {
736 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
739 bool isVISrc_128_f32()
const {
740 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
743 bool isVISrc_256V2FP32()
const {
744 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
747 bool isVISrc_256V2INT32()
const {
748 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
751 bool isVISrc_512_b32()
const {
752 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
755 bool isVISrc_512B16()
const {
756 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
759 bool isVISrc_512V2B16()
const {
760 return isVISrc_512B16();
763 bool isVISrc_512_f32()
const {
764 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
767 bool isVISrc_512F16()
const {
768 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
771 bool isVISrc_512V2F16()
const {
772 return isVISrc_512F16() || isVISrc_512_b32();
775 bool isVISrc_1024_b32()
const {
776 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
779 bool isVISrc_1024B16()
const {
780 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
783 bool isVISrc_1024V2B16()
const {
784 return isVISrc_1024B16();
787 bool isVISrc_1024_f32()
const {
788 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
791 bool isVISrc_1024F16()
const {
792 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
795 bool isVISrc_1024V2F16()
const {
796 return isVISrc_1024F16() || isVISrc_1024_b32();
799 bool isAISrcB32()
const {
800 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
803 bool isAISrcB16()
const {
804 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
807 bool isAISrcV2B16()
const {
811 bool isAISrcF32()
const {
812 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
815 bool isAISrcF16()
const {
816 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
819 bool isAISrcV2F16()
const {
820 return isAISrcF16() || isAISrcB32();
823 bool isAISrc_64B64()
const {
824 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
827 bool isAISrc_64_f64()
const {
828 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
831 bool isAISrc_128_b32()
const {
832 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
835 bool isAISrc_128B16()
const {
836 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
839 bool isAISrc_128V2B16()
const {
840 return isAISrc_128B16();
843 bool isAISrc_128_f32()
const {
844 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
847 bool isAISrc_128F16()
const {
848 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
851 bool isAISrc_128V2F16()
const {
852 return isAISrc_128F16() || isAISrc_128_b32();
855 bool isVISrc_128_bf16()
const {
856 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
859 bool isVISrc_128_f16()
const {
860 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
863 bool isVISrc_128V2F16()
const {
864 return isVISrc_128_f16() || isVISrc_128_b32();
867 bool isAISrc_256B64()
const {
868 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
871 bool isAISrc_256_f64()
const {
872 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
875 bool isAISrc_512_b32()
const {
876 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
879 bool isAISrc_512B16()
const {
880 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
883 bool isAISrc_512V2B16()
const {
884 return isAISrc_512B16();
887 bool isAISrc_512_f32()
const {
888 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
891 bool isAISrc_512F16()
const {
892 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
895 bool isAISrc_512V2F16()
const {
896 return isAISrc_512F16() || isAISrc_512_b32();
899 bool isAISrc_1024_b32()
const {
900 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
903 bool isAISrc_1024B16()
const {
904 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
907 bool isAISrc_1024V2B16()
const {
908 return isAISrc_1024B16();
911 bool isAISrc_1024_f32()
const {
912 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
915 bool isAISrc_1024F16()
const {
916 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
919 bool isAISrc_1024V2F16()
const {
920 return isAISrc_1024F16() || isAISrc_1024_b32();
923 bool isKImmFP32()
const {
924 return isLiteralImm(MVT::f32);
927 bool isKImmFP16()
const {
928 return isLiteralImm(MVT::f16);
931 bool isMem()
const override {
935 bool isExpr()
const {
939 bool isSOPPBrTarget()
const {
return isExpr() ||
isImm(); }
941 bool isSWaitCnt()
const;
942 bool isDepCtr()
const;
943 bool isSDelayALU()
const;
944 bool isHwreg()
const;
945 bool isSendMsg()
const;
946 bool isSplitBarrier()
const;
947 bool isSwizzle()
const;
948 bool isSMRDOffset8()
const;
949 bool isSMEMOffset()
const;
950 bool isSMRDLiteralOffset()
const;
952 bool isDPPCtrl()
const;
956 bool isGPRIdxMode()
const;
957 bool isS16Imm()
const;
958 bool isU16Imm()
const;
959 bool isEndpgm()
const;
960 bool isWaitVDST()
const;
961 bool isWaitEXP()
const;
962 bool isWaitVAVDst()
const;
963 bool isWaitVMVSrc()
const;
965 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
966 return std::bind(
P, *
this);
974 int64_t getImm()
const {
979 void setImm(int64_t Val) {
984 ImmTy getImmTy()
const {
994 SMLoc getStartLoc()
const override {
998 SMLoc getEndLoc()
const override {
1003 return SMRange(StartLoc, EndLoc);
1006 Modifiers getModifiers()
const {
1007 assert(isRegKind() || isImmTy(ImmTyNone));
1008 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1011 void setModifiers(Modifiers Mods) {
1012 assert(isRegKind() || isImmTy(ImmTyNone));
1019 bool hasModifiers()
const {
1020 return getModifiers().hasModifiers();
1023 bool hasFPModifiers()
const {
1024 return getModifiers().hasFPModifiers();
1027 bool hasIntModifiers()
const {
1028 return getModifiers().hasIntModifiers();
1033 void addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1035 void addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1037 void addRegOperands(
MCInst &Inst,
unsigned N)
const;
1039 void addRegOrImmOperands(
MCInst &Inst,
unsigned N)
const {
1041 addRegOperands(Inst,
N);
1043 addImmOperands(Inst,
N);
1046 void addRegOrImmWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1047 Modifiers Mods = getModifiers();
1050 addRegOperands(Inst,
N);
1052 addImmOperands(Inst,
N,
false);
1056 void addRegOrImmWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1057 assert(!hasIntModifiers());
1058 addRegOrImmWithInputModsOperands(Inst,
N);
1061 void addRegOrImmWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1062 assert(!hasFPModifiers());
1063 addRegOrImmWithInputModsOperands(Inst,
N);
1066 void addRegWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1067 Modifiers Mods = getModifiers();
1070 addRegOperands(Inst,
N);
1073 void addRegWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1074 assert(!hasIntModifiers());
1075 addRegWithInputModsOperands(Inst,
N);
1078 void addRegWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1079 assert(!hasFPModifiers());
1080 addRegWithInputModsOperands(Inst,
N);
1086 case ImmTyNone:
OS <<
"None";
break;
1087 case ImmTyGDS:
OS <<
"GDS";
break;
1088 case ImmTyLDS:
OS <<
"LDS";
break;
1089 case ImmTyOffen:
OS <<
"Offen";
break;
1090 case ImmTyIdxen:
OS <<
"Idxen";
break;
1091 case ImmTyAddr64:
OS <<
"Addr64";
break;
1092 case ImmTyOffset:
OS <<
"Offset";
break;
1093 case ImmTyInstOffset:
OS <<
"InstOffset";
break;
1094 case ImmTyOffset0:
OS <<
"Offset0";
break;
1095 case ImmTyOffset1:
OS <<
"Offset1";
break;
1096 case ImmTySMEMOffsetMod:
OS <<
"SMEMOffsetMod";
break;
1097 case ImmTyCPol:
OS <<
"CPol";
break;
1098 case ImmTyIndexKey8bit:
OS <<
"index_key";
break;
1099 case ImmTyIndexKey16bit:
OS <<
"index_key";
break;
1100 case ImmTyTFE:
OS <<
"TFE";
break;
1101 case ImmTyD16:
OS <<
"D16";
break;
1102 case ImmTyFORMAT:
OS <<
"FORMAT";
break;
1103 case ImmTyClampSI:
OS <<
"ClampSI";
break;
1104 case ImmTyOModSI:
OS <<
"OModSI";
break;
1105 case ImmTyDPP8:
OS <<
"DPP8";
break;
1106 case ImmTyDppCtrl:
OS <<
"DppCtrl";
break;
1107 case ImmTyDppRowMask:
OS <<
"DppRowMask";
break;
1108 case ImmTyDppBankMask:
OS <<
"DppBankMask";
break;
1109 case ImmTyDppBoundCtrl:
OS <<
"DppBoundCtrl";
break;
1110 case ImmTyDppFI:
OS <<
"DppFI";
break;
1111 case ImmTySDWADstSel:
OS <<
"SDWADstSel";
break;
1112 case ImmTySDWASrc0Sel:
OS <<
"SDWASrc0Sel";
break;
1113 case ImmTySDWASrc1Sel:
OS <<
"SDWASrc1Sel";
break;
1114 case ImmTySDWADstUnused:
OS <<
"SDWADstUnused";
break;
1115 case ImmTyDMask:
OS <<
"DMask";
break;
1116 case ImmTyDim:
OS <<
"Dim";
break;
1117 case ImmTyUNorm:
OS <<
"UNorm";
break;
1118 case ImmTyDA:
OS <<
"DA";
break;
1119 case ImmTyR128A16:
OS <<
"R128A16";
break;
1120 case ImmTyA16:
OS <<
"A16";
break;
1121 case ImmTyLWE:
OS <<
"LWE";
break;
1122 case ImmTyOff:
OS <<
"Off";
break;
1123 case ImmTyExpTgt:
OS <<
"ExpTgt";
break;
1124 case ImmTyExpCompr:
OS <<
"ExpCompr";
break;
1125 case ImmTyExpVM:
OS <<
"ExpVM";
break;
1126 case ImmTyHwreg:
OS <<
"Hwreg";
break;
1127 case ImmTySendMsg:
OS <<
"SendMsg";
break;
1128 case ImmTyInterpSlot:
OS <<
"InterpSlot";
break;
1129 case ImmTyInterpAttr:
OS <<
"InterpAttr";
break;
1130 case ImmTyInterpAttrChan:
OS <<
"InterpAttrChan";
break;
1131 case ImmTyOpSel:
OS <<
"OpSel";
break;
1132 case ImmTyOpSelHi:
OS <<
"OpSelHi";
break;
1133 case ImmTyNegLo:
OS <<
"NegLo";
break;
1134 case ImmTyNegHi:
OS <<
"NegHi";
break;
1135 case ImmTySwizzle:
OS <<
"Swizzle";
break;
1136 case ImmTyGprIdxMode:
OS <<
"GprIdxMode";
break;
1137 case ImmTyHigh:
OS <<
"High";
break;
1138 case ImmTyBLGP:
OS <<
"BLGP";
break;
1139 case ImmTyCBSZ:
OS <<
"CBSZ";
break;
1140 case ImmTyABID:
OS <<
"ABID";
break;
1141 case ImmTyEndpgm:
OS <<
"Endpgm";
break;
1142 case ImmTyWaitVDST:
OS <<
"WaitVDST";
break;
1143 case ImmTyWaitEXP:
OS <<
"WaitEXP";
break;
1144 case ImmTyWaitVAVDst:
OS <<
"WaitVAVDst";
break;
1145 case ImmTyWaitVMVSrc:
OS <<
"WaitVMVSrc";
break;
1146 case ImmTyByteSel:
OS <<
"ByteSel" ;
break;
1154 OS <<
"<register " <<
getReg() <<
" mods: " <<
Reg.Mods <<
'>';
1157 OS <<
'<' << getImm();
1158 if (getImmTy() != ImmTyNone) {
1159 OS <<
" type: "; printImmTy(
OS, getImmTy());
1161 OS <<
" mods: " <<
Imm.Mods <<
'>';
1164 OS <<
'\'' << getToken() <<
'\'';
1167 OS <<
"<expr " << *Expr <<
'>';
1172 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1173 int64_t Val,
SMLoc Loc,
1174 ImmTy
Type = ImmTyNone,
1175 bool IsFPImm =
false) {
1176 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1178 Op->Imm.IsFPImm = IsFPImm;
1179 Op->Imm.Kind = ImmKindTyNone;
1181 Op->Imm.Mods = Modifiers();
1187 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1189 bool HasExplicitEncodingSize =
true) {
1190 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1191 Res->Tok.Data = Str.data();
1192 Res->Tok.Length = Str.size();
1193 Res->StartLoc = Loc;
1198 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1199 unsigned RegNo,
SMLoc S,
1201 auto Op = std::make_unique<AMDGPUOperand>(
Register, AsmParser);
1202 Op->Reg.RegNo = RegNo;
1203 Op->Reg.Mods = Modifiers();
1209 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1211 auto Op = std::make_unique<AMDGPUOperand>(
Expression, AsmParser);
1220 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1231class KernelScopeInfo {
1232 int SgprIndexUnusedMin = -1;
1233 int VgprIndexUnusedMin = -1;
1234 int AgprIndexUnusedMin = -1;
1238 void usesSgprAt(
int i) {
1239 if (i >= SgprIndexUnusedMin) {
1240 SgprIndexUnusedMin = ++i;
1249 void usesVgprAt(
int i) {
1250 if (i >= VgprIndexUnusedMin) {
1251 VgprIndexUnusedMin = ++i;
1256 VgprIndexUnusedMin);
1262 void usesAgprAt(
int i) {
1267 if (i >= AgprIndexUnusedMin) {
1268 AgprIndexUnusedMin = ++i;
1278 VgprIndexUnusedMin);
1285 KernelScopeInfo() =
default;
1291 usesSgprAt(SgprIndexUnusedMin = -1);
1292 usesVgprAt(VgprIndexUnusedMin = -1);
1294 usesAgprAt(AgprIndexUnusedMin = -1);
1298 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1299 unsigned RegWidth) {
1302 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1305 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1308 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1319 unsigned ForcedEncodingSize = 0;
1320 bool ForcedDPP =
false;
1321 bool ForcedSDWA =
false;
1322 KernelScopeInfo KernelScope;
1327#define GET_ASSEMBLER_HEADER
1328#include "AMDGPUGenAsmMatcher.inc"
1333 bool ParseAsAbsoluteExpression(
uint32_t &Ret);
1334 bool OutOfRangeError(
SMRange Range);
1350 bool calculateGPRBlocks(
const FeatureBitset &Features,
bool VCCUsed,
1351 bool FlatScrUsed,
bool XNACKUsed,
1352 std::optional<bool> EnableWavefrontSize32,
1353 unsigned NextFreeVGPR,
SMRange VGPRRange,
1354 unsigned NextFreeSGPR,
SMRange SGPRRange,
1355 unsigned &VGPRBlocks,
unsigned &SGPRBlocks);
1356 bool ParseDirectiveAMDGCNTarget();
1357 bool ParseDirectiveAMDHSACodeObjectVersion();
1358 bool ParseDirectiveAMDHSAKernel();
1360 bool ParseDirectiveAMDKernelCodeT();
1363 bool ParseDirectiveAMDGPUHsaKernel();
1365 bool ParseDirectiveISAVersion();
1366 bool ParseDirectiveHSAMetadata();
1367 bool ParseDirectivePALMetadataBegin();
1368 bool ParseDirectivePALMetadata();
1369 bool ParseDirectiveAMDGPULDS();
1373 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1374 const char *AssemblerDirectiveEnd,
1375 std::string &CollectString);
1377 bool AddNextRegisterToList(
unsigned& Reg,
unsigned& RegWidth,
1378 RegisterKind RegKind,
unsigned Reg1,
SMLoc Loc);
1379 bool ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
1380 unsigned &RegNum,
unsigned &RegWidth,
1381 bool RestoreOnFailure =
false);
1382 bool ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
1383 unsigned &RegNum,
unsigned &RegWidth,
1385 unsigned ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1388 unsigned ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1391 unsigned ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1393 bool ParseRegRange(
unsigned& Num,
unsigned& Width);
1394 unsigned getRegularReg(RegisterKind RegKind,
unsigned RegNum,
unsigned SubReg,
1395 unsigned RegWidth,
SMLoc Loc);
1399 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1400 void initializeGprCountSymbol(RegisterKind RegKind);
1401 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1407 enum AMDGPUMatchResultTy {
1408 Match_PreferE32 = FIRST_TARGET_MATCH_RESULT_TY
1411 OperandMode_Default,
1415 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1423 if (getFeatureBits().
none()) {
1455 initializeGprCountSymbol(IS_VGPR);
1456 initializeGprCountSymbol(IS_SGPR);
1529 bool hasInv2PiInlineImm()
const {
1530 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1533 bool hasFlatOffsets()
const {
1534 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1538 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1541 bool hasSGPR102_SGPR103()
const {
1545 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1547 bool hasIntClamp()
const {
1548 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1551 bool hasPartialNSAEncoding()
const {
1552 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1584 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1585 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1586 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1588 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1589 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1590 bool isForcedDPP()
const {
return ForcedDPP; }
1591 bool isForcedSDWA()
const {
return ForcedSDWA; }
1593 StringRef getMatchedVariantName()
const;
1595 std::unique_ptr<AMDGPUOperand>
parseRegister(
bool RestoreOnFailure =
false);
1597 bool RestoreOnFailure);
1600 SMLoc &EndLoc)
override;
1603 unsigned Kind)
override;
1607 bool MatchingInlineAsm)
override;
1610 OperandMode Mode = OperandMode_Default);
1618 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1622 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1623 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1627 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1628 bool (*ConvertResult)(int64_t &) =
nullptr);
1632 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1641 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1642 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1643 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1644 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1645 bool parseSP3NegModifier();
1647 bool HasLit =
false);
1650 bool HasLit =
false);
1652 bool AllowImm =
true);
1654 bool AllowImm =
true);
1659 AMDGPUOperand::ImmTy ImmTy);
1670 ParseStatus parseSymbolicOrNumericFormat(int64_t &Format);
1675 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1676 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt,
StringRef FormatStr,
SMLoc Loc);
1680 bool parseCnt(int64_t &IntVal);
1683 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1687 bool parseDelay(int64_t &Delay);
1693 struct OperandInfoTy {
1696 bool IsSymbolic =
false;
1697 bool IsDefined =
false;
1699 OperandInfoTy(int64_t Val) : Val(Val) {}
1702 struct StructuredOpField : OperandInfoTy {
1706 bool IsDefined =
false;
1711 virtual ~StructuredOpField() =
default;
1713 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1714 Parser.Error(Loc,
"invalid " +
Desc +
": " + Err);
1718 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1720 return Error(Parser,
"not supported on this GPU");
1722 return Error(Parser,
"only " +
Twine(Width) +
"-bit values are legal");
1730 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1731 bool validateSendMsg(
const OperandInfoTy &Msg,
1732 const OperandInfoTy &
Op,
1733 const OperandInfoTy &Stream);
1736 OperandInfoTy &Width);
1742 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1747 bool SearchMandatoryLiterals =
false)
const;
1756 bool validateSOPLiteral(
const MCInst &Inst)
const;
1758 bool validateVOPDRegBankConstraints(
const MCInst &Inst,
1760 bool validateIntClampSupported(
const MCInst &Inst);
1761 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1762 bool validateMIMGGatherDMask(
const MCInst &Inst);
1764 bool validateMIMGDataSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1765 bool validateMIMGAddrSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1766 bool validateMIMGD16(
const MCInst &Inst);
1767 bool validateMIMGMSAA(
const MCInst &Inst);
1768 bool validateOpSel(
const MCInst &Inst);
1771 bool validateVccOperand(
unsigned Reg)
const;
1776 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1777 bool validateVGPRAlign(
const MCInst &Inst)
const;
1781 bool validateDivScale(
const MCInst &Inst);
1784 const SMLoc &IDLoc);
1786 const unsigned CPol);
1789 std::optional<StringRef> validateLdsDirect(
const MCInst &Inst);
1790 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1791 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1792 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1793 unsigned findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1819 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1821 SMLoc getLoc()
const;
1825 void onBeginOfFile()
override;
1826 bool parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc)
override;
1837 bool parseSwizzleOperand(int64_t &
Op,
1838 const unsigned MinVal,
1839 const unsigned MaxVal,
1842 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1843 const unsigned MinVal,
1844 const unsigned MaxVal,
1847 bool parseSwizzleOffset(int64_t &Imm);
1848 bool parseSwizzleMacro(int64_t &Imm);
1849 bool parseSwizzleQuadPerm(int64_t &Imm);
1850 bool parseSwizzleBitmaskPerm(int64_t &Imm);
1851 bool parseSwizzleBroadcast(int64_t &Imm);
1852 bool parseSwizzleSwap(int64_t &Imm);
1853 bool parseSwizzleReverse(int64_t &Imm);
1856 int64_t parseGPRIdxMacro();
1864 OptionalImmIndexMap &OptionalIdx);
1872 OptionalImmIndexMap &OptionalIdx);
1874 OptionalImmIndexMap &OptionalIdx);
1879 bool parseDimId(
unsigned &Encoding);
1881 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1885 int64_t parseDPPCtrlSel(
StringRef Ctrl);
1886 int64_t parseDPPCtrlPerm();
1892 bool IsDPP8 =
false);
1898 AMDGPUOperand::ImmTy
Type);
1907 bool SkipDstVcc =
false,
1908 bool SkipSrcVcc =
false);
1921 return &APFloat::IEEEsingle();
1923 return &APFloat::IEEEdouble();
1925 return &APFloat::IEEEhalf();
1958 return &APFloat::IEEEsingle();
1964 return &APFloat::IEEEdouble();
1973 return &APFloat::IEEEhalf();
1981 return &APFloat::BFloat();
1996 APFloat::rmNearestTiesToEven,
1999 if (
Status != APFloat::opOK &&
2001 ((
Status & APFloat::opOverflow) != 0 ||
2002 (
Status & APFloat::opUnderflow) != 0)) {
2025bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2035 if (!isImmTy(ImmTyNone)) {
2046 if (type == MVT::f64 || type == MVT::i64) {
2048 AsmParser->hasInv2PiInlineImm());
2070 APFloat::rmNearestTiesToEven, &Lost);
2077 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2079 AsmParser->hasInv2PiInlineImm());
2084 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2085 AsmParser->hasInv2PiInlineImm());
2089 if (type == MVT::f64 || type == MVT::i64) {
2091 AsmParser->hasInv2PiInlineImm());
2100 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2101 type, AsmParser->hasInv2PiInlineImm());
2105 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2106 AsmParser->hasInv2PiInlineImm());
2109bool AMDGPUOperand::isLiteralImm(
MVT type)
const {
2111 if (!isImmTy(ImmTyNone)) {
2118 if (type == MVT::f64 && hasFPModifiers()) {
2135 if (type == MVT::f64) {
2140 if (type == MVT::i64) {
2153 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2154 : (type == MVT::v2i16) ? MVT::f32
2155 : (type == MVT::v2f32) ? MVT::f32
2162bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2163 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2166bool AMDGPUOperand::isVRegWithInputMods()
const {
2167 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2169 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2170 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2173template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2174 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2175 : AMDGPU::VGPR_16_Lo128RegClassID);
2178bool AMDGPUOperand::isSDWAOperand(
MVT type)
const {
2179 if (AsmParser->isVI())
2181 else if (AsmParser->isGFX9Plus())
2182 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2187bool AMDGPUOperand::isSDWAFP16Operand()
const {
2188 return isSDWAOperand(MVT::f16);
2191bool AMDGPUOperand::isSDWAFP32Operand()
const {
2192 return isSDWAOperand(MVT::f32);
2195bool AMDGPUOperand::isSDWAInt16Operand()
const {
2196 return isSDWAOperand(MVT::i16);
2199bool AMDGPUOperand::isSDWAInt32Operand()
const {
2200 return isSDWAOperand(MVT::i32);
2203bool AMDGPUOperand::isBoolReg()
const {
2204 auto FB = AsmParser->getFeatureBits();
2205 return isReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrc_b64()) ||
2206 (FB[AMDGPU::FeatureWavefrontSize32] && isSCSrc_b32()));
2211 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2226void AMDGPUOperand::addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2234 addLiteralImmOperand(Inst,
Imm.Val,
2236 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2238 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2244void AMDGPUOperand::addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2245 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2250 if (ApplyModifiers) {
2253 Val = applyInputFPModifiers(Val,
Size);
2257 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2267 AsmParser->hasInv2PiInlineImm())) {
2276 if (
Literal.getLoBits(32) != 0) {
2277 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(Inst.
getLoc(),
2278 "Can't encode literal as exact 64-bit floating-point operand. "
2279 "Low 32-bits will be set to zero");
2280 Val &= 0xffffffff00000000u;
2284 setImmKindLiteral();
2300 if (AsmParser->hasInv2PiInlineImm() &&
Literal == 0x3fc45f306725feed) {
2306 setImmKindLiteral();
2342 APFloat::rmNearestTiesToEven, &lost);
2346 uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2349 setImmKindMandatoryLiteral();
2351 setImmKindLiteral();
2382 AsmParser->hasInv2PiInlineImm())) {
2389 setImmKindLiteral();
2407 setImmKindLiteral();
2421 setImmKindLiteral();
2430 AsmParser->hasInv2PiInlineImm())) {
2437 setImmKindLiteral();
2446 AsmParser->hasInv2PiInlineImm())) {
2453 setImmKindLiteral();
2467 AsmParser->hasInv2PiInlineImm()));
2477 AsmParser->hasInv2PiInlineImm()));
2485 setImmKindMandatoryLiteral();
2489 setImmKindMandatoryLiteral();
2496void AMDGPUOperand::addRegOperands(
MCInst &Inst,
unsigned N)
const {
2500bool AMDGPUOperand::isInlineValue()
const {
2509 if (Is == IS_VGPR) {
2513 return AMDGPU::VGPR_32RegClassID;
2515 return AMDGPU::VReg_64RegClassID;
2517 return AMDGPU::VReg_96RegClassID;
2519 return AMDGPU::VReg_128RegClassID;
2521 return AMDGPU::VReg_160RegClassID;
2523 return AMDGPU::VReg_192RegClassID;
2525 return AMDGPU::VReg_224RegClassID;
2527 return AMDGPU::VReg_256RegClassID;
2529 return AMDGPU::VReg_288RegClassID;
2531 return AMDGPU::VReg_320RegClassID;
2533 return AMDGPU::VReg_352RegClassID;
2535 return AMDGPU::VReg_384RegClassID;
2537 return AMDGPU::VReg_512RegClassID;
2539 return AMDGPU::VReg_1024RegClassID;
2541 }
else if (Is == IS_TTMP) {
2545 return AMDGPU::TTMP_32RegClassID;
2547 return AMDGPU::TTMP_64RegClassID;
2549 return AMDGPU::TTMP_128RegClassID;
2551 return AMDGPU::TTMP_256RegClassID;
2553 return AMDGPU::TTMP_512RegClassID;
2555 }
else if (Is == IS_SGPR) {
2559 return AMDGPU::SGPR_32RegClassID;
2561 return AMDGPU::SGPR_64RegClassID;
2563 return AMDGPU::SGPR_96RegClassID;
2565 return AMDGPU::SGPR_128RegClassID;
2567 return AMDGPU::SGPR_160RegClassID;
2569 return AMDGPU::SGPR_192RegClassID;
2571 return AMDGPU::SGPR_224RegClassID;
2573 return AMDGPU::SGPR_256RegClassID;
2575 return AMDGPU::SGPR_288RegClassID;
2577 return AMDGPU::SGPR_320RegClassID;
2579 return AMDGPU::SGPR_352RegClassID;
2581 return AMDGPU::SGPR_384RegClassID;
2583 return AMDGPU::SGPR_512RegClassID;
2585 }
else if (Is == IS_AGPR) {
2589 return AMDGPU::AGPR_32RegClassID;
2591 return AMDGPU::AReg_64RegClassID;
2593 return AMDGPU::AReg_96RegClassID;
2595 return AMDGPU::AReg_128RegClassID;
2597 return AMDGPU::AReg_160RegClassID;
2599 return AMDGPU::AReg_192RegClassID;
2601 return AMDGPU::AReg_224RegClassID;
2603 return AMDGPU::AReg_256RegClassID;
2605 return AMDGPU::AReg_288RegClassID;
2607 return AMDGPU::AReg_320RegClassID;
2609 return AMDGPU::AReg_352RegClassID;
2611 return AMDGPU::AReg_384RegClassID;
2613 return AMDGPU::AReg_512RegClassID;
2615 return AMDGPU::AReg_1024RegClassID;
2623 .
Case(
"exec", AMDGPU::EXEC)
2624 .
Case(
"vcc", AMDGPU::VCC)
2625 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2626 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2627 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2628 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2629 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2630 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2631 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2632 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2633 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2634 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2635 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2636 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2637 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2638 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2639 .
Case(
"m0", AMDGPU::M0)
2640 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2641 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2642 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2643 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2644 .
Case(
"scc", AMDGPU::SRC_SCC)
2645 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2646 .
Case(
"tba", AMDGPU::TBA)
2647 .
Case(
"tma", AMDGPU::TMA)
2648 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2649 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2650 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2651 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2652 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2653 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2654 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2655 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2656 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2657 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2658 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2659 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2660 .
Case(
"pc", AMDGPU::PC_REG)
2661 .
Case(
"null", AMDGPU::SGPR_NULL)
2665bool AMDGPUAsmParser::ParseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
2666 SMLoc &EndLoc,
bool RestoreOnFailure) {
2667 auto R = parseRegister();
2668 if (!R)
return true;
2670 RegNo =
R->getReg();
2671 StartLoc =
R->getStartLoc();
2672 EndLoc =
R->getEndLoc();
2678 return ParseRegister(Reg, StartLoc, EndLoc,
false);
2683 bool Result = ParseRegister(Reg, StartLoc, EndLoc,
true);
2684 bool PendingErrors = getParser().hasPendingError();
2685 getParser().clearPendingErrors();
2693bool AMDGPUAsmParser::AddNextRegisterToList(
unsigned &Reg,
unsigned &RegWidth,
2694 RegisterKind RegKind,
unsigned Reg1,
2698 if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2703 if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2704 Reg = AMDGPU::FLAT_SCR;
2708 if (Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2709 Reg = AMDGPU::XNACK_MASK;
2713 if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2718 if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2723 if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2728 Error(Loc,
"register does not fit in the list");
2734 if (Reg1 != Reg + RegWidth / 32) {
2735 Error(Loc,
"registers in a list must have consecutive indices");
2753 {{
"ttmp"}, IS_TTMP},
2759 return Kind == IS_VGPR ||
2767 if (Str.starts_with(Reg.Name))
2773 return !Str.getAsInteger(10, Num);
2777AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2794 if (!RegSuffix.
empty()) {
2812AMDGPUAsmParser::isRegister()
2814 return isRegister(getToken(), peekToken());
2817unsigned AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2818 unsigned SubReg,
unsigned RegWidth,
2822 unsigned AlignSize = 1;
2823 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2829 if (RegNum % AlignSize != 0) {
2830 Error(Loc,
"invalid register alignment");
2831 return AMDGPU::NoRegister;
2834 unsigned RegIdx = RegNum / AlignSize;
2837 Error(Loc,
"invalid or unsupported register size");
2838 return AMDGPU::NoRegister;
2844 Error(Loc,
"register index is out of range");
2845 return AMDGPU::NoRegister;
2855 assert(Reg &&
"Invalid subregister!");
2861bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth) {
2862 int64_t RegLo, RegHi;
2866 SMLoc FirstIdxLoc = getLoc();
2869 if (!parseExpr(RegLo))
2873 SecondIdxLoc = getLoc();
2874 if (!parseExpr(RegHi))
2883 if (!isUInt<32>(RegLo)) {
2884 Error(FirstIdxLoc,
"invalid register index");
2888 if (!isUInt<32>(RegHi)) {
2889 Error(SecondIdxLoc,
"invalid register index");
2893 if (RegLo > RegHi) {
2894 Error(FirstIdxLoc,
"first register index should not exceed second index");
2898 Num =
static_cast<unsigned>(RegLo);
2899 RegWidth = 32 * ((RegHi - RegLo) + 1);
2903unsigned AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2904 unsigned &RegNum,
unsigned &RegWidth,
2911 RegKind = IS_SPECIAL;
2918unsigned AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2919 unsigned &RegNum,
unsigned &RegWidth,
2923 auto Loc = getLoc();
2927 Error(Loc,
"invalid register name");
2928 return AMDGPU::NoRegister;
2936 unsigned SubReg = NoSubRegister;
2937 if (!RegSuffix.
empty()) {
2949 Error(Loc,
"invalid register index");
2950 return AMDGPU::NoRegister;
2955 if (!ParseRegRange(RegNum, RegWidth))
2956 return AMDGPU::NoRegister;
2959 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
2962unsigned AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
2965 unsigned Reg = AMDGPU::NoRegister;
2966 auto ListLoc = getLoc();
2969 "expected a register or a list of registers")) {
2970 return AMDGPU::NoRegister;
2975 auto Loc = getLoc();
2976 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth))
2977 return AMDGPU::NoRegister;
2978 if (RegWidth != 32) {
2979 Error(Loc,
"expected a single 32-bit register");
2980 return AMDGPU::NoRegister;
2984 RegisterKind NextRegKind;
2985 unsigned NextReg, NextRegNum, NextRegWidth;
2988 if (!ParseAMDGPURegister(NextRegKind, NextReg,
2989 NextRegNum, NextRegWidth,
2991 return AMDGPU::NoRegister;
2993 if (NextRegWidth != 32) {
2994 Error(Loc,
"expected a single 32-bit register");
2995 return AMDGPU::NoRegister;
2997 if (NextRegKind != RegKind) {
2998 Error(Loc,
"registers in a list must be of the same kind");
2999 return AMDGPU::NoRegister;
3001 if (!AddNextRegisterToList(Reg, RegWidth, RegKind, NextReg, Loc))
3002 return AMDGPU::NoRegister;
3006 "expected a comma or a closing square bracket")) {
3007 return AMDGPU::NoRegister;
3011 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3016bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
3017 unsigned &RegNum,
unsigned &RegWidth,
3019 auto Loc = getLoc();
3020 Reg = AMDGPU::NoRegister;
3023 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3024 if (Reg == AMDGPU::NoRegister)
3025 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3027 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3031 if (Reg == AMDGPU::NoRegister) {
3032 assert(Parser.hasPendingError());
3036 if (!subtargetHasRegister(*
TRI, Reg)) {
3037 if (Reg == AMDGPU::SGPR_NULL) {
3038 Error(Loc,
"'null' operand is not supported on this GPU");
3040 Error(Loc,
"register not available on this GPU");
3048bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
3049 unsigned &RegNum,
unsigned &RegWidth,
3050 bool RestoreOnFailure ) {
3051 Reg = AMDGPU::NoRegister;
3054 if (ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, Tokens)) {
3055 if (RestoreOnFailure) {
3056 while (!Tokens.
empty()) {
3065std::optional<StringRef>
3066AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3069 return StringRef(
".amdgcn.next_free_vgpr");
3071 return StringRef(
".amdgcn.next_free_sgpr");
3073 return std::nullopt;
3077void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3078 auto SymbolName = getGprCountSymbolName(RegKind);
3079 assert(SymbolName &&
"initializing invalid register kind");
3080 MCSymbol *
Sym = getContext().getOrCreateSymbol(*SymbolName);
3084bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3085 unsigned DwordRegIndex,
3086 unsigned RegWidth) {
3091 auto SymbolName = getGprCountSymbolName(RegKind);
3094 MCSymbol *
Sym = getContext().getOrCreateSymbol(*SymbolName);
3096 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3099 if (!
Sym->isVariable())
3100 return !
Error(getLoc(),
3101 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3102 if (!
Sym->getVariableValue(
false)->evaluateAsAbsolute(OldCount))
3105 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3107 if (OldCount <= NewMax)
3113std::unique_ptr<AMDGPUOperand>
3114AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3115 const auto &Tok = getToken();
3116 SMLoc StartLoc = Tok.getLoc();
3117 SMLoc EndLoc = Tok.getEndLoc();
3118 RegisterKind RegKind;
3119 unsigned Reg, RegNum, RegWidth;
3121 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth)) {
3125 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3128 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3129 return AMDGPUOperand::CreateReg(
this, Reg, StartLoc, EndLoc);
3133 bool HasSP3AbsModifier,
bool HasLit) {
3141 HasLit = trySkipId(
"lit");
3153 const auto& Tok = getToken();
3154 const auto& NextTok = peekToken();
3157 bool Negate =
false;
3165 AMDGPUOperand::Modifiers Mods;
3176 APFloat RealVal(APFloat::IEEEdouble());
3177 auto roundMode = APFloat::rmNearestTiesToEven;
3178 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3181 RealVal.changeSign();
3184 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3185 AMDGPUOperand::ImmTyNone,
true));
3186 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3187 Op.setModifiers(Mods);
3196 if (HasSP3AbsModifier) {
3205 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3208 if (Parser.parseExpression(Expr))
3212 if (Expr->evaluateAsAbsolute(IntVal)) {
3213 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3214 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3215 Op.setModifiers(Mods);
3219 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3232 if (
auto R = parseRegister()) {
3241 bool HasSP3AbsMod,
bool HasLit) {
3247 return parseImm(
Operands, HasSP3AbsMod, HasLit);
3251AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3254 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3260AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3265AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3266 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3270AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3271 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3288AMDGPUAsmParser::isModifier() {
3292 peekTokens(NextToken);
3294 return isOperandModifier(Tok, NextToken[0]) ||
3295 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3296 isOpcodeModifierWithVal(Tok, NextToken[0]);
3322AMDGPUAsmParser::parseSP3NegModifier() {
3325 peekTokens(NextToken);
3328 (isRegister(NextToken[0], NextToken[1]) ||
3330 isId(NextToken[0],
"abs"))) {
3348 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3350 SP3Neg = parseSP3NegModifier();
3353 Neg = trySkipId(
"neg");
3355 return Error(Loc,
"expected register or immediate");
3359 Abs = trySkipId(
"abs");
3363 Lit = trySkipId(
"lit");
3370 return Error(Loc,
"expected register or immediate");
3374 Res = parseRegOrImm(
Operands, SP3Abs, Lit);
3381 if (Lit && !
Operands.back()->isImm())
3382 Error(Loc,
"expected immediate with lit modifier");
3384 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3393 AMDGPUOperand::Modifiers Mods;
3394 Mods.Abs = Abs || SP3Abs;
3395 Mods.Neg = Neg || SP3Neg;
3398 if (Mods.hasFPModifiers() || Lit) {
3399 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3401 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3402 Op.setModifiers(Mods);
3410 bool Sext = trySkipId(
"sext");
3411 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3426 AMDGPUOperand::Modifiers Mods;
3429 if (Mods.hasIntModifiers()) {
3430 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3432 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3433 Op.setModifiers(Mods);
3440 return parseRegOrImmWithFPInputMods(
Operands,
false);
3444 return parseRegOrImmWithIntInputMods(
Operands,
false);
3448 auto Loc = getLoc();
3449 if (trySkipId(
"off")) {
3450 Operands.push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3451 AMDGPUOperand::ImmTyOff,
false));
3458 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3460 Operands.push_back(std::move(Reg));
3467unsigned AMDGPUAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
3474 return Match_InvalidOperand;
3476 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3477 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3482 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3483 return Match_InvalidOperand;
3487 return Match_Success;
3491 static const unsigned Variants[] = {
3502 if (isForcedDPP() && isForcedVOP3()) {
3506 if (getForcedEncodingSize() == 32) {
3511 if (isForcedVOP3()) {
3516 if (isForcedSDWA()) {
3522 if (isForcedDPP()) {
3530StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3531 if (isForcedDPP() && isForcedVOP3())
3534 if (getForcedEncodingSize() == 32)
3549unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3553 case AMDGPU::FLAT_SCR:
3555 case AMDGPU::VCC_LO:
3556 case AMDGPU::VCC_HI:
3563 return AMDGPU::NoRegister;
3570bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3571 unsigned OpIdx)
const {
3581 int64_t Val = MO.
getImm();
3630unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3636 case AMDGPU::V_LSHLREV_B64_e64:
3637 case AMDGPU::V_LSHLREV_B64_gfx10:
3638 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3639 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3640 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3641 case AMDGPU::V_LSHRREV_B64_e64:
3642 case AMDGPU::V_LSHRREV_B64_gfx10:
3643 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3644 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3645 case AMDGPU::V_ASHRREV_I64_e64:
3646 case AMDGPU::V_ASHRREV_I64_gfx10:
3647 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3648 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3649 case AMDGPU::V_LSHL_B64_e64:
3650 case AMDGPU::V_LSHR_B64_e64:
3651 case AMDGPU::V_ASHR_I64_e64:
3664 bool AddMandatoryLiterals =
false) {
3670 int16_t ImmDeferredIdx =
3687bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3690 return !isInlineConstant(Inst, OpIdx);
3691 }
else if (MO.
isReg()) {
3698 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3710 const unsigned Opcode = Inst.
getOpcode();
3711 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3714 if (!LaneSelOp.
isReg())
3717 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3720bool AMDGPUAsmParser::validateConstantBusLimitations(
3722 const unsigned Opcode = Inst.
getOpcode();
3724 unsigned LastSGPR = AMDGPU::NoRegister;
3725 unsigned ConstantBusUseCount = 0;
3726 unsigned NumLiterals = 0;
3727 unsigned LiteralSize;
3729 if (!(
Desc.TSFlags &
3745 unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3746 if (SGPRUsed != AMDGPU::NoRegister) {
3747 SGPRsUsed.
insert(SGPRUsed);
3748 ++ConstantBusUseCount;
3753 for (
int OpIdx : OpIndices) {
3758 if (usesConstantBus(Inst, OpIdx)) {
3767 if (SGPRsUsed.
insert(LastSGPR).second) {
3768 ++ConstantBusUseCount;
3788 if (NumLiterals == 0) {
3791 }
else if (LiteralSize !=
Size) {
3797 ConstantBusUseCount += NumLiterals;
3799 if (ConstantBusUseCount <= getConstantBusLimit(Opcode))
3805 Error(Loc,
"invalid operand (violates constant bus restrictions)");
3809bool AMDGPUAsmParser::validateVOPDRegBankConstraints(
3812 const unsigned Opcode = Inst.
getOpcode();
3818 auto getVRegIdx = [&](
unsigned,
unsigned OperandIdx) {
3826 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12;
3829 auto InvalidCompOprIdx =
3830 InstInfo.getInvalidCompOperandIndex(getVRegIdx, SkipSrc);
3831 if (!InvalidCompOprIdx)
3834 auto CompOprIdx = *InvalidCompOprIdx;
3836 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3837 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3840 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
3841 if (CompOprIdx == VOPD::Component::DST) {
3842 Error(Loc,
"one dst register must be even and the other odd");
3844 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3846 " operands must use different VGPR banks");
3852bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
3869bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
3870 const SMLoc &IDLoc) {
3888 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
3893 bool IsPackedD16 =
false;
3898 IsPackedD16 = D16Idx >= 0;
3900 DataSize = (DataSize + 1) / 2;
3903 if ((VDataSize / 4) == DataSize + TFESize)
3908 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
3910 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
3912 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
3916bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst,
3917 const SMLoc &IDLoc) {
3930 : AMDGPU::OpName::rsrc;
3937 assert(SrsrcIdx > VAddr0Idx);
3940 if (BaseOpcode->
BVH) {
3941 if (IsA16 == BaseOpcode->
A16)
3943 Error(IDLoc,
"image address size does not match a16");
3949 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
3950 unsigned ActualAddrSize =
3951 IsNSA ? SrsrcIdx - VAddr0Idx
3954 unsigned ExpectedAddrSize =
3958 if (hasPartialNSAEncoding() &&
3961 int VAddrLastIdx = SrsrcIdx - 1;
3962 unsigned VAddrLastSize =
3965 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
3968 if (ExpectedAddrSize > 12)
3969 ExpectedAddrSize = 16;
3974 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
3978 if (ActualAddrSize == ExpectedAddrSize)
3981 Error(IDLoc,
"image address size does not match dim and a16");
3985bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
3992 if (!
Desc.mayLoad() || !
Desc.mayStore())
4002 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4005bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4021 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4024bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4035 if (!BaseOpcode->
MSAA)
4044 return DimInfo->
MSAA;
4050 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4051 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4052 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4062bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4086 Error(ErrLoc,
"source operand must be a VGPR");
4090bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4095 if (Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4109 "source operand must be either a VGPR or an inline constant");
4116bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4122 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4129 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4131 "inline constants are not allowed for this operand");
4138bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4156 if (Src2Reg == DstReg)
4160 if (
TRI->getRegClass(
Desc.operands()[0].RegClass).getSizeInBits() <= 128)
4163 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4165 "source 2 operand must not partially overlap with dst");
4172bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4176 case V_DIV_SCALE_F32_gfx6_gfx7:
4177 case V_DIV_SCALE_F32_vi:
4178 case V_DIV_SCALE_F32_gfx10:
4179 case V_DIV_SCALE_F64_gfx6_gfx7:
4180 case V_DIV_SCALE_F64_vi:
4181 case V_DIV_SCALE_F64_gfx10:
4187 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4188 AMDGPU::OpName::src2_modifiers,
4189 AMDGPU::OpName::src2_modifiers}) {
4200bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4220 case AMDGPU::V_SUBREV_F32_e32:
4221 case AMDGPU::V_SUBREV_F32_e64:
4222 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4223 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4224 case AMDGPU::V_SUBREV_F32_e32_vi:
4225 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4226 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4227 case AMDGPU::V_SUBREV_F32_e64_vi:
4229 case AMDGPU::V_SUBREV_CO_U32_e32:
4230 case AMDGPU::V_SUBREV_CO_U32_e64:
4231 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4232 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4234 case AMDGPU::V_SUBBREV_U32_e32:
4235 case AMDGPU::V_SUBBREV_U32_e64:
4236 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4237 case AMDGPU::V_SUBBREV_U32_e32_vi:
4238 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4239 case AMDGPU::V_SUBBREV_U32_e64_vi:
4241 case AMDGPU::V_SUBREV_U32_e32:
4242 case AMDGPU::V_SUBREV_U32_e64:
4243 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4244 case AMDGPU::V_SUBREV_U32_e32_vi:
4245 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4246 case AMDGPU::V_SUBREV_U32_e64_vi:
4248 case AMDGPU::V_SUBREV_F16_e32:
4249 case AMDGPU::V_SUBREV_F16_e64:
4250 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4251 case AMDGPU::V_SUBREV_F16_e32_vi:
4252 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4253 case AMDGPU::V_SUBREV_F16_e64_vi:
4255 case AMDGPU::V_SUBREV_U16_e32:
4256 case AMDGPU::V_SUBREV_U16_e64:
4257 case AMDGPU::V_SUBREV_U16_e32_vi:
4258 case AMDGPU::V_SUBREV_U16_e64_vi:
4260 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4261 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4262 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4264 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4265 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4267 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4268 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4270 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4271 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4273 case AMDGPU::V_LSHRREV_B32_e32:
4274 case AMDGPU::V_LSHRREV_B32_e64:
4275 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4276 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4277 case AMDGPU::V_LSHRREV_B32_e32_vi:
4278 case AMDGPU::V_LSHRREV_B32_e64_vi:
4279 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4280 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4282 case AMDGPU::V_ASHRREV_I32_e32:
4283 case AMDGPU::V_ASHRREV_I32_e64:
4284 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4285 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4286 case AMDGPU::V_ASHRREV_I32_e32_vi:
4287 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4288 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4289 case AMDGPU::V_ASHRREV_I32_e64_vi:
4291 case AMDGPU::V_LSHLREV_B32_e32:
4292 case AMDGPU::V_LSHLREV_B32_e64:
4293 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4294 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4295 case AMDGPU::V_LSHLREV_B32_e32_vi:
4296 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4297 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4298 case AMDGPU::V_LSHLREV_B32_e64_vi:
4300 case AMDGPU::V_LSHLREV_B16_e32:
4301 case AMDGPU::V_LSHLREV_B16_e64:
4302 case AMDGPU::V_LSHLREV_B16_e32_vi:
4303 case AMDGPU::V_LSHLREV_B16_e64_vi:
4304 case AMDGPU::V_LSHLREV_B16_gfx10:
4306 case AMDGPU::V_LSHRREV_B16_e32:
4307 case AMDGPU::V_LSHRREV_B16_e64:
4308 case AMDGPU::V_LSHRREV_B16_e32_vi:
4309 case AMDGPU::V_LSHRREV_B16_e64_vi:
4310 case AMDGPU::V_LSHRREV_B16_gfx10:
4312 case AMDGPU::V_ASHRREV_I16_e32:
4313 case AMDGPU::V_ASHRREV_I16_e64:
4314 case AMDGPU::V_ASHRREV_I16_e32_vi:
4315 case AMDGPU::V_ASHRREV_I16_e64_vi:
4316 case AMDGPU::V_ASHRREV_I16_gfx10:
4318 case AMDGPU::V_LSHLREV_B64_e64:
4319 case AMDGPU::V_LSHLREV_B64_gfx10:
4320 case AMDGPU::V_LSHLREV_B64_vi:
4322 case AMDGPU::V_LSHRREV_B64_e64:
4323 case AMDGPU::V_LSHRREV_B64_gfx10:
4324 case AMDGPU::V_LSHRREV_B64_vi:
4326 case AMDGPU::V_ASHRREV_I64_e64:
4327 case AMDGPU::V_ASHRREV_I64_gfx10:
4328 case AMDGPU::V_ASHRREV_I64_vi:
4330 case AMDGPU::V_PK_LSHLREV_B16:
4331 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4332 case AMDGPU::V_PK_LSHLREV_B16_vi:
4334 case AMDGPU::V_PK_LSHRREV_B16:
4335 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4336 case AMDGPU::V_PK_LSHRREV_B16_vi:
4337 case AMDGPU::V_PK_ASHRREV_I16:
4338 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4339 case AMDGPU::V_PK_ASHRREV_I16_vi:
4346std::optional<StringRef>
4347AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst) {
4349 using namespace SIInstrFlags;
4350 const unsigned Opcode = Inst.
getOpcode();
4356 if ((
Desc.TSFlags & Enc) == 0)
4357 return std::nullopt;
4359 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4364 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4367 return StringRef(
"lds_direct is not supported on this GPU");
4370 return StringRef(
"lds_direct cannot be used with this instruction");
4372 if (SrcName != OpName::src0)
4373 return StringRef(
"lds_direct may be used as src0 only");
4377 return std::nullopt;
4381 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4382 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4383 if (
Op.isFlatOffset())
4384 return Op.getStartLoc();
4389bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4398 return validateFlatOffset(Inst,
Operands);
4401 return validateSMEMOffset(Inst,
Operands);
4406 const unsigned OffsetSize = 24;
4407 if (!
isIntN(OffsetSize,
Op.getImm())) {
4409 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit signed offset");
4413 const unsigned OffsetSize = 16;
4414 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4416 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit unsigned offset");
4423bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4434 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4436 "flat offset modifier is not supported on this GPU");
4443 bool AllowNegative =
4446 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4448 Twine(
"expected a ") +
4449 (AllowNegative ?
Twine(OffsetSize) +
"-bit signed offset"
4450 :
Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4459 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4460 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4461 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4462 return Op.getStartLoc();
4467bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4493 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4494 :
"expected a 21-bit signed offset");
4499bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst)
const {
4508 const int OpIndices[] = { Src0Idx, Src1Idx };
4510 unsigned NumExprs = 0;
4511 unsigned NumLiterals = 0;
4514 for (
int OpIdx : OpIndices) {
4515 if (OpIdx == -1)
break;
4520 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4522 if (NumLiterals == 0 || LiteralValue !=
Value) {
4526 }
else if (MO.
isExpr()) {
4532 return NumLiterals + NumExprs <= 1;
4535bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4549 if (OpSelIdx != -1) {
4554 if (OpSelHiIdx != -1) {
4572bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst,
int OpName) {
4597 int SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4598 AMDGPU::OpName::src1_modifiers,
4599 AMDGPU::OpName::src2_modifiers};
4601 for (
unsigned i = 0; i < 3; ++i) {
4611bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4615 if (DppCtrlIdx >= 0) {
4622 Error(S,
"DP ALU dpp only supports row_newbcast");
4628 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4638 Error(S,
"invalid operand for instruction");
4643 "src1 immediate operand invalid for instruction");
4653bool AMDGPUAsmParser::validateVccOperand(
unsigned Reg)
const {
4654 auto FB = getFeatureBits();
4655 return (FB[AMDGPU::FeatureWavefrontSize64] && Reg == AMDGPU::VCC) ||
4656 (FB[AMDGPU::FeatureWavefrontSize32] &&
Reg == AMDGPU::VCC_LO);
4660bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
4666 !HasMandatoryLiteral && !
isVOPD(Opcode))
4671 unsigned NumExprs = 0;
4672 unsigned NumLiterals = 0;
4675 for (
int OpIdx : OpIndices) {
4685 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4691 if (!IsValid32Op && !isInt<32>(
Value) && !isUInt<32>(
Value)) {
4692 Error(getLitLoc(
Operands),
"invalid operand for instruction");
4696 if (IsFP64 && IsValid32Op)
4699 if (NumLiterals == 0 || LiteralValue !=
Value) {
4703 }
else if (MO.
isExpr()) {
4707 NumLiterals += NumExprs;
4712 if (!HasMandatoryLiteral && !getFeatureBits()[FeatureVOP3Literal]) {
4713 Error(getLitLoc(
Operands),
"literal operands are not supported");
4717 if (NumLiterals > 1) {
4718 Error(getLitLoc(
Operands,
true),
"only one unique literal operand is allowed");
4736 unsigned Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
4737 auto Reg = Sub ? Sub :
Op.getReg();
4739 return AGPR32.
contains(Reg) ? 1 : 0;
4742bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
4750 : AMDGPU::OpName::vdata;
4758 if (Data2Areg >= 0 && Data2Areg != DataAreg)
4762 auto FB = getFeatureBits();
4763 if (FB[AMDGPU::FeatureGFX90AInsts]) {
4764 if (DataAreg < 0 || DstAreg < 0)
4766 return DstAreg == DataAreg;
4769 return DstAreg < 1 && DataAreg < 1;
4772bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
4773 auto FB = getFeatureBits();
4774 if (!FB[AMDGPU::FeatureGFX90AInsts])
4785 unsigned Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
4789 if (VGPR32.
contains(Sub) && ((Sub - AMDGPU::VGPR0) & 1))
4791 if (AGPR32.
contains(Sub) && ((Sub - AMDGPU::AGPR0) & 1))
4799 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4800 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4802 return Op.getStartLoc();
4807bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
4817 auto FB = getFeatureBits();
4818 bool UsesNeg =
false;
4819 if (FB[AMDGPU::FeatureGFX940Insts]) {
4821 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
4822 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
4823 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
4824 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
4829 if (IsNeg == UsesNeg)
4833 UsesNeg ?
"invalid modifier: blgp is not supported"
4834 :
"invalid modifier: neg is not supported");
4839bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
4845 if (Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
4846 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
4847 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
4848 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
4854 if (Reg == AMDGPU::SGPR_NULL)
4858 Error(RegLoc,
"src0 must be null");
4862bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
4868 return validateGWS(Inst,
Operands);
4879 Error(S,
"gds modifier is not supported on this GPU");
4887bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
4889 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
4893 if (Opc != AMDGPU::DS_GWS_INIT_vi && Opc != AMDGPU::DS_GWS_BARRIER_vi &&
4894 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
4903 auto RegIdx =
Reg - (VGPR32.
contains(Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
4906 Error(RegLoc,
"vgpr must be even aligned");
4913bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
4915 const SMLoc &IDLoc) {
4917 AMDGPU::OpName::cpol);
4924 return validateTHAndScopeBits(Inst,
Operands, CPol);
4930 Error(S,
"cache policy is not supported for SMRD instructions");
4934 Error(IDLoc,
"invalid cache policy for SMEM instruction");
4943 if (!(TSFlags & AllowSCCModifier)) {
4948 "scc modifier is not supported for this instruction on this GPU");
4959 :
"instruction must use glc");
4967 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
4969 :
"instruction must not use glc");
4977bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
4979 const unsigned CPol) {
4983 const unsigned Opcode = Inst.
getOpcode();
4995 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5003 return PrintError(
"invalid th value for SMEM instruction");
5010 return PrintError(
"scope and th combination is not valid");
5019 return PrintError(
"invalid th value for atomic instructions");
5020 }
else if (IsStore) {
5022 return PrintError(
"invalid th value for store instructions");
5025 return PrintError(
"invalid th value for load instructions");
5035 if (!Operand->isReg())
5037 unsigned Reg = Operand->getReg();
5038 if (Reg == SRC_EXECZ || Reg == SRC_VCCZ) {
5040 "execz and vccz are not supported on this GPU");
5047bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5050 if (
Desc.mayStore() &&
5054 Error(Loc,
"TFE modifier has no meaning for store instructions");
5062bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst,
5065 if (
auto ErrMsg = validateLdsDirect(Inst)) {
5069 if (!validateSOPLiteral(Inst)) {
5071 "only one unique literal operand is allowed");
5074 if (!validateVOPLiteral(Inst,
Operands)) {
5077 if (!validateConstantBusLimitations(Inst,
Operands)) {
5080 if (!validateVOPDRegBankConstraints(Inst,
Operands)) {
5083 if (!validateIntClampSupported(Inst)) {
5085 "integer clamping is not supported on this GPU");
5088 if (!validateOpSel(Inst)) {
5090 "invalid op_sel operand");
5093 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5095 "invalid neg_lo operand");
5098 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5100 "invalid neg_hi operand");
5103 if (!validateDPP(Inst,
Operands)) {
5107 if (!validateMIMGD16(Inst)) {
5109 "d16 modifier is not supported on this GPU");
5112 if (!validateMIMGMSAA(Inst)) {
5114 "invalid dim; must be MSAA type");
5117 if (!validateMIMGDataSize(Inst, IDLoc)) {
5120 if (!validateMIMGAddrSize(Inst, IDLoc))
5122 if (!validateMIMGAtomicDMask(Inst)) {
5124 "invalid atomic image dmask");
5127 if (!validateMIMGGatherDMask(Inst)) {
5129 "invalid image_gather dmask: only one bit must be set");
5132 if (!validateMovrels(Inst,
Operands)) {
5135 if (!validateOffset(Inst,
Operands)) {
5138 if (!validateMAIAccWrite(Inst,
Operands)) {
5141 if (!validateMAISrc2(Inst,
Operands)) {
5144 if (!validateMFMA(Inst,
Operands)) {
5147 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5151 if (!validateAGPRLdSt(Inst)) {
5152 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5153 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5154 :
"invalid register class: agpr loads and stores not supported on this GPU"
5158 if (!validateVGPRAlign(Inst)) {
5160 "invalid register class: vgpr tuples must be 64 bit aligned");
5167 if (!validateBLGP(Inst,
Operands)) {
5171 if (!validateDivScale(Inst)) {
5172 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5175 if (!validateWaitCnt(Inst,
Operands)) {
5178 if (!validateExeczVcczOperands(
Operands)) {
5181 if (!validateTFE(Inst,
Operands)) {
5190 unsigned VariantID = 0);
5194 unsigned VariantID);
5196bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5201bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5204 for (
auto Variant : Variants) {
5212bool AMDGPUAsmParser::checkUnsupportedInstruction(
StringRef Mnemo,
5213 const SMLoc &IDLoc) {
5214 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5217 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5222 getParser().clearPendingErrors();
5226 StringRef VariantName = getMatchedVariantName();
5227 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5230 " variant of this instruction is not supported"));
5234 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5235 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5238 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5239 .
flip(AMDGPU::FeatureWavefrontSize32);
5241 ComputeAvailableFeatures(FeaturesWS32);
5243 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5244 return Error(IDLoc,
"instruction requires wavesize=32");
5249 return Error(IDLoc,
"instruction not supported on this GPU");
5254 return Error(IDLoc,
"invalid instruction" + Suggestion);
5260 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5261 if (
Op.isToken() && InvalidOprIdx > 1) {
5262 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5263 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5268bool AMDGPUAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
5272 bool MatchingInlineAsm) {
5274 unsigned Result = Match_Success;
5275 for (
auto Variant : getMatchedVariants()) {
5277 auto R = MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm,
5282 if ((R == Match_Success) ||
5283 (R == Match_PreferE32) ||
5284 (R == Match_MissingFeature && Result != Match_PreferE32) ||
5285 (R == Match_InvalidOperand && Result != Match_MissingFeature
5286 && Result != Match_PreferE32) ||
5287 (R == Match_MnemonicFail && Result != Match_InvalidOperand
5288 && Result != Match_MissingFeature
5289 && Result != Match_PreferE32)) {
5293 if (R == Match_Success)
5297 if (Result == Match_Success) {
5298 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5307 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5313 case Match_MissingFeature:
5317 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5319 case Match_InvalidOperand: {
5320 SMLoc ErrorLoc = IDLoc;
5323 return Error(IDLoc,
"too few operands for instruction");
5326 if (ErrorLoc ==
SMLoc())
5330 return Error(ErrorLoc,
"invalid VOPDY instruction");
5332 return Error(ErrorLoc,
"invalid operand for instruction");
5335 case Match_PreferE32:
5336 return Error(IDLoc,
"internal error: instruction without _e64 suffix "
5337 "should be encoded as e32");
5338 case Match_MnemonicFail:
5344bool AMDGPUAsmParser::ParseAsAbsoluteExpression(
uint32_t &Ret) {
5349 if (getParser().parseAbsoluteExpression(Tmp)) {
5356bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5358 return TokError(
"directive only supported for amdgcn architecture");
5360 std::string TargetIDDirective;
5361 SMLoc TargetStart = getTok().getLoc();
5362 if (getParser().parseEscapedString(TargetIDDirective))
5366 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5367 return getParser().Error(TargetRange.
Start,
5368 (
Twine(
".amdgcn_target directive's target id ") +
5369 Twine(TargetIDDirective) +
5370 Twine(
" does not match the specified target id ") +
5371 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5376bool AMDGPUAsmParser::OutOfRangeError(
SMRange Range) {
5377 return Error(
Range.Start,
"value out of range", Range);
5380bool AMDGPUAsmParser::calculateGPRBlocks(
5381 const FeatureBitset &Features,
bool VCCUsed,
bool FlatScrUsed,
5382 bool XNACKUsed, std::optional<bool> EnableWavefrontSize32,
5383 unsigned NextFreeVGPR,
SMRange VGPRRange,
unsigned NextFreeSGPR,
5384 SMRange SGPRRange,
unsigned &VGPRBlocks,
unsigned &SGPRBlocks) {
5395 unsigned MaxAddressableNumSGPRs =
5398 if (
Version.Major >= 8 && !Features.
test(FeatureSGPRInitBug) &&
5399 NumSGPRs > MaxAddressableNumSGPRs)
5400 return OutOfRangeError(SGPRRange);
5405 if ((
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5406 NumSGPRs > MaxAddressableNumSGPRs)
5407 return OutOfRangeError(SGPRRange);
5409 if (Features.
test(FeatureSGPRInitBug))
5414 EnableWavefrontSize32);
5420bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5422 return TokError(
"directive only supported for amdgcn architecture");
5425 return TokError(
"directive only supported for amdhsa OS");
5428 if (getParser().parseIdentifier(KernelName))
5433 &getSTI(), getContext());
5449 unsigned ImpliedUserSGPRCount = 0;
5453 std::optional<unsigned> ExplicitUserSGPRCount;
5454 bool ReserveVCC =
true;
5455 bool ReserveFlatScr =
true;
5456 std::optional<bool> EnableWavefrontSize32;
5462 SMRange IDRange = getTok().getLocRange();
5463 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5466 if (
ID ==
".end_amdhsa_kernel")
5470 return TokError(
".amdhsa_ directives cannot be repeated");
5472 SMLoc ValStart = getLoc();
5474 if (getParser().parseExpression(ExprVal))
5476 SMLoc ValEnd = getLoc();
5481 bool EvaluatableExpr;
5482 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5484 return OutOfRangeError(ValRange);
5488#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5489 if (!isUInt<ENTRY##_WIDTH>(Val)) \
5490 return OutOfRangeError(RANGE); \
5491 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
5496#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
5498 return Error(IDRange.Start, "directive should have resolvable expression", \
5501 if (
ID ==
".amdhsa_group_segment_fixed_size") {
5504 return OutOfRangeError(ValRange);
5506 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
5509 return OutOfRangeError(ValRange);
5511 }
else if (
ID ==
".amdhsa_kernarg_size") {
5513 return OutOfRangeError(ValRange);
5515 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
5517 ExplicitUserSGPRCount = Val;
5518 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
5522 "directive is not supported with architected flat scratch",
5525 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
5528 ImpliedUserSGPRCount += 4;
5529 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
5532 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5535 return OutOfRangeError(ValRange);
5539 ImpliedUserSGPRCount += Val;
5540 PreloadLength = Val;
5542 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
5545 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5548 return OutOfRangeError(ValRange);
5552 PreloadOffset = Val;
5553 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
5556 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
5559 ImpliedUserSGPRCount += 2;
5560 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
5563 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
5566 ImpliedUserSGPRCount += 2;
5567 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
5570 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
5573 ImpliedUserSGPRCount += 2;
5574 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
5577 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
5580 ImpliedUserSGPRCount += 2;
5581 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
5584 "directive is not supported with architected flat scratch",
5588 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
5591 ImpliedUserSGPRCount += 2;
5592 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
5595 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
5598 ImpliedUserSGPRCount += 1;
5599 }
else if (
ID ==
".amdhsa_wavefront_size32") {
5601 if (IVersion.
Major < 10)
5602 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5603 EnableWavefrontSize32 = Val;
5605 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
5607 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
5609 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
5611 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
5614 "directive is not supported with architected flat scratch",
5617 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
5619 }
else if (
ID ==
".amdhsa_enable_private_segment") {
5623 "directive is not supported without architected flat scratch",
5626 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
5628 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
5630 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
5632 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
5634 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
5636 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
5638 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
5640 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
5642 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
5644 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
5646 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
5648 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
5650 VGPRRange = ValRange;
5652 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
5654 SGPRRange = ValRange;
5656 }
else if (
ID ==
".amdhsa_accum_offset") {
5658 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5661 }
else if (
ID ==
".amdhsa_reserve_vcc") {
5663 if (!isUInt<1>(Val))
5664 return OutOfRangeError(ValRange);
5666 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
5668 if (IVersion.
Major < 7)
5669 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
5672 "directive is not supported with architected flat scratch",
5674 if (!isUInt<1>(Val))
5675 return OutOfRangeError(ValRange);
5676 ReserveFlatScr = Val;
5677 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
5678 if (IVersion.
Major < 8)
5679 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
5680 if (!isUInt<1>(Val))
5681 return OutOfRangeError(ValRange);
5682 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
5683 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
5685 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
5687 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
5689 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
5691 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
5693 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
5695 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
5697 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
5699 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
5701 }
else if (
ID ==
".amdhsa_dx10_clamp") {
5702 if (IVersion.
Major >= 12)
5703 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
5705 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
5707 }
else if (
ID ==
".amdhsa_ieee_mode") {
5708 if (IVersion.
Major >= 12)
5709 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
5711 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
5713 }
else if (
ID ==
".amdhsa_fp16_overflow") {
5714 if (IVersion.
Major < 9)
5715 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
5717 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
5719 }
else if (
ID ==
".amdhsa_tg_split") {
5721 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5724 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
5725 if (IVersion.
Major < 10)
5726 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5728 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
5730 }
else if (
ID ==
".amdhsa_memory_ordered") {
5731 if (IVersion.
Major < 10)
5732 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5734 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
5736 }
else if (
ID ==
".amdhsa_forward_progress") {
5737 if (IVersion.
Major < 10)
5738 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5740 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
5742 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
5744 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
5745 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
5747 SharedVGPRCount = Val;
5749 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
5751 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
5754 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
5756 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
5758 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
5760 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
5763 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
5765 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
5767 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
5769 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
5771 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
5773 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
5775 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
5777 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
5779 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
5781 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
5782 if (IVersion.
Major < 12)
5783 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
5785 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
5788 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
5791#undef PARSE_BITS_ENTRY
5794 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
5795 return TokError(
".amdhsa_next_free_vgpr directive is required");
5797 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
5798 return TokError(
".amdhsa_next_free_sgpr directive is required");
5800 unsigned VGPRBlocks;
5801 unsigned SGPRBlocks;
5802 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
5803 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
5804 EnableWavefrontSize32, NextFreeVGPR,
5805 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
5809 if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_WIDTH>(
5811 return OutOfRangeError(VGPRRange);
5814 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
5815 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT, getContext());
5817 if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_WIDTH>(
5819 return OutOfRangeError(SGPRRange);
5822 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
5823 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT, getContext());
5825 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
5826 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
5827 "enabled user SGPRs");
5829 unsigned UserSGPRCount =
5830 ExplicitUserSGPRCount ? *ExplicitUserSGPRCount : ImpliedUserSGPRCount;
5832 if (!isUInt<COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_WIDTH>(UserSGPRCount))
5833 return TokError(
"too many user SGPRs enabled");
5836 COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_SHIFT,
5837 COMPUTE_PGM_RSRC2_USER_SGPR_COUNT, getContext());
5841 return TokError(
"Kernarg size should be resolvable");
5843 if (PreloadLength && kernarg_size &&
5844 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
5845 return TokError(
"Kernarg preload length + offset is larger than the "
5846 "kernarg segment size");
5849 if (!Seen.
contains(
".amdhsa_accum_offset"))
5850 return TokError(
".amdhsa_accum_offset directive is required");
5851 if (AccumOffset < 4 || AccumOffset > 256 || (AccumOffset & 3))
5852 return TokError(
"accum_offset should be in range [4..256] in "
5855 return TokError(
"accum_offset exceeds total VGPR allocation");
5859 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
5860 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET, getContext());
5863 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
5865 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
5866 return TokError(
"shared_vgpr_count directive not valid on "
5867 "wavefront size 32");
5869 if (SharedVGPRCount * 2 + VGPRBlocks > 63) {
5870 return TokError(
"shared_vgpr_count*2 + "
5871 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
5876 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
5877 NextFreeVGPR, NextFreeSGPR,
5878 ReserveVCC, ReserveFlatScr);
5882bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
5884 if (ParseAsAbsoluteExpression(Version))
5887 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(Version);
5891bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(
StringRef ID,
5895 if (
ID ==
"max_scratch_backing_memory_byte_size") {
5896 Parser.eatToEndOfStatement();
5903 return TokError(Err.str());
5907 if (
ID ==
"enable_dx10_clamp") {
5910 return TokError(
"enable_dx10_clamp=1 is not allowed on GFX12+");
5913 if (
ID ==
"enable_ieee_mode") {
5916 return TokError(
"enable_ieee_mode=1 is not allowed on GFX12+");
5919 if (
ID ==
"enable_wavefront_size32") {
5922 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
5923 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5924 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
5926 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5927 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
5931 if (
ID ==
"wavefront_size") {
5932 if (Header.wavefront_size == 5) {
5934 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
5935 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5936 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
5937 }
else if (Header.wavefront_size == 6) {
5938 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5939 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
5943 if (
ID ==
"enable_wgp_mode") {
5946 return TokError(
"enable_wgp_mode=1 is only allowed on GFX10+");
5949 if (
ID ==
"enable_mem_ordered") {
5952 return TokError(
"enable_mem_ordered=1 is only allowed on GFX10+");
5955 if (
ID ==
"enable_fwd_progress") {
5958 return TokError(
"enable_fwd_progress=1 is only allowed on GFX10+");
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, Header))
5984 getTargetStreamer().EmitAMDKernelCodeT(Header);
5989bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
5991 if (!parseId(KernelName,
"expected symbol name"))
5994 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
5997 KernelScope.initialize(getContext());
6001bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6003 return Error(getLoc(),
6004 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6008 auto TargetIDDirective = getLexer().getTok().getStringContents();
6009 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6010 return Error(getParser().getTok().getLoc(),
"target id must match options");
6012 getTargetStreamer().EmitISAVersion();
6018bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6021 std::string HSAMetadataString;
6026 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6027 return Error(getLoc(),
"invalid HSA metadata");
6034bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6035 const char *AssemblerDirectiveEnd,
6036 std::string &CollectString) {
6040 getLexer().setSkipSpace(
false);
6042 bool FoundEnd =
false;
6045 CollectStream << getTokenStr();
6049 if (trySkipId(AssemblerDirectiveEnd)) {
6054 CollectStream << Parser.parseStringToEndOfStatement()
6055 << getContext().getAsmInfo()->getSeparatorString();
6057 Parser.eatToEndOfStatement();
6060 getLexer().setSkipSpace(
true);
6063 return TokError(
Twine(
"expected directive ") +
6064 Twine(AssemblerDirectiveEnd) +
Twine(
" not found"));
6067 CollectStream.flush();
6072bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6078 auto PALMetadata = getTargetStreamer().getPALMetadata();
6079 if (!PALMetadata->setFromString(
String))
6080 return Error(getLoc(),
"invalid PAL metadata");
6085bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6087 return Error(getLoc(),
6089 "not available on non-amdpal OSes")).str());
6092 auto PALMetadata = getTargetStreamer().getPALMetadata();
6093 PALMetadata->setLegacy();
6096 if (ParseAsAbsoluteExpression(Key)) {
6097 return TokError(
Twine(
"invalid value in ") +
6101 return TokError(
Twine(
"expected an even number of values in ") +
6104 if (ParseAsAbsoluteExpression(
Value)) {
6105 return TokError(
Twine(
"invalid value in ") +
6108 PALMetadata->setRegister(Key,
Value);
6117bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6118 if (getParser().checkForValidSection())
6122 SMLoc NameLoc = getLoc();
6123 if (getParser().parseIdentifier(
Name))
6124 return TokError(
"expected identifier in directive");
6127 if (getParser().parseComma())
6133 SMLoc SizeLoc = getLoc();
6134 if (getParser().parseAbsoluteExpression(
Size))
6137 return Error(SizeLoc,
"size must be non-negative");
6138 if (
Size > LocalMemorySize)
6139 return Error(SizeLoc,
"size is too large");
6141 int64_t Alignment = 4;
6143 SMLoc AlignLoc = getLoc();
6144 if (getParser().parseAbsoluteExpression(Alignment))
6147 return Error(AlignLoc,
"alignment must be a power of two");
6152 if (Alignment >= 1u << 31)
6153 return Error(AlignLoc,
"alignment is too large");
6159 Symbol->redefineIfPossible();
6160 if (!
Symbol->isUndefined())
6161 return Error(NameLoc,
"invalid symbol redefinition");
6163 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6167bool AMDGPUAsmParser::ParseDirective(
AsmToken DirectiveID) {
6171 if (IDVal ==
".amdhsa_kernel")
6172 return ParseDirectiveAMDHSAKernel();
6174 if (IDVal ==
".amdhsa_code_object_version")
6175 return ParseDirectiveAMDHSACodeObjectVersion();
6179 return ParseDirectiveHSAMetadata();
6181 if (IDVal ==
".amd_kernel_code_t")
6182 return ParseDirectiveAMDKernelCodeT();
6184 if (IDVal ==
".amdgpu_hsa_kernel")
6185 return ParseDirectiveAMDGPUHsaKernel();
6187 if (IDVal ==
".amd_amdgpu_isa")
6188 return ParseDirectiveISAVersion();
6192 Twine(
" directive is "
6193 "not available on non-amdhsa OSes"))
6198 if (IDVal ==
".amdgcn_target")
6199 return ParseDirectiveAMDGCNTarget();
6201 if (IDVal ==
".amdgpu_lds")
6202 return ParseDirectiveAMDGPULDS();
6205 return ParseDirectivePALMetadataBegin();
6208 return ParseDirectivePALMetadata();
6216 if (
MRI.regsOverlap(AMDGPU::TTMP12_TTMP13_TTMP14_TTMP15, RegNo))
6220 if (
MRI.regsOverlap(AMDGPU::SGPR104_SGPR105, RegNo))
6221 return hasSGPR104_SGPR105();
6224 case AMDGPU::SRC_SHARED_BASE_LO:
6225 case AMDGPU::SRC_SHARED_BASE:
6226 case AMDGPU::SRC_SHARED_LIMIT_LO:
6227 case AMDGPU::SRC_SHARED_LIMIT:
6228 case AMDGPU::SRC_PRIVATE_BASE_LO:
6229 case AMDGPU::SRC_PRIVATE_BASE:
6230 case AMDGPU::SRC_PRIVATE_LIMIT_LO:
6231 case AMDGPU::SRC_PRIVATE_LIMIT:
6233 case AMDGPU::SRC_POPS_EXITING_WAVE_ID:
6236 case AMDGPU::TBA_LO:
6237 case AMDGPU::TBA_HI:
6239 case AMDGPU::TMA_LO:
6240 case AMDGPU::TMA_HI:
6242 case AMDGPU::XNACK_MASK:
6243 case AMDGPU::XNACK_MASK_LO:
6244 case AMDGPU::XNACK_MASK_HI:
6245 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6246 case AMDGPU::SGPR_NULL:
6260 case AMDGPU::FLAT_SCR:
6261 case AMDGPU::FLAT_SCR_LO:
6262 case AMDGPU::FLAT_SCR_HI:
6271 if (
MRI.regsOverlap(AMDGPU::SGPR102_SGPR103, RegNo))
6272 return hasSGPR102_SGPR103();
6285 Res = MatchOperandParserImpl(
Operands, Mnemonic);
6297 SMLoc LBraceLoc = getLoc();
6302 auto Loc = getLoc();
6305 Error(Loc,
"expected a register");
6309 RBraceLoc = getLoc();
6314 "expected a comma or a closing square bracket"))
6318 if (
Operands.size() - Prefix > 1) {
6320 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6321 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6332 setForcedEncodingSize(0);
6333 setForcedDPP(
false);
6334 setForcedSDWA(
false);
6336 if (
Name.ends_with(
"_e64_dpp")) {
6338 setForcedEncodingSize(64);
6339 return Name.substr(0,
Name.size() - 8);
6340 }
else if (
Name.ends_with(
"_e64")) {
6341 setForcedEncodingSize(64);
6342 return Name.substr(0,
Name.size() - 4);
6343 }
else if (
Name.ends_with(
"_e32")) {
6344 setForcedEncodingSize(32);
6345 return Name.substr(0,
Name.size() - 4);
6346 }
else if (
Name.ends_with(
"_dpp")) {
6348 return Name.substr(0,
Name.size() - 4);
6349 }
else if (
Name.ends_with(
"_sdwa")) {
6350 setForcedSDWA(
true);
6351 return Name.substr(0,
Name.size() - 5);
6358 unsigned VariantID);
6370 Operands.push_back(AMDGPUOperand::CreateToken(
this,
Name, NameLoc));
6372 bool IsMIMG =
Name.starts_with(
"image_");
6375 OperandMode Mode = OperandMode_Default;
6377 Mode = OperandMode_NSA;
6381 checkUnsupportedInstruction(
Name, NameLoc);
6382 if (!Parser.hasPendingError()) {
6385 :
"not a valid operand.";
6386 Error(getLoc(), Msg);
6408 if (!trySkipId(
Name))
6411 Operands.push_back(AMDGPUOperand::CreateToken(
this,
Name, S));
6415ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6426 std::function<
bool(int64_t &)> ConvertResult) {
6434 if (ConvertResult && !ConvertResult(
Value)) {
6438 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6442ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6444 bool (*ConvertResult)(int64_t &)) {
6453 const unsigned MaxSize = 4;
6457 for (
int I = 0; ; ++
I) {
6459 SMLoc Loc = getLoc();
6463 if (
Op != 0 &&
Op != 1)
6471 if (
I + 1 == MaxSize)
6472 return Error(getLoc(),
"expected a closing square bracket");
6478 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
6484 AMDGPUOperand::ImmTy ImmTy) {
6488 if (trySkipId(
Name)) {
6490 }
else if (trySkipId(
"no",
Name)) {
6497 return Error(S,
"r128 modifier is not supported on this GPU");
6499 return Error(S,
"a16 modifier is not supported on this GPU");
6501 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
6502 ImmTy = AMDGPUOperand::ImmTyR128A16;
6504 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
6509 bool &Disabling)
const {
6510 Disabling =
Id.consume_front(
"no");
6530 SMLoc StringLoc = getLoc();
6532 int64_t CPolVal = 0;
6550 ResScope = parseScope(
Operands, Scope);
6565 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
6566 AMDGPUOperand::ImmTyCPol));
6571 SMLoc OpLoc = getLoc();
6572 unsigned Enabled = 0, Seen = 0;
6576 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
6583 return Error(S,
"dlc modifier is not supported on this GPU");
6586 return Error(S,
"scc modifier is not supported on this GPU");
6589 return Error(S,
"duplicate cache policy modifier");
6601 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
6613 Res = parseStringWithPrefix(
"scope",
Value, StringLoc);
6624 if (Scope == 0xffffffff)
6625 return Error(StringLoc,
"invalid scope value");
6639 if (
Value ==
"TH_DEFAULT")
6641 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_RT_WB" ||
6642 Value ==
"TH_LOAD_NT_WB") {
6643 return Error(StringLoc,
"invalid th value");
6644 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
6646 }
else if (
Value.consume_front(
"TH_LOAD_")) {
6648 }
else if (
Value.consume_front(
"TH_STORE_")) {
6651 return Error(StringLoc,
"invalid th value");
6654 if (
Value ==
"BYPASS")
6685 if (TH == 0xffffffff)
6686 return Error(StringLoc,
"invalid th value");
6693 AMDGPUAsmParser::OptionalImmIndexMap& OptionalIdx,
6694 AMDGPUOperand::ImmTy ImmT,
6696 auto i = OptionalIdx.find(ImmT);
6697 if (i != OptionalIdx.end()) {
6698 unsigned Idx = i->second;
6699 ((AMDGPUOperand &)*
Operands[
Idx]).addImmOperands(Inst, 1);
6711 StringLoc = getLoc();
6720bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
6724 SMLoc Loc = getLoc();
6726 auto Res = parseIntWithPrefix(Pref, Val);
6732 if (Val < 0 || Val > MaxVal) {
6742 AMDGPUOperand::ImmTy ImmTy) {
6743 const char *Pref =
"index_key";
6745 SMLoc Loc = getLoc();
6746 auto Res = parseIntWithPrefix(Pref, ImmVal);
6750 if (ImmTy == AMDGPUOperand::ImmTyIndexKey16bit && (ImmVal < 0 || ImmVal > 1))
6753 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
6756 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
6761 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
6765 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
6770ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &Format) {
6777 for (
int I = 0;
I < 2; ++
I) {
6778 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
6781 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
6786 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
6792 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
6795 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6796 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6802ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &Format) {
6807 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
6810 if (Fmt == UFMT_UNDEF)
6817bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
6825 if (Format != DFMT_UNDEF) {
6831 if (Format != NFMT_UNDEF) {
6836 Error(Loc,
"unsupported format");
6847 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
6852 SMLoc Loc = getLoc();
6853 if (!parseId(Str,
"expected a format string") ||
6854 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
6856 if (Dfmt == DFMT_UNDEF)
6857 return Error(Loc,
"duplicate numeric format");
6858 if (Nfmt == NFMT_UNDEF)
6859 return Error(Loc,
"duplicate data format");
6862 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6863 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6867 if (Ufmt == UFMT_UNDEF)
6868 return Error(FormatLoc,
"unsupported format");
6883 if (Id == UFMT_UNDEF)
6887 return Error(Loc,
"unified format is not supported on this GPU");
6893ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &Format) {
6895 SMLoc Loc = getLoc();
6897 if (!parseExpr(Format))
6900 return Error(Loc,
"out of range format");
6905ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &Format) {
6913 SMLoc Loc = getLoc();
6914 if (!parseId(FormatStr,
"expected a format string"))
6917 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc, Format);
6919 Res = parseSymbolicSplitFormat(FormatStr, Loc, Format);
6929 return parseNumericFormat(Format);
6937 SMLoc Loc = getLoc();
6947 AMDGPUOperand::CreateImm(
this, Format, Loc, AMDGPUOperand::ImmTyFORMAT));
6966 Res = parseSymbolicOrNumericFormat(Format);
6971 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
6972 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
6979 return Error(getLoc(),
"duplicate format");
6985 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
6987 Res = parseIntWithPrefix(
"inst_offset",
Operands,
6988 AMDGPUOperand::ImmTyInstOffset);
6995 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
6997 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
7003 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
7006 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
7016 OptionalImmIndexMap OptionalIdx;
7018 unsigned OperandIdx[4];
7019 unsigned EnMask = 0;
7022 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
7023 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7028 OperandIdx[SrcIdx] = Inst.
size();
7029 Op.addRegOperands(Inst, 1);
7036 OperandIdx[SrcIdx] = Inst.
size();
7042 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7043 Op.addImmOperands(Inst, 1);
7047 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7051 OptionalIdx[
Op.getImmTy()] = i;
7057 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7064 for (
auto i = 0; i < SrcIdx; ++i) {
7066 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7091 IntVal =
encode(ISA, IntVal, CntVal);
7092 if (CntVal !=
decode(ISA, IntVal)) {
7094 IntVal =
encode(ISA, IntVal, -1);
7102bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7104 SMLoc CntLoc = getLoc();
7112 SMLoc ValLoc = getLoc();
7113 if (!parseExpr(CntVal))
7121 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7123 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7125 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7128 Error(CntLoc,
"invalid counter name " + CntName);
7133 Error(ValLoc,
"too large value for " + CntName);
7142 Error(getLoc(),
"expected a counter name");
7169bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7170 SMLoc FieldLoc = getLoc();
7176 SMLoc ValueLoc = getLoc();
7183 if (FieldName ==
"instid0") {
7185 }
else if (FieldName ==
"instskip") {
7187 }
else if (FieldName ==
"instid1") {
7190 Error(FieldLoc,
"invalid field name " + FieldName);
7209 .
Case(
"VALU_DEP_1", 1)
7210 .
Case(
"VALU_DEP_2", 2)
7211 .
Case(
"VALU_DEP_3", 3)
7212 .
Case(
"VALU_DEP_4", 4)
7213 .
Case(
"TRANS32_DEP_1", 5)
7214 .
Case(
"TRANS32_DEP_2", 6)
7215 .
Case(
"TRANS32_DEP_3", 7)
7216 .
Case(
"FMA_ACCUM_CYCLE_1", 8)
7217 .
Case(
"SALU_CYCLE_1", 9)
7218 .
Case(
"SALU_CYCLE_2", 10)
7219 .
Case(
"SALU_CYCLE_3", 11)
7227 Delay |=
Value << Shift;
7237 if (!parseDelay(Delay))
7241 if (!parseExpr(Delay))
7245 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7250AMDGPUOperand::isSWaitCnt()
const {
7254bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7260void AMDGPUAsmParser::depCtrError(
SMLoc Loc,
int ErrorId,
7264 Error(Loc,
Twine(
"invalid counter name ", DepCtrName));
7267 Error(Loc,
Twine(DepCtrName,
" is not supported on this GPU"));
7270 Error(Loc,
Twine(
"duplicate counter name ", DepCtrName));
7273 Error(Loc,
Twine(
"invalid value for ", DepCtrName));
7280bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7284 SMLoc DepCtrLoc = getLoc();
7292 if (!parseExpr(ExprVal))
7295 unsigned PrevOprMask = UsedOprMask;
7296 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7299 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7308 Error(getLoc(),
"expected a counter name");
7313 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7314 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7322 SMLoc Loc = getLoc();
7325 unsigned UsedOprMask = 0;
7327 if (!parseDepCtr(DepCtr, UsedOprMask))
7331 if (!parseExpr(DepCtr))
7335 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
7339bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
7345ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
7347 OperandInfoTy &Width) {
7354 HwReg.Loc = getLoc();
7357 HwReg.IsSymbolic =
true;
7359 }
else if (!parseExpr(HwReg.Val,
"a register name")) {
7367 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
7371 if (!parseExpr(
Offset.Val))
7377 Width.Loc = getLoc();
7378 if (!parseExpr(Width.Val) ||
7389 SMLoc Loc = getLoc();
7391 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
7393 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
7394 HwregOffset::Default);
7395 struct : StructuredOpField {
7396 using StructuredOpField::StructuredOpField;
7397 bool validate(AMDGPUAsmParser &Parser)
const override {
7399 return Error(Parser,
"only values from 1 to 32 are legal");
7402 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
7406 Res = parseHwregFunc(HwReg,
Offset, Width);
7409 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
7411 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
7415 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
7421 if (!isUInt<16>(ImmVal))
7422 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
7424 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
7428bool AMDGPUOperand::isHwreg()
const {
7429 return isImmTy(ImmTyHwreg);
7437AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
7439 OperandInfoTy &Stream) {
7445 Msg.IsSymbolic =
true;
7447 }
else if (!parseExpr(
Msg.Val,
"a message name")) {
7452 Op.IsDefined =
true;
7457 }
else if (!parseExpr(
Op.Val,
"an operation name")) {
7462 Stream.IsDefined =
true;
7463 Stream.Loc = getLoc();
7464 if (!parseExpr(Stream.Val))
7473AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
7474 const OperandInfoTy &
Op,
7475 const OperandInfoTy &Stream) {
7485 Error(
Msg.Loc,
"specified message id is not supported on this GPU");
7490 Error(
Msg.Loc,
"invalid message id");
7496 Error(
Op.Loc,
"message does not support operations");
7498 Error(
Msg.Loc,
"missing message operation");
7503 Error(
Op.Loc,
"invalid operation id");
7508 Error(Stream.Loc,
"message operation does not support streams");
7512 Error(Stream.Loc,
"invalid message stream id");
7522 SMLoc Loc = getLoc();
7526 OperandInfoTy
Op(OP_NONE_);
7527 OperandInfoTy Stream(STREAM_ID_NONE_);
7528 if (parseSendMsgBody(Msg,
Op, Stream) &&
7529 validateSendMsg(Msg,
Op, Stream)) {
7534 }
else if (parseExpr(ImmVal,
"a sendmsg macro")) {
7535 if (ImmVal < 0 || !isUInt<16>(ImmVal))
7536 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
7541 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
7545bool AMDGPUOperand::isSendMsg()
const {
7546 return isImmTy(ImmTySendMsg);
7567 return Error(S,
"invalid interpolation slot");
7569 Operands.push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
7570 AMDGPUOperand::ImmTyInterpSlot));
7581 if (!Str.starts_with(
"attr"))
7582 return Error(S,
"invalid interpolation attribute");
7592 return Error(S,
"invalid or missing interpolation attribute channel");
7594 Str = Str.drop_back(2).drop_front(4);
7597 if (Str.getAsInteger(10, Attr))
7598 return Error(S,
"invalid or missing interpolation attribute number");
7601 return Error(S,
"out of bounds interpolation attribute number");
7605 Operands.push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
7606 AMDGPUOperand::ImmTyInterpAttr));
7607 Operands.push_back(AMDGPUOperand::CreateImm(
7608 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
7627 return Error(S, (
Id == ET_INVALID)
7628 ?
"invalid exp target"
7629 :
"exp target is not supported on this GPU");
7631 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Id, S,
7632 AMDGPUOperand::ImmTyExpTgt));
7647 return isId(getToken(),
Id);
7652 return getTokenKind() ==
Kind;
7655StringRef AMDGPUAsmParser::getId()
const {
7682 if (isId(
Id) && peekToken().is(Kind)) {
7692 if (isToken(Kind)) {
7702 if (!trySkipToken(Kind)) {
7703 Error(getLoc(), ErrMsg);
7714 if (Parser.parseExpression(Expr))
7717 if (Expr->evaluateAsAbsolute(Imm))
7721 Error(S,
"expected absolute expression");
7724 Twine(
" or an absolute expression"));
7734 if (Parser.parseExpression(Expr))
7738 if (Expr->evaluateAsAbsolute(IntVal)) {
7739 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
7741 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
7749 Val = getToken().getStringContents();
7753 Error(getLoc(), ErrMsg);
7761 Val = getTokenStr();
7765 if (!ErrMsg.
empty())
7766 Error(getLoc(), ErrMsg);
7772AMDGPUAsmParser::getToken()
const {
7773 return Parser.getTok();
7776AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
7779 : getLexer().peekTok(ShouldSkipSpace);
7784 auto TokCount = getLexer().peekTokens(Tokens);
7791AMDGPUAsmParser::getTokenKind()
const {
7796AMDGPUAsmParser::getLoc()
const {
7797 return getToken().getLoc();
7801AMDGPUAsmParser::getTokenStr()
const {
7802 return getToken().getString();
7806AMDGPUAsmParser::lex() {
7811 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
7815AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
7817 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
7818 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7820 return Op.getStartLoc();
7826AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
7828 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
7833AMDGPUAsmParser::getRegLoc(
unsigned Reg,
7835 auto Test = [=](
const AMDGPUOperand&
Op) {
7836 return Op.isRegKind() &&
Op.getReg() ==
Reg;
7842 bool SearchMandatoryLiterals)
const {
7843 auto Test = [](
const AMDGPUOperand&
Op) {
7844 return Op.IsImmKindLiteral() ||
Op.isExpr();
7847 if (SearchMandatoryLiterals && Loc == getInstLoc(
Operands))
7848 Loc = getMandatoryLitLoc(
Operands);
7853 auto Test = [](
const AMDGPUOperand &
Op) {
7854 return Op.IsImmKindMandatoryLiteral();
7861 auto Test = [](
const AMDGPUOperand&
Op) {
7862 return Op.isImmKindConst();
7879 SMLoc IdLoc = getLoc();
7885 find_if(Fields, [
Id](StructuredOpField *
F) {
return F->Id ==
Id; });
7886 if (
I == Fields.
end())
7887 return Error(IdLoc,
"unknown field");
7888 if ((*I)->IsDefined)
7889 return Error(IdLoc,
"duplicate field");
7892 (*I)->Loc = getLoc();
7893 if (!parseExpr((*I)->Val))
7895 (*I)->IsDefined =
true;
7902bool AMDGPUAsmParser::validateStructuredOpFields(
7904 return all_of(Fields, [
this](
const StructuredOpField *
F) {
7905 return F->validate(*
this);
7916 const unsigned OrMask,
7917 const unsigned XorMask) {
7920 return BITMASK_PERM_ENC |
7921 (AndMask << BITMASK_AND_SHIFT) |
7922 (OrMask << BITMASK_OR_SHIFT) |
7923 (XorMask << BITMASK_XOR_SHIFT);
7927AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
7928 const unsigned MinVal,
7929 const unsigned MaxVal,
7936 if (!parseExpr(
Op)) {
7939 if (Op < MinVal || Op > MaxVal) {
7948AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
7949 const unsigned MinVal,
7950 const unsigned MaxVal,
7953 for (
unsigned i = 0; i < OpNum; ++i) {
7954 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
7962AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &Imm) {
7966 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
7967 "expected a 2-bit lane id")) {
7978AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &Imm) {
7985 if (!parseSwizzleOperand(GroupSize,
7987 "group size must be in the interval [2,32]",
7992 Error(Loc,
"group size must be a power of two");
7995 if (parseSwizzleOperand(LaneIdx,
7997 "lane id must be in the interval [0,group size - 1]",
8006AMDGPUAsmParser::parseSwizzleReverse(int64_t &Imm) {
8012 if (!parseSwizzleOperand(GroupSize,
8014 "group size must be in the interval [2,32]",
8019 Error(Loc,
"group size must be a power of two");
8028AMDGPUAsmParser::parseSwizzleSwap(int64_t &Imm) {
8034 if (!parseSwizzleOperand(GroupSize,
8036 "group size must be in the interval [1,16]",
8041 Error(Loc,
"group size must be a power of two");
8050AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &Imm) {
8058 SMLoc StrLoc = getLoc();
8059 if (!parseString(Ctl)) {
8062 if (Ctl.
size() != BITMASK_WIDTH) {
8063 Error(StrLoc,
"expected a 5-character mask");
8067 unsigned AndMask = 0;
8068 unsigned OrMask = 0;
8069 unsigned XorMask = 0;
8071 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8075 Error(StrLoc,
"invalid mask");
8097AMDGPUAsmParser::parseSwizzleOffset(int64_t &Imm) {
8099 SMLoc OffsetLoc = getLoc();
8101 if (!parseExpr(Imm,
"a swizzle macro")) {
8104 if (!isUInt<16>(Imm)) {
8105 Error(OffsetLoc,
"expected a 16-bit offset");
8112AMDGPUAsmParser::parseSwizzleMacro(int64_t &Imm) {
8117 SMLoc ModeLoc = getLoc();
8120 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8121 Ok = parseSwizzleQuadPerm(Imm);
8122 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8123 Ok = parseSwizzleBitmaskPerm(Imm);
8124 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8125 Ok = parseSwizzleBroadcast(Imm);
8126 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8127 Ok = parseSwizzleSwap(Imm);
8128 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8129 Ok = parseSwizzleReverse(Imm);
8131 Error(ModeLoc,
"expected a swizzle mode");
8134 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8144 if (trySkipId(
"offset")) {
8148 if (trySkipId(
"swizzle")) {
8149 Ok = parseSwizzleMacro(Imm);
8151 Ok = parseSwizzleOffset(Imm);
8155 Operands.push_back(AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTySwizzle));
8163AMDGPUOperand::isSwizzle()
const {
8164 return isImmTy(ImmTySwizzle);
8171int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8185 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8186 if (trySkipId(IdSymbolic[ModeId])) {
8193 Error(S, (Imm == 0)?
8194 "expected a VGPR index mode or a closing parenthesis" :
8195 "expected a VGPR index mode");
8200 Error(S,
"duplicate VGPR index mode");
8208 "expected a comma or a closing parenthesis"))
8223 Imm = parseGPRIdxMacro();
8227 if (getParser().parseAbsoluteExpression(Imm))
8229 if (Imm < 0 || !isUInt<4>(Imm))
8230 return Error(S,
"invalid immediate: only 4-bit values are legal");
8234 AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8238bool AMDGPUOperand::isGPRIdxMode()
const {
8239 return isImmTy(ImmTyGprIdxMode);
8251 if (isRegister() || isModifier())
8263 if (
Opr.isExpr() && !
Opr.isSymbolRefExpr()) {
8264 Error(Loc,
"expected an absolute expression or a label");
8265 }
else if (
Opr.isImm() && !
Opr.isS16Imm()) {
8266 Error(Loc,
"expected a 16-bit signed jump offset");
8284void AMDGPUAsmParser::cvtMubufImpl(
MCInst &Inst,
8287 OptionalImmIndexMap OptionalIdx;
8288 unsigned FirstOperandIdx = 1;
8289 bool IsAtomicReturn =
false;
8296 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
8297 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8301 Op.addRegOperands(Inst, 1);
8305 if (IsAtomicReturn && i == FirstOperandIdx)
8306 Op.addRegOperands(Inst, 1);
8311 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
8312 Op.addImmOperands(Inst, 1);
8324 OptionalIdx[
Op.getImmTy()] = i;
8335bool AMDGPUOperand::isSMRDOffset8()
const {
8336 return isImmLiteral() && isUInt<8>(getImm());
8339bool AMDGPUOperand::isSMEMOffset()
const {
8341 return isImmLiteral();
8344bool AMDGPUOperand::isSMRDLiteralOffset()
const {
8347 return isImmLiteral() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
8379bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
8380 if (BoundCtrl == 0 || BoundCtrl == 1) {
8388void AMDGPUAsmParser::onBeginOfFile() {
8389 if (!getParser().getStreamer().getTargetStreamer() ||
8393 if (!getTargetStreamer().getTargetID())
8394 getTargetStreamer().initializeTargetID(getSTI(),
8395 getSTI().getFeatureString());
8398 getTargetStreamer().EmitDirectiveAMDGCNTarget();
8406bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
8412 .
Case(
"max", AGVK::AGVK_Max)
8413 .
Case(
"or", AGVK::AGVK_Or)
8423 if (Exprs.
empty()) {
8424 Error(getToken().getLoc(),
8425 "empty " +
Twine(TokenId) +
" expression");
8428 if (CommaCount + 1 != Exprs.
size()) {
8429 Error(getToken().getLoc(),
8430 "mismatch of commas in " +
Twine(TokenId) +
" expression");
8437 if (getParser().parseExpression(Expr, EndLoc))
8441 if (LastTokenWasComma)
8444 Error(getToken().getLoc(),
8445 "unexpected token in " +
Twine(TokenId) +
" expression");
8451 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
8456 if (
Name ==
"mul") {
8457 return parseIntWithPrefix(
"mul",
Operands,
8461 if (
Name ==
"div") {
8462 return parseIntWithPrefix(
"div",
Operands,
8478 const int Ops[] = { AMDGPU::OpName::src0,
8479 AMDGPU::OpName::src1,
8480 AMDGPU::OpName::src2 };
8495 if (
DstOp.isReg() &&
8496 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
8500 if ((OpSel & (1 << SrcNum)) != 0)
8506void AMDGPUAsmParser::cvtVOP3OpSel(
MCInst &Inst,
8513 OptionalImmIndexMap &OptionalIdx) {
8514 cvtVOP3P(Inst,
Operands, OptionalIdx);
8523 &&
Desc.NumOperands > (OpNum + 1)
8525 &&
Desc.operands()[OpNum + 1].RegClass != -1
8527 &&
Desc.getOperandConstraint(OpNum + 1,
8528 MCOI::OperandConstraint::TIED_TO) == -1;
8533 OptionalImmIndexMap OptionalIdx;
8538 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8539 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8542 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8543 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8545 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8546 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
8547 Op.isInterpAttrChan()) {
8549 }
else if (
Op.isImmModifier()) {
8550 OptionalIdx[
Op.getImmTy()] =
I;
8558 AMDGPUOperand::ImmTyHigh);
8562 AMDGPUOperand::ImmTyClampSI);
8566 AMDGPUOperand::ImmTyOModSI);
8571 OptionalImmIndexMap OptionalIdx;
8576 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8577 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8580 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8581 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8583 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8584 }
else if (
Op.isImmModifier()) {
8585 OptionalIdx[
Op.getImmTy()] =
I;
8602 const int Ops[] = { AMDGPU::OpName::src0,
8603 AMDGPU::OpName::src1,
8604 AMDGPU::OpName::src2 };
8605 const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8606 AMDGPU::OpName::src1_modifiers,
8607 AMDGPU::OpName::src2_modifiers };
8611 for (
int J = 0; J < 3; ++J) {
8619 if ((OpSel & (1 << J)) != 0)
8621 if (ModOps[J] == AMDGPU::OpName::src0_modifiers &&
8622 (OpSel & (1 << 3)) != 0)
8630 OptionalImmIndexMap &OptionalIdx) {
8635 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8636 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8639 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8640 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8642 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8643 }
else if (
Op.isImmModifier()) {
8644 OptionalIdx[
Op.getImmTy()] =
I;
8645 }
else if (
Op.isRegOrImm()) {
8646 Op.addRegOrImmOperands(Inst, 1);
8656 AMDGPUOperand::ImmTyByteSel);
8661 AMDGPUOperand::ImmTyClampSI);
8665 AMDGPUOperand::ImmTyOModSI);
8672 auto it = Inst.
begin();
8682 OptionalImmIndexMap OptionalIdx;
8683 cvtVOP3(Inst,
Operands, OptionalIdx);
8687 OptionalImmIndexMap &OptIdx) {
8693 if (Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
8694 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
8695 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
8696 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
8704 !(Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp_gfx12 ||
8705 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp_gfx12 ||
8706 Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp8_gfx12 ||
8707 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp8_gfx12 ||
8708 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
8709 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
8710 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
8711 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12)) {
8720 if (OpSelIdx != -1) {
8725 if (OpSelHiIdx != -1) {
8739 const int Ops[] = { AMDGPU::OpName::src0,
8740 AMDGPU::OpName::src1,
8741 AMDGPU::OpName::src2 };
8742 const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8743 AMDGPU::OpName::src1_modifiers,
8744 AMDGPU::OpName::src2_modifiers };
8747 unsigned OpSelHi = 0;
8754 if (OpSelHiIdx != -1)
8763 for (
int J = 0; J < 3; ++J) {
8776 if (
SrcOp.isReg() && getMRI()
8783 if ((OpSel & (1 << J)) != 0)
8787 if ((OpSelHi & (1 << J)) != 0)
8790 if ((NegLo & (1 << J)) != 0)
8793 if ((NegHi & (1 << J)) != 0)
8801 OptionalImmIndexMap OptIdx;
8807 unsigned i,
unsigned Opc,
unsigned OpName) {
8809 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
8811 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
8817 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
8820 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
8821 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
8823 OptionalImmIndexMap OptIdx;
8824 for (
unsigned i = 5; i <
Operands.size(); ++i) {
8825 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8826 OptIdx[
Op.getImmTy()] = i;
8831 AMDGPUOperand::ImmTyIndexKey8bit);
8835 AMDGPUOperand::ImmTyIndexKey16bit);
8855 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
8856 SMLoc OpYLoc = getLoc();
8859 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
8862 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
8869 auto addOp = [&](
uint16_t ParsedOprIdx) {
8870 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
8872 Op.addRegOperands(Inst, 1);
8876 Op.addImmOperands(Inst, 1);
8888 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
8892 const auto &CInfo = InstInfo[CompIdx];
8893 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
8894 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
8895 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
8896 if (CInfo.hasSrc2Acc())
8897 addOp(CInfo.getIndexOfDstInParsedOperands());
8905bool AMDGPUOperand::isDPP8()
const {
8906 return isImmTy(ImmTyDPP8);
8909bool AMDGPUOperand::isDPPCtrl()
const {
8910 using namespace AMDGPU::DPP;
8912 bool result =
isImm() && getImmTy() == ImmTyDppCtrl && isUInt<9>(getImm());
8914 int64_t
Imm = getImm();
8915 return (Imm >= DppCtrl::QUAD_PERM_FIRST && Imm <= DppCtrl::QUAD_PERM_LAST) ||
8916 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
8917 (Imm >= DppCtrl::ROW_SHR_FIRST && Imm <= DppCtrl::ROW_SHR_LAST) ||
8918 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
8919 (Imm == DppCtrl::WAVE_SHL1) ||
8920 (
Imm == DppCtrl::WAVE_ROL1) ||
8921 (Imm == DppCtrl::WAVE_SHR1) ||
8922 (
Imm == DppCtrl::WAVE_ROR1) ||
8923 (Imm == DppCtrl::ROW_MIRROR) ||
8924 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
8925 (Imm == DppCtrl::BCAST15) ||
8926 (
Imm == DppCtrl::BCAST31) ||
8927 (Imm >= DppCtrl::ROW_SHARE_FIRST && Imm <= DppCtrl::ROW_SHARE_LAST) ||
8928 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
8937bool AMDGPUOperand::isBLGP()
const {
8938 return isImm() && getImmTy() == ImmTyBLGP && isUInt<3>(getImm());
8941bool AMDGPUOperand::isCBSZ()
const {
8942 return isImm() && getImmTy() == ImmTyCBSZ && isUInt<3>(getImm());
8945bool AMDGPUOperand::isABID()
const {
8946 return isImm() && getImmTy() == ImmTyABID && isUInt<4>(getImm());
8949bool AMDGPUOperand::isS16Imm()
const {
8950 return isImmLiteral() && (isInt<16>(getImm()) || isUInt<16>(getImm()));
8953bool AMDGPUOperand::isU16Imm()
const {
8954 return isImmLiteral() && isUInt<16>(getImm());
8961bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
8966 SMLoc Loc = getToken().getEndLoc();
8967 Token = std::string(getTokenStr());
8969 if (getLoc() != Loc)
8974 if (!parseId(Suffix))
9000 SMLoc Loc = getLoc();
9001 if (!parseDimId(Encoding))
9002 return Error(Loc,
"invalid dim value");
9004 Operands.push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9005 AMDGPUOperand::ImmTyDim));
9023 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9026 for (
size_t i = 0; i < 8; ++i) {
9030 SMLoc Loc = getLoc();
9031 if (getParser().parseAbsoluteExpression(Sels[i]))
9033 if (0 > Sels[i] || 7 < Sels[i])
9034 return Error(Loc,
"expected a 3-bit value");
9041 for (
size_t i = 0; i < 8; ++i)
9042 DPP8 |= (Sels[i] << (i * 3));
9044 Operands.push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9049AMDGPUAsmParser::isSupportedDPPCtrl(
StringRef Ctrl,
9051 if (Ctrl ==
"row_newbcast")
9054 if (Ctrl ==
"row_share" ||
9055 Ctrl ==
"row_xmask")
9058 if (Ctrl ==
"wave_shl" ||
9059 Ctrl ==
"wave_shr" ||
9060 Ctrl ==
"wave_rol" ||
9061 Ctrl ==
"wave_ror" ||
9062 Ctrl ==
"row_bcast")
9065 return Ctrl ==
"row_mirror" ||
9066 Ctrl ==
"row_half_mirror" ||
9067 Ctrl ==
"quad_perm" ||
9068 Ctrl ==
"row_shl" ||
9069 Ctrl ==
"row_shr" ||
9074AMDGPUAsmParser::parseDPPCtrlPerm() {
9077 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9081 for (
int i = 0; i < 4; ++i) {
9086 SMLoc Loc = getLoc();
9087 if (getParser().parseAbsoluteExpression(Temp))
9089 if (Temp < 0 || Temp > 3) {
9090 Error(Loc,
"expected a 2-bit value");
9094 Val += (Temp << i * 2);
9104AMDGPUAsmParser::parseDPPCtrlSel(
StringRef Ctrl) {
9105 using namespace AMDGPU::DPP;
9110 SMLoc Loc = getLoc();
9112 if (getParser().parseAbsoluteExpression(Val))
9115 struct DppCtrlCheck {
9122 .
Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
9123 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
9124 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
9125 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
9126 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
9127 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
9128 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
9129 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
9130 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
9131 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
9135 if (
Check.Ctrl == -1) {
9136 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
9137 Val = (Val == 15)? DppCtrl::BCAST15 : DppCtrl::BCAST31;
9152 using namespace AMDGPU::DPP;
9155 !isSupportedDPPCtrl(getTokenStr(),
Operands))
9164 if (Ctrl ==
"row_mirror") {
9165 Val = DppCtrl::ROW_MIRROR;
9166 }
else if (Ctrl ==
"row_half_mirror") {
9167 Val = DppCtrl::ROW_HALF_MIRROR;
9170 if (Ctrl ==
"quad_perm") {
9171 Val = parseDPPCtrlPerm();
9173 Val = parseDPPCtrlSel(Ctrl);
9182 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
9188 OptionalImmIndexMap OptionalIdx;
9198 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
9202 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9203 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9207 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9211 if (OldIdx == NumOperands) {
9213 constexpr int DST_IDX = 0;
9215 }
else if (Src2ModIdx == NumOperands) {
9226 bool IsVOP3CvtSrDpp =
9227 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9228 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9229 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9230 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
9231 if (IsVOP3CvtSrDpp) {
9245 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9247 if (IsDPP8 &&
Op.isDppFI()) {
9250 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9251 }
else if (
Op.isReg()) {
9252 Op.addRegOperands(Inst, 1);
9253 }
else if (
Op.isImm() &&
9255 assert(!
Op.IsImmKindLiteral() &&
"Cannot use literal with DPP");
9256 Op.addImmOperands(Inst, 1);
9257 }
else if (
Op.isImm()) {
9258 OptionalIdx[
Op.getImmTy()] =
I;
9266 AMDGPUOperand::ImmTyByteSel);
9275 cvtVOP3P(Inst,
Operands, OptionalIdx);
9277 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
9294 AMDGPUOperand::ImmTyDppFI);
9299 OptionalImmIndexMap OptionalIdx;
9303 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9304 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9308 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9316 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9318 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
9326 Op.addImmOperands(Inst, 1);
9328 Op.addRegWithFPInputModsOperands(Inst, 2);
9329 }
else if (
Op.isDppFI()) {
9331 }
else if (
Op.isReg()) {
9332 Op.addRegOperands(Inst, 1);
9338 Op.addRegWithFPInputModsOperands(Inst, 2);
9339 }
else if (
Op.isReg()) {
9340 Op.addRegOperands(Inst, 1);
9341 }
else if (
Op.isDPPCtrl()) {
9342 Op.addImmOperands(Inst, 1);
9343 }
else if (
Op.isImm()) {
9345 OptionalIdx[
Op.getImmTy()] =
I;
9361 AMDGPUOperand::ImmTyDppFI);
9372 AMDGPUOperand::ImmTy
Type) {
9385 .
Case(
"BYTE_0", SdwaSel::BYTE_0)
9386 .
Case(
"BYTE_1", SdwaSel::BYTE_1)
9387 .
Case(
"BYTE_2", SdwaSel::BYTE_2)
9388 .
Case(
"BYTE_3", SdwaSel::BYTE_3)
9389 .
Case(
"WORD_0", SdwaSel::WORD_0)
9390 .
Case(
"WORD_1", SdwaSel::WORD_1)
9391 .
Case(
"DWORD", SdwaSel::DWORD)
9394 if (
Int == 0xffffffff)
9395 return Error(StringLoc,
"invalid " +
Twine(Prefix) +
" value");
9414 .
Case(
"UNUSED_PAD", DstUnused::UNUSED_PAD)
9415 .
Case(
"UNUSED_SEXT", DstUnused::UNUSED_SEXT)
9416 .
Case(
"UNUSED_PRESERVE", DstUnused::UNUSED_PRESERVE)
9419 if (
Int == 0xffffffff)
9420 return Error(StringLoc,
"invalid dst_unused value");
9422 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Int, S, AMDGPUOperand::ImmTySDWADstUnused));
9452 OptionalImmIndexMap OptionalIdx;
9453 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
9454 bool SkippedVcc =
false;
9458 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9459 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9462 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9463 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9464 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
9465 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
9483 Op.addRegOrImmWithInputModsOperands(Inst, 2);
9484 }
else if (
Op.isImm()) {
9486 OptionalIdx[
Op.getImmTy()] =
I;
9494 if (Opc != AMDGPU::V_NOP_sdwa_gfx10 && Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
9495 Opc != AMDGPU::V_NOP_sdwa_vi) {
9497 switch (BasicInstType) {
9501 AMDGPUOperand::ImmTyClampSI, 0);
9505 AMDGPUOperand::ImmTyOModSI, 0);
9509 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
9513 AMDGPUOperand::ImmTySDWADstUnused,
9514 DstUnused::UNUSED_PRESERVE);
9539 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
9545 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
9546 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
9547 auto it = Inst.
begin();
9560#define GET_REGISTER_MATCHER
9561#define GET_MATCHER_IMPLEMENTATION
9562#define GET_MNEMONIC_SPELL_CHECKER
9563#define GET_MNEMONIC_CHECKER
9564#include "AMDGPUGenAsmMatcher.inc"
9570 return parseTokenOp(
"addr64",
Operands);
9572 return parseTokenOp(
"done",
Operands);
9574 return parseTokenOp(
"idxen",
Operands);
9576 return parseTokenOp(
"lds",
Operands);
9578 return parseTokenOp(
"offen",
Operands);
9580 return parseTokenOp(
"off",
Operands);
9582 return parseTokenOp(
"row_en",
Operands);
9584 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
9586 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
9588 return tryCustomParseOperand(
Operands, MCK);
9599 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
9602 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
9604 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
9606 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
9608 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
9610 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
9612 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
9620 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
9622 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
9623 case MCK_SOPPBrTarget:
9624 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
9625 case MCK_VReg32OrOff:
9626 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
9627 case MCK_InterpSlot:
9628 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
9629 case MCK_InterpAttr:
9630 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
9631 case MCK_InterpAttrChan:
9632 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
9634 case MCK_SReg_64_XEXEC:
9640 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
9642 return Match_InvalidOperand;
9654 if (!parseExpr(Imm)) {
9659 if (!isUInt<16>(Imm))
9660 return Error(S,
"expected a 16-bit value");
9663 AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTyEndpgm));
9667bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
9673bool AMDGPUOperand::isWaitVDST()
const {
9674 return isImmTy(ImmTyWaitVDST) && isUInt<4>(getImm());
9677bool AMDGPUOperand::isWaitVAVDst()
const {
9678 return isImmTy(ImmTyWaitVAVDst) && isUInt<4>(getImm());
9681bool AMDGPUOperand::isWaitVMVSrc()
const {
9682 return isImmTy(ImmTyWaitVMVSrc) && isUInt<1>(getImm());
9689bool AMDGPUOperand::isWaitEXP()
const {
9690 return isImmTy(ImmTyWaitEXP) && isUInt<3>(getImm());
9697bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
unsigned const MachineRegisterInfo * MRI
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
constexpr uint64_t MIMGFlags
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static unsigned getSpecialRegForName(StringRef RegName)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, unsigned OpName)
static bool IsRevOpcode(const unsigned Opcode)
static int getRegClass(RegisterKind Is, unsigned RegWidth)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
static int IsAGPROperand(const MCInst &Inst, uint16_t NameIdx, const MCRegisterInfo *MRI)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static unsigned getOperandSize(MachineInstr &MI, unsigned Idx, MachineRegisterInfo &MRI)
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
mir Rename Register Operands
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
#define G_00B848_FWD_PROGRESS(x)
#define G_00B848_MEM_ORDERED(x)
#define G_00B848_IEEE_MODE(x)
#define G_00B848_DX10_CLAMP(x)
#define G_00B848_WGP_MODE(x)
Interface definition for SIInstrInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Interface definition for SIRegisterInfo.
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
unsigned unsigned DefaultVal
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
support::ulittle16_t & Lo
support::ulittle16_t & Hi
static const AMDGPUVariadicMCExpr * create(VariadicKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Target independent representation for an assembler token.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Class representing an expression and its matching format.
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCRegisterInfo * getRegisterInfo() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCSubtargetInfo * getSubtargetInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
bool mayStore() const
Return true if this instruction could possibly modify memory.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
void setReg(unsigned Reg)
Set the register number.
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NoRegister
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void setVariableValue(const MCExpr *Value)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
Target specific streamer interface.
uint64_t getScalarSizeInBits() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
Represents a range in source code.
Implements a dense probed hash-table based set with some number of buckets stored inline.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
StringSet - A wrapper for StringMap that provides set-like functionality.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
unsigned getTgtId(const StringRef Name)
constexpr char NumVGPRs[]
Key for Kernel::CodeProps::Metadata::mNumVGPRs.
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
const CustomOperand< const MCSubtargetInfo & > Opr[]
int64_t getHwregId(const StringRef Name, const MCSubtargetInfo &STI)
unsigned getNumExtraSGPRs(const MCSubtargetInfo *STI, bool VCCUsed, bool FlatScrUsed, bool XNACKUsed)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
unsigned getNumSGPRBlocks(const MCSubtargetInfo *STI, unsigned NumSGPRs)
unsigned getEncodedNumVGPRBlocks(const MCSubtargetInfo *STI, unsigned NumVGPRs, std::optional< bool > EnableWavefrontSize32)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
int64_t getMsgId(const StringRef Name, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
int64_t getMsgOpId(int64_t MsgId, const StringRef Name)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
const CustomOperand< const MCSubtargetInfo & > Msg[]
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
constexpr unsigned COMPONENTS[]
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc, unsigned OpNo)
Get size of register operand.
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
LLVM_READNONE bool isLegalDPALU_DPPControl(unsigned DC)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
bool isGFX10(const MCSubtargetInfo &STI)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header, const MCSubtargetInfo *STI)
bool isInlinableLiteralV2BF16(uint32_t Literal)
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
unsigned mc2PseudoReg(unsigned Reg)
Convert hardware register Reg to a pseudo register.
bool hasA16(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset, bool IsBuffer)
bool isGFX12Plus(const MCSubtargetInfo &STI)
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool isHsaAbi(const MCSubtargetInfo &STI)
bool isGFX11(const MCSubtargetInfo &STI)
const int OPR_VAL_INVALID
bool getSMEMIsBuffer(unsigned Opc)
IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
bool isDPALU_DPP(const MCInstrDesc &OpDesc)
bool isSI(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
bool isGFX9(const MCSubtargetInfo &STI)
bool isGFX10_AEncoding(const MCSubtargetInfo &STI)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this an AMDGPU specific source operand? These include registers, inline constants,...
bool hasMAIInsts(const MCSubtargetInfo &STI)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, uint64_t NamedIdx)
LLVM_READNONE bool isInlinableIntLiteral(int64_t Literal)
Is this literal inlinable, and not one of the values intended for floating point values.
bool isSGPR(unsigned Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
bool isHi(unsigned Reg, const MCRegisterInfo &MRI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isInlineValue(unsigned Reg)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_V2INT32
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_INLINE_AC_V2FP16
@ OPERAND_REG_IMM_INT32
Operands with register or 32-bit immediate.
@ OPERAND_REG_IMM_BF16_DEFERRED
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_AC_BF16
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_INLINE_AC_INT16
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_V2INT16
@ OPERAND_REG_INLINE_AC_FP16
@ OPERAND_REG_INLINE_AC_INT32
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_INLINE_AC_V2BF16
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_REG_INLINE_C_V2FP32
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
@ OPERAND_REG_IMM_FP32_DEFERRED
@ OPERAND_REG_IMM_FP16_DEFERRED
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isVI(const MCSubtargetInfo &STI)
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
Reg
All possible values of the reg field in the ModR/M byte.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
int popcount(T Value) noexcept
Count the number of set bits in a value.
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator)
Returns the integer ceil(Numerator / Denominator).
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool parseAmdKernelCodeField(StringRef ID, MCAsmParser &Parser, amd_kernel_code_t &C, raw_ostream &Err)
AMD Kernel Code Object (amd_kernel_code_t).
Instruction set architecture version.
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
const MCExpr * compute_pgm_rsrc1
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * group_segment_fixed_size
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * kernel_code_properties
Represents the counter values to wait for in an s_waitcnt instruction.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static const fltSemantics & IEEEhalf() LLVM_READNONE
static const fltSemantics & BFloat() LLVM_READNONE
opStatus
IEEE-754R 7: Default exception handling.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Description of the encoding of one expression Op.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size