52enum RegisterKind { IS_UNKNOWN,
IS_VGPR, IS_SGPR, IS_AGPR, IS_TTMP, IS_SPECIAL };
66 SMLoc StartLoc, EndLoc;
67 const AMDGPUAsmParser *AsmParser;
70 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
71 :
Kind(Kind_), AsmParser(AsmParser_) {}
73 using Ptr = std::unique_ptr<AMDGPUOperand>;
81 bool hasFPModifiers()
const {
return Abs || Neg; }
82 bool hasIntModifiers()
const {
return Sext; }
83 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
85 int64_t getFPModifiersOperand()
const {
92 int64_t getIntModifiersOperand()
const {
98 int64_t getModifiersOperand()
const {
99 assert(!(hasFPModifiers() && hasIntModifiers())
100 &&
"fp and int modifiers should not be used simultaneously");
101 if (hasFPModifiers()) {
102 return getFPModifiersOperand();
103 }
else if (hasIntModifiers()) {
104 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 isDMask()
const {
return isImmTy(ImmTyDMask); }
378 bool isDim()
const {
return isImmTy(ImmTyDim); }
379 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
380 bool isOff()
const {
return isImmTy(ImmTyOff); }
381 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
382 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
383 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
384 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
385 bool isOffset()
const {
return isImmTy(ImmTyOffset); }
386 bool isOffset0()
const {
return isImmTy(ImmTyOffset0) && isUInt<8>(getImm()); }
387 bool isOffset1()
const {
return isImmTy(ImmTyOffset1) && isUInt<8>(getImm()); }
388 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
389 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
390 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
391 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
392 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
393 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
394 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
395 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
396 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) && isUInt<7>(getImm()); }
397 bool isDppBankMask()
const {
return isImmTy(ImmTyDppBankMask); }
398 bool isDppRowMask()
const {
return isImmTy(ImmTyDppRowMask); }
399 bool isDppBoundCtrl()
const {
return isImmTy(ImmTyDppBoundCtrl); }
400 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
401 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
402 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
403 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
404 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
405 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
406 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
407 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
408 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
409 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
410 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
411 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
413 bool isRegOrImm()
const {
417 bool isRegClass(
unsigned RCID)
const;
421 bool isRegOrInlineNoMods(
unsigned RCID,
MVT type)
const {
422 return isRegOrInline(RCID, type) && !hasModifiers();
425 bool isSCSrcB16()
const {
426 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
429 bool isSCSrcV2B16()
const {
433 bool isSCSrc_b32()
const {
434 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
437 bool isSCSrc_b64()
const {
438 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
441 bool isBoolReg()
const;
443 bool isSCSrcF16()
const {
444 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
447 bool isSCSrcV2F16()
const {
451 bool isSCSrcF32()
const {
452 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
455 bool isSCSrcF64()
const {
456 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
459 bool isSSrc_b32()
const {
460 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
463 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
465 bool isSSrcV2B16()
const {
470 bool isSSrc_b64()
const {
473 return isSCSrc_b64() || isLiteralImm(MVT::i64);
476 bool isSSrc_f32()
const {
477 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
480 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
482 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
484 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
486 bool isSSrcV2F16()
const {
491 bool isSSrcV2FP32()
const {
496 bool isSCSrcV2FP32()
const {
501 bool isSSrcV2INT32()
const {
506 bool isSCSrcV2INT32()
const {
508 return isSCSrc_b32();
511 bool isSSrcOrLds_b32()
const {
512 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
513 isLiteralImm(MVT::i32) || isExpr();
516 bool isVCSrc_b32()
const {
517 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
520 bool isVCSrcB64()
const {
521 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
524 bool isVCSrcTB16()
const {
525 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
528 bool isVCSrcTB16_Lo128()
const {
529 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
532 bool isVCSrcFake16B16_Lo128()
const {
533 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
536 bool isVCSrc_b16()
const {
537 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
540 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
542 bool isVCSrc_f32()
const {
543 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
546 bool isVCSrcF64()
const {
547 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
550 bool isVCSrcTBF16()
const {
551 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
554 bool isVCSrcTF16()
const {
555 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
558 bool isVCSrcTBF16_Lo128()
const {
559 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
562 bool isVCSrcTF16_Lo128()
const {
563 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
566 bool isVCSrcFake16BF16_Lo128()
const {
567 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
570 bool isVCSrcFake16F16_Lo128()
const {
571 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
574 bool isVCSrc_bf16()
const {
575 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
578 bool isVCSrc_f16()
const {
579 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
582 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
584 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
586 bool isVSrc_b32()
const {
587 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
590 bool isVSrc_b64()
const {
return isVCSrcF64() || isLiteralImm(MVT::i64); }
592 bool isVSrcT_b16()
const {
return isVCSrcTB16() || isLiteralImm(MVT::i16); }
594 bool isVSrcT_b16_Lo128()
const {
595 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
598 bool isVSrcFake16_b16_Lo128()
const {
599 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
602 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
604 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
606 bool isVCSrcV2FP32()
const {
610 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
612 bool isVCSrcV2INT32()
const {
616 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
618 bool isVSrc_f32()
const {
619 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
622 bool isVSrc_f64()
const {
return isVCSrcF64() || isLiteralImm(MVT::f64); }
624 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
626 bool isVSrcT_f16()
const {
return isVCSrcTF16() || isLiteralImm(MVT::f16); }
628 bool isVSrcT_bf16_Lo128()
const {
629 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
632 bool isVSrcT_f16_Lo128()
const {
633 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
636 bool isVSrcFake16_bf16_Lo128()
const {
637 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
640 bool isVSrcFake16_f16_Lo128()
const {
641 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
644 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
646 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
648 bool isVSrc_v2bf16()
const {
649 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
652 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
654 bool isVISrcB32()
const {
655 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
658 bool isVISrcB16()
const {
659 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
662 bool isVISrcV2B16()
const {
666 bool isVISrcF32()
const {
667 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
670 bool isVISrcF16()
const {
671 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
674 bool isVISrcV2F16()
const {
675 return isVISrcF16() || isVISrcB32();
678 bool isVISrc_64_bf16()
const {
679 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
682 bool isVISrc_64_f16()
const {
683 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
686 bool isVISrc_64_b32()
const {
687 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
690 bool isVISrc_64B64()
const {
691 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
694 bool isVISrc_64_f64()
const {
695 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
698 bool isVISrc_64V2FP32()
const {
699 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
702 bool isVISrc_64V2INT32()
const {
703 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
706 bool isVISrc_256_b32()
const {
707 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
710 bool isVISrc_256_f32()
const {
711 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
714 bool isVISrc_256B64()
const {
715 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
718 bool isVISrc_256_f64()
const {
719 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
722 bool isVISrc_128B16()
const {
723 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
726 bool isVISrc_128V2B16()
const {
727 return isVISrc_128B16();
730 bool isVISrc_128_b32()
const {
731 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
734 bool isVISrc_128_f32()
const {
735 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
738 bool isVISrc_256V2FP32()
const {
739 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
742 bool isVISrc_256V2INT32()
const {
743 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
746 bool isVISrc_512_b32()
const {
747 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
750 bool isVISrc_512B16()
const {
751 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
754 bool isVISrc_512V2B16()
const {
755 return isVISrc_512B16();
758 bool isVISrc_512_f32()
const {
759 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
762 bool isVISrc_512F16()
const {
763 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
766 bool isVISrc_512V2F16()
const {
767 return isVISrc_512F16() || isVISrc_512_b32();
770 bool isVISrc_1024_b32()
const {
771 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
774 bool isVISrc_1024B16()
const {
775 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
778 bool isVISrc_1024V2B16()
const {
779 return isVISrc_1024B16();
782 bool isVISrc_1024_f32()
const {
783 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
786 bool isVISrc_1024F16()
const {
787 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
790 bool isVISrc_1024V2F16()
const {
791 return isVISrc_1024F16() || isVISrc_1024_b32();
794 bool isAISrcB32()
const {
795 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
798 bool isAISrcB16()
const {
799 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
802 bool isAISrcV2B16()
const {
806 bool isAISrcF32()
const {
807 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
810 bool isAISrcF16()
const {
811 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
814 bool isAISrcV2F16()
const {
815 return isAISrcF16() || isAISrcB32();
818 bool isAISrc_64B64()
const {
819 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
822 bool isAISrc_64_f64()
const {
823 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
826 bool isAISrc_128_b32()
const {
827 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
830 bool isAISrc_128B16()
const {
831 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
834 bool isAISrc_128V2B16()
const {
835 return isAISrc_128B16();
838 bool isAISrc_128_f32()
const {
839 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
842 bool isAISrc_128F16()
const {
843 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
846 bool isAISrc_128V2F16()
const {
847 return isAISrc_128F16() || isAISrc_128_b32();
850 bool isVISrc_128_bf16()
const {
851 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
854 bool isVISrc_128_f16()
const {
855 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
858 bool isVISrc_128V2F16()
const {
859 return isVISrc_128_f16() || isVISrc_128_b32();
862 bool isAISrc_256B64()
const {
863 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
866 bool isAISrc_256_f64()
const {
867 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
870 bool isAISrc_512_b32()
const {
871 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
874 bool isAISrc_512B16()
const {
875 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
878 bool isAISrc_512V2B16()
const {
879 return isAISrc_512B16();
882 bool isAISrc_512_f32()
const {
883 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
886 bool isAISrc_512F16()
const {
887 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
890 bool isAISrc_512V2F16()
const {
891 return isAISrc_512F16() || isAISrc_512_b32();
894 bool isAISrc_1024_b32()
const {
895 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
898 bool isAISrc_1024B16()
const {
899 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
902 bool isAISrc_1024V2B16()
const {
903 return isAISrc_1024B16();
906 bool isAISrc_1024_f32()
const {
907 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
910 bool isAISrc_1024F16()
const {
911 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
914 bool isAISrc_1024V2F16()
const {
915 return isAISrc_1024F16() || isAISrc_1024_b32();
918 bool isKImmFP32()
const {
919 return isLiteralImm(MVT::f32);
922 bool isKImmFP16()
const {
923 return isLiteralImm(MVT::f16);
926 bool isMem()
const override {
930 bool isExpr()
const {
934 bool isSOPPBrTarget()
const {
return isExpr() ||
isImm(); }
936 bool isSWaitCnt()
const;
937 bool isDepCtr()
const;
938 bool isSDelayALU()
const;
939 bool isHwreg()
const;
940 bool isSendMsg()
const;
941 bool isSplitBarrier()
const;
942 bool isSwizzle()
const;
943 bool isSMRDOffset8()
const;
944 bool isSMEMOffset()
const;
945 bool isSMRDLiteralOffset()
const;
947 bool isDPPCtrl()
const;
951 bool isGPRIdxMode()
const;
952 bool isS16Imm()
const;
953 bool isU16Imm()
const;
954 bool isEndpgm()
const;
955 bool isWaitVDST()
const;
956 bool isWaitEXP()
const;
957 bool isWaitVAVDst()
const;
958 bool isWaitVMVSrc()
const;
960 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
961 return std::bind(
P, *
this);
969 int64_t getImm()
const {
974 void setImm(int64_t Val) {
979 ImmTy getImmTy()
const {
984 unsigned getReg()
const override {
989 SMLoc getStartLoc()
const override {
993 SMLoc getEndLoc()
const override {
998 return SMRange(StartLoc, EndLoc);
1001 Modifiers getModifiers()
const {
1002 assert(isRegKind() || isImmTy(ImmTyNone));
1003 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1006 void setModifiers(Modifiers Mods) {
1007 assert(isRegKind() || isImmTy(ImmTyNone));
1014 bool hasModifiers()
const {
1015 return getModifiers().hasModifiers();
1018 bool hasFPModifiers()
const {
1019 return getModifiers().hasFPModifiers();
1022 bool hasIntModifiers()
const {
1023 return getModifiers().hasIntModifiers();
1028 void addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1030 void addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1032 void addRegOperands(
MCInst &Inst,
unsigned N)
const;
1034 void addRegOrImmOperands(
MCInst &Inst,
unsigned N)
const {
1036 addRegOperands(Inst,
N);
1038 addImmOperands(Inst,
N);
1041 void addRegOrImmWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1042 Modifiers Mods = getModifiers();
1045 addRegOperands(Inst,
N);
1047 addImmOperands(Inst,
N,
false);
1051 void addRegOrImmWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1052 assert(!hasIntModifiers());
1053 addRegOrImmWithInputModsOperands(Inst,
N);
1056 void addRegOrImmWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1057 assert(!hasFPModifiers());
1058 addRegOrImmWithInputModsOperands(Inst,
N);
1061 void addRegWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1062 Modifiers Mods = getModifiers();
1065 addRegOperands(Inst,
N);
1068 void addRegWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1069 assert(!hasIntModifiers());
1070 addRegWithInputModsOperands(Inst,
N);
1073 void addRegWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
1074 assert(!hasFPModifiers());
1075 addRegWithInputModsOperands(Inst,
N);
1081 case ImmTyNone:
OS <<
"None";
break;
1082 case ImmTyGDS:
OS <<
"GDS";
break;
1083 case ImmTyLDS:
OS <<
"LDS";
break;
1084 case ImmTyOffen:
OS <<
"Offen";
break;
1085 case ImmTyIdxen:
OS <<
"Idxen";
break;
1086 case ImmTyAddr64:
OS <<
"Addr64";
break;
1087 case ImmTyOffset:
OS <<
"Offset";
break;
1088 case ImmTyInstOffset:
OS <<
"InstOffset";
break;
1089 case ImmTyOffset0:
OS <<
"Offset0";
break;
1090 case ImmTyOffset1:
OS <<
"Offset1";
break;
1091 case ImmTySMEMOffsetMod:
OS <<
"SMEMOffsetMod";
break;
1092 case ImmTyCPol:
OS <<
"CPol";
break;
1093 case ImmTyIndexKey8bit:
OS <<
"index_key";
break;
1094 case ImmTyIndexKey16bit:
OS <<
"index_key";
break;
1095 case ImmTyTFE:
OS <<
"TFE";
break;
1096 case ImmTyD16:
OS <<
"D16";
break;
1097 case ImmTyFORMAT:
OS <<
"FORMAT";
break;
1098 case ImmTyClampSI:
OS <<
"ClampSI";
break;
1099 case ImmTyOModSI:
OS <<
"OModSI";
break;
1100 case ImmTyDPP8:
OS <<
"DPP8";
break;
1101 case ImmTyDppCtrl:
OS <<
"DppCtrl";
break;
1102 case ImmTyDppRowMask:
OS <<
"DppRowMask";
break;
1103 case ImmTyDppBankMask:
OS <<
"DppBankMask";
break;
1104 case ImmTyDppBoundCtrl:
OS <<
"DppBoundCtrl";
break;
1105 case ImmTyDppFI:
OS <<
"DppFI";
break;
1106 case ImmTySDWADstSel:
OS <<
"SDWADstSel";
break;
1107 case ImmTySDWASrc0Sel:
OS <<
"SDWASrc0Sel";
break;
1108 case ImmTySDWASrc1Sel:
OS <<
"SDWASrc1Sel";
break;
1109 case ImmTySDWADstUnused:
OS <<
"SDWADstUnused";
break;
1110 case ImmTyDMask:
OS <<
"DMask";
break;
1111 case ImmTyDim:
OS <<
"Dim";
break;
1112 case ImmTyUNorm:
OS <<
"UNorm";
break;
1113 case ImmTyDA:
OS <<
"DA";
break;
1114 case ImmTyR128A16:
OS <<
"R128A16";
break;
1115 case ImmTyA16:
OS <<
"A16";
break;
1116 case ImmTyLWE:
OS <<
"LWE";
break;
1117 case ImmTyOff:
OS <<
"Off";
break;
1118 case ImmTyExpTgt:
OS <<
"ExpTgt";
break;
1119 case ImmTyExpCompr:
OS <<
"ExpCompr";
break;
1120 case ImmTyExpVM:
OS <<
"ExpVM";
break;
1121 case ImmTyHwreg:
OS <<
"Hwreg";
break;
1122 case ImmTySendMsg:
OS <<
"SendMsg";
break;
1123 case ImmTyInterpSlot:
OS <<
"InterpSlot";
break;
1124 case ImmTyInterpAttr:
OS <<
"InterpAttr";
break;
1125 case ImmTyInterpAttrChan:
OS <<
"InterpAttrChan";
break;
1126 case ImmTyOpSel:
OS <<
"OpSel";
break;
1127 case ImmTyOpSelHi:
OS <<
"OpSelHi";
break;
1128 case ImmTyNegLo:
OS <<
"NegLo";
break;
1129 case ImmTyNegHi:
OS <<
"NegHi";
break;
1130 case ImmTySwizzle:
OS <<
"Swizzle";
break;
1131 case ImmTyGprIdxMode:
OS <<
"GprIdxMode";
break;
1132 case ImmTyHigh:
OS <<
"High";
break;
1133 case ImmTyBLGP:
OS <<
"BLGP";
break;
1134 case ImmTyCBSZ:
OS <<
"CBSZ";
break;
1135 case ImmTyABID:
OS <<
"ABID";
break;
1136 case ImmTyEndpgm:
OS <<
"Endpgm";
break;
1137 case ImmTyWaitVDST:
OS <<
"WaitVDST";
break;
1138 case ImmTyWaitEXP:
OS <<
"WaitEXP";
break;
1139 case ImmTyWaitVAVDst:
OS <<
"WaitVAVDst";
break;
1140 case ImmTyWaitVMVSrc:
OS <<
"WaitVMVSrc";
break;
1148 OS <<
"<register " <<
getReg() <<
" mods: " <<
Reg.Mods <<
'>';
1151 OS <<
'<' << getImm();
1152 if (getImmTy() != ImmTyNone) {
1153 OS <<
" type: "; printImmTy(
OS, getImmTy());
1155 OS <<
" mods: " <<
Imm.Mods <<
'>';
1158 OS <<
'\'' << getToken() <<
'\'';
1161 OS <<
"<expr " << *Expr <<
'>';
1166 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1167 int64_t Val,
SMLoc Loc,
1168 ImmTy
Type = ImmTyNone,
1169 bool IsFPImm =
false) {
1170 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1172 Op->Imm.IsFPImm = IsFPImm;
1173 Op->Imm.Kind = ImmKindTyNone;
1175 Op->Imm.Mods = Modifiers();
1181 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1183 bool HasExplicitEncodingSize =
true) {
1184 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1185 Res->Tok.Data = Str.data();
1186 Res->Tok.Length = Str.size();
1187 Res->StartLoc = Loc;
1192 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1193 unsigned RegNo,
SMLoc S,
1195 auto Op = std::make_unique<AMDGPUOperand>(
Register, AsmParser);
1196 Op->Reg.RegNo = RegNo;
1197 Op->Reg.Mods = Modifiers();
1203 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1205 auto Op = std::make_unique<AMDGPUOperand>(
Expression, AsmParser);
1214 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1225class KernelScopeInfo {
1226 int SgprIndexUnusedMin = -1;
1227 int VgprIndexUnusedMin = -1;
1228 int AgprIndexUnusedMin = -1;
1232 void usesSgprAt(
int i) {
1233 if (i >= SgprIndexUnusedMin) {
1234 SgprIndexUnusedMin = ++i;
1243 void usesVgprAt(
int i) {
1244 if (i >= VgprIndexUnusedMin) {
1245 VgprIndexUnusedMin = ++i;
1250 VgprIndexUnusedMin);
1256 void usesAgprAt(
int i) {
1261 if (i >= AgprIndexUnusedMin) {
1262 AgprIndexUnusedMin = ++i;
1272 VgprIndexUnusedMin);
1279 KernelScopeInfo() =
default;
1285 usesSgprAt(SgprIndexUnusedMin = -1);
1286 usesVgprAt(VgprIndexUnusedMin = -1);
1288 usesAgprAt(AgprIndexUnusedMin = -1);
1292 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1293 unsigned RegWidth) {
1296 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1299 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1302 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1313 unsigned ForcedEncodingSize = 0;
1314 bool ForcedDPP =
false;
1315 bool ForcedSDWA =
false;
1316 KernelScopeInfo KernelScope;
1321#define GET_ASSEMBLER_HEADER
1322#include "AMDGPUGenAsmMatcher.inc"
1327 bool ParseAsAbsoluteExpression(
uint32_t &Ret);
1328 bool OutOfRangeError(
SMRange Range);
1344 bool calculateGPRBlocks(
const FeatureBitset &Features,
bool VCCUsed,
1345 bool FlatScrUsed,
bool XNACKUsed,
1346 std::optional<bool> EnableWavefrontSize32,
1347 unsigned NextFreeVGPR,
SMRange VGPRRange,
1348 unsigned NextFreeSGPR,
SMRange SGPRRange,
1349 unsigned &VGPRBlocks,
unsigned &SGPRBlocks);
1350 bool ParseDirectiveAMDGCNTarget();
1351 bool ParseDirectiveAMDHSACodeObjectVersion();
1352 bool ParseDirectiveAMDHSAKernel();
1354 bool ParseDirectiveAMDKernelCodeT();
1357 bool ParseDirectiveAMDGPUHsaKernel();
1359 bool ParseDirectiveISAVersion();
1360 bool ParseDirectiveHSAMetadata();
1361 bool ParseDirectivePALMetadataBegin();
1362 bool ParseDirectivePALMetadata();
1363 bool ParseDirectiveAMDGPULDS();
1367 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1368 const char *AssemblerDirectiveEnd,
1369 std::string &CollectString);
1371 bool AddNextRegisterToList(
unsigned& Reg,
unsigned& RegWidth,
1372 RegisterKind RegKind,
unsigned Reg1,
SMLoc Loc);
1373 bool ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
1374 unsigned &RegNum,
unsigned &RegWidth,
1375 bool RestoreOnFailure =
false);
1376 bool ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
1377 unsigned &RegNum,
unsigned &RegWidth,
1379 unsigned ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1382 unsigned ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1385 unsigned ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1387 bool ParseRegRange(
unsigned& Num,
unsigned& Width);
1388 unsigned getRegularReg(RegisterKind RegKind,
unsigned RegNum,
unsigned SubReg,
1389 unsigned RegWidth,
SMLoc Loc);
1393 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1394 void initializeGprCountSymbol(RegisterKind RegKind);
1395 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1401 enum AMDGPUMatchResultTy {
1402 Match_PreferE32 = FIRST_TARGET_MATCH_RESULT_TY
1405 OperandMode_Default,
1409 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1417 if (getFeatureBits().
none()) {
1449 initializeGprCountSymbol(IS_VGPR);
1450 initializeGprCountSymbol(IS_SGPR);
1523 bool hasInv2PiInlineImm()
const {
1524 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1527 bool hasFlatOffsets()
const {
1528 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1532 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1535 bool hasSGPR102_SGPR103()
const {
1539 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1541 bool hasIntClamp()
const {
1542 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1545 bool hasPartialNSAEncoding()
const {
1546 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1578 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1579 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1580 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1582 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1583 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1584 bool isForcedDPP()
const {
return ForcedDPP; }
1585 bool isForcedSDWA()
const {
return ForcedSDWA; }
1587 StringRef getMatchedVariantName()
const;
1589 std::unique_ptr<AMDGPUOperand>
parseRegister(
bool RestoreOnFailure =
false);
1591 bool RestoreOnFailure);
1594 SMLoc &EndLoc)
override;
1597 unsigned Kind)
override;
1601 bool MatchingInlineAsm)
override;
1604 OperandMode Mode = OperandMode_Default);
1612 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1616 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1617 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1621 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1622 bool (*ConvertResult)(int64_t &) =
nullptr);
1626 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1635 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1636 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1637 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1638 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1639 bool parseSP3NegModifier();
1641 bool HasLit =
false);
1644 bool HasLit =
false);
1646 bool AllowImm =
true);
1648 bool AllowImm =
true);
1653 AMDGPUOperand::ImmTy ImmTy);
1664 ParseStatus parseSymbolicOrNumericFormat(int64_t &Format);
1669 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1670 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt,
StringRef FormatStr,
SMLoc Loc);
1674 bool parseCnt(int64_t &IntVal);
1677 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1681 bool parseDelay(int64_t &Delay);
1687 struct OperandInfoTy {
1690 bool IsSymbolic =
false;
1691 bool IsDefined =
false;
1693 OperandInfoTy(int64_t Val) : Val(Val) {}
1696 struct StructuredOpField : OperandInfoTy {
1700 bool IsDefined =
false;
1705 virtual ~StructuredOpField() =
default;
1707 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1708 Parser.Error(Loc,
"invalid " +
Desc +
": " + Err);
1712 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1714 return Error(Parser,
"not supported on this GPU");
1716 return Error(Parser,
"only " +
Twine(Width) +
"-bit values are legal");
1724 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1725 bool validateSendMsg(
const OperandInfoTy &Msg,
1726 const OperandInfoTy &
Op,
1727 const OperandInfoTy &Stream);
1730 OperandInfoTy &Width);
1736 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1741 bool SearchMandatoryLiterals =
false)
const;
1750 bool validateSOPLiteral(
const MCInst &Inst)
const;
1752 bool validateVOPDRegBankConstraints(
const MCInst &Inst,
1754 bool validateIntClampSupported(
const MCInst &Inst);
1755 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1756 bool validateMIMGGatherDMask(
const MCInst &Inst);
1758 bool validateMIMGDataSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1759 bool validateMIMGAddrSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1760 bool validateMIMGD16(
const MCInst &Inst);
1761 bool validateMIMGMSAA(
const MCInst &Inst);
1762 bool validateOpSel(
const MCInst &Inst);
1765 bool validateVccOperand(
unsigned Reg)
const;
1770 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1771 bool validateVGPRAlign(
const MCInst &Inst)
const;
1775 bool validateDivScale(
const MCInst &Inst);
1778 const SMLoc &IDLoc);
1780 const unsigned CPol);
1783 std::optional<StringRef> validateLdsDirect(
const MCInst &Inst);
1784 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1785 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1786 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1787 unsigned findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1813 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1815 SMLoc getLoc()
const;
1819 void onBeginOfFile()
override;
1820 bool parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc)
override;
1831 bool parseSwizzleOperand(int64_t &
Op,
1832 const unsigned MinVal,
1833 const unsigned MaxVal,
1836 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1837 const unsigned MinVal,
1838 const unsigned MaxVal,
1841 bool parseSwizzleOffset(int64_t &Imm);
1842 bool parseSwizzleMacro(int64_t &Imm);
1843 bool parseSwizzleQuadPerm(int64_t &Imm);
1844 bool parseSwizzleBitmaskPerm(int64_t &Imm);
1845 bool parseSwizzleBroadcast(int64_t &Imm);
1846 bool parseSwizzleSwap(int64_t &Imm);
1847 bool parseSwizzleReverse(int64_t &Imm);
1850 int64_t parseGPRIdxMacro();
1858 OptionalImmIndexMap &OptionalIdx);
1866 OptionalImmIndexMap &OptionalIdx);
1868 OptionalImmIndexMap &OptionalIdx);
1873 bool parseDimId(
unsigned &Encoding);
1875 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1879 int64_t parseDPPCtrlSel(
StringRef Ctrl);
1880 int64_t parseDPPCtrlPerm();
1886 bool IsDPP8 =
false);
1892 AMDGPUOperand::ImmTy
Type);
1901 bool SkipDstVcc =
false,
1902 bool SkipSrcVcc =
false);
1915 return &APFloat::IEEEsingle();
1917 return &APFloat::IEEEdouble();
1919 return &APFloat::IEEEhalf();
1952 return &APFloat::IEEEsingle();
1958 return &APFloat::IEEEdouble();
1967 return &APFloat::IEEEhalf();
1975 return &APFloat::BFloat();
1990 APFloat::rmNearestTiesToEven,
1993 if (
Status != APFloat::opOK &&
1995 ((
Status & APFloat::opOverflow) != 0 ||
1996 (
Status & APFloat::opUnderflow) != 0)) {
2019bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2029 if (!isImmTy(ImmTyNone)) {
2040 if (type == MVT::f64 || type == MVT::i64) {
2042 AsmParser->hasInv2PiInlineImm());
2064 APFloat::rmNearestTiesToEven, &Lost);
2071 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2073 AsmParser->hasInv2PiInlineImm());
2078 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2079 AsmParser->hasInv2PiInlineImm());
2083 if (type == MVT::f64 || type == MVT::i64) {
2085 AsmParser->hasInv2PiInlineImm());
2094 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2095 type, AsmParser->hasInv2PiInlineImm());
2099 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2100 AsmParser->hasInv2PiInlineImm());
2103bool AMDGPUOperand::isLiteralImm(
MVT type)
const {
2105 if (!isImmTy(ImmTyNone)) {
2112 if (type == MVT::f64 && hasFPModifiers()) {
2129 if (type == MVT::f64) {
2134 if (type == MVT::i64) {
2147 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2148 : (type == MVT::v2i16) ? MVT::f32
2149 : (type == MVT::v2f32) ? MVT::f32
2156bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2157 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2160bool AMDGPUOperand::isVRegWithInputMods()
const {
2161 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2163 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2164 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2167template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2168 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2169 : AMDGPU::VGPR_16_Lo128RegClassID);
2172bool AMDGPUOperand::isSDWAOperand(
MVT type)
const {
2173 if (AsmParser->isVI())
2175 else if (AsmParser->isGFX9Plus())
2176 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2181bool AMDGPUOperand::isSDWAFP16Operand()
const {
2182 return isSDWAOperand(MVT::f16);
2185bool AMDGPUOperand::isSDWAFP32Operand()
const {
2186 return isSDWAOperand(MVT::f32);
2189bool AMDGPUOperand::isSDWAInt16Operand()
const {
2190 return isSDWAOperand(MVT::i16);
2193bool AMDGPUOperand::isSDWAInt32Operand()
const {
2194 return isSDWAOperand(MVT::i32);
2197bool AMDGPUOperand::isBoolReg()
const {
2198 auto FB = AsmParser->getFeatureBits();
2199 return isReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrc_b64()) ||
2200 (FB[AMDGPU::FeatureWavefrontSize32] && isSCSrc_b32()));
2205 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2220void AMDGPUOperand::addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2228 addLiteralImmOperand(Inst,
Imm.Val,
2230 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2232 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2238void AMDGPUOperand::addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2239 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2244 if (ApplyModifiers) {
2247 Val = applyInputFPModifiers(Val,
Size);
2251 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2261 AsmParser->hasInv2PiInlineImm())) {
2270 if (
Literal.getLoBits(32) != 0) {
2271 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(Inst.
getLoc(),
2272 "Can't encode literal as exact 64-bit floating-point operand. "
2273 "Low 32-bits will be set to zero");
2274 Val &= 0xffffffff00000000u;
2278 setImmKindLiteral();
2294 if (AsmParser->hasInv2PiInlineImm() &&
Literal == 0x3fc45f306725feed) {
2300 setImmKindLiteral();
2336 APFloat::rmNearestTiesToEven, &lost);
2340 uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2343 setImmKindMandatoryLiteral();
2345 setImmKindLiteral();
2376 AsmParser->hasInv2PiInlineImm())) {
2383 setImmKindLiteral();
2401 setImmKindLiteral();
2415 setImmKindLiteral();
2424 AsmParser->hasInv2PiInlineImm())) {
2431 setImmKindLiteral();
2440 AsmParser->hasInv2PiInlineImm())) {
2447 setImmKindLiteral();
2461 AsmParser->hasInv2PiInlineImm()));
2471 AsmParser->hasInv2PiInlineImm()));
2479 setImmKindMandatoryLiteral();
2483 setImmKindMandatoryLiteral();
2490void AMDGPUOperand::addRegOperands(
MCInst &Inst,
unsigned N)
const {
2494bool AMDGPUOperand::isInlineValue()
const {
2503 if (Is == IS_VGPR) {
2507 return AMDGPU::VGPR_32RegClassID;
2509 return AMDGPU::VReg_64RegClassID;
2511 return AMDGPU::VReg_96RegClassID;
2513 return AMDGPU::VReg_128RegClassID;
2515 return AMDGPU::VReg_160RegClassID;
2517 return AMDGPU::VReg_192RegClassID;
2519 return AMDGPU::VReg_224RegClassID;
2521 return AMDGPU::VReg_256RegClassID;
2523 return AMDGPU::VReg_288RegClassID;
2525 return AMDGPU::VReg_320RegClassID;
2527 return AMDGPU::VReg_352RegClassID;
2529 return AMDGPU::VReg_384RegClassID;
2531 return AMDGPU::VReg_512RegClassID;
2533 return AMDGPU::VReg_1024RegClassID;
2535 }
else if (Is == IS_TTMP) {
2539 return AMDGPU::TTMP_32RegClassID;
2541 return AMDGPU::TTMP_64RegClassID;
2543 return AMDGPU::TTMP_128RegClassID;
2545 return AMDGPU::TTMP_256RegClassID;
2547 return AMDGPU::TTMP_512RegClassID;
2549 }
else if (Is == IS_SGPR) {
2553 return AMDGPU::SGPR_32RegClassID;
2555 return AMDGPU::SGPR_64RegClassID;
2557 return AMDGPU::SGPR_96RegClassID;
2559 return AMDGPU::SGPR_128RegClassID;
2561 return AMDGPU::SGPR_160RegClassID;
2563 return AMDGPU::SGPR_192RegClassID;
2565 return AMDGPU::SGPR_224RegClassID;
2567 return AMDGPU::SGPR_256RegClassID;
2569 return AMDGPU::SGPR_288RegClassID;
2571 return AMDGPU::SGPR_320RegClassID;
2573 return AMDGPU::SGPR_352RegClassID;
2575 return AMDGPU::SGPR_384RegClassID;
2577 return AMDGPU::SGPR_512RegClassID;
2579 }
else if (Is == IS_AGPR) {
2583 return AMDGPU::AGPR_32RegClassID;
2585 return AMDGPU::AReg_64RegClassID;
2587 return AMDGPU::AReg_96RegClassID;
2589 return AMDGPU::AReg_128RegClassID;
2591 return AMDGPU::AReg_160RegClassID;
2593 return AMDGPU::AReg_192RegClassID;
2595 return AMDGPU::AReg_224RegClassID;
2597 return AMDGPU::AReg_256RegClassID;
2599 return AMDGPU::AReg_288RegClassID;
2601 return AMDGPU::AReg_320RegClassID;
2603 return AMDGPU::AReg_352RegClassID;
2605 return AMDGPU::AReg_384RegClassID;
2607 return AMDGPU::AReg_512RegClassID;
2609 return AMDGPU::AReg_1024RegClassID;
2617 .
Case(
"exec", AMDGPU::EXEC)
2618 .
Case(
"vcc", AMDGPU::VCC)
2619 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2620 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2621 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2622 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2623 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2624 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2625 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2626 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2627 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2628 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2629 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2630 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2631 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2632 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2633 .
Case(
"m0", AMDGPU::M0)
2634 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2635 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2636 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2637 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2638 .
Case(
"scc", AMDGPU::SRC_SCC)
2639 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2640 .
Case(
"tba", AMDGPU::TBA)
2641 .
Case(
"tma", AMDGPU::TMA)
2642 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2643 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2644 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2645 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2646 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2647 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2648 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2649 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2650 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2651 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2652 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2653 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2654 .
Case(
"pc", AMDGPU::PC_REG)
2655 .
Case(
"null", AMDGPU::SGPR_NULL)
2659bool AMDGPUAsmParser::ParseRegister(
MCRegister &RegNo,
SMLoc &StartLoc,
2660 SMLoc &EndLoc,
bool RestoreOnFailure) {
2661 auto R = parseRegister();
2662 if (!R)
return true;
2664 RegNo =
R->getReg();
2665 StartLoc =
R->getStartLoc();
2666 EndLoc =
R->getEndLoc();
2672 return ParseRegister(Reg, StartLoc, EndLoc,
false);
2677 bool Result = ParseRegister(Reg, StartLoc, EndLoc,
true);
2678 bool PendingErrors = getParser().hasPendingError();
2679 getParser().clearPendingErrors();
2687bool AMDGPUAsmParser::AddNextRegisterToList(
unsigned &Reg,
unsigned &RegWidth,
2688 RegisterKind RegKind,
unsigned Reg1,
2692 if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2697 if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2698 Reg = AMDGPU::FLAT_SCR;
2702 if (Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2703 Reg = AMDGPU::XNACK_MASK;
2707 if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2712 if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2717 if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2722 Error(Loc,
"register does not fit in the list");
2728 if (Reg1 != Reg + RegWidth / 32) {
2729 Error(Loc,
"registers in a list must have consecutive indices");
2747 {{
"ttmp"}, IS_TTMP},
2753 return Kind == IS_VGPR ||
2761 if (Str.starts_with(Reg.Name))
2767 return !Str.getAsInteger(10, Num);
2771AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2788 if (!RegSuffix.
empty()) {
2806AMDGPUAsmParser::isRegister()
2808 return isRegister(getToken(), peekToken());
2811unsigned AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2812 unsigned SubReg,
unsigned RegWidth,
2816 unsigned AlignSize = 1;
2817 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2823 if (RegNum % AlignSize != 0) {
2824 Error(Loc,
"invalid register alignment");
2825 return AMDGPU::NoRegister;
2828 unsigned RegIdx = RegNum / AlignSize;
2831 Error(Loc,
"invalid or unsupported register size");
2832 return AMDGPU::NoRegister;
2838 Error(Loc,
"register index is out of range");
2839 return AMDGPU::NoRegister;
2849 assert(Reg &&
"Invalid subregister!");
2855bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth) {
2856 int64_t RegLo, RegHi;
2860 SMLoc FirstIdxLoc = getLoc();
2863 if (!parseExpr(RegLo))
2867 SecondIdxLoc = getLoc();
2868 if (!parseExpr(RegHi))
2877 if (!isUInt<32>(RegLo)) {
2878 Error(FirstIdxLoc,
"invalid register index");
2882 if (!isUInt<32>(RegHi)) {
2883 Error(SecondIdxLoc,
"invalid register index");
2887 if (RegLo > RegHi) {
2888 Error(FirstIdxLoc,
"first register index should not exceed second index");
2892 Num =
static_cast<unsigned>(RegLo);
2893 RegWidth = 32 * ((RegHi - RegLo) + 1);
2897unsigned AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2898 unsigned &RegNum,
unsigned &RegWidth,
2905 RegKind = IS_SPECIAL;
2912unsigned AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2913 unsigned &RegNum,
unsigned &RegWidth,
2917 auto Loc = getLoc();
2921 Error(Loc,
"invalid register name");
2922 return AMDGPU::NoRegister;
2930 unsigned SubReg = NoSubRegister;
2931 if (!RegSuffix.
empty()) {
2943 Error(Loc,
"invalid register index");
2944 return AMDGPU::NoRegister;
2949 if (!ParseRegRange(RegNum, RegWidth))
2950 return AMDGPU::NoRegister;
2953 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
2956unsigned AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
2959 unsigned Reg = AMDGPU::NoRegister;
2960 auto ListLoc = getLoc();
2963 "expected a register or a list of registers")) {
2964 return AMDGPU::NoRegister;
2969 auto Loc = getLoc();
2970 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth))
2971 return AMDGPU::NoRegister;
2972 if (RegWidth != 32) {
2973 Error(Loc,
"expected a single 32-bit register");
2974 return AMDGPU::NoRegister;
2978 RegisterKind NextRegKind;
2979 unsigned NextReg, NextRegNum, NextRegWidth;
2982 if (!ParseAMDGPURegister(NextRegKind, NextReg,
2983 NextRegNum, NextRegWidth,
2985 return AMDGPU::NoRegister;
2987 if (NextRegWidth != 32) {
2988 Error(Loc,
"expected a single 32-bit register");
2989 return AMDGPU::NoRegister;
2991 if (NextRegKind != RegKind) {
2992 Error(Loc,
"registers in a list must be of the same kind");
2993 return AMDGPU::NoRegister;
2995 if (!AddNextRegisterToList(Reg, RegWidth, RegKind, NextReg, Loc))
2996 return AMDGPU::NoRegister;
3000 "expected a comma or a closing square bracket")) {
3001 return AMDGPU::NoRegister;
3005 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3010bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
3011 unsigned &RegNum,
unsigned &RegWidth,
3013 auto Loc = getLoc();
3014 Reg = AMDGPU::NoRegister;
3017 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3018 if (Reg == AMDGPU::NoRegister)
3019 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3021 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3025 if (Reg == AMDGPU::NoRegister) {
3026 assert(Parser.hasPendingError());
3030 if (!subtargetHasRegister(*
TRI, Reg)) {
3031 if (Reg == AMDGPU::SGPR_NULL) {
3032 Error(Loc,
"'null' operand is not supported on this GPU");
3034 Error(Loc,
"register not available on this GPU");
3042bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &Reg,
3043 unsigned &RegNum,
unsigned &RegWidth,
3044 bool RestoreOnFailure ) {
3045 Reg = AMDGPU::NoRegister;
3048 if (ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, Tokens)) {
3049 if (RestoreOnFailure) {
3050 while (!Tokens.
empty()) {
3059std::optional<StringRef>
3060AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3063 return StringRef(
".amdgcn.next_free_vgpr");
3065 return StringRef(
".amdgcn.next_free_sgpr");
3067 return std::nullopt;
3071void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3072 auto SymbolName = getGprCountSymbolName(RegKind);
3073 assert(SymbolName &&
"initializing invalid register kind");
3074 MCSymbol *
Sym = getContext().getOrCreateSymbol(*SymbolName);
3078bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3079 unsigned DwordRegIndex,
3080 unsigned RegWidth) {
3085 auto SymbolName = getGprCountSymbolName(RegKind);
3088 MCSymbol *
Sym = getContext().getOrCreateSymbol(*SymbolName);
3090 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3093 if (!
Sym->isVariable())
3094 return !
Error(getLoc(),
3095 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3096 if (!
Sym->getVariableValue(
false)->evaluateAsAbsolute(OldCount))
3099 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3101 if (OldCount <= NewMax)
3107std::unique_ptr<AMDGPUOperand>
3108AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3109 const auto &Tok = getToken();
3110 SMLoc StartLoc = Tok.getLoc();
3111 SMLoc EndLoc = Tok.getEndLoc();
3112 RegisterKind RegKind;
3113 unsigned Reg, RegNum, RegWidth;
3115 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth)) {
3119 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3122 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3123 return AMDGPUOperand::CreateReg(
this, Reg, StartLoc, EndLoc);
3127 bool HasSP3AbsModifier,
bool HasLit) {
3135 HasLit = trySkipId(
"lit");
3147 const auto& Tok = getToken();
3148 const auto& NextTok = peekToken();
3151 bool Negate =
false;
3159 AMDGPUOperand::Modifiers Mods;
3170 APFloat RealVal(APFloat::IEEEdouble());
3171 auto roundMode = APFloat::rmNearestTiesToEven;
3172 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3175 RealVal.changeSign();
3178 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3179 AMDGPUOperand::ImmTyNone,
true));
3180 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3181 Op.setModifiers(Mods);
3190 if (HasSP3AbsModifier) {
3199 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3202 if (Parser.parseExpression(Expr))
3206 if (Expr->evaluateAsAbsolute(IntVal)) {
3207 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3208 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3209 Op.setModifiers(Mods);
3213 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3226 if (
auto R = parseRegister()) {
3235 bool HasSP3AbsMod,
bool HasLit) {
3241 return parseImm(
Operands, HasSP3AbsMod, HasLit);
3245AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3248 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3254AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3259AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3260 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3264AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3265 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3282AMDGPUAsmParser::isModifier() {
3286 peekTokens(NextToken);
3288 return isOperandModifier(Tok, NextToken[0]) ||
3289 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3290 isOpcodeModifierWithVal(Tok, NextToken[0]);
3316AMDGPUAsmParser::parseSP3NegModifier() {
3319 peekTokens(NextToken);
3322 (isRegister(NextToken[0], NextToken[1]) ||
3324 isId(NextToken[0],
"abs"))) {
3342 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3344 SP3Neg = parseSP3NegModifier();
3347 Neg = trySkipId(
"neg");
3349 return Error(Loc,
"expected register or immediate");
3353 Abs = trySkipId(
"abs");
3357 Lit = trySkipId(
"lit");
3364 return Error(Loc,
"expected register or immediate");
3368 Res = parseRegOrImm(
Operands, SP3Abs, Lit);
3375 if (Lit && !
Operands.back()->isImm())
3376 Error(Loc,
"expected immediate with lit modifier");
3378 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3387 AMDGPUOperand::Modifiers Mods;
3388 Mods.Abs = Abs || SP3Abs;
3389 Mods.Neg = Neg || SP3Neg;
3392 if (Mods.hasFPModifiers() || Lit) {
3393 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3395 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3396 Op.setModifiers(Mods);
3404 bool Sext = trySkipId(
"sext");
3405 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3420 AMDGPUOperand::Modifiers Mods;
3423 if (Mods.hasIntModifiers()) {
3424 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3426 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3427 Op.setModifiers(Mods);
3434 return parseRegOrImmWithFPInputMods(
Operands,
false);
3438 return parseRegOrImmWithIntInputMods(
Operands,
false);
3442 auto Loc = getLoc();
3443 if (trySkipId(
"off")) {
3444 Operands.push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3445 AMDGPUOperand::ImmTyOff,
false));
3452 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3454 Operands.push_back(std::move(Reg));
3461unsigned AMDGPUAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
3468 return Match_InvalidOperand;
3470 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3471 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3476 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3477 return Match_InvalidOperand;
3481 return Match_Success;
3485 static const unsigned Variants[] = {
3496 if (isForcedDPP() && isForcedVOP3()) {
3500 if (getForcedEncodingSize() == 32) {
3505 if (isForcedVOP3()) {
3510 if (isForcedSDWA()) {
3516 if (isForcedDPP()) {
3524StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3525 if (isForcedDPP() && isForcedVOP3())
3528 if (getForcedEncodingSize() == 32)
3543unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3547 case AMDGPU::FLAT_SCR:
3549 case AMDGPU::VCC_LO:
3550 case AMDGPU::VCC_HI:
3557 return AMDGPU::NoRegister;
3564bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3565 unsigned OpIdx)
const {
3575 int64_t Val = MO.
getImm();
3624unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3630 case AMDGPU::V_LSHLREV_B64_e64:
3631 case AMDGPU::V_LSHLREV_B64_gfx10:
3632 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3633 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3634 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3635 case AMDGPU::V_LSHRREV_B64_e64:
3636 case AMDGPU::V_LSHRREV_B64_gfx10:
3637 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3638 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3639 case AMDGPU::V_ASHRREV_I64_e64:
3640 case AMDGPU::V_ASHRREV_I64_gfx10:
3641 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3642 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3643 case AMDGPU::V_LSHL_B64_e64:
3644 case AMDGPU::V_LSHR_B64_e64:
3645 case AMDGPU::V_ASHR_I64_e64:
3658 bool AddMandatoryLiterals =
false) {
3664 int16_t ImmDeferredIdx =
3681bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3684 return !isInlineConstant(Inst, OpIdx);
3685 }
else if (MO.
isReg()) {
3692 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3704 const unsigned Opcode = Inst.
getOpcode();
3705 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3708 if (!LaneSelOp.
isReg())
3711 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3714bool AMDGPUAsmParser::validateConstantBusLimitations(
3716 const unsigned Opcode = Inst.
getOpcode();
3718 unsigned LastSGPR = AMDGPU::NoRegister;
3719 unsigned ConstantBusUseCount = 0;
3720 unsigned NumLiterals = 0;
3721 unsigned LiteralSize;
3723 if (!(
Desc.TSFlags &
3739 unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3740 if (SGPRUsed != AMDGPU::NoRegister) {
3741 SGPRsUsed.
insert(SGPRUsed);
3742 ++ConstantBusUseCount;
3747 for (
int OpIdx : OpIndices) {
3752 if (usesConstantBus(Inst, OpIdx)) {
3761 if (SGPRsUsed.
insert(LastSGPR).second) {
3762 ++ConstantBusUseCount;
3782 if (NumLiterals == 0) {
3785 }
else if (LiteralSize !=
Size) {
3791 ConstantBusUseCount += NumLiterals;
3793 if (ConstantBusUseCount <= getConstantBusLimit(Opcode))
3799 Error(Loc,
"invalid operand (violates constant bus restrictions)");
3803bool AMDGPUAsmParser::validateVOPDRegBankConstraints(
3806 const unsigned Opcode = Inst.
getOpcode();
3812 auto getVRegIdx = [&](
unsigned,
unsigned OperandIdx) {
3820 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12;
3823 auto InvalidCompOprIdx =
3824 InstInfo.getInvalidCompOperandIndex(getVRegIdx, SkipSrc);
3825 if (!InvalidCompOprIdx)
3828 auto CompOprIdx = *InvalidCompOprIdx;
3830 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3831 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3834 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
3835 if (CompOprIdx == VOPD::Component::DST) {
3836 Error(Loc,
"one dst register must be even and the other odd");
3838 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3840 " operands must use different VGPR banks");
3846bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
3863bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
3864 const SMLoc &IDLoc) {
3882 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
3887 bool IsPackedD16 =
false;
3892 IsPackedD16 = D16Idx >= 0;
3894 DataSize = (DataSize + 1) / 2;
3897 if ((VDataSize / 4) == DataSize + TFESize)
3902 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
3904 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
3906 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
3910bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst,
3911 const SMLoc &IDLoc) {
3924 : AMDGPU::OpName::rsrc;
3931 assert(SrsrcIdx > VAddr0Idx);
3934 if (BaseOpcode->
BVH) {
3935 if (IsA16 == BaseOpcode->
A16)
3937 Error(IDLoc,
"image address size does not match a16");
3943 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
3944 unsigned ActualAddrSize =
3945 IsNSA ? SrsrcIdx - VAddr0Idx
3948 unsigned ExpectedAddrSize =
3952 if (hasPartialNSAEncoding() &&
3955 int VAddrLastIdx = SrsrcIdx - 1;
3956 unsigned VAddrLastSize =
3959 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
3962 if (ExpectedAddrSize > 12)
3963 ExpectedAddrSize = 16;
3968 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
3972 if (ActualAddrSize == ExpectedAddrSize)
3975 Error(IDLoc,
"image address size does not match dim and a16");
3979bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
3986 if (!
Desc.mayLoad() || !
Desc.mayStore())
3996 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
3999bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4015 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4018bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4029 if (!BaseOpcode->
MSAA)
4038 return DimInfo->
MSAA;
4044 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4045 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4046 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4056bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4080 Error(ErrLoc,
"source operand must be a VGPR");
4084bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4089 if (Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4103 "source operand must be either a VGPR or an inline constant");
4110bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4116 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4123 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4125 "inline constants are not allowed for this operand");
4132bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4150 if (Src2Reg == DstReg)
4154 if (
TRI->getRegClass(
Desc.operands()[0].RegClass).getSizeInBits() <= 128)
4157 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4159 "source 2 operand must not partially overlap with dst");
4166bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4170 case V_DIV_SCALE_F32_gfx6_gfx7:
4171 case V_DIV_SCALE_F32_vi:
4172 case V_DIV_SCALE_F32_gfx10:
4173 case V_DIV_SCALE_F64_gfx6_gfx7:
4174 case V_DIV_SCALE_F64_vi:
4175 case V_DIV_SCALE_F64_gfx10:
4181 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4182 AMDGPU::OpName::src2_modifiers,
4183 AMDGPU::OpName::src2_modifiers}) {
4194bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4214 case AMDGPU::V_SUBREV_F32_e32:
4215 case AMDGPU::V_SUBREV_F32_e64:
4216 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4217 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4218 case AMDGPU::V_SUBREV_F32_e32_vi:
4219 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4220 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4221 case AMDGPU::V_SUBREV_F32_e64_vi:
4223 case AMDGPU::V_SUBREV_CO_U32_e32:
4224 case AMDGPU::V_SUBREV_CO_U32_e64:
4225 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4226 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4228 case AMDGPU::V_SUBBREV_U32_e32:
4229 case AMDGPU::V_SUBBREV_U32_e64:
4230 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4231 case AMDGPU::V_SUBBREV_U32_e32_vi:
4232 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4233 case AMDGPU::V_SUBBREV_U32_e64_vi:
4235 case AMDGPU::V_SUBREV_U32_e32:
4236 case AMDGPU::V_SUBREV_U32_e64:
4237 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4238 case AMDGPU::V_SUBREV_U32_e32_vi:
4239 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4240 case AMDGPU::V_SUBREV_U32_e64_vi:
4242 case AMDGPU::V_SUBREV_F16_e32:
4243 case AMDGPU::V_SUBREV_F16_e64:
4244 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4245 case AMDGPU::V_SUBREV_F16_e32_vi:
4246 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4247 case AMDGPU::V_SUBREV_F16_e64_vi:
4249 case AMDGPU::V_SUBREV_U16_e32:
4250 case AMDGPU::V_SUBREV_U16_e64:
4251 case AMDGPU::V_SUBREV_U16_e32_vi:
4252 case AMDGPU::V_SUBREV_U16_e64_vi:
4254 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4255 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4256 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4258 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4259 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4261 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4262 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4264 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4265 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4267 case AMDGPU::V_LSHRREV_B32_e32:
4268 case AMDGPU::V_LSHRREV_B32_e64:
4269 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4270 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4271 case AMDGPU::V_LSHRREV_B32_e32_vi:
4272 case AMDGPU::V_LSHRREV_B32_e64_vi:
4273 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4274 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4276 case AMDGPU::V_ASHRREV_I32_e32:
4277 case AMDGPU::V_ASHRREV_I32_e64:
4278 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4279 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4280 case AMDGPU::V_ASHRREV_I32_e32_vi:
4281 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4282 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4283 case AMDGPU::V_ASHRREV_I32_e64_vi:
4285 case AMDGPU::V_LSHLREV_B32_e32:
4286 case AMDGPU::V_LSHLREV_B32_e64:
4287 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4288 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4289 case AMDGPU::V_LSHLREV_B32_e32_vi:
4290 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4291 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4292 case AMDGPU::V_LSHLREV_B32_e64_vi:
4294 case AMDGPU::V_LSHLREV_B16_e32:
4295 case AMDGPU::V_LSHLREV_B16_e64:
4296 case AMDGPU::V_LSHLREV_B16_e32_vi:
4297 case AMDGPU::V_LSHLREV_B16_e64_vi:
4298 case AMDGPU::V_LSHLREV_B16_gfx10:
4300 case AMDGPU::V_LSHRREV_B16_e32:
4301 case AMDGPU::V_LSHRREV_B16_e64:
4302 case AMDGPU::V_LSHRREV_B16_e32_vi:
4303 case AMDGPU::V_LSHRREV_B16_e64_vi:
4304 case AMDGPU::V_LSHRREV_B16_gfx10:
4306 case AMDGPU::V_ASHRREV_I16_e32:
4307 case AMDGPU::V_ASHRREV_I16_e64:
4308 case AMDGPU::V_ASHRREV_I16_e32_vi:
4309 case AMDGPU::V_ASHRREV_I16_e64_vi:
4310 case AMDGPU::V_ASHRREV_I16_gfx10:
4312 case AMDGPU::V_LSHLREV_B64_e64:
4313 case AMDGPU::V_LSHLREV_B64_gfx10:
4314 case AMDGPU::V_LSHLREV_B64_vi:
4316 case AMDGPU::V_LSHRREV_B64_e64:
4317 case AMDGPU::V_LSHRREV_B64_gfx10:
4318 case AMDGPU::V_LSHRREV_B64_vi:
4320 case AMDGPU::V_ASHRREV_I64_e64:
4321 case AMDGPU::V_ASHRREV_I64_gfx10:
4322 case AMDGPU::V_ASHRREV_I64_vi:
4324 case AMDGPU::V_PK_LSHLREV_B16:
4325 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4326 case AMDGPU::V_PK_LSHLREV_B16_vi:
4328 case AMDGPU::V_PK_LSHRREV_B16:
4329 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4330 case AMDGPU::V_PK_LSHRREV_B16_vi:
4331 case AMDGPU::V_PK_ASHRREV_I16:
4332 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4333 case AMDGPU::V_PK_ASHRREV_I16_vi:
4340std::optional<StringRef>
4341AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst) {
4343 using namespace SIInstrFlags;
4344 const unsigned Opcode = Inst.
getOpcode();
4350 if ((
Desc.TSFlags & Enc) == 0)
4351 return std::nullopt;
4353 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4358 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4361 return StringRef(
"lds_direct is not supported on this GPU");
4364 return StringRef(
"lds_direct cannot be used with this instruction");
4366 if (SrcName != OpName::src0)
4367 return StringRef(
"lds_direct may be used as src0 only");
4371 return std::nullopt;
4375 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4376 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4377 if (
Op.isFlatOffset())
4378 return Op.getStartLoc();
4383bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4392 return validateFlatOffset(Inst,
Operands);
4395 return validateSMEMOffset(Inst,
Operands);
4400 const unsigned OffsetSize = 24;
4401 if (!
isIntN(OffsetSize,
Op.getImm())) {
4403 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit signed offset");
4407 const unsigned OffsetSize = 16;
4408 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4410 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit unsigned offset");
4417bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4428 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4430 "flat offset modifier is not supported on this GPU");
4437 bool AllowNegative =
4440 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4442 Twine(
"expected a ") +
4443 (AllowNegative ?
Twine(OffsetSize) +
"-bit signed offset"
4444 :
Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4453 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4454 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4455 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4456 return Op.getStartLoc();
4461bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4487 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4488 :
"expected a 21-bit signed offset");
4493bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst)
const {
4502 const int OpIndices[] = { Src0Idx, Src1Idx };
4504 unsigned NumExprs = 0;
4505 unsigned NumLiterals = 0;
4508 for (
int OpIdx : OpIndices) {
4509 if (OpIdx == -1)
break;
4514 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4516 if (NumLiterals == 0 || LiteralValue !=
Value) {
4520 }
else if (MO.
isExpr()) {
4526 return NumLiterals + NumExprs <= 1;
4529bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4543 if (OpSelIdx != -1) {
4548 if (OpSelHiIdx != -1) {
4566bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst,
int OpName) {
4591 int SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4592 AMDGPU::OpName::src1_modifiers,
4593 AMDGPU::OpName::src2_modifiers};
4595 for (
unsigned i = 0; i < 3; ++i) {
4605bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4609 if (DppCtrlIdx >= 0) {
4616 Error(S,
"DP ALU dpp only supports row_newbcast");
4622 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4631 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[Src1Idx]);
4632 Error(
Op.getStartLoc(),
"invalid operand 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) ||
5272 (R == Match_PreferE32) ||
5273 (R == Match_MissingFeature && Result != Match_PreferE32) ||
5274 (R == Match_InvalidOperand && Result != Match_MissingFeature
5275 && Result != Match_PreferE32) ||
5276 (R == Match_MnemonicFail && Result != Match_InvalidOperand
5277 && Result != Match_MissingFeature
5278 && Result != Match_PreferE32)) {
5282 if (R == Match_Success)
5286 if (Result == Match_Success) {
5287 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5296 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5302 case Match_MissingFeature:
5306 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5308 case Match_InvalidOperand: {
5309 SMLoc ErrorLoc = IDLoc;
5312 return Error(IDLoc,
"too few operands for instruction");
5315 if (ErrorLoc ==
SMLoc())
5319 return Error(ErrorLoc,
"invalid VOPDY instruction");
5321 return Error(ErrorLoc,
"invalid operand for instruction");
5324 case Match_PreferE32:
5325 return Error(IDLoc,
"internal error: instruction without _e64 suffix "
5326 "should be encoded as e32");
5327 case Match_MnemonicFail:
5333bool AMDGPUAsmParser::ParseAsAbsoluteExpression(
uint32_t &Ret) {
5338 if (getParser().parseAbsoluteExpression(Tmp)) {
5345bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5347 return TokError(
"directive only supported for amdgcn architecture");
5349 std::string TargetIDDirective;
5350 SMLoc TargetStart = getTok().getLoc();
5351 if (getParser().parseEscapedString(TargetIDDirective))
5355 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5356 return getParser().Error(TargetRange.
Start,
5357 (
Twine(
".amdgcn_target directive's target id ") +
5358 Twine(TargetIDDirective) +
5359 Twine(
" does not match the specified target id ") +
5360 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5365bool AMDGPUAsmParser::OutOfRangeError(
SMRange Range) {
5366 return Error(
Range.Start,
"value out of range", Range);
5369bool AMDGPUAsmParser::calculateGPRBlocks(
5370 const FeatureBitset &Features,
bool VCCUsed,
bool FlatScrUsed,
5371 bool XNACKUsed, std::optional<bool> EnableWavefrontSize32,
5372 unsigned NextFreeVGPR,
SMRange VGPRRange,
unsigned NextFreeSGPR,
5373 SMRange SGPRRange,
unsigned &VGPRBlocks,
unsigned &SGPRBlocks) {
5384 unsigned MaxAddressableNumSGPRs =
5387 if (
Version.Major >= 8 && !Features.
test(FeatureSGPRInitBug) &&
5388 NumSGPRs > MaxAddressableNumSGPRs)
5389 return OutOfRangeError(SGPRRange);
5394 if ((
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5395 NumSGPRs > MaxAddressableNumSGPRs)
5396 return OutOfRangeError(SGPRRange);
5398 if (Features.
test(FeatureSGPRInitBug))
5403 EnableWavefrontSize32);
5409bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5411 return TokError(
"directive only supported for amdgcn architecture");
5414 return TokError(
"directive only supported for amdhsa OS");
5417 if (getParser().parseIdentifier(KernelName))
5436 unsigned ImpliedUserSGPRCount = 0;
5440 std::optional<unsigned> ExplicitUserSGPRCount;
5441 bool ReserveVCC =
true;
5442 bool ReserveFlatScr =
true;
5443 std::optional<bool> EnableWavefrontSize32;
5449 SMRange IDRange = getTok().getLocRange();
5450 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5453 if (
ID ==
".end_amdhsa_kernel")
5457 return TokError(
".amdhsa_ directives cannot be repeated");
5459 SMLoc ValStart = getLoc();
5461 if (getParser().parseAbsoluteExpression(IVal))
5463 SMLoc ValEnd = getLoc();
5467 return OutOfRangeError(ValRange);
5471#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5472 if (!isUInt<ENTRY##_WIDTH>(VALUE)) \
5473 return OutOfRangeError(RANGE); \
5474 AMDHSA_BITS_SET(FIELD, ENTRY, VALUE);
5476 if (
ID ==
".amdhsa_group_segment_fixed_size") {
5478 return OutOfRangeError(ValRange);
5480 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
5482 return OutOfRangeError(ValRange);
5484 }
else if (
ID ==
".amdhsa_kernarg_size") {
5486 return OutOfRangeError(ValRange);
5488 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
5489 ExplicitUserSGPRCount = Val;
5490 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
5493 "directive is not supported with architected flat scratch",
5496 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
5499 ImpliedUserSGPRCount += 4;
5500 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
5502 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5505 return OutOfRangeError(ValRange);
5509 ImpliedUserSGPRCount += Val;
5510 PreloadLength = Val;
5512 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
5514 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5517 return OutOfRangeError(ValRange);
5521 PreloadOffset = Val;
5522 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
5524 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, Val,
5527 ImpliedUserSGPRCount += 2;
5528 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
5530 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, Val,
5533 ImpliedUserSGPRCount += 2;
5534 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
5536 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
5539 ImpliedUserSGPRCount += 2;
5540 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
5542 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, Val,
5545 ImpliedUserSGPRCount += 2;
5546 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
5549 "directive is not supported with architected flat scratch",
5552 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT, Val,
5555 ImpliedUserSGPRCount += 2;
5556 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
5558 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
5561 ImpliedUserSGPRCount += 1;
5562 }
else if (
ID ==
".amdhsa_wavefront_size32") {
5563 if (IVersion.
Major < 10)
5564 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5565 EnableWavefrontSize32 = Val;
5567 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32,
5569 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
5571 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, Val, ValRange);
5572 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
5575 "directive is not supported with architected flat scratch",
5578 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, Val, ValRange);
5579 }
else if (
ID ==
".amdhsa_enable_private_segment") {
5583 "directive is not supported without architected flat scratch",
5586 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, Val, ValRange);
5587 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
5589 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, Val,
5591 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
5593 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, Val,
5595 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
5597 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, Val,
5599 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
5601 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, Val,
5603 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
5605 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, Val,
5607 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
5608 VGPRRange = ValRange;
5610 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
5611 SGPRRange = ValRange;
5613 }
else if (
ID ==
".amdhsa_accum_offset") {
5615 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5617 }
else if (
ID ==
".amdhsa_reserve_vcc") {
5618 if (!isUInt<1>(Val))
5619 return OutOfRangeError(ValRange);
5621 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
5622 if (IVersion.
Major < 7)
5623 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
5626 "directive is not supported with architected flat scratch",
5628 if (!isUInt<1>(Val))
5629 return OutOfRangeError(ValRange);
5630 ReserveFlatScr = Val;
5631 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
5632 if (IVersion.
Major < 8)
5633 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
5634 if (!isUInt<1>(Val))
5635 return OutOfRangeError(ValRange);
5636 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
5637 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
5639 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
5641 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, Val, ValRange);
5642 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
5644 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, Val, ValRange);
5645 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
5647 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, Val, ValRange);
5648 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
5650 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, Val,
5652 }
else if (
ID ==
".amdhsa_dx10_clamp") {
5653 if (IVersion.
Major >= 12)
5654 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
5656 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, Val,
5658 }
else if (
ID ==
".amdhsa_ieee_mode") {
5659 if (IVersion.
Major >= 12)
5660 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
5662 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, Val,
5664 }
else if (
ID ==
".amdhsa_fp16_overflow") {
5665 if (IVersion.
Major < 9)
5666 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
5669 }
else if (
ID ==
".amdhsa_tg_split") {
5671 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5674 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
5675 if (IVersion.
Major < 10)
5676 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5679 }
else if (
ID ==
".amdhsa_memory_ordered") {
5680 if (IVersion.
Major < 10)
5681 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5684 }
else if (
ID ==
".amdhsa_forward_progress") {
5685 if (IVersion.
Major < 10)
5686 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5689 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
5690 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
5691 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
5693 SharedVGPRCount = Val;
5695 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, Val,
5697 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
5700 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION, Val,
5702 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
5704 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
5706 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
5709 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO, Val,
5711 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
5713 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
5715 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
5717 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
5719 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
5721 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
5723 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
5725 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
5727 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
5728 if (IVersion.
Major < 12)
5729 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
5731 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, Val,
5734 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
5737#undef PARSE_BITS_ENTRY
5740 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
5741 return TokError(
".amdhsa_next_free_vgpr directive is required");
5743 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
5744 return TokError(
".amdhsa_next_free_sgpr directive is required");
5746 unsigned VGPRBlocks;
5747 unsigned SGPRBlocks;
5748 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
5749 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
5750 EnableWavefrontSize32, NextFreeVGPR,
5751 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
5755 if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_WIDTH>(
5757 return OutOfRangeError(VGPRRange);
5759 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT, VGPRBlocks);
5761 if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_WIDTH>(
5763 return OutOfRangeError(SGPRRange);
5765 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
5768 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
5769 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
5770 "enabled user SGPRs");
5772 unsigned UserSGPRCount =
5773 ExplicitUserSGPRCount ? *ExplicitUserSGPRCount : ImpliedUserSGPRCount;
5775 if (!isUInt<COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_WIDTH>(UserSGPRCount))
5776 return TokError(
"too many user SGPRs enabled");
5781 (PreloadLength * 4 + PreloadOffset * 4 > KD.
kernarg_size))
5782 return TokError(
"Kernarg preload length + offset is larger than the "
5783 "kernarg segment size");
5786 if (!Seen.
contains(
".amdhsa_accum_offset"))
5787 return TokError(
".amdhsa_accum_offset directive is required");
5788 if (AccumOffset < 4 || AccumOffset > 256 || (AccumOffset & 3))
5789 return TokError(
"accum_offset should be in range [4..256] in "
5792 return TokError(
"accum_offset exceeds total VGPR allocation");
5794 (AccumOffset / 4 - 1));
5797 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
5799 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
5800 return TokError(
"shared_vgpr_count directive not valid on "
5801 "wavefront size 32");
5803 if (SharedVGPRCount * 2 + VGPRBlocks > 63) {
5804 return TokError(
"shared_vgpr_count*2 + "
5805 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
5810 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
5811 NextFreeVGPR, NextFreeSGPR,
5812 ReserveVCC, ReserveFlatScr);
5816bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
5818 if (ParseAsAbsoluteExpression(Version))
5821 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(Version);
5825bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(
StringRef ID,
5829 if (
ID ==
"max_scratch_backing_memory_byte_size") {
5830 Parser.eatToEndOfStatement();
5837 return TokError(Err.str());
5841 if (
ID ==
"enable_dx10_clamp") {
5844 return TokError(
"enable_dx10_clamp=1 is not allowed on GFX12+");
5847 if (
ID ==
"enable_ieee_mode") {
5850 return TokError(
"enable_ieee_mode=1 is not allowed on GFX12+");
5853 if (
ID ==
"enable_wavefront_size32") {
5856 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
5857 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5858 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
5860 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5861 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
5865 if (
ID ==
"wavefront_size") {
5866 if (Header.wavefront_size == 5) {
5868 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
5869 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5870 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
5871 }
else if (Header.wavefront_size == 6) {
5872 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5873 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
5877 if (
ID ==
"enable_wgp_mode") {
5880 return TokError(
"enable_wgp_mode=1 is only allowed on GFX10+");
5883 if (
ID ==
"enable_mem_ordered") {
5886 return TokError(
"enable_mem_ordered=1 is only allowed on GFX10+");
5889 if (
ID ==
"enable_fwd_progress") {
5892 return TokError(
"enable_fwd_progress=1 is only allowed on GFX10+");
5898bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
5908 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
5911 if (
ID ==
".end_amd_kernel_code_t")
5914 if (ParseAMDKernelCodeTValue(
ID, Header))
5918 getTargetStreamer().EmitAMDKernelCodeT(Header);
5923bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
5925 if (!parseId(KernelName,
"expected symbol name"))
5928 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
5931 KernelScope.initialize(getContext());
5935bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
5937 return Error(getLoc(),
5938 ".amd_amdgpu_isa directive is not available on non-amdgcn "
5942 auto TargetIDDirective = getLexer().getTok().getStringContents();
5943 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5944 return Error(getParser().getTok().getLoc(),
"target id must match options");
5946 getTargetStreamer().EmitISAVersion();
5952bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
5955 std::string HSAMetadataString;
5960 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
5961 return Error(getLoc(),
"invalid HSA metadata");
5968bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
5969 const char *AssemblerDirectiveEnd,
5970 std::string &CollectString) {
5974 getLexer().setSkipSpace(
false);
5976 bool FoundEnd =
false;
5979 CollectStream << getTokenStr();
5983 if (trySkipId(AssemblerDirectiveEnd)) {
5988 CollectStream << Parser.parseStringToEndOfStatement()
5989 << getContext().getAsmInfo()->getSeparatorString();
5991 Parser.eatToEndOfStatement();
5994 getLexer().setSkipSpace(
true);
5997 return TokError(
Twine(
"expected directive ") +
5998 Twine(AssemblerDirectiveEnd) +
Twine(
" not found"));
6001 CollectStream.flush();
6006bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6012 auto PALMetadata = getTargetStreamer().getPALMetadata();
6013 if (!PALMetadata->setFromString(
String))
6014 return Error(getLoc(),
"invalid PAL metadata");
6019bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6021 return Error(getLoc(),
6023 "not available on non-amdpal OSes")).str());
6026 auto PALMetadata = getTargetStreamer().getPALMetadata();
6027 PALMetadata->setLegacy();
6030 if (ParseAsAbsoluteExpression(Key)) {
6031 return TokError(
Twine(
"invalid value in ") +
6035 return TokError(
Twine(
"expected an even number of values in ") +
6038 if (ParseAsAbsoluteExpression(
Value)) {
6039 return TokError(
Twine(
"invalid value in ") +
6042 PALMetadata->setRegister(Key,
Value);
6051bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6052 if (getParser().checkForValidSection())
6056 SMLoc NameLoc = getLoc();
6057 if (getParser().parseIdentifier(
Name))
6058 return TokError(
"expected identifier in directive");
6061 if (getParser().parseComma())
6067 SMLoc SizeLoc = getLoc();
6068 if (getParser().parseAbsoluteExpression(
Size))
6071 return Error(SizeLoc,
"size must be non-negative");
6072 if (
Size > LocalMemorySize)
6073 return Error(SizeLoc,
"size is too large");
6075 int64_t Alignment = 4;
6077 SMLoc AlignLoc = getLoc();
6078 if (getParser().parseAbsoluteExpression(Alignment))
6081 return Error(AlignLoc,
"alignment must be a power of two");
6086 if (Alignment >= 1u << 31)
6087 return Error(AlignLoc,
"alignment is too large");
6093 Symbol->redefineIfPossible();
6094 if (!
Symbol->isUndefined())
6095 return Error(NameLoc,
"invalid symbol redefinition");
6097 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6101bool AMDGPUAsmParser::ParseDirective(
AsmToken DirectiveID) {
6105 if (IDVal ==
".amdhsa_kernel")
6106 return ParseDirectiveAMDHSAKernel();
6108 if (IDVal ==
".amdhsa_code_object_version")
6109 return ParseDirectiveAMDHSACodeObjectVersion();
6113 return ParseDirectiveHSAMetadata();
6115 if (IDVal ==
".amd_kernel_code_t")
6116 return ParseDirectiveAMDKernelCodeT();
6118 if (IDVal ==
".amdgpu_hsa_kernel")
6119 return ParseDirectiveAMDGPUHsaKernel();
6121 if (IDVal ==
".amd_amdgpu_isa")
6122 return ParseDirectiveISAVersion();
6126 Twine(
" directive is "
6127 "not available on non-amdhsa OSes"))
6132 if (IDVal ==
".amdgcn_target")
6133 return ParseDirectiveAMDGCNTarget();
6135 if (IDVal ==
".amdgpu_lds")
6136 return ParseDirectiveAMDGPULDS();
6139 return ParseDirectivePALMetadataBegin();
6142 return ParseDirectivePALMetadata();
6150 if (
MRI.regsOverlap(AMDGPU::TTMP12_TTMP13_TTMP14_TTMP15, RegNo))
6154 if (
MRI.regsOverlap(AMDGPU::SGPR104_SGPR105, RegNo))
6155 return hasSGPR104_SGPR105();
6158 case AMDGPU::SRC_SHARED_BASE_LO:
6159 case AMDGPU::SRC_SHARED_BASE:
6160 case AMDGPU::SRC_SHARED_LIMIT_LO:
6161 case AMDGPU::SRC_SHARED_LIMIT:
6162 case AMDGPU::SRC_PRIVATE_BASE_LO:
6163 case AMDGPU::SRC_PRIVATE_BASE:
6164 case AMDGPU::SRC_PRIVATE_LIMIT_LO:
6165 case AMDGPU::SRC_PRIVATE_LIMIT:
6167 case AMDGPU::SRC_POPS_EXITING_WAVE_ID:
6170 case AMDGPU::TBA_LO:
6171 case AMDGPU::TBA_HI:
6173 case AMDGPU::TMA_LO:
6174 case AMDGPU::TMA_HI:
6176 case AMDGPU::XNACK_MASK:
6177 case AMDGPU::XNACK_MASK_LO:
6178 case AMDGPU::XNACK_MASK_HI:
6179 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6180 case AMDGPU::SGPR_NULL:
6194 case AMDGPU::FLAT_SCR:
6195 case AMDGPU::FLAT_SCR_LO:
6196 case AMDGPU::FLAT_SCR_HI:
6205 if (
MRI.regsOverlap(AMDGPU::SGPR102_SGPR103, RegNo))
6206 return hasSGPR102_SGPR103();
6219 Res = MatchOperandParserImpl(
Operands, Mnemonic);
6231 SMLoc LBraceLoc = getLoc();
6236 auto Loc = getLoc();
6239 Error(Loc,
"expected a register");
6243 RBraceLoc = getLoc();
6248 "expected a comma or a closing square bracket"))
6252 if (
Operands.size() - Prefix > 1) {
6254 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6255 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6266 setForcedEncodingSize(0);
6267 setForcedDPP(
false);
6268 setForcedSDWA(
false);
6270 if (
Name.ends_with(
"_e64_dpp")) {
6272 setForcedEncodingSize(64);
6273 return Name.substr(0,
Name.size() - 8);
6274 }
else if (
Name.ends_with(
"_e64")) {
6275 setForcedEncodingSize(64);
6276 return Name.substr(0,
Name.size() - 4);
6277 }
else if (
Name.ends_with(
"_e32")) {
6278 setForcedEncodingSize(32);
6279 return Name.substr(0,
Name.size() - 4);
6280 }
else if (
Name.ends_with(
"_dpp")) {
6282 return Name.substr(0,
Name.size() - 4);
6283 }
else if (
Name.ends_with(
"_sdwa")) {
6284 setForcedSDWA(
true);
6285 return Name.substr(0,
Name.size() - 5);
6292 unsigned VariantID);
6304 Operands.push_back(AMDGPUOperand::CreateToken(
this,
Name, NameLoc));
6306 bool IsMIMG =
Name.starts_with(
"image_");
6309 OperandMode Mode = OperandMode_Default;
6311 Mode = OperandMode_NSA;
6315 checkUnsupportedInstruction(
Name, NameLoc);
6316 if (!Parser.hasPendingError()) {
6319 :
"not a valid operand.";
6320 Error(getLoc(), Msg);
6342 if (!trySkipId(
Name))
6345 Operands.push_back(AMDGPUOperand::CreateToken(
this,
Name, S));
6349ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6360 std::function<
bool(int64_t &)> ConvertResult) {
6368 if (ConvertResult && !ConvertResult(
Value)) {
6372 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6376ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6378 bool (*ConvertResult)(int64_t &)) {
6387 const unsigned MaxSize = 4;
6391 for (
int I = 0; ; ++
I) {
6393 SMLoc Loc = getLoc();
6397 if (
Op != 0 &&
Op != 1)
6405 if (
I + 1 == MaxSize)
6406 return Error(getLoc(),
"expected a closing square bracket");
6412 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
6418 AMDGPUOperand::ImmTy ImmTy) {
6422 if (trySkipId(
Name)) {
6424 }
else if (trySkipId(
"no",
Name)) {
6431 return Error(S,
"r128 modifier is not supported on this GPU");
6433 return Error(S,
"a16 modifier is not supported on this GPU");
6435 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
6436 ImmTy = AMDGPUOperand::ImmTyR128A16;
6438 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
6443 bool &Disabling)
const {
6444 Disabling =
Id.consume_front(
"no");
6464 SMLoc StringLoc = getLoc();
6466 int64_t CPolVal = 0;
6484 ResScope = parseScope(
Operands, Scope);
6499 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
6500 AMDGPUOperand::ImmTyCPol));
6505 SMLoc OpLoc = getLoc();
6506 unsigned Enabled = 0, Seen = 0;
6510 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
6517 return Error(S,
"dlc modifier is not supported on this GPU");
6520 return Error(S,
"scc modifier is not supported on this GPU");
6523 return Error(S,
"duplicate cache policy modifier");
6535 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
6547 Res = parseStringWithPrefix(
"scope",
Value, StringLoc);
6558 if (Scope == 0xffffffff)
6559 return Error(StringLoc,
"invalid scope value");
6573 if (
Value ==
"TH_DEFAULT")
6575 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_RT_WB" ||
6576 Value ==
"TH_LOAD_NT_WB") {
6577 return Error(StringLoc,
"invalid th value");
6578 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
6580 }
else if (
Value.consume_front(
"TH_LOAD_")) {
6582 }
else if (
Value.consume_front(
"TH_STORE_")) {
6585 return Error(StringLoc,
"invalid th value");
6588 if (
Value ==
"BYPASS")
6619 if (TH == 0xffffffff)
6620 return Error(StringLoc,
"invalid th value");
6627 AMDGPUAsmParser::OptionalImmIndexMap& OptionalIdx,
6628 AMDGPUOperand::ImmTy ImmT,
6630 auto i = OptionalIdx.find(ImmT);
6631 if (i != OptionalIdx.end()) {
6632 unsigned Idx = i->second;
6633 ((AMDGPUOperand &)*
Operands[
Idx]).addImmOperands(Inst, 1);
6645 StringLoc = getLoc();
6654bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
6658 SMLoc Loc = getLoc();
6660 auto Res = parseIntWithPrefix(Pref, Val);
6666 if (Val < 0 || Val > MaxVal) {
6676 AMDGPUOperand::ImmTy ImmTy) {
6677 const char *Pref =
"index_key";
6679 SMLoc Loc = getLoc();
6680 auto Res = parseIntWithPrefix(Pref, ImmVal);
6684 if (ImmTy == AMDGPUOperand::ImmTyIndexKey16bit && (ImmVal < 0 || ImmVal > 1))
6687 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
6690 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
6695 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
6699 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
6704ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &Format) {
6711 for (
int I = 0;
I < 2; ++
I) {
6712 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
6715 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
6720 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
6726 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
6729 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6730 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6736ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &Format) {
6741 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
6744 if (Fmt == UFMT_UNDEF)
6751bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
6759 if (Format != DFMT_UNDEF) {
6765 if (Format != NFMT_UNDEF) {
6770 Error(Loc,
"unsupported format");
6781 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
6786 SMLoc Loc = getLoc();
6787 if (!parseId(Str,
"expected a format string") ||
6788 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
6790 if (Dfmt == DFMT_UNDEF)
6791 return Error(Loc,
"duplicate numeric format");
6792 if (Nfmt == NFMT_UNDEF)
6793 return Error(Loc,
"duplicate data format");
6796 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6797 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6801 if (Ufmt == UFMT_UNDEF)
6802 return Error(FormatLoc,
"unsupported format");
6817 if (Id == UFMT_UNDEF)
6821 return Error(Loc,
"unified format is not supported on this GPU");
6827ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &Format) {
6829 SMLoc Loc = getLoc();
6831 if (!parseExpr(Format))
6834 return Error(Loc,
"out of range format");
6839ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &Format) {
6847 SMLoc Loc = getLoc();
6848 if (!parseId(FormatStr,
"expected a format string"))
6851 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc, Format);
6853 Res = parseSymbolicSplitFormat(FormatStr, Loc, Format);
6863 return parseNumericFormat(Format);
6871 SMLoc Loc = getLoc();
6881 AMDGPUOperand::CreateImm(
this, Format, Loc, AMDGPUOperand::ImmTyFORMAT));
6900 Res = parseSymbolicOrNumericFormat(Format);
6905 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
6906 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
6913 return Error(getLoc(),
"duplicate format");
6919 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
6921 Res = parseIntWithPrefix(
"inst_offset",
Operands,
6922 AMDGPUOperand::ImmTyInstOffset);
6929 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
6931 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
6937 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
6940 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
6950 OptionalImmIndexMap OptionalIdx;
6952 unsigned OperandIdx[4];
6953 unsigned EnMask = 0;
6956 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
6957 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
6962 OperandIdx[SrcIdx] = Inst.
size();
6963 Op.addRegOperands(Inst, 1);
6970 OperandIdx[SrcIdx] = Inst.
size();
6976 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
6977 Op.addImmOperands(Inst, 1);
6981 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
6985 OptionalIdx[
Op.getImmTy()] = i;
6991 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
6998 for (
auto i = 0; i < SrcIdx; ++i) {
7000 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7025 IntVal =
encode(ISA, IntVal, CntVal);
7026 if (CntVal !=
decode(ISA, IntVal)) {
7028 IntVal =
encode(ISA, IntVal, -1);
7036bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7038 SMLoc CntLoc = getLoc();
7046 SMLoc ValLoc = getLoc();
7047 if (!parseExpr(CntVal))
7055 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7057 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7059 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7062 Error(CntLoc,
"invalid counter name " + CntName);
7067 Error(ValLoc,
"too large value for " + CntName);
7076 Error(getLoc(),
"expected a counter name");
7103bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7104 SMLoc FieldLoc = getLoc();
7110 SMLoc ValueLoc = getLoc();
7117 if (FieldName ==
"instid0") {
7119 }
else if (FieldName ==
"instskip") {
7121 }
else if (FieldName ==
"instid1") {
7124 Error(FieldLoc,
"invalid field name " + FieldName);
7143 .
Case(
"VALU_DEP_1", 1)
7144 .
Case(
"VALU_DEP_2", 2)
7145 .
Case(
"VALU_DEP_3", 3)
7146 .
Case(
"VALU_DEP_4", 4)
7147 .
Case(
"TRANS32_DEP_1", 5)
7148 .
Case(
"TRANS32_DEP_2", 6)
7149 .
Case(
"TRANS32_DEP_3", 7)
7150 .
Case(
"FMA_ACCUM_CYCLE_1", 8)
7151 .
Case(
"SALU_CYCLE_1", 9)
7152 .
Case(
"SALU_CYCLE_2", 10)
7153 .
Case(
"SALU_CYCLE_3", 11)
7161 Delay |=
Value << Shift;
7171 if (!parseDelay(Delay))
7175 if (!parseExpr(Delay))
7179 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7184AMDGPUOperand::isSWaitCnt()
const {
7188bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7194void AMDGPUAsmParser::depCtrError(
SMLoc Loc,
int ErrorId,
7198 Error(Loc,
Twine(
"invalid counter name ", DepCtrName));
7201 Error(Loc,
Twine(DepCtrName,
" is not supported on this GPU"));
7204 Error(Loc,
Twine(
"duplicate counter name ", DepCtrName));
7207 Error(Loc,
Twine(
"invalid value for ", DepCtrName));
7214bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7218 SMLoc DepCtrLoc = getLoc();
7226 if (!parseExpr(ExprVal))
7229 unsigned PrevOprMask = UsedOprMask;
7230 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7233 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7242 Error(getLoc(),
"expected a counter name");
7247 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7248 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7256 SMLoc Loc = getLoc();
7259 unsigned UsedOprMask = 0;
7261 if (!parseDepCtr(DepCtr, UsedOprMask))
7265 if (!parseExpr(DepCtr))
7269 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
7273bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
7279ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
7281 OperandInfoTy &Width) {
7288 HwReg.Loc = getLoc();
7291 HwReg.IsSymbolic =
true;
7293 }
else if (!parseExpr(HwReg.Val,
"a register name")) {
7301 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
7305 if (!parseExpr(
Offset.Val))
7311 Width.Loc = getLoc();
7312 if (!parseExpr(Width.Val) ||
7323 SMLoc Loc = getLoc();
7325 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
7327 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
7328 HwregOffset::Default);
7329 struct : StructuredOpField {
7330 using StructuredOpField::StructuredOpField;
7331 bool validate(AMDGPUAsmParser &Parser)
const override {
7333 return Error(Parser,
"only values from 1 to 32 are legal");
7336 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
7340 Res = parseHwregFunc(HwReg,
Offset, Width);
7343 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
7345 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
7349 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
7355 if (!isUInt<16>(ImmVal))
7356 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
7358 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
7362bool AMDGPUOperand::isHwreg()
const {
7363 return isImmTy(ImmTyHwreg);
7371AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
7373 OperandInfoTy &Stream) {
7379 Msg.IsSymbolic =
true;
7381 }
else if (!parseExpr(
Msg.Val,
"a message name")) {
7386 Op.IsDefined =
true;
7391 }
else if (!parseExpr(
Op.Val,
"an operation name")) {
7396 Stream.IsDefined =
true;
7397 Stream.Loc = getLoc();
7398 if (!parseExpr(Stream.Val))
7407AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
7408 const OperandInfoTy &
Op,
7409 const OperandInfoTy &Stream) {
7419 Error(
Msg.Loc,
"specified message id is not supported on this GPU");
7424 Error(
Msg.Loc,
"invalid message id");
7430 Error(
Op.Loc,
"message does not support operations");
7432 Error(
Msg.Loc,
"missing message operation");
7437 Error(
Op.Loc,
"invalid operation id");
7442 Error(Stream.Loc,
"message operation does not support streams");
7446 Error(Stream.Loc,
"invalid message stream id");
7456 SMLoc Loc = getLoc();
7460 OperandInfoTy
Op(OP_NONE_);
7461 OperandInfoTy Stream(STREAM_ID_NONE_);
7462 if (parseSendMsgBody(Msg,
Op, Stream) &&
7463 validateSendMsg(Msg,
Op, Stream)) {
7468 }
else if (parseExpr(ImmVal,
"a sendmsg macro")) {
7469 if (ImmVal < 0 || !isUInt<16>(ImmVal))
7470 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
7475 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
7479bool AMDGPUOperand::isSendMsg()
const {
7480 return isImmTy(ImmTySendMsg);
7501 return Error(S,
"invalid interpolation slot");
7503 Operands.push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
7504 AMDGPUOperand::ImmTyInterpSlot));
7515 if (!Str.starts_with(
"attr"))
7516 return Error(S,
"invalid interpolation attribute");
7526 return Error(S,
"invalid or missing interpolation attribute channel");
7528 Str = Str.drop_back(2).drop_front(4);
7531 if (Str.getAsInteger(10, Attr))
7532 return Error(S,
"invalid or missing interpolation attribute number");
7535 return Error(S,
"out of bounds interpolation attribute number");
7539 Operands.push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
7540 AMDGPUOperand::ImmTyInterpAttr));
7541 Operands.push_back(AMDGPUOperand::CreateImm(
7542 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
7561 return Error(S, (
Id == ET_INVALID)
7562 ?
"invalid exp target"
7563 :
"exp target is not supported on this GPU");
7565 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Id, S,
7566 AMDGPUOperand::ImmTyExpTgt));
7581 return isId(getToken(),
Id);
7586 return getTokenKind() ==
Kind;
7589StringRef AMDGPUAsmParser::getId()
const {
7616 if (isId(
Id) && peekToken().is(Kind)) {
7626 if (isToken(Kind)) {
7636 if (!trySkipToken(Kind)) {
7637 Error(getLoc(), ErrMsg);
7648 if (Parser.parseExpression(Expr))
7651 if (Expr->evaluateAsAbsolute(Imm))
7655 Error(S,
"expected absolute expression");
7658 Twine(
" or an absolute expression"));
7668 if (Parser.parseExpression(Expr))
7672 if (Expr->evaluateAsAbsolute(IntVal)) {
7673 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
7675 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
7683 Val = getToken().getStringContents();
7687 Error(getLoc(), ErrMsg);
7695 Val = getTokenStr();
7699 if (!ErrMsg.
empty())
7700 Error(getLoc(), ErrMsg);
7706AMDGPUAsmParser::getToken()
const {
7707 return Parser.getTok();
7710AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
7713 : getLexer().peekTok(ShouldSkipSpace);
7718 auto TokCount = getLexer().peekTokens(Tokens);
7725AMDGPUAsmParser::getTokenKind()
const {
7730AMDGPUAsmParser::getLoc()
const {
7731 return getToken().getLoc();
7735AMDGPUAsmParser::getTokenStr()
const {
7736 return getToken().getString();
7740AMDGPUAsmParser::lex() {
7745 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
7749AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
7751 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
7752 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7754 return Op.getStartLoc();
7760AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
7762 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
7767AMDGPUAsmParser::getRegLoc(
unsigned Reg,
7769 auto Test = [=](
const AMDGPUOperand&
Op) {
7770 return Op.isRegKind() &&
Op.getReg() ==
Reg;
7776 bool SearchMandatoryLiterals)
const {
7777 auto Test = [](
const AMDGPUOperand&
Op) {
7778 return Op.IsImmKindLiteral() ||
Op.isExpr();
7781 if (SearchMandatoryLiterals && Loc == getInstLoc(
Operands))
7782 Loc = getMandatoryLitLoc(
Operands);
7787 auto Test = [](
const AMDGPUOperand &
Op) {
7788 return Op.IsImmKindMandatoryLiteral();
7795 auto Test = [](
const AMDGPUOperand&
Op) {
7796 return Op.isImmKindConst();
7813 SMLoc IdLoc = getLoc();
7819 find_if(Fields, [
Id](StructuredOpField *
F) {
return F->Id ==
Id; });
7820 if (
I == Fields.
end())
7821 return Error(IdLoc,
"unknown field");
7822 if ((*I)->IsDefined)
7823 return Error(IdLoc,
"duplicate field");
7826 (*I)->Loc = getLoc();
7827 if (!parseExpr((*I)->Val))
7829 (*I)->IsDefined =
true;
7836bool AMDGPUAsmParser::validateStructuredOpFields(
7838 return all_of(Fields, [
this](
const StructuredOpField *
F) {
7839 return F->validate(*
this);
7850 const unsigned OrMask,
7851 const unsigned XorMask) {
7854 return BITMASK_PERM_ENC |
7855 (AndMask << BITMASK_AND_SHIFT) |
7856 (OrMask << BITMASK_OR_SHIFT) |
7857 (XorMask << BITMASK_XOR_SHIFT);
7861AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
7862 const unsigned MinVal,
7863 const unsigned MaxVal,
7870 if (!parseExpr(
Op)) {
7873 if (Op < MinVal || Op > MaxVal) {
7882AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
7883 const unsigned MinVal,
7884 const unsigned MaxVal,
7887 for (
unsigned i = 0; i < OpNum; ++i) {
7888 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
7896AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &Imm) {
7900 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
7901 "expected a 2-bit lane id")) {
7912AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &Imm) {
7919 if (!parseSwizzleOperand(GroupSize,
7921 "group size must be in the interval [2,32]",
7926 Error(Loc,
"group size must be a power of two");
7929 if (parseSwizzleOperand(LaneIdx,
7931 "lane id must be in the interval [0,group size - 1]",
7940AMDGPUAsmParser::parseSwizzleReverse(int64_t &Imm) {
7946 if (!parseSwizzleOperand(GroupSize,
7948 "group size must be in the interval [2,32]",
7953 Error(Loc,
"group size must be a power of two");
7962AMDGPUAsmParser::parseSwizzleSwap(int64_t &Imm) {
7968 if (!parseSwizzleOperand(GroupSize,
7970 "group size must be in the interval [1,16]",
7975 Error(Loc,
"group size must be a power of two");
7984AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &Imm) {
7992 SMLoc StrLoc = getLoc();
7993 if (!parseString(Ctl)) {
7996 if (Ctl.
size() != BITMASK_WIDTH) {
7997 Error(StrLoc,
"expected a 5-character mask");
8001 unsigned AndMask = 0;
8002 unsigned OrMask = 0;
8003 unsigned XorMask = 0;
8005 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8009 Error(StrLoc,
"invalid mask");
8031AMDGPUAsmParser::parseSwizzleOffset(int64_t &Imm) {
8033 SMLoc OffsetLoc = getLoc();
8035 if (!parseExpr(Imm,
"a swizzle macro")) {
8038 if (!isUInt<16>(Imm)) {
8039 Error(OffsetLoc,
"expected a 16-bit offset");
8046AMDGPUAsmParser::parseSwizzleMacro(int64_t &Imm) {
8051 SMLoc ModeLoc = getLoc();
8054 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8055 Ok = parseSwizzleQuadPerm(Imm);
8056 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8057 Ok = parseSwizzleBitmaskPerm(Imm);
8058 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8059 Ok = parseSwizzleBroadcast(Imm);
8060 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8061 Ok = parseSwizzleSwap(Imm);
8062 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8063 Ok = parseSwizzleReverse(Imm);
8065 Error(ModeLoc,
"expected a swizzle mode");
8068 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8078 if (trySkipId(
"offset")) {
8082 if (trySkipId(
"swizzle")) {
8083 Ok = parseSwizzleMacro(Imm);
8085 Ok = parseSwizzleOffset(Imm);
8089 Operands.push_back(AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTySwizzle));
8097AMDGPUOperand::isSwizzle()
const {
8098 return isImmTy(ImmTySwizzle);
8105int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8119 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8120 if (trySkipId(IdSymbolic[ModeId])) {
8127 Error(S, (Imm == 0)?
8128 "expected a VGPR index mode or a closing parenthesis" :
8129 "expected a VGPR index mode");
8134 Error(S,
"duplicate VGPR index mode");
8142 "expected a comma or a closing parenthesis"))
8157 Imm = parseGPRIdxMacro();
8161 if (getParser().parseAbsoluteExpression(Imm))
8163 if (Imm < 0 || !isUInt<4>(Imm))
8164 return Error(S,
"invalid immediate: only 4-bit values are legal");
8168 AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8172bool AMDGPUOperand::isGPRIdxMode()
const {
8173 return isImmTy(ImmTyGprIdxMode);
8185 if (isRegister() || isModifier())
8197 if (
Opr.isExpr() && !
Opr.isSymbolRefExpr()) {
8198 Error(Loc,
"expected an absolute expression or a label");
8199 }
else if (
Opr.isImm() && !
Opr.isS16Imm()) {
8200 Error(Loc,
"expected a 16-bit signed jump offset");
8218void AMDGPUAsmParser::cvtMubufImpl(
MCInst &Inst,
8221 OptionalImmIndexMap OptionalIdx;
8222 unsigned FirstOperandIdx = 1;
8223 bool IsAtomicReturn =
false;
8230 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
8231 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8235 Op.addRegOperands(Inst, 1);
8239 if (IsAtomicReturn && i == FirstOperandIdx)
8240 Op.addRegOperands(Inst, 1);
8245 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
8246 Op.addImmOperands(Inst, 1);
8258 OptionalIdx[
Op.getImmTy()] = i;
8269bool AMDGPUOperand::isSMRDOffset8()
const {
8270 return isImmLiteral() && isUInt<8>(getImm());
8273bool AMDGPUOperand::isSMEMOffset()
const {
8275 return isImmLiteral();
8278bool AMDGPUOperand::isSMRDLiteralOffset()
const {
8281 return isImmLiteral() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
8313bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
8314 if (BoundCtrl == 0 || BoundCtrl == 1) {
8322void AMDGPUAsmParser::onBeginOfFile() {
8323 if (!getParser().getStreamer().getTargetStreamer() ||
8327 if (!getTargetStreamer().getTargetID())
8328 getTargetStreamer().initializeTargetID(getSTI(),
8329 getSTI().getFeatureString());
8332 getTargetStreamer().EmitDirectiveAMDGCNTarget();
8340bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
8346 .
Case(
"max", AGVK::AGVK_Max)
8347 .
Case(
"or", AGVK::AGVK_Or)
8357 if (Exprs.
empty()) {
8358 Error(getToken().getLoc(),
8359 "empty " +
Twine(TokenId) +
" expression");
8362 if (CommaCount + 1 != Exprs.
size()) {
8363 Error(getToken().getLoc(),
8364 "mismatch of commas in " +
Twine(TokenId) +
" expression");
8371 if (getParser().parseExpression(Expr, EndLoc))
8375 if (LastTokenWasComma)
8378 Error(getToken().getLoc(),
8379 "unexpected token in " +
Twine(TokenId) +
" expression");
8385 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
8390 if (
Name ==
"mul") {
8391 return parseIntWithPrefix(
"mul",
Operands,
8395 if (
Name ==
"div") {
8396 return parseIntWithPrefix(
"div",
Operands,
8412 const int Ops[] = { AMDGPU::OpName::src0,
8413 AMDGPU::OpName::src1,
8414 AMDGPU::OpName::src2 };
8429 if (
DstOp.isReg() &&
8430 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
8434 if ((OpSel & (1 << SrcNum)) != 0)
8440void AMDGPUAsmParser::cvtVOP3OpSel(
MCInst &Inst,
8447 OptionalImmIndexMap &OptionalIdx) {
8448 cvtVOP3P(Inst,
Operands, OptionalIdx);
8457 &&
Desc.NumOperands > (OpNum + 1)
8459 &&
Desc.operands()[OpNum + 1].RegClass != -1
8461 &&
Desc.getOperandConstraint(OpNum + 1,
8462 MCOI::OperandConstraint::TIED_TO) == -1;
8467 OptionalImmIndexMap OptionalIdx;
8472 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8473 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8477 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8479 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8480 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
8481 Op.isInterpAttrChan()) {
8483 }
else if (
Op.isImmModifier()) {
8484 OptionalIdx[
Op.getImmTy()] =
I;
8492 AMDGPUOperand::ImmTyHigh);
8496 AMDGPUOperand::ImmTyClampSI);
8500 AMDGPUOperand::ImmTyOModSI);
8505 OptionalImmIndexMap OptionalIdx;
8510 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8511 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8515 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8517 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8518 }
else if (
Op.isImmModifier()) {
8519 OptionalIdx[
Op.getImmTy()] =
I;
8536 const int Ops[] = { AMDGPU::OpName::src0,
8537 AMDGPU::OpName::src1,
8538 AMDGPU::OpName::src2 };
8539 const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8540 AMDGPU::OpName::src1_modifiers,
8541 AMDGPU::OpName::src2_modifiers };
8545 for (
int J = 0; J < 3; ++J) {
8553 if ((OpSel & (1 << J)) != 0)
8555 if (ModOps[J] == AMDGPU::OpName::src0_modifiers &&
8556 (OpSel & (1 << 3)) != 0)
8564 OptionalImmIndexMap &OptionalIdx) {
8569 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
8570 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
8574 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
8576 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8577 }
else if (
Op.isImmModifier()) {
8578 OptionalIdx[
Op.getImmTy()] =
I;
8579 }
else if (
Op.isRegOrImm()) {
8580 Op.addRegOrImmOperands(Inst, 1);
8588 AMDGPUOperand::ImmTyClampSI);
8592 AMDGPUOperand::ImmTyOModSI);
8599 auto it = Inst.
begin();
8609 OptionalImmIndexMap OptionalIdx;
8610 cvtVOP3(Inst,
Operands, OptionalIdx);
8614 OptionalImmIndexMap &OptIdx) {
8620 if (Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
8621 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
8622 Opc == AMDGPU::V_CVT_SR_BF8_F32_e64_gfx12 ||
8623 Opc == AMDGPU::V_CVT_SR_FP8_F32_e64_gfx12) {
8631 !(Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp_gfx12 ||
8632 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp_gfx12 ||
8633 Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp8_gfx12 ||
8634 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp8_gfx12)) {
8643 if (OpSelIdx != -1) {
8648 if (OpSelHiIdx != -1) {
8662 const int Ops[] = { AMDGPU::OpName::src0,
8663 AMDGPU::OpName::src1,
8664 AMDGPU::OpName::src2 };
8665 const int ModOps[] = { AMDGPU::OpName::src0_modifiers,
8666 AMDGPU::OpName::src1_modifiers,
8667 AMDGPU::OpName::src2_modifiers };
8670 unsigned OpSelHi = 0;
8677 if (OpSelHiIdx != -1)
8686 for (
int J = 0; J < 3; ++J) {
8699 if (
SrcOp.isReg() && getMRI()
8706 if ((OpSel & (1 << J)) != 0)
8710 if ((OpSelHi & (1 << J)) != 0)
8713 if ((NegLo & (1 << J)) != 0)
8716 if ((NegHi & (1 << J)) != 0)
8724 OptionalImmIndexMap OptIdx;
8730 unsigned i,
unsigned Opc,
unsigned OpName) {
8732 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
8734 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
8740 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
8743 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
8744 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
8746 OptionalImmIndexMap OptIdx;
8747 for (
unsigned i = 5; i <
Operands.size(); ++i) {
8748 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8749 OptIdx[
Op.getImmTy()] = i;
8754 AMDGPUOperand::ImmTyIndexKey8bit);
8758 AMDGPUOperand::ImmTyIndexKey16bit);
8778 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
8779 SMLoc OpYLoc = getLoc();
8782 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
8785 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
8792 auto addOp = [&](
uint16_t ParsedOprIdx) {
8793 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
8795 Op.addRegOperands(Inst, 1);
8799 Op.addImmOperands(Inst, 1);
8811 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
8815 const auto &CInfo = InstInfo[CompIdx];
8816 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
8817 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
8818 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
8819 if (CInfo.hasSrc2Acc())
8820 addOp(CInfo.getIndexOfDstInParsedOperands());
8828bool AMDGPUOperand::isDPP8()
const {
8829 return isImmTy(ImmTyDPP8);
8832bool AMDGPUOperand::isDPPCtrl()
const {
8833 using namespace AMDGPU::DPP;
8835 bool result =
isImm() && getImmTy() == ImmTyDppCtrl && isUInt<9>(getImm());
8837 int64_t
Imm = getImm();
8838 return (Imm >= DppCtrl::QUAD_PERM_FIRST && Imm <= DppCtrl::QUAD_PERM_LAST) ||
8839 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
8840 (Imm >= DppCtrl::ROW_SHR_FIRST && Imm <= DppCtrl::ROW_SHR_LAST) ||
8841 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
8842 (Imm == DppCtrl::WAVE_SHL1) ||
8843 (
Imm == DppCtrl::WAVE_ROL1) ||
8844 (Imm == DppCtrl::WAVE_SHR1) ||
8845 (
Imm == DppCtrl::WAVE_ROR1) ||
8846 (Imm == DppCtrl::ROW_MIRROR) ||
8847 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
8848 (Imm == DppCtrl::BCAST15) ||
8849 (
Imm == DppCtrl::BCAST31) ||
8850 (Imm >= DppCtrl::ROW_SHARE_FIRST && Imm <= DppCtrl::ROW_SHARE_LAST) ||
8851 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
8860bool AMDGPUOperand::isBLGP()
const {
8861 return isImm() && getImmTy() == ImmTyBLGP && isUInt<3>(getImm());
8864bool AMDGPUOperand::isCBSZ()
const {
8865 return isImm() && getImmTy() == ImmTyCBSZ && isUInt<3>(getImm());
8868bool AMDGPUOperand::isABID()
const {
8869 return isImm() && getImmTy() == ImmTyABID && isUInt<4>(getImm());
8872bool AMDGPUOperand::isS16Imm()
const {
8873 return isImmLiteral() && (isInt<16>(getImm()) || isUInt<16>(getImm()));
8876bool AMDGPUOperand::isU16Imm()
const {
8877 return isImmLiteral() && isUInt<16>(getImm());
8884bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
8889 SMLoc Loc = getToken().getEndLoc();
8890 Token = std::string(getTokenStr());
8892 if (getLoc() != Loc)
8897 if (!parseId(Suffix))
8923 SMLoc Loc = getLoc();
8924 if (!parseDimId(Encoding))
8925 return Error(Loc,
"invalid dim value");
8927 Operands.push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
8928 AMDGPUOperand::ImmTyDim));
8946 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
8949 for (
size_t i = 0; i < 8; ++i) {
8953 SMLoc Loc = getLoc();
8954 if (getParser().parseAbsoluteExpression(Sels[i]))
8956 if (0 > Sels[i] || 7 < Sels[i])
8957 return Error(Loc,
"expected a 3-bit value");
8964 for (
size_t i = 0; i < 8; ++i)
8965 DPP8 |= (Sels[i] << (i * 3));
8967 Operands.push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
8972AMDGPUAsmParser::isSupportedDPPCtrl(
StringRef Ctrl,
8974 if (Ctrl ==
"row_newbcast")
8977 if (Ctrl ==
"row_share" ||
8978 Ctrl ==
"row_xmask")
8981 if (Ctrl ==
"wave_shl" ||
8982 Ctrl ==
"wave_shr" ||
8983 Ctrl ==
"wave_rol" ||
8984 Ctrl ==
"wave_ror" ||
8985 Ctrl ==
"row_bcast")
8988 return Ctrl ==
"row_mirror" ||
8989 Ctrl ==
"row_half_mirror" ||
8990 Ctrl ==
"quad_perm" ||
8991 Ctrl ==
"row_shl" ||
8992 Ctrl ==
"row_shr" ||
8997AMDGPUAsmParser::parseDPPCtrlPerm() {
9000 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9004 for (
int i = 0; i < 4; ++i) {
9009 SMLoc Loc = getLoc();
9010 if (getParser().parseAbsoluteExpression(Temp))
9012 if (Temp < 0 || Temp > 3) {
9013 Error(Loc,
"expected a 2-bit value");
9017 Val += (Temp << i * 2);
9027AMDGPUAsmParser::parseDPPCtrlSel(
StringRef Ctrl) {
9028 using namespace AMDGPU::DPP;
9033 SMLoc Loc = getLoc();
9035 if (getParser().parseAbsoluteExpression(Val))
9038 struct DppCtrlCheck {
9045 .
Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
9046 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
9047 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
9048 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
9049 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
9050 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
9051 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
9052 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
9053 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
9054 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
9058 if (
Check.Ctrl == -1) {
9059 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
9060 Val = (Val == 15)? DppCtrl::BCAST15 : DppCtrl::BCAST31;
9075 using namespace AMDGPU::DPP;
9078 !isSupportedDPPCtrl(getTokenStr(),
Operands))
9087 if (Ctrl ==
"row_mirror") {
9088 Val = DppCtrl::ROW_MIRROR;
9089 }
else if (Ctrl ==
"row_half_mirror") {
9090 Val = DppCtrl::ROW_HALF_MIRROR;
9093 if (Ctrl ==
"quad_perm") {
9094 Val = parseDPPCtrlPerm();
9096 Val = parseDPPCtrlSel(Ctrl);
9105 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
9111 OptionalImmIndexMap OptionalIdx;
9121 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
9125 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9126 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9134 if (OldIdx == NumOperands) {
9136 constexpr int DST_IDX = 0;
9138 }
else if (Src2ModIdx == NumOperands) {
9149 bool IsVOP3CvtSrDpp = Opc == AMDGPU::V_CVT_SR_BF8_F32_e64_dpp8_gfx12 ||
9150 Opc == AMDGPU::V_CVT_SR_FP8_F32_e64_dpp8_gfx12 ||
9151 Opc == AMDGPU::V_CVT_SR_BF8_F32_e64_dpp_gfx12 ||
9152 Opc == AMDGPU::V_CVT_SR_FP8_F32_e64_dpp_gfx12;
9153 if (IsVOP3CvtSrDpp) {
9167 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9169 if (IsDPP8 &&
Op.isDppFI()) {
9172 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9173 }
else if (
Op.isReg()) {
9174 Op.addRegOperands(Inst, 1);
9175 }
else if (
Op.isImm() &&
9177 assert(!
Op.IsImmKindLiteral() &&
"Cannot use literal with DPP");
9178 Op.addImmOperands(Inst, 1);
9179 }
else if (
Op.isImm()) {
9180 OptionalIdx[
Op.getImmTy()] =
I;
9192 cvtVOP3P(Inst,
Operands, OptionalIdx);
9194 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
9211 AMDGPUOperand::ImmTyDppFI);
9216 OptionalImmIndexMap OptionalIdx;
9220 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9221 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9233 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9235 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
9243 Op.addImmOperands(Inst, 1);
9245 Op.addRegWithFPInputModsOperands(Inst, 2);
9246 }
else if (
Op.isDppFI()) {
9248 }
else if (
Op.isReg()) {
9249 Op.addRegOperands(Inst, 1);
9255 Op.addRegWithFPInputModsOperands(Inst, 2);
9256 }
else if (
Op.isReg()) {
9257 Op.addRegOperands(Inst, 1);
9258 }
else if (
Op.isDPPCtrl()) {
9259 Op.addImmOperands(Inst, 1);
9260 }
else if (
Op.isImm()) {
9262 OptionalIdx[
Op.getImmTy()] =
I;
9278 AMDGPUOperand::ImmTyDppFI);
9289 AMDGPUOperand::ImmTy
Type) {
9302 .
Case(
"BYTE_0", SdwaSel::BYTE_0)
9303 .
Case(
"BYTE_1", SdwaSel::BYTE_1)
9304 .
Case(
"BYTE_2", SdwaSel::BYTE_2)
9305 .
Case(
"BYTE_3", SdwaSel::BYTE_3)
9306 .
Case(
"WORD_0", SdwaSel::WORD_0)
9307 .
Case(
"WORD_1", SdwaSel::WORD_1)
9308 .
Case(
"DWORD", SdwaSel::DWORD)
9311 if (
Int == 0xffffffff)
9312 return Error(StringLoc,
"invalid " +
Twine(Prefix) +
" value");
9331 .
Case(
"UNUSED_PAD", DstUnused::UNUSED_PAD)
9332 .
Case(
"UNUSED_SEXT", DstUnused::UNUSED_SEXT)
9333 .
Case(
"UNUSED_PRESERVE", DstUnused::UNUSED_PRESERVE)
9336 if (
Int == 0xffffffff)
9337 return Error(StringLoc,
"invalid dst_unused value");
9339 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Int, S, AMDGPUOperand::ImmTySDWADstUnused));
9369 OptionalImmIndexMap OptionalIdx;
9370 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
9371 bool SkippedVcc =
false;
9375 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9376 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9380 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9381 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
9382 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
9400 Op.addRegOrImmWithInputModsOperands(Inst, 2);
9401 }
else if (
Op.isImm()) {
9403 OptionalIdx[
Op.getImmTy()] =
I;
9411 if (Opc != AMDGPU::V_NOP_sdwa_gfx10 && Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
9412 Opc != AMDGPU::V_NOP_sdwa_vi) {
9414 switch (BasicInstType) {
9418 AMDGPUOperand::ImmTyClampSI, 0);
9422 AMDGPUOperand::ImmTyOModSI, 0);
9426 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
9430 AMDGPUOperand::ImmTySDWADstUnused,
9431 DstUnused::UNUSED_PRESERVE);
9456 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
9462 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
9463 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
9464 auto it = Inst.
begin();
9477#define GET_REGISTER_MATCHER
9478#define GET_MATCHER_IMPLEMENTATION
9479#define GET_MNEMONIC_SPELL_CHECKER
9480#define GET_MNEMONIC_CHECKER
9481#include "AMDGPUGenAsmMatcher.inc"
9487 return parseTokenOp(
"addr64",
Operands);
9489 return parseTokenOp(
"done",
Operands);
9491 return parseTokenOp(
"idxen",
Operands);
9493 return parseTokenOp(
"lds",
Operands);
9495 return parseTokenOp(
"offen",
Operands);
9497 return parseTokenOp(
"off",
Operands);
9499 return parseTokenOp(
"row_en",
Operands);
9501 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
9503 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
9505 return tryCustomParseOperand(
Operands, MCK);
9516 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
9519 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
9521 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
9523 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
9525 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
9527 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
9529 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
9537 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
9539 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
9540 case MCK_SOPPBrTarget:
9541 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
9542 case MCK_VReg32OrOff:
9543 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
9544 case MCK_InterpSlot:
9545 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
9546 case MCK_InterpAttr:
9547 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
9548 case MCK_InterpAttrChan:
9549 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
9551 case MCK_SReg_64_XEXEC:
9557 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
9559 return Match_InvalidOperand;
9571 if (!parseExpr(Imm)) {
9576 if (!isUInt<16>(Imm))
9577 return Error(S,
"expected a 16-bit value");
9580 AMDGPUOperand::CreateImm(
this, Imm, S, AMDGPUOperand::ImmTyEndpgm));
9584bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
9590bool AMDGPUOperand::isWaitVDST()
const {
9591 return isImmTy(ImmTyWaitVDST) && isUInt<4>(getImm());
9594bool AMDGPUOperand::isWaitVAVDst()
const {
9595 return isImmTy(ImmTyWaitVAVDst) && isUInt<4>(getImm());
9598bool AMDGPUOperand::isWaitVMVSrc()
const {
9599 return isImmTy(ImmTyWaitVMVSrc) && isUInt<1>(getImm());
9606bool AMDGPUOperand::isWaitEXP()
const {
9607 return isImmTy(ImmTyWaitEXP) && isUInt<3>(getImm());
9614bool 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
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)
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
#define AMDHSA_BITS_SET(DST, MSK, VAL)
@ 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")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static unsigned getOperandSize(MachineInstr &MI, unsigned Idx, MachineRegisterInfo &MRI)
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
mir Rename Register Operands
unsigned const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
#define G_00B848_FWD_PROGRESS(x)
#define G_00B848_MEM_ORDERED(x)
#define G_00B848_IEEE_MODE(x)
#define G_00B848_DX10_CLAMP(x)
#define G_00B848_WGP_MODE(x)
Interface definition for SIInstrInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Interface definition for SIRegisterInfo.
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
unsigned unsigned DefaultVal
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
support::ulittle16_t & Lo
support::ulittle16_t & Hi
static const AMDGPUVariadicMCExpr * create(VariadicKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Target independent representation for an assembler token.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Class representing an expression and its matching format.
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCRegisterInfo * getRegisterInfo() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
const MCSubtargetInfo * getSubtargetInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
bool mayStore() const
Return true if this instruction could possibly modify memory.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
void setReg(unsigned Reg)
Set the register number.
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual unsigned getReg() const =0
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
static constexpr unsigned NoRegister
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void setVariableValue(const MCExpr *Value)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
Target specific streamer interface.
uint64_t getScalarSizeInBits() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
Represents a range in source code.
Implements a dense probed hash-table based set with some number of buckets stored inline.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
StringSet - A wrapper for StringMap that provides set-like functionality.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
unsigned getTgtId(const StringRef Name)
constexpr char NumVGPRs[]
Key for Kernel::CodeProps::Metadata::mNumVGPRs.
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
const CustomOperand< const MCSubtargetInfo & > Opr[]
int64_t getHwregId(const StringRef Name, const MCSubtargetInfo &STI)
unsigned getNumExtraSGPRs(const MCSubtargetInfo *STI, bool VCCUsed, bool FlatScrUsed, bool XNACKUsed)
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
unsigned getNumSGPRBlocks(const MCSubtargetInfo *STI, unsigned NumSGPRs)
unsigned getEncodedNumVGPRBlocks(const MCSubtargetInfo *STI, unsigned NumVGPRs, std::optional< bool > EnableWavefrontSize32)
@ 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.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
int64_t getMsgId(const StringRef Name, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
int64_t getMsgOpId(int64_t MsgId, const StringRef Name)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
const CustomOperand< const MCSubtargetInfo & > Msg[]
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
constexpr unsigned COMPONENTS[]
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc, unsigned OpNo)
Get size of register operand.
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
LLVM_READNONE bool isLegalDPALU_DPPControl(unsigned DC)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
bool isGFX10(const MCSubtargetInfo &STI)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header, const MCSubtargetInfo *STI)
bool isInlinableLiteralV2BF16(uint32_t Literal)
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
unsigned mc2PseudoReg(unsigned Reg)
Convert hardware register Reg to a pseudo register.
bool hasA16(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset, bool IsBuffer)
bool isGFX12Plus(const MCSubtargetInfo &STI)
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool isHsaAbi(const MCSubtargetInfo &STI)
bool isGFX11(const MCSubtargetInfo &STI)
const int OPR_VAL_INVALID
bool getSMEMIsBuffer(unsigned Opc)
IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
bool isDPALU_DPP(const MCInstrDesc &OpDesc)
bool isSI(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
bool isGFX9(const MCSubtargetInfo &STI)
bool isGFX10_AEncoding(const MCSubtargetInfo &STI)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this an AMDGPU specific source operand? These include registers, inline constants,...
bool hasMAIInsts(const MCSubtargetInfo &STI)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, uint64_t NamedIdx)
LLVM_READNONE bool isInlinableIntLiteral(int64_t Literal)
Is this literal inlinable, and not one of the values intended for floating point values.
bool isSGPR(unsigned Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
bool isHi(unsigned Reg, const MCRegisterInfo &MRI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isInlineValue(unsigned Reg)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_V2INT32
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_INLINE_AC_V2FP16
@ OPERAND_REG_IMM_INT32
Operands with register or 32-bit immediate.
@ OPERAND_REG_IMM_BF16_DEFERRED
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_AC_BF16
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_INLINE_AC_INT16
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_V2INT16
@ OPERAND_REG_INLINE_AC_FP16
@ OPERAND_REG_INLINE_AC_INT32
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_INLINE_AC_V2BF16
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_REG_INLINE_C_V2FP32
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
@ OPERAND_REG_IMM_FP32_DEFERRED
@ OPERAND_REG_IMM_FP16_DEFERRED
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isVI(const MCSubtargetInfo &STI)
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
amdhsa::kernel_descriptor_t getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
Reg
All possible values of the reg field in the ModR/M byte.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
int popcount(T Value) noexcept
Count the number of set bits in a value.
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
uint64_t divideCeil(uint64_t Numerator, uint64_t Denominator)
Returns the integer ceil(Numerator / Denominator).
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool parseAmdKernelCodeField(StringRef ID, MCAsmParser &Parser, amd_kernel_code_t &C, raw_ostream &Err)
AMD Kernel Code Object (amd_kernel_code_t).
Instruction set architecture version.
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 compute_pgm_rsrc1
uint32_t private_segment_fixed_size
uint32_t compute_pgm_rsrc2
uint16_t kernel_code_properties
uint32_t compute_pgm_rsrc3