56enum RegisterKind { IS_UNKNOWN,
IS_VGPR, IS_SGPR,
IS_AGPR, IS_TTMP, IS_SPECIAL };
58enum class LitModifier {
None, Lit, Lit64 };
72 SMLoc StartLoc, EndLoc;
73 const AMDGPUAsmParser *AsmParser;
76 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
77 : Kind(Kind_), AsmParser(AsmParser_) {}
79 using Ptr = std::unique_ptr<AMDGPUOperand>;
85 LitModifier Lit = LitModifier::None;
87 bool hasFPModifiers()
const {
return Abs || Neg; }
88 bool hasIntModifiers()
const {
return Sext; }
89 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
91 int64_t getFPModifiersOperand()
const {
98 int64_t getIntModifiersOperand()
const {
104 int64_t getModifiersOperand()
const {
105 assert(!(hasFPModifiers() && hasIntModifiers())
106 &&
"fp and int modifiers should not be used simultaneously");
107 if (hasFPModifiers())
108 return getFPModifiersOperand();
109 if (hasIntModifiers())
110 return getIntModifiersOperand();
114 friend raw_ostream &
operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
184 ImmTyMatrixAScaleFmt,
185 ImmTyMatrixBScaleFmt,
218 mutable int MCOpIdx = -1;
221 bool isToken()
const override {
return Kind == Token; }
223 bool isSymbolRefExpr()
const {
227 bool isImm()
const override {
228 return Kind == Immediate;
231 bool isInlinableImm(MVT type)
const;
232 bool isLiteralImm(MVT type)
const;
234 bool isRegKind()
const {
235 return Kind == Register;
238 bool isReg()
const override {
239 return isRegKind() && !hasModifiers();
242 bool isRegOrInline(
unsigned RCID, MVT type)
const {
243 return isRegClass(RCID) || isInlinableImm(type);
247 return isRegOrInline(RCID, type) || isLiteralImm(type);
250 bool isRegOrImmWithInt16InputMods()
const {
254 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
256 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
259 bool isRegOrImmWithInt32InputMods()
const {
263 bool isRegOrInlineImmWithInt16InputMods()
const {
264 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
267 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
268 return isRegOrInline(
269 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
272 bool isRegOrInlineImmWithInt32InputMods()
const {
273 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
276 bool isRegOrImmWithInt64InputMods()
const {
280 bool isRegOrImmWithFP16InputMods()
const {
284 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
286 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
289 bool isRegOrImmWithFP32InputMods()
const {
293 bool isRegOrImmWithFP64InputMods()
const {
297 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
298 return isRegOrInline(
299 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
302 bool isRegOrInlineImmWithFP32InputMods()
const {
303 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
306 bool isRegOrInlineImmWithFP64InputMods()
const {
307 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
310 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
312 bool isVRegWithFP32InputMods()
const {
313 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
316 bool isVRegWithFP64InputMods()
const {
317 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
320 bool isPackedFP16InputMods()
const {
324 bool isPackedVGPRFP32InputMods()
const {
328 bool isVReg()
const {
329 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
330 isRegClass(AMDGPU::VReg_64RegClassID) ||
331 isRegClass(AMDGPU::VReg_96RegClassID) ||
332 isRegClass(AMDGPU::VReg_128RegClassID) ||
333 isRegClass(AMDGPU::VReg_160RegClassID) ||
334 isRegClass(AMDGPU::VReg_192RegClassID) ||
335 isRegClass(AMDGPU::VReg_256RegClassID) ||
336 isRegClass(AMDGPU::VReg_512RegClassID) ||
337 isRegClass(AMDGPU::VReg_1024RegClassID);
340 bool isVReg32()
const {
341 return isRegClass(AMDGPU::VGPR_32RegClassID);
344 bool isVReg32OrOff()
const {
345 return isOff() || isVReg32();
349 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
352 bool isVRegWithInputMods()
const;
353 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
354 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
356 bool isSDWAOperand(MVT type)
const;
357 bool isSDWAFP16Operand()
const;
358 bool isSDWAFP32Operand()
const;
359 bool isSDWAInt16Operand()
const;
360 bool isSDWAInt32Operand()
const;
362 bool isImmTy(ImmTy ImmT)
const {
363 return isImm() &&
Imm.Type == ImmT;
366 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
368 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
370 bool isImmModifier()
const {
371 return isImm() &&
Imm.Type != ImmTyNone;
374 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
375 bool isDim()
const {
return isImmTy(ImmTyDim); }
376 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
377 bool isOff()
const {
return isImmTy(ImmTyOff); }
378 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
379 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
380 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
381 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
382 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
383 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
384 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
385 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
386 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
387 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
388 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
389 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
390 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
391 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
392 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
393 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
394 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
395 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
396 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
397 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
398 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
399 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
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); }
412 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
414 bool isRegOrImm()
const {
415 return isReg() || isImm();
418 bool isRegClass(
unsigned RCID)
const;
422 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
423 return isRegOrInline(RCID, type) && !hasModifiers();
426 bool isSCSrcB16()
const {
427 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
430 bool isSCSrcV2B16()
const {
434 bool isSCSrc_b32()
const {
435 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
438 bool isSCSrc_b64()
const {
439 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
442 bool isBoolReg()
const;
444 bool isSCSrcF16()
const {
445 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
448 bool isSCSrcV2F16()
const {
452 bool isSCSrcF32()
const {
453 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
456 bool isSCSrcF64()
const {
457 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
460 bool isSSrc_b32()
const {
461 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
464 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
466 bool isSSrcV2B16()
const {
471 bool isSSrc_b64()
const {
474 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
475 (((
const MCTargetAsmParser *)AsmParser)
476 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
480 bool isSSrc_f32()
const {
481 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
484 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
486 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
488 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
490 bool isSSrcV2F16()
const {
495 bool isSSrcV2FP32()
const {
500 bool isSCSrcV2FP32()
const {
505 bool isSSrcV2INT32()
const {
510 bool isSCSrcV2INT32()
const {
512 return isSCSrc_b32();
515 bool isSSrcOrLds_b32()
const {
516 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
517 isLiteralImm(MVT::i32) || isExpr();
520 bool isVCSrc_b32()
const {
521 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
524 bool isVCSrc_b32_Lo256()
const {
525 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
528 bool isVCSrc_b64_Lo256()
const {
529 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
532 bool isVCSrc_b64()
const {
533 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
536 bool isVCSrcT_b16()
const {
537 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
540 bool isVCSrcTB16_Lo128()
const {
541 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
544 bool isVCSrcFake16B16_Lo128()
const {
545 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
548 bool isVCSrc_b16()
const {
549 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
552 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
554 bool isVCSrc_f32()
const {
555 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
558 bool isVCSrc_f64()
const {
559 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
562 bool isVCSrcTBF16()
const {
563 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
566 bool isVCSrcT_f16()
const {
567 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
570 bool isVCSrcT_bf16()
const {
571 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
574 bool isVCSrcTBF16_Lo128()
const {
575 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
578 bool isVCSrcTF16_Lo128()
const {
579 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
582 bool isVCSrcFake16BF16_Lo128()
const {
583 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
586 bool isVCSrcFake16F16_Lo128()
const {
587 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
590 bool isVCSrc_bf16()
const {
591 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
594 bool isVCSrc_f16()
const {
595 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
598 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
600 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
602 bool isVSrc_b32()
const {
603 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
606 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
608 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
610 bool isVSrcT_b16_Lo128()
const {
611 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
614 bool isVSrcFake16_b16_Lo128()
const {
615 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
618 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
620 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
622 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
624 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
626 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
628 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
630 bool isVSrc_f32()
const {
631 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
634 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
636 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
638 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
640 bool isVSrcT_bf16_Lo128()
const {
641 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
644 bool isVSrcT_f16_Lo128()
const {
645 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
648 bool isVSrcFake16_bf16_Lo128()
const {
649 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
652 bool isVSrcFake16_f16_Lo128()
const {
653 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
656 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
658 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
660 bool isVSrc_v2bf16()
const {
661 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
664 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
666 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
668 bool isVISrcB32()
const {
669 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
672 bool isVISrcB16()
const {
673 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
676 bool isVISrcV2B16()
const {
680 bool isVISrcF32()
const {
681 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
684 bool isVISrcF16()
const {
685 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
688 bool isVISrcV2F16()
const {
689 return isVISrcF16() || isVISrcB32();
692 bool isVISrc_64_bf16()
const {
693 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
696 bool isVISrc_64_f16()
const {
697 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
700 bool isVISrc_64_b32()
const {
701 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
704 bool isVISrc_64B64()
const {
705 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
708 bool isVISrc_64_f64()
const {
709 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
712 bool isVISrc_64V2FP32()
const {
713 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
716 bool isVISrc_64V2INT32()
const {
717 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
720 bool isVISrc_256_b32()
const {
721 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
724 bool isVISrc_256_f32()
const {
725 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
728 bool isVISrc_256B64()
const {
729 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
732 bool isVISrc_256_f64()
const {
733 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
736 bool isVISrc_512_f64()
const {
737 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
740 bool isVISrc_128B16()
const {
741 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
744 bool isVISrc_128V2B16()
const {
745 return isVISrc_128B16();
748 bool isVISrc_128_b32()
const {
749 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
752 bool isVISrc_128_f32()
const {
753 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
756 bool isVISrc_256V2FP32()
const {
757 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
760 bool isVISrc_256V2INT32()
const {
761 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
764 bool isVISrc_512_b32()
const {
765 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
768 bool isVISrc_512B16()
const {
769 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
772 bool isVISrc_512V2B16()
const {
773 return isVISrc_512B16();
776 bool isVISrc_512_f32()
const {
777 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
780 bool isVISrc_512F16()
const {
781 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
784 bool isVISrc_512V2F16()
const {
785 return isVISrc_512F16() || isVISrc_512_b32();
788 bool isVISrc_1024_b32()
const {
789 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
792 bool isVISrc_1024B16()
const {
793 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
796 bool isVISrc_1024V2B16()
const {
797 return isVISrc_1024B16();
800 bool isVISrc_1024_f32()
const {
801 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
804 bool isVISrc_1024F16()
const {
805 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
808 bool isVISrc_1024V2F16()
const {
809 return isVISrc_1024F16() || isVISrc_1024_b32();
812 bool isAISrcB32()
const {
813 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
816 bool isAISrcB16()
const {
817 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
820 bool isAISrcV2B16()
const {
824 bool isAISrcF32()
const {
825 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
828 bool isAISrcF16()
const {
829 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
832 bool isAISrcV2F16()
const {
833 return isAISrcF16() || isAISrcB32();
836 bool isAISrc_64B64()
const {
837 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
840 bool isAISrc_64_f64()
const {
841 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
844 bool isAISrc_128_b32()
const {
845 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
848 bool isAISrc_128B16()
const {
849 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
852 bool isAISrc_128V2B16()
const {
853 return isAISrc_128B16();
856 bool isAISrc_128_f32()
const {
857 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
860 bool isAISrc_128F16()
const {
861 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
864 bool isAISrc_128V2F16()
const {
865 return isAISrc_128F16() || isAISrc_128_b32();
868 bool isVISrc_128_bf16()
const {
869 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
872 bool isVISrc_128_f16()
const {
873 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
876 bool isVISrc_128V2F16()
const {
877 return isVISrc_128_f16() || isVISrc_128_b32();
880 bool isAISrc_256B64()
const {
881 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
884 bool isAISrc_256_f64()
const {
885 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
888 bool isAISrc_512_b32()
const {
889 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
892 bool isAISrc_512B16()
const {
893 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
896 bool isAISrc_512V2B16()
const {
897 return isAISrc_512B16();
900 bool isAISrc_512_f32()
const {
901 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
904 bool isAISrc_512F16()
const {
905 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
908 bool isAISrc_512V2F16()
const {
909 return isAISrc_512F16() || isAISrc_512_b32();
912 bool isAISrc_1024_b32()
const {
913 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
916 bool isAISrc_1024B16()
const {
917 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
920 bool isAISrc_1024V2B16()
const {
921 return isAISrc_1024B16();
924 bool isAISrc_1024_f32()
const {
925 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
928 bool isAISrc_1024F16()
const {
929 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
932 bool isAISrc_1024V2F16()
const {
933 return isAISrc_1024F16() || isAISrc_1024_b32();
936 bool isKImmFP32()
const {
937 return isLiteralImm(MVT::f32);
940 bool isKImmFP16()
const {
941 return isLiteralImm(MVT::f16);
944 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
946 bool isMem()
const override {
950 bool isExpr()
const {
951 return Kind == Expression;
954 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
956 bool isSWaitCnt()
const;
957 bool isDepCtr()
const;
958 bool isSDelayALU()
const;
959 bool isHwreg()
const;
960 bool isSendMsg()
const;
961 bool isSplitBarrier()
const;
962 bool isSwizzle()
const;
963 bool isSMRDOffset8()
const;
964 bool isSMEMOffset()
const;
965 bool isSMRDLiteralOffset()
const;
967 bool isDPPCtrl()
const;
969 bool isGPRIdxMode()
const;
970 bool isS16Imm()
const;
971 bool isU16Imm()
const;
972 bool isEndpgm()
const;
974 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
975 return [
this,
P]() {
return P(*
this); };
980 return StringRef(Tok.Data, Tok.Length);
988 void setImm(int64_t Val) {
993 ImmTy getImmTy()
const {
998 MCRegister
getReg()
const override {
1003 SMLoc getStartLoc()
const override {
1007 SMLoc getEndLoc()
const override {
1011 SMRange getLocRange()
const {
1012 return SMRange(StartLoc, EndLoc);
1015 int getMCOpIdx()
const {
return MCOpIdx; }
1017 Modifiers getModifiers()
const {
1018 assert(isRegKind() || isImmTy(ImmTyNone));
1019 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1022 void setModifiers(Modifiers Mods) {
1023 assert(isRegKind() || isImmTy(ImmTyNone));
1030 bool hasModifiers()
const {
1031 return getModifiers().hasModifiers();
1034 bool hasFPModifiers()
const {
1035 return getModifiers().hasFPModifiers();
1038 bool hasIntModifiers()
const {
1039 return getModifiers().hasIntModifiers();
1042 uint64_t applyInputFPModifiers(uint64_t Val,
unsigned Size)
const;
1044 void addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1046 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1048 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1050 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1052 addRegOperands(Inst,
N);
1054 addImmOperands(Inst,
N);
1057 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1058 Modifiers Mods = getModifiers();
1061 addRegOperands(Inst,
N);
1063 addImmOperands(Inst,
N,
false);
1067 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1068 assert(!hasIntModifiers());
1069 addRegOrImmWithInputModsOperands(Inst,
N);
1072 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1073 assert(!hasFPModifiers());
1074 addRegOrImmWithInputModsOperands(Inst,
N);
1077 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1078 Modifiers Mods = getModifiers();
1081 addRegOperands(Inst,
N);
1084 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1085 assert(!hasIntModifiers());
1086 addRegWithInputModsOperands(Inst,
N);
1089 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1090 assert(!hasFPModifiers());
1091 addRegWithInputModsOperands(Inst,
N);
1094 static void printImmTy(raw_ostream& OS, ImmTy
Type) {
1097 case ImmTyNone: OS <<
"None";
break;
1098 case ImmTyGDS: OS <<
"GDS";
break;
1099 case ImmTyLDS: OS <<
"LDS";
break;
1100 case ImmTyOffen: OS <<
"Offen";
break;
1101 case ImmTyIdxen: OS <<
"Idxen";
break;
1102 case ImmTyAddr64: OS <<
"Addr64";
break;
1103 case ImmTyOffset: OS <<
"Offset";
break;
1104 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1105 case ImmTyOffset0: OS <<
"Offset0";
break;
1106 case ImmTyOffset1: OS <<
"Offset1";
break;
1107 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1108 case ImmTyCPol: OS <<
"CPol";
break;
1109 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1110 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1111 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1112 case ImmTyTFE: OS <<
"TFE";
break;
1113 case ImmTyD16: OS <<
"D16";
break;
1114 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1115 case ImmTyClamp: OS <<
"Clamp";
break;
1116 case ImmTyOModSI: OS <<
"OModSI";
break;
1117 case ImmTyDPP8: OS <<
"DPP8";
break;
1118 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1119 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1120 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1121 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1122 case ImmTyDppFI: OS <<
"DppFI";
break;
1123 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1124 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1125 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1126 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1127 case ImmTyDMask: OS <<
"DMask";
break;
1128 case ImmTyDim: OS <<
"Dim";
break;
1129 case ImmTyUNorm: OS <<
"UNorm";
break;
1130 case ImmTyDA: OS <<
"DA";
break;
1131 case ImmTyR128A16: OS <<
"R128A16";
break;
1132 case ImmTyA16: OS <<
"A16";
break;
1133 case ImmTyLWE: OS <<
"LWE";
break;
1134 case ImmTyOff: OS <<
"Off";
break;
1135 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1136 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1137 case ImmTyExpVM: OS <<
"ExpVM";
break;
1138 case ImmTyHwreg: OS <<
"Hwreg";
break;
1139 case ImmTySendMsg: OS <<
"SendMsg";
break;
1140 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1141 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1142 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1143 case ImmTyOpSel: OS <<
"OpSel";
break;
1144 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1145 case ImmTyNegLo: OS <<
"NegLo";
break;
1146 case ImmTyNegHi: OS <<
"NegHi";
break;
1147 case ImmTySwizzle: OS <<
"Swizzle";
break;
1148 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1149 case ImmTyHigh: OS <<
"High";
break;
1150 case ImmTyBLGP: OS <<
"BLGP";
break;
1151 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1152 case ImmTyABID: OS <<
"ABID";
break;
1153 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1154 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1155 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1156 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1157 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1158 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1159 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1160 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1161 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1162 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1163 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1164 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1165 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1166 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1167 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1168 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1173 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1177 <<
" mods: " <<
Reg.Mods <<
'>';
1181 if (getImmTy() != ImmTyNone) {
1182 OS <<
" type: "; printImmTy(OS, getImmTy());
1184 OS <<
" mods: " <<
Imm.Mods <<
'>';
1197 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1198 int64_t Val, SMLoc Loc,
1199 ImmTy
Type = ImmTyNone,
1200 bool IsFPImm =
false) {
1201 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1203 Op->Imm.IsFPImm = IsFPImm;
1205 Op->Imm.Mods = Modifiers();
1211 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1212 StringRef Str, SMLoc Loc,
1213 bool HasExplicitEncodingSize =
true) {
1214 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1215 Res->Tok.Data = Str.data();
1216 Res->Tok.Length = Str.size();
1217 Res->StartLoc = Loc;
1222 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1223 MCRegister
Reg, SMLoc S, SMLoc
E) {
1224 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1225 Op->Reg.RegNo =
Reg;
1226 Op->Reg.Mods = Modifiers();
1232 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1233 const class MCExpr *Expr, SMLoc S) {
1234 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1243 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1254class KernelScopeInfo {
1255 int SgprIndexUnusedMin = -1;
1256 int VgprIndexUnusedMin = -1;
1257 int AgprIndexUnusedMin = -1;
1258 MCContext *Ctx =
nullptr;
1259 MCSubtargetInfo
const *MSTI =
nullptr;
1261 void usesSgprAt(
int i) {
1262 if (i >= SgprIndexUnusedMin) {
1263 SgprIndexUnusedMin = ++i;
1266 Ctx->getOrCreateSymbol(Twine(
".kernel.sgpr_count"));
1272 void usesVgprAt(
int i) {
1273 if (i >= VgprIndexUnusedMin) {
1274 VgprIndexUnusedMin = ++i;
1277 Ctx->getOrCreateSymbol(Twine(
".kernel.vgpr_count"));
1279 VgprIndexUnusedMin);
1285 void usesAgprAt(
int i) {
1290 if (i >= AgprIndexUnusedMin) {
1291 AgprIndexUnusedMin = ++i;
1294 Ctx->getOrCreateSymbol(Twine(
".kernel.agpr_count"));
1299 Ctx->getOrCreateSymbol(Twine(
".kernel.vgpr_count"));
1301 VgprIndexUnusedMin);
1308 KernelScopeInfo() =
default;
1312 MSTI = Ctx->getSubtargetInfo();
1314 usesSgprAt(SgprIndexUnusedMin = -1);
1315 usesVgprAt(VgprIndexUnusedMin = -1);
1317 usesAgprAt(AgprIndexUnusedMin = -1);
1321 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1322 unsigned RegWidth) {
1325 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1328 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1331 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1340 MCAsmParser &Parser;
1342 unsigned ForcedEncodingSize = 0;
1343 bool ForcedDPP =
false;
1344 bool ForcedSDWA =
false;
1345 KernelScopeInfo KernelScope;
1350#define GET_ASSEMBLER_HEADER
1351#include "AMDGPUGenAsmMatcher.inc"
1356 void createConstantSymbol(
StringRef Id, int64_t Val);
1358 bool ParseAsAbsoluteExpression(
uint32_t &Ret);
1376 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1377 std::optional<bool> EnableWavefrontSize32,
1381 bool ParseDirectiveAMDGCNTarget();
1382 bool ParseDirectiveAMDHSACodeObjectVersion();
1383 bool ParseDirectiveAMDHSAKernel();
1385 bool ParseDirectiveAMDKernelCodeT();
1388 bool ParseDirectiveAMDGPUHsaKernel();
1390 bool ParseDirectiveISAVersion();
1391 bool ParseDirectiveHSAMetadata();
1392 bool ParseDirectivePALMetadataBegin();
1393 bool ParseDirectivePALMetadata();
1394 bool ParseDirectiveAMDGPULDS();
1398 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1399 const char *AssemblerDirectiveEnd,
1400 std::string &CollectString);
1402 bool AddNextRegisterToList(
MCRegister &
Reg,
unsigned &RegWidth,
1404 bool ParseAMDGPURegister(RegisterKind &RegKind,
MCRegister &
Reg,
1405 unsigned &RegNum,
unsigned &RegWidth,
1406 bool RestoreOnFailure =
false);
1407 bool ParseAMDGPURegister(RegisterKind &RegKind,
MCRegister &
Reg,
1408 unsigned &RegNum,
unsigned &RegWidth,
1410 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1413 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1416 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1419 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &
SubReg);
1420 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1425 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1426 void initializeGprCountSymbol(RegisterKind RegKind);
1427 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1434 OperandMode_Default,
1438 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1440 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1441 const MCInstrInfo &MII,
1442 const MCTargetOptions &
Options)
1443 : MCTargetAsmParser(
Options, STI, MII), Parser(_Parser) {
1446 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1450 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1451 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1452 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1454 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1455 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1456 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1459 initializeGprCountSymbol(IS_VGPR);
1460 initializeGprCountSymbol(IS_SGPR);
1465 createConstantSymbol(Symbol, Code);
1467 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1468 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1469 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1541 bool hasInv2PiInlineImm()
const {
1542 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1545 bool has64BitLiterals()
const {
1546 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1549 bool hasFlatOffsets()
const {
1550 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1553 bool hasTrue16Insts()
const {
1554 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1558 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1561 bool hasSGPR102_SGPR103()
const {
1565 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1567 bool hasIntClamp()
const {
1568 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1571 bool hasPartialNSAEncoding()
const {
1572 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1575 bool hasGloballyAddressableScratch()
const {
1576 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1589 AMDGPUTargetStreamer &getTargetStreamer() {
1590 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1591 return static_cast<AMDGPUTargetStreamer &
>(TS);
1594 const MCRegisterInfo *getMRI()
const {
1597 return const_cast<AMDGPUAsmParser*
>(
this)->
getContext().getRegisterInfo();
1600 const MCInstrInfo *getMII()
const {
1604 const FeatureBitset &getFeatureBits()
const {
1605 return getSTI().getFeatureBits();
1608 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1609 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1610 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1612 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1613 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1614 bool isForcedDPP()
const {
return ForcedDPP; }
1615 bool isForcedSDWA()
const {
return ForcedSDWA; }
1616 ArrayRef<unsigned> getMatchedVariants()
const;
1617 StringRef getMatchedVariantName()
const;
1619 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1620 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1621 bool RestoreOnFailure);
1622 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1623 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1624 SMLoc &EndLoc)
override;
1625 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1626 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1627 unsigned Kind)
override;
1628 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1630 uint64_t &ErrorInfo,
1631 bool MatchingInlineAsm)
override;
1632 bool ParseDirective(AsmToken DirectiveID)
override;
1634 OperandMode
Mode = OperandMode_Default);
1635 StringRef parseMnemonicSuffix(StringRef Name);
1636 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
1642 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1646 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1647 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1649 ParseStatus parseOperandArrayWithPrefix(
1651 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1652 bool (*ConvertResult)(int64_t &) =
nullptr);
1656 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1657 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1661 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1665 ArrayRef<const char *> Ids,
1669 ArrayRef<const char *> Ids,
1670 AMDGPUOperand::ImmTy
Type);
1673 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1674 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1675 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1676 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1677 bool parseSP3NegModifier();
1679 LitModifier Lit = LitModifier::None);
1682 LitModifier Lit = LitModifier::None);
1684 bool AllowImm =
true);
1686 bool AllowImm =
true);
1691 AMDGPUOperand::ImmTy ImmTy);
1696 AMDGPUOperand::ImmTy
Type);
1700 AMDGPUOperand::ImmTy
Type);
1704 AMDGPUOperand::ImmTy
Type);
1708 ParseStatus parseDfmtNfmt(int64_t &
Format);
1709 ParseStatus parseUfmt(int64_t &
Format);
1710 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1712 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1715 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1716 ParseStatus parseNumericFormat(int64_t &
Format);
1720 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1721 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1725 bool parseCnt(int64_t &IntVal);
1728 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1729 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1732 bool parseDelay(int64_t &Delay);
1738 struct OperandInfoTy {
1741 bool IsSymbolic =
false;
1742 bool IsDefined =
false;
1744 OperandInfoTy(int64_t Val) : Val(Val) {}
1747 struct StructuredOpField : OperandInfoTy {
1751 bool IsDefined =
false;
1753 StructuredOpField(StringLiteral Id, StringLiteral Desc,
unsigned Width,
1755 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1756 virtual ~StructuredOpField() =
default;
1758 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1759 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1763 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1765 return Error(Parser,
"not supported on this GPU");
1767 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1775 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1776 bool validateSendMsg(
const OperandInfoTy &Msg,
1777 const OperandInfoTy &
Op,
1778 const OperandInfoTy &Stream);
1780 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1781 OperandInfoTy &Width);
1783 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1790 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1792 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1802 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1805 bool tryVOPD(
const MCInst &Inst);
1806 bool tryVOPD3(
const MCInst &Inst);
1807 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1809 bool validateIntClampSupported(
const MCInst &Inst);
1810 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1811 bool validateMIMGGatherDMask(
const MCInst &Inst);
1813 bool validateMIMGDataSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1814 bool validateMIMGAddrSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1815 bool validateMIMGD16(
const MCInst &Inst);
1817 bool validateTensorR128(
const MCInst &Inst);
1818 bool validateMIMGMSAA(
const MCInst &Inst);
1819 bool validateOpSel(
const MCInst &Inst);
1820 bool validateTrue16OpSel(
const MCInst &Inst);
1821 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1823 bool validateVccOperand(MCRegister
Reg)
const;
1828 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1829 bool validateVGPRAlign(
const MCInst &Inst)
const;
1833 bool validateDivScale(
const MCInst &Inst);
1836 const SMLoc &IDLoc);
1838 const unsigned CPol);
1843 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1844 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1845 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1846 unsigned findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1848 bool isSupportedMnemo(StringRef Mnemo,
1849 const FeatureBitset &FBS);
1850 bool isSupportedMnemo(StringRef Mnemo,
1851 const FeatureBitset &FBS,
1852 ArrayRef<unsigned> Variants);
1853 bool checkUnsupportedInstruction(StringRef Name,
const SMLoc &IDLoc);
1855 bool isId(
const StringRef Id)
const;
1856 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1858 StringRef getId()
const;
1859 bool trySkipId(
const StringRef Id);
1860 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1864 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1865 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1871 StringRef getTokenStr()
const;
1872 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1874 SMLoc getLoc()
const;
1878 void onBeginOfFile()
override;
1879 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1890 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1891 const unsigned MaxVal,
const Twine &ErrMsg,
1893 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1894 const unsigned MinVal,
1895 const unsigned MaxVal,
1896 const StringRef ErrMsg);
1898 bool parseSwizzleOffset(int64_t &
Imm);
1899 bool parseSwizzleMacro(int64_t &
Imm);
1900 bool parseSwizzleQuadPerm(int64_t &
Imm);
1901 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1902 bool parseSwizzleBroadcast(int64_t &
Imm);
1903 bool parseSwizzleSwap(int64_t &
Imm);
1904 bool parseSwizzleReverse(int64_t &
Imm);
1905 bool parseSwizzleFFT(int64_t &
Imm);
1906 bool parseSwizzleRotate(int64_t &
Imm);
1909 int64_t parseGPRIdxMacro();
1917 OptionalImmIndexMap &OptionalIdx);
1926 OptionalImmIndexMap &OptionalIdx);
1928 OptionalImmIndexMap &OptionalIdx);
1933 bool parseDimId(
unsigned &Encoding);
1935 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1939 int64_t parseDPPCtrlSel(StringRef Ctrl);
1940 int64_t parseDPPCtrlPerm();
1946 bool IsDPP8 =
false);
1952 AMDGPUOperand::ImmTy
Type);
1960 uint64_t BasicInstType,
1961 bool SkipDstVcc =
false,
1962 bool SkipSrcVcc =
false);
2070bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2080 if (!isImmTy(ImmTyNone)) {
2091 if (type == MVT::f64 || type == MVT::i64) {
2093 AsmParser->hasInv2PiInlineImm());
2096 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2115 APFloat::rmNearestTiesToEven, &Lost);
2122 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2124 AsmParser->hasInv2PiInlineImm());
2129 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2130 AsmParser->hasInv2PiInlineImm());
2134 if (type == MVT::f64 || type == MVT::i64) {
2136 AsmParser->hasInv2PiInlineImm());
2145 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2146 type, AsmParser->hasInv2PiInlineImm());
2150 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2151 AsmParser->hasInv2PiInlineImm());
2154bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2156 if (!isImmTy(ImmTyNone)) {
2161 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2166 if (type == MVT::f64 && hasFPModifiers()) {
2186 if (type == MVT::f64) {
2191 if (type == MVT::i64) {
2204 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2205 : (type == MVT::v2i16) ? MVT::f32
2206 : (type == MVT::v2f32) ? MVT::f32
2209 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2213bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2214 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2217bool AMDGPUOperand::isVRegWithInputMods()
const {
2218 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2220 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2221 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2224template <
bool IsFake16>
2225bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2226 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2227 : AMDGPU::VGPR_16_Lo128RegClassID);
2230template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2231 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2232 : AMDGPU::VGPR_16RegClassID);
2235bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2236 if (AsmParser->isVI())
2238 if (AsmParser->isGFX9Plus())
2239 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2243bool AMDGPUOperand::isSDWAFP16Operand()
const {
2244 return isSDWAOperand(MVT::f16);
2247bool AMDGPUOperand::isSDWAFP32Operand()
const {
2248 return isSDWAOperand(MVT::f32);
2251bool AMDGPUOperand::isSDWAInt16Operand()
const {
2252 return isSDWAOperand(MVT::i16);
2255bool AMDGPUOperand::isSDWAInt32Operand()
const {
2256 return isSDWAOperand(MVT::i32);
2259bool AMDGPUOperand::isBoolReg()
const {
2260 auto FB = AsmParser->getFeatureBits();
2261 return isReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrc_b64()) ||
2262 (FB[AMDGPU::FeatureWavefrontSize32] && isSCSrc_b32()));
2265uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2267 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2270 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2282void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2292 addLiteralImmOperand(Inst,
Imm.Val,
2294 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2296 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2301void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2302 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2307 if (ApplyModifiers) {
2310 Val = applyInputFPModifiers(Val,
Size);
2314 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2324 AsmParser->hasInv2PiInlineImm())) {
2332 bool HasMandatoryLiteral =
2335 if (
Literal.getLoBits(32) != 0 &&
2336 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2337 !HasMandatoryLiteral) {
2338 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2340 "Can't encode literal as exact 64-bit floating-point operand. "
2341 "Low 32-bits will be set to zero");
2342 Val &= 0xffffffff00000000u;
2362 if (AsmParser->hasInv2PiInlineImm() &&
Literal == 0x3fc45f306725feed) {
2396 APFloat::rmNearestTiesToEven, &lost);
2400 uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2441 if (!AsmParser->has64BitLiterals() ||
2442 getModifiers().Lit == LitModifier::Lit)
2458 if (!AsmParser->has64BitLiterals()) {
2459 Val =
static_cast<uint64_t
>(Val) << 32;
2466 if (getModifiers().Lit == LitModifier::Lit ||
2467 (getModifiers().Lit != LitModifier::Lit64 &&
2469 Val =
static_cast<uint64_t
>(Val) << 32;
2491 getModifiers().Lit != LitModifier::Lit64)
2502void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2507bool AMDGPUOperand::isInlineValue()
const {
2515void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2526 if (Is == IS_VGPR) {
2530 return AMDGPU::VGPR_32RegClassID;
2532 return AMDGPU::VReg_64RegClassID;
2534 return AMDGPU::VReg_96RegClassID;
2536 return AMDGPU::VReg_128RegClassID;
2538 return AMDGPU::VReg_160RegClassID;
2540 return AMDGPU::VReg_192RegClassID;
2542 return AMDGPU::VReg_224RegClassID;
2544 return AMDGPU::VReg_256RegClassID;
2546 return AMDGPU::VReg_288RegClassID;
2548 return AMDGPU::VReg_320RegClassID;
2550 return AMDGPU::VReg_352RegClassID;
2552 return AMDGPU::VReg_384RegClassID;
2554 return AMDGPU::VReg_512RegClassID;
2556 return AMDGPU::VReg_1024RegClassID;
2558 }
else if (Is == IS_TTMP) {
2562 return AMDGPU::TTMP_32RegClassID;
2564 return AMDGPU::TTMP_64RegClassID;
2566 return AMDGPU::TTMP_128RegClassID;
2568 return AMDGPU::TTMP_256RegClassID;
2570 return AMDGPU::TTMP_512RegClassID;
2572 }
else if (Is == IS_SGPR) {
2576 return AMDGPU::SGPR_32RegClassID;
2578 return AMDGPU::SGPR_64RegClassID;
2580 return AMDGPU::SGPR_96RegClassID;
2582 return AMDGPU::SGPR_128RegClassID;
2584 return AMDGPU::SGPR_160RegClassID;
2586 return AMDGPU::SGPR_192RegClassID;
2588 return AMDGPU::SGPR_224RegClassID;
2590 return AMDGPU::SGPR_256RegClassID;
2592 return AMDGPU::SGPR_288RegClassID;
2594 return AMDGPU::SGPR_320RegClassID;
2596 return AMDGPU::SGPR_352RegClassID;
2598 return AMDGPU::SGPR_384RegClassID;
2600 return AMDGPU::SGPR_512RegClassID;
2602 }
else if (Is == IS_AGPR) {
2606 return AMDGPU::AGPR_32RegClassID;
2608 return AMDGPU::AReg_64RegClassID;
2610 return AMDGPU::AReg_96RegClassID;
2612 return AMDGPU::AReg_128RegClassID;
2614 return AMDGPU::AReg_160RegClassID;
2616 return AMDGPU::AReg_192RegClassID;
2618 return AMDGPU::AReg_224RegClassID;
2620 return AMDGPU::AReg_256RegClassID;
2622 return AMDGPU::AReg_288RegClassID;
2624 return AMDGPU::AReg_320RegClassID;
2626 return AMDGPU::AReg_352RegClassID;
2628 return AMDGPU::AReg_384RegClassID;
2630 return AMDGPU::AReg_512RegClassID;
2632 return AMDGPU::AReg_1024RegClassID;
2640 .
Case(
"exec", AMDGPU::EXEC)
2641 .
Case(
"vcc", AMDGPU::VCC)
2642 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2643 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2644 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2645 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2646 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2647 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2648 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2649 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2650 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2651 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2652 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2653 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2654 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2655 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2656 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2657 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2658 .
Case(
"m0", AMDGPU::M0)
2659 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2660 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2661 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2662 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2663 .
Case(
"scc", AMDGPU::SRC_SCC)
2664 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2665 .
Case(
"tba", AMDGPU::TBA)
2666 .
Case(
"tma", AMDGPU::TMA)
2667 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2668 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2669 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2670 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2671 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2672 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2673 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2674 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2675 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2676 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2677 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2678 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2679 .
Case(
"pc", AMDGPU::PC_REG)
2680 .
Case(
"null", AMDGPU::SGPR_NULL)
2684bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2685 SMLoc &EndLoc,
bool RestoreOnFailure) {
2686 auto R = parseRegister();
2687 if (!R)
return true;
2689 RegNo =
R->getReg();
2690 StartLoc =
R->getStartLoc();
2691 EndLoc =
R->getEndLoc();
2695bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2697 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2700ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2702 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2703 bool PendingErrors = getParser().hasPendingError();
2704 getParser().clearPendingErrors();
2712bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2713 RegisterKind RegKind,
2714 MCRegister Reg1, SMLoc Loc) {
2717 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2722 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2723 Reg = AMDGPU::FLAT_SCR;
2727 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2728 Reg = AMDGPU::XNACK_MASK;
2732 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2737 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2742 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2747 Error(Loc,
"register does not fit in the list");
2753 if (Reg1 !=
Reg + RegWidth / 32) {
2754 Error(Loc,
"registers in a list must have consecutive indices");
2772 {{
"ttmp"}, IS_TTMP},
2778 return Kind == IS_VGPR ||
2786 if (Str.starts_with(
Reg.Name))
2792 return !Str.getAsInteger(10, Num);
2796AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2797 const AsmToken &NextToken)
const {
2812 StringRef RegSuffix = Str.substr(
RegName.size());
2813 if (!RegSuffix.
empty()) {
2831AMDGPUAsmParser::isRegister()
2833 return isRegister(
getToken(), peekToken());
2836MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2837 unsigned SubReg,
unsigned RegWidth,
2841 unsigned AlignSize = 1;
2842 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2848 if (RegNum % AlignSize != 0) {
2849 Error(Loc,
"invalid register alignment");
2850 return MCRegister();
2853 unsigned RegIdx = RegNum / AlignSize;
2856 Error(Loc,
"invalid or unsupported register size");
2857 return MCRegister();
2861 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2862 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2863 Error(Loc,
"register index is out of range");
2864 return AMDGPU::NoRegister;
2867 if (RegKind == IS_VGPR && !
isGFX1250() && RegIdx + RegWidth / 32 > 256) {
2868 Error(Loc,
"register index is out of range");
2869 return MCRegister();
2885bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2887 int64_t RegLo, RegHi;
2891 SMLoc FirstIdxLoc = getLoc();
2898 SecondIdxLoc = getLoc();
2909 Error(FirstIdxLoc,
"invalid register index");
2914 Error(SecondIdxLoc,
"invalid register index");
2918 if (RegLo > RegHi) {
2919 Error(FirstIdxLoc,
"first register index should not exceed second index");
2923 if (RegHi == RegLo) {
2924 StringRef RegSuffix = getTokenStr();
2925 if (RegSuffix ==
".l") {
2928 }
else if (RegSuffix ==
".h") {
2934 Num =
static_cast<unsigned>(RegLo);
2935 RegWidth = 32 * ((RegHi - RegLo) + 1);
2940MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2943 SmallVectorImpl<AsmToken> &Tokens) {
2949 RegKind = IS_SPECIAL;
2956MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2959 SmallVectorImpl<AsmToken> &Tokens) {
2961 StringRef
RegName = getTokenStr();
2962 auto Loc = getLoc();
2966 Error(Loc,
"invalid register name");
2967 return MCRegister();
2975 unsigned SubReg = NoSubRegister;
2976 if (!RegSuffix.
empty()) {
2984 Error(Loc,
"invalid register index");
2985 return MCRegister();
2990 if (!ParseRegRange(RegNum, RegWidth,
SubReg))
2991 return MCRegister();
2994 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
2997MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
2998 unsigned &RegNum,
unsigned &RegWidth,
2999 SmallVectorImpl<AsmToken> &Tokens) {
3001 auto ListLoc = getLoc();
3004 "expected a register or a list of registers")) {
3005 return MCRegister();
3010 auto Loc = getLoc();
3011 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3012 return MCRegister();
3013 if (RegWidth != 32) {
3014 Error(Loc,
"expected a single 32-bit register");
3015 return MCRegister();
3019 RegisterKind NextRegKind;
3021 unsigned NextRegNum, NextRegWidth;
3024 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3025 NextRegNum, NextRegWidth,
3027 return MCRegister();
3029 if (NextRegWidth != 32) {
3030 Error(Loc,
"expected a single 32-bit register");
3031 return MCRegister();
3033 if (NextRegKind != RegKind) {
3034 Error(Loc,
"registers in a list must be of the same kind");
3035 return MCRegister();
3037 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3038 return MCRegister();
3042 "expected a comma or a closing square bracket")) {
3043 return MCRegister();
3047 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3052bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3053 MCRegister &
Reg,
unsigned &RegNum,
3055 SmallVectorImpl<AsmToken> &Tokens) {
3056 auto Loc = getLoc();
3060 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3062 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3064 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3069 assert(Parser.hasPendingError());
3073 if (!subtargetHasRegister(*
TRI,
Reg)) {
3074 if (
Reg == AMDGPU::SGPR_NULL) {
3075 Error(Loc,
"'null' operand is not supported on this GPU");
3078 " register not available on this GPU");
3086bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3087 MCRegister &
Reg,
unsigned &RegNum,
3089 bool RestoreOnFailure ) {
3093 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3094 if (RestoreOnFailure) {
3095 while (!Tokens.
empty()) {
3104std::optional<StringRef>
3105AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3108 return StringRef(
".amdgcn.next_free_vgpr");
3110 return StringRef(
".amdgcn.next_free_sgpr");
3112 return std::nullopt;
3116void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3117 auto SymbolName = getGprCountSymbolName(RegKind);
3118 assert(SymbolName &&
"initializing invalid register kind");
3124bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3125 unsigned DwordRegIndex,
3126 unsigned RegWidth) {
3131 auto SymbolName = getGprCountSymbolName(RegKind);
3136 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3140 return !
Error(getLoc(),
3141 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3145 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3147 if (OldCount <= NewMax)
3153std::unique_ptr<AMDGPUOperand>
3154AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3156 SMLoc StartLoc = Tok.getLoc();
3157 SMLoc EndLoc = Tok.getEndLoc();
3158 RegisterKind RegKind;
3160 unsigned RegNum, RegWidth;
3162 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3166 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3169 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3170 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3174 bool HasSP3AbsModifier, LitModifier Lit) {
3177 if (isRegister() || isModifier())
3180 if (Lit == LitModifier::None) {
3181 if (trySkipId(
"lit"))
3182 Lit = LitModifier::Lit;
3183 else if (trySkipId(
"lit64"))
3184 Lit = LitModifier::Lit64;
3186 if (Lit != LitModifier::None) {
3189 ParseStatus S = parseImm(
Operands, HasSP3AbsModifier, Lit);
3198 const auto& NextTok = peekToken();
3201 bool Negate =
false;
3209 AMDGPUOperand::Modifiers Mods;
3217 StringRef Num = getTokenStr();
3220 APFloat RealVal(APFloat::IEEEdouble());
3221 auto roundMode = APFloat::rmNearestTiesToEven;
3222 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3225 RealVal.changeSign();
3228 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3229 AMDGPUOperand::ImmTyNone,
true));
3230 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3231 Op.setModifiers(Mods);
3240 if (HasSP3AbsModifier) {
3249 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3252 if (Parser.parseExpression(Expr))
3256 if (Expr->evaluateAsAbsolute(IntVal)) {
3257 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3258 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3259 Op.setModifiers(Mods);
3261 if (Lit != LitModifier::None)
3263 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3276 if (
auto R = parseRegister()) {
3285 bool HasSP3AbsMod, LitModifier Lit) {
3286 ParseStatus Res = parseReg(
Operands);
3291 return parseImm(
Operands, HasSP3AbsMod, Lit);
3295AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3298 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3304AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3309AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3310 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3314AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3315 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3332AMDGPUAsmParser::isModifier() {
3335 AsmToken NextToken[2];
3336 peekTokens(NextToken);
3338 return isOperandModifier(Tok, NextToken[0]) ||
3339 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3340 isOpcodeModifierWithVal(Tok, NextToken[0]);
3366AMDGPUAsmParser::parseSP3NegModifier() {
3368 AsmToken NextToken[2];
3369 peekTokens(NextToken);
3372 (isRegister(NextToken[0], NextToken[1]) ||
3374 isId(NextToken[0],
"abs"))) {
3391 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3393 SP3Neg = parseSP3NegModifier();
3396 Neg = trySkipId(
"neg");
3398 return Error(Loc,
"expected register or immediate");
3402 Abs = trySkipId(
"abs");
3406 LitModifier Lit = LitModifier::None;
3407 if (trySkipId(
"lit")) {
3408 Lit = LitModifier::Lit;
3411 }
else if (trySkipId(
"lit64")) {
3412 Lit = LitModifier::Lit64;
3415 if (!has64BitLiterals())
3416 return Error(Loc,
"lit64 is not supported on this GPU");
3422 return Error(Loc,
"expected register or immediate");
3426 Res = parseRegOrImm(
Operands, SP3Abs, Lit);
3431 return (SP3Neg || Neg || SP3Abs || Abs || Lit != LitModifier::None)
3435 if (Lit != LitModifier::None && !
Operands.back()->isImm())
3436 Error(Loc,
"expected immediate with lit modifier");
3438 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3444 if (Lit != LitModifier::None &&
3448 AMDGPUOperand::Modifiers Mods;
3449 Mods.Abs = Abs || SP3Abs;
3450 Mods.Neg = Neg || SP3Neg;
3453 if (Mods.hasFPModifiers() || Lit != LitModifier::None) {
3454 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3456 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3457 Op.setModifiers(Mods);
3465 bool Sext = trySkipId(
"sext");
3466 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3481 AMDGPUOperand::Modifiers Mods;
3484 if (Mods.hasIntModifiers()) {
3485 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3487 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3488 Op.setModifiers(Mods);
3495 return parseRegOrImmWithFPInputMods(
Operands,
false);
3499 return parseRegOrImmWithIntInputMods(
Operands,
false);
3503 auto Loc = getLoc();
3504 if (trySkipId(
"off")) {
3505 Operands.push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3506 AMDGPUOperand::ImmTyOff,
false));
3513 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3522unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3529 return Match_InvalidOperand;
3531 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3532 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3535 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3537 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3538 return Match_InvalidOperand;
3546 if (tryAnotherVOPDEncoding(Inst))
3547 return Match_InvalidOperand;
3549 return Match_Success;
3553 static const unsigned Variants[] = {
3563ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3564 if (isForcedDPP() && isForcedVOP3()) {
3568 if (getForcedEncodingSize() == 32) {
3573 if (isForcedVOP3()) {
3578 if (isForcedSDWA()) {
3584 if (isForcedDPP()) {
3592StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3593 if (isForcedDPP() && isForcedVOP3())
3596 if (getForcedEncodingSize() == 32)
3611unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3615 case AMDGPU::FLAT_SCR:
3617 case AMDGPU::VCC_LO:
3618 case AMDGPU::VCC_HI:
3625 return AMDGPU::NoRegister;
3632bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3633 unsigned OpIdx)
const {
3643 int64_t Val = MO.
getImm();
3687unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3693 case AMDGPU::V_LSHLREV_B64_e64:
3694 case AMDGPU::V_LSHLREV_B64_gfx10:
3695 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3696 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3697 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3698 case AMDGPU::V_LSHRREV_B64_e64:
3699 case AMDGPU::V_LSHRREV_B64_gfx10:
3700 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3701 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3702 case AMDGPU::V_ASHRREV_I64_e64:
3703 case AMDGPU::V_ASHRREV_I64_gfx10:
3704 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3705 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3706 case AMDGPU::V_LSHL_B64_e64:
3707 case AMDGPU::V_LSHR_B64_e64:
3708 case AMDGPU::V_ASHR_I64_e64:
3721 bool AddMandatoryLiterals =
false) {
3724 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3728 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3730 return {getNamedOperandIdx(Opcode, OpName::src0X),
3731 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3732 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3733 getNamedOperandIdx(Opcode, OpName::src0Y),
3734 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3735 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3740 return {getNamedOperandIdx(Opcode, OpName::src0),
3741 getNamedOperandIdx(Opcode, OpName::src1),
3742 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3745bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3748 return !isInlineConstant(Inst,
OpIdx);
3755 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3766 const unsigned Opcode = Inst.
getOpcode();
3767 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3770 if (!LaneSelOp.
isReg())
3773 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3776bool AMDGPUAsmParser::validateConstantBusLimitations(
3778 const unsigned Opcode = Inst.
getOpcode();
3779 const MCInstrDesc &
Desc = MII.
get(Opcode);
3780 MCRegister LastSGPR;
3781 unsigned ConstantBusUseCount = 0;
3782 unsigned NumLiterals = 0;
3783 unsigned LiteralSize;
3785 if (!(
Desc.TSFlags &
3800 SmallDenseSet<unsigned> SGPRsUsed;
3801 unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3802 if (SGPRUsed != AMDGPU::NoRegister) {
3803 SGPRsUsed.
insert(SGPRUsed);
3804 ++ConstantBusUseCount;
3809 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3811 for (
int OpIdx : OpIndices) {
3816 if (usesConstantBus(Inst,
OpIdx)) {
3825 if (SGPRsUsed.
insert(LastSGPR).second) {
3826 ++ConstantBusUseCount;
3846 if (NumLiterals == 0) {
3849 }
else if (LiteralSize !=
Size) {
3855 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3857 "invalid operand (violates constant bus restrictions)");
3864std::optional<unsigned>
3865AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3867 const unsigned Opcode = Inst.
getOpcode();
3873 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3874 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3882 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3883 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3884 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250;
3888 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3889 int I = getNamedOperandIdx(Opcode, OpName);
3893 int64_t
Imm =
Op.getImm();
3899 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3900 OpName::vsrc2Y, OpName::imm}) {
3901 int I = getNamedOperandIdx(Opcode, OpName);
3911 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3912 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3914 return InvalidCompOprIdx;
3917bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
3924 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand :
Operands) {
3925 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
3926 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
3928 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
3932 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
3933 if (!InvalidCompOprIdx.has_value())
3936 auto CompOprIdx = *InvalidCompOprIdx;
3939 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3940 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3943 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
3944 if (CompOprIdx == VOPD::Component::DST) {
3946 Error(Loc,
"dst registers must be distinct");
3948 Error(Loc,
"one dst register must be even and the other odd");
3950 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3951 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
3952 " operands must use different VGPR banks");
3960bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
3962 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
3963 if (!InvalidCompOprIdx.has_value())
3967 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
3968 if (InvalidCompOprIdx.has_value()) {
3973 if (*InvalidCompOprIdx == VOPD::Component::DST)
3986bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
3987 const unsigned Opcode = Inst.
getOpcode();
4002 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4003 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4004 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4005 int I = getNamedOperandIdx(Opcode, OpName);
4012 return !tryVOPD3(Inst);
4017bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4018 const unsigned Opcode = Inst.
getOpcode();
4023 return tryVOPD(Inst);
4024 return tryVOPD3(Inst);
4027bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4033 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4044bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
4045 const SMLoc &IDLoc) {
4053 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4054 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4055 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4064 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4069 bool IsPackedD16 =
false;
4073 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4074 IsPackedD16 = D16Idx >= 0;
4079 if ((VDataSize / 4) ==
DataSize + TFESize)
4084 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4086 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4088 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4092bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst,
4093 const SMLoc &IDLoc) {
4102 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4104 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4106 ? AMDGPU::OpName::srsrc
4107 : AMDGPU::OpName::rsrc;
4108 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4109 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4110 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4114 assert(SrsrcIdx > VAddr0Idx);
4117 if (BaseOpcode->
BVH) {
4118 if (IsA16 == BaseOpcode->
A16)
4120 Error(IDLoc,
"image address size does not match a16");
4126 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4127 unsigned ActualAddrSize =
4128 IsNSA ? SrsrcIdx - VAddr0Idx
4131 unsigned ExpectedAddrSize =
4135 if (hasPartialNSAEncoding() &&
4138 int VAddrLastIdx = SrsrcIdx - 1;
4139 unsigned VAddrLastSize =
4142 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4145 if (ExpectedAddrSize > 12)
4146 ExpectedAddrSize = 16;
4151 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4155 if (ActualAddrSize == ExpectedAddrSize)
4158 Error(IDLoc,
"image address size does not match dim and a16");
4162bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4169 if (!
Desc.mayLoad() || !
Desc.mayStore())
4172 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4179 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4182bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4190 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4198 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4201bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4216 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4217 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4224bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4232 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4235 if (!BaseOpcode->
MSAA)
4238 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4244 return DimInfo->
MSAA;
4250 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4251 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4252 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4262bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4271 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4274 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4282 Error(getOperandLoc(
Operands, Src0Idx),
"source operand must be a VGPR");
4286bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4291 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4294 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4297 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4305 "source operand must be either a VGPR or an inline constant");
4312bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4315 const MCInstrDesc &
Desc = MII.
get(Opcode);
4318 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4321 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4325 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4327 "inline constants are not allowed for this operand");
4334bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4342 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4343 if (BlgpIdx != -1) {
4344 if (
const MFMA_F8F6F4_Info *
Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4345 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4355 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4357 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4362 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4364 "wrong register tuple size for blgp value " + Twine(BLGP));
4372 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4376 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4380 MCRegister Src2Reg = Src2.
getReg();
4382 if (Src2Reg == DstReg)
4386 if (
TRI->getRegClass(
Desc.operands()[0].RegClass).getSizeInBits() <= 128)
4389 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4391 "source 2 operand must not partially overlap with dst");
4398bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4402 case V_DIV_SCALE_F32_gfx6_gfx7:
4403 case V_DIV_SCALE_F32_vi:
4404 case V_DIV_SCALE_F32_gfx10:
4405 case V_DIV_SCALE_F64_gfx6_gfx7:
4406 case V_DIV_SCALE_F64_vi:
4407 case V_DIV_SCALE_F64_gfx10:
4413 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4414 AMDGPU::OpName::src2_modifiers,
4415 AMDGPU::OpName::src2_modifiers}) {
4426bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4434 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4443bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4450 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4458 case AMDGPU::V_SUBREV_F32_e32:
4459 case AMDGPU::V_SUBREV_F32_e64:
4460 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4461 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4462 case AMDGPU::V_SUBREV_F32_e32_vi:
4463 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4464 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4465 case AMDGPU::V_SUBREV_F32_e64_vi:
4467 case AMDGPU::V_SUBREV_CO_U32_e32:
4468 case AMDGPU::V_SUBREV_CO_U32_e64:
4469 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4470 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4472 case AMDGPU::V_SUBBREV_U32_e32:
4473 case AMDGPU::V_SUBBREV_U32_e64:
4474 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4475 case AMDGPU::V_SUBBREV_U32_e32_vi:
4476 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4477 case AMDGPU::V_SUBBREV_U32_e64_vi:
4479 case AMDGPU::V_SUBREV_U32_e32:
4480 case AMDGPU::V_SUBREV_U32_e64:
4481 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4482 case AMDGPU::V_SUBREV_U32_e32_vi:
4483 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4484 case AMDGPU::V_SUBREV_U32_e64_vi:
4486 case AMDGPU::V_SUBREV_F16_e32:
4487 case AMDGPU::V_SUBREV_F16_e64:
4488 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4489 case AMDGPU::V_SUBREV_F16_e32_vi:
4490 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4491 case AMDGPU::V_SUBREV_F16_e64_vi:
4493 case AMDGPU::V_SUBREV_U16_e32:
4494 case AMDGPU::V_SUBREV_U16_e64:
4495 case AMDGPU::V_SUBREV_U16_e32_vi:
4496 case AMDGPU::V_SUBREV_U16_e64_vi:
4498 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4499 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4500 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4502 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4503 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4505 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4506 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4508 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4509 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4511 case AMDGPU::V_LSHRREV_B32_e32:
4512 case AMDGPU::V_LSHRREV_B32_e64:
4513 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4514 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4515 case AMDGPU::V_LSHRREV_B32_e32_vi:
4516 case AMDGPU::V_LSHRREV_B32_e64_vi:
4517 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4518 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4520 case AMDGPU::V_ASHRREV_I32_e32:
4521 case AMDGPU::V_ASHRREV_I32_e64:
4522 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4523 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4524 case AMDGPU::V_ASHRREV_I32_e32_vi:
4525 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4526 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4527 case AMDGPU::V_ASHRREV_I32_e64_vi:
4529 case AMDGPU::V_LSHLREV_B32_e32:
4530 case AMDGPU::V_LSHLREV_B32_e64:
4531 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4532 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4533 case AMDGPU::V_LSHLREV_B32_e32_vi:
4534 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4535 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4536 case AMDGPU::V_LSHLREV_B32_e64_vi:
4538 case AMDGPU::V_LSHLREV_B16_e32:
4539 case AMDGPU::V_LSHLREV_B16_e64:
4540 case AMDGPU::V_LSHLREV_B16_e32_vi:
4541 case AMDGPU::V_LSHLREV_B16_e64_vi:
4542 case AMDGPU::V_LSHLREV_B16_gfx10:
4544 case AMDGPU::V_LSHRREV_B16_e32:
4545 case AMDGPU::V_LSHRREV_B16_e64:
4546 case AMDGPU::V_LSHRREV_B16_e32_vi:
4547 case AMDGPU::V_LSHRREV_B16_e64_vi:
4548 case AMDGPU::V_LSHRREV_B16_gfx10:
4550 case AMDGPU::V_ASHRREV_I16_e32:
4551 case AMDGPU::V_ASHRREV_I16_e64:
4552 case AMDGPU::V_ASHRREV_I16_e32_vi:
4553 case AMDGPU::V_ASHRREV_I16_e64_vi:
4554 case AMDGPU::V_ASHRREV_I16_gfx10:
4556 case AMDGPU::V_LSHLREV_B64_e64:
4557 case AMDGPU::V_LSHLREV_B64_gfx10:
4558 case AMDGPU::V_LSHLREV_B64_vi:
4560 case AMDGPU::V_LSHRREV_B64_e64:
4561 case AMDGPU::V_LSHRREV_B64_gfx10:
4562 case AMDGPU::V_LSHRREV_B64_vi:
4564 case AMDGPU::V_ASHRREV_I64_e64:
4565 case AMDGPU::V_ASHRREV_I64_gfx10:
4566 case AMDGPU::V_ASHRREV_I64_vi:
4568 case AMDGPU::V_PK_LSHLREV_B16:
4569 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4570 case AMDGPU::V_PK_LSHLREV_B16_vi:
4572 case AMDGPU::V_PK_LSHRREV_B16:
4573 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4574 case AMDGPU::V_PK_LSHRREV_B16_vi:
4575 case AMDGPU::V_PK_ASHRREV_I16:
4576 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4577 case AMDGPU::V_PK_ASHRREV_I16_vi:
4584bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4586 using namespace SIInstrFlags;
4587 const unsigned Opcode = Inst.
getOpcode();
4588 const MCInstrDesc &
Desc = MII.
get(Opcode);
4593 if ((
Desc.TSFlags & Enc) == 0)
4596 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4597 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4601 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4605 "lds_direct is not supported on this GPU");
4611 "lds_direct cannot be used with this instruction");
4615 if (SrcName != OpName::src0) {
4617 "lds_direct may be used as src0 only");
4627 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4628 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4629 if (
Op.isFlatOffset())
4630 return Op.getStartLoc();
4635bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4638 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4644 return validateFlatOffset(Inst,
Operands);
4647 return validateSMEMOffset(Inst,
Operands);
4653 const unsigned OffsetSize = 24;
4654 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4656 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4657 "-bit unsigned offset for buffer ops");
4661 const unsigned OffsetSize = 16;
4662 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4664 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4671bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4678 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4682 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4684 "flat offset modifier is not supported on this GPU");
4691 bool AllowNegative =
4694 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4696 Twine(
"expected a ") +
4697 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4698 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4707 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4708 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4709 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4710 return Op.getStartLoc();
4715bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4725 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4741 ?
"expected a 23-bit unsigned offset for buffer ops"
4742 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4743 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4744 :
"expected a 21-bit signed offset");
4749bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4752 const MCInstrDesc &
Desc = MII.
get(Opcode);
4756 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4757 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4759 const int OpIndices[] = { Src0Idx, Src1Idx };
4761 unsigned NumExprs = 0;
4762 unsigned NumLiterals = 0;
4765 for (
int OpIdx : OpIndices) {
4766 if (
OpIdx == -1)
break;
4771 if (MO.
isImm() && !isInlineConstant(Inst,
OpIdx)) {
4775 if (NumLiterals == 0 || LiteralValue !=
Value) {
4779 }
else if (MO.
isExpr()) {
4785 if (NumLiterals + NumExprs <= 1)
4789 "only one unique literal operand is allowed");
4793bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4796 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4806 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4807 if (OpSelIdx != -1) {
4811 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4812 if (OpSelHiIdx != -1) {
4821 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4831 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4832 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4833 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4834 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4836 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4837 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4843 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4845 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4855 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4856 if (Src2Idx != -1) {
4857 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4867bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4868 if (!hasTrue16Insts())
4870 const MCRegisterInfo *
MRI = getMRI();
4872 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4878 if (OpSelOpValue == 0)
4880 unsigned OpCount = 0;
4881 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4882 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4883 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4888 MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(
Op.getReg())) {
4890 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4891 if (OpSelOpIsHi != VGPRSuffixIsHi)
4900bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4901 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4914 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
4925 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4926 AMDGPU::OpName::src1_modifiers,
4927 AMDGPU::OpName::src2_modifiers};
4929 for (
unsigned i = 0; i < 3; ++i) {
4939bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4942 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
4943 if (DppCtrlIdx >= 0) {
4950 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl,
Operands);
4951 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
4952 :
"DP ALU dpp only supports row_newbcast");
4957 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
4958 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4961 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4963 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4967 "invalid operand for instruction");
4972 "src1 immediate operand invalid for instruction");
4982bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
4983 auto FB = getFeatureBits();
4984 return (FB[AMDGPU::FeatureWavefrontSize64] &&
Reg == AMDGPU::VCC) ||
4985 (FB[AMDGPU::FeatureWavefrontSize32] &&
Reg == AMDGPU::VCC_LO);
4989bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
4992 const MCInstrDesc &
Desc = MII.
get(Opcode);
4993 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
4995 !HasMandatoryLiteral && !
isVOPD(Opcode))
5000 std::optional<unsigned> LiteralOpIdx;
5003 for (
int OpIdx : OpIndices) {
5013 bool IsAnotherLiteral =
false;
5014 if (MO.
isImm() && !isInlineConstant(Inst,
OpIdx)) {
5015 uint64_t
Value =
static_cast<uint64_t
>(MO.
getImm());
5019 HasMandatoryLiteral);
5025 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5027 "invalid operand for instruction");
5031 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5036 }
else if (MO.
isExpr()) {
5038 IsAnotherLiteral =
true;
5041 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5042 !getFeatureBits()[FeatureVOP3Literal]) {
5044 "literal operands are not supported");
5048 if (LiteralOpIdx && IsAnotherLiteral) {
5050 getOperandLoc(
Operands, *LiteralOpIdx)),
5051 "only one unique literal operand is allowed");
5055 if (IsAnotherLiteral)
5056 LiteralOpIdx =
OpIdx;
5079bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5087 ? AMDGPU::OpName::data0
5088 : AMDGPU::OpName::vdata;
5090 const MCRegisterInfo *
MRI = getMRI();
5096 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5100 auto FB = getFeatureBits();
5101 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5102 if (DataAreg < 0 || DstAreg < 0)
5104 return DstAreg == DataAreg;
5107 return DstAreg < 1 && DataAreg < 1;
5110bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5111 auto FB = getFeatureBits();
5112 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5116 const MCRegisterInfo *
MRI = getMRI();
5119 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5122 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5126 case AMDGPU::DS_LOAD_TR6_B96:
5127 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5131 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5132 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5136 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5137 if (VAddrIdx != -1) {
5139 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5140 if ((
Sub - AMDGPU::VGPR0) & 1)
5145 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5146 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5151 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5152 const MCRegisterClass &AGPR32 =
MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
5158 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5172 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
5173 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
5175 return Op.getStartLoc();
5180bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5183 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5186 SMLoc BLGPLoc = getBLGPLoc(
Operands);
5189 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5190 auto FB = getFeatureBits();
5191 bool UsesNeg =
false;
5192 if (FB[AMDGPU::FeatureGFX940Insts]) {
5194 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5195 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5196 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5197 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5202 if (IsNeg == UsesNeg)
5206 UsesNeg ?
"invalid modifier: blgp is not supported"
5207 :
"invalid modifier: neg is not supported");
5212bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5218 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5219 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5220 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5221 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5224 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5227 if (
Reg == AMDGPU::SGPR_NULL)
5230 Error(getOperandLoc(
Operands, Src0Idx),
"src0 must be null");
5234bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5240 return validateGWS(Inst,
Operands);
5245 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5250 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS,
Operands);
5251 Error(S,
"gds modifier is not supported on this GPU");
5259bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5261 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5265 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5266 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5269 const MCRegisterInfo *
MRI = getMRI();
5270 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5272 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5275 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5277 Error(getOperandLoc(
Operands, Data0Pos),
"vgpr must be even aligned");
5284bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5286 const SMLoc &IDLoc) {
5287 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5288 AMDGPU::OpName::cpol);
5296 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5299 Error(S,
"scale_offset is not supported on this GPU");
5302 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5305 Error(S,
"nv is not supported on this GPU");
5310 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5313 Error(S,
"scale_offset is not supported for this instruction");
5317 return validateTHAndScopeBits(Inst,
Operands, CPol);
5322 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5323 Error(S,
"cache policy is not supported for SMRD instructions");
5327 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5336 if (!(TSFlags & AllowSCCModifier)) {
5337 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5341 "scc modifier is not supported for this instruction on this GPU");
5352 :
"instruction must use glc");
5357 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5360 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5362 :
"instruction must not use glc");
5370bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5372 const unsigned CPol) {
5376 const unsigned Opcode = Inst.
getOpcode();
5377 const MCInstrDesc &TID = MII.
get(Opcode);
5380 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5388 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5396 return PrintError(
"invalid th value for SMEM instruction");
5403 return PrintError(
"scope and th combination is not valid");
5409 return PrintError(
"invalid th value for atomic instructions");
5412 return PrintError(
"invalid th value for store instructions");
5415 return PrintError(
"invalid th value for load instructions");
5421bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5424 if (
Desc.mayStore() &&
5426 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE,
Operands);
5428 Error(Loc,
"TFE modifier has no meaning for store instructions");
5436bool AMDGPUAsmParser::validateSetVgprMSB(
const MCInst &Inst,
5438 if (Inst.
getOpcode() != AMDGPU::S_SET_VGPR_MSB_gfx12)
5442 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::simm16);
5444 SMLoc Loc =
Operands[1]->getStartLoc();
5445 Error(Loc,
"s_set_vgpr_msb accepts values in range [0..255]");
5452bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5458 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5459 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5463 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5465 TRI->getRegClass(
Desc.operands()[SrcIdx].RegClass).getSizeInBits();
5470 static const char *FmtNames[] = {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
5471 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
5475 "wrong register tuple size for " + Twine(FmtNames[Fmt]));
5479 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5480 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5483bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst,
5486 if (!validateLdsDirect(Inst,
Operands))
5488 if (!validateTrue16OpSel(Inst)) {
5490 "op_sel operand conflicts with 16-bit operand suffix");
5493 if (!validateSOPLiteral(Inst,
Operands))
5495 if (!validateVOPLiteral(Inst,
Operands)) {
5498 if (!validateConstantBusLimitations(Inst,
Operands)) {
5501 if (!validateVOPD(Inst,
Operands)) {
5504 if (!validateIntClampSupported(Inst)) {
5506 "integer clamping is not supported on this GPU");
5509 if (!validateOpSel(Inst)) {
5511 "invalid op_sel operand");
5514 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5516 "invalid neg_lo operand");
5519 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5521 "invalid neg_hi operand");
5524 if (!validateDPP(Inst,
Operands)) {
5528 if (!validateMIMGD16(Inst)) {
5530 "d16 modifier is not supported on this GPU");
5533 if (!validateMIMGDim(Inst,
Operands)) {
5534 Error(IDLoc,
"missing dim operand");
5537 if (!validateTensorR128(Inst)) {
5539 "instruction must set modifier r128=0");
5542 if (!validateMIMGMSAA(Inst)) {
5544 "invalid dim; must be MSAA type");
5547 if (!validateMIMGDataSize(Inst, IDLoc)) {
5550 if (!validateMIMGAddrSize(Inst, IDLoc))
5552 if (!validateMIMGAtomicDMask(Inst)) {
5554 "invalid atomic image dmask");
5557 if (!validateMIMGGatherDMask(Inst)) {
5559 "invalid image_gather dmask: only one bit must be set");
5562 if (!validateMovrels(Inst,
Operands)) {
5565 if (!validateOffset(Inst,
Operands)) {
5568 if (!validateMAIAccWrite(Inst,
Operands)) {
5571 if (!validateMAISrc2(Inst,
Operands)) {
5574 if (!validateMFMA(Inst,
Operands)) {
5577 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5581 if (!validateAGPRLdSt(Inst)) {
5582 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5583 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5584 :
"invalid register class: agpr loads and stores not supported on this GPU"
5588 if (!validateVGPRAlign(Inst)) {
5590 "invalid register class: vgpr tuples must be 64 bit aligned");
5597 if (!validateBLGP(Inst,
Operands)) {
5601 if (!validateDivScale(Inst)) {
5602 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5605 if (!validateWaitCnt(Inst,
Operands)) {
5608 if (!validateTFE(Inst,
Operands)) {
5611 if (!validateSetVgprMSB(Inst,
Operands)) {
5614 if (!validateWMMA(Inst,
Operands)) {
5623 unsigned VariantID = 0);
5627 unsigned VariantID);
5629bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5634bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5635 const FeatureBitset &FBS,
5636 ArrayRef<unsigned> Variants) {
5637 for (
auto Variant : Variants) {
5645bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5646 const SMLoc &IDLoc) {
5647 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5650 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5655 getParser().clearPendingErrors();
5659 StringRef VariantName = getMatchedVariantName();
5660 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5663 " variant of this instruction is not supported"));
5667 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5668 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5670 FeatureBitset FeaturesWS32 = getFeatureBits();
5671 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5672 .
flip(AMDGPU::FeatureWavefrontSize32);
5673 FeatureBitset AvailableFeaturesWS32 =
5674 ComputeAvailableFeatures(FeaturesWS32);
5676 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5677 return Error(IDLoc,
"instruction requires wavesize=32");
5681 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5682 return Error(IDLoc,
"instruction not supported on this GPU");
5687 return Error(IDLoc,
"invalid instruction" + Suggestion);
5693 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5694 if (
Op.isToken() && InvalidOprIdx > 1) {
5695 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5696 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5701bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5704 uint64_t &ErrorInfo,
5705 bool MatchingInlineAsm) {
5708 unsigned Result = Match_Success;
5709 for (
auto Variant : getMatchedVariants()) {
5711 auto R = MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm,
5716 if (R == Match_Success || R == Match_MissingFeature ||
5717 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5718 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5719 Result != Match_MissingFeature)) {
5723 if (R == Match_Success)
5727 if (Result == Match_Success) {
5728 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5736 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5742 case Match_MissingFeature:
5746 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5748 case Match_InvalidOperand: {
5749 SMLoc ErrorLoc = IDLoc;
5750 if (ErrorInfo != ~0ULL) {
5751 if (ErrorInfo >=
Operands.size()) {
5752 return Error(IDLoc,
"too few operands for instruction");
5754 ErrorLoc = ((AMDGPUOperand &)*
Operands[ErrorInfo]).getStartLoc();
5755 if (ErrorLoc == SMLoc())
5759 return Error(ErrorLoc,
"invalid VOPDY instruction");
5761 return Error(ErrorLoc,
"invalid operand for instruction");
5764 case Match_MnemonicFail:
5770bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5775 if (getParser().parseAbsoluteExpression(Tmp)) {
5778 Ret =
static_cast<uint32_t
>(Tmp);
5782bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5783 if (!getSTI().getTargetTriple().isAMDGCN())
5784 return TokError(
"directive only supported for amdgcn architecture");
5786 std::string TargetIDDirective;
5787 SMLoc TargetStart = getTok().getLoc();
5788 if (getParser().parseEscapedString(TargetIDDirective))
5791 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5792 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5793 return getParser().Error(TargetRange.
Start,
5794 (Twine(
".amdgcn_target directive's target id ") +
5795 Twine(TargetIDDirective) +
5796 Twine(
" does not match the specified target id ") +
5797 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5802bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5806bool AMDGPUAsmParser::calculateGPRBlocks(
5807 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5808 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5809 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5810 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5811 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5817 const MCExpr *
NumSGPRs = NextFreeSGPR;
5818 int64_t EvaluatedSGPRs;
5823 unsigned MaxAddressableNumSGPRs =
5826 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5827 !Features.
test(FeatureSGPRInitBug) &&
5828 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5829 return OutOfRangeError(SGPRRange);
5831 const MCExpr *ExtraSGPRs =
5835 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5836 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5837 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5838 return OutOfRangeError(SGPRRange);
5840 if (Features.
test(FeatureSGPRInitBug))
5847 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5848 unsigned Granule) ->
const MCExpr * {
5852 const MCExpr *AlignToGPR =
5854 const MCExpr *DivGPR =
5860 VGPRBlocks = GetNumGPRBlocks(
5869bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5870 if (!getSTI().getTargetTriple().isAMDGCN())
5871 return TokError(
"directive only supported for amdgcn architecture");
5874 return TokError(
"directive only supported for amdhsa OS");
5876 StringRef KernelName;
5877 if (getParser().parseIdentifier(KernelName))
5880 AMDGPU::MCKernelDescriptor KD =
5892 const MCExpr *NextFreeVGPR = ZeroExpr;
5894 const MCExpr *NamedBarCnt = ZeroExpr;
5895 uint64_t SharedVGPRCount = 0;
5896 uint64_t PreloadLength = 0;
5897 uint64_t PreloadOffset = 0;
5899 const MCExpr *NextFreeSGPR = ZeroExpr;
5902 unsigned ImpliedUserSGPRCount = 0;
5906 std::optional<unsigned> ExplicitUserSGPRCount;
5907 const MCExpr *ReserveVCC = OneExpr;
5908 const MCExpr *ReserveFlatScr = OneExpr;
5909 std::optional<bool> EnableWavefrontSize32;
5915 SMRange IDRange = getTok().getLocRange();
5916 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5919 if (
ID ==
".end_amdhsa_kernel")
5923 return TokError(
".amdhsa_ directives cannot be repeated");
5925 SMLoc ValStart = getLoc();
5926 const MCExpr *ExprVal;
5927 if (getParser().parseExpression(ExprVal))
5929 SMLoc ValEnd = getLoc();
5930 SMRange ValRange = SMRange(ValStart, ValEnd);
5933 uint64_t Val = IVal;
5934 bool EvaluatableExpr;
5935 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5937 return OutOfRangeError(ValRange);
5941#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5942 if (!isUInt<ENTRY##_WIDTH>(Val)) \
5943 return OutOfRangeError(RANGE); \
5944 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
5949#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
5951 return Error(IDRange.Start, "directive should have resolvable expression", \
5954 if (
ID ==
".amdhsa_group_segment_fixed_size") {
5957 return OutOfRangeError(ValRange);
5959 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
5962 return OutOfRangeError(ValRange);
5964 }
else if (
ID ==
".amdhsa_kernarg_size") {
5966 return OutOfRangeError(ValRange);
5968 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
5970 ExplicitUserSGPRCount = Val;
5971 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
5975 "directive is not supported with architected flat scratch",
5978 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
5981 ImpliedUserSGPRCount += 4;
5982 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
5985 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5988 return OutOfRangeError(ValRange);
5992 ImpliedUserSGPRCount += Val;
5993 PreloadLength = Val;
5995 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
5998 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6001 return OutOfRangeError(ValRange);
6005 PreloadOffset = Val;
6006 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6009 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6012 ImpliedUserSGPRCount += 2;
6013 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6016 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6019 ImpliedUserSGPRCount += 2;
6020 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6023 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6026 ImpliedUserSGPRCount += 2;
6027 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6030 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6033 ImpliedUserSGPRCount += 2;
6034 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6037 "directive is not supported with architected flat scratch",
6041 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6044 ImpliedUserSGPRCount += 2;
6045 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6048 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6051 ImpliedUserSGPRCount += 1;
6052 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6054 if (IVersion.
Major < 10)
6055 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6056 EnableWavefrontSize32 = Val;
6058 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6060 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6062 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6064 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6067 "directive is not supported with architected flat scratch",
6070 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6072 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6076 "directive is not supported without architected flat scratch",
6079 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6081 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6083 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6085 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6087 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6089 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6091 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6093 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6095 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6097 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6099 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6101 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6102 VGPRRange = ValRange;
6103 NextFreeVGPR = ExprVal;
6104 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6105 SGPRRange = ValRange;
6106 NextFreeSGPR = ExprVal;
6107 }
else if (
ID ==
".amdhsa_accum_offset") {
6109 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6110 AccumOffset = ExprVal;
6111 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6113 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6114 NamedBarCnt = ExprVal;
6115 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6117 return OutOfRangeError(ValRange);
6118 ReserveVCC = ExprVal;
6119 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6120 if (IVersion.
Major < 7)
6121 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6124 "directive is not supported with architected flat scratch",
6127 return OutOfRangeError(ValRange);
6128 ReserveFlatScr = ExprVal;
6129 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6130 if (IVersion.
Major < 8)
6131 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6133 return OutOfRangeError(ValRange);
6134 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6135 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6137 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6139 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6141 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6143 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6145 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6147 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6149 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6151 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6153 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6154 if (IVersion.
Major >= 12)
6155 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6157 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6159 }
else if (
ID ==
".amdhsa_ieee_mode") {
6160 if (IVersion.
Major >= 12)
6161 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6163 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6165 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6166 if (IVersion.
Major < 9)
6167 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6169 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6171 }
else if (
ID ==
".amdhsa_tg_split") {
6173 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6176 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6179 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6181 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6183 }
else if (
ID ==
".amdhsa_memory_ordered") {
6184 if (IVersion.
Major < 10)
6185 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6187 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6189 }
else if (
ID ==
".amdhsa_forward_progress") {
6190 if (IVersion.
Major < 10)
6191 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6193 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6195 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6197 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6198 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6200 SharedVGPRCount = Val;
6202 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6204 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6205 if (IVersion.
Major < 11)
6206 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6207 if (IVersion.
Major == 11) {
6209 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6213 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6216 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6219 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6221 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6223 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6225 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6228 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6230 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6232 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6234 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6236 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6238 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6240 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6242 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6244 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6246 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6247 if (IVersion.
Major < 12)
6248 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6250 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6253 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6256#undef PARSE_BITS_ENTRY
6259 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6260 return TokError(
".amdhsa_next_free_vgpr directive is required");
6262 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6263 return TokError(
".amdhsa_next_free_sgpr directive is required");
6265 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6270 if (PreloadLength) {
6276 const MCExpr *VGPRBlocks;
6277 const MCExpr *SGPRBlocks;
6278 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6279 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6280 EnableWavefrontSize32, NextFreeVGPR,
6281 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6285 int64_t EvaluatedVGPRBlocks;
6286 bool VGPRBlocksEvaluatable =
6287 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6288 if (VGPRBlocksEvaluatable &&
6290 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6291 return OutOfRangeError(VGPRRange);
6295 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6296 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6298 int64_t EvaluatedSGPRBlocks;
6299 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6301 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6302 return OutOfRangeError(SGPRRange);
6305 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6306 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6308 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6309 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6310 "enabled user SGPRs");
6314 return TokError(
"too many user SGPRs enabled");
6318 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6319 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6323 return TokError(
"too many user SGPRs enabled");
6327 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6328 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6333 return TokError(
"Kernarg size should be resolvable");
6334 uint64_t kernarg_size = IVal;
6335 if (PreloadLength && kernarg_size &&
6336 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6337 return TokError(
"Kernarg preload length + offset is larger than the "
6338 "kernarg segment size");
6341 if (!Seen.
contains(
".amdhsa_accum_offset"))
6342 return TokError(
".amdhsa_accum_offset directive is required");
6343 int64_t EvaluatedAccum;
6344 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6345 uint64_t UEvaluatedAccum = EvaluatedAccum;
6346 if (AccumEvaluatable &&
6347 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6348 return TokError(
"accum_offset should be in range [4..256] in "
6351 int64_t EvaluatedNumVGPR;
6352 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6355 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6356 return TokError(
"accum_offset exceeds total VGPR allocation");
6362 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6363 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6369 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6370 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6373 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6375 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6376 return TokError(
"shared_vgpr_count directive not valid on "
6377 "wavefront size 32");
6380 if (VGPRBlocksEvaluatable &&
6381 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6383 return TokError(
"shared_vgpr_count*2 + "
6384 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6389 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6390 NextFreeVGPR, NextFreeSGPR,
6391 ReserveVCC, ReserveFlatScr);
6395bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6397 if (ParseAsAbsoluteExpression(
Version))
6400 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6404bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6405 AMDGPUMCKernelCodeT &
C) {
6408 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6409 Parser.eatToEndOfStatement();
6413 SmallString<40> ErrStr;
6414 raw_svector_ostream Err(ErrStr);
6415 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6416 return TokError(Err.
str());
6420 if (
ID ==
"enable_wavefront_size32") {
6423 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6424 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
6425 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6427 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
6428 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6432 if (
ID ==
"wavefront_size") {
6433 if (
C.wavefront_size == 5) {
6435 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6436 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
6437 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6438 }
else if (
C.wavefront_size == 6) {
6439 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
6440 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6447bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6448 AMDGPUMCKernelCodeT KernelCode;
6457 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6460 if (
ID ==
".end_amd_kernel_code_t")
6463 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6468 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6473bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6474 StringRef KernelName;
6475 if (!parseId(KernelName,
"expected symbol name"))
6478 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6485bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6486 if (!getSTI().getTargetTriple().isAMDGCN()) {
6487 return Error(getLoc(),
6488 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6492 auto TargetIDDirective = getLexer().getTok().getStringContents();
6493 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6494 return Error(getParser().getTok().getLoc(),
"target id must match options");
6496 getTargetStreamer().EmitISAVersion();
6502bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6505 std::string HSAMetadataString;
6510 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6511 return Error(getLoc(),
"invalid HSA metadata");
6518bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6519 const char *AssemblerDirectiveEnd,
6520 std::string &CollectString) {
6522 raw_string_ostream CollectStream(CollectString);
6524 getLexer().setSkipSpace(
false);
6526 bool FoundEnd =
false;
6529 CollectStream << getTokenStr();
6533 if (trySkipId(AssemblerDirectiveEnd)) {
6538 CollectStream << Parser.parseStringToEndOfStatement()
6539 <<
getContext().getAsmInfo()->getSeparatorString();
6541 Parser.eatToEndOfStatement();
6544 getLexer().setSkipSpace(
true);
6547 return TokError(Twine(
"expected directive ") +
6548 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6555bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6561 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6562 if (!PALMetadata->setFromString(
String))
6563 return Error(getLoc(),
"invalid PAL metadata");
6568bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6570 return Error(getLoc(),
6572 "not available on non-amdpal OSes")).str());
6575 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6576 PALMetadata->setLegacy();
6579 if (ParseAsAbsoluteExpression(
Key)) {
6580 return TokError(Twine(
"invalid value in ") +
6584 return TokError(Twine(
"expected an even number of values in ") +
6587 if (ParseAsAbsoluteExpression(
Value)) {
6588 return TokError(Twine(
"invalid value in ") +
6591 PALMetadata->setRegister(
Key,
Value);
6600bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6601 if (getParser().checkForValidSection())
6605 SMLoc NameLoc = getLoc();
6606 if (getParser().parseIdentifier(Name))
6607 return TokError(
"expected identifier in directive");
6610 if (getParser().parseComma())
6616 SMLoc SizeLoc = getLoc();
6617 if (getParser().parseAbsoluteExpression(
Size))
6620 return Error(SizeLoc,
"size must be non-negative");
6621 if (
Size > LocalMemorySize)
6622 return Error(SizeLoc,
"size is too large");
6624 int64_t Alignment = 4;
6626 SMLoc AlignLoc = getLoc();
6627 if (getParser().parseAbsoluteExpression(Alignment))
6630 return Error(AlignLoc,
"alignment must be a power of two");
6635 if (Alignment >= 1u << 31)
6636 return Error(AlignLoc,
"alignment is too large");
6642 Symbol->redefineIfPossible();
6643 if (!
Symbol->isUndefined())
6644 return Error(NameLoc,
"invalid symbol redefinition");
6646 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6650bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6651 StringRef IDVal = DirectiveID.
getString();
6654 if (IDVal ==
".amdhsa_kernel")
6655 return ParseDirectiveAMDHSAKernel();
6657 if (IDVal ==
".amdhsa_code_object_version")
6658 return ParseDirectiveAMDHSACodeObjectVersion();
6662 return ParseDirectiveHSAMetadata();
6664 if (IDVal ==
".amd_kernel_code_t")
6665 return ParseDirectiveAMDKernelCodeT();
6667 if (IDVal ==
".amdgpu_hsa_kernel")
6668 return ParseDirectiveAMDGPUHsaKernel();
6670 if (IDVal ==
".amd_amdgpu_isa")
6671 return ParseDirectiveISAVersion();
6675 Twine(
" directive is "
6676 "not available on non-amdhsa OSes"))
6681 if (IDVal ==
".amdgcn_target")
6682 return ParseDirectiveAMDGCNTarget();
6684 if (IDVal ==
".amdgpu_lds")
6685 return ParseDirectiveAMDGPULDS();
6688 return ParseDirectivePALMetadataBegin();
6691 return ParseDirectivePALMetadata();
6696bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
6698 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
6702 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
6703 return hasSGPR104_SGPR105();
6706 case SRC_SHARED_BASE_LO:
6707 case SRC_SHARED_BASE:
6708 case SRC_SHARED_LIMIT_LO:
6709 case SRC_SHARED_LIMIT:
6710 case SRC_PRIVATE_BASE_LO:
6711 case SRC_PRIVATE_BASE:
6712 case SRC_PRIVATE_LIMIT_LO:
6713 case SRC_PRIVATE_LIMIT:
6715 case SRC_FLAT_SCRATCH_BASE_LO:
6716 case SRC_FLAT_SCRATCH_BASE_HI:
6717 return hasGloballyAddressableScratch();
6718 case SRC_POPS_EXITING_WAVE_ID:
6730 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6759 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
6760 return hasSGPR102_SGPR103();
6768 ParseStatus Res = parseVOPD(
Operands);
6773 Res = MatchOperandParserImpl(
Operands, Mnemonic);
6785 SMLoc LBraceLoc = getLoc();
6790 auto Loc = getLoc();
6793 Error(Loc,
"expected a register");
6797 RBraceLoc = getLoc();
6802 "expected a comma or a closing square bracket"))
6806 if (
Operands.size() - Prefix > 1) {
6808 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6809 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6818StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6820 setForcedEncodingSize(0);
6821 setForcedDPP(
false);
6822 setForcedSDWA(
false);
6824 if (
Name.consume_back(
"_e64_dpp")) {
6826 setForcedEncodingSize(64);
6829 if (
Name.consume_back(
"_e64")) {
6830 setForcedEncodingSize(64);
6833 if (
Name.consume_back(
"_e32")) {
6834 setForcedEncodingSize(32);
6837 if (
Name.consume_back(
"_dpp")) {
6841 if (
Name.consume_back(
"_sdwa")) {
6842 setForcedSDWA(
true);
6850 unsigned VariantID);
6856 Name = parseMnemonicSuffix(Name);
6862 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6864 bool IsMIMG = Name.starts_with(
"image_");
6867 OperandMode
Mode = OperandMode_Default;
6869 Mode = OperandMode_NSA;
6873 checkUnsupportedInstruction(Name, NameLoc);
6874 if (!Parser.hasPendingError()) {
6877 :
"not a valid operand.";
6878 Error(getLoc(), Msg);
6897ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6900 if (!trySkipId(Name))
6903 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6907ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6916ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6918 std::function<
bool(int64_t &)> ConvertResult) {
6922 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
6926 if (ConvertResult && !ConvertResult(
Value)) {
6927 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
6930 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6934ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6936 bool (*ConvertResult)(int64_t &)) {
6945 const unsigned MaxSize = 4;
6949 for (
int I = 0; ; ++
I) {
6951 SMLoc Loc = getLoc();
6955 if (
Op != 0 &&
Op != 1)
6956 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
6963 if (
I + 1 == MaxSize)
6964 return Error(getLoc(),
"expected a closing square bracket");
6970 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
6974ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
6976 AMDGPUOperand::ImmTy ImmTy) {
6980 if (trySkipId(Name)) {
6982 }
else if (trySkipId(
"no", Name)) {
6989 return Error(S,
"r128 modifier is not supported on this GPU");
6990 if (Name ==
"a16" && !
hasA16())
6991 return Error(S,
"a16 modifier is not supported on this GPU");
6993 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
6994 ImmTy = AMDGPUOperand::ImmTyR128A16;
6996 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7000unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7001 bool &Disabling)
const {
7002 Disabling =
Id.consume_front(
"no");
7005 return StringSwitch<unsigned>(Id)
7012 return StringSwitch<unsigned>(Id)
7022 SMLoc StringLoc = getLoc();
7024 int64_t CPolVal = 0;
7044 ResScope = parseScope(
Operands, Scope);
7057 if (trySkipId(
"nv")) {
7061 }
else if (trySkipId(
"no",
"nv")) {
7068 if (trySkipId(
"scale_offset")) {
7072 }
else if (trySkipId(
"no",
"scale_offset")) {
7085 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7086 AMDGPUOperand::ImmTyCPol));
7091 SMLoc OpLoc = getLoc();
7092 unsigned Enabled = 0, Seen = 0;
7096 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7103 return Error(S,
"dlc modifier is not supported on this GPU");
7106 return Error(S,
"scc modifier is not supported on this GPU");
7109 return Error(S,
"duplicate cache policy modifier");
7121 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7130 ParseStatus Res = parseStringOrIntWithPrefix(
7131 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7145 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7149 if (
Value ==
"TH_DEFAULT")
7151 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7152 Value ==
"TH_LOAD_NT_WB") {
7153 return Error(StringLoc,
"invalid th value");
7154 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7156 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7158 }
else if (
Value.consume_front(
"TH_STORE_")) {
7161 return Error(StringLoc,
"invalid th value");
7164 if (
Value ==
"BYPASS")
7169 TH |= StringSwitch<int64_t>(
Value)
7179 .Default(0xffffffff);
7181 TH |= StringSwitch<int64_t>(
Value)
7192 .Default(0xffffffff);
7195 if (TH == 0xffffffff)
7196 return Error(StringLoc,
"invalid th value");
7203 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7204 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7205 std::optional<unsigned> InsertAt = std::nullopt) {
7206 auto i = OptionalIdx.find(ImmT);
7207 if (i != OptionalIdx.end()) {
7208 unsigned Idx = i->second;
7209 const AMDGPUOperand &
Op =
7210 static_cast<const AMDGPUOperand &
>(*
Operands[Idx]);
7214 Op.addImmOperands(Inst, 1);
7216 if (InsertAt.has_value())
7223ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7229 StringLoc = getLoc();
7234ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7240 SMLoc StringLoc = getLoc();
7244 Value = getTokenStr();
7248 if (
Value == Ids[IntVal])
7253 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7254 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7259ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7261 AMDGPUOperand::ImmTy
Type) {
7265 ParseStatus Res = parseStringOrIntWithPrefix(
Operands, Name, Ids, IntVal);
7267 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7276bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7280 SMLoc Loc = getLoc();
7282 auto Res = parseIntWithPrefix(Pref, Val);
7288 if (Val < 0 || Val > MaxVal) {
7289 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7298 AMDGPUOperand::ImmTy ImmTy) {
7299 const char *Pref =
"index_key";
7301 SMLoc Loc = getLoc();
7302 auto Res = parseIntWithPrefix(Pref, ImmVal);
7306 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7307 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7308 (ImmVal < 0 || ImmVal > 1))
7309 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7311 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7312 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7314 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7319 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7323 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7327 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7332 AMDGPUOperand::ImmTy
Type) {
7333 return parseStringOrIntWithPrefix(
Operands, Name,
7334 {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
7335 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
7341 return tryParseMatrixFMT(
Operands,
"matrix_a_fmt",
7342 AMDGPUOperand::ImmTyMatrixAFMT);
7346 return tryParseMatrixFMT(
Operands,
"matrix_b_fmt",
7347 AMDGPUOperand::ImmTyMatrixBFMT);
7352 AMDGPUOperand::ImmTy
Type) {
7353 return parseStringOrIntWithPrefix(
7354 Operands, Name, {
"MATRIX_SCALE_ROW0",
"MATRIX_SCALE_ROW1"},
Type);
7358 return tryParseMatrixScale(
Operands,
"matrix_a_scale",
7359 AMDGPUOperand::ImmTyMatrixAScale);
7363 return tryParseMatrixScale(
Operands,
"matrix_b_scale",
7364 AMDGPUOperand::ImmTyMatrixBScale);
7369 AMDGPUOperand::ImmTy
Type) {
7370 return parseStringOrIntWithPrefix(
7372 {
"MATRIX_SCALE_FMT_E8",
"MATRIX_SCALE_FMT_E5M3",
"MATRIX_SCALE_FMT_E4M3"},
7377 return tryParseMatrixScaleFmt(
Operands,
"matrix_a_scale_fmt",
7378 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7382 return tryParseMatrixScaleFmt(
Operands,
"matrix_b_scale_fmt",
7383 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7388ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7389 using namespace llvm::AMDGPU::MTBUFFormat;
7395 for (
int I = 0;
I < 2; ++
I) {
7396 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7399 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7404 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7410 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7413 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7414 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7420ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7421 using namespace llvm::AMDGPU::MTBUFFormat;
7425 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7428 if (Fmt == UFMT_UNDEF)
7435bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7437 StringRef FormatStr,
7439 using namespace llvm::AMDGPU::MTBUFFormat;
7443 if (
Format != DFMT_UNDEF) {
7449 if (
Format != NFMT_UNDEF) {
7454 Error(Loc,
"unsupported format");
7458ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7461 using namespace llvm::AMDGPU::MTBUFFormat;
7465 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7470 SMLoc Loc = getLoc();
7471 if (!parseId(Str,
"expected a format string") ||
7472 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7474 if (Dfmt == DFMT_UNDEF)
7475 return Error(Loc,
"duplicate numeric format");
7476 if (Nfmt == NFMT_UNDEF)
7477 return Error(Loc,
"duplicate data format");
7480 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7481 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7485 if (Ufmt == UFMT_UNDEF)
7486 return Error(FormatLoc,
"unsupported format");
7495ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7498 using namespace llvm::AMDGPU::MTBUFFormat;
7501 if (Id == UFMT_UNDEF)
7505 return Error(Loc,
"unified format is not supported on this GPU");
7511ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7512 using namespace llvm::AMDGPU::MTBUFFormat;
7513 SMLoc Loc = getLoc();
7518 return Error(Loc,
"out of range format");
7523ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7524 using namespace llvm::AMDGPU::MTBUFFormat;
7530 StringRef FormatStr;
7531 SMLoc Loc = getLoc();
7532 if (!parseId(FormatStr,
"expected a format string"))
7535 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7537 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7547 return parseNumericFormat(
Format);
7551 using namespace llvm::AMDGPU::MTBUFFormat;
7555 SMLoc Loc = getLoc();
7565 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7584 Res = parseSymbolicOrNumericFormat(
Format);
7589 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
7590 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7597 return Error(getLoc(),
"duplicate format");
7603 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
7605 Res = parseIntWithPrefix(
"inst_offset",
Operands,
7606 AMDGPUOperand::ImmTyInstOffset);
7613 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
7615 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
7621 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
7624 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
7634 OptionalImmIndexMap OptionalIdx;
7636 unsigned OperandIdx[4];
7637 unsigned EnMask = 0;
7640 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
7641 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7646 OperandIdx[SrcIdx] = Inst.
size();
7647 Op.addRegOperands(Inst, 1);
7654 OperandIdx[SrcIdx] = Inst.
size();
7660 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7661 Op.addImmOperands(Inst, 1);
7665 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7669 OptionalIdx[
Op.getImmTy()] = i;
7675 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7682 for (
auto i = 0; i < SrcIdx; ++i) {
7684 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7709 IntVal =
encode(ISA, IntVal, CntVal);
7710 if (CntVal !=
decode(ISA, IntVal)) {
7712 IntVal =
encode(ISA, IntVal, -1);
7720bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7722 SMLoc CntLoc = getLoc();
7723 StringRef CntName = getTokenStr();
7730 SMLoc ValLoc = getLoc();
7739 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7741 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7743 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7746 Error(CntLoc,
"invalid counter name " + CntName);
7751 Error(ValLoc,
"too large value for " + CntName);
7760 Error(getLoc(),
"expected a counter name");
7775 if (!parseCnt(Waitcnt))
7783 Operands.push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7787bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7788 SMLoc FieldLoc = getLoc();
7789 StringRef FieldName = getTokenStr();
7794 SMLoc ValueLoc = getLoc();
7801 if (FieldName ==
"instid0") {
7803 }
else if (FieldName ==
"instskip") {
7805 }
else if (FieldName ==
"instid1") {
7808 Error(FieldLoc,
"invalid field name " + FieldName);
7827 .Case(
"VALU_DEP_1", 1)
7828 .Case(
"VALU_DEP_2", 2)
7829 .Case(
"VALU_DEP_3", 3)
7830 .Case(
"VALU_DEP_4", 4)
7831 .Case(
"TRANS32_DEP_1", 5)
7832 .Case(
"TRANS32_DEP_2", 6)
7833 .Case(
"TRANS32_DEP_3", 7)
7834 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7835 .Case(
"SALU_CYCLE_1", 9)
7836 .Case(
"SALU_CYCLE_2", 10)
7837 .Case(
"SALU_CYCLE_3", 11)
7845 Delay |=
Value << Shift;
7855 if (!parseDelay(Delay))
7863 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7868AMDGPUOperand::isSWaitCnt()
const {
7872bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7878void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7879 StringRef DepCtrName) {
7882 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7885 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7888 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7891 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7898bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7900 using namespace llvm::AMDGPU::DepCtr;
7902 SMLoc DepCtrLoc = getLoc();
7903 StringRef DepCtrName = getTokenStr();
7913 unsigned PrevOprMask = UsedOprMask;
7914 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7917 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7926 Error(getLoc(),
"expected a counter name");
7931 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7932 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7937 using namespace llvm::AMDGPU::DepCtr;
7940 SMLoc Loc = getLoc();
7943 unsigned UsedOprMask = 0;
7945 if (!parseDepCtr(DepCtr, UsedOprMask))
7953 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
7957bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
7963ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
7965 OperandInfoTy &Width) {
7966 using namespace llvm::AMDGPU::Hwreg;
7972 HwReg.Loc = getLoc();
7975 HwReg.IsSymbolic =
true;
7977 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
7985 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
7995 Width.Loc = getLoc();
8004 using namespace llvm::AMDGPU::Hwreg;
8007 SMLoc Loc = getLoc();
8009 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8011 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8012 HwregOffset::Default);
8013 struct : StructuredOpField {
8014 using StructuredOpField::StructuredOpField;
8015 bool validate(AMDGPUAsmParser &Parser)
const override {
8017 return Error(Parser,
"only values from 1 to 32 are legal");
8020 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8021 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8024 Res = parseHwregFunc(HwReg,
Offset, Width);
8027 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8029 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8033 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8040 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8042 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8046bool AMDGPUOperand::isHwreg()
const {
8047 return isImmTy(ImmTyHwreg);
8055AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8057 OperandInfoTy &Stream) {
8058 using namespace llvm::AMDGPU::SendMsg;
8063 Msg.IsSymbolic =
true;
8065 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8070 Op.IsDefined =
true;
8073 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8076 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8081 Stream.IsDefined =
true;
8082 Stream.Loc = getLoc();
8092AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8093 const OperandInfoTy &
Op,
8094 const OperandInfoTy &Stream) {
8095 using namespace llvm::AMDGPU::SendMsg;
8100 bool Strict = Msg.IsSymbolic;
8104 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8109 Error(Msg.Loc,
"invalid message id");
8115 Error(
Op.Loc,
"message does not support operations");
8117 Error(Msg.Loc,
"missing message operation");
8123 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8125 Error(
Op.Loc,
"invalid operation id");
8130 Error(Stream.Loc,
"message operation does not support streams");
8134 Error(Stream.Loc,
"invalid message stream id");
8141 using namespace llvm::AMDGPU::SendMsg;
8144 SMLoc Loc = getLoc();
8148 OperandInfoTy
Op(OP_NONE_);
8149 OperandInfoTy Stream(STREAM_ID_NONE_);
8150 if (parseSendMsgBody(Msg,
Op, Stream) &&
8151 validateSendMsg(Msg,
Op, Stream)) {
8156 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8158 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8163 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8167bool AMDGPUOperand::isSendMsg()
const {
8168 return isImmTy(ImmTySendMsg);
8182 int Slot = StringSwitch<int>(Str)
8189 return Error(S,
"invalid interpolation slot");
8191 Operands.push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8192 AMDGPUOperand::ImmTyInterpSlot));
8203 if (!Str.starts_with(
"attr"))
8204 return Error(S,
"invalid interpolation attribute");
8206 StringRef Chan = Str.take_back(2);
8207 int AttrChan = StringSwitch<int>(Chan)
8214 return Error(S,
"invalid or missing interpolation attribute channel");
8216 Str = Str.drop_back(2).drop_front(4);
8219 if (Str.getAsInteger(10, Attr))
8220 return Error(S,
"invalid or missing interpolation attribute number");
8223 return Error(S,
"out of bounds interpolation attribute number");
8227 Operands.push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8228 AMDGPUOperand::ImmTyInterpAttr));
8229 Operands.push_back(AMDGPUOperand::CreateImm(
8230 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8239 using namespace llvm::AMDGPU::Exp;
8249 return Error(S, (Id == ET_INVALID)
8250 ?
"invalid exp target"
8251 :
"exp target is not supported on this GPU");
8253 Operands.push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8254 AMDGPUOperand::ImmTyExpTgt));
8263AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8268AMDGPUAsmParser::isId(
const StringRef Id)
const {
8274 return getTokenKind() ==
Kind;
8277StringRef AMDGPUAsmParser::getId()
const {
8282AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8291AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8293 StringRef Tok = getTokenStr();
8304 if (isId(Id) && peekToken().is(Kind)) {
8314 if (isToken(Kind)) {
8323 const StringRef ErrMsg) {
8324 if (!trySkipToken(Kind)) {
8325 Error(getLoc(), ErrMsg);
8332AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8336 if (Parser.parseExpression(Expr))
8339 if (Expr->evaluateAsAbsolute(
Imm))
8342 if (Expected.empty()) {
8343 Error(S,
"expected absolute expression");
8345 Error(S, Twine(
"expected ", Expected) +
8346 Twine(
" or an absolute expression"));
8356 if (Parser.parseExpression(Expr))
8360 if (Expr->evaluateAsAbsolute(IntVal)) {
8361 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8363 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8369AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8371 Val =
getToken().getStringContents();
8375 Error(getLoc(), ErrMsg);
8380AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8382 Val = getTokenStr();
8386 if (!ErrMsg.
empty())
8387 Error(getLoc(), ErrMsg);
8392AMDGPUAsmParser::getToken()
const {
8393 return Parser.getTok();
8396AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8399 : getLexer().peekTok(ShouldSkipSpace);
8404 auto TokCount = getLexer().peekTokens(Tokens);
8406 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8411AMDGPUAsmParser::getTokenKind()
const {
8412 return getLexer().getKind();
8416AMDGPUAsmParser::getLoc()
const {
8421AMDGPUAsmParser::getTokenStr()
const {
8426AMDGPUAsmParser::lex() {
8431 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
8435SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8440 int MCOpIdx)
const {
8442 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8443 if (TargetOp.getMCOpIdx() == MCOpIdx)
8444 return TargetOp.getStartLoc();
8450AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8452 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
8453 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8455 return Op.getStartLoc();
8461AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8463 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8478 StringRef
Id = getTokenStr();
8479 SMLoc IdLoc = getLoc();
8485 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8486 if (
I == Fields.
end())
8487 return Error(IdLoc,
"unknown field");
8488 if ((*I)->IsDefined)
8489 return Error(IdLoc,
"duplicate field");
8492 (*I)->Loc = getLoc();
8495 (*I)->IsDefined =
true;
8502bool AMDGPUAsmParser::validateStructuredOpFields(
8504 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8505 return F->validate(*
this);
8516 const unsigned OrMask,
8517 const unsigned XorMask) {
8526bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8527 const unsigned MaxVal,
8528 const Twine &ErrMsg, SMLoc &Loc) {
8545AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8546 const unsigned MinVal,
8547 const unsigned MaxVal,
8548 const StringRef ErrMsg) {
8550 for (
unsigned i = 0; i < OpNum; ++i) {
8551 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8559AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8560 using namespace llvm::AMDGPU::Swizzle;
8563 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8564 "expected a 2-bit lane id")) {
8575AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8576 using namespace llvm::AMDGPU::Swizzle;
8582 if (!parseSwizzleOperand(GroupSize,
8584 "group size must be in the interval [2,32]",
8589 Error(Loc,
"group size must be a power of two");
8592 if (parseSwizzleOperand(LaneIdx,
8594 "lane id must be in the interval [0,group size - 1]",
8603AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8604 using namespace llvm::AMDGPU::Swizzle;
8609 if (!parseSwizzleOperand(GroupSize,
8611 "group size must be in the interval [2,32]",
8616 Error(Loc,
"group size must be a power of two");
8625AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8626 using namespace llvm::AMDGPU::Swizzle;
8631 if (!parseSwizzleOperand(GroupSize,
8633 "group size must be in the interval [1,16]",
8638 Error(Loc,
"group size must be a power of two");
8647AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8648 using namespace llvm::AMDGPU::Swizzle;
8655 SMLoc StrLoc = getLoc();
8656 if (!parseString(Ctl)) {
8659 if (Ctl.
size() != BITMASK_WIDTH) {
8660 Error(StrLoc,
"expected a 5-character mask");
8664 unsigned AndMask = 0;
8665 unsigned OrMask = 0;
8666 unsigned XorMask = 0;
8668 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8672 Error(StrLoc,
"invalid mask");
8693bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8694 using namespace llvm::AMDGPU::Swizzle;
8697 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8703 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8704 "FFT swizzle must be in the interval [0," +
8705 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8713bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8714 using namespace llvm::AMDGPU::Swizzle;
8717 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8724 if (!parseSwizzleOperand(
Direction, 0, 1,
8725 "direction must be 0 (left) or 1 (right)", Loc))
8729 if (!parseSwizzleOperand(
8730 RotateSize, 0, ROTATE_MAX_SIZE,
8731 "number of threads to rotate must be in the interval [0," +
8732 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8737 (RotateSize << ROTATE_SIZE_SHIFT);
8742AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8744 SMLoc OffsetLoc = getLoc();
8750 Error(OffsetLoc,
"expected a 16-bit offset");
8757AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8758 using namespace llvm::AMDGPU::Swizzle;
8762 SMLoc ModeLoc = getLoc();
8765 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8766 Ok = parseSwizzleQuadPerm(
Imm);
8767 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8768 Ok = parseSwizzleBitmaskPerm(
Imm);
8769 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8770 Ok = parseSwizzleBroadcast(
Imm);
8771 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8772 Ok = parseSwizzleSwap(
Imm);
8773 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8774 Ok = parseSwizzleReverse(
Imm);
8775 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8776 Ok = parseSwizzleFFT(
Imm);
8777 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8778 Ok = parseSwizzleRotate(
Imm);
8780 Error(ModeLoc,
"expected a swizzle mode");
8783 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8793 if (trySkipId(
"offset")) {
8797 if (trySkipId(
"swizzle")) {
8798 Ok = parseSwizzleMacro(
Imm);
8800 Ok = parseSwizzleOffset(
Imm);
8804 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8812AMDGPUOperand::isSwizzle()
const {
8813 return isImmTy(ImmTySwizzle);
8820int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8822 using namespace llvm::AMDGPU::VGPRIndexMode;
8834 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8835 if (trySkipId(IdSymbolic[ModeId])) {
8843 "expected a VGPR index mode or a closing parenthesis" :
8844 "expected a VGPR index mode");
8849 Error(S,
"duplicate VGPR index mode");
8857 "expected a comma or a closing parenthesis"))
8866 using namespace llvm::AMDGPU::VGPRIndexMode;
8872 Imm = parseGPRIdxMacro();
8876 if (getParser().parseAbsoluteExpression(
Imm))
8879 return Error(S,
"invalid immediate: only 4-bit values are legal");
8883 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8887bool AMDGPUOperand::isGPRIdxMode()
const {
8888 return isImmTy(ImmTyGprIdxMode);
8900 if (isRegister() || isModifier())
8907 assert(Opr.isImm() || Opr.isExpr());
8908 SMLoc Loc = Opr.getStartLoc();
8912 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8913 Error(Loc,
"expected an absolute expression or a label");
8914 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8915 Error(Loc,
"expected a 16-bit signed jump offset");
8933void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
8936 OptionalImmIndexMap OptionalIdx;
8937 unsigned FirstOperandIdx = 1;
8938 bool IsAtomicReturn =
false;
8945 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
8946 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8950 Op.addRegOperands(Inst, 1);
8954 if (IsAtomicReturn && i == FirstOperandIdx)
8955 Op.addRegOperands(Inst, 1);
8960 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
8961 Op.addImmOperands(Inst, 1);
8973 OptionalIdx[
Op.getImmTy()] = i;
8984bool AMDGPUOperand::isSMRDOffset8()
const {
8988bool AMDGPUOperand::isSMEMOffset()
const {
8990 return isImmLiteral();
8993bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9028bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9029 if (BoundCtrl == 0 || BoundCtrl == 1) {
9037void AMDGPUAsmParser::onBeginOfFile() {
9038 if (!getParser().getStreamer().getTargetStreamer() ||
9042 if (!getTargetStreamer().getTargetID())
9043 getTargetStreamer().initializeTargetID(getSTI(),
9044 getSTI().getFeatureString());
9047 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9055bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9059 StringRef TokenId = getTokenStr();
9060 AGVK VK = StringSwitch<AGVK>(TokenId)
9061 .Case(
"max", AGVK::AGVK_Max)
9062 .Case(
"or", AGVK::AGVK_Or)
9063 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9064 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9065 .Case(
"alignto", AGVK::AGVK_AlignTo)
9066 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9067 .Default(AGVK::AGVK_None);
9071 uint64_t CommaCount = 0;
9076 if (Exprs.
empty()) {
9078 "empty " + Twine(TokenId) +
" expression");
9081 if (CommaCount + 1 != Exprs.
size()) {
9083 "mismatch of commas in " + Twine(TokenId) +
" expression");
9090 if (getParser().parseExpression(Expr, EndLoc))
9094 if (LastTokenWasComma)
9098 "unexpected token in " + Twine(TokenId) +
" expression");
9104 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9108 StringRef
Name = getTokenStr();
9109 if (Name ==
"mul") {
9110 return parseIntWithPrefix(
"mul",
Operands,
9114 if (Name ==
"div") {
9115 return parseIntWithPrefix(
"div",
Operands,
9126 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9131 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9132 AMDGPU::OpName::src2};
9140 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9145 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9147 if (
DstOp.isReg() &&
9148 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9152 if ((OpSel & (1 << SrcNum)) != 0)
9158void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9165 OptionalImmIndexMap &OptionalIdx) {
9166 cvtVOP3P(Inst,
Operands, OptionalIdx);
9175 &&
Desc.NumOperands > (OpNum + 1)
9177 &&
Desc.operands()[OpNum + 1].RegClass != -1
9179 &&
Desc.getOperandConstraint(OpNum + 1,
9185 OptionalImmIndexMap OptionalIdx;
9190 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9191 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9195 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9197 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9198 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9199 Op.isInterpAttrChan()) {
9201 }
else if (
Op.isImmModifier()) {
9202 OptionalIdx[
Op.getImmTy()] =
I;
9210 AMDGPUOperand::ImmTyHigh);
9214 AMDGPUOperand::ImmTyClamp);
9218 AMDGPUOperand::ImmTyOModSI);
9223 OptionalImmIndexMap OptionalIdx;
9228 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9229 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9233 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9235 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9236 }
else if (
Op.isImmModifier()) {
9237 OptionalIdx[
Op.getImmTy()] =
I;
9245 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9254 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9255 AMDGPU::OpName::src2};
9256 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9257 AMDGPU::OpName::src1_modifiers,
9258 AMDGPU::OpName::src2_modifiers};
9262 for (
int J = 0; J < 3; ++J) {
9263 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9267 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9270 if ((OpSel & (1 << J)) != 0)
9272 if (ModOps[J] == AMDGPU::OpName::src0_modifiers &&
9273 (OpSel & (1 << 3)) != 0)
9279void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9281 OptionalImmIndexMap OptionalIdx;
9284 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9288 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9289 static_cast<AMDGPUOperand &
>(*
Operands[
I++]).addRegOperands(Inst, 1);
9292 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
I]);
9297 if (NumOperands == CbszOpIdx) {
9302 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9303 }
else if (
Op.isImmModifier()) {
9304 OptionalIdx[
Op.getImmTy()] =
I;
9306 Op.addRegOrImmOperands(Inst, 1);
9311 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9312 if (CbszIdx != OptionalIdx.end()) {
9313 int CbszVal = ((AMDGPUOperand &)*
Operands[CbszIdx->second]).
getImm();
9317 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9318 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9319 if (BlgpIdx != OptionalIdx.end()) {
9320 int BlgpVal = ((AMDGPUOperand &)*
Operands[BlgpIdx->second]).
getImm();
9331 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9332 if (OpselIdx != OptionalIdx.end()) {
9333 OpSel =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselIdx->second])
9337 unsigned OpSelHi = 0;
9338 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9339 if (OpselHiIdx != OptionalIdx.end()) {
9340 OpSelHi =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselHiIdx->second])
9343 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9344 AMDGPU::OpName::src1_modifiers};
9346 for (
unsigned J = 0; J < 2; ++J) {
9347 unsigned ModVal = 0;
9348 if (OpSel & (1 << J))
9350 if (OpSelHi & (1 << J))
9353 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9359 OptionalImmIndexMap &OptionalIdx) {
9364 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9365 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9369 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9371 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9372 }
else if (
Op.isImmModifier()) {
9373 OptionalIdx[
Op.getImmTy()] =
I;
9375 Op.addRegOrImmOperands(Inst, 1);
9381 AMDGPUOperand::ImmTyScaleSel);
9385 AMDGPUOperand::ImmTyClamp);
9391 AMDGPUOperand::ImmTyByteSel);
9396 AMDGPUOperand::ImmTyOModSI);
9403 auto *it = Inst.
begin();
9404 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9413 OptionalImmIndexMap OptionalIdx;
9414 cvtVOP3(Inst,
Operands, OptionalIdx);
9418 OptionalImmIndexMap &OptIdx) {
9424 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9425 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9426 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9427 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9428 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9429 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9437 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9438 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9439 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9440 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9441 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9442 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9443 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9444 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9445 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9446 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9447 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9448 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9449 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9450 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9451 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9452 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9453 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9454 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9455 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9456 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9457 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9458 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9459 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9460 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9461 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9462 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9466 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9467 if (BitOp3Idx != -1) {
9474 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9475 if (OpSelIdx != -1) {
9479 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9480 if (OpSelHiIdx != -1) {
9487 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9488 if (MatrixAFMTIdx != -1) {
9490 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9494 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9495 if (MatrixBFMTIdx != -1) {
9497 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9500 int MatrixAScaleIdx =
9501 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9502 if (MatrixAScaleIdx != -1) {
9504 AMDGPUOperand::ImmTyMatrixAScale, 0);
9507 int MatrixBScaleIdx =
9508 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9509 if (MatrixBScaleIdx != -1) {
9511 AMDGPUOperand::ImmTyMatrixBScale, 0);
9514 int MatrixAScaleFmtIdx =
9515 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9516 if (MatrixAScaleFmtIdx != -1) {
9518 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9521 int MatrixBScaleFmtIdx =
9522 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9523 if (MatrixBScaleFmtIdx != -1) {
9525 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9530 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9534 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9536 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9540 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9544 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9545 AMDGPU::OpName::src2};
9546 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9547 AMDGPU::OpName::src1_modifiers,
9548 AMDGPU::OpName::src2_modifiers};
9551 unsigned OpSelHi = 0;
9558 if (OpSelHiIdx != -1)
9567 for (
int J = 0; J < 3; ++J) {
9568 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9572 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9577 uint32_t ModVal = 0;
9580 if (SrcOp.
isReg() && getMRI()
9587 if ((OpSel & (1 << J)) != 0)
9591 if ((OpSelHi & (1 << J)) != 0)
9594 if ((NegLo & (1 << J)) != 0)
9597 if ((NegHi & (1 << J)) != 0)
9605 OptionalImmIndexMap OptIdx;
9611 unsigned i,
unsigned Opc,
9613 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9614 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9616 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9622 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
9625 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
9626 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
9628 OptionalImmIndexMap OptIdx;
9629 for (
unsigned i = 5; i <
Operands.size(); ++i) {
9630 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
9631 OptIdx[
Op.getImmTy()] = i;
9636 AMDGPUOperand::ImmTyIndexKey8bit);
9640 AMDGPUOperand::ImmTyIndexKey16bit);
9644 AMDGPUOperand::ImmTyIndexKey32bit);
9664 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9665 SMLoc OpYLoc = getLoc();
9668 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9671 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9680 auto addOp = [&](uint16_t ParsedOprIdx) {
9681 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
9683 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9687 Op.addRegOperands(Inst, 1);
9691 Op.addImmOperands(Inst, 1);
9703 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9707 const auto &CInfo = InstInfo[CompIdx];
9708 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9709 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9710 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9711 if (CInfo.hasSrc2Acc())
9712 addOp(CInfo.getIndexOfDstInParsedOperands());
9716 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9717 if (BitOp3Idx != -1) {
9718 OptionalImmIndexMap OptIdx;
9719 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands.back());
9731bool AMDGPUOperand::isDPP8()
const {
9732 return isImmTy(ImmTyDPP8);
9735bool AMDGPUOperand::isDPPCtrl()
const {
9736 using namespace AMDGPU::DPP;
9738 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9741 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9742 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9743 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9744 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9745 (
Imm == DppCtrl::WAVE_SHL1) ||
9746 (
Imm == DppCtrl::WAVE_ROL1) ||
9747 (
Imm == DppCtrl::WAVE_SHR1) ||
9748 (
Imm == DppCtrl::WAVE_ROR1) ||
9749 (
Imm == DppCtrl::ROW_MIRROR) ||
9750 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9751 (
Imm == DppCtrl::BCAST15) ||
9752 (
Imm == DppCtrl::BCAST31) ||
9753 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9754 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9763bool AMDGPUOperand::isBLGP()
const {
9767bool AMDGPUOperand::isS16Imm()
const {
9771bool AMDGPUOperand::isU16Imm()
const {
9779bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9784 SMLoc Loc =
getToken().getEndLoc();
9785 Token = std::string(getTokenStr());
9787 if (getLoc() != Loc)
9792 if (!parseId(Suffix))
9796 StringRef DimId = Token;
9817 SMLoc Loc = getLoc();
9818 if (!parseDimId(Encoding))
9819 return Error(Loc,
"invalid dim value");
9821 Operands.push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9822 AMDGPUOperand::ImmTyDim));
9840 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9843 for (
size_t i = 0; i < 8; ++i) {
9847 SMLoc Loc = getLoc();
9848 if (getParser().parseAbsoluteExpression(Sels[i]))
9850 if (0 > Sels[i] || 7 < Sels[i])
9851 return Error(Loc,
"expected a 3-bit value");
9858 for (
size_t i = 0; i < 8; ++i)
9859 DPP8 |= (Sels[i] << (i * 3));
9861 Operands.push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9866AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
9868 if (Ctrl ==
"row_newbcast")
9871 if (Ctrl ==
"row_share" ||
9872 Ctrl ==
"row_xmask")
9875 if (Ctrl ==
"wave_shl" ||
9876 Ctrl ==
"wave_shr" ||
9877 Ctrl ==
"wave_rol" ||
9878 Ctrl ==
"wave_ror" ||
9879 Ctrl ==
"row_bcast")
9882 return Ctrl ==
"row_mirror" ||
9883 Ctrl ==
"row_half_mirror" ||
9884 Ctrl ==
"quad_perm" ||
9885 Ctrl ==
"row_shl" ||
9886 Ctrl ==
"row_shr" ||
9891AMDGPUAsmParser::parseDPPCtrlPerm() {
9894 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9898 for (
int i = 0; i < 4; ++i) {
9903 SMLoc Loc = getLoc();
9904 if (getParser().parseAbsoluteExpression(Temp))
9906 if (Temp < 0 || Temp > 3) {
9907 Error(Loc,
"expected a 2-bit value");
9911 Val += (Temp << i * 2);
9921AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
9922 using namespace AMDGPU::DPP;
9927 SMLoc Loc = getLoc();
9929 if (getParser().parseAbsoluteExpression(Val))
9932 struct DppCtrlCheck {
9938 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
9939 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
9940 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
9941 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
9942 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
9943 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
9944 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
9945 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
9946 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
9947 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
9948 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
9952 if (
Check.Ctrl == -1) {
9953 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
9961 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
9969 using namespace AMDGPU::DPP;
9972 !isSupportedDPPCtrl(getTokenStr(),
Operands))
9981 if (Ctrl ==
"row_mirror") {
9982 Val = DppCtrl::ROW_MIRROR;
9983 }
else if (Ctrl ==
"row_half_mirror") {
9984 Val = DppCtrl::ROW_HALF_MIRROR;
9987 if (Ctrl ==
"quad_perm") {
9988 Val = parseDPPCtrlPerm();
9990 Val = parseDPPCtrlSel(Ctrl);
9999 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10005 OptionalImmIndexMap OptionalIdx;
10012 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10014 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10015 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10019 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10020 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10024 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10025 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10026 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10027 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10028 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10034 if (OldIdx == NumOperands) {
10036 constexpr int DST_IDX = 0;
10038 }
else if (Src2ModIdx == NumOperands) {
10048 if (IsVOP3CvtSrDpp) {
10057 if (TiedTo != -1) {
10062 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10064 if (IsDPP8 &&
Op.isDppFI()) {
10067 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10068 }
else if (
Op.isReg()) {
10069 Op.addRegOperands(Inst, 1);
10070 }
else if (
Op.isImm() &&
10072 Op.addImmOperands(Inst, 1);
10073 }
else if (
Op.isImm()) {
10074 OptionalIdx[
Op.getImmTy()] =
I;
10082 AMDGPUOperand::ImmTyClamp);
10088 AMDGPUOperand::ImmTyByteSel);
10095 cvtVOP3P(Inst,
Operands, OptionalIdx);
10097 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
10104 using namespace llvm::AMDGPU::DPP;
10114 AMDGPUOperand::ImmTyDppFI);
10119 OptionalImmIndexMap OptionalIdx;
10123 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10124 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10131 if (TiedTo != -1) {
10136 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10138 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10146 Op.addImmOperands(Inst, 1);
10148 Op.addRegWithFPInputModsOperands(Inst, 2);
10149 }
else if (
Op.isDppFI()) {
10151 }
else if (
Op.isReg()) {
10152 Op.addRegOperands(Inst, 1);
10158 Op.addRegWithFPInputModsOperands(Inst, 2);
10159 }
else if (
Op.isReg()) {
10160 Op.addRegOperands(Inst, 1);
10161 }
else if (
Op.isDPPCtrl()) {
10162 Op.addImmOperands(Inst, 1);
10163 }
else if (
Op.isImm()) {
10165 OptionalIdx[
Op.getImmTy()] =
I;
10173 using namespace llvm::AMDGPU::DPP;
10181 AMDGPUOperand::ImmTyDppFI);
10192 AMDGPUOperand::ImmTy
Type) {
10193 return parseStringOrIntWithPrefix(
10195 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10200 return parseStringOrIntWithPrefix(
10201 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10202 AMDGPUOperand::ImmTySDWADstUnused);
10226 uint64_t BasicInstType,
10229 using namespace llvm::AMDGPU::SDWA;
10231 OptionalImmIndexMap OptionalIdx;
10232 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10233 bool SkippedVcc =
false;
10237 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10238 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10242 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10243 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10244 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10262 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10263 }
else if (
Op.isImm()) {
10265 OptionalIdx[
Op.getImmTy()] =
I;
10269 SkippedVcc =
false;
10273 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10274 Opc != AMDGPU::V_NOP_sdwa_vi) {
10276 switch (BasicInstType) {
10280 AMDGPUOperand::ImmTyClamp, 0);
10284 AMDGPUOperand::ImmTyOModSI, 0);
10288 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10292 AMDGPUOperand::ImmTySDWADstUnused,
10293 DstUnused::UNUSED_PRESERVE);
10300 AMDGPUOperand::ImmTyClamp, 0);
10314 AMDGPUOperand::ImmTyClamp, 0);
10320 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10326 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10327 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10328 auto *it = Inst.
begin();
10330 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10342#define GET_REGISTER_MATCHER
10343#define GET_MATCHER_IMPLEMENTATION
10344#define GET_MNEMONIC_SPELL_CHECKER
10345#define GET_MNEMONIC_CHECKER
10346#include "AMDGPUGenAsmMatcher.inc"
10352 return parseTokenOp(
"addr64",
Operands);
10354 return parseTokenOp(
"done",
Operands);
10356 return parseTokenOp(
"idxen",
Operands);
10358 return parseTokenOp(
"lds",
Operands);
10360 return parseTokenOp(
"offen",
Operands);
10362 return parseTokenOp(
"off",
Operands);
10363 case MCK_row_95_en:
10364 return parseTokenOp(
"row_en",
Operands);
10366 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10368 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10370 return tryCustomParseOperand(
Operands, MCK);
10375unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10381 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10384 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10386 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10388 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10390 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10392 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10394 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10402 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10404 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10405 case MCK_SOPPBrTarget:
10406 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10407 case MCK_VReg32OrOff:
10408 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10409 case MCK_InterpSlot:
10410 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10411 case MCK_InterpAttr:
10412 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10413 case MCK_InterpAttrChan:
10414 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10416 case MCK_SReg_64_XEXEC:
10426 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10428 return Match_InvalidOperand;
10437 SMLoc S = getLoc();
10446 return Error(S,
"expected a 16-bit value");
10449 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10453bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10459bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, AMDGPU::OpName OpName)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static int IsAGPROperand(const MCInst &Inst, AMDGPU::OpName Name, const MCRegisterInfo *MRI)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
constexpr uint64_t MIMGFlags
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static bool IsRevOpcode(const unsigned Opcode)
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 MCRegister getSpecialRegForName(StringRef RegName)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0, std::optional< unsigned > InsertAt=std::nullopt)
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)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Loop::LoopBounds::Direction Direction
mir Rename Register Operands
Register const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
MachineInstr unsigned OpIdx
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
unsigned unsigned DefaultVal
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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 std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
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
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
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.
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 createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
void setReg(MCRegister Reg)
Set the register number.
MCRegister getReg() const
Returns the register number.
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterClass - Base class of TargetRegisterClass.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this 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.
constexpr bool isValid() const
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
bool isVariable() const
isVariable - Check if this is a variable symbol.
LLVM_ABI void setVariableValue(const MCExpr *Value)
void setRedefinable(bool Value)
Mark this symbol as redefinable.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
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.
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
constexpr unsigned id() const
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.
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...
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.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
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 consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
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...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
#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 Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI)
unsigned getVGPREncodingGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI)
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
bool isPackedFP32Inst(unsigned Opc)
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)
bool isSGPR(MCRegister Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
uint8_t wmmaScaleF8F6F4FormatToNumRegs(unsigned Fmt)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
unsigned getTemporalHintType(const MCInstrDesc TID)
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
bool isGFX10(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.
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)
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
CanBeVOPD getCanBeVOPD(unsigned Opc, unsigned EncodingFamily, bool VOPD3)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
bool isSI(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isGFX9(const MCSubtargetInfo &STI)
unsigned getVOPDEncodingFamily(const MCSubtargetInfo &ST)
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 hasMAIInsts(const MCSubtargetInfo &STI)
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCSubtargetInfo &ST)
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)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ 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_INLINE_SPLIT_BARRIER_INT32
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 isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ 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)
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
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.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
FunctionAddr VTableAddr uintptr_t uintptr_t Version
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
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.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
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)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
@ Default
The result values are uniform if and only if all operands are uniform.
int popcount(T Value) noexcept
Count the number of set bits in a value.
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
Instruction set architecture version.
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
const MCExpr * compute_pgm_rsrc1
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * group_segment_fixed_size
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * kernel_code_properties
static LLVM_ABI const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI const fltSemantics & IEEEdouble() LLVM_READNONE
static LLVM_ABI const fltSemantics & IEEEhalf() LLVM_READNONE
static LLVM_ABI const fltSemantics & BFloat() LLVM_READNONE
opStatus
IEEE-754R 7: Default exception handling.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size