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 if (hasIntModifiers())
105 return getIntModifiersOperand();
186 ImmKindTyMandatoryLiteral,
200 mutable ImmKindTy
Kind;
217 bool isToken()
const override {
return Kind == Token; }
219 bool isSymbolRefExpr()
const {
220 return isExpr() && Expr && isa<MCSymbolRefExpr>(Expr);
223 bool isImm()
const override {
224 return Kind == Immediate;
227 void setImmKindNone()
const {
229 Imm.Kind = ImmKindTyNone;
232 void setImmKindLiteral()
const {
234 Imm.Kind = ImmKindTyLiteral;
237 void setImmKindMandatoryLiteral()
const {
239 Imm.Kind = ImmKindTyMandatoryLiteral;
242 void setImmKindConst()
const {
244 Imm.Kind = ImmKindTyConst;
247 bool IsImmKindLiteral()
const {
248 return isImm() &&
Imm.Kind == ImmKindTyLiteral;
251 bool IsImmKindMandatoryLiteral()
const {
252 return isImm() &&
Imm.Kind == ImmKindTyMandatoryLiteral;
255 bool isImmKindConst()
const {
256 return isImm() &&
Imm.Kind == ImmKindTyConst;
259 bool isInlinableImm(
MVT type)
const;
260 bool isLiteralImm(
MVT type)
const;
262 bool isRegKind()
const {
266 bool isReg()
const override {
267 return isRegKind() && !hasModifiers();
270 bool isRegOrInline(
unsigned RCID,
MVT type)
const {
271 return isRegClass(RCID) || isInlinableImm(type);
275 return isRegOrInline(RCID, type) || isLiteralImm(type);
278 bool isRegOrImmWithInt16InputMods()
const {
282 bool isRegOrImmWithIntT16InputMods()
const {
286 bool isRegOrImmWithInt32InputMods()
const {
290 bool isRegOrInlineImmWithInt16InputMods()
const {
291 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
294 bool isRegOrInlineImmWithInt32InputMods()
const {
295 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
298 bool isRegOrImmWithInt64InputMods()
const {
302 bool isRegOrImmWithFP16InputMods()
const {
306 bool isRegOrImmWithFPT16InputMods()
const {
310 bool isRegOrImmWithFP32InputMods()
const {
314 bool isRegOrImmWithFP64InputMods()
const {
318 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
319 return isRegOrInline(
320 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
323 bool isRegOrInlineImmWithFP32InputMods()
const {
324 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
327 bool isPackedFP16InputMods()
const {
331 bool isVReg()
const {
332 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
333 isRegClass(AMDGPU::VReg_64RegClassID) ||
334 isRegClass(AMDGPU::VReg_96RegClassID) ||
335 isRegClass(AMDGPU::VReg_128RegClassID) ||
336 isRegClass(AMDGPU::VReg_160RegClassID) ||
337 isRegClass(AMDGPU::VReg_192RegClassID) ||
338 isRegClass(AMDGPU::VReg_256RegClassID) ||
339 isRegClass(AMDGPU::VReg_512RegClassID) ||
340 isRegClass(AMDGPU::VReg_1024RegClassID);
343 bool isVReg32()
const {
344 return isRegClass(AMDGPU::VGPR_32RegClassID);
347 bool isVReg32OrOff()
const {
348 return isOff() || isVReg32();
351 bool isNull()
const {
352 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
355 bool isVRegWithInputMods()
const;
356 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
358 bool isSDWAOperand(
MVT type)
const;
359 bool isSDWAFP16Operand()
const;
360 bool isSDWAFP32Operand()
const;
361 bool isSDWAInt16Operand()
const;
362 bool isSDWAInt32Operand()
const;
364 bool isImmTy(ImmTy ImmT)
const {
368 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
370 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
372 bool isImmModifier()
const {
373 return isImm() &&
Imm.Type != ImmTyNone;
376 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
377 bool isDim()
const {
return isImmTy(ImmTyDim); }
378 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
379 bool isOff()
const {
return isImmTy(ImmTyOff); }
380 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
381 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
382 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
383 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
384 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
385 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
386 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
387 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
388 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
389 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
390 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
391 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
392 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) && isUInt<7>(getImm()); }
393 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
394 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
395 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
396 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
397 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
398 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
399 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
400 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
401 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
402 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
403 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
404 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
406 bool isRegOrImm()
const {
410 bool isRegClass(
unsigned RCID)
const;
414 bool isRegOrInlineNoMods(
unsigned RCID,
MVT type)
const {
415 return isRegOrInline(RCID, type) && !hasModifiers();
418 bool isSCSrcB16()
const {
419 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
422 bool isSCSrcV2B16()
const {
426 bool isSCSrc_b32()
const {
427 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
430 bool isSCSrc_b64()
const {
431 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
434 bool isBoolReg()
const;
436 bool isSCSrcF16()
const {
437 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
440 bool isSCSrcV2F16()
const {
444 bool isSCSrcF32()
const {
445 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
448 bool isSCSrcF64()
const {
449 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
452 bool isSSrc_b32()
const {
453 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
456 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
458 bool isSSrcV2B16()
const {
463 bool isSSrc_b64()
const {
466 return isSCSrc_b64() || isLiteralImm(MVT::i64);
469 bool isSSrc_f32()
const {
470 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
473 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
475 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
477 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
479 bool isSSrcV2F16()
const {
484 bool isSSrcV2FP32()
const {
489 bool isSCSrcV2FP32()
const {
494 bool isSSrcV2INT32()
const {
499 bool isSCSrcV2INT32()
const {
501 return isSCSrc_b32();
504 bool isSSrcOrLds_b32()
const {
505 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
506 isLiteralImm(MVT::i32) || isExpr();
509 bool isVCSrc_b32()
const {
510 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
513 bool isVCSrcB64()
const {
514 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
517 bool isVCSrcTB16()
const {
518 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
521 bool isVCSrcTB16_Lo128()
const {
522 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
525 bool isVCSrcFake16B16_Lo128()
const {
526 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
529 bool isVCSrc_b16()
const {
530 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
533 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
535 bool isVCSrc_f32()
const {
536 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
539 bool isVCSrcF64()
const {
540 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
543 bool isVCSrcTBF16()
const {
544 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
547 bool isVCSrcTF16()
const {
548 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
551 bool isVCSrcTBF16_Lo128()
const {
552 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
555 bool isVCSrcTF16_Lo128()
const {
556 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
559 bool isVCSrcFake16BF16_Lo128()
const {
560 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
563 bool isVCSrcFake16F16_Lo128()
const {
564 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
567 bool isVCSrc_bf16()
const {
568 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
571 bool isVCSrc_f16()
const {
572 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
575 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
577 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
579 bool isVSrc_b32()
const {
580 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
583 bool isVSrc_b64()
const {
return isVCSrcF64() || isLiteralImm(MVT::i64); }
585 bool isVSrcT_b16()
const {
return isVCSrcTB16() || isLiteralImm(MVT::i16); }
587 bool isVSrcT_b16_Lo128()
const {
588 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
591 bool isVSrcFake16_b16_Lo128()
const {
592 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
595 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
597 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
599 bool isVCSrcV2FP32()
const {
603 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
605 bool isVCSrcV2INT32()
const {
609 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
611 bool isVSrc_f32()
const {
612 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
615 bool isVSrc_f64()
const {
return isVCSrcF64() || isLiteralImm(MVT::f64); }
617 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
619 bool isVSrcT_f16()
const {
return isVCSrcTF16() || isLiteralImm(MVT::f16); }
621 bool isVSrcT_bf16_Lo128()
const {
622 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
625 bool isVSrcT_f16_Lo128()
const {
626 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
629 bool isVSrcFake16_bf16_Lo128()
const {
630 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
633 bool isVSrcFake16_f16_Lo128()
const {
634 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
637 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
639 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
641 bool isVSrc_v2bf16()
const {
642 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
645 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
647 bool isVISrcB32()
const {
648 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
651 bool isVISrcB16()
const {
652 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
655 bool isVISrcV2B16()
const {
659 bool isVISrcF32()
const {
660 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
663 bool isVISrcF16()
const {
664 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
667 bool isVISrcV2F16()
const {
668 return isVISrcF16() || isVISrcB32();
671 bool isVISrc_64_bf16()
const {
672 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
675 bool isVISrc_64_f16()
const {
676 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
679 bool isVISrc_64_b32()
const {
680 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
683 bool isVISrc_64B64()
const {
684 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
687 bool isVISrc_64_f64()
const {
688 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
691 bool isVISrc_64V2FP32()
const {
692 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
695 bool isVISrc_64V2INT32()
const {
696 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
699 bool isVISrc_256_b32()
const {
700 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
703 bool isVISrc_256_f32()
const {
704 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
707 bool isVISrc_256B64()
const {
708 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
711 bool isVISrc_256_f64()
const {
712 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
715 bool isVISrc_128B16()
const {
716 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
719 bool isVISrc_128V2B16()
const {
720 return isVISrc_128B16();
723 bool isVISrc_128_b32()
const {
724 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
727 bool isVISrc_128_f32()
const {
728 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
731 bool isVISrc_256V2FP32()
const {
732 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
735 bool isVISrc_256V2INT32()
const {
736 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
739 bool isVISrc_512_b32()
const {
740 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
743 bool isVISrc_512B16()
const {
744 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
747 bool isVISrc_512V2B16()
const {
748 return isVISrc_512B16();
751 bool isVISrc_512_f32()
const {
752 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
755 bool isVISrc_512F16()
const {
756 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
759 bool isVISrc_512V2F16()
const {
760 return isVISrc_512F16() || isVISrc_512_b32();
763 bool isVISrc_1024_b32()
const {
764 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
767 bool isVISrc_1024B16()
const {
768 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
771 bool isVISrc_1024V2B16()
const {
772 return isVISrc_1024B16();
775 bool isVISrc_1024_f32()
const {
776 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
779 bool isVISrc_1024F16()
const {
780 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
783 bool isVISrc_1024V2F16()
const {
784 return isVISrc_1024F16() || isVISrc_1024_b32();
787 bool isAISrcB32()
const {
788 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
791 bool isAISrcB16()
const {
792 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
795 bool isAISrcV2B16()
const {
799 bool isAISrcF32()
const {
800 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
803 bool isAISrcF16()
const {
804 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
807 bool isAISrcV2F16()
const {
808 return isAISrcF16() || isAISrcB32();
811 bool isAISrc_64B64()
const {
812 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
815 bool isAISrc_64_f64()
const {
816 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
819 bool isAISrc_128_b32()
const {
820 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
823 bool isAISrc_128B16()
const {
824 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
827 bool isAISrc_128V2B16()
const {
828 return isAISrc_128B16();
831 bool isAISrc_128_f32()
const {
832 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
835 bool isAISrc_128F16()
const {
836 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
839 bool isAISrc_128V2F16()
const {
840 return isAISrc_128F16() || isAISrc_128_b32();
843 bool isVISrc_128_bf16()
const {
844 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
847 bool isVISrc_128_f16()
const {
848 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
851 bool isVISrc_128V2F16()
const {
852 return isVISrc_128_f16() || isVISrc_128_b32();
855 bool isAISrc_256B64()
const {
856 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
859 bool isAISrc_256_f64()
const {
860 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
863 bool isAISrc_512_b32()
const {
864 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
867 bool isAISrc_512B16()
const {
868 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
871 bool isAISrc_512V2B16()
const {
872 return isAISrc_512B16();
875 bool isAISrc_512_f32()
const {
876 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
879 bool isAISrc_512F16()
const {
880 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
883 bool isAISrc_512V2F16()
const {
884 return isAISrc_512F16() || isAISrc_512_b32();
887 bool isAISrc_1024_b32()
const {
888 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
891 bool isAISrc_1024B16()
const {
892 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
895 bool isAISrc_1024V2B16()
const {
896 return isAISrc_1024B16();
899 bool isAISrc_1024_f32()
const {
900 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
903 bool isAISrc_1024F16()
const {
904 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
907 bool isAISrc_1024V2F16()
const {
908 return isAISrc_1024F16() || isAISrc_1024_b32();
911 bool isKImmFP32()
const {
912 return isLiteralImm(MVT::f32);
915 bool isKImmFP16()
const {
916 return isLiteralImm(MVT::f16);
919 bool isMem()
const override {
923 bool isExpr()
const {
927 bool isSOPPBrTarget()
const {
return isExpr() ||
isImm(); }
929 bool isSWaitCnt()
const;
930 bool isDepCtr()
const;
931 bool isSDelayALU()
const;
932 bool isHwreg()
const;
933 bool isSendMsg()
const;
934 bool isSplitBarrier()
const;
935 bool isSwizzle()
const;
936 bool isSMRDOffset8()
const;
937 bool isSMEMOffset()
const;
938 bool isSMRDLiteralOffset()
const;
940 bool isDPPCtrl()
const;
942 bool isGPRIdxMode()
const;
943 bool isS16Imm()
const;
944 bool isU16Imm()
const;
945 bool isEndpgm()
const;
947 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
948 return [=](){
return P(*
this); };
956 int64_t getImm()
const {
961 void setImm(int64_t Val) {
966 ImmTy getImmTy()
const {
976 SMLoc getStartLoc()
const override {
980 SMLoc getEndLoc()
const override {
985 return SMRange(StartLoc, EndLoc);
988 Modifiers getModifiers()
const {
989 assert(isRegKind() || isImmTy(ImmTyNone));
990 return isRegKind() ?
Reg.Mods :
Imm.Mods;
993 void setModifiers(Modifiers Mods) {
994 assert(isRegKind() || isImmTy(ImmTyNone));
1001 bool hasModifiers()
const {
1002 return getModifiers().hasModifiers();
1005 bool hasFPModifiers()
const {
1006 return getModifiers().hasFPModifiers();
1009 bool hasIntModifiers()
const {
1010 return getModifiers().hasIntModifiers();
1015 void addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1017 void addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1019 void addRegOperands(
MCInst &Inst,
unsigned N)
const;
1021 void addRegOrImmOperands(
MCInst &Inst,
unsigned N)
const {
1023 addRegOperands(Inst,
N);
1025 addImmOperands(Inst,
N);
1028 void addRegOrImmWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1029 Modifiers Mods = getModifiers();
1032 addRegOperands(Inst,
N);
1034 addImmOperands(Inst,
N,
false);
1038 void addRegOrImmWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1039 assert(!hasIntModifiers());
1040 addRegOrImmWithInputModsOperands(Inst,
N);
1043 void addRegOrImmWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1044 assert(!hasFPModifiers());
1045 addRegOrImmWithInputModsOperands(Inst,
N);
1048 void addRegWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1049 Modifiers Mods = getModifiers();
1052 addRegOperands(Inst,
N);
1055 void addRegWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1056 assert(!hasIntModifiers());
1057 addRegWithInputModsOperands(Inst,
N);
1060 void addRegWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1061 assert(!hasFPModifiers());
1062 addRegWithInputModsOperands(Inst,
N);
1068 case ImmTyNone:
OS <<
"None";
break;
1069 case ImmTyGDS:
OS <<
"GDS";
break;
1070 case ImmTyLDS:
OS <<
"LDS";
break;
1071 case ImmTyOffen:
OS <<
"Offen";
break;
1072 case ImmTyIdxen:
OS <<
"Idxen";
break;
1073 case ImmTyAddr64:
OS <<
"Addr64";
break;
1074 case ImmTyOffset:
OS <<
"Offset";
break;
1075 case ImmTyInstOffset:
OS <<
"InstOffset";
break;
1076 case ImmTyOffset0:
OS <<
"Offset0";
break;
1077 case ImmTyOffset1:
OS <<
"Offset1";
break;
1078 case ImmTySMEMOffsetMod:
OS <<
"SMEMOffsetMod";
break;
1079 case ImmTyCPol:
OS <<
"CPol";
break;
1080 case ImmTyIndexKey8bit:
OS <<
"index_key";
break;
1081 case ImmTyIndexKey16bit:
OS <<
"index_key";
break;
1082 case ImmTyTFE:
OS <<
"TFE";
break;
1083 case ImmTyD16:
OS <<
"D16";
break;
1084 case ImmTyFORMAT:
OS <<
"FORMAT";
break;
1085 case ImmTyClamp:
OS <<
"Clamp";
break;
1086 case ImmTyOModSI:
OS <<
"OModSI";
break;
1087 case ImmTyDPP8:
OS <<
"DPP8";
break;
1088 case ImmTyDppCtrl:
OS <<
"DppCtrl";
break;
1089 case ImmTyDppRowMask:
OS <<
"DppRowMask";
break;
1090 case ImmTyDppBankMask:
OS <<
"DppBankMask";
break;
1091 case ImmTyDppBoundCtrl:
OS <<
"DppBoundCtrl";
break;
1092 case ImmTyDppFI:
OS <<
"DppFI";
break;
1093 case ImmTySDWADstSel:
OS <<
"SDWADstSel";
break;
1094 case ImmTySDWASrc0Sel:
OS <<
"SDWASrc0Sel";
break;
1095 case ImmTySDWASrc1Sel:
OS <<
"SDWASrc1Sel";
break;
1096 case ImmTySDWADstUnused:
OS <<
"SDWADstUnused";
break;
1097 case ImmTyDMask:
OS <<
"DMask";
break;
1098 case ImmTyDim:
OS <<
"Dim";
break;
1099 case ImmTyUNorm:
OS <<
"UNorm";
break;
1100 case ImmTyDA:
OS <<
"DA";
break;
1101 case ImmTyR128A16:
OS <<
"R128A16";
break;
1102 case ImmTyA16:
OS <<
"A16";
break;
1103 case ImmTyLWE:
OS <<
"LWE";
break;
1104 case ImmTyOff:
OS <<
"Off";
break;
1105 case ImmTyExpTgt:
OS <<
"ExpTgt";
break;
1106 case ImmTyExpCompr:
OS <<
"ExpCompr";
break;
1107 case ImmTyExpVM:
OS <<
"ExpVM";
break;
1108 case ImmTyHwreg:
OS <<
"Hwreg";
break;
1109 case ImmTySendMsg:
OS <<
"SendMsg";
break;
1110 case ImmTyInterpSlot:
OS <<
"InterpSlot";
break;
1111 case ImmTyInterpAttr:
OS <<
"InterpAttr";
break;
1112 case ImmTyInterpAttrChan:
OS <<
"InterpAttrChan";
break;
1113 case ImmTyOpSel:
OS <<
"OpSel";
break;
1114 case ImmTyOpSelHi:
OS <<
"OpSelHi";
break;
1115 case ImmTyNegLo:
OS <<
"NegLo";
break;
1116 case ImmTyNegHi:
OS <<
"NegHi";
break;
1117 case ImmTySwizzle:
OS <<
"Swizzle";
break;
1118 case ImmTyGprIdxMode:
OS <<
"GprIdxMode";
break;
1119 case ImmTyHigh:
OS <<
"High";
break;
1120 case ImmTyBLGP:
OS <<
"BLGP";
break;
1121 case ImmTyCBSZ:
OS <<
"CBSZ";
break;
1122 case ImmTyABID:
OS <<
"ABID";
break;
1123 case ImmTyEndpgm:
OS <<
"Endpgm";
break;
1124 case ImmTyWaitVDST:
OS <<
"WaitVDST";
break;
1125 case ImmTyWaitEXP:
OS <<
"WaitEXP";
break;
1126 case ImmTyWaitVAVDst:
OS <<
"WaitVAVDst";
break;
1127 case ImmTyWaitVMVSrc:
OS <<
"WaitVMVSrc";
break;
1128 case ImmTyByteSel:
OS <<
"ByteSel" ;
break;
1136 OS <<
"<register " <<
getReg() <<
" mods: " <<
Reg.Mods <<
'>';
1139 OS <<
'<' << getImm();
1140 if (getImmTy() != ImmTyNone) {
1141 OS <<
" type: "; printImmTy(
OS, getImmTy());
1143 OS <<
" mods: " <<
Imm.Mods <<
'>';
1146 OS <<
'\'' << getToken() <<
'\'';
1149 OS <<
"<expr " << *Expr <<
'>';
1154 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1155 int64_t Val,
SMLoc Loc,
1156 ImmTy
Type = ImmTyNone,
1157 bool IsFPImm =
false) {
1158 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1160 Op->Imm.IsFPImm = IsFPImm;
1161 Op->Imm.Kind = ImmKindTyNone;
1163 Op->Imm.Mods = Modifiers();
1169 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1171 bool HasExplicitEncodingSize =
true) {
1172 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1173 Res->Tok.Data = Str.data();
1174 Res->Tok.Length = Str.size();
1175 Res->StartLoc = Loc;
1180 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1181 unsigned RegNo,
SMLoc S,
1183 auto Op = std::make_unique<AMDGPUOperand>(
Register, AsmParser);
1184 Op->Reg.RegNo = RegNo;
1185 Op->Reg.Mods = Modifiers();
1191 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1193 auto Op = std::make_unique<AMDGPUOperand>(
Expression, AsmParser);
1202 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1213class KernelScopeInfo {
1214 int SgprIndexUnusedMin = -1;
1215 int VgprIndexUnusedMin = -1;
1216 int AgprIndexUnusedMin = -1;
1220 void usesSgprAt(
int i) {
1221 if (i >= SgprIndexUnusedMin) {
1222 SgprIndexUnusedMin = ++i;
1231 void usesVgprAt(
int i) {
1232 if (i >= VgprIndexUnusedMin) {
1233 VgprIndexUnusedMin = ++i;
1238 VgprIndexUnusedMin);
1244 void usesAgprAt(
int i) {
1249 if (i >= AgprIndexUnusedMin) {
1250 AgprIndexUnusedMin = ++i;
1260 VgprIndexUnusedMin);
1267 KernelScopeInfo() =
default;
1273 usesSgprAt(SgprIndexUnusedMin = -1);
1274 usesVgprAt(VgprIndexUnusedMin = -1);
1276 usesAgprAt(AgprIndexUnusedMin = -1);
1280 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1281 unsigned RegWidth) {
1284 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1287 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1290 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1301 unsigned ForcedEncodingSize = 0;
1302 bool ForcedDPP =
false;
1303 bool ForcedSDWA =
false;
1304 KernelScopeInfo KernelScope;
1309#define GET_ASSEMBLER_HEADER
1310#include "AMDGPUGenAsmMatcher.inc"
1315 void createConstantSymbol(
StringRef Id, int64_t Val);
1317 bool ParseAsAbsoluteExpression(
uint32_t &Ret);
1335 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1336 std::optional<bool> EnableWavefrontSize32,
1340 bool ParseDirectiveAMDGCNTarget();
1341 bool ParseDirectiveAMDHSACodeObjectVersion();
1342 bool ParseDirectiveAMDHSAKernel();
1344 bool ParseDirectiveAMDKernelCodeT();
1347 bool ParseDirectiveAMDGPUHsaKernel();
1349 bool ParseDirectiveISAVersion();
1350 bool ParseDirectiveHSAMetadata();
1351 bool ParseDirectivePALMetadataBegin();
1352 bool ParseDirectivePALMetadata();
1353 bool ParseDirectiveAMDGPULDS();
1357 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1358 const char *AssemblerDirectiveEnd,
1359 std::string &CollectString);
1361 bool AddNextRegisterToList(
unsigned& Reg,
unsigned& RegWidth,
1362 RegisterKind RegKind,
unsigned Reg1,
SMLoc Loc);
1363 bool ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
1364 unsigned &RegNum,
unsigned &RegWidth,
1365 bool RestoreOnFailure =
false);
1366 bool ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
1367 unsigned &RegNum,
unsigned &RegWidth,
1369 unsigned ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1372 unsigned ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1375 unsigned ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1377 bool ParseRegRange(
unsigned& Num,
unsigned& Width);
1378 unsigned getRegularReg(RegisterKind RegKind,
unsigned RegNum,
unsigned SubReg,
1379 unsigned RegWidth,
SMLoc Loc);
1383 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1384 void initializeGprCountSymbol(RegisterKind RegKind);
1385 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1392 OperandMode_Default,
1396 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1404 if (getFeatureBits().
none()) {
1410 if (!FB[AMDGPU::FeatureWavefrontSize64] &&
1411 !FB[AMDGPU::FeatureWavefrontSize32]) {
1422 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1423 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1424 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1426 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1427 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1428 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1431 initializeGprCountSymbol(IS_VGPR);
1432 initializeGprCountSymbol(IS_SGPR);
1437 createConstantSymbol(Symbol, Code);
1439 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1440 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1441 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1511 bool hasInv2PiInlineImm()
const {
1512 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1515 bool hasFlatOffsets()
const {
1516 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1520 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1523 bool hasSGPR102_SGPR103()
const {
1527 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1529 bool hasIntClamp()
const {
1530 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1533 bool hasPartialNSAEncoding()
const {
1534 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1566 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1567 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1568 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1570 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1571 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1572 bool isForcedDPP()
const {
return ForcedDPP; }
1573 bool isForcedSDWA()
const {
return ForcedSDWA; }
1575 StringRef getMatchedVariantName()
const;
1577 std::unique_ptr<AMDGPUOperand>
parseRegister(
bool RestoreOnFailure =
false);
1579 bool RestoreOnFailure);
1582 SMLoc &EndLoc)
override;
1585 unsigned Kind)
override;
1589 bool MatchingInlineAsm)
override;
1592 OperandMode Mode = OperandMode_Default);
1600 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1604 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1605 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1609 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1610 bool (*ConvertResult)(int64_t &) =
nullptr);
1614 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1623 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1624 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1625 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1626 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1627 bool parseSP3NegModifier();
1629 bool HasLit =
false);
1632 bool HasLit =
false);
1634 bool AllowImm =
true);
1636 bool AllowImm =
true);
1641 AMDGPUOperand::ImmTy ImmTy);
1652 ParseStatus parseSymbolicOrNumericFormat(int64_t &Format);
1657 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1658 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt,
StringRef FormatStr,
SMLoc Loc);
1662 bool parseCnt(int64_t &IntVal);
1665 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1669 bool parseDelay(int64_t &Delay);
1675 struct OperandInfoTy {
1678 bool IsSymbolic =
false;
1679 bool IsDefined =
false;
1681 OperandInfoTy(int64_t Val) : Val(Val) {}
1684 struct StructuredOpField : OperandInfoTy {
1688 bool IsDefined =
false;
1693 virtual ~StructuredOpField() =
default;
1695 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1696 Parser.Error(Loc,
"invalid " +
Desc +
": " + Err);
1700 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1702 return Error(Parser,
"not supported on this GPU");
1704 return Error(Parser,
"only " +
Twine(Width) +
"-bit values are legal");
1712 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1713 bool validateSendMsg(
const OperandInfoTy &Msg,
1714 const OperandInfoTy &
Op,
1715 const OperandInfoTy &Stream);
1718 OperandInfoTy &Width);
1724 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1729 bool SearchMandatoryLiterals =
false)
const;
1738 bool validateSOPLiteral(
const MCInst &Inst)
const;
1740 bool validateVOPDRegBankConstraints(
const MCInst &Inst,
1742 bool validateIntClampSupported(
const MCInst &Inst);
1743 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1744 bool validateMIMGGatherDMask(
const MCInst &Inst);
1746 bool validateMIMGDataSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1747 bool validateMIMGAddrSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1748 bool validateMIMGD16(
const MCInst &Inst);
1749 bool validateMIMGMSAA(
const MCInst &Inst);
1750 bool validateOpSel(
const MCInst &Inst);
1753 bool validateVccOperand(
unsigned Reg)
const;
1758 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1759 bool validateVGPRAlign(
const MCInst &Inst)
const;
1763 bool validateDivScale(
const MCInst &Inst);
1766 const SMLoc &IDLoc);
1768 const unsigned CPol);
1771 std::optional<StringRef> validateLdsDirect(
const MCInst &Inst);
1772 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1773 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1774 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1775 unsigned findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1801 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1803 SMLoc getLoc()
const;
1807 void onBeginOfFile()
override;
1808 bool parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc)
override;
1819 bool parseSwizzleOperand(int64_t &
Op,
1820 const unsigned MinVal,
1821 const unsigned MaxVal,
1824 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1825 const unsigned MinVal,
1826 const unsigned MaxVal,
1829 bool parseSwizzleOffset(int64_t &Imm);
1830 bool parseSwizzleMacro(int64_t &Imm);
1831 bool parseSwizzleQuadPerm(int64_t &Imm);
1832 bool parseSwizzleBitmaskPerm(int64_t &Imm);
1833 bool parseSwizzleBroadcast(int64_t &Imm);
1834 bool parseSwizzleSwap(int64_t &Imm);
1835 bool parseSwizzleReverse(int64_t &Imm);
1838 int64_t parseGPRIdxMacro();
1846 OptionalImmIndexMap &OptionalIdx);
1854 OptionalImmIndexMap &OptionalIdx);
1856 OptionalImmIndexMap &OptionalIdx);
1861 bool parseDimId(
unsigned &Encoding);
1863 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1867 int64_t parseDPPCtrlSel(
StringRef Ctrl);
1868 int64_t parseDPPCtrlPerm();
1874 bool IsDPP8 =
false);
1880 AMDGPUOperand::ImmTy
Type);
1889 bool SkipDstVcc =
false,
1890 bool SkipSrcVcc =
false);
1903 return &APFloat::IEEEsingle();
1905 return &APFloat::IEEEdouble();
1907 return &APFloat::IEEEhalf();
1940 return &APFloat::IEEEsingle();
1946 return &APFloat::IEEEdouble();
1955 return &APFloat::IEEEhalf();
1963 return &APFloat::BFloat();
1978 APFloat::rmNearestTiesToEven,
1981 if (
Status != APFloat::opOK &&
1983 ((
Status & APFloat::opOverflow) != 0 ||
1984 (
Status & APFloat::opUnderflow) != 0)) {
2007bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2017 if (!isImmTy(ImmTyNone)) {
2028 if (type == MVT::f64 || type == MVT::i64) {
2030 AsmParser->hasInv2PiInlineImm());
2052 APFloat::rmNearestTiesToEven, &Lost);
2059 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2061 AsmParser->hasInv2PiInlineImm());
2066 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2067 AsmParser->hasInv2PiInlineImm());
2071 if (type == MVT::f64 || type == MVT::i64) {
2073 AsmParser->hasInv2PiInlineImm());
2082 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2083 type, AsmParser->hasInv2PiInlineImm());
2087 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2088 AsmParser->hasInv2PiInlineImm());
2091bool AMDGPUOperand::isLiteralImm(
MVT type)
const {
2093 if (!isImmTy(ImmTyNone)) {
2100 if (type == MVT::f64 && hasFPModifiers()) {
2117 if (type == MVT::f64) {
2122 if (type == MVT::i64) {
2135 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2136 : (type == MVT::v2i16) ? MVT::f32
2137 : (type == MVT::v2f32) ? MVT::f32
2144bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2145 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2148bool AMDGPUOperand::isVRegWithInputMods()
const {
2149 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2151 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2152 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2155template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2156 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2157 : AMDGPU::VGPR_16_Lo128RegClassID);
2160bool AMDGPUOperand::isSDWAOperand(
MVT type)
const {
2161 if (AsmParser->isVI())
2163 if (AsmParser->isGFX9Plus())
2164 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2168bool AMDGPUOperand::isSDWAFP16Operand()
const {
2169 return isSDWAOperand(MVT::f16);
2172bool AMDGPUOperand::isSDWAFP32Operand()
const {
2173 return isSDWAOperand(MVT::f32);
2176bool AMDGPUOperand::isSDWAInt16Operand()
const {
2177 return isSDWAOperand(MVT::i16);
2180bool AMDGPUOperand::isSDWAInt32Operand()
const {
2181 return isSDWAOperand(MVT::i32);
2184bool AMDGPUOperand::isBoolReg()
const {
2185 auto FB = AsmParser->getFeatureBits();
2186 return isReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrc_b64()) ||
2187 (FB[AMDGPU::FeatureWavefrontSize32] && isSCSrc_b32()));
2192 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2207void AMDGPUOperand::addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2215 addLiteralImmOperand(Inst,
Imm.Val,
2217 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2219 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2225void AMDGPUOperand::addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2226 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2231 if (ApplyModifiers) {
2234 Val = applyInputFPModifiers(Val,
Size);
2238 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2248 AsmParser->hasInv2PiInlineImm())) {
2257 if (
Literal.getLoBits(32) != 0) {
2258 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(Inst.
getLoc(),
2259 "Can't encode literal as exact 64-bit floating-point operand. "
2260 "Low 32-bits will be set to zero");
2261 Val &= 0xffffffff00000000u;
2265 setImmKindLiteral();
2281 if (AsmParser->hasInv2PiInlineImm() &&
Literal == 0x3fc45f306725feed) {
2287 setImmKindLiteral();
2323 APFloat::rmNearestTiesToEven, &lost);
2327 uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2330 setImmKindMandatoryLiteral();
2332 setImmKindLiteral();
2363 AsmParser->hasInv2PiInlineImm())) {
2370 setImmKindLiteral();
2388 setImmKindLiteral();
2402 setImmKindLiteral();
2411 AsmParser->hasInv2PiInlineImm())) {
2418 setImmKindLiteral();
2427 AsmParser->hasInv2PiInlineImm())) {
2434 setImmKindLiteral();
2448 AsmParser->hasInv2PiInlineImm()));
2458 AsmParser->hasInv2PiInlineImm()));
2466 setImmKindMandatoryLiteral();
2470 setImmKindMandatoryLiteral();
2477void AMDGPUOperand::addRegOperands(
MCInst &Inst,
unsigned N)
const {
2481bool AMDGPUOperand::isInlineValue()
const {
2489void AMDGPUAsmParser::createConstantSymbol(
StringRef Id, int64_t Val) {
2500 if (Is == IS_VGPR) {
2504 return AMDGPU::VGPR_32RegClassID;
2506 return AMDGPU::VReg_64RegClassID;
2508 return AMDGPU::VReg_96RegClassID;
2510 return AMDGPU::VReg_128RegClassID;
2512 return AMDGPU::VReg_160RegClassID;
2514 return AMDGPU::VReg_192RegClassID;
2516 return AMDGPU::VReg_224RegClassID;
2518 return AMDGPU::VReg_256RegClassID;
2520 return AMDGPU::VReg_288RegClassID;
2522 return AMDGPU::VReg_320RegClassID;
2524 return AMDGPU::VReg_352RegClassID;
2526 return AMDGPU::VReg_384RegClassID;
2528 return AMDGPU::VReg_512RegClassID;
2530 return AMDGPU::VReg_1024RegClassID;
2532 }
else if (Is == IS_TTMP) {
2536 return AMDGPU::TTMP_32RegClassID;
2538 return AMDGPU::TTMP_64RegClassID;
2540 return AMDGPU::TTMP_128RegClassID;
2542 return AMDGPU::TTMP_256RegClassID;
2544 return AMDGPU::TTMP_512RegClassID;
2546 }
else if (Is == IS_SGPR) {
2550 return AMDGPU::SGPR_32RegClassID;
2552 return AMDGPU::SGPR_64RegClassID;
2554 return AMDGPU::SGPR_96RegClassID;
2556 return AMDGPU::SGPR_128RegClassID;
2558 return AMDGPU::SGPR_160RegClassID;
2560 return AMDGPU::SGPR_192RegClassID;
2562 return AMDGPU::SGPR_224RegClassID;
2564 return AMDGPU::SGPR_256RegClassID;
2566 return AMDGPU::SGPR_288RegClassID;
2568 return AMDGPU::SGPR_320RegClassID;
2570 return AMDGPU::SGPR_352RegClassID;
2572 return AMDGPU::SGPR_384RegClassID;
2574 return AMDGPU::SGPR_512RegClassID;
2576 }
else if (Is == IS_AGPR) {
2580 return AMDGPU::AGPR_32RegClassID;
2582 return AMDGPU::AReg_64RegClassID;
2584 return AMDGPU::AReg_96RegClassID;
2586 return AMDGPU::AReg_128RegClassID;
2588 return AMDGPU::AReg_160RegClassID;
2590 return AMDGPU::AReg_192RegClassID;
2592 return AMDGPU::AReg_224RegClassID;
2594 return AMDGPU::AReg_256RegClassID;
2596 return AMDGPU::AReg_288RegClassID;
2598 return AMDGPU::AReg_320RegClassID;
2600 return AMDGPU::AReg_352RegClassID;
2602 return AMDGPU::AReg_384RegClassID;
2604 return AMDGPU::AReg_512RegClassID;
2606 return AMDGPU::AReg_1024RegClassID;
2614 .
Case(
"exec", AMDGPU::EXEC)
2615 .
Case(
"vcc", AMDGPU::VCC)
2616 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2617 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2618 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2619 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2620 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2621 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2622 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2623 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2624 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2625 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2626 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2627 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2628 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2629 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2630 .
Case(
"m0", AMDGPU::M0)
2631 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2632 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2633 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2634 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2635 .
Case(
"scc", AMDGPU::SRC_SCC)
2636 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2637 .
Case(
"tba", AMDGPU::TBA)
2638 .
Case(
"tma", AMDGPU::TMA)
2639 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2640 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2641 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2642 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2643 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2644 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2645 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2646 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2647 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2648 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2649 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2650 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2651 .
Case(
"pc", AMDGPU::PC_REG)
2652 .
Case(
"null", AMDGPU::SGPR_NULL)
2656bool AMDGPUAsmParser::ParseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
2657 SMLoc &EndLoc,
bool RestoreOnFailure) {
2658 auto R = parseRegister();
2659 if (!R)
return true;
2661 RegNo =
R->getReg();
2662 StartLoc =
R->getStartLoc();
2663 EndLoc =
R->getEndLoc();
2669 return ParseRegister(Reg, StartLoc, EndLoc,
false);
2674 bool Result = ParseRegister(Reg, StartLoc, EndLoc,
true);
2675 bool PendingErrors = getParser().hasPendingError();
2676 getParser().clearPendingErrors();
2684bool AMDGPUAsmParser::AddNextRegisterToList(
unsigned &Reg,
unsigned &RegWidth,
2685 RegisterKind RegKind,
unsigned Reg1,
2689 if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2694 if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2695 Reg = AMDGPU::FLAT_SCR;
2699 if (Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2700 Reg = AMDGPU::XNACK_MASK;
2704 if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2709 if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2714 if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2719 Error(Loc,
"register does not fit in the list");
2725 if (Reg1 != Reg + RegWidth / 32) {
2726 Error(Loc,
"registers in a list must have consecutive indices");
2744 {{
"ttmp"}, IS_TTMP},
2750 return Kind == IS_VGPR ||
2758 if (Str.starts_with(Reg.Name))
2764 return !Str.getAsInteger(10, Num);
2768AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2785 if (!RegSuffix.
empty()) {
2803AMDGPUAsmParser::isRegister()
2805 return isRegister(getToken(), peekToken());
2808unsigned AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2809 unsigned SubReg,
unsigned RegWidth,
2813 unsigned AlignSize = 1;
2814 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2820 if (RegNum % AlignSize != 0) {
2821 Error(Loc,
"invalid register alignment");
2822 return AMDGPU::NoRegister;
2825 unsigned RegIdx = RegNum / AlignSize;
2828 Error(Loc,
"invalid or unsupported register size");
2829 return AMDGPU::NoRegister;
2835 Error(Loc,
"register index is out of range");
2836 return AMDGPU::NoRegister;
2846 assert(Reg &&
"Invalid subregister!");
2852bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth) {
2853 int64_t RegLo, RegHi;
2857 SMLoc FirstIdxLoc = getLoc();
2864 SecondIdxLoc = getLoc();
2874 if (!isUInt<32>(RegLo)) {
2875 Error(FirstIdxLoc,
"invalid register index");
2879 if (!isUInt<32>(RegHi)) {
2880 Error(SecondIdxLoc,
"invalid register index");
2884 if (RegLo > RegHi) {
2885 Error(FirstIdxLoc,
"first register index should not exceed second index");
2889 Num =
static_cast<unsigned>(RegLo);
2890 RegWidth = 32 * ((RegHi - RegLo) + 1);
2894unsigned AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2895 unsigned &RegNum,
unsigned &RegWidth,
2902 RegKind = IS_SPECIAL;
2909unsigned AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2910 unsigned &RegNum,
unsigned &RegWidth,
2914 auto Loc = getLoc();
2918 Error(Loc,
"invalid register name");
2919 return AMDGPU::NoRegister;
2927 unsigned SubReg = NoSubRegister;
2928 if (!RegSuffix.
empty()) {
2940 Error(Loc,
"invalid register index");
2941 return AMDGPU::NoRegister;
2946 if (!ParseRegRange(RegNum, RegWidth))
2947 return AMDGPU::NoRegister;
2950 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
2953unsigned AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
2956 unsigned Reg = AMDGPU::NoRegister;
2957 auto ListLoc = getLoc();
2960 "expected a register or a list of registers")) {
2961 return AMDGPU::NoRegister;
2966 auto Loc = getLoc();
2967 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth))
2968 return AMDGPU::NoRegister;
2969 if (RegWidth != 32) {
2970 Error(Loc,
"expected a single 32-bit register");
2971 return AMDGPU::NoRegister;
2975 RegisterKind NextRegKind;
2976 unsigned NextReg, NextRegNum, NextRegWidth;
2979 if (!ParseAMDGPURegister(NextRegKind, NextReg,
2980 NextRegNum, NextRegWidth,
2982 return AMDGPU::NoRegister;
2984 if (NextRegWidth != 32) {
2985 Error(Loc,
"expected a single 32-bit register");
2986 return AMDGPU::NoRegister;
2988 if (NextRegKind != RegKind) {
2989 Error(Loc,
"registers in a list must be of the same kind");
2990 return AMDGPU::NoRegister;
2992 if (!AddNextRegisterToList(Reg, RegWidth, RegKind, NextReg, Loc))
2993 return AMDGPU::NoRegister;
2997 "expected a comma or a closing square bracket")) {
2998 return AMDGPU::NoRegister;
3002 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3007bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
3008 unsigned &RegNum,
unsigned &RegWidth,
3010 auto Loc = getLoc();
3011 Reg = AMDGPU::NoRegister;
3014 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3015 if (Reg == AMDGPU::NoRegister)
3016 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3018 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3022 if (Reg == AMDGPU::NoRegister) {
3023 assert(Parser.hasPendingError());
3027 if (!subtargetHasRegister(*
TRI, Reg)) {
3028 if (Reg == AMDGPU::SGPR_NULL) {
3029 Error(Loc,
"'null' operand is not supported on this GPU");
3031 Error(Loc,
"register not available on this GPU");
3039bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
3040 unsigned &RegNum,
unsigned &RegWidth,
3041 bool RestoreOnFailure ) {
3042 Reg = AMDGPU::NoRegister;
3045 if (ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, Tokens)) {
3046 if (RestoreOnFailure) {
3047 while (!Tokens.
empty()) {
3056std::optional<StringRef>
3057AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3060 return StringRef(
".amdgcn.next_free_vgpr");
3062 return StringRef(
".amdgcn.next_free_sgpr");
3064 return std::nullopt;
3068void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3069 auto SymbolName = getGprCountSymbolName(RegKind);
3070 assert(SymbolName &&
"initializing invalid register kind");
3071 MCSymbol *
Sym = getContext().getOrCreateSymbol(*SymbolName);
3075bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3076 unsigned DwordRegIndex,
3077 unsigned RegWidth) {
3082 auto SymbolName = getGprCountSymbolName(RegKind);
3085 MCSymbol *
Sym = getContext().getOrCreateSymbol(*SymbolName);
3087 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3090 if (!
Sym->isVariable())
3091 return !
Error(getLoc(),
3092 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3093 if (!
Sym->getVariableValue(
false)->evaluateAsAbsolute(OldCount))
3096 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3098 if (OldCount <= NewMax)
3104std::unique_ptr<AMDGPUOperand>
3105AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3106 const auto &Tok = getToken();
3107 SMLoc StartLoc = Tok.getLoc();
3108 SMLoc EndLoc = Tok.getEndLoc();
3109 RegisterKind RegKind;
3110 unsigned Reg, RegNum, RegWidth;
3112 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth)) {
3116 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3119 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3120 return AMDGPUOperand::CreateReg(
this, Reg, StartLoc, EndLoc);
3124 bool HasSP3AbsModifier,
bool HasLit) {
3132 HasLit = trySkipId(
"lit");
3144 const auto& Tok = getToken();
3145 const auto& NextTok = peekToken();
3148 bool Negate =
false;
3156 AMDGPUOperand::Modifiers Mods;
3167 APFloat RealVal(APFloat::IEEEdouble());
3168 auto roundMode = APFloat::rmNearestTiesToEven;
3169 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3172 RealVal.changeSign();
3175 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3176 AMDGPUOperand::ImmTyNone,
true));
3177 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3178 Op.setModifiers(Mods);
3187 if (HasSP3AbsModifier) {
3196 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3199 if (Parser.parseExpression(Expr))
3203 if (Expr->evaluateAsAbsolute(IntVal)) {
3204 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3205 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3206 Op.setModifiers(Mods);
3210 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3223 if (
auto R = parseRegister()) {
3232 bool HasSP3AbsMod,
bool HasLit) {
3238 return parseImm(
Operands, HasSP3AbsMod, HasLit);
3242AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3245 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3251AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3256AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3257 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3261AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3262 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3279AMDGPUAsmParser::isModifier() {
3283 peekTokens(NextToken);
3285 return isOperandModifier(Tok, NextToken[0]) ||
3286 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3287 isOpcodeModifierWithVal(Tok, NextToken[0]);
3313AMDGPUAsmParser::parseSP3NegModifier() {
3316 peekTokens(NextToken);
3319 (isRegister(NextToken[0], NextToken[1]) ||
3321 isId(NextToken[0],
"abs"))) {
3339 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3341 SP3Neg = parseSP3NegModifier();
3344 Neg = trySkipId(
"neg");
3346 return Error(Loc,
"expected register or immediate");
3350 Abs = trySkipId(
"abs");
3354 Lit = trySkipId(
"lit");
3361 return Error(Loc,
"expected register or immediate");
3365 Res = parseRegOrImm(
Operands, SP3Abs, Lit);
3372 if (Lit && !
Operands.back()->isImm())
3373 Error(Loc,
"expected immediate with lit modifier");
3375 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3384 AMDGPUOperand::Modifiers Mods;
3385 Mods.Abs = Abs || SP3Abs;
3386 Mods.Neg = Neg || SP3Neg;
3389 if (Mods.hasFPModifiers() || Lit) {
3390 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3392 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3393 Op.setModifiers(Mods);
3401 bool Sext = trySkipId(
"sext");
3402 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3417 AMDGPUOperand::Modifiers Mods;
3420 if (Mods.hasIntModifiers()) {
3421 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3423 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3424 Op.setModifiers(Mods);
3431 return parseRegOrImmWithFPInputMods(
Operands,
false);
3435 return parseRegOrImmWithIntInputMods(
Operands,
false);
3439 auto Loc = getLoc();
3440 if (trySkipId(
"off")) {
3441 Operands.push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3442 AMDGPUOperand::ImmTyOff,
false));
3449 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3451 Operands.push_back(std::move(Reg));
3458unsigned AMDGPUAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
3465 return Match_InvalidOperand;
3467 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3468 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3473 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3474 return Match_InvalidOperand;
3478 return Match_Success;
3482 static const unsigned Variants[] = {
3493 if (isForcedDPP() && isForcedVOP3()) {
3497 if (getForcedEncodingSize() == 32) {
3502 if (isForcedVOP3()) {
3507 if (isForcedSDWA()) {
3513 if (isForcedDPP()) {
3521StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3522 if (isForcedDPP() && isForcedVOP3())
3525 if (getForcedEncodingSize() == 32)
3540unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3544 case AMDGPU::FLAT_SCR:
3546 case AMDGPU::VCC_LO:
3547 case AMDGPU::VCC_HI:
3554 return AMDGPU::NoRegister;
3561bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3562 unsigned OpIdx)
const {
3572 int64_t Val = MO.
getImm();
3621unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3627 case AMDGPU::V_LSHLREV_B64_e64:
3628 case AMDGPU::V_LSHLREV_B64_gfx10:
3629 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3630 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3631 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3632 case AMDGPU::V_LSHRREV_B64_e64:
3633 case AMDGPU::V_LSHRREV_B64_gfx10:
3634 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3635 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3636 case AMDGPU::V_ASHRREV_I64_e64:
3637 case AMDGPU::V_ASHRREV_I64_gfx10:
3638 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3639 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3640 case AMDGPU::V_LSHL_B64_e64:
3641 case AMDGPU::V_LSHR_B64_e64:
3642 case AMDGPU::V_ASHR_I64_e64:
3655 bool AddMandatoryLiterals =
false) {
3661 int16_t ImmDeferredIdx =
3678bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3681 return !isInlineConstant(Inst, OpIdx);
3688 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3699 const unsigned Opcode = Inst.
getOpcode();
3700 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3703 if (!LaneSelOp.
isReg())
3706 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3709bool AMDGPUAsmParser::validateConstantBusLimitations(
3711 const unsigned Opcode = Inst.
getOpcode();
3713 unsigned LastSGPR = AMDGPU::NoRegister;
3714 unsigned ConstantBusUseCount = 0;
3715 unsigned NumLiterals = 0;
3716 unsigned LiteralSize;
3718 if (!(
Desc.TSFlags &
3734 unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3735 if (SGPRUsed != AMDGPU::NoRegister) {
3736 SGPRsUsed.
insert(SGPRUsed);
3737 ++ConstantBusUseCount;
3742 for (
int OpIdx : OpIndices) {
3747 if (usesConstantBus(Inst, OpIdx)) {
3756 if (SGPRsUsed.
insert(LastSGPR).second) {
3757 ++ConstantBusUseCount;
3777 if (NumLiterals == 0) {
3780 }
else if (LiteralSize !=
Size) {
3786 ConstantBusUseCount += NumLiterals;
3788 if (ConstantBusUseCount <= getConstantBusLimit(Opcode))
3794 Error(Loc,
"invalid operand (violates constant bus restrictions)");
3798bool AMDGPUAsmParser::validateVOPDRegBankConstraints(
3801 const unsigned Opcode = Inst.
getOpcode();
3807 auto getVRegIdx = [&](
unsigned,
unsigned OperandIdx) {
3815 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12;
3818 auto InvalidCompOprIdx =
3819 InstInfo.getInvalidCompOperandIndex(getVRegIdx, SkipSrc);
3820 if (!InvalidCompOprIdx)
3823 auto CompOprIdx = *InvalidCompOprIdx;
3825 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3826 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3829 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
3830 if (CompOprIdx == VOPD::Component::DST) {
3831 Error(Loc,
"one dst register must be even and the other odd");
3833 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3835 " operands must use different VGPR banks");
3841bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
3858bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
3859 const SMLoc &IDLoc) {
3877 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
3882 bool IsPackedD16 =
false;
3887 IsPackedD16 = D16Idx >= 0;
3889 DataSize = (DataSize + 1) / 2;
3892 if ((VDataSize / 4) == DataSize + TFESize)
3897 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
3899 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
3901 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
3905bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst,
3906 const SMLoc &IDLoc) {
3919 : AMDGPU::OpName::rsrc;
3926 assert(SrsrcIdx > VAddr0Idx);
3929 if (BaseOpcode->
BVH) {
3930 if (IsA16 == BaseOpcode->
A16)
3932 Error(IDLoc,
"image address size does not match a16");
3938 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
3939 unsigned ActualAddrSize =
3940 IsNSA ? SrsrcIdx - VAddr0Idx
3943 unsigned ExpectedAddrSize =
3947 if (hasPartialNSAEncoding() &&
3950 int VAddrLastIdx = SrsrcIdx - 1;
3951 unsigned VAddrLastSize =
3954 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
3957 if (ExpectedAddrSize > 12)
3958 ExpectedAddrSize = 16;
3963 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
3967 if (ActualAddrSize == ExpectedAddrSize)
3970 Error(IDLoc,
"image address size does not match dim and a16");
3974bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
3981 if (!
Desc.mayLoad() || !
Desc.mayStore())
3991 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
3994bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4010 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4013bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4024 if (!BaseOpcode->
MSAA)
4033 return DimInfo->
MSAA;
4039 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4040 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4041 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4051bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4075 Error(ErrLoc,
"source operand must be a VGPR");
4079bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4084 if (Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4098 "source operand must be either a VGPR or an inline constant");
4105bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4111 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4118 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4120 "inline constants are not allowed for this operand");
4127bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4145 if (Src2Reg == DstReg)
4149 if (
TRI->getRegClass(
Desc.operands()[0].RegClass).getSizeInBits() <= 128)
4152 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4154 "source 2 operand must not partially overlap with dst");
4161bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4165 case V_DIV_SCALE_F32_gfx6_gfx7:
4166 case V_DIV_SCALE_F32_vi:
4167 case V_DIV_SCALE_F32_gfx10:
4168 case V_DIV_SCALE_F64_gfx6_gfx7:
4169 case V_DIV_SCALE_F64_vi:
4170 case V_DIV_SCALE_F64_gfx10:
4176 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4177 AMDGPU::OpName::src2_modifiers,
4178 AMDGPU::OpName::src2_modifiers}) {
4189bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4209 case AMDGPU::V_SUBREV_F32_e32:
4210 case AMDGPU::V_SUBREV_F32_e64:
4211 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4212 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4213 case AMDGPU::V_SUBREV_F32_e32_vi:
4214 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4215 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4216 case AMDGPU::V_SUBREV_F32_e64_vi:
4218 case AMDGPU::V_SUBREV_CO_U32_e32:
4219 case AMDGPU::V_SUBREV_CO_U32_e64:
4220 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4221 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4223 case AMDGPU::V_SUBBREV_U32_e32:
4224 case AMDGPU::V_SUBBREV_U32_e64:
4225 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4226 case AMDGPU::V_SUBBREV_U32_e32_vi:
4227 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4228 case AMDGPU::V_SUBBREV_U32_e64_vi:
4230 case AMDGPU::V_SUBREV_U32_e32:
4231 case AMDGPU::V_SUBREV_U32_e64:
4232 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4233 case AMDGPU::V_SUBREV_U32_e32_vi:
4234 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4235 case AMDGPU::V_SUBREV_U32_e64_vi:
4237 case AMDGPU::V_SUBREV_F16_e32:
4238 case AMDGPU::V_SUBREV_F16_e64:
4239 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4240 case AMDGPU::V_SUBREV_F16_e32_vi:
4241 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4242 case AMDGPU::V_SUBREV_F16_e64_vi:
4244 case AMDGPU::V_SUBREV_U16_e32:
4245 case AMDGPU::V_SUBREV_U16_e64:
4246 case AMDGPU::V_SUBREV_U16_e32_vi:
4247 case AMDGPU::V_SUBREV_U16_e64_vi:
4249 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4250 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4251 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4253 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4254 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4256 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4257 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4259 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4260 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4262 case AMDGPU::V_LSHRREV_B32_e32:
4263 case AMDGPU::V_LSHRREV_B32_e64:
4264 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4265 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4266 case AMDGPU::V_LSHRREV_B32_e32_vi:
4267 case AMDGPU::V_LSHRREV_B32_e64_vi:
4268 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4269 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4271 case AMDGPU::V_ASHRREV_I32_e32:
4272 case AMDGPU::V_ASHRREV_I32_e64:
4273 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4274 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4275 case AMDGPU::V_ASHRREV_I32_e32_vi:
4276 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4277 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4278 case AMDGPU::V_ASHRREV_I32_e64_vi:
4280 case AMDGPU::V_LSHLREV_B32_e32:
4281 case AMDGPU::V_LSHLREV_B32_e64:
4282 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4283 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4284 case AMDGPU::V_LSHLREV_B32_e32_vi:
4285 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4286 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4287 case AMDGPU::V_LSHLREV_B32_e64_vi:
4289 case AMDGPU::V_LSHLREV_B16_e32:
4290 case AMDGPU::V_LSHLREV_B16_e64:
4291 case AMDGPU::V_LSHLREV_B16_e32_vi:
4292 case AMDGPU::V_LSHLREV_B16_e64_vi:
4293 case AMDGPU::V_LSHLREV_B16_gfx10:
4295 case AMDGPU::V_LSHRREV_B16_e32:
4296 case AMDGPU::V_LSHRREV_B16_e64:
4297 case AMDGPU::V_LSHRREV_B16_e32_vi:
4298 case AMDGPU::V_LSHRREV_B16_e64_vi:
4299 case AMDGPU::V_LSHRREV_B16_gfx10:
4301 case AMDGPU::V_ASHRREV_I16_e32:
4302 case AMDGPU::V_ASHRREV_I16_e64:
4303 case AMDGPU::V_ASHRREV_I16_e32_vi:
4304 case AMDGPU::V_ASHRREV_I16_e64_vi:
4305 case AMDGPU::V_ASHRREV_I16_gfx10:
4307 case AMDGPU::V_LSHLREV_B64_e64:
4308 case AMDGPU::V_LSHLREV_B64_gfx10:
4309 case AMDGPU::V_LSHLREV_B64_vi:
4311 case AMDGPU::V_LSHRREV_B64_e64:
4312 case AMDGPU::V_LSHRREV_B64_gfx10:
4313 case AMDGPU::V_LSHRREV_B64_vi:
4315 case AMDGPU::V_ASHRREV_I64_e64:
4316 case AMDGPU::V_ASHRREV_I64_gfx10:
4317 case AMDGPU::V_ASHRREV_I64_vi:
4319 case AMDGPU::V_PK_LSHLREV_B16:
4320 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4321 case AMDGPU::V_PK_LSHLREV_B16_vi:
4323 case AMDGPU::V_PK_LSHRREV_B16:
4324 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4325 case AMDGPU::V_PK_LSHRREV_B16_vi:
4326 case AMDGPU::V_PK_ASHRREV_I16:
4327 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4328 case AMDGPU::V_PK_ASHRREV_I16_vi:
4335std::optional<StringRef>
4336AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst) {
4338 using namespace SIInstrFlags;
4339 const unsigned Opcode = Inst.
getOpcode();
4345 if ((
Desc.TSFlags & Enc) == 0)
4346 return std::nullopt;
4348 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4353 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4356 return StringRef(
"lds_direct is not supported on this GPU");
4359 return StringRef(
"lds_direct cannot be used with this instruction");
4361 if (SrcName != OpName::src0)
4362 return StringRef(
"lds_direct may be used as src0 only");
4366 return std::nullopt;
4370 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4371 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4372 if (
Op.isFlatOffset())
4373 return Op.getStartLoc();
4378bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4387 return validateFlatOffset(Inst,
Operands);
4390 return validateSMEMOffset(Inst,
Operands);
4395 const unsigned OffsetSize = 24;
4396 if (!
isIntN(OffsetSize,
Op.getImm())) {
4398 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit signed offset");
4402 const unsigned OffsetSize = 16;
4403 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4405 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit unsigned offset");
4412bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4423 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4425 "flat offset modifier is not supported on this GPU");
4432 bool AllowNegative =
4435 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4437 Twine(
"expected a ") +
4438 (AllowNegative ?
Twine(OffsetSize) +
"-bit signed offset"
4439 :
Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4448 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4449 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4450 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4451 return Op.getStartLoc();
4456bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4482 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4483 :
"expected a 21-bit signed offset");
4488bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst)
const {
4497 const int OpIndices[] = { Src0Idx, Src1Idx };
4499 unsigned NumExprs = 0;
4500 unsigned NumLiterals = 0;
4503 for (
int OpIdx : OpIndices) {
4504 if (OpIdx == -1)
break;
4509 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4511 if (NumLiterals == 0 || LiteralValue !=
Value) {
4515 }
else if (MO.
isExpr()) {
4521 return NumLiterals + NumExprs <= 1;
4524bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4538 if (OpSelIdx != -1) {
4543 if (OpSelHiIdx != -1) {
4561bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst,
int OpName) {
4586 int SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4587 AMDGPU::OpName::src1_modifiers,
4588 AMDGPU::OpName::src2_modifiers};
4590 for (
unsigned i = 0; i < 3; ++i) {
4600bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4604 if (DppCtrlIdx >= 0) {
4611 Error(S,
"DP ALU dpp only supports row_newbcast");
4617 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4627 Error(S,
"invalid operand for instruction");
4632 "src1 immediate operand invalid for instruction");
4642bool AMDGPUAsmParser::validateVccOperand(
unsigned Reg)
const {
4643 auto FB = getFeatureBits();
4644 return (FB[AMDGPU::FeatureWavefrontSize64] && Reg == AMDGPU::VCC) ||
4645 (FB[AMDGPU::FeatureWavefrontSize32] &&
Reg == AMDGPU::VCC_LO);
4649bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
4655 !HasMandatoryLiteral && !
isVOPD(Opcode))
4660 unsigned NumExprs = 0;
4661 unsigned NumLiterals = 0;
4664 for (
int OpIdx : OpIndices) {
4674 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4680 if (!IsValid32Op && !isInt<32>(
Value) && !isUInt<32>(
Value)) {
4681 Error(getLitLoc(
Operands),
"invalid operand for instruction");
4685 if (IsFP64 && IsValid32Op)
4688 if (NumLiterals == 0 || LiteralValue !=
Value) {
4692 }
else if (MO.
isExpr()) {
4696 NumLiterals += NumExprs;
4701 if (!HasMandatoryLiteral && !getFeatureBits()[FeatureVOP3Literal]) {
4702 Error(getLitLoc(
Operands),
"literal operands are not supported");
4706 if (NumLiterals > 1) {
4707 Error(getLitLoc(
Operands,
true),
"only one unique literal operand is allowed");
4725 unsigned Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
4726 auto Reg = Sub ? Sub :
Op.getReg();
4728 return AGPR32.
contains(Reg) ? 1 : 0;
4731bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
4739 : AMDGPU::OpName::vdata;
4747 if (Data2Areg >= 0 && Data2Areg != DataAreg)
4751 auto FB = getFeatureBits();
4752 if (FB[AMDGPU::FeatureGFX90AInsts]) {
4753 if (DataAreg < 0 || DstAreg < 0)
4755 return DstAreg == DataAreg;
4758 return DstAreg < 1 && DataAreg < 1;
4761bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
4762 auto FB = getFeatureBits();
4763 if (!FB[AMDGPU::FeatureGFX90AInsts])
4774 unsigned Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
4778 if (VGPR32.
contains(Sub) && ((Sub - AMDGPU::VGPR0) & 1))
4780 if (AGPR32.
contains(Sub) && ((Sub - AMDGPU::AGPR0) & 1))
4788 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4789 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4791 return Op.getStartLoc();
4796bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
4806 auto FB = getFeatureBits();
4807 bool UsesNeg =
false;
4808 if (FB[AMDGPU::FeatureGFX940Insts]) {
4810 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
4811 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
4812 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
4813 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
4818 if (IsNeg == UsesNeg)
4822 UsesNeg ?
"invalid modifier: blgp is not supported"
4823 :
"invalid modifier: neg is not supported");
4828bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
4834 if (Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
4835 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
4836 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
4837 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
4843 if (Reg == AMDGPU::SGPR_NULL)
4847 Error(RegLoc,
"src0 must be null");
4851bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
4857 return validateGWS(Inst,
Operands);
4868 Error(S,
"gds modifier is not supported on this GPU");
4876bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
4878 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
4882 if (Opc != AMDGPU::DS_GWS_INIT_vi && Opc != AMDGPU::DS_GWS_BARRIER_vi &&
4883 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
4892 auto RegIdx =
Reg - (VGPR32.
contains(Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
4895 Error(RegLoc,
"vgpr must be even aligned");
4902bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
4904 const SMLoc &IDLoc) {
4906 AMDGPU::OpName::cpol);
4913 return validateTHAndScopeBits(Inst,
Operands, CPol);
4919 Error(S,
"cache policy is not supported for SMRD instructions");
4923 Error(IDLoc,
"invalid cache policy for SMEM instruction");
4932 if (!(TSFlags & AllowSCCModifier)) {
4937 "scc modifier is not supported for this instruction on this GPU");
4948 :
"instruction must use glc");
4956 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
4958 :
"instruction must not use glc");
4966bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
4968 const unsigned CPol) {
4972 const unsigned Opcode = Inst.
getOpcode();
4984 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
4992 return PrintError(
"invalid th value for SMEM instruction");
4999 return PrintError(
"scope and th combination is not valid");
5008 return PrintError(
"invalid th value for atomic instructions");
5009 }
else if (IsStore) {
5011 return PrintError(
"invalid th value for store instructions");
5014 return PrintError(
"invalid th value for load instructions");
5024 if (!Operand->isReg())
5026 unsigned Reg = Operand->getReg();
5027 if (Reg == SRC_EXECZ || Reg == SRC_VCCZ) {
5029 "execz and vccz are not supported on this GPU");
5036bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5039 if (
Desc.mayStore() &&
5043 Error(Loc,
"TFE modifier has no meaning for store instructions");
5051bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst,
5054 if (
auto ErrMsg = validateLdsDirect(Inst)) {
5058 if (!validateSOPLiteral(Inst)) {
5060 "only one unique literal operand is allowed");
5063 if (!validateVOPLiteral(Inst,
Operands)) {
5066 if (!validateConstantBusLimitations(Inst,
Operands)) {
5069 if (!validateVOPDRegBankConstraints(Inst,
Operands)) {
5072 if (!validateIntClampSupported(Inst)) {
5074 "integer clamping is not supported on this GPU");
5077 if (!validateOpSel(Inst)) {
5079 "invalid op_sel operand");
5082 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5084 "invalid neg_lo operand");
5087 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5089 "invalid neg_hi operand");
5092 if (!validateDPP(Inst,
Operands)) {
5096 if (!validateMIMGD16(Inst)) {
5098 "d16 modifier is not supported on this GPU");
5101 if (!validateMIMGMSAA(Inst)) {
5103 "invalid dim; must be MSAA type");
5106 if (!validateMIMGDataSize(Inst, IDLoc)) {
5109 if (!validateMIMGAddrSize(Inst, IDLoc))
5111 if (!validateMIMGAtomicDMask(Inst)) {
5113 "invalid atomic image dmask");
5116 if (!validateMIMGGatherDMask(Inst)) {
5118 "invalid image_gather dmask: only one bit must be set");
5121 if (!validateMovrels(Inst,
Operands)) {
5124 if (!validateOffset(Inst,
Operands)) {
5127 if (!validateMAIAccWrite(Inst,
Operands)) {
5130 if (!validateMAISrc2(Inst,
Operands)) {
5133 if (!validateMFMA(Inst,
Operands)) {
5136 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5140 if (!validateAGPRLdSt(Inst)) {
5141 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5142 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5143 :
"invalid register class: agpr loads and stores not supported on this GPU"
5147 if (!validateVGPRAlign(Inst)) {
5149 "invalid register class: vgpr tuples must be 64 bit aligned");
5156 if (!validateBLGP(Inst,
Operands)) {
5160 if (!validateDivScale(Inst)) {
5161 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5164 if (!validateWaitCnt(Inst,
Operands)) {
5167 if (!validateExeczVcczOperands(
Operands)) {
5170 if (!validateTFE(Inst,
Operands)) {
5179 unsigned VariantID = 0);
5183 unsigned VariantID);
5185bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5190bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5193 for (
auto Variant : Variants) {
5201bool AMDGPUAsmParser::checkUnsupportedInstruction(
StringRef Mnemo,
5202 const SMLoc &IDLoc) {
5203 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5206 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5211 getParser().clearPendingErrors();
5215 StringRef VariantName = getMatchedVariantName();
5216 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5219 " variant of this instruction is not supported"));
5223 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5224 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5227 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5228 .
flip(AMDGPU::FeatureWavefrontSize32);
5230 ComputeAvailableFeatures(FeaturesWS32);
5232 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5233 return Error(IDLoc,
"instruction requires wavesize=32");
5238 return Error(IDLoc,
"instruction not supported on this GPU");
5243 return Error(IDLoc,
"invalid instruction" + Suggestion);
5249 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5250 if (
Op.isToken() && InvalidOprIdx > 1) {
5251 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5252 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5257bool AMDGPUAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
5261 bool MatchingInlineAsm) {
5263 unsigned Result = Match_Success;
5264 for (
auto Variant : getMatchedVariants()) {
5266 auto R = MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm,
5271 if (R == Match_Success || R == Match_MissingFeature ||
5272 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5273 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5274 Result != Match_MissingFeature)) {
5278 if (R == Match_Success)
5282 if (Result == Match_Success) {
5283 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5292 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5298 case Match_MissingFeature:
5302 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5304 case Match_InvalidOperand: {
5305 SMLoc ErrorLoc = IDLoc;
5308 return Error(IDLoc,
"too few operands for instruction");
5311 if (ErrorLoc ==
SMLoc())
5315 return Error(ErrorLoc,
"invalid VOPDY instruction");
5317 return Error(ErrorLoc,
"invalid operand for instruction");
5320 case Match_MnemonicFail:
5326bool AMDGPUAsmParser::ParseAsAbsoluteExpression(
uint32_t &Ret) {
5331 if (getParser().parseAbsoluteExpression(Tmp)) {
5338bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5340 return TokError(
"directive only supported for amdgcn architecture");
5342 std::string TargetIDDirective;
5343 SMLoc TargetStart = getTok().getLoc();
5344 if (getParser().parseEscapedString(TargetIDDirective))
5348 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5349 return getParser().Error(TargetRange.
Start,
5350 (
Twine(
".amdgcn_target directive's target id ") +
5351 Twine(TargetIDDirective) +
5352 Twine(
" does not match the specified target id ") +
5353 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5362bool AMDGPUAsmParser::calculateGPRBlocks(
5364 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5365 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5367 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5374 int64_t EvaluatedSGPRs;
5379 unsigned MaxAddressableNumSGPRs =
5382 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5383 !Features.
test(FeatureSGPRInitBug) &&
5384 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5385 return OutOfRangeError(SGPRRange);
5387 const MCExpr *ExtraSGPRs =
5391 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5392 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5393 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5394 return OutOfRangeError(SGPRRange);
5396 if (Features.
test(FeatureSGPRInitBug))
5403 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5404 unsigned Granule) ->
const MCExpr * {
5408 const MCExpr *AlignToGPR =
5416 VGPRBlocks = GetNumGPRBlocks(
5425bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5427 return TokError(
"directive only supported for amdgcn architecture");
5430 return TokError(
"directive only supported for amdhsa OS");
5433 if (getParser().parseIdentifier(KernelName))
5438 &getSTI(), getContext());
5448 const MCExpr *NextFreeVGPR = ZeroExpr;
5454 const MCExpr *NextFreeSGPR = ZeroExpr;
5457 unsigned ImpliedUserSGPRCount = 0;
5461 std::optional<unsigned> ExplicitUserSGPRCount;
5462 const MCExpr *ReserveVCC = OneExpr;
5463 const MCExpr *ReserveFlatScr = OneExpr;
5464 std::optional<bool> EnableWavefrontSize32;
5470 SMRange IDRange = getTok().getLocRange();
5471 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5474 if (
ID ==
".end_amdhsa_kernel")
5478 return TokError(
".amdhsa_ directives cannot be repeated");
5480 SMLoc ValStart = getLoc();
5482 if (getParser().parseExpression(ExprVal))
5484 SMLoc ValEnd = getLoc();
5489 bool EvaluatableExpr;
5490 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5492 return OutOfRangeError(ValRange);
5496#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5497 if (!isUInt<ENTRY##_WIDTH>(Val)) \
5498 return OutOfRangeError(RANGE); \
5499 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
5504#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
5506 return Error(IDRange.Start, "directive should have resolvable expression", \
5509 if (
ID ==
".amdhsa_group_segment_fixed_size") {
5512 return OutOfRangeError(ValRange);
5514 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
5517 return OutOfRangeError(ValRange);
5519 }
else if (
ID ==
".amdhsa_kernarg_size") {
5521 return OutOfRangeError(ValRange);
5523 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
5525 ExplicitUserSGPRCount = Val;
5526 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
5530 "directive is not supported with architected flat scratch",
5533 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
5536 ImpliedUserSGPRCount += 4;
5537 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
5540 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5543 return OutOfRangeError(ValRange);
5547 ImpliedUserSGPRCount += Val;
5548 PreloadLength = Val;
5550 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
5553 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5556 return OutOfRangeError(ValRange);
5560 PreloadOffset = Val;
5561 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
5564 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
5567 ImpliedUserSGPRCount += 2;
5568 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
5571 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
5574 ImpliedUserSGPRCount += 2;
5575 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
5578 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
5581 ImpliedUserSGPRCount += 2;
5582 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
5585 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
5588 ImpliedUserSGPRCount += 2;
5589 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
5592 "directive is not supported with architected flat scratch",
5596 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
5599 ImpliedUserSGPRCount += 2;
5600 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
5603 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
5606 ImpliedUserSGPRCount += 1;
5607 }
else if (
ID ==
".amdhsa_wavefront_size32") {
5609 if (IVersion.
Major < 10)
5610 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5611 EnableWavefrontSize32 = Val;
5613 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
5615 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
5617 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
5619 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
5622 "directive is not supported with architected flat scratch",
5625 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
5627 }
else if (
ID ==
".amdhsa_enable_private_segment") {
5631 "directive is not supported without architected flat scratch",
5634 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
5636 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
5638 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
5640 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
5642 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
5644 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
5646 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
5648 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
5650 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
5652 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
5654 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
5656 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
5657 VGPRRange = ValRange;
5658 NextFreeVGPR = ExprVal;
5659 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
5660 SGPRRange = ValRange;
5661 NextFreeSGPR = ExprVal;
5662 }
else if (
ID ==
".amdhsa_accum_offset") {
5664 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5665 AccumOffset = ExprVal;
5666 }
else if (
ID ==
".amdhsa_reserve_vcc") {
5667 if (EvaluatableExpr && !isUInt<1>(Val))
5668 return OutOfRangeError(ValRange);
5669 ReserveVCC = ExprVal;
5670 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
5671 if (IVersion.
Major < 7)
5672 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
5675 "directive is not supported with architected flat scratch",
5677 if (EvaluatableExpr && !isUInt<1>(Val))
5678 return OutOfRangeError(ValRange);
5679 ReserveFlatScr = ExprVal;
5680 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
5681 if (IVersion.
Major < 8)
5682 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
5683 if (!isUInt<1>(Val))
5684 return OutOfRangeError(ValRange);
5685 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
5686 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
5688 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
5690 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
5692 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
5694 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
5696 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
5698 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
5700 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
5702 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
5704 }
else if (
ID ==
".amdhsa_dx10_clamp") {
5705 if (IVersion.
Major >= 12)
5706 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
5708 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
5710 }
else if (
ID ==
".amdhsa_ieee_mode") {
5711 if (IVersion.
Major >= 12)
5712 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
5714 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
5716 }
else if (
ID ==
".amdhsa_fp16_overflow") {
5717 if (IVersion.
Major < 9)
5718 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
5720 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
5722 }
else if (
ID ==
".amdhsa_tg_split") {
5724 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5727 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
5728 if (IVersion.
Major < 10)
5729 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5731 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
5733 }
else if (
ID ==
".amdhsa_memory_ordered") {
5734 if (IVersion.
Major < 10)
5735 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5737 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
5739 }
else if (
ID ==
".amdhsa_forward_progress") {
5740 if (IVersion.
Major < 10)
5741 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5743 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
5745 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
5747 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
5748 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
5750 SharedVGPRCount = Val;
5752 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
5754 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
5757 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
5759 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
5761 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
5763 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
5766 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
5768 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
5770 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
5772 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
5774 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
5776 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
5778 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
5780 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
5782 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
5784 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
5785 if (IVersion.
Major < 12)
5786 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
5788 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
5791 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
5794#undef PARSE_BITS_ENTRY
5797 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
5798 return TokError(
".amdhsa_next_free_vgpr directive is required");
5800 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
5801 return TokError(
".amdhsa_next_free_sgpr directive is required");
5803 const MCExpr *VGPRBlocks;
5804 const MCExpr *SGPRBlocks;
5805 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
5806 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
5807 EnableWavefrontSize32, NextFreeVGPR,
5808 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
5812 int64_t EvaluatedVGPRBlocks;
5813 bool VGPRBlocksEvaluatable =
5814 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
5815 if (VGPRBlocksEvaluatable &&
5816 !isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_WIDTH>(
5817 static_cast<uint64_t>(EvaluatedVGPRBlocks))) {
5818 return OutOfRangeError(VGPRRange);
5822 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
5823 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT, getContext());
5825 int64_t EvaluatedSGPRBlocks;
5826 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
5827 !isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_WIDTH>(
5828 static_cast<uint64_t>(EvaluatedSGPRBlocks)))
5829 return OutOfRangeError(SGPRRange);
5832 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
5833 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT, getContext());
5835 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
5836 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
5837 "enabled user SGPRs");
5839 unsigned UserSGPRCount =
5840 ExplicitUserSGPRCount ? *ExplicitUserSGPRCount : ImpliedUserSGPRCount;
5842 if (!isUInt<COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_WIDTH>(UserSGPRCount))
5843 return TokError(
"too many user SGPRs enabled");
5846 COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_SHIFT,
5847 COMPUTE_PGM_RSRC2_USER_SGPR_COUNT, getContext());
5851 return TokError(
"Kernarg size should be resolvable");
5853 if (PreloadLength && kernarg_size &&
5854 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
5855 return TokError(
"Kernarg preload length + offset is larger than the "
5856 "kernarg segment size");
5859 if (!Seen.
contains(
".amdhsa_accum_offset"))
5860 return TokError(
".amdhsa_accum_offset directive is required");
5861 int64_t EvaluatedAccum;
5862 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
5863 uint64_t UEvaluatedAccum = EvaluatedAccum;
5864 if (AccumEvaluatable &&
5865 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
5866 return TokError(
"accum_offset should be in range [4..256] in "
5869 int64_t EvaluatedNumVGPR;
5870 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
5874 return TokError(
"accum_offset exceeds total VGPR allocation");
5880 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
5881 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
5885 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
5887 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
5888 return TokError(
"shared_vgpr_count directive not valid on "
5889 "wavefront size 32");
5892 if (VGPRBlocksEvaluatable &&
5893 (SharedVGPRCount * 2 +
static_cast<uint64_t>(EvaluatedVGPRBlocks) >
5895 return TokError(
"shared_vgpr_count*2 + "
5896 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
5901 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
5902 NextFreeVGPR, NextFreeSGPR,
5903 ReserveVCC, ReserveFlatScr);
5907bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
5909 if (ParseAsAbsoluteExpression(Version))
5912 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(Version);
5916bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(
StringRef ID,
5920 if (
ID ==
"max_scratch_backing_memory_byte_size") {
5921 Parser.eatToEndOfStatement();
5927 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
5928 return TokError(Err.str());
5932 if (
ID ==
"enable_wavefront_size32") {
5935 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
5936 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5937 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
5939 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5940 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
5944 if (
ID ==
"wavefront_size") {
5945 if (
C.wavefront_size == 5) {
5947 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
5948 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5949 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
5950 }
else if (
C.wavefront_size == 6) {
5951 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5952 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
5959bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
5969 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
5972 if (
ID ==
".end_amd_kernel_code_t")
5975 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
5979 KernelCode.
validate(&getSTI(), getContext());
5980 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
5985bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
5987 if (!parseId(KernelName,
"expected symbol name"))
5990 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
5993 KernelScope.initialize(getContext());
5997bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
5999 return Error(getLoc(),
6000 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6004 auto TargetIDDirective = getLexer().getTok().getStringContents();
6005 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6006 return Error(getParser().getTok().getLoc(),
"target id must match options");
6008 getTargetStreamer().EmitISAVersion();
6014bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6017 std::string HSAMetadataString;
6022 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6023 return Error(getLoc(),
"invalid HSA metadata");
6030bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6031 const char *AssemblerDirectiveEnd,
6032 std::string &CollectString) {
6036 getLexer().setSkipSpace(
false);
6038 bool FoundEnd =
false;
6041 CollectStream << getTokenStr();
6045 if (trySkipId(AssemblerDirectiveEnd)) {
6050 CollectStream << Parser.parseStringToEndOfStatement()
6051 << getContext().getAsmInfo()->getSeparatorString();
6053 Parser.eatToEndOfStatement();
6056 getLexer().setSkipSpace(
true);
6059 return TokError(
Twine(
"expected directive ") +
6060 Twine(AssemblerDirectiveEnd) +
Twine(
" not found"));
6063 CollectStream.flush();
6068bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6074 auto PALMetadata = getTargetStreamer().getPALMetadata();
6075 if (!PALMetadata->setFromString(
String))
6076 return Error(getLoc(),
"invalid PAL metadata");
6081bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6083 return Error(getLoc(),
6085 "not available on non-amdpal OSes")).str());
6088 auto PALMetadata = getTargetStreamer().getPALMetadata();
6089 PALMetadata->setLegacy();
6092 if (ParseAsAbsoluteExpression(Key)) {
6093 return TokError(
Twine(
"invalid value in ") +
6097 return TokError(
Twine(
"expected an even number of values in ") +
6100 if (ParseAsAbsoluteExpression(
Value)) {
6101 return TokError(
Twine(
"invalid value in ") +
6104 PALMetadata->setRegister(Key,
Value);
6113bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6114 if (getParser().checkForValidSection())
6118 SMLoc NameLoc = getLoc();
6119 if (getParser().parseIdentifier(
Name))
6120 return TokError(
"expected identifier in directive");
6123 if (getParser().parseComma())
6129 SMLoc SizeLoc = getLoc();
6130 if (getParser().parseAbsoluteExpression(
Size))
6133 return Error(SizeLoc,
"size must be non-negative");
6134 if (
Size > LocalMemorySize)
6135 return Error(SizeLoc,
"size is too large");
6137 int64_t Alignment = 4;
6139 SMLoc AlignLoc = getLoc();
6140 if (getParser().parseAbsoluteExpression(Alignment))
6143 return Error(AlignLoc,
"alignment must be a power of two");
6148 if (Alignment >= 1u << 31)
6149 return Error(AlignLoc,
"alignment is too large");
6155 Symbol->redefineIfPossible();
6156 if (!
Symbol->isUndefined())
6157 return Error(NameLoc,
"invalid symbol redefinition");
6159 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6163bool AMDGPUAsmParser::ParseDirective(
AsmToken DirectiveID) {
6167 if (IDVal ==
".amdhsa_kernel")
6168 return ParseDirectiveAMDHSAKernel();
6170 if (IDVal ==
".amdhsa_code_object_version")
6171 return ParseDirectiveAMDHSACodeObjectVersion();
6175 return ParseDirectiveHSAMetadata();
6177 if (IDVal ==
".amd_kernel_code_t")
6178 return ParseDirectiveAMDKernelCodeT();
6180 if (IDVal ==
".amdgpu_hsa_kernel")
6181 return ParseDirectiveAMDGPUHsaKernel();
6183 if (IDVal ==
".amd_amdgpu_isa")
6184 return ParseDirectiveISAVersion();
6188 Twine(
" directive is "
6189 "not available on non-amdhsa OSes"))
6194 if (IDVal ==
".amdgcn_target")
6195 return ParseDirectiveAMDGCNTarget();
6197 if (IDVal ==
".amdgpu_lds")
6198 return ParseDirectiveAMDGPULDS();
6201 return ParseDirectivePALMetadataBegin();
6204 return ParseDirectivePALMetadata();
6212 if (
MRI.regsOverlap(AMDGPU::TTMP12_TTMP13_TTMP14_TTMP15, RegNo))
6216 if (
MRI.regsOverlap(AMDGPU::SGPR104_SGPR105, RegNo))
6217 return hasSGPR104_SGPR105();
6220 case AMDGPU::SRC_SHARED_BASE_LO:
6221 case AMDGPU::SRC_SHARED_BASE:
6222 case AMDGPU::SRC_SHARED_LIMIT_LO:
6223 case AMDGPU::SRC_SHARED_LIMIT:
6224 case AMDGPU::SRC_PRIVATE_BASE_LO:
6225 case AMDGPU::SRC_PRIVATE_BASE:
6226 case AMDGPU::SRC_PRIVATE_LIMIT_LO:
6227 case AMDGPU::SRC_PRIVATE_LIMIT:
6229 case AMDGPU::SRC_POPS_EXITING_WAVE_ID:
6232 case AMDGPU::TBA_LO:
6233 case AMDGPU::TBA_HI:
6235 case AMDGPU::TMA_LO:
6236 case AMDGPU::TMA_HI:
6238 case AMDGPU::XNACK_MASK:
6239 case AMDGPU::XNACK_MASK_LO:
6240 case AMDGPU::XNACK_MASK_HI:
6241 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6242 case AMDGPU::SGPR_NULL:
6256 case AMDGPU::FLAT_SCR:
6257 case AMDGPU::FLAT_SCR_LO:
6258 case AMDGPU::FLAT_SCR_HI:
6267 if (
MRI.regsOverlap(AMDGPU::SGPR102_SGPR103, RegNo))
6268 return hasSGPR102_SGPR103();
6281 Res = MatchOperandParserImpl(
Operands, Mnemonic);
6293 SMLoc LBraceLoc = getLoc();
6298 auto Loc = getLoc();
6301 Error(Loc,
"expected a register");
6305 RBraceLoc = getLoc();
6310 "expected a comma or a closing square bracket"))
6314 if (
Operands.size() - Prefix > 1) {
6316 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6317 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6328 setForcedEncodingSize(0);
6329 setForcedDPP(
false);
6330 setForcedSDWA(
false);
6332 if (
Name.ends_with(
"_e64_dpp")) {
6334 setForcedEncodingSize(64);
6335 return Name.substr(0,
Name.size() - 8);
6337 if (
Name.ends_with(
"_e64")) {
6338 setForcedEncodingSize(64);
6339 return Name.substr(0,
Name.size() - 4);
6341 if (
Name.ends_with(
"_e32")) {
6342 setForcedEncodingSize(32);
6343 return Name.substr(0,
Name.size() - 4);
6345 if (
Name.ends_with(
"_dpp")) {
6347 return Name.substr(0,
Name.size() - 4);
6349 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();
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();
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))
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();
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))
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"))
7377 Width.Loc = getLoc();
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;
7455 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
7458 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
7463 Stream.IsDefined =
true;
7464 Stream.Loc = getLoc();
7474AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
7475 const OperandInfoTy &
Op,
7476 const OperandInfoTy &Stream) {
7482 bool Strict = Msg.IsSymbolic;
7486 Error(Msg.Loc,
"specified message id is not supported on this GPU");
7491 Error(Msg.Loc,
"invalid message id");
7497 Error(
Op.Loc,
"message does not support operations");
7499 Error(Msg.Loc,
"missing message operation");
7505 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
7507 Error(
Op.Loc,
"invalid operation id");
7512 Error(Stream.Loc,
"message operation does not support streams");
7516 Error(Stream.Loc,
"invalid message stream id");
7526 SMLoc Loc = getLoc();
7530 OperandInfoTy
Op(OP_NONE_);
7531 OperandInfoTy Stream(STREAM_ID_NONE_);
7532 if (parseSendMsgBody(Msg,
Op, Stream) &&
7533 validateSendMsg(Msg,
Op, Stream)) {
7538 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
7539 if (ImmVal < 0 || !isUInt<16>(ImmVal))
7540 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
7545 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
7549bool AMDGPUOperand::isSendMsg()
const {
7550 return isImmTy(ImmTySendMsg);
7571 return Error(S,
"invalid interpolation slot");
7573 Operands.push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
7574 AMDGPUOperand::ImmTyInterpSlot));
7585 if (!Str.starts_with(
"attr"))
7586 return Error(S,
"invalid interpolation attribute");
7596 return Error(S,
"invalid or missing interpolation attribute channel");
7598 Str = Str.drop_back(2).drop_front(4);
7601 if (Str.getAsInteger(10, Attr))
7602 return Error(S,
"invalid or missing interpolation attribute number");
7605 return Error(S,
"out of bounds interpolation attribute number");
7609 Operands.push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
7610 AMDGPUOperand::ImmTyInterpAttr));
7611 Operands.push_back(AMDGPUOperand::CreateImm(
7612 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
7631 return Error(S, (
Id == ET_INVALID)
7632 ?
"invalid exp target"
7633 :
"exp target is not supported on this GPU");
7635 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Id, S,
7636 AMDGPUOperand::ImmTyExpTgt));
7651 return isId(getToken(),
Id);
7656 return getTokenKind() ==
Kind;
7659StringRef AMDGPUAsmParser::getId()
const {
7686 if (isId(
Id) && peekToken().is(Kind)) {
7696 if (isToken(Kind)) {
7706 if (!trySkipToken(Kind)) {
7707 Error(getLoc(), ErrMsg);
7718 if (Parser.parseExpression(Expr))
7721 if (Expr->evaluateAsAbsolute(Imm))
7725 Error(S,
"expected absolute expression");
7728 Twine(
" or an absolute expression"));
7738 if (Parser.parseExpression(Expr))
7742 if (Expr->evaluateAsAbsolute(IntVal)) {
7743 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
7745 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
7753 Val = getToken().getStringContents();
7757 Error(getLoc(), ErrMsg);
7764 Val = getTokenStr();
7768 if (!ErrMsg.
empty())
7769 Error(getLoc(), ErrMsg);
7774AMDGPUAsmParser::getToken()
const {
7775 return Parser.getTok();
7778AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
7781 : getLexer().peekTok(ShouldSkipSpace);
7786 auto TokCount = getLexer().peekTokens(Tokens);
7793AMDGPUAsmParser::getTokenKind()
const {
7798AMDGPUAsmParser::getLoc()
const {
7799 return getToken().getLoc();
7803AMDGPUAsmParser::getTokenStr()
const {
7804 return getToken().getString();
7808AMDGPUAsmParser::lex() {
7813 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
7817AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
7819 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
7820 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7822 return Op.getStartLoc();
7828AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
7830 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
7835AMDGPUAsmParser::getRegLoc(
unsigned Reg,
7837 auto Test = [=](
const AMDGPUOperand&
Op) {
7838 return Op.isRegKind() &&
Op.getReg() ==
Reg;
7844 bool SearchMandatoryLiterals)
const {
7845 auto Test = [](
const AMDGPUOperand&
Op) {
7846 return Op.IsImmKindLiteral() ||
Op.isExpr();
7849 if (SearchMandatoryLiterals && Loc == getInstLoc(
Operands))
7850 Loc = getMandatoryLitLoc(
Operands);
7855 auto Test = [](
const AMDGPUOperand &
Op) {
7856 return Op.IsImmKindMandatoryLiteral();
7863 auto Test = [](
const AMDGPUOperand&
Op) {
7864 return Op.isImmKindConst();
7881 SMLoc IdLoc = getLoc();
7887 find_if(Fields, [
Id](StructuredOpField *
F) {
return F->Id ==
Id; });
7888 if (
I == Fields.
end())
7889 return Error(IdLoc,
"unknown field");
7890 if ((*I)->IsDefined)
7891 return Error(IdLoc,
"duplicate field");
7894 (*I)->Loc = getLoc();
7897 (*I)->IsDefined =
true;
7904bool AMDGPUAsmParser::validateStructuredOpFields(
7906 return all_of(Fields, [
this](
const StructuredOpField *
F) {
7907 return F->validate(*
this);
7918 const unsigned OrMask,
7919 const unsigned XorMask) {
7922 return BITMASK_PERM_ENC |
7923 (AndMask << BITMASK_AND_SHIFT) |
7924 (OrMask << BITMASK_OR_SHIFT) |
7925 (XorMask << BITMASK_XOR_SHIFT);
7929AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
7930 const unsigned MinVal,
7931 const unsigned MaxVal,
7941 if (Op < MinVal || Op > MaxVal) {
7950AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
7951 const unsigned MinVal,
7952 const unsigned MaxVal,
7955 for (
unsigned i = 0; i < OpNum; ++i) {
7956 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
7964AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &Imm) {
7968 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
7969 "expected a 2-bit lane id")) {
7980AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &Imm) {
7987 if (!parseSwizzleOperand(GroupSize,
7989 "group size must be in the interval [2,32]",
7994 Error(Loc,
"group size must be a power of two");
7997 if (parseSwizzleOperand(LaneIdx,
7999 "lane id must be in the interval [0,group size - 1]",
8008AMDGPUAsmParser::parseSwizzleReverse(int64_t &Imm) {
8014 if (!parseSwizzleOperand(GroupSize,
8016 "group size must be in the interval [2,32]",
8021 Error(Loc,
"group size must be a power of two");
8030AMDGPUAsmParser::parseSwizzleSwap(int64_t &Imm) {
8036 if (!parseSwizzleOperand(GroupSize,
8038 "group size must be in the interval [1,16]",
8043 Error(Loc,
"group size must be a power of two");
8052AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &Imm) {
8060 SMLoc StrLoc = getLoc();
8061 if (!parseString(Ctl)) {
8064 if (Ctl.
size() != BITMASK_WIDTH) {
8065 Error(StrLoc,
"expected a 5-character mask");
8069 unsigned AndMask = 0;
8070 unsigned OrMask = 0;
8071 unsigned XorMask = 0;
8073 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8077 Error(StrLoc,
"invalid mask");
8099AMDGPUAsmParser::parseSwizzleOffset(int64_t &Imm) {
8101 SMLoc OffsetLoc = getLoc();
8103 if (!
parseExpr(Imm,
"a swizzle macro")) {
8106 if (!isUInt<16>(Imm)) {
8107 Error(OffsetLoc,
"expected a 16-bit offset");
8114AMDGPUAsmParser::parseSwizzleMacro(int64_t &Imm) {
8119 SMLoc ModeLoc = getLoc();
8122 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8123 Ok = parseSwizzleQuadPerm(Imm);
8124 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8125 Ok = parseSwizzleBitmaskPerm(Imm);
8126 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8127 Ok = parseSwizzleBroadcast(Imm);
8128 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8129 Ok = parseSwizzleSwap(Imm);
8130 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8131 Ok = parseSwizzleReverse(Imm);
8133 Error(ModeLoc,
"expected a swizzle mode");
8136 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8146 if (trySkipId(
"offset")) {
8150 if (trySkipId(
"swizzle")) {
8151 Ok = parseSwizzleMacro(Imm);
8153 Ok = parseSwizzleOffset(Imm);
8157 Operands.push_back(AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTySwizzle));
8165AMDGPUOperand::isSwizzle()
const {
8166 return isImmTy(ImmTySwizzle);
8173int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8187 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8188 if (trySkipId(IdSymbolic[ModeId])) {
8195 Error(S, (Imm == 0)?
8196 "expected a VGPR index mode or a closing parenthesis" :
8197 "expected a VGPR index mode");
8202 Error(S,
"duplicate VGPR index mode");
8210 "expected a comma or a closing parenthesis"))
8225 Imm = parseGPRIdxMacro();
8229 if (getParser().parseAbsoluteExpression(Imm))
8231 if (Imm < 0 || !isUInt<4>(Imm))
8232 return Error(S,
"invalid immediate: only 4-bit values are legal");
8236 AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8240bool AMDGPUOperand::isGPRIdxMode()
const {
8241 return isImmTy(ImmTyGprIdxMode);
8253 if (isRegister() || isModifier())
8260 assert(Opr.isImm() || Opr.isExpr());
8261 SMLoc Loc = Opr.getStartLoc();
8265 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8266 Error(Loc,
"expected an absolute expression or a label");
8267 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8268 Error(Loc,
"expected a 16-bit signed jump offset");
8286void AMDGPUAsmParser::cvtMubufImpl(
MCInst &Inst,
8289 OptionalImmIndexMap OptionalIdx;
8290 unsigned FirstOperandIdx = 1;
8291 bool IsAtomicReturn =
false;
8298 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
8299 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8303 Op.addRegOperands(Inst, 1);
8307 if (IsAtomicReturn && i == FirstOperandIdx)
8308 Op.addRegOperands(Inst, 1);
8313 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
8314 Op.addImmOperands(Inst, 1);
8326 OptionalIdx[
Op.getImmTy()] = i;
8337bool AMDGPUOperand::isSMRDOffset8()
const {
8338 return isImmLiteral() && isUInt<8>(getImm());
8341bool AMDGPUOperand::isSMEMOffset()
const {
8343 return isImmLiteral();
8346bool AMDGPUOperand::isSMRDLiteralOffset()
const {
8349 return isImmLiteral() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
8381bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
8382 if (BoundCtrl == 0 || BoundCtrl == 1) {
8390void AMDGPUAsmParser::onBeginOfFile() {
8391 if (!getParser().getStreamer().getTargetStreamer() ||
8395 if (!getTargetStreamer().getTargetID())
8396 getTargetStreamer().initializeTargetID(getSTI(),
8397 getSTI().getFeatureString());
8400 getTargetStreamer().EmitDirectiveAMDGCNTarget();
8408bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
8414 .
Case(
"max", AGVK::AGVK_Max)
8415 .
Case(
"or", AGVK::AGVK_Or)
8416 .
Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
8417 .
Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
8418 .
Case(
"alignto", AGVK::AGVK_AlignTo)
8419 .
Case(
"occupancy", AGVK::AGVK_Occupancy)
8429 if (Exprs.
empty()) {
8430 Error(getToken().getLoc(),
8431 "empty " +
Twine(TokenId) +
" expression");
8434 if (CommaCount + 1 != Exprs.
size()) {
8435 Error(getToken().getLoc(),
8436 "mismatch of commas in " +
Twine(TokenId) +
" expression");
8443 if (getParser().parseExpression(Expr, EndLoc))
8447 if (LastTokenWasComma)
8450 Error(getToken().getLoc(),
8451 "unexpected token in " +
Twine(TokenId) +
" expression");
8457 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
8462 if (
Name ==
"mul") {
8463 return parseIntWithPrefix(
"mul",
Operands,
8467 if (
Name ==
"div") {
8468 return parseIntWithPrefix(
"div",
Operands,
8484 const int Ops[] = { AMDGPU::OpName::src0,
8485 AMDGPU::OpName::src1,
8486 AMDGPU::OpName::src2 };
8501 if (
DstOp.isReg() &&
8502 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
8506 if ((OpSel & (1 << SrcNum)) != 0)
8512void AMDGPUAsmParser::cvtVOP3OpSel(
MCInst &Inst,
8519 OptionalImmIndexMap &OptionalIdx) {
8520 cvtVOP3P(Inst,
Operands, OptionalIdx);
8529 &&
Desc.NumOperands > (OpNum + 1)
8531 &&
Desc.operands()[OpNum + 1].RegClass != -1
8533 &&
Desc.getOperandConstraint(OpNum + 1,
8534 MCOI::OperandConstraint::TIED_TO) == -1;
8539 OptionalImmIndexMap OptionalIdx;
8544 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8545 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8548 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8549 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8551 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8552 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
8553 Op.isInterpAttrChan()) {
8555 }
else if (
Op.isImmModifier()) {
8556 OptionalIdx[
Op.getImmTy()] =
I;
8564 AMDGPUOperand::ImmTyHigh);
8568 AMDGPUOperand::ImmTyClamp);
8572 AMDGPUOperand::ImmTyOModSI);
8577 OptionalImmIndexMap OptionalIdx;
8582 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8583 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8586 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8587 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8589 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8590 }
else if (
Op.isImmModifier()) {
8591 OptionalIdx[
Op.getImmTy()] =
I;
8608 const int Ops[] = { AMDGPU::OpName::src0,
8609 AMDGPU::OpName::src1,
8610 AMDGPU::OpName::src2 };
8611 const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8612 AMDGPU::OpName::src1_modifiers,
8613 AMDGPU::OpName::src2_modifiers };
8617 for (
int J = 0; J < 3; ++J) {
8625 if ((OpSel & (1 << J)) != 0)
8627 if (ModOps[J] == AMDGPU::OpName::src0_modifiers &&
8628 (OpSel & (1 << 3)) != 0)
8636 OptionalImmIndexMap &OptionalIdx) {
8641 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8642 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8645 for (
unsigned E =
Operands.size();
I != E; ++
I) {
8646 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8648 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8649 }
else if (
Op.isImmModifier()) {
8650 OptionalIdx[
Op.getImmTy()] =
I;
8651 }
else if (
Op.isRegOrImm()) {
8652 Op.addRegOrImmOperands(Inst, 1);
8662 AMDGPUOperand::ImmTyByteSel);
8667 AMDGPUOperand::ImmTyClamp);
8671 AMDGPUOperand::ImmTyOModSI);
8678 auto it = Inst.
begin();
8688 OptionalImmIndexMap OptionalIdx;
8689 cvtVOP3(Inst,
Operands, OptionalIdx);
8693 OptionalImmIndexMap &OptIdx) {
8699 if (Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
8700 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
8701 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
8702 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
8710 !(Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp_gfx12 ||
8711 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp_gfx12 ||
8712 Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp8_gfx12 ||
8713 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp8_gfx12 ||
8714 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
8715 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
8716 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
8717 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12)) {
8726 if (OpSelIdx != -1) {
8731 if (OpSelHiIdx != -1) {
8745 const int Ops[] = { AMDGPU::OpName::src0,
8746 AMDGPU::OpName::src1,
8747 AMDGPU::OpName::src2 };
8748 const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8749 AMDGPU::OpName::src1_modifiers,
8750 AMDGPU::OpName::src2_modifiers };
8753 unsigned OpSelHi = 0;
8760 if (OpSelHiIdx != -1)
8769 for (
int J = 0; J < 3; ++J) {
8782 if (
SrcOp.isReg() && getMRI()
8789 if ((OpSel & (1 << J)) != 0)
8793 if ((OpSelHi & (1 << J)) != 0)
8796 if ((NegLo & (1 << J)) != 0)
8799 if ((NegHi & (1 << J)) != 0)
8807 OptionalImmIndexMap OptIdx;
8813 unsigned i,
unsigned Opc,
unsigned OpName) {
8815 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
8817 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
8823 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
8826 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
8827 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
8829 OptionalImmIndexMap OptIdx;
8830 for (
unsigned i = 5; i <
Operands.size(); ++i) {
8831 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8832 OptIdx[
Op.getImmTy()] = i;
8837 AMDGPUOperand::ImmTyIndexKey8bit);
8841 AMDGPUOperand::ImmTyIndexKey16bit);
8861 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
8862 SMLoc OpYLoc = getLoc();
8865 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
8868 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
8875 auto addOp = [&](
uint16_t ParsedOprIdx) {
8876 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
8878 Op.addRegOperands(Inst, 1);
8882 Op.addImmOperands(Inst, 1);
8894 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
8898 const auto &CInfo = InstInfo[CompIdx];
8899 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
8900 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
8901 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
8902 if (CInfo.hasSrc2Acc())
8903 addOp(CInfo.getIndexOfDstInParsedOperands());
8911bool AMDGPUOperand::isDPP8()
const {
8912 return isImmTy(ImmTyDPP8);
8915bool AMDGPUOperand::isDPPCtrl()
const {
8916 using namespace AMDGPU::DPP;
8918 bool result =
isImm() && getImmTy() == ImmTyDppCtrl && isUInt<9>(getImm());
8920 int64_t
Imm = getImm();
8921 return (Imm >= DppCtrl::QUAD_PERM_FIRST && Imm <= DppCtrl::QUAD_PERM_LAST) ||
8922 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
8923 (Imm >= DppCtrl::ROW_SHR_FIRST && Imm <= DppCtrl::ROW_SHR_LAST) ||
8924 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
8925 (Imm == DppCtrl::WAVE_SHL1) ||
8926 (
Imm == DppCtrl::WAVE_ROL1) ||
8927 (Imm == DppCtrl::WAVE_SHR1) ||
8928 (
Imm == DppCtrl::WAVE_ROR1) ||
8929 (Imm == DppCtrl::ROW_MIRROR) ||
8930 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
8931 (Imm == DppCtrl::BCAST15) ||
8932 (
Imm == DppCtrl::BCAST31) ||
8933 (Imm >= DppCtrl::ROW_SHARE_FIRST && Imm <= DppCtrl::ROW_SHARE_LAST) ||
8934 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
8943bool AMDGPUOperand::isBLGP()
const {
8944 return isImm() && getImmTy() == ImmTyBLGP && isUInt<3>(getImm());
8947bool AMDGPUOperand::isS16Imm()
const {
8948 return isImmLiteral() && (isInt<16>(getImm()) || isUInt<16>(getImm()));
8951bool AMDGPUOperand::isU16Imm()
const {
8952 return isImmLiteral() && isUInt<16>(getImm());
8959bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
8964 SMLoc Loc = getToken().getEndLoc();
8965 Token = std::string(getTokenStr());
8967 if (getLoc() != Loc)
8972 if (!parseId(Suffix))
8998 SMLoc Loc = getLoc();
8999 if (!parseDimId(Encoding))
9000 return Error(Loc,
"invalid dim value");
9002 Operands.push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9003 AMDGPUOperand::ImmTyDim));
9021 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9024 for (
size_t i = 0; i < 8; ++i) {
9028 SMLoc Loc = getLoc();
9029 if (getParser().parseAbsoluteExpression(Sels[i]))
9031 if (0 > Sels[i] || 7 < Sels[i])
9032 return Error(Loc,
"expected a 3-bit value");
9039 for (
size_t i = 0; i < 8; ++i)
9040 DPP8 |= (Sels[i] << (i * 3));
9042 Operands.push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9047AMDGPUAsmParser::isSupportedDPPCtrl(
StringRef Ctrl,
9049 if (Ctrl ==
"row_newbcast")
9052 if (Ctrl ==
"row_share" ||
9053 Ctrl ==
"row_xmask")
9056 if (Ctrl ==
"wave_shl" ||
9057 Ctrl ==
"wave_shr" ||
9058 Ctrl ==
"wave_rol" ||
9059 Ctrl ==
"wave_ror" ||
9060 Ctrl ==
"row_bcast")
9063 return Ctrl ==
"row_mirror" ||
9064 Ctrl ==
"row_half_mirror" ||
9065 Ctrl ==
"quad_perm" ||
9066 Ctrl ==
"row_shl" ||
9067 Ctrl ==
"row_shr" ||
9072AMDGPUAsmParser::parseDPPCtrlPerm() {
9075 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9079 for (
int i = 0; i < 4; ++i) {
9084 SMLoc Loc = getLoc();
9085 if (getParser().parseAbsoluteExpression(Temp))
9087 if (Temp < 0 || Temp > 3) {
9088 Error(Loc,
"expected a 2-bit value");
9092 Val += (Temp << i * 2);
9102AMDGPUAsmParser::parseDPPCtrlSel(
StringRef Ctrl) {
9103 using namespace AMDGPU::DPP;
9108 SMLoc Loc = getLoc();
9110 if (getParser().parseAbsoluteExpression(Val))
9113 struct DppCtrlCheck {
9120 .
Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
9121 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
9122 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
9123 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
9124 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
9125 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
9126 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
9127 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
9128 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
9129 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
9133 if (
Check.Ctrl == -1) {
9134 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
9135 Val = (Val == 15)? DppCtrl::BCAST15 : DppCtrl::BCAST31;
9150 using namespace AMDGPU::DPP;
9153 !isSupportedDPPCtrl(getTokenStr(),
Operands))
9162 if (Ctrl ==
"row_mirror") {
9163 Val = DppCtrl::ROW_MIRROR;
9164 }
else if (Ctrl ==
"row_half_mirror") {
9165 Val = DppCtrl::ROW_HALF_MIRROR;
9168 if (Ctrl ==
"quad_perm") {
9169 Val = parseDPPCtrlPerm();
9171 Val = parseDPPCtrlSel(Ctrl);
9180 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
9186 OptionalImmIndexMap OptionalIdx;
9196 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
9200 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9201 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9205 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9209 if (OldIdx == NumOperands) {
9211 constexpr int DST_IDX = 0;
9213 }
else if (Src2ModIdx == NumOperands) {
9224 bool IsVOP3CvtSrDpp =
9225 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9226 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9227 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9228 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
9229 if (IsVOP3CvtSrDpp) {
9243 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9245 if (IsDPP8 &&
Op.isDppFI()) {
9248 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9249 }
else if (
Op.isReg()) {
9250 Op.addRegOperands(Inst, 1);
9251 }
else if (
Op.isImm() &&
9253 assert(!
Op.IsImmKindLiteral() &&
"Cannot use literal with DPP");
9254 Op.addImmOperands(Inst, 1);
9255 }
else if (
Op.isImm()) {
9256 OptionalIdx[
Op.getImmTy()] =
I;
9264 AMDGPUOperand::ImmTyByteSel);
9268 AMDGPUOperand::ImmTyClamp);
9274 cvtVOP3P(Inst,
Operands, OptionalIdx);
9276 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
9293 AMDGPUOperand::ImmTyDppFI);
9298 OptionalImmIndexMap OptionalIdx;
9302 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9303 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9307 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9315 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9317 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
9325 Op.addImmOperands(Inst, 1);
9327 Op.addRegWithFPInputModsOperands(Inst, 2);
9328 }
else if (
Op.isDppFI()) {
9330 }
else if (
Op.isReg()) {
9331 Op.addRegOperands(Inst, 1);
9337 Op.addRegWithFPInputModsOperands(Inst, 2);
9338 }
else if (
Op.isReg()) {
9339 Op.addRegOperands(Inst, 1);
9340 }
else if (
Op.isDPPCtrl()) {
9341 Op.addImmOperands(Inst, 1);
9342 }
else if (
Op.isImm()) {
9344 OptionalIdx[
Op.getImmTy()] =
I;
9360 AMDGPUOperand::ImmTyDppFI);
9371 AMDGPUOperand::ImmTy
Type) {
9384 .
Case(
"BYTE_0", SdwaSel::BYTE_0)
9385 .
Case(
"BYTE_1", SdwaSel::BYTE_1)
9386 .
Case(
"BYTE_2", SdwaSel::BYTE_2)
9387 .
Case(
"BYTE_3", SdwaSel::BYTE_3)
9388 .
Case(
"WORD_0", SdwaSel::WORD_0)
9389 .
Case(
"WORD_1", SdwaSel::WORD_1)
9390 .
Case(
"DWORD", SdwaSel::DWORD)
9393 if (
Int == 0xffffffff)
9394 return Error(StringLoc,
"invalid " +
Twine(Prefix) +
" value");
9413 .
Case(
"UNUSED_PAD", DstUnused::UNUSED_PAD)
9414 .
Case(
"UNUSED_SEXT", DstUnused::UNUSED_SEXT)
9415 .
Case(
"UNUSED_PRESERVE", DstUnused::UNUSED_PRESERVE)
9418 if (
Int == 0xffffffff)
9419 return Error(StringLoc,
"invalid dst_unused value");
9421 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Int, S, AMDGPUOperand::ImmTySDWADstUnused));
9451 OptionalImmIndexMap OptionalIdx;
9452 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
9453 bool SkippedVcc =
false;
9457 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9458 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9461 for (
unsigned E =
Operands.size();
I != E; ++
I) {
9462 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9463 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
9464 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
9482 Op.addRegOrImmWithInputModsOperands(Inst, 2);
9483 }
else if (
Op.isImm()) {
9485 OptionalIdx[
Op.getImmTy()] =
I;
9493 if (Opc != AMDGPU::V_NOP_sdwa_gfx10 && Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
9494 Opc != AMDGPU::V_NOP_sdwa_vi) {
9496 switch (BasicInstType) {
9500 AMDGPUOperand::ImmTyClamp, 0);
9504 AMDGPUOperand::ImmTyOModSI, 0);
9508 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
9512 AMDGPUOperand::ImmTySDWADstUnused,
9513 DstUnused::UNUSED_PRESERVE);
9520 AMDGPUOperand::ImmTyClamp, 0);
9534 AMDGPUOperand::ImmTyClamp, 0);
9540 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
9546 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
9547 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
9548 auto it = Inst.
begin();
9561#define GET_REGISTER_MATCHER
9562#define GET_MATCHER_IMPLEMENTATION
9563#define GET_MNEMONIC_SPELL_CHECKER
9564#define GET_MNEMONIC_CHECKER
9565#include "AMDGPUGenAsmMatcher.inc"
9571 return parseTokenOp(
"addr64",
Operands);
9573 return parseTokenOp(
"done",
Operands);
9575 return parseTokenOp(
"idxen",
Operands);
9577 return parseTokenOp(
"lds",
Operands);
9579 return parseTokenOp(
"offen",
Operands);
9581 return parseTokenOp(
"off",
Operands);
9583 return parseTokenOp(
"row_en",
Operands);
9585 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
9587 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
9589 return tryCustomParseOperand(
Operands, MCK);
9600 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
9603 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
9605 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
9607 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
9609 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
9611 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
9613 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
9621 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
9623 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
9624 case MCK_SOPPBrTarget:
9625 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
9626 case MCK_VReg32OrOff:
9627 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
9628 case MCK_InterpSlot:
9629 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
9630 case MCK_InterpAttr:
9631 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
9632 case MCK_InterpAttrChan:
9633 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
9635 case MCK_SReg_64_XEXEC:
9641 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
9643 return Match_InvalidOperand;
9660 if (!isUInt<16>(Imm))
9661 return Error(S,
"expected a 16-bit value");
9664 AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTyEndpgm));
9668bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
9674bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
unsigned const MachineRegisterInfo * MRI
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
constexpr uint64_t MIMGFlags
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static unsigned getSpecialRegForName(StringRef RegName)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, unsigned OpName)
static bool IsRevOpcode(const unsigned Opcode)
static int getRegClass(RegisterKind Is, unsigned RegWidth)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
static int IsAGPROperand(const MCInst &Inst, uint16_t NameIdx, const MCRegisterInfo *MRI)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static unsigned getOperandSize(MachineInstr &MI, unsigned Idx, MachineRegisterInfo &MRI)
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
mir Rename Register Operands
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
Interface definition for SIInstrInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Interface definition for SIRegisterInfo.
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
unsigned unsigned DefaultVal
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
support::ulittle16_t & Lo
support::ulittle16_t & Hi
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Target independent representation for an assembler token.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Class representing an expression and its matching format.
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCRegisterInfo * getRegisterInfo() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCSubtargetInfo * getSubtargetInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
bool mayStore() const
Return true if this instruction could possibly modify memory.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
void setReg(unsigned Reg)
Set the register number.
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NoRegister
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void setVariableValue(const MCExpr *Value)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
Target specific streamer interface.
uint64_t getScalarSizeInBits() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
Represents a range in source code.
Implements a dense probed hash-table based set with some number of buckets stored inline.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
StringSet - A wrapper for StringMap that provides set-like functionality.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
unsigned getTgtId(const StringRef Name)
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI)
unsigned getVGPREncodingGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI)
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc, unsigned OpNo)
Get size of register operand.
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
LLVM_READNONE bool isLegalDPALU_DPPControl(unsigned DC)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
bool isGFX10(const MCSubtargetInfo &STI)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
bool isInlinableLiteralV2BF16(uint32_t Literal)
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
unsigned mc2PseudoReg(unsigned Reg)
Convert hardware register Reg to a pseudo register.
bool hasA16(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset, bool IsBuffer)
bool isGFX12Plus(const MCSubtargetInfo &STI)
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool isHsaAbi(const MCSubtargetInfo &STI)
bool isGFX11(const MCSubtargetInfo &STI)
const int OPR_VAL_INVALID
bool getSMEMIsBuffer(unsigned Opc)
IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
bool isDPALU_DPP(const MCInstrDesc &OpDesc)
bool isSI(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
bool isGFX9(const MCSubtargetInfo &STI)
bool isGFX10_AEncoding(const MCSubtargetInfo &STI)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this an AMDGPU specific source operand? These include registers, inline constants,...
bool hasMAIInsts(const MCSubtargetInfo &STI)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, uint64_t NamedIdx)
LLVM_READNONE bool isInlinableIntLiteral(int64_t Literal)
Is this literal inlinable, and not one of the values intended for floating point values.
bool isSGPR(unsigned Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
bool isHi(unsigned Reg, const MCRegisterInfo &MRI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isInlineValue(unsigned Reg)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_V2INT32
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_INLINE_AC_V2FP16
@ OPERAND_REG_IMM_INT32
Operands with register or 32-bit immediate.
@ OPERAND_REG_IMM_BF16_DEFERRED
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_AC_BF16
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_INLINE_AC_INT16
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_V2INT16
@ OPERAND_REG_INLINE_AC_FP16
@ OPERAND_REG_INLINE_AC_INT32
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_INLINE_AC_V2BF16
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_REG_INLINE_C_V2FP32
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
@ OPERAND_REG_IMM_FP32_DEFERRED
@ OPERAND_REG_IMM_FP16_DEFERRED
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isVI(const MCSubtargetInfo &STI)
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
Reg
All possible values of the reg field in the ModR/M byte.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
int popcount(T Value) noexcept
Count the number of set bits in a value.
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
Instruction set architecture version.
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
const MCExpr * compute_pgm_rsrc1
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * group_segment_fixed_size
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * kernel_code_properties
Represents the counter values to wait for in an s_waitcnt instruction.
static const fltSemantics & IEEEsingle() LLVM_READNONE
static const fltSemantics & IEEEhalf() LLVM_READNONE
static const fltSemantics & BFloat() LLVM_READNONE
opStatus
IEEE-754R 7: Default exception handling.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Description of the encoding of one expression Op.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size