56enum RegisterKind { IS_UNKNOWN,
IS_VGPR, IS_SGPR,
IS_AGPR, IS_TTMP, IS_SPECIAL };
70 SMLoc StartLoc, EndLoc;
71 const AMDGPUAsmParser *AsmParser;
74 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
75 : Kind(Kind_), AsmParser(AsmParser_) {}
77 using Ptr = std::unique_ptr<AMDGPUOperand>;
85 bool hasFPModifiers()
const {
return Abs || Neg; }
86 bool hasIntModifiers()
const {
return Sext; }
87 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
88 bool isForcedLit64()
const {
return Lit == LitModifier::Lit64; }
90 int64_t getFPModifiersOperand()
const {
97 int64_t getIntModifiersOperand()
const {
103 int64_t getModifiersOperand()
const {
104 assert(!(hasFPModifiers() && hasIntModifiers())
105 &&
"fp and int modifiers should not be used simultaneously");
106 if (hasFPModifiers())
107 return getFPModifiersOperand();
108 if (hasIntModifiers())
109 return getIntModifiersOperand();
113 friend raw_ostream &
operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
187 ImmTyMatrixAScaleFmt,
188 ImmTyMatrixBScaleFmt,
221 mutable int MCOpIdx = -1;
224 bool isToken()
const override {
return Kind == Token; }
226 bool isSymbolRefExpr()
const {
230 bool isImm()
const override {
231 return Kind == Immediate;
234 bool isInlinableImm(MVT type)
const;
235 bool isLiteralImm(MVT type)
const;
237 bool isRegKind()
const {
238 return Kind == Register;
241 bool isReg()
const override {
242 return isRegKind() && !hasModifiers();
245 bool isRegOrInline(
unsigned RCID, MVT type)
const {
246 return isRegClass(RCID) || isInlinableImm(type);
250 return isRegOrInline(RCID, type) || isLiteralImm(type);
253 bool isRegOrImmWithInt16InputMods()
const {
257 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
259 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
262 bool isRegOrImmWithInt32InputMods()
const {
266 bool isRegOrInlineImmWithInt16InputMods()
const {
267 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
270 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
271 return isRegOrInline(
272 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
275 bool isRegOrInlineImmWithInt32InputMods()
const {
276 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
279 bool isRegOrImmWithInt64InputMods()
const {
283 bool isRegOrImmWithFP16InputMods()
const {
287 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
289 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
292 bool isRegOrImmWithFP32InputMods()
const {
296 bool isRegOrImmWithFP64InputMods()
const {
300 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
301 return isRegOrInline(
302 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
305 bool isRegOrInlineImmWithFP32InputMods()
const {
306 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
309 bool isRegOrInlineImmWithFP64InputMods()
const {
310 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
313 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
315 bool isVRegWithFP32InputMods()
const {
316 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
319 bool isVRegWithFP64InputMods()
const {
320 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
323 bool isPackedFP16InputMods()
const {
327 bool isPackedVGPRFP32InputMods()
const {
331 bool isVReg()
const {
332 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
333 isRegClass(AMDGPU::VReg_64RegClassID) ||
334 isRegClass(AMDGPU::VReg_96RegClassID) ||
335 isRegClass(AMDGPU::VReg_128RegClassID) ||
336 isRegClass(AMDGPU::VReg_160RegClassID) ||
337 isRegClass(AMDGPU::VReg_192RegClassID) ||
338 isRegClass(AMDGPU::VReg_256RegClassID) ||
339 isRegClass(AMDGPU::VReg_512RegClassID) ||
340 isRegClass(AMDGPU::VReg_1024RegClassID);
343 bool isVReg32()
const {
344 return isRegClass(AMDGPU::VGPR_32RegClassID);
347 bool isVReg32OrOff()
const {
348 return isOff() || isVReg32();
352 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
355 bool isAV_LdSt_32_Align2_RegOp()
const {
356 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
357 isRegClass(AMDGPU::AGPR_32RegClassID);
360 bool isVRegWithInputMods()
const;
361 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
362 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
364 bool isSDWAOperand(MVT type)
const;
365 bool isSDWAFP16Operand()
const;
366 bool isSDWAFP32Operand()
const;
367 bool isSDWAInt16Operand()
const;
368 bool isSDWAInt32Operand()
const;
370 bool isImmTy(ImmTy ImmT)
const {
371 return isImm() &&
Imm.Type == ImmT;
374 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
376 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
378 bool isImmModifier()
const {
379 return isImm() &&
Imm.Type != ImmTyNone;
382 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
383 bool isDim()
const {
return isImmTy(ImmTyDim); }
384 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
385 bool isOff()
const {
return isImmTy(ImmTyOff); }
386 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
387 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
388 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
389 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
390 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
391 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
392 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
393 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
394 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
395 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
396 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
397 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
398 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
399 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
400 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
401 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
402 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
403 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
404 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
405 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
406 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
407 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
408 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
409 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
410 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
411 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
412 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
413 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
414 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
415 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
416 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
417 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
418 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
419 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
420 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
421 bool isDone()
const {
return isImmTy(ImmTyDone); }
422 bool isRowEn()
const {
return isImmTy(ImmTyRowEn); }
424 bool isRegOrImm()
const {
425 return isReg() || isImm();
428 bool isRegClass(
unsigned RCID)
const;
432 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
433 return isRegOrInline(RCID, type) && !hasModifiers();
436 bool isSCSrcB16()
const {
437 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
440 bool isSCSrcV2B16()
const {
444 bool isSCSrc_b32()
const {
445 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
448 bool isSCSrc_b64()
const {
449 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
452 bool isBoolReg()
const;
454 bool isSCSrcF16()
const {
455 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
458 bool isSCSrcV2F16()
const {
462 bool isSCSrcF32()
const {
463 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
466 bool isSCSrcF64()
const {
467 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
470 bool isSSrc_b32()
const {
471 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
474 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
476 bool isSSrcV2B16()
const {
481 bool isSSrc_b64()
const {
484 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
485 (((
const MCTargetAsmParser *)AsmParser)
486 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
490 bool isSSrc_f32()
const {
491 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
494 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
496 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
498 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
500 bool isSSrcV2F16()
const {
505 bool isSSrcV2FP32()
const {
510 bool isSCSrcV2FP32()
const {
515 bool isSSrcV2INT32()
const {
520 bool isSCSrcV2INT32()
const {
522 return isSCSrc_b32();
525 bool isSSrcOrLds_b32()
const {
526 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
527 isLiteralImm(MVT::i32) || isExpr();
530 bool isVCSrc_b32()
const {
531 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
534 bool isVCSrc_b32_Lo256()
const {
535 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
538 bool isVCSrc_b64_Lo256()
const {
539 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
542 bool isVCSrc_b64()
const {
543 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
546 bool isVCSrcT_b16()
const {
547 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
550 bool isVCSrcTB16_Lo128()
const {
551 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
554 bool isVCSrcFake16B16_Lo128()
const {
555 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
558 bool isVCSrc_b16()
const {
559 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
562 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
564 bool isVCSrc_f32()
const {
565 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
568 bool isVCSrc_f64()
const {
569 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
572 bool isVCSrcTBF16()
const {
573 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
576 bool isVCSrcT_f16()
const {
577 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
580 bool isVCSrcT_bf16()
const {
581 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
584 bool isVCSrcTBF16_Lo128()
const {
585 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
588 bool isVCSrcTF16_Lo128()
const {
589 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
592 bool isVCSrcFake16BF16_Lo128()
const {
593 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
596 bool isVCSrcFake16F16_Lo128()
const {
597 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
600 bool isVCSrc_bf16()
const {
601 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
604 bool isVCSrc_f16()
const {
605 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
608 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
610 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
612 bool isVSrc_b32()
const {
613 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
616 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
618 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
620 bool isVSrcT_b16_Lo128()
const {
621 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
624 bool isVSrcFake16_b16_Lo128()
const {
625 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
628 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
630 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
632 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
634 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
636 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
638 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
640 bool isVSrc_f32()
const {
641 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
644 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
646 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
648 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
650 bool isVSrcT_bf16_Lo128()
const {
651 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
654 bool isVSrcT_f16_Lo128()
const {
655 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
658 bool isVSrcFake16_bf16_Lo128()
const {
659 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
662 bool isVSrcFake16_f16_Lo128()
const {
663 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
666 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
668 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
670 bool isVSrc_v2bf16()
const {
671 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
674 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
676 bool isVSrc_v2f16_splat()
const {
return isVSrc_v2f16(); }
678 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
680 bool isVISrcB32()
const {
681 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
684 bool isVISrcB16()
const {
685 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
688 bool isVISrcV2B16()
const {
692 bool isVISrcF32()
const {
693 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
696 bool isVISrcF16()
const {
697 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
700 bool isVISrcV2F16()
const {
701 return isVISrcF16() || isVISrcB32();
704 bool isVISrc_64_bf16()
const {
705 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
708 bool isVISrc_64_f16()
const {
709 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
712 bool isVISrc_64_b32()
const {
713 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
716 bool isVISrc_64B64()
const {
717 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
720 bool isVISrc_64_f64()
const {
721 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
724 bool isVISrc_64V2FP32()
const {
725 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
728 bool isVISrc_64V2INT32()
const {
729 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
732 bool isVISrc_256_b32()
const {
733 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
736 bool isVISrc_256_f32()
const {
737 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
740 bool isVISrc_256B64()
const {
741 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
744 bool isVISrc_256_f64()
const {
745 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
748 bool isVISrc_512_f64()
const {
749 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
752 bool isVISrc_128B16()
const {
753 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
756 bool isVISrc_128V2B16()
const {
757 return isVISrc_128B16();
760 bool isVISrc_128_b32()
const {
761 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
764 bool isVISrc_128_f32()
const {
765 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
768 bool isVISrc_256V2FP32()
const {
769 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
772 bool isVISrc_256V2INT32()
const {
773 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
776 bool isVISrc_512_b32()
const {
777 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
780 bool isVISrc_512B16()
const {
781 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
784 bool isVISrc_512V2B16()
const {
785 return isVISrc_512B16();
788 bool isVISrc_512_f32()
const {
789 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
792 bool isVISrc_512F16()
const {
793 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
796 bool isVISrc_512V2F16()
const {
797 return isVISrc_512F16() || isVISrc_512_b32();
800 bool isVISrc_1024_b32()
const {
801 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
804 bool isVISrc_1024B16()
const {
805 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
808 bool isVISrc_1024V2B16()
const {
809 return isVISrc_1024B16();
812 bool isVISrc_1024_f32()
const {
813 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
816 bool isVISrc_1024F16()
const {
817 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
820 bool isVISrc_1024V2F16()
const {
821 return isVISrc_1024F16() || isVISrc_1024_b32();
824 bool isAISrcB32()
const {
825 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
828 bool isAISrcB16()
const {
829 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
832 bool isAISrcV2B16()
const {
836 bool isAISrcF32()
const {
837 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
840 bool isAISrcF16()
const {
841 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
844 bool isAISrcV2F16()
const {
845 return isAISrcF16() || isAISrcB32();
848 bool isAISrc_64B64()
const {
849 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
852 bool isAISrc_64_f64()
const {
853 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
856 bool isAISrc_128_b32()
const {
857 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
860 bool isAISrc_128B16()
const {
861 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
864 bool isAISrc_128V2B16()
const {
865 return isAISrc_128B16();
868 bool isAISrc_128_f32()
const {
869 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
872 bool isAISrc_128F16()
const {
873 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
876 bool isAISrc_128V2F16()
const {
877 return isAISrc_128F16() || isAISrc_128_b32();
880 bool isVISrc_128_bf16()
const {
881 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
884 bool isVISrc_128_f16()
const {
885 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
888 bool isVISrc_128V2F16()
const {
889 return isVISrc_128_f16() || isVISrc_128_b32();
892 bool isAISrc_256B64()
const {
893 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
896 bool isAISrc_256_f64()
const {
897 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
900 bool isAISrc_512_b32()
const {
901 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
904 bool isAISrc_512B16()
const {
905 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
908 bool isAISrc_512V2B16()
const {
909 return isAISrc_512B16();
912 bool isAISrc_512_f32()
const {
913 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
916 bool isAISrc_512F16()
const {
917 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
920 bool isAISrc_512V2F16()
const {
921 return isAISrc_512F16() || isAISrc_512_b32();
924 bool isAISrc_1024_b32()
const {
925 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
928 bool isAISrc_1024B16()
const {
929 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
932 bool isAISrc_1024V2B16()
const {
933 return isAISrc_1024B16();
936 bool isAISrc_1024_f32()
const {
937 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
940 bool isAISrc_1024F16()
const {
941 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
944 bool isAISrc_1024V2F16()
const {
945 return isAISrc_1024F16() || isAISrc_1024_b32();
948 bool isKImmFP32()
const {
949 return isLiteralImm(MVT::f32);
952 bool isKImmFP16()
const {
953 return isLiteralImm(MVT::f16);
956 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
958 bool isMem()
const override {
962 bool isExpr()
const {
963 return Kind == Expression;
966 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
968 bool isSWaitCnt()
const;
969 bool isDepCtr()
const;
970 bool isSDelayALU()
const;
971 bool isHwreg()
const;
972 bool isSendMsg()
const;
973 bool isWaitEvent()
const;
974 bool isSplitBarrier()
const;
975 bool isSwizzle()
const;
976 bool isSMRDOffset8()
const;
977 bool isSMEMOffset()
const;
978 bool isSMRDLiteralOffset()
const;
980 bool isDPPCtrl()
const;
982 bool isGPRIdxMode()
const;
983 bool isS16Imm()
const;
984 bool isU16Imm()
const;
985 bool isEndpgm()
const;
987 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
988 return [
this,
P]() {
return P(*
this); };
993 return StringRef(Tok.Data, Tok.Length);
1001 void setImm(int64_t Val) {
1006 ImmTy getImmTy()
const {
1011 MCRegister
getReg()
const override {
1016 SMLoc getStartLoc()
const override {
1020 SMLoc getEndLoc()
const override {
1024 SMRange getLocRange()
const {
1025 return SMRange(StartLoc, EndLoc);
1028 int getMCOpIdx()
const {
return MCOpIdx; }
1030 Modifiers getModifiers()
const {
1031 assert(isRegKind() || isImmTy(ImmTyNone));
1032 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1035 void setModifiers(Modifiers Mods) {
1036 assert(isRegKind() || isImmTy(ImmTyNone));
1043 bool hasModifiers()
const {
1044 return getModifiers().hasModifiers();
1047 bool hasFPModifiers()
const {
1048 return getModifiers().hasFPModifiers();
1051 bool hasIntModifiers()
const {
1052 return getModifiers().hasIntModifiers();
1055 bool isForcedLit64()
const {
1056 return isImmLiteral() && getModifiers().isForcedLit64();
1059 uint64_t applyInputFPModifiers(uint64_t Val,
unsigned Size)
const;
1061 void addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1063 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1065 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1067 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1069 addRegOperands(Inst,
N);
1071 addImmOperands(Inst,
N);
1074 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1075 Modifiers Mods = getModifiers();
1078 addRegOperands(Inst,
N);
1080 addImmOperands(Inst,
N,
false);
1084 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1085 assert(!hasIntModifiers());
1086 addRegOrImmWithInputModsOperands(Inst,
N);
1089 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1090 assert(!hasFPModifiers());
1091 addRegOrImmWithInputModsOperands(Inst,
N);
1094 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1095 Modifiers Mods = getModifiers();
1098 addRegOperands(Inst,
N);
1101 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1102 assert(!hasIntModifiers());
1103 addRegWithInputModsOperands(Inst,
N);
1106 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1107 assert(!hasFPModifiers());
1108 addRegWithInputModsOperands(Inst,
N);
1111 static void printImmTy(raw_ostream& OS, ImmTy
Type) {
1114 case ImmTyNone: OS <<
"None";
break;
1115 case ImmTyGDS: OS <<
"GDS";
break;
1116 case ImmTyLDS: OS <<
"LDS";
break;
1117 case ImmTyOffen: OS <<
"Offen";
break;
1118 case ImmTyIdxen: OS <<
"Idxen";
break;
1119 case ImmTyAddr64: OS <<
"Addr64";
break;
1120 case ImmTyOffset: OS <<
"Offset";
break;
1121 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1122 case ImmTyOffset0: OS <<
"Offset0";
break;
1123 case ImmTyOffset1: OS <<
"Offset1";
break;
1124 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1125 case ImmTyCPol: OS <<
"CPol";
break;
1126 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1127 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1128 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1129 case ImmTyTFE: OS <<
"TFE";
break;
1130 case ImmTyIsAsync: OS <<
"IsAsync";
break;
1131 case ImmTyD16: OS <<
"D16";
break;
1132 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1133 case ImmTyClamp: OS <<
"Clamp";
break;
1134 case ImmTyOModSI: OS <<
"OModSI";
break;
1135 case ImmTyDPP8: OS <<
"DPP8";
break;
1136 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1137 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1138 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1139 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1140 case ImmTyDppFI: OS <<
"DppFI";
break;
1141 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1142 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1143 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1144 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1145 case ImmTyDMask: OS <<
"DMask";
break;
1146 case ImmTyDim: OS <<
"Dim";
break;
1147 case ImmTyUNorm: OS <<
"UNorm";
break;
1148 case ImmTyDA: OS <<
"DA";
break;
1149 case ImmTyR128A16: OS <<
"R128A16";
break;
1150 case ImmTyA16: OS <<
"A16";
break;
1151 case ImmTyLWE: OS <<
"LWE";
break;
1152 case ImmTyOff: OS <<
"Off";
break;
1153 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1154 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1155 case ImmTyExpVM: OS <<
"ExpVM";
break;
1156 case ImmTyDone: OS <<
"Done";
break;
1157 case ImmTyRowEn: OS <<
"RowEn";
break;
1158 case ImmTyHwreg: OS <<
"Hwreg";
break;
1159 case ImmTySendMsg: OS <<
"SendMsg";
break;
1160 case ImmTyWaitEvent: OS <<
"WaitEvent";
break;
1161 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1162 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1163 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1164 case ImmTyOpSel: OS <<
"OpSel";
break;
1165 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1166 case ImmTyNegLo: OS <<
"NegLo";
break;
1167 case ImmTyNegHi: OS <<
"NegHi";
break;
1168 case ImmTySwizzle: OS <<
"Swizzle";
break;
1169 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1170 case ImmTyHigh: OS <<
"High";
break;
1171 case ImmTyBLGP: OS <<
"BLGP";
break;
1172 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1173 case ImmTyABID: OS <<
"ABID";
break;
1174 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1175 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1176 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1177 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1178 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1179 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1180 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1181 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1182 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1183 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1184 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1185 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1186 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1187 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1188 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1189 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1194 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1198 <<
" mods: " <<
Reg.Mods <<
'>';
1202 if (getImmTy() != ImmTyNone) {
1203 OS <<
" type: "; printImmTy(OS, getImmTy());
1205 OS <<
" mods: " <<
Imm.Mods <<
'>';
1218 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1219 int64_t Val, SMLoc Loc,
1220 ImmTy
Type = ImmTyNone,
1221 bool IsFPImm =
false) {
1222 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1224 Op->Imm.IsFPImm = IsFPImm;
1226 Op->Imm.Mods = Modifiers();
1232 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1233 StringRef Str, SMLoc Loc,
1234 bool HasExplicitEncodingSize =
true) {
1235 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1236 Res->Tok.Data = Str.data();
1237 Res->Tok.Length = Str.size();
1238 Res->StartLoc = Loc;
1243 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1244 MCRegister
Reg, SMLoc S, SMLoc
E) {
1245 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1246 Op->Reg.RegNo =
Reg;
1247 Op->Reg.Mods = Modifiers();
1253 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1254 const class MCExpr *Expr, SMLoc S) {
1255 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1264 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1273#define GET_REGISTER_MATCHER
1274#include "AMDGPUGenAsmMatcher.inc"
1275#undef GET_REGISTER_MATCHER
1276#undef GET_SUBTARGET_FEATURE_NAME
1281class KernelScopeInfo {
1282 int SgprIndexUnusedMin = -1;
1283 int VgprIndexUnusedMin = -1;
1284 int AgprIndexUnusedMin = -1;
1288 void usesSgprAt(
int i) {
1289 if (i >= SgprIndexUnusedMin) {
1290 SgprIndexUnusedMin = ++i;
1293 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1299 void usesVgprAt(
int i) {
1300 if (i >= VgprIndexUnusedMin) {
1301 VgprIndexUnusedMin = ++i;
1304 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1306 VgprIndexUnusedMin);
1312 void usesAgprAt(
int i) {
1317 if (i >= AgprIndexUnusedMin) {
1318 AgprIndexUnusedMin = ++i;
1321 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1326 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1328 VgprIndexUnusedMin);
1335 KernelScopeInfo() =
default;
1339 MSTI = Ctx->getSubtargetInfo();
1341 usesSgprAt(SgprIndexUnusedMin = -1);
1342 usesVgprAt(VgprIndexUnusedMin = -1);
1344 usesAgprAt(AgprIndexUnusedMin = -1);
1348 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1349 unsigned RegWidth) {
1352 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1355 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1358 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1367 MCAsmParser &Parser;
1369 unsigned ForcedEncodingSize = 0;
1370 bool ForcedDPP =
false;
1371 bool ForcedSDWA =
false;
1372 KernelScopeInfo KernelScope;
1373 const unsigned HwMode;
1378#define GET_ASSEMBLER_HEADER
1379#include "AMDGPUGenAsmMatcher.inc"
1384 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1386 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1391 void createConstantSymbol(StringRef Id, int64_t Val);
1393 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1394 bool OutOfRangeError(SMRange
Range);
1410 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1411 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1412 std::optional<bool> EnableWavefrontSize32,
1413 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1414 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1415 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1416 bool ParseDirectiveAMDGCNTarget();
1417 bool ParseDirectiveAMDHSACodeObjectVersion();
1418 bool ParseDirectiveAMDHSAKernel();
1419 bool ParseAMDKernelCodeTValue(StringRef
ID, AMDGPUMCKernelCodeT &Header);
1420 bool ParseDirectiveAMDKernelCodeT();
1422 bool subtargetHasRegister(
const MCRegisterInfo &MRI, MCRegister
Reg);
1423 bool ParseDirectiveAMDGPUHsaKernel();
1425 bool ParseDirectiveISAVersion();
1426 bool ParseDirectiveHSAMetadata();
1427 bool ParseDirectivePALMetadataBegin();
1428 bool ParseDirectivePALMetadata();
1429 bool ParseDirectiveAMDGPULDS();
1433 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1434 const char *AssemblerDirectiveEnd,
1435 std::string &CollectString);
1437 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1438 RegisterKind RegKind, MCRegister Reg1, SMLoc Loc);
1439 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1440 unsigned &RegNum,
unsigned &RegWidth,
1441 bool RestoreOnFailure =
false);
1442 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1443 unsigned &RegNum,
unsigned &RegWidth,
1444 SmallVectorImpl<AsmToken> &Tokens);
1445 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1447 SmallVectorImpl<AsmToken> &Tokens);
1448 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1450 SmallVectorImpl<AsmToken> &Tokens);
1451 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1453 SmallVectorImpl<AsmToken> &Tokens);
1454 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &SubReg);
1455 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1456 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1459 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1460 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1461 void initializeGprCountSymbol(RegisterKind RegKind);
1462 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1464 void cvtMubufImpl(MCInst &Inst,
const OperandVector &Operands,
1469 OperandMode_Default,
1473 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1475 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1476 const MCInstrInfo &MII)
1477 : MCTargetAsmParser(STI, MII), Parser(_Parser),
1478 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)) {
1481 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1485 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1486 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1487 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1489 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1490 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1491 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1494 initializeGprCountSymbol(IS_VGPR);
1495 initializeGprCountSymbol(IS_SGPR);
1500 createConstantSymbol(Symbol, Code);
1502 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1503 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1504 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1582 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1584 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1586 bool hasInv2PiInlineImm()
const {
1587 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1590 bool has64BitLiterals()
const {
1591 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1594 bool hasFlatOffsets()
const {
1595 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1598 bool hasTrue16Insts()
const {
1599 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1603 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1606 bool hasSGPR102_SGPR103()
const {
1610 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1612 bool hasIntClamp()
const {
1613 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1616 bool hasPartialNSAEncoding()
const {
1617 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1620 bool hasGloballyAddressableScratch()
const {
1621 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1634 AMDGPUTargetStreamer &getTargetStreamer() {
1635 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1636 return static_cast<AMDGPUTargetStreamer &
>(TS);
1642 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1645 const MCRegisterInfo *getMRI()
const {
1649 const MCInstrInfo *getMII()
const {
1655 const FeatureBitset &getFeatureBits()
const {
1656 return getSTI().getFeatureBits();
1659 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1660 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1661 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1663 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1664 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1665 bool isForcedDPP()
const {
return ForcedDPP; }
1666 bool isForcedSDWA()
const {
return ForcedSDWA; }
1667 ArrayRef<unsigned> getMatchedVariants()
const;
1668 StringRef getMatchedVariantName()
const;
1670 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1671 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1672 bool RestoreOnFailure);
1673 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1674 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1675 SMLoc &EndLoc)
override;
1676 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1677 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1678 unsigned Kind)
override;
1679 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1681 uint64_t &ErrorInfo,
1682 bool MatchingInlineAsm)
override;
1683 bool ParseDirective(AsmToken DirectiveID)
override;
1684 ParseStatus parseOperand(
OperandVector &Operands, StringRef Mnemonic,
1685 OperandMode
Mode = OperandMode_Default);
1686 StringRef parseMnemonicSuffix(StringRef Name);
1687 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1691 ParseStatus parseTokenOp(StringRef Name,
OperandVector &Operands);
1693 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1696 parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1697 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1698 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1700 ParseStatus parseOperandArrayWithPrefix(
1702 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1703 bool (*ConvertResult)(int64_t &) =
nullptr);
1707 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1708 bool IgnoreNegative =
false);
1709 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1711 ParseStatus parseScope(
OperandVector &Operands, int64_t &Scope);
1713 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1715 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1717 ArrayRef<const char *> Ids,
1719 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1721 ArrayRef<const char *> Ids,
1722 AMDGPUOperand::ImmTy
Type);
1725 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1726 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1727 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1728 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1729 bool parseSP3NegModifier();
1730 ParseStatus parseImm(
OperandVector &Operands,
bool HasSP3AbsModifier =
false,
1733 ParseStatus parseRegOrImm(
OperandVector &Operands,
bool HasSP3AbsMod =
false,
1735 ParseStatus parseRegOrImmWithFPInputMods(
OperandVector &Operands,
1736 bool AllowImm =
true);
1737 ParseStatus parseRegOrImmWithIntInputMods(
OperandVector &Operands,
1738 bool AllowImm =
true);
1739 ParseStatus parseRegWithFPInputMods(
OperandVector &Operands);
1740 ParseStatus parseRegWithIntInputMods(
OperandVector &Operands);
1743 AMDGPUOperand::ImmTy ImmTy);
1747 ParseStatus tryParseMatrixFMT(
OperandVector &Operands, StringRef Name,
1748 AMDGPUOperand::ImmTy
Type);
1751 ParseStatus tryParseMatrixScale(
OperandVector &Operands, StringRef Name,
1752 AMDGPUOperand::ImmTy
Type);
1755 ParseStatus tryParseMatrixScaleFmt(
OperandVector &Operands, StringRef Name,
1756 AMDGPUOperand::ImmTy
Type);
1760 ParseStatus parseDfmtNfmt(int64_t &
Format);
1761 ParseStatus parseUfmt(int64_t &
Format);
1762 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1764 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1767 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1768 ParseStatus parseNumericFormat(int64_t &
Format);
1772 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1773 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1777 bool parseCnt(int64_t &IntVal);
1780 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1781 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1784 bool parseDelay(int64_t &Delay);
1790 struct OperandInfoTy {
1793 bool IsSymbolic =
false;
1794 bool IsDefined =
false;
1796 constexpr OperandInfoTy(int64_t Val) : Val(Val) {}
1799 struct StructuredOpField : OperandInfoTy {
1803 bool IsDefined =
false;
1805 constexpr StructuredOpField(StringLiteral Id, StringLiteral Desc,
1806 unsigned Width, int64_t
Default)
1807 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1808 virtual ~StructuredOpField() =
default;
1810 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1811 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1815 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1817 return Error(Parser,
"not supported on this GPU");
1819 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1827 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1828 bool validateSendMsg(
const OperandInfoTy &Msg,
1829 const OperandInfoTy &
Op,
1830 const OperandInfoTy &Stream);
1832 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1833 OperandInfoTy &Width);
1835 const AMDGPUOperand &findMCOperand(
const OperandVector &Operands,
1838 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1840 SMLoc getFlatOffsetLoc(
const OperandVector &Operands)
const;
1841 SMLoc getSMEMOffsetLoc(
const OperandVector &Operands)
const;
1844 SMLoc getOperandLoc(
const OperandVector &Operands,
int MCOpIdx)
const;
1845 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1847 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1851 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1853 bool validateOffset(
const MCInst &Inst,
const OperandVector &Operands);
1854 bool validateFlatOffset(
const MCInst &Inst,
const OperandVector &Operands);
1855 bool validateSMEMOffset(
const MCInst &Inst,
const OperandVector &Operands);
1856 bool validateSOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1857 bool validateConstantBusLimitations(
const MCInst &Inst,
const OperandVector &Operands);
1858 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1860 bool validateVOPD(
const MCInst &Inst,
const OperandVector &Operands);
1861 bool tryVOPD(
const MCInst &Inst);
1862 bool tryVOPD3(
const MCInst &Inst);
1863 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1865 bool validateIntClampSupported(
const MCInst &Inst);
1866 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1867 bool validateMIMGGatherDMask(
const MCInst &Inst);
1868 bool validateMovrels(
const MCInst &Inst,
const OperandVector &Operands);
1869 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1870 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1871 bool validateMIMGD16(
const MCInst &Inst);
1872 bool validateMIMGDim(
const MCInst &Inst,
const OperandVector &Operands);
1873 bool validateTensorR128(
const MCInst &Inst);
1874 bool validateMIMGMSAA(
const MCInst &Inst);
1875 bool validateOpSel(
const MCInst &Inst);
1876 bool validateTrue16OpSel(
const MCInst &Inst);
1877 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1878 bool validateDPP(
const MCInst &Inst,
const OperandVector &Operands);
1879 bool validateVccOperand(MCRegister
Reg)
const;
1880 bool validateVOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1881 bool validateMAIAccWrite(
const MCInst &Inst,
const OperandVector &Operands);
1882 bool validateMAISrc2(
const MCInst &Inst,
const OperandVector &Operands);
1883 bool validateMFMA(
const MCInst &Inst,
const OperandVector &Operands);
1884 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1885 bool validateVGPRAlign(
const MCInst &Inst)
const;
1886 bool validateBLGP(
const MCInst &Inst,
const OperandVector &Operands);
1887 bool validateDS(
const MCInst &Inst,
const OperandVector &Operands);
1888 bool validateGWS(
const MCInst &Inst,
const OperandVector &Operands);
1889 bool validateDivScale(
const MCInst &Inst);
1890 bool validateWaitCnt(
const MCInst &Inst,
const OperandVector &Operands);
1891 bool validateCoherencyBits(
const MCInst &Inst,
const OperandVector &Operands,
1893 bool validateTHAndScopeBits(
const MCInst &Inst,
const OperandVector &Operands,
1894 const unsigned CPol);
1895 bool validateTFE(
const MCInst &Inst,
const OperandVector &Operands);
1896 bool validateLdsDirect(
const MCInst &Inst,
const OperandVector &Operands);
1897 bool validateWMMA(
const MCInst &Inst,
const OperandVector &Operands);
1898 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1899 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1900 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1901 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1903 bool isSupportedMnemo(StringRef Mnemo,
1904 const FeatureBitset &FBS);
1905 bool isSupportedMnemo(StringRef Mnemo,
1906 const FeatureBitset &FBS,
1907 ArrayRef<unsigned> Variants);
1908 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1910 bool isId(
const StringRef Id)
const;
1911 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1913 StringRef getId()
const;
1914 bool trySkipId(
const StringRef Id);
1915 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1919 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1920 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1926 StringRef getTokenStr()
const;
1927 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1929 SMLoc getLoc()
const;
1933 void onBeginOfFile()
override;
1934 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1936 ParseStatus parseCustomOperand(
OperandVector &Operands,
unsigned MCK);
1946 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1947 const unsigned MaxVal,
const Twine &ErrMsg,
1949 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1950 const unsigned MinVal,
1951 const unsigned MaxVal,
1952 const StringRef ErrMsg);
1954 bool parseSwizzleOffset(int64_t &
Imm);
1955 bool parseSwizzleMacro(int64_t &
Imm);
1956 bool parseSwizzleQuadPerm(int64_t &
Imm);
1957 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1958 bool parseSwizzleBroadcast(int64_t &
Imm);
1959 bool parseSwizzleSwap(int64_t &
Imm);
1960 bool parseSwizzleReverse(int64_t &
Imm);
1961 bool parseSwizzleFFT(int64_t &
Imm);
1962 bool parseSwizzleRotate(int64_t &
Imm);
1965 int64_t parseGPRIdxMacro();
1967 void cvtMubuf(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
false); }
1968 void cvtMubufAtomic(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
true); }
1973 OptionalImmIndexMap &OptionalIdx);
1974 void cvtScaledMFMA(MCInst &Inst,
const OperandVector &Operands);
1975 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands);
1978 void cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands);
1981 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
1982 OptionalImmIndexMap &OptionalIdx);
1984 OptionalImmIndexMap &OptionalIdx);
1986 void cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands);
1987 void cvtVINTERP(MCInst &Inst,
const OperandVector &Operands);
1988 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1990 bool parseDimId(
unsigned &Encoding);
1992 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1995 bool isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands);
1996 int64_t parseDPPCtrlSel(StringRef Ctrl);
1997 int64_t parseDPPCtrlPerm();
1998 void cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8 =
false);
2000 cvtDPP(Inst, Operands,
true);
2002 void cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
2003 bool IsDPP8 =
false);
2004 void cvtVOP3DPP8(MCInst &Inst,
const OperandVector &Operands) {
2005 cvtVOP3DPP(Inst, Operands,
true);
2008 ParseStatus parseSDWASel(
OperandVector &Operands, StringRef Prefix,
2009 AMDGPUOperand::ImmTy
Type);
2011 void cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands);
2012 void cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands);
2013 void cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands);
2014 void cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands);
2015 void cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands);
2017 uint64_t BasicInstType,
2018 bool SkipDstVcc =
false,
2019 bool SkipSrcVcc =
false);
2128bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2138 if (!isImmTy(ImmTyNone)) {
2143 if (getModifiers().
Lit != LitModifier::None)
2153 if (type == MVT::f64 || type == MVT::i64) {
2155 AsmParser->hasInv2PiInlineImm());
2158 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2177 APFloat::rmNearestTiesToEven, &Lost);
2184 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2186 AsmParser->hasInv2PiInlineImm());
2191 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2192 AsmParser->hasInv2PiInlineImm());
2196 if (type == MVT::f64 || type == MVT::i64) {
2198 AsmParser->hasInv2PiInlineImm());
2207 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2208 type, AsmParser->hasInv2PiInlineImm());
2212 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2213 AsmParser->hasInv2PiInlineImm());
2216bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2218 if (!isImmTy(ImmTyNone)) {
2223 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2228 if (type == MVT::f64 && hasFPModifiers()) {
2248 if (type == MVT::f64) {
2253 if (type == MVT::i64) {
2266 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2267 : (type == MVT::v2i16) ? MVT::f32
2268 : (type == MVT::v2f32) ? MVT::f32
2271 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2275bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2276 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2279bool AMDGPUOperand::isVRegWithInputMods()
const {
2280 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2282 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2283 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2286template <
bool IsFake16>
2287bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2288 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2289 : AMDGPU::VGPR_16_Lo128RegClassID);
2292template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2293 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2294 : AMDGPU::VGPR_16RegClassID);
2297bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2298 if (AsmParser->isVI())
2300 if (AsmParser->isGFX9Plus())
2301 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2305bool AMDGPUOperand::isSDWAFP16Operand()
const {
2306 return isSDWAOperand(MVT::f16);
2309bool AMDGPUOperand::isSDWAFP32Operand()
const {
2310 return isSDWAOperand(MVT::f32);
2313bool AMDGPUOperand::isSDWAInt16Operand()
const {
2314 return isSDWAOperand(MVT::i16);
2317bool AMDGPUOperand::isSDWAInt32Operand()
const {
2318 return isSDWAOperand(MVT::i32);
2321bool AMDGPUOperand::isBoolReg()
const {
2322 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2323 (AsmParser->isWave32() && isSCSrc_b32()));
2326uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2328 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2331 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2343void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2353 addLiteralImmOperand(Inst,
Imm.Val,
2355 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2357 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2362void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2363 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2368 if (ApplyModifiers) {
2371 Val = applyInputFPModifiers(Val,
Size);
2375 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2377 bool CanUse64BitLiterals =
2378 AsmParser->has64BitLiterals() &&
2381 MCContext &Ctx = AsmParser->getContext();
2390 if (
Lit == LitModifier::None &&
2392 AsmParser->hasInv2PiInlineImm())) {
2400 bool HasMandatoryLiteral =
2403 if (
Literal.getLoBits(32) != 0 &&
2404 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2405 !HasMandatoryLiteral) {
2406 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2408 "Can't encode literal as exact 64-bit floating-point operand. "
2409 "Low 32-bits will be set to zero");
2410 Val &= 0xffffffff00000000u;
2416 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2422 Lit = LitModifier::Lit64;
2423 }
else if (
Lit == LitModifier::Lit) {
2437 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2439 Lit = LitModifier::Lit64;
2446 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2447 Literal == 0x3fc45f306725feed) {
2482 APFloat::rmNearestTiesToEven, &lost);
2486 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2493 if (
Lit != LitModifier::None) {
2523 if (
Lit == LitModifier::None &&
2533 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2540 if (
Lit == LitModifier::None &&
2548 if (!AsmParser->has64BitLiterals()) {
2549 Val =
static_cast<uint64_t
>(Val) << 32;
2556 if (
Lit == LitModifier::Lit ||
2558 Val =
static_cast<uint64_t
>(Val) << 32;
2562 if (
Lit == LitModifier::Lit)
2588 if (
Lit != LitModifier::None) {
2596void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2601bool AMDGPUOperand::isInlineValue()
const {
2609void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2620 if (Is == IS_VGPR) {
2624 return AMDGPU::VGPR_32RegClassID;
2626 return AMDGPU::VReg_64RegClassID;
2628 return AMDGPU::VReg_96RegClassID;
2630 return AMDGPU::VReg_128RegClassID;
2632 return AMDGPU::VReg_160RegClassID;
2634 return AMDGPU::VReg_192RegClassID;
2636 return AMDGPU::VReg_224RegClassID;
2638 return AMDGPU::VReg_256RegClassID;
2640 return AMDGPU::VReg_288RegClassID;
2642 return AMDGPU::VReg_320RegClassID;
2644 return AMDGPU::VReg_352RegClassID;
2646 return AMDGPU::VReg_384RegClassID;
2648 return AMDGPU::VReg_512RegClassID;
2650 return AMDGPU::VReg_1024RegClassID;
2652 }
else if (Is == IS_TTMP) {
2656 return AMDGPU::TTMP_32RegClassID;
2658 return AMDGPU::TTMP_64RegClassID;
2660 return AMDGPU::TTMP_128RegClassID;
2662 return AMDGPU::TTMP_256RegClassID;
2664 return AMDGPU::TTMP_512RegClassID;
2666 }
else if (Is == IS_SGPR) {
2670 return AMDGPU::SGPR_32RegClassID;
2672 return AMDGPU::SGPR_64RegClassID;
2674 return AMDGPU::SGPR_96RegClassID;
2676 return AMDGPU::SGPR_128RegClassID;
2678 return AMDGPU::SGPR_160RegClassID;
2680 return AMDGPU::SGPR_192RegClassID;
2682 return AMDGPU::SGPR_224RegClassID;
2684 return AMDGPU::SGPR_256RegClassID;
2686 return AMDGPU::SGPR_288RegClassID;
2688 return AMDGPU::SGPR_320RegClassID;
2690 return AMDGPU::SGPR_352RegClassID;
2692 return AMDGPU::SGPR_384RegClassID;
2694 return AMDGPU::SGPR_512RegClassID;
2696 }
else if (Is == IS_AGPR) {
2700 return AMDGPU::AGPR_32RegClassID;
2702 return AMDGPU::AReg_64RegClassID;
2704 return AMDGPU::AReg_96RegClassID;
2706 return AMDGPU::AReg_128RegClassID;
2708 return AMDGPU::AReg_160RegClassID;
2710 return AMDGPU::AReg_192RegClassID;
2712 return AMDGPU::AReg_224RegClassID;
2714 return AMDGPU::AReg_256RegClassID;
2716 return AMDGPU::AReg_288RegClassID;
2718 return AMDGPU::AReg_320RegClassID;
2720 return AMDGPU::AReg_352RegClassID;
2722 return AMDGPU::AReg_384RegClassID;
2724 return AMDGPU::AReg_512RegClassID;
2726 return AMDGPU::AReg_1024RegClassID;
2734 .
Case(
"exec", AMDGPU::EXEC)
2735 .
Case(
"vcc", AMDGPU::VCC)
2736 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2737 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2738 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2739 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2740 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2741 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2742 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2743 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2744 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2745 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2746 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2747 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2748 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2749 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2750 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2751 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2752 .
Case(
"m0", AMDGPU::M0)
2753 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2754 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2755 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2756 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2757 .
Case(
"scc", AMDGPU::SRC_SCC)
2758 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2759 .
Case(
"tba", AMDGPU::TBA)
2760 .
Case(
"tma", AMDGPU::TMA)
2761 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2762 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2763 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2764 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2765 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2766 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2767 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2768 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2769 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2770 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2771 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2772 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2773 .
Case(
"pc", AMDGPU::PC_REG)
2774 .
Case(
"null", AMDGPU::SGPR_NULL)
2778bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2779 SMLoc &EndLoc,
bool RestoreOnFailure) {
2780 auto R = parseRegister();
2781 if (!R)
return true;
2783 RegNo =
R->getReg();
2784 StartLoc =
R->getStartLoc();
2785 EndLoc =
R->getEndLoc();
2789bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2791 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2794ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2796 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2797 bool PendingErrors = getParser().hasPendingError();
2798 getParser().clearPendingErrors();
2806bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2807 RegisterKind RegKind,
2808 MCRegister Reg1, SMLoc Loc) {
2811 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2816 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2817 Reg = AMDGPU::FLAT_SCR;
2821 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2822 Reg = AMDGPU::XNACK_MASK;
2826 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2831 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2836 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2841 Error(Loc,
"register does not fit in the list");
2847 if (Reg1 !=
Reg + RegWidth / 32) {
2848 Error(Loc,
"registers in a list must have consecutive indices");
2866 {{
"ttmp"}, IS_TTMP},
2872 return Kind == IS_VGPR ||
2880 if (Str.starts_with(
Reg.Name))
2886 return !Str.getAsInteger(10, Num);
2890AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2891 const AsmToken &NextToken)
const {
2906 StringRef RegSuffix = Str.substr(
RegName.size());
2907 if (!RegSuffix.
empty()) {
2925AMDGPUAsmParser::isRegister()
2927 return isRegister(
getToken(), peekToken());
2930MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2931 unsigned SubReg,
unsigned RegWidth,
2935 unsigned AlignSize = 1;
2936 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2942 if (RegNum % AlignSize != 0) {
2943 Error(Loc,
"invalid register alignment");
2944 return MCRegister();
2947 unsigned RegIdx = RegNum / AlignSize;
2950 Error(Loc,
"invalid or unsupported register size");
2951 return MCRegister();
2955 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2956 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2957 Error(Loc,
"register index is out of range");
2958 return AMDGPU::NoRegister;
2961 if (RegKind == IS_VGPR && !
isGFX1250Plus() && RegIdx + RegWidth / 32 > 256) {
2962 Error(Loc,
"register index is out of range");
2963 return MCRegister();
2979bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2981 int64_t RegLo, RegHi;
2985 SMLoc FirstIdxLoc = getLoc();
2992 SecondIdxLoc = getLoc();
3003 Error(FirstIdxLoc,
"invalid register index");
3008 Error(SecondIdxLoc,
"invalid register index");
3012 if (RegLo > RegHi) {
3013 Error(FirstIdxLoc,
"first register index should not exceed second index");
3017 if (RegHi == RegLo) {
3018 StringRef RegSuffix = getTokenStr();
3019 if (RegSuffix ==
".l") {
3020 SubReg = AMDGPU::lo16;
3022 }
else if (RegSuffix ==
".h") {
3023 SubReg = AMDGPU::hi16;
3028 Num =
static_cast<unsigned>(RegLo);
3029 RegWidth = 32 * ((RegHi - RegLo) + 1);
3034MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3037 SmallVectorImpl<AsmToken> &Tokens) {
3043 RegKind = IS_SPECIAL;
3050MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3053 SmallVectorImpl<AsmToken> &Tokens) {
3055 StringRef
RegName = getTokenStr();
3056 auto Loc = getLoc();
3060 Error(Loc,
"invalid register name");
3061 return MCRegister();
3069 unsigned SubReg = NoSubRegister;
3070 if (!RegSuffix.
empty()) {
3072 SubReg = AMDGPU::lo16;
3074 SubReg = AMDGPU::hi16;
3078 Error(Loc,
"invalid register index");
3079 return MCRegister();
3084 if (!ParseRegRange(RegNum, RegWidth, SubReg))
3085 return MCRegister();
3088 return getRegularReg(RegKind, RegNum, SubReg, RegWidth, Loc);
3091MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3092 unsigned &RegNum,
unsigned &RegWidth,
3093 SmallVectorImpl<AsmToken> &Tokens) {
3095 auto ListLoc = getLoc();
3098 "expected a register or a list of registers")) {
3099 return MCRegister();
3104 auto Loc = getLoc();
3105 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3106 return MCRegister();
3107 if (RegWidth != 32) {
3108 Error(Loc,
"expected a single 32-bit register");
3109 return MCRegister();
3113 RegisterKind NextRegKind;
3115 unsigned NextRegNum, NextRegWidth;
3118 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3119 NextRegNum, NextRegWidth,
3121 return MCRegister();
3123 if (NextRegWidth != 32) {
3124 Error(Loc,
"expected a single 32-bit register");
3125 return MCRegister();
3127 if (NextRegKind != RegKind) {
3128 Error(Loc,
"registers in a list must be of the same kind");
3129 return MCRegister();
3131 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3132 return MCRegister();
3136 "expected a comma or a closing square bracket")) {
3137 return MCRegister();
3141 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3146bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3147 MCRegister &
Reg,
unsigned &RegNum,
3149 SmallVectorImpl<AsmToken> &Tokens) {
3150 auto Loc = getLoc();
3154 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3156 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3158 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3163 assert(Parser.hasPendingError());
3167 if (!subtargetHasRegister(*
TRI,
Reg)) {
3168 if (
Reg == AMDGPU::SGPR_NULL) {
3169 Error(Loc,
"'null' operand is not supported on this GPU");
3172 " register not available on this GPU");
3180bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3181 MCRegister &
Reg,
unsigned &RegNum,
3183 bool RestoreOnFailure ) {
3187 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3188 if (RestoreOnFailure) {
3189 while (!Tokens.
empty()) {
3198std::optional<StringRef>
3199AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3202 return StringRef(
".amdgcn.next_free_vgpr");
3204 return StringRef(
".amdgcn.next_free_sgpr");
3206 return std::nullopt;
3210void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3211 auto SymbolName = getGprCountSymbolName(RegKind);
3212 assert(SymbolName &&
"initializing invalid register kind");
3218bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3219 unsigned DwordRegIndex,
3220 unsigned RegWidth) {
3225 auto SymbolName = getGprCountSymbolName(RegKind);
3230 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3234 return !
Error(getLoc(),
3235 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3239 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3241 if (OldCount <= NewMax)
3247std::unique_ptr<AMDGPUOperand>
3248AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3250 SMLoc StartLoc = Tok.getLoc();
3251 SMLoc EndLoc = Tok.getEndLoc();
3252 RegisterKind RegKind;
3254 unsigned RegNum, RegWidth;
3256 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3260 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3263 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3264 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3267ParseStatus AMDGPUAsmParser::parseImm(
OperandVector &Operands,
3271 if (isRegister() || isModifier())
3274 if (
Lit == LitModifier::None) {
3275 if (trySkipId(
"lit"))
3276 Lit = LitModifier::Lit;
3277 else if (trySkipId(
"lit64"))
3278 Lit = LitModifier::Lit64;
3280 if (
Lit != LitModifier::None) {
3283 ParseStatus S = parseImm(Operands, HasSP3AbsModifier,
Lit);
3292 const auto& NextTok = peekToken();
3295 bool Negate =
false;
3303 AMDGPUOperand::Modifiers Mods;
3311 StringRef Num = getTokenStr();
3314 APFloat RealVal(APFloat::IEEEdouble());
3315 auto roundMode = APFloat::rmNearestTiesToEven;
3316 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3319 RealVal.changeSign();
3322 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3323 AMDGPUOperand::ImmTyNone,
true));
3324 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3325 Op.setModifiers(Mods);
3334 if (HasSP3AbsModifier) {
3343 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3346 if (Parser.parseExpression(Expr))
3350 if (Expr->evaluateAsAbsolute(IntVal)) {
3351 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3352 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3353 Op.setModifiers(Mods);
3355 if (
Lit != LitModifier::None)
3357 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3366ParseStatus AMDGPUAsmParser::parseReg(
OperandVector &Operands) {
3370 if (
auto R = parseRegister()) {
3378ParseStatus AMDGPUAsmParser::parseRegOrImm(
OperandVector &Operands,
3380 ParseStatus Res = parseReg(Operands);
3385 return parseImm(Operands, HasSP3AbsMod,
Lit);
3389AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3392 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3398AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3403AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3404 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3408AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3409 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3426AMDGPUAsmParser::isModifier() {
3429 AsmToken NextToken[2];
3430 peekTokens(NextToken);
3432 return isOperandModifier(Tok, NextToken[0]) ||
3433 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3434 isOpcodeModifierWithVal(Tok, NextToken[0]);
3460AMDGPUAsmParser::parseSP3NegModifier() {
3462 AsmToken NextToken[2];
3463 peekTokens(NextToken);
3466 (isRegister(NextToken[0], NextToken[1]) ||
3468 isId(NextToken[0],
"abs"))) {
3477AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
3485 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3487 SP3Neg = parseSP3NegModifier();
3490 Neg = trySkipId(
"neg");
3492 return Error(Loc,
"expected register or immediate");
3496 Abs = trySkipId(
"abs");
3501 if (trySkipId(
"lit")) {
3502 Lit = LitModifier::Lit;
3505 }
else if (trySkipId(
"lit64")) {
3506 Lit = LitModifier::Lit64;
3509 if (!has64BitLiterals())
3510 return Error(Loc,
"lit64 is not supported on this GPU");
3516 return Error(Loc,
"expected register or immediate");
3520 Res = parseRegOrImm(Operands, SP3Abs,
Lit);
3522 Res = parseReg(Operands);
3525 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3529 if (
Lit != LitModifier::None && !Operands.
back()->isImm())
3530 Error(Loc,
"expected immediate with lit modifier");
3532 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3538 if (
Lit != LitModifier::None &&
3542 AMDGPUOperand::Modifiers Mods;
3543 Mods.Abs = Abs || SP3Abs;
3544 Mods.Neg = Neg || SP3Neg;
3547 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3548 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3550 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3551 Op.setModifiers(Mods);
3557AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
3559 bool Sext = trySkipId(
"sext");
3560 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3565 Res = parseRegOrImm(Operands);
3567 Res = parseReg(Operands);
3575 AMDGPUOperand::Modifiers Mods;
3578 if (Mods.hasIntModifiers()) {
3579 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3581 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3582 Op.setModifiers(Mods);
3588ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
3589 return parseRegOrImmWithFPInputMods(Operands,
false);
3592ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
3593 return parseRegOrImmWithIntInputMods(Operands,
false);
3596ParseStatus AMDGPUAsmParser::parseVReg32OrOff(
OperandVector &Operands) {
3597 auto Loc = getLoc();
3598 if (trySkipId(
"off")) {
3599 Operands.
push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3600 AMDGPUOperand::ImmTyOff,
false));
3607 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3616unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3623 return Match_InvalidOperand;
3625 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3626 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3629 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3631 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3632 return Match_InvalidOperand;
3640 if (tryAnotherVOPDEncoding(Inst))
3641 return Match_InvalidOperand;
3643 return Match_Success;
3647 static const unsigned Variants[] = {
3657ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3658 if (isForcedDPP() && isForcedVOP3()) {
3662 if (getForcedEncodingSize() == 32) {
3667 if (isForcedVOP3()) {
3672 if (isForcedSDWA()) {
3678 if (isForcedDPP()) {
3686StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3687 if (isForcedDPP() && isForcedVOP3())
3690 if (getForcedEncodingSize() == 32)
3706AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3710 case AMDGPU::FLAT_SCR:
3712 case AMDGPU::VCC_LO:
3713 case AMDGPU::VCC_HI:
3720 return MCRegister();
3727bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3728 unsigned OpIdx)
const {
3785unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3791 case AMDGPU::V_LSHLREV_B64_e64:
3792 case AMDGPU::V_LSHLREV_B64_gfx10:
3793 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3794 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3795 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3796 case AMDGPU::V_LSHRREV_B64_e64:
3797 case AMDGPU::V_LSHRREV_B64_gfx10:
3798 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3799 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3800 case AMDGPU::V_ASHRREV_I64_e64:
3801 case AMDGPU::V_ASHRREV_I64_gfx10:
3802 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3803 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3804 case AMDGPU::V_LSHL_B64_e64:
3805 case AMDGPU::V_LSHR_B64_e64:
3806 case AMDGPU::V_ASHR_I64_e64:
3819 bool AddMandatoryLiterals =
false) {
3822 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3826 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3828 return {getNamedOperandIdx(Opcode, OpName::src0X),
3829 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3830 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3831 getNamedOperandIdx(Opcode, OpName::src0Y),
3832 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3833 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3838 return {getNamedOperandIdx(Opcode, OpName::src0),
3839 getNamedOperandIdx(Opcode, OpName::src1),
3840 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3843bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3846 return !isInlineConstant(Inst,
OpIdx);
3853 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3864 const unsigned Opcode = Inst.
getOpcode();
3865 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3868 if (!LaneSelOp.
isReg())
3871 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3874bool AMDGPUAsmParser::validateConstantBusLimitations(
3876 const unsigned Opcode = Inst.
getOpcode();
3877 const MCInstrDesc &
Desc = MII.
get(Opcode);
3878 MCRegister LastSGPR;
3879 unsigned ConstantBusUseCount = 0;
3880 unsigned NumLiterals = 0;
3881 unsigned LiteralSize;
3883 if (!(
Desc.TSFlags &
3898 SmallDenseSet<MCRegister> SGPRsUsed;
3899 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3901 SGPRsUsed.
insert(SGPRUsed);
3902 ++ConstantBusUseCount;
3907 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3909 for (
int OpIdx : OpIndices) {
3914 if (usesConstantBus(Inst,
OpIdx)) {
3923 if (SGPRsUsed.
insert(LastSGPR).second) {
3924 ++ConstantBusUseCount;
3944 if (NumLiterals == 0) {
3947 }
else if (LiteralSize !=
Size) {
3953 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3955 "invalid operand (violates constant bus restrictions)");
3962std::optional<unsigned>
3963AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3965 const unsigned Opcode = Inst.
getOpcode();
3971 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3972 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3981 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1170 ||
3982 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3983 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3984 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx13 ||
3985 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250 ||
3986 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx13;
3990 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3991 int I = getNamedOperandIdx(Opcode, OpName);
3995 int64_t
Imm =
Op.getImm();
4001 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
4002 OpName::vsrc2Y, OpName::imm}) {
4003 int I = getNamedOperandIdx(Opcode, OpName);
4013 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
4014 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
4016 return InvalidCompOprIdx;
4019bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
4026 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
4027 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
4028 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
4030 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
4034 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
4035 if (!InvalidCompOprIdx.has_value())
4038 auto CompOprIdx = *InvalidCompOprIdx;
4041 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4042 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4043 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4045 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4046 if (CompOprIdx == VOPD::Component::DST) {
4048 Error(Loc,
"dst registers must be distinct");
4050 Error(Loc,
"one dst register must be even and the other odd");
4052 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4053 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4054 " operands must use different VGPR banks");
4062bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4064 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4065 if (!InvalidCompOprIdx.has_value())
4069 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4070 if (InvalidCompOprIdx.has_value()) {
4075 if (*InvalidCompOprIdx == VOPD::Component::DST)
4088bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4089 const unsigned Opcode = Inst.
getOpcode();
4099 if (
II[
VOPD::X].getOpcode() == AMDGPU::V_CNDMASK_B32_e32 ||
4100 II[
VOPD::Y].getOpcode() == AMDGPU::V_CNDMASK_B32_e32)
4104 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4105 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4106 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4107 int I = getNamedOperandIdx(Opcode, OpName);
4114 return !tryVOPD3(Inst);
4119bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4120 const unsigned Opcode = Inst.
getOpcode();
4125 return tryVOPD(Inst);
4126 return tryVOPD3(Inst);
4129bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4135 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4146bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4154 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4155 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4156 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4164 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4165 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4170 bool IsPackedD16 =
false;
4174 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4175 IsPackedD16 = D16Idx >= 0;
4180 if ((VDataSize / 4) ==
DataSize + TFESize)
4185 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4187 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4189 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4193bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4202 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4204 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4206 ? AMDGPU::OpName::srsrc
4207 : AMDGPU::OpName::rsrc;
4208 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4209 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4210 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4214 assert(SrsrcIdx > VAddr0Idx);
4217 if (BaseOpcode->
BVH) {
4218 if (IsA16 == BaseOpcode->
A16)
4220 Error(IDLoc,
"image address size does not match a16");
4226 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4227 unsigned ActualAddrSize =
4228 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4230 unsigned ExpectedAddrSize =
4234 if (hasPartialNSAEncoding() &&
4237 int VAddrLastIdx = SrsrcIdx - 1;
4238 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4240 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4243 if (ExpectedAddrSize > 12)
4244 ExpectedAddrSize = 16;
4249 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4253 if (ActualAddrSize == ExpectedAddrSize)
4256 Error(IDLoc,
"image address size does not match dim and a16");
4260bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4267 if (!
Desc.mayLoad() || !
Desc.mayStore())
4270 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4277 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4280bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4288 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4296 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4299bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4314 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4315 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4322bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4330 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4333 if (!BaseOpcode->
MSAA)
4336 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4342 return DimInfo->
MSAA;
4348 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4349 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4350 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4360bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4369 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4372 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4380 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4384bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4389 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4392 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4395 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4402 Error(getOperandLoc(Operands, Src0Idx),
4403 "source operand must be either a VGPR or an inline constant");
4410bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4413 const MCInstrDesc &
Desc = MII.
get(Opcode);
4416 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4419 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4423 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4424 Error(getOperandLoc(Operands, Src2Idx),
4425 "inline constants are not allowed for this operand");
4432bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4440 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4441 if (BlgpIdx != -1) {
4442 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4443 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4453 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4454 Error(getOperandLoc(Operands, Src0Idx),
4455 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4460 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4461 Error(getOperandLoc(Operands, Src1Idx),
4462 "wrong register tuple size for blgp value " + Twine(BLGP));
4470 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4474 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4478 MCRegister Src2Reg = Src2.
getReg();
4480 if (Src2Reg == DstReg)
4485 .getSizeInBits() <= 128)
4488 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4489 Error(getOperandLoc(Operands, Src2Idx),
4490 "source 2 operand must not partially overlap with dst");
4497bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4501 case V_DIV_SCALE_F32_gfx6_gfx7:
4502 case V_DIV_SCALE_F32_vi:
4503 case V_DIV_SCALE_F32_gfx10:
4504 case V_DIV_SCALE_F64_gfx6_gfx7:
4505 case V_DIV_SCALE_F64_vi:
4506 case V_DIV_SCALE_F64_gfx10:
4512 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4513 AMDGPU::OpName::src2_modifiers,
4514 AMDGPU::OpName::src2_modifiers}) {
4525bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4533 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4542bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4549 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4557 case AMDGPU::V_SUBREV_F32_e32:
4558 case AMDGPU::V_SUBREV_F32_e64:
4559 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4560 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4561 case AMDGPU::V_SUBREV_F32_e32_vi:
4562 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4563 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4564 case AMDGPU::V_SUBREV_F32_e64_vi:
4566 case AMDGPU::V_SUBREV_CO_U32_e32:
4567 case AMDGPU::V_SUBREV_CO_U32_e64:
4568 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4569 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4571 case AMDGPU::V_SUBBREV_U32_e32:
4572 case AMDGPU::V_SUBBREV_U32_e64:
4573 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4574 case AMDGPU::V_SUBBREV_U32_e32_vi:
4575 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4576 case AMDGPU::V_SUBBREV_U32_e64_vi:
4578 case AMDGPU::V_SUBREV_U32_e32:
4579 case AMDGPU::V_SUBREV_U32_e64:
4580 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4581 case AMDGPU::V_SUBREV_U32_e32_vi:
4582 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4583 case AMDGPU::V_SUBREV_U32_e64_vi:
4585 case AMDGPU::V_SUBREV_F16_e32:
4586 case AMDGPU::V_SUBREV_F16_e64:
4587 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4588 case AMDGPU::V_SUBREV_F16_e32_vi:
4589 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4590 case AMDGPU::V_SUBREV_F16_e64_vi:
4592 case AMDGPU::V_SUBREV_U16_e32:
4593 case AMDGPU::V_SUBREV_U16_e64:
4594 case AMDGPU::V_SUBREV_U16_e32_vi:
4595 case AMDGPU::V_SUBREV_U16_e64_vi:
4597 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4598 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4599 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4601 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4602 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4604 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4605 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4607 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4608 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4610 case AMDGPU::V_LSHRREV_B32_e32:
4611 case AMDGPU::V_LSHRREV_B32_e64:
4612 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4613 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4614 case AMDGPU::V_LSHRREV_B32_e32_vi:
4615 case AMDGPU::V_LSHRREV_B32_e64_vi:
4616 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4617 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4619 case AMDGPU::V_ASHRREV_I32_e32:
4620 case AMDGPU::V_ASHRREV_I32_e64:
4621 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4622 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4623 case AMDGPU::V_ASHRREV_I32_e32_vi:
4624 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4625 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4626 case AMDGPU::V_ASHRREV_I32_e64_vi:
4628 case AMDGPU::V_LSHLREV_B32_e32:
4629 case AMDGPU::V_LSHLREV_B32_e64:
4630 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4631 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4632 case AMDGPU::V_LSHLREV_B32_e32_vi:
4633 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4634 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4635 case AMDGPU::V_LSHLREV_B32_e64_vi:
4637 case AMDGPU::V_LSHLREV_B16_e32:
4638 case AMDGPU::V_LSHLREV_B16_e64:
4639 case AMDGPU::V_LSHLREV_B16_e32_vi:
4640 case AMDGPU::V_LSHLREV_B16_e64_vi:
4641 case AMDGPU::V_LSHLREV_B16_gfx10:
4643 case AMDGPU::V_LSHRREV_B16_e32:
4644 case AMDGPU::V_LSHRREV_B16_e64:
4645 case AMDGPU::V_LSHRREV_B16_e32_vi:
4646 case AMDGPU::V_LSHRREV_B16_e64_vi:
4647 case AMDGPU::V_LSHRREV_B16_gfx10:
4649 case AMDGPU::V_ASHRREV_I16_e32:
4650 case AMDGPU::V_ASHRREV_I16_e64:
4651 case AMDGPU::V_ASHRREV_I16_e32_vi:
4652 case AMDGPU::V_ASHRREV_I16_e64_vi:
4653 case AMDGPU::V_ASHRREV_I16_gfx10:
4655 case AMDGPU::V_LSHLREV_B64_e64:
4656 case AMDGPU::V_LSHLREV_B64_gfx10:
4657 case AMDGPU::V_LSHLREV_B64_vi:
4659 case AMDGPU::V_LSHRREV_B64_e64:
4660 case AMDGPU::V_LSHRREV_B64_gfx10:
4661 case AMDGPU::V_LSHRREV_B64_vi:
4663 case AMDGPU::V_ASHRREV_I64_e64:
4664 case AMDGPU::V_ASHRREV_I64_gfx10:
4665 case AMDGPU::V_ASHRREV_I64_vi:
4667 case AMDGPU::V_PK_LSHLREV_B16:
4668 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4669 case AMDGPU::V_PK_LSHLREV_B16_vi:
4671 case AMDGPU::V_PK_LSHRREV_B16:
4672 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4673 case AMDGPU::V_PK_LSHRREV_B16_vi:
4674 case AMDGPU::V_PK_ASHRREV_I16:
4675 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4676 case AMDGPU::V_PK_ASHRREV_I16_vi:
4683bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4685 using namespace SIInstrFlags;
4686 const unsigned Opcode = Inst.
getOpcode();
4687 const MCInstrDesc &
Desc = MII.
get(Opcode);
4692 if ((
Desc.TSFlags & Enc) == 0)
4695 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4696 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4700 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4703 Error(getOperandLoc(Operands, SrcIdx),
4704 "lds_direct is not supported on this GPU");
4709 Error(getOperandLoc(Operands, SrcIdx),
4710 "lds_direct cannot be used with this instruction");
4714 if (SrcName != OpName::src0) {
4715 Error(getOperandLoc(Operands, SrcIdx),
4716 "lds_direct may be used as src0 only");
4725SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4726 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4727 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4728 if (
Op.isFlatOffset())
4729 return Op.getStartLoc();
4734bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4737 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4743 return validateFlatOffset(Inst, Operands);
4746 return validateSMEMOffset(Inst, Operands);
4752 const unsigned OffsetSize = 24;
4753 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4754 Error(getFlatOffsetLoc(Operands),
4755 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4756 "-bit unsigned offset for buffer ops");
4760 const unsigned OffsetSize = 16;
4761 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4762 Error(getFlatOffsetLoc(Operands),
4763 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4770bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4777 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4781 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4782 Error(getFlatOffsetLoc(Operands),
4783 "flat offset modifier is not supported on this GPU");
4790 bool AllowNegative =
4793 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4794 Error(getFlatOffsetLoc(Operands),
4795 Twine(
"expected a ") +
4796 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4797 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4804SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4806 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4807 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4808 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4809 return Op.getStartLoc();
4814bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4824 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4838 Error(getSMEMOffsetLoc(Operands),
4840 ?
"expected a 23-bit unsigned offset for buffer ops"
4841 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4842 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4843 :
"expected a 21-bit signed offset");
4848bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4851 const MCInstrDesc &
Desc = MII.
get(Opcode);
4855 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4856 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4858 const int OpIndices[] = { Src0Idx, Src1Idx };
4860 unsigned NumExprs = 0;
4861 unsigned NumLiterals = 0;
4864 for (
int OpIdx : OpIndices) {
4865 if (
OpIdx == -1)
break;
4871 std::optional<int64_t>
Imm;
4874 }
else if (MO.
isExpr()) {
4883 if (!
Imm.has_value()) {
4885 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4889 if (NumLiterals == 0 || LiteralValue !=
Value) {
4897 if (NumLiterals + NumExprs <= 1)
4900 Error(getOperandLoc(Operands, Src1Idx),
4901 "only one unique literal operand is allowed");
4905bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4908 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4918 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4919 if (OpSelIdx != -1) {
4923 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4924 if (OpSelHiIdx != -1) {
4933 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4943 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4944 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4945 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4946 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4948 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4949 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4955 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4957 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4967 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4968 if (Src2Idx != -1) {
4969 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4979bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4980 if (!hasTrue16Insts())
4982 const MCRegisterInfo *MRI = getMRI();
4984 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4990 if (OpSelOpValue == 0)
4992 unsigned OpCount = 0;
4993 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4994 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4995 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
5002 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
5003 if (OpSelOpIsHi != VGPRSuffixIsHi)
5012bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
5013 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
5026 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
5037 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
5038 AMDGPU::OpName::src1_modifiers,
5039 AMDGPU::OpName::src2_modifiers};
5041 for (
unsigned i = 0; i < 3; ++i) {
5051bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5054 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5055 if (DppCtrlIdx >= 0) {
5062 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5063 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5064 :
"DP ALU dpp only supports row_newbcast");
5069 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5070 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5073 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5075 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5078 Error(getOperandLoc(Operands, Src1Idx),
5079 "invalid operand for instruction");
5083 Error(getInstLoc(Operands),
5084 "src1 immediate operand invalid for instruction");
5094bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5095 return (
Reg == AMDGPU::VCC && isWave64()) ||
5096 (
Reg == AMDGPU::VCC_LO && isWave32());
5100bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5103 const MCInstrDesc &
Desc = MII.
get(Opcode);
5104 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5106 !HasMandatoryLiteral && !
isVOPD(Opcode))
5111 std::optional<unsigned> LiteralOpIdx;
5114 for (
int OpIdx : OpIndices) {
5124 std::optional<int64_t>
Imm;
5130 bool IsAnotherLiteral =
false;
5131 bool IsForcedLit64 = findMCOperand(Operands,
OpIdx).isForcedLit64();
5132 if (!
Imm.has_value()) {
5134 IsAnotherLiteral =
true;
5135 }
else if (IsForcedLit64 || !isInlineConstant(Inst,
OpIdx)) {
5140 HasMandatoryLiteral);
5147 (IsForcedLit64 && !HasMandatoryLiteral)) &&
5148 (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5150 "invalid operand for instruction");
5154 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5161 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5162 !getFeatureBits()[FeatureVOP3Literal]) {
5164 "literal operands are not supported");
5168 if (LiteralOpIdx && IsAnotherLiteral) {
5169 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5170 getOperandLoc(Operands, *LiteralOpIdx)),
5171 "only one unique literal operand is allowed");
5175 if (IsAnotherLiteral)
5176 LiteralOpIdx =
OpIdx;
5199bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5207 ? AMDGPU::OpName::data0
5208 : AMDGPU::OpName::vdata;
5210 const MCRegisterInfo *MRI = getMRI();
5211 int DstAreg =
IsAGPROperand(Inst, AMDGPU::OpName::vdst, MRI);
5215 int Data2Areg =
IsAGPROperand(Inst, AMDGPU::OpName::data1, MRI);
5216 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5220 auto FB = getFeatureBits();
5221 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5222 if (DataAreg < 0 || DstAreg < 0)
5224 return DstAreg == DataAreg;
5227 return DstAreg < 1 && DataAreg < 1;
5230bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5231 auto FB = getFeatureBits();
5232 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5236 const MCRegisterInfo *MRI = getMRI();
5239 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5242 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5246 case AMDGPU::DS_LOAD_TR6_B96:
5247 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5251 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5252 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5256 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5257 if (VAddrIdx != -1) {
5260 if ((
Sub - AMDGPU::VGPR0) & 1)
5265 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5266 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5271 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5272 const MCRegisterClass &AGPR32 = MRI->
getRegClass(AMDGPU::AGPR_32RegClassID);
5291SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5292 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5293 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5295 return Op.getStartLoc();
5300bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5303 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5306 SMLoc BLGPLoc = getBLGPLoc(Operands);
5309 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5310 auto FB = getFeatureBits();
5311 bool UsesNeg =
false;
5312 if (FB[AMDGPU::FeatureGFX940Insts]) {
5314 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5315 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5316 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5317 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5322 if (IsNeg == UsesNeg)
5326 UsesNeg ?
"invalid modifier: blgp is not supported"
5327 :
"invalid modifier: neg is not supported");
5332bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5338 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5339 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5340 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5341 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5344 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5347 if (
Reg == AMDGPU::SGPR_NULL)
5350 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5354bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5360 return validateGWS(Inst, Operands);
5365 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5370 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5371 Error(S,
"gds modifier is not supported on this GPU");
5379bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5381 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5385 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5386 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5389 const MCRegisterInfo *MRI = getMRI();
5390 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5392 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5395 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5397 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5404bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5407 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5408 AMDGPU::OpName::cpol);
5416 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5419 Error(S,
"scale_offset is not supported on this GPU");
5422 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5425 Error(S,
"nv is not supported on this GPU");
5430 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5433 Error(S,
"scale_offset is not supported for this instruction");
5437 return validateTHAndScopeBits(Inst, Operands, CPol);
5442 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5443 Error(S,
"cache policy is not supported for SMRD instructions");
5447 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5456 if (!(TSFlags & AllowSCCModifier)) {
5457 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5461 "scc modifier is not supported for this instruction on this GPU");
5472 :
"instruction must use glc");
5477 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5480 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5482 :
"instruction must not use glc");
5490bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5492 const unsigned CPol) {
5496 const unsigned Opcode = Inst.
getOpcode();
5497 const MCInstrDesc &TID = MII.
get(Opcode);
5500 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5507 return PrintError(
"th:TH_ATOMIC_RETURN requires a destination operand");
5512 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5520 return PrintError(
"invalid th value for SMEM instruction");
5527 return PrintError(
"scope and th combination is not valid");
5533 return PrintError(
"invalid th value for atomic instructions");
5536 return PrintError(
"invalid th value for store instructions");
5539 return PrintError(
"invalid th value for load instructions");
5545bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5548 if (
Desc.mayStore() &&
5550 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5551 if (Loc != getInstLoc(Operands)) {
5552 Error(Loc,
"TFE modifier has no meaning for store instructions");
5560bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5566 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5567 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5571 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5579 Error(getOperandLoc(Operands, SrcIdx),
5580 "wrong register tuple size for " +
5585 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5586 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5589bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5591 if (!validateLdsDirect(Inst, Operands))
5593 if (!validateTrue16OpSel(Inst)) {
5594 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5595 "op_sel operand conflicts with 16-bit operand suffix");
5598 if (!validateSOPLiteral(Inst, Operands))
5600 if (!validateVOPLiteral(Inst, Operands)) {
5603 if (!validateConstantBusLimitations(Inst, Operands)) {
5606 if (!validateVOPD(Inst, Operands)) {
5609 if (!validateIntClampSupported(Inst)) {
5610 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5611 "integer clamping is not supported on this GPU");
5614 if (!validateOpSel(Inst)) {
5615 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5616 "invalid op_sel operand");
5619 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5620 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5621 "invalid neg_lo operand");
5624 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5625 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5626 "invalid neg_hi operand");
5629 if (!validateDPP(Inst, Operands)) {
5633 if (!validateMIMGD16(Inst)) {
5634 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5635 "d16 modifier is not supported on this GPU");
5638 if (!validateMIMGDim(Inst, Operands)) {
5639 Error(IDLoc,
"missing dim operand");
5642 if (!validateTensorR128(Inst)) {
5643 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5644 "instruction must set modifier r128=0");
5647 if (!validateMIMGMSAA(Inst)) {
5648 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5649 "invalid dim; must be MSAA type");
5652 if (!validateMIMGDataSize(Inst, IDLoc)) {
5655 if (!validateMIMGAddrSize(Inst, IDLoc))
5657 if (!validateMIMGAtomicDMask(Inst)) {
5658 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5659 "invalid atomic image dmask");
5662 if (!validateMIMGGatherDMask(Inst)) {
5663 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5664 "invalid image_gather dmask: only one bit must be set");
5667 if (!validateMovrels(Inst, Operands)) {
5670 if (!validateOffset(Inst, Operands)) {
5673 if (!validateMAIAccWrite(Inst, Operands)) {
5676 if (!validateMAISrc2(Inst, Operands)) {
5679 if (!validateMFMA(Inst, Operands)) {
5682 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5686 if (!validateAGPRLdSt(Inst)) {
5687 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5688 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5689 :
"invalid register class: agpr loads and stores not supported on this GPU"
5693 if (!validateVGPRAlign(Inst)) {
5695 "invalid register class: vgpr tuples must be 64 bit aligned");
5698 if (!validateDS(Inst, Operands)) {
5702 if (!validateBLGP(Inst, Operands)) {
5706 if (!validateDivScale(Inst)) {
5707 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5710 if (!validateWaitCnt(Inst, Operands)) {
5713 if (!validateTFE(Inst, Operands)) {
5716 if (!validateWMMA(Inst, Operands)) {
5725 unsigned VariantID = 0);
5729 unsigned VariantID);
5731bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5736bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5737 const FeatureBitset &FBS,
5738 ArrayRef<unsigned> Variants) {
5739 for (
auto Variant : Variants) {
5747bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5749 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5752 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5757 getParser().clearPendingErrors();
5761 StringRef VariantName = getMatchedVariantName();
5762 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5765 " variant of this instruction is not supported"));
5769 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5770 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5772 FeatureBitset FeaturesWS32 = getFeatureBits();
5773 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5774 .
flip(AMDGPU::FeatureWavefrontSize32);
5775 FeatureBitset AvailableFeaturesWS32 =
5776 ComputeAvailableFeatures(FeaturesWS32);
5778 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5779 return Error(IDLoc,
"instruction requires wavesize=32");
5783 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5784 return Error(IDLoc,
"instruction not supported on this GPU (" +
5785 getSTI().
getCPU() +
")" +
": " + Mnemo);
5790 return Error(IDLoc,
"invalid instruction" + Suggestion);
5796 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5797 if (
Op.isToken() && InvalidOprIdx > 1) {
5798 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5799 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5804bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5807 uint64_t &ErrorInfo,
5808 bool MatchingInlineAsm) {
5811 unsigned Result = Match_Success;
5812 for (
auto Variant : getMatchedVariants()) {
5814 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5819 if (R == Match_Success || R == Match_MissingFeature ||
5820 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5821 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5822 Result != Match_MissingFeature)) {
5826 if (R == Match_Success)
5830 if (Result == Match_Success) {
5831 if (!validateInstruction(Inst, IDLoc, Operands)) {
5838 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5839 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5845 case Match_MissingFeature:
5849 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5851 case Match_InvalidOperand: {
5852 SMLoc ErrorLoc = IDLoc;
5853 if (ErrorInfo != ~0ULL) {
5854 if (ErrorInfo >= Operands.
size()) {
5855 return Error(IDLoc,
"too few operands for instruction");
5857 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5858 if (ErrorLoc == SMLoc())
5862 return Error(ErrorLoc,
"invalid VOPDY instruction");
5864 return Error(ErrorLoc,
"invalid operand for instruction");
5867 case Match_MnemonicFail:
5873bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5878 if (getParser().parseAbsoluteExpression(Tmp)) {
5881 Ret =
static_cast<uint32_t
>(Tmp);
5885bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5886 if (!getSTI().getTargetTriple().isAMDGCN())
5887 return TokError(
"directive only supported for amdgcn architecture");
5889 std::string TargetIDDirective;
5890 SMLoc TargetStart = getTok().getLoc();
5891 if (getParser().parseEscapedString(TargetIDDirective))
5894 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5895 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5896 return getParser().Error(TargetRange.
Start,
5897 (Twine(
".amdgcn_target directive's target id ") +
5898 Twine(TargetIDDirective) +
5899 Twine(
" does not match the specified target id ") +
5900 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5905bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5909bool AMDGPUAsmParser::calculateGPRBlocks(
5910 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5911 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5912 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5913 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5914 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5920 const MCExpr *
NumSGPRs = NextFreeSGPR;
5921 int64_t EvaluatedSGPRs;
5926 unsigned MaxAddressableNumSGPRs =
5929 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5930 !Features.
test(FeatureSGPRInitBug) &&
5931 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5932 return OutOfRangeError(SGPRRange);
5934 const MCExpr *ExtraSGPRs =
5938 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5939 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5940 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5941 return OutOfRangeError(SGPRRange);
5943 if (Features.
test(FeatureSGPRInitBug))
5950 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5951 unsigned Granule) ->
const MCExpr * {
5955 const MCExpr *AlignToGPR =
5957 const MCExpr *DivGPR =
5963 VGPRBlocks = GetNumGPRBlocks(
5972bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5973 if (!getSTI().getTargetTriple().isAMDGCN())
5974 return TokError(
"directive only supported for amdgcn architecture");
5977 return TokError(
"directive only supported for amdhsa OS");
5979 StringRef KernelName;
5980 if (getParser().parseIdentifier(KernelName))
5983 AMDGPU::MCKernelDescriptor KD =
5995 const MCExpr *NextFreeVGPR = ZeroExpr;
5997 const MCExpr *NamedBarCnt = ZeroExpr;
5998 uint64_t SharedVGPRCount = 0;
5999 uint64_t PreloadLength = 0;
6000 uint64_t PreloadOffset = 0;
6002 const MCExpr *NextFreeSGPR = ZeroExpr;
6005 unsigned ImpliedUserSGPRCount = 0;
6009 std::optional<unsigned> ExplicitUserSGPRCount;
6010 const MCExpr *ReserveVCC = OneExpr;
6011 const MCExpr *ReserveFlatScr = OneExpr;
6012 std::optional<bool> EnableWavefrontSize32;
6018 SMRange IDRange = getTok().getLocRange();
6019 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6022 if (
ID ==
".end_amdhsa_kernel")
6026 return TokError(
".amdhsa_ directives cannot be repeated");
6028 SMLoc ValStart = getLoc();
6029 const MCExpr *ExprVal;
6030 if (getParser().parseExpression(ExprVal))
6032 SMLoc ValEnd = getLoc();
6033 SMRange ValRange = SMRange(ValStart, ValEnd);
6036 uint64_t Val = IVal;
6037 bool EvaluatableExpr;
6038 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6040 return OutOfRangeError(ValRange);
6044#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6045 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6046 return OutOfRangeError(RANGE); \
6047 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6052#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6054 return Error(IDRange.Start, "directive should have resolvable expression", \
6057 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6060 return OutOfRangeError(ValRange);
6062 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6065 return OutOfRangeError(ValRange);
6067 }
else if (
ID ==
".amdhsa_kernarg_size") {
6069 return OutOfRangeError(ValRange);
6071 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6073 ExplicitUserSGPRCount = Val;
6074 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6078 "directive is not supported with architected flat scratch",
6081 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6084 ImpliedUserSGPRCount += 4;
6085 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6088 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6091 return OutOfRangeError(ValRange);
6095 ImpliedUserSGPRCount += Val;
6096 PreloadLength = Val;
6098 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6101 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6104 return OutOfRangeError(ValRange);
6108 PreloadOffset = Val;
6109 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6112 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6115 ImpliedUserSGPRCount += 2;
6116 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6119 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6122 ImpliedUserSGPRCount += 2;
6123 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6126 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6129 ImpliedUserSGPRCount += 2;
6130 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6133 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6136 ImpliedUserSGPRCount += 2;
6137 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6140 "directive is not supported with architected flat scratch",
6144 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6147 ImpliedUserSGPRCount += 2;
6148 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6151 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6154 ImpliedUserSGPRCount += 1;
6155 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6157 if (IVersion.
Major < 10)
6158 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6159 EnableWavefrontSize32 = Val;
6161 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6163 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6165 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6167 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6170 "directive is not supported with architected flat scratch",
6173 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6175 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6179 "directive is not supported without architected flat scratch",
6182 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6184 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6186 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6188 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6190 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6192 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6194 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6196 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6198 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6200 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6202 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6204 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6205 VGPRRange = ValRange;
6206 NextFreeVGPR = ExprVal;
6207 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6208 SGPRRange = ValRange;
6209 NextFreeSGPR = ExprVal;
6210 }
else if (
ID ==
".amdhsa_accum_offset") {
6212 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6213 AccumOffset = ExprVal;
6214 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6216 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6217 NamedBarCnt = ExprVal;
6218 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6220 return OutOfRangeError(ValRange);
6221 ReserveVCC = ExprVal;
6222 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6223 if (IVersion.
Major < 7)
6224 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6227 "directive is not supported with architected flat scratch",
6230 return OutOfRangeError(ValRange);
6231 ReserveFlatScr = ExprVal;
6232 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6233 if (IVersion.
Major < 8)
6234 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6236 return OutOfRangeError(ValRange);
6237 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6238 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6240 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6242 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6244 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6246 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6248 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6250 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6252 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6254 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6256 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6257 if (!getSTI().hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6258 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6261 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6263 }
else if (
ID ==
".amdhsa_ieee_mode") {
6264 if (!getSTI().hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6265 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6268 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6270 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6271 if (IVersion.
Major < 9)
6272 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6274 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6276 }
else if (
ID ==
".amdhsa_tg_split") {
6278 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6281 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6284 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6286 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6288 }
else if (
ID ==
".amdhsa_memory_ordered") {
6289 if (IVersion.
Major < 10)
6290 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6292 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6294 }
else if (
ID ==
".amdhsa_forward_progress") {
6295 if (IVersion.
Major < 10)
6296 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6298 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6300 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6302 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6303 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6305 SharedVGPRCount = Val;
6307 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6309 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6310 if (IVersion.
Major < 11)
6311 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6312 if (IVersion.
Major == 11) {
6314 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6318 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6321 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6324 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6326 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6328 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6330 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6333 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6335 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6337 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6339 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6341 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6343 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6345 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6347 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6349 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6351 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6352 if (IVersion.
Major < 12)
6353 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6355 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6358 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6361#undef PARSE_BITS_ENTRY
6364 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6365 return TokError(
".amdhsa_next_free_vgpr directive is required");
6367 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6368 return TokError(
".amdhsa_next_free_sgpr directive is required");
6370 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6372 return TokError(
"too many user SGPRs enabled, found " +
6373 Twine(UserSGPRCount) +
", but only " +
6379 if (PreloadLength) {
6385 const MCExpr *VGPRBlocks;
6386 const MCExpr *SGPRBlocks;
6387 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6388 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6389 EnableWavefrontSize32, NextFreeVGPR,
6390 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6394 int64_t EvaluatedVGPRBlocks;
6395 bool VGPRBlocksEvaluatable =
6396 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6397 if (VGPRBlocksEvaluatable &&
6399 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6400 return OutOfRangeError(VGPRRange);
6404 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6405 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6407 int64_t EvaluatedSGPRBlocks;
6408 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6410 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6411 return OutOfRangeError(SGPRRange);
6414 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6415 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6417 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6418 return TokError(
"amdgpu_user_sgpr_count smaller than implied by "
6419 "enabled user SGPRs");
6425 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6426 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6431 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6432 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6437 return TokError(
"Kernarg size should be resolvable");
6438 uint64_t kernarg_size = IVal;
6439 if (PreloadLength && kernarg_size &&
6440 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6441 return TokError(
"Kernarg preload length + offset is larger than the "
6442 "kernarg segment size");
6445 if (!Seen.
contains(
".amdhsa_accum_offset"))
6446 return TokError(
".amdhsa_accum_offset directive is required");
6447 int64_t EvaluatedAccum;
6448 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6449 uint64_t UEvaluatedAccum = EvaluatedAccum;
6450 if (AccumEvaluatable &&
6451 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6452 return TokError(
"accum_offset should be in range [4..256] in "
6455 int64_t EvaluatedNumVGPR;
6456 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6459 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6460 return TokError(
"accum_offset exceeds total VGPR allocation");
6466 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6467 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6473 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6474 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6477 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6479 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6480 return TokError(
"shared_vgpr_count directive not valid on "
6481 "wavefront size 32");
6484 if (VGPRBlocksEvaluatable &&
6485 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6487 return TokError(
"shared_vgpr_count*2 + "
6488 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6493 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6494 NextFreeVGPR, NextFreeSGPR,
6495 ReserveVCC, ReserveFlatScr);
6499bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6501 if (ParseAsAbsoluteExpression(
Version))
6504 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6508bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6509 AMDGPUMCKernelCodeT &
C) {
6512 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6513 Parser.eatToEndOfStatement();
6517 SmallString<40> ErrStr;
6518 raw_svector_ostream Err(ErrStr);
6519 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6520 return TokError(Err.
str());
6524 if (
ID ==
"enable_wavefront_size32") {
6527 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6529 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6532 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6536 if (
ID ==
"wavefront_size") {
6537 if (
C.wavefront_size == 5) {
6539 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6541 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6542 }
else if (
C.wavefront_size == 6) {
6544 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6551bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6552 AMDGPUMCKernelCodeT KernelCode;
6561 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6564 if (
ID ==
".end_amd_kernel_code_t")
6567 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6572 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6577bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6578 StringRef KernelName;
6579 if (!parseId(KernelName,
"expected symbol name"))
6582 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6589bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6590 if (!getSTI().getTargetTriple().isAMDGCN()) {
6591 return Error(getLoc(),
6592 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6596 auto TargetIDDirective = getLexer().getTok().getStringContents();
6597 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6598 return Error(getParser().getTok().getLoc(),
"target id must match options");
6600 getTargetStreamer().EmitISAVersion();
6606bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6609 std::string HSAMetadataString;
6614 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6615 return Error(getLoc(),
"invalid HSA metadata");
6622bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6623 const char *AssemblerDirectiveEnd,
6624 std::string &CollectString) {
6626 raw_string_ostream CollectStream(CollectString);
6628 getLexer().setSkipSpace(
false);
6630 bool FoundEnd =
false;
6633 CollectStream << getTokenStr();
6637 if (trySkipId(AssemblerDirectiveEnd)) {
6642 CollectStream << Parser.parseStringToEndOfStatement()
6643 <<
getContext().getAsmInfo().getSeparatorString();
6645 Parser.eatToEndOfStatement();
6648 getLexer().setSkipSpace(
true);
6651 return TokError(Twine(
"expected directive ") +
6652 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6659bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6665 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6666 if (!PALMetadata->setFromString(
String))
6667 return Error(getLoc(),
"invalid PAL metadata");
6672bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6674 return Error(getLoc(),
6676 "not available on non-amdpal OSes")).str());
6679 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6680 PALMetadata->setLegacy();
6683 if (ParseAsAbsoluteExpression(
Key)) {
6684 return TokError(Twine(
"invalid value in ") +
6688 return TokError(Twine(
"expected an even number of values in ") +
6691 if (ParseAsAbsoluteExpression(
Value)) {
6692 return TokError(Twine(
"invalid value in ") +
6695 PALMetadata->setRegister(
Key,
Value);
6704bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6705 if (getParser().checkForValidSection())
6709 SMLoc NameLoc = getLoc();
6710 if (getParser().parseIdentifier(Name))
6711 return TokError(
"expected identifier in directive");
6714 if (getParser().parseComma())
6720 SMLoc SizeLoc = getLoc();
6721 if (getParser().parseAbsoluteExpression(
Size))
6724 return Error(SizeLoc,
"size must be non-negative");
6725 if (
Size > LocalMemorySize)
6726 return Error(SizeLoc,
"size is too large");
6728 int64_t Alignment = 4;
6730 SMLoc AlignLoc = getLoc();
6731 if (getParser().parseAbsoluteExpression(Alignment))
6734 return Error(AlignLoc,
"alignment must be a power of two");
6739 if (Alignment >= 1u << 31)
6740 return Error(AlignLoc,
"alignment is too large");
6746 Symbol->redefineIfPossible();
6747 if (!
Symbol->isUndefined())
6748 return Error(NameLoc,
"invalid symbol redefinition");
6750 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6754bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6755 StringRef IDVal = DirectiveID.
getString();
6758 if (IDVal ==
".amdhsa_kernel")
6759 return ParseDirectiveAMDHSAKernel();
6761 if (IDVal ==
".amdhsa_code_object_version")
6762 return ParseDirectiveAMDHSACodeObjectVersion();
6766 return ParseDirectiveHSAMetadata();
6768 if (IDVal ==
".amd_kernel_code_t")
6769 return ParseDirectiveAMDKernelCodeT();
6771 if (IDVal ==
".amdgpu_hsa_kernel")
6772 return ParseDirectiveAMDGPUHsaKernel();
6774 if (IDVal ==
".amd_amdgpu_isa")
6775 return ParseDirectiveISAVersion();
6779 Twine(
" directive is "
6780 "not available on non-amdhsa OSes"))
6785 if (IDVal ==
".amdgcn_target")
6786 return ParseDirectiveAMDGCNTarget();
6788 if (IDVal ==
".amdgpu_lds")
6789 return ParseDirectiveAMDGPULDS();
6792 return ParseDirectivePALMetadataBegin();
6795 return ParseDirectivePALMetadata();
6800bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &MRI,
6807 return hasSGPR104_SGPR105();
6810 case SRC_SHARED_BASE_LO:
6811 case SRC_SHARED_BASE:
6812 case SRC_SHARED_LIMIT_LO:
6813 case SRC_SHARED_LIMIT:
6814 case SRC_PRIVATE_BASE_LO:
6815 case SRC_PRIVATE_BASE:
6816 case SRC_PRIVATE_LIMIT_LO:
6817 case SRC_PRIVATE_LIMIT:
6819 case SRC_FLAT_SCRATCH_BASE_LO:
6820 case SRC_FLAT_SCRATCH_BASE_HI:
6821 return hasGloballyAddressableScratch();
6822 case SRC_POPS_EXITING_WAVE_ID:
6834 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6864 return hasSGPR102_SGPR103();
6869ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6872 ParseStatus Res = parseVOPD(Operands);
6877 Res = MatchOperandParserImpl(Operands, Mnemonic);
6889 SMLoc LBraceLoc = getLoc();
6894 auto Loc = getLoc();
6895 Res = parseReg(Operands);
6897 Error(Loc,
"expected a register");
6901 RBraceLoc = getLoc();
6906 "expected a comma or a closing square bracket"))
6910 if (Operands.
size() - Prefix > 1) {
6912 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6913 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6919 return parseRegOrImm(Operands);
6922StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6924 setForcedEncodingSize(0);
6925 setForcedDPP(
false);
6926 setForcedSDWA(
false);
6928 if (
Name.consume_back(
"_e64_dpp")) {
6930 setForcedEncodingSize(64);
6933 if (
Name.consume_back(
"_e64")) {
6934 setForcedEncodingSize(64);
6937 if (
Name.consume_back(
"_e32")) {
6938 setForcedEncodingSize(32);
6941 if (
Name.consume_back(
"_dpp")) {
6945 if (
Name.consume_back(
"_sdwa")) {
6946 setForcedSDWA(
true);
6954 unsigned VariantID);
6960 Name = parseMnemonicSuffix(Name);
6966 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6968 bool IsMIMG = Name.starts_with(
"image_");
6971 OperandMode
Mode = OperandMode_Default;
6973 Mode = OperandMode_NSA;
6977 checkUnsupportedInstruction(Name, NameLoc);
6978 if (!Parser.hasPendingError()) {
6981 :
"not a valid operand.";
6982 Error(getLoc(), Msg);
7001ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
7004 if (!trySkipId(Name))
7007 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
7011ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7020ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7021 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7022 std::function<
bool(int64_t &)> ConvertResult) {
7026 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7030 if (ConvertResult && !ConvertResult(
Value)) {
7031 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7034 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7038ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7039 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7040 bool (*ConvertResult)(int64_t &)) {
7049 const unsigned MaxSize = 4;
7053 for (
int I = 0; ; ++
I) {
7055 SMLoc Loc = getLoc();
7059 if (
Op != 0 &&
Op != 1)
7060 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7067 if (
I + 1 == MaxSize)
7068 return Error(getLoc(),
"expected a closing square bracket");
7074 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7078ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7080 AMDGPUOperand::ImmTy ImmTy,
7081 bool IgnoreNegative) {
7085 if (trySkipId(Name)) {
7087 }
else if (trySkipId(
"no", Name)) {
7096 return Error(S,
"r128 modifier is not supported on this GPU");
7097 if (Name ==
"a16" && !
hasA16())
7098 return Error(S,
"a16 modifier is not supported on this GPU");
7100 if (Bit == 0 && Name ==
"gds") {
7101 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7103 return Error(S,
"nogds is not allowed");
7106 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7107 ImmTy = AMDGPUOperand::ImmTyR128A16;
7109 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7113unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7114 bool &Disabling)
const {
7115 Disabling =
Id.consume_front(
"no");
7118 return StringSwitch<unsigned>(Id)
7125 return StringSwitch<unsigned>(Id)
7133ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7135 SMLoc StringLoc = getLoc();
7137 int64_t CPolVal = 0;
7146 ResTH = parseTH(Operands, TH);
7157 ResScope = parseScope(Operands, Scope);
7170 if (trySkipId(
"nv")) {
7174 }
else if (trySkipId(
"no",
"nv")) {
7181 if (trySkipId(
"scale_offset")) {
7185 }
else if (trySkipId(
"no",
"scale_offset")) {
7198 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7199 AMDGPUOperand::ImmTyCPol));
7203 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7204 SMLoc OpLoc = getLoc();
7205 unsigned Enabled = 0, Seen = 0;
7209 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7216 return Error(S,
"dlc modifier is not supported on this GPU");
7219 return Error(S,
"scc modifier is not supported on this GPU");
7222 return Error(S,
"duplicate cache policy modifier");
7234 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7238ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7243 ParseStatus Res = parseStringOrIntWithPrefix(
7244 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7253ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7258 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7262 if (
Value ==
"TH_DEFAULT")
7264 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7265 Value ==
"TH_LOAD_NT_WB") {
7266 return Error(StringLoc,
"invalid th value");
7267 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7269 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7271 }
else if (
Value.consume_front(
"TH_STORE_")) {
7274 return Error(StringLoc,
"invalid th value");
7277 if (
Value ==
"BYPASS")
7282 TH |= StringSwitch<int64_t>(
Value)
7292 .Default(0xffffffff);
7294 TH |= StringSwitch<int64_t>(
Value)
7305 .Default(0xffffffff);
7308 if (TH == 0xffffffff)
7309 return Error(StringLoc,
"invalid th value");
7316 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7317 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7318 std::optional<unsigned> InsertAt = std::nullopt) {
7319 auto i = OptionalIdx.find(ImmT);
7320 if (i != OptionalIdx.end()) {
7321 unsigned Idx = i->second;
7322 const AMDGPUOperand &
Op =
7323 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7327 Op.addImmOperands(Inst, 1);
7329 if (InsertAt.has_value())
7336ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7342 StringLoc = getLoc();
7347ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7348 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7353 SMLoc StringLoc = getLoc();
7357 Value = getTokenStr();
7361 if (
Value == Ids[IntVal])
7366 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7367 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7372ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7373 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7374 AMDGPUOperand::ImmTy
Type) {
7378 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7380 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7389bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7393 SMLoc Loc = getLoc();
7395 auto Res = parseIntWithPrefix(Pref, Val);
7401 if (Val < 0 || Val > MaxVal) {
7402 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7410ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7411 AMDGPUOperand::ImmTy ImmTy) {
7412 const char *Pref =
"index_key";
7414 SMLoc Loc = getLoc();
7415 auto Res = parseIntWithPrefix(Pref, ImmVal);
7419 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7420 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7421 (ImmVal < 0 || ImmVal > 1))
7422 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7424 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7425 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7427 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7431ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7432 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7435ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7436 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7439ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7440 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7443ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7445 AMDGPUOperand::ImmTy
Type) {
7450ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7451 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7452 AMDGPUOperand::ImmTyMatrixAFMT);
7455ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7456 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7457 AMDGPUOperand::ImmTyMatrixBFMT);
7460ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7462 AMDGPUOperand::ImmTy
Type) {
7467ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7468 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7469 AMDGPUOperand::ImmTyMatrixAScale);
7472ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7473 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7474 AMDGPUOperand::ImmTyMatrixBScale);
7477ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7479 AMDGPUOperand::ImmTy
Type) {
7484ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7485 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7486 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7489ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7490 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7491 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7496ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7497 using namespace llvm::AMDGPU::MTBUFFormat;
7503 for (
int I = 0;
I < 2; ++
I) {
7504 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7507 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7512 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7518 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7521 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7522 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7528ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7529 using namespace llvm::AMDGPU::MTBUFFormat;
7533 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7536 if (Fmt == UFMT_UNDEF)
7543bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7545 StringRef FormatStr,
7547 using namespace llvm::AMDGPU::MTBUFFormat;
7551 if (
Format != DFMT_UNDEF) {
7557 if (
Format != NFMT_UNDEF) {
7562 Error(Loc,
"unsupported format");
7566ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7569 using namespace llvm::AMDGPU::MTBUFFormat;
7573 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7578 SMLoc Loc = getLoc();
7579 if (!parseId(Str,
"expected a format string") ||
7580 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7582 if (Dfmt == DFMT_UNDEF)
7583 return Error(Loc,
"duplicate numeric format");
7584 if (Nfmt == NFMT_UNDEF)
7585 return Error(Loc,
"duplicate data format");
7588 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7589 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7593 if (Ufmt == UFMT_UNDEF)
7594 return Error(FormatLoc,
"unsupported format");
7603ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7606 using namespace llvm::AMDGPU::MTBUFFormat;
7609 if (Id == UFMT_UNDEF)
7613 return Error(Loc,
"unified format is not supported on this GPU");
7619ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7620 using namespace llvm::AMDGPU::MTBUFFormat;
7621 SMLoc Loc = getLoc();
7626 return Error(Loc,
"out of range format");
7631ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7632 using namespace llvm::AMDGPU::MTBUFFormat;
7638 StringRef FormatStr;
7639 SMLoc Loc = getLoc();
7640 if (!parseId(FormatStr,
"expected a format string"))
7643 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7645 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7655 return parseNumericFormat(
Format);
7658ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7659 using namespace llvm::AMDGPU::MTBUFFormat;
7663 SMLoc Loc = getLoc();
7673 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7685 Res = parseRegOrImm(Operands);
7692 Res = parseSymbolicOrNumericFormat(
Format);
7697 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7698 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7705 return Error(getLoc(),
"duplicate format");
7709ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7711 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7713 Res = parseIntWithPrefix(
"inst_offset", Operands,
7714 AMDGPUOperand::ImmTyInstOffset);
7719ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7721 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7723 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7727ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7729 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7732 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7741void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7742 OptionalImmIndexMap OptionalIdx;
7744 unsigned OperandIdx[4];
7745 unsigned EnMask = 0;
7748 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7749 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7754 OperandIdx[SrcIdx] = Inst.
size();
7755 Op.addRegOperands(Inst, 1);
7762 OperandIdx[SrcIdx] = Inst.
size();
7768 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7769 Op.addImmOperands(Inst, 1);
7773 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7777 OptionalIdx[
Op.getImmTy()] = i;
7783 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7790 for (
auto i = 0; i < SrcIdx; ++i) {
7792 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7817 IntVal =
encode(ISA, IntVal, CntVal);
7818 if (CntVal !=
decode(ISA, IntVal)) {
7820 IntVal =
encode(ISA, IntVal, -1);
7828bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7830 SMLoc CntLoc = getLoc();
7831 StringRef CntName = getTokenStr();
7838 SMLoc ValLoc = getLoc();
7847 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7849 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7851 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7854 Error(CntLoc,
"invalid counter name " + CntName);
7859 Error(ValLoc,
"too large value for " + CntName);
7868 Error(getLoc(),
"expected a counter name");
7876ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7883 if (!parseCnt(Waitcnt))
7891 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7895bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7896 SMLoc FieldLoc = getLoc();
7897 StringRef FieldName = getTokenStr();
7902 SMLoc ValueLoc = getLoc();
7909 if (FieldName ==
"instid0") {
7911 }
else if (FieldName ==
"instskip") {
7913 }
else if (FieldName ==
"instid1") {
7916 Error(FieldLoc,
"invalid field name " + FieldName);
7935 .Case(
"VALU_DEP_1", 1)
7936 .Case(
"VALU_DEP_2", 2)
7937 .Case(
"VALU_DEP_3", 3)
7938 .Case(
"VALU_DEP_4", 4)
7939 .Case(
"TRANS32_DEP_1", 5)
7940 .Case(
"TRANS32_DEP_2", 6)
7941 .Case(
"TRANS32_DEP_3", 7)
7942 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7943 .Case(
"SALU_CYCLE_1", 9)
7944 .Case(
"SALU_CYCLE_2", 10)
7945 .Case(
"SALU_CYCLE_3", 11)
7953 Delay |=
Value << Shift;
7957ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7963 if (!parseDelay(Delay))
7971 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7976AMDGPUOperand::isSWaitCnt()
const {
7980bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7986void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7987 StringRef DepCtrName) {
7990 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7993 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7996 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7999 Error(Loc, Twine(
"invalid value for ", DepCtrName));
8006bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
8008 using namespace llvm::AMDGPU::DepCtr;
8010 SMLoc DepCtrLoc = getLoc();
8011 StringRef DepCtrName = getTokenStr();
8021 unsigned PrevOprMask = UsedOprMask;
8022 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8025 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8034 Error(getLoc(),
"expected a counter name");
8039 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
8040 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8044ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
8045 using namespace llvm::AMDGPU::DepCtr;
8048 SMLoc Loc = getLoc();
8051 unsigned UsedOprMask = 0;
8053 if (!parseDepCtr(DepCtr, UsedOprMask))
8061 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8065bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8071ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8073 OperandInfoTy &Width) {
8074 using namespace llvm::AMDGPU::Hwreg;
8080 HwReg.Loc = getLoc();
8083 HwReg.IsSymbolic =
true;
8085 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8093 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8103 Width.Loc = getLoc();
8111ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8112 using namespace llvm::AMDGPU::Hwreg;
8115 SMLoc Loc = getLoc();
8117 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8119 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8120 HwregOffset::Default);
8121 struct : StructuredOpField {
8122 using StructuredOpField::StructuredOpField;
8123 bool validate(AMDGPUAsmParser &Parser)
const override {
8125 return Error(Parser,
"only values from 1 to 32 are legal");
8128 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8129 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8132 Res = parseHwregFunc(HwReg,
Offset, Width);
8135 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8137 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8141 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8148 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8150 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8154bool AMDGPUOperand::isHwreg()
const {
8155 return isImmTy(ImmTyHwreg);
8163AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8165 OperandInfoTy &Stream) {
8166 using namespace llvm::AMDGPU::SendMsg;
8171 Msg.IsSymbolic =
true;
8173 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8178 Op.IsDefined =
true;
8181 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8184 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8189 Stream.IsDefined =
true;
8190 Stream.Loc = getLoc();
8200AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8201 const OperandInfoTy &
Op,
8202 const OperandInfoTy &Stream) {
8203 using namespace llvm::AMDGPU::SendMsg;
8208 bool Strict = Msg.IsSymbolic;
8212 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8217 Error(Msg.Loc,
"invalid message id");
8223 Error(
Op.Loc,
"message does not support operations");
8225 Error(Msg.Loc,
"missing message operation");
8231 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8233 Error(
Op.Loc,
"invalid operation id");
8238 Error(Stream.Loc,
"message operation does not support streams");
8242 Error(Stream.Loc,
"invalid message stream id");
8248ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8249 using namespace llvm::AMDGPU::SendMsg;
8252 SMLoc Loc = getLoc();
8256 OperandInfoTy
Op(OP_NONE_);
8257 OperandInfoTy Stream(STREAM_ID_NONE_);
8258 if (parseSendMsgBody(Msg,
Op, Stream) &&
8259 validateSendMsg(Msg,
Op, Stream)) {
8264 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8266 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8271 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8275bool AMDGPUOperand::isSendMsg()
const {
8276 return isImmTy(ImmTySendMsg);
8279ParseStatus AMDGPUAsmParser::parseWaitEvent(
OperandVector &Operands) {
8280 using namespace llvm::AMDGPU::WaitEvent;
8282 SMLoc Loc = getLoc();
8285 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8287 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8289 StructuredOpField *TargetBitfield =
8290 isGFX11() ? &DontWaitExportReady : &ExportReady;
8292 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8296 if (!validateStructuredOpFields({TargetBitfield}))
8298 ImmVal = TargetBitfield->Val;
8305 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8307 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8308 AMDGPUOperand::ImmTyWaitEvent));
8312bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8318ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8325 int Slot = StringSwitch<int>(Str)
8332 return Error(S,
"invalid interpolation slot");
8334 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8335 AMDGPUOperand::ImmTyInterpSlot));
8339ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8346 if (!Str.starts_with(
"attr"))
8347 return Error(S,
"invalid interpolation attribute");
8349 StringRef Chan = Str.take_back(2);
8350 int AttrChan = StringSwitch<int>(Chan)
8357 return Error(S,
"invalid or missing interpolation attribute channel");
8359 Str = Str.drop_back(2).drop_front(4);
8362 if (Str.getAsInteger(10, Attr))
8363 return Error(S,
"invalid or missing interpolation attribute number");
8366 return Error(S,
"out of bounds interpolation attribute number");
8370 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8371 AMDGPUOperand::ImmTyInterpAttr));
8372 Operands.
push_back(AMDGPUOperand::CreateImm(
8373 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8381ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8382 using namespace llvm::AMDGPU::Exp;
8392 return Error(S, (Id == ET_INVALID)
8393 ?
"invalid exp target"
8394 :
"exp target is not supported on this GPU");
8396 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8397 AMDGPUOperand::ImmTyExpTgt));
8406AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8411AMDGPUAsmParser::isId(
const StringRef Id)
const {
8417 return getTokenKind() ==
Kind;
8420StringRef AMDGPUAsmParser::getId()
const {
8425AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8434AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8436 StringRef Tok = getTokenStr();
8447 if (isId(Id) && peekToken().is(Kind)) {
8457 if (isToken(Kind)) {
8466 const StringRef ErrMsg) {
8467 if (!trySkipToken(Kind)) {
8468 Error(getLoc(), ErrMsg);
8475AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8479 if (Parser.parseExpression(Expr))
8482 if (Expr->evaluateAsAbsolute(
Imm))
8485 if (Expected.empty()) {
8486 Error(S,
"expected absolute expression");
8488 Error(S, Twine(
"expected ", Expected) +
8489 Twine(
" or an absolute expression"));
8499 if (Parser.parseExpression(Expr))
8503 if (Expr->evaluateAsAbsolute(IntVal)) {
8504 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8506 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8512AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8514 Val =
getToken().getStringContents();
8518 Error(getLoc(), ErrMsg);
8523AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8525 Val = getTokenStr();
8529 if (!ErrMsg.
empty())
8530 Error(getLoc(), ErrMsg);
8535AMDGPUAsmParser::getToken()
const {
8536 return Parser.getTok();
8539AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8542 : getLexer().peekTok(ShouldSkipSpace);
8547 auto TokCount = getLexer().peekTokens(Tokens);
8549 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8554AMDGPUAsmParser::getTokenKind()
const {
8555 return getLexer().getKind();
8559AMDGPUAsmParser::getLoc()
const {
8564AMDGPUAsmParser::getTokenStr()
const {
8569AMDGPUAsmParser::lex() {
8573const AMDGPUOperand &
8574AMDGPUAsmParser::findMCOperand(
const OperandVector &Operands,
8575 int MCOpIdx)
const {
8576 for (
const auto &
Op : Operands) {
8577 const AMDGPUOperand &TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8578 if (TargetOp.getMCOpIdx() == MCOpIdx)
8584SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8585 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8589SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8593SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8594 int MCOpIdx)
const {
8595 return findMCOperand(Operands, MCOpIdx).getStartLoc();
8599AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8601 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8602 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8604 return Op.getStartLoc();
8606 return getInstLoc(Operands);
8610AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8612 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8613 return getOperandLoc(
Test, Operands);
8627 StringRef
Id = getTokenStr();
8628 SMLoc IdLoc = getLoc();
8634 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8635 if (
I == Fields.
end())
8636 return Error(IdLoc,
"unknown field");
8637 if ((*I)->IsDefined)
8638 return Error(IdLoc,
"duplicate field");
8641 (*I)->Loc = getLoc();
8644 (*I)->IsDefined =
true;
8651bool AMDGPUAsmParser::validateStructuredOpFields(
8653 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8654 return F->validate(*
this);
8665 const unsigned OrMask,
8666 const unsigned XorMask) {
8675bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8676 const unsigned MaxVal,
8677 const Twine &ErrMsg, SMLoc &Loc) {
8694AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8695 const unsigned MinVal,
8696 const unsigned MaxVal,
8697 const StringRef ErrMsg) {
8699 for (
unsigned i = 0; i < OpNum; ++i) {
8700 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8708AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8709 using namespace llvm::AMDGPU::Swizzle;
8712 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8713 "expected a 2-bit lane id")) {
8724AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8725 using namespace llvm::AMDGPU::Swizzle;
8731 if (!parseSwizzleOperand(GroupSize,
8733 "group size must be in the interval [2,32]",
8738 Error(Loc,
"group size must be a power of two");
8741 if (parseSwizzleOperand(LaneIdx,
8743 "lane id must be in the interval [0,group size - 1]",
8752AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8753 using namespace llvm::AMDGPU::Swizzle;
8758 if (!parseSwizzleOperand(GroupSize,
8760 "group size must be in the interval [2,32]",
8765 Error(Loc,
"group size must be a power of two");
8774AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8775 using namespace llvm::AMDGPU::Swizzle;
8780 if (!parseSwizzleOperand(GroupSize,
8782 "group size must be in the interval [1,16]",
8787 Error(Loc,
"group size must be a power of two");
8796AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8797 using namespace llvm::AMDGPU::Swizzle;
8804 SMLoc StrLoc = getLoc();
8805 if (!parseString(Ctl)) {
8808 if (Ctl.
size() != BITMASK_WIDTH) {
8809 Error(StrLoc,
"expected a 5-character mask");
8813 unsigned AndMask = 0;
8814 unsigned OrMask = 0;
8815 unsigned XorMask = 0;
8817 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8821 Error(StrLoc,
"invalid mask");
8842bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8843 using namespace llvm::AMDGPU::Swizzle;
8846 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8852 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8853 "FFT swizzle must be in the interval [0," +
8854 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8862bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8863 using namespace llvm::AMDGPU::Swizzle;
8866 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8873 if (!parseSwizzleOperand(
Direction, 0, 1,
8874 "direction must be 0 (left) or 1 (right)", Loc))
8878 if (!parseSwizzleOperand(
8879 RotateSize, 0, ROTATE_MAX_SIZE,
8880 "number of threads to rotate must be in the interval [0," +
8881 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8886 (RotateSize << ROTATE_SIZE_SHIFT);
8891AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8893 SMLoc OffsetLoc = getLoc();
8899 Error(OffsetLoc,
"expected a 16-bit offset");
8906AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8907 using namespace llvm::AMDGPU::Swizzle;
8911 SMLoc ModeLoc = getLoc();
8914 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8915 Ok = parseSwizzleQuadPerm(
Imm);
8916 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8917 Ok = parseSwizzleBitmaskPerm(
Imm);
8918 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8919 Ok = parseSwizzleBroadcast(
Imm);
8920 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8921 Ok = parseSwizzleSwap(
Imm);
8922 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8923 Ok = parseSwizzleReverse(
Imm);
8924 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8925 Ok = parseSwizzleFFT(
Imm);
8926 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8927 Ok = parseSwizzleRotate(
Imm);
8929 Error(ModeLoc,
"expected a swizzle mode");
8932 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8938ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8942 if (trySkipId(
"offset")) {
8946 if (trySkipId(
"swizzle")) {
8947 Ok = parseSwizzleMacro(
Imm);
8949 Ok = parseSwizzleOffset(
Imm);
8953 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8961AMDGPUOperand::isSwizzle()
const {
8962 return isImmTy(ImmTySwizzle);
8969int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8971 using namespace llvm::AMDGPU::VGPRIndexMode;
8983 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8984 if (trySkipId(IdSymbolic[ModeId])) {
8992 "expected a VGPR index mode or a closing parenthesis" :
8993 "expected a VGPR index mode");
8998 Error(S,
"duplicate VGPR index mode");
9006 "expected a comma or a closing parenthesis"))
9013ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
9015 using namespace llvm::AMDGPU::VGPRIndexMode;
9021 Imm = parseGPRIdxMacro();
9025 if (getParser().parseAbsoluteExpression(
Imm))
9028 return Error(S,
"invalid immediate: only 4-bit values are legal");
9032 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9036bool AMDGPUOperand::isGPRIdxMode()
const {
9037 return isImmTy(ImmTyGprIdxMode);
9044ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
9049 if (isRegister() || isModifier())
9055 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
9056 assert(Opr.isImm() || Opr.isExpr());
9057 SMLoc Loc = Opr.getStartLoc();
9061 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9062 Error(Loc,
"expected an absolute expression or a label");
9063 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9064 Error(Loc,
"expected a 16-bit signed jump offset");
9074ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
9075 return parseReg(Operands);
9082void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
9085 OptionalImmIndexMap OptionalIdx;
9086 unsigned FirstOperandIdx = 1;
9087 bool IsAtomicReturn =
false;
9094 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9095 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9099 Op.addRegOperands(Inst, 1);
9103 if (IsAtomicReturn && i == FirstOperandIdx)
9104 Op.addRegOperands(Inst, 1);
9109 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9110 Op.addImmOperands(Inst, 1);
9122 OptionalIdx[
Op.getImmTy()] = i;
9136bool AMDGPUOperand::isSMRDOffset8()
const {
9140bool AMDGPUOperand::isSMEMOffset()
const {
9142 return isImmLiteral();
9145bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9180bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9181 if (BoundCtrl == 0 || BoundCtrl == 1) {
9189void AMDGPUAsmParser::onBeginOfFile() {
9190 if (!getParser().getStreamer().getTargetStreamer() ||
9194 if (!getTargetStreamer().getTargetID())
9195 getTargetStreamer().initializeTargetID(getSTI(),
9196 getSTI().getFeatureString());
9199 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9207bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9211 StringRef TokenId = getTokenStr();
9212 AGVK VK = StringSwitch<AGVK>(TokenId)
9213 .Case(
"max", AGVK::AGVK_Max)
9214 .Case(
"or", AGVK::AGVK_Or)
9215 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9216 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9217 .Case(
"alignto", AGVK::AGVK_AlignTo)
9218 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9219 .Default(AGVK::AGVK_None);
9223 uint64_t CommaCount = 0;
9228 if (Exprs.
empty()) {
9230 "empty " + Twine(TokenId) +
" expression");
9233 if (CommaCount + 1 != Exprs.
size()) {
9235 "mismatch of commas in " + Twine(TokenId) +
" expression");
9242 if (getParser().parseExpression(Expr, EndLoc))
9246 if (LastTokenWasComma)
9250 "unexpected token in " + Twine(TokenId) +
" expression");
9256 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9259ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9260 StringRef
Name = getTokenStr();
9261 if (Name ==
"mul") {
9262 return parseIntWithPrefix(
"mul", Operands,
9266 if (Name ==
"div") {
9267 return parseIntWithPrefix(
"div", Operands,
9278 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9283 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9284 AMDGPU::OpName::src2};
9292 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9297 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9299 if (
DstOp.isReg() &&
9304 if ((OpSel & (1 << SrcNum)) != 0)
9310void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9312 cvtVOP3P(Inst, Operands);
9316void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9317 OptionalImmIndexMap &OptionalIdx) {
9318 cvtVOP3P(Inst, Operands, OptionalIdx);
9327 &&
Desc.NumOperands > (OpNum + 1)
9329 &&
Desc.operands()[OpNum + 1].RegClass != -1
9331 &&
Desc.getOperandConstraint(OpNum + 1,
9335void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9337 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9338 AMDGPU::OpName::src2};
9339 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9340 AMDGPU::OpName::src1_modifiers,
9341 AMDGPU::OpName::src2_modifiers};
9342 for (
int J = 0; J < 3; ++J) {
9343 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9349 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9352 if ((OpSel & (1 << J)) != 0)
9355 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9362void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9364 OptionalImmIndexMap OptionalIdx;
9369 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9370 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9373 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9374 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9376 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9377 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9378 Op.isInterpAttrChan()) {
9380 }
else if (
Op.isImmModifier()) {
9381 OptionalIdx[
Op.getImmTy()] =
I;
9389 AMDGPUOperand::ImmTyHigh);
9393 AMDGPUOperand::ImmTyClamp);
9397 AMDGPUOperand::ImmTyOModSI);
9402 AMDGPUOperand::ImmTyOpSel);
9403 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9406 cvtOpSelHelper(Inst, OpSel);
9410void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9412 OptionalImmIndexMap OptionalIdx;
9417 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9418 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9421 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9422 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9424 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9425 }
else if (
Op.isImmModifier()) {
9426 OptionalIdx[
Op.getImmTy()] =
I;
9434 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9444 cvtOpSelHelper(Inst, OpSel);
9447void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9449 OptionalImmIndexMap OptionalIdx;
9452 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9456 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9457 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9459 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9460 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9465 if (NumOperands == CbszOpIdx) {
9470 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9471 }
else if (
Op.isImmModifier()) {
9472 OptionalIdx[
Op.getImmTy()] =
I;
9474 Op.addRegOrImmOperands(Inst, 1);
9479 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9480 if (CbszIdx != OptionalIdx.end()) {
9481 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9485 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9486 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9487 if (BlgpIdx != OptionalIdx.end()) {
9488 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9499 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9500 if (OpselIdx != OptionalIdx.end()) {
9501 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9505 unsigned OpSelHi = 0;
9506 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9507 if (OpselHiIdx != OptionalIdx.end()) {
9508 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9511 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9512 AMDGPU::OpName::src1_modifiers};
9514 for (
unsigned J = 0; J < 2; ++J) {
9515 unsigned ModVal = 0;
9516 if (OpSel & (1 << J))
9518 if (OpSelHi & (1 << J))
9521 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9526void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9527 OptionalImmIndexMap &OptionalIdx) {
9532 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9533 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9536 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9537 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9539 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9540 }
else if (
Op.isImmModifier()) {
9541 OptionalIdx[
Op.getImmTy()] =
I;
9543 Op.addRegOrImmOperands(Inst, 1);
9549 AMDGPUOperand::ImmTyScaleSel);
9553 AMDGPUOperand::ImmTyClamp);
9559 AMDGPUOperand::ImmTyByteSel);
9564 AMDGPUOperand::ImmTyOModSI);
9571 auto *it = Inst.
begin();
9572 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9580void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9581 OptionalImmIndexMap OptionalIdx;
9582 cvtVOP3(Inst, Operands, OptionalIdx);
9585void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9586 OptionalImmIndexMap &OptIdx) {
9592 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9593 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9594 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9595 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9596 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9597 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9598 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9599 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9608 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
9609 if (VdstInIdx != -1 && VdstInIdx ==
static_cast<int>(Inst.
getNumOperands()))
9612 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9613 if (BitOp3Idx != -1) {
9620 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9621 if (OpSelIdx != -1) {
9625 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9626 if (OpSelHiIdx != -1) {
9627 int DefaultVal =
IsPacked ? -1 : 0;
9633 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9634 if (MatrixAFMTIdx != -1) {
9636 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9640 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9641 if (MatrixBFMTIdx != -1) {
9643 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9646 int MatrixAScaleIdx =
9647 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9648 if (MatrixAScaleIdx != -1) {
9650 AMDGPUOperand::ImmTyMatrixAScale, 0);
9653 int MatrixBScaleIdx =
9654 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9655 if (MatrixBScaleIdx != -1) {
9657 AMDGPUOperand::ImmTyMatrixBScale, 0);
9660 int MatrixAScaleFmtIdx =
9661 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9662 if (MatrixAScaleFmtIdx != -1) {
9664 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9667 int MatrixBScaleFmtIdx =
9668 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9669 if (MatrixBScaleFmtIdx != -1) {
9671 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9676 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9680 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9682 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9686 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9690 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9691 AMDGPU::OpName::src2};
9692 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9693 AMDGPU::OpName::src1_modifiers,
9694 AMDGPU::OpName::src2_modifiers};
9697 unsigned OpSelHi = 0;
9704 if (OpSelHiIdx != -1)
9713 for (
int J = 0; J < 3; ++J) {
9714 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9718 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9723 uint32_t ModVal = 0;
9726 if (SrcOp.
isReg() && getMRI()
9733 if ((OpSel & (1 << J)) != 0)
9737 if ((OpSelHi & (1 << J)) != 0)
9740 if ((NegLo & (1 << J)) != 0)
9743 if ((NegHi & (1 << J)) != 0)
9750void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9751 OptionalImmIndexMap OptIdx;
9752 cvtVOP3(Inst, Operands, OptIdx);
9753 cvtVOP3P(Inst, Operands, OptIdx);
9757 unsigned i,
unsigned Opc,
9759 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9760 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9762 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9765void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9768 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9771 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9772 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9774 OptionalImmIndexMap OptIdx;
9775 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9776 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9777 OptIdx[
Op.getImmTy()] = i;
9782 AMDGPUOperand::ImmTyIndexKey8bit);
9786 AMDGPUOperand::ImmTyIndexKey16bit);
9790 AMDGPUOperand::ImmTyIndexKey32bit);
9795 cvtVOP3P(Inst, Operands, OptIdx);
9802ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9810 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9811 SMLoc OpYLoc = getLoc();
9814 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9817 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9823void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9826 auto addOp = [&](uint16_t ParsedOprIdx) {
9827 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9829 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9833 Op.addRegOperands(Inst, 1);
9837 Op.addImmOperands(Inst, 1);
9849 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9853 const auto &CInfo = InstInfo[CompIdx];
9854 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9855 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9856 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9857 if (CInfo.hasSrc2Acc())
9858 addOp(CInfo.getIndexOfDstInParsedOperands());
9862 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9863 if (BitOp3Idx != -1) {
9864 OptionalImmIndexMap OptIdx;
9865 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9867 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9877bool AMDGPUOperand::isDPP8()
const {
9878 return isImmTy(ImmTyDPP8);
9881bool AMDGPUOperand::isDPPCtrl()
const {
9882 using namespace AMDGPU::DPP;
9884 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9887 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9888 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9889 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9890 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9891 (
Imm == DppCtrl::WAVE_SHL1) ||
9892 (
Imm == DppCtrl::WAVE_ROL1) ||
9893 (
Imm == DppCtrl::WAVE_SHR1) ||
9894 (
Imm == DppCtrl::WAVE_ROR1) ||
9895 (
Imm == DppCtrl::ROW_MIRROR) ||
9896 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9897 (
Imm == DppCtrl::BCAST15) ||
9898 (
Imm == DppCtrl::BCAST31) ||
9899 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9900 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9909bool AMDGPUOperand::isBLGP()
const {
9913bool AMDGPUOperand::isS16Imm()
const {
9917bool AMDGPUOperand::isU16Imm()
const {
9925bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9930 SMLoc Loc =
getToken().getEndLoc();
9931 Token = std::string(getTokenStr());
9933 if (getLoc() != Loc)
9938 if (!parseId(Suffix))
9942 StringRef DimId = Token;
9953ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9963 SMLoc Loc = getLoc();
9964 if (!parseDimId(Encoding))
9965 return Error(Loc,
"invalid dim value");
9967 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9968 AMDGPUOperand::ImmTyDim));
9976ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
9986 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9989 for (
size_t i = 0; i < 8; ++i) {
9993 SMLoc Loc = getLoc();
9994 if (getParser().parseAbsoluteExpression(Sels[i]))
9996 if (0 > Sels[i] || 7 < Sels[i])
9997 return Error(Loc,
"expected a 3-bit value");
10000 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10004 for (
size_t i = 0; i < 8; ++i)
10005 DPP8 |= (Sels[i] << (i * 3));
10007 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10012AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10014 if (Ctrl ==
"row_newbcast")
10017 if (Ctrl ==
"row_share" ||
10018 Ctrl ==
"row_xmask")
10021 if (Ctrl ==
"wave_shl" ||
10022 Ctrl ==
"wave_shr" ||
10023 Ctrl ==
"wave_rol" ||
10024 Ctrl ==
"wave_ror" ||
10025 Ctrl ==
"row_bcast")
10028 return Ctrl ==
"row_mirror" ||
10029 Ctrl ==
"row_half_mirror" ||
10030 Ctrl ==
"quad_perm" ||
10031 Ctrl ==
"row_shl" ||
10032 Ctrl ==
"row_shr" ||
10037AMDGPUAsmParser::parseDPPCtrlPerm() {
10040 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10044 for (
int i = 0; i < 4; ++i) {
10049 SMLoc Loc = getLoc();
10050 if (getParser().parseAbsoluteExpression(Temp))
10052 if (Temp < 0 || Temp > 3) {
10053 Error(Loc,
"expected a 2-bit value");
10057 Val += (Temp << i * 2);
10060 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10067AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10068 using namespace AMDGPU::DPP;
10073 SMLoc Loc = getLoc();
10075 if (getParser().parseAbsoluteExpression(Val))
10078 struct DppCtrlCheck {
10084 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10085 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10086 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10087 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10088 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10089 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10090 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10091 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10092 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10093 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10094 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10098 if (
Check.Ctrl == -1) {
10099 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10107 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10114ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10115 using namespace AMDGPU::DPP;
10118 !isSupportedDPPCtrl(getTokenStr(), Operands))
10121 SMLoc S = getLoc();
10127 if (Ctrl ==
"row_mirror") {
10128 Val = DppCtrl::ROW_MIRROR;
10129 }
else if (Ctrl ==
"row_half_mirror") {
10130 Val = DppCtrl::ROW_HALF_MIRROR;
10133 if (Ctrl ==
"quad_perm") {
10134 Val = parseDPPCtrlPerm();
10136 Val = parseDPPCtrlSel(Ctrl);
10145 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10149void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10151 OptionalImmIndexMap OptionalIdx;
10158 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10160 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10161 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10165 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10166 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10170 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10171 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10172 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10173 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10174 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10176 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10180 if (OldIdx == NumOperands) {
10182 constexpr int DST_IDX = 0;
10184 }
else if (Src2ModIdx == NumOperands) {
10194 if (IsVOP3CvtSrDpp) {
10203 if (TiedTo != -1) {
10208 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10210 if (IsDPP8 &&
Op.isDppFI()) {
10213 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10214 }
else if (
Op.isReg()) {
10215 Op.addRegOperands(Inst, 1);
10216 }
else if (
Op.isImm() &&
10218 Op.addImmOperands(Inst, 1);
10219 }
else if (
Op.isImm()) {
10220 OptionalIdx[
Op.getImmTy()] =
I;
10228 AMDGPUOperand::ImmTyClamp);
10234 AMDGPUOperand::ImmTyByteSel);
10241 cvtVOP3P(Inst, Operands, OptionalIdx);
10243 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10250 using namespace llvm::AMDGPU::DPP;
10260 AMDGPUOperand::ImmTyDppFI);
10264void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10265 OptionalImmIndexMap OptionalIdx;
10269 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10270 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10274 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10277 if (TiedTo != -1) {
10282 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10284 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10292 Op.addImmOperands(Inst, 1);
10294 Op.addRegWithFPInputModsOperands(Inst, 2);
10295 }
else if (
Op.isDppFI()) {
10297 }
else if (
Op.isReg()) {
10298 Op.addRegOperands(Inst, 1);
10304 Op.addRegWithFPInputModsOperands(Inst, 2);
10305 }
else if (
Op.isReg()) {
10306 Op.addRegOperands(Inst, 1);
10307 }
else if (
Op.isDPPCtrl()) {
10308 Op.addImmOperands(Inst, 1);
10309 }
else if (
Op.isImm()) {
10311 OptionalIdx[
Op.getImmTy()] =
I;
10319 using namespace llvm::AMDGPU::DPP;
10327 AMDGPUOperand::ImmTyDppFI);
10336ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10338 AMDGPUOperand::ImmTy
Type) {
10339 return parseStringOrIntWithPrefix(
10341 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10345ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10346 return parseStringOrIntWithPrefix(
10347 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10348 AMDGPUOperand::ImmTySDWADstUnused);
10351void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10355void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10359void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10363void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10367void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10371void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10372 uint64_t BasicInstType,
10375 using namespace llvm::AMDGPU::SDWA;
10377 OptionalImmIndexMap OptionalIdx;
10378 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10379 bool SkippedVcc =
false;
10383 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10384 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10387 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10388 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10389 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10390 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10408 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10409 }
else if (
Op.isImm()) {
10411 OptionalIdx[
Op.getImmTy()] =
I;
10415 SkippedVcc =
false;
10419 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10420 Opc != AMDGPU::V_NOP_sdwa_vi) {
10422 switch (BasicInstType) {
10426 AMDGPUOperand::ImmTyClamp, 0);
10430 AMDGPUOperand::ImmTyOModSI, 0);
10434 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10438 AMDGPUOperand::ImmTySDWADstUnused,
10439 DstUnused::UNUSED_PRESERVE);
10441 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10446 AMDGPUOperand::ImmTyClamp, 0);
10451 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10452 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10453 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10454 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10460 AMDGPUOperand::ImmTyClamp, 0);
10461 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10462 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10466 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10472 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10473 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10474 auto *it = Inst.
begin();
10476 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10488#define GET_MATCHER_IMPLEMENTATION
10489#define GET_MNEMONIC_SPELL_CHECKER
10490#define GET_MNEMONIC_CHECKER
10491#include "AMDGPUGenAsmMatcher.inc"
10497 return parseTokenOp(
"addr64",
Operands);
10499 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10501 return parseTokenOp(
"idxen",
Operands);
10503 return parseNamedBit(
"lds",
Operands, AMDGPUOperand::ImmTyLDS,
10506 return parseTokenOp(
"offen",
Operands);
10508 return parseTokenOp(
"off",
Operands);
10509 case MCK_row_95_en:
10510 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10512 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10514 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10516 return tryCustomParseOperand(
Operands, MCK);
10521unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10527 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10530 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10532 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10534 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10536 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10538 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10540 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10542 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10543 case MCK_row_95_en:
10544 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10552 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10554 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10555 case MCK_SOPPBrTarget:
10556 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10557 case MCK_VReg32OrOff:
10558 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10559 case MCK_InterpSlot:
10560 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10561 case MCK_InterpAttr:
10562 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10563 case MCK_InterpAttrChan:
10564 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10566 case MCK_SReg_64_XEXEC:
10576 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10578 return Match_InvalidOperand;
10586ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10587 SMLoc S = getLoc();
10596 return Error(S,
"expected a 16-bit value");
10599 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10603bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10609bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
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")
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(GsymDataExtractor &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
Register const TargetRegisterInfo * TRI
static MCRegister 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.
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 void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, 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)
static const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
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)
Context object for machine code objects.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
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.
int16_t getOpRegClassID(const MCOperandInfo &OpInfo, unsigned HwModeId) const
Return the ID of the register class to use for OpInfo, for the active HwMode HwModeId.
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.
const MCExpr * getExpr() const
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...
bool regsOverlap(MCRegister RegA, MCRegister RegB) const
Returns true if the two registers are equal or alias each other.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
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.
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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
iterator insert(iterator I, T &&Elt)
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...
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
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
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
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)
static constexpr CustomOperand Operands[]
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[]
constexpr const char *const ModMatrixFmt[]
constexpr const char *const ModMatrixScaleFmt[]
constexpr const char *const ModMatrixScale[]
bool isPackedFP32Inst(unsigned Opc)
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
bool isInlineValue(MCRegister Reg)
bool isPKFMACF16InlineConstant(uint32_t Literal, bool IsGFX11Plus)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
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)
LLVM_READONLY bool isLitExpr(const MCExpr *Expr)
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)
bool isGFX13(const MCSubtargetInfo &STI)
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?
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 isGFX13Plus(const MCSubtargetInfo &STI)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
@ 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_IMM_V2FP16_SPLAT
@ 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 isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
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)
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
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)
bool isGFX1250Plus(const MCSubtargetInfo &STI)
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)
@ Valid
The data is already valid.
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.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
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 uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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...
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.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ Default
The result value is uniform if and only if all operands are uniform.
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
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size