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(); }
89 int64_t getFPModifiersOperand()
const {
96 int64_t getIntModifiersOperand()
const {
102 int64_t getModifiersOperand()
const {
103 assert(!(hasFPModifiers() && hasIntModifiers())
104 &&
"fp and int modifiers should not be used simultaneously");
105 if (hasFPModifiers())
106 return getFPModifiersOperand();
107 if (hasIntModifiers())
108 return getIntModifiersOperand();
112 friend raw_ostream &
operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
186 ImmTyMatrixAScaleFmt,
187 ImmTyMatrixBScaleFmt,
220 mutable int MCOpIdx = -1;
223 bool isToken()
const override {
return Kind == Token; }
225 bool isSymbolRefExpr()
const {
229 bool isImm()
const override {
230 return Kind == Immediate;
233 bool isInlinableImm(MVT type)
const;
234 bool isLiteralImm(MVT type)
const;
236 bool isRegKind()
const {
237 return Kind == Register;
240 bool isReg()
const override {
241 return isRegKind() && !hasModifiers();
244 bool isRegOrInline(
unsigned RCID, MVT type)
const {
245 return isRegClass(RCID) || isInlinableImm(type);
249 return isRegOrInline(RCID, type) || isLiteralImm(type);
252 bool isRegOrImmWithInt16InputMods()
const {
256 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
258 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
261 bool isRegOrImmWithInt32InputMods()
const {
265 bool isRegOrInlineImmWithInt16InputMods()
const {
266 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
269 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
270 return isRegOrInline(
271 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
274 bool isRegOrInlineImmWithInt32InputMods()
const {
275 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
278 bool isRegOrImmWithInt64InputMods()
const {
282 bool isRegOrImmWithFP16InputMods()
const {
286 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
288 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
291 bool isRegOrImmWithFP32InputMods()
const {
295 bool isRegOrImmWithFP64InputMods()
const {
299 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
300 return isRegOrInline(
301 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
304 bool isRegOrInlineImmWithFP32InputMods()
const {
305 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
308 bool isRegOrInlineImmWithFP64InputMods()
const {
309 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
312 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
314 bool isVRegWithFP32InputMods()
const {
315 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
318 bool isVRegWithFP64InputMods()
const {
319 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
322 bool isPackedFP16InputMods()
const {
326 bool isPackedVGPRFP32InputMods()
const {
330 bool isVReg()
const {
331 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
332 isRegClass(AMDGPU::VReg_64RegClassID) ||
333 isRegClass(AMDGPU::VReg_96RegClassID) ||
334 isRegClass(AMDGPU::VReg_128RegClassID) ||
335 isRegClass(AMDGPU::VReg_160RegClassID) ||
336 isRegClass(AMDGPU::VReg_192RegClassID) ||
337 isRegClass(AMDGPU::VReg_256RegClassID) ||
338 isRegClass(AMDGPU::VReg_512RegClassID) ||
339 isRegClass(AMDGPU::VReg_1024RegClassID);
342 bool isVReg32()
const {
343 return isRegClass(AMDGPU::VGPR_32RegClassID);
346 bool isVReg32OrOff()
const {
347 return isOff() || isVReg32();
351 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
354 bool isAV_LdSt_32_Align2_RegOp()
const {
355 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
356 isRegClass(AMDGPU::AGPR_32RegClassID);
359 bool isVRegWithInputMods()
const;
360 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
361 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
363 bool isSDWAOperand(MVT type)
const;
364 bool isSDWAFP16Operand()
const;
365 bool isSDWAFP32Operand()
const;
366 bool isSDWAInt16Operand()
const;
367 bool isSDWAInt32Operand()
const;
369 bool isImmTy(ImmTy ImmT)
const {
370 return isImm() &&
Imm.Type == ImmT;
373 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
375 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
377 bool isImmModifier()
const {
378 return isImm() &&
Imm.Type != ImmTyNone;
381 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
382 bool isDim()
const {
return isImmTy(ImmTyDim); }
383 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
384 bool isOff()
const {
return isImmTy(ImmTyOff); }
385 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
386 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
387 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
388 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
389 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
390 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
391 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
392 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
393 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
394 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
395 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
396 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
397 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
398 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
399 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
400 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
401 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
402 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
403 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
404 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
405 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
406 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
407 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
408 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
409 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
410 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
411 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
412 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
413 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
414 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
415 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
416 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
417 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
418 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
419 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
420 bool isDone()
const {
return isImmTy(ImmTyDone); }
421 bool isRowEn()
const {
return isImmTy(ImmTyRowEn); }
423 bool isRegOrImm()
const {
424 return isReg() || isImm();
427 bool isRegClass(
unsigned RCID)
const;
431 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
432 return isRegOrInline(RCID, type) && !hasModifiers();
435 bool isSCSrcB16()
const {
436 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
439 bool isSCSrcV2B16()
const {
443 bool isSCSrc_b32()
const {
444 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
447 bool isSCSrc_b64()
const {
448 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
451 bool isBoolReg()
const;
453 bool isSCSrcF16()
const {
454 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
457 bool isSCSrcV2F16()
const {
461 bool isSCSrcF32()
const {
462 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
465 bool isSCSrcF64()
const {
466 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
469 bool isSSrc_b32()
const {
470 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
473 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
475 bool isSSrcV2B16()
const {
480 bool isSSrc_b64()
const {
483 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
484 (((
const MCTargetAsmParser *)AsmParser)
485 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
489 bool isSSrc_f32()
const {
490 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
493 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
495 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
497 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
499 bool isSSrcV2F16()
const {
504 bool isSSrcV2FP32()
const {
509 bool isSCSrcV2FP32()
const {
514 bool isSSrcV2INT32()
const {
519 bool isSCSrcV2INT32()
const {
521 return isSCSrc_b32();
524 bool isSSrcOrLds_b32()
const {
525 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
526 isLiteralImm(MVT::i32) || isExpr();
529 bool isVCSrc_b32()
const {
530 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
533 bool isVCSrc_b32_Lo256()
const {
534 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
537 bool isVCSrc_b64_Lo256()
const {
538 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
541 bool isVCSrc_b64()
const {
542 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
545 bool isVCSrcT_b16()
const {
546 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
549 bool isVCSrcTB16_Lo128()
const {
550 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
553 bool isVCSrcFake16B16_Lo128()
const {
554 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
557 bool isVCSrc_b16()
const {
558 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
561 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
563 bool isVCSrc_f32()
const {
564 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
567 bool isVCSrc_f64()
const {
568 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
571 bool isVCSrcTBF16()
const {
572 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
575 bool isVCSrcT_f16()
const {
576 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
579 bool isVCSrcT_bf16()
const {
580 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
583 bool isVCSrcTBF16_Lo128()
const {
584 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
587 bool isVCSrcTF16_Lo128()
const {
588 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
591 bool isVCSrcFake16BF16_Lo128()
const {
592 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
595 bool isVCSrcFake16F16_Lo128()
const {
596 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
599 bool isVCSrc_bf16()
const {
600 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
603 bool isVCSrc_f16()
const {
604 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
607 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
609 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
611 bool isVSrc_b32()
const {
612 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
615 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
617 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
619 bool isVSrcT_b16_Lo128()
const {
620 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
623 bool isVSrcFake16_b16_Lo128()
const {
624 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
627 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
629 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
631 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
633 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
635 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
637 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
639 bool isVSrc_f32()
const {
640 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
643 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
645 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
647 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
649 bool isVSrcT_bf16_Lo128()
const {
650 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
653 bool isVSrcT_f16_Lo128()
const {
654 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
657 bool isVSrcFake16_bf16_Lo128()
const {
658 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
661 bool isVSrcFake16_f16_Lo128()
const {
662 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
665 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
667 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
669 bool isVSrc_v2bf16()
const {
670 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
673 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
675 bool isVSrc_v2f16_splat()
const {
return isVSrc_v2f16(); }
677 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
679 bool isVISrcB32()
const {
680 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
683 bool isVISrcB16()
const {
684 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
687 bool isVISrcV2B16()
const {
691 bool isVISrcF32()
const {
692 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
695 bool isVISrcF16()
const {
696 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
699 bool isVISrcV2F16()
const {
700 return isVISrcF16() || isVISrcB32();
703 bool isVISrc_64_bf16()
const {
704 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
707 bool isVISrc_64_f16()
const {
708 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
711 bool isVISrc_64_b32()
const {
712 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
715 bool isVISrc_64B64()
const {
716 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
719 bool isVISrc_64_f64()
const {
720 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
723 bool isVISrc_64V2FP32()
const {
724 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
727 bool isVISrc_64V2INT32()
const {
728 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
731 bool isVISrc_256_b32()
const {
732 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
735 bool isVISrc_256_f32()
const {
736 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
739 bool isVISrc_256B64()
const {
740 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
743 bool isVISrc_256_f64()
const {
744 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
747 bool isVISrc_512_f64()
const {
748 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
751 bool isVISrc_128B16()
const {
752 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
755 bool isVISrc_128V2B16()
const {
756 return isVISrc_128B16();
759 bool isVISrc_128_b32()
const {
760 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
763 bool isVISrc_128_f32()
const {
764 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
767 bool isVISrc_256V2FP32()
const {
768 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
771 bool isVISrc_256V2INT32()
const {
772 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
775 bool isVISrc_512_b32()
const {
776 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
779 bool isVISrc_512B16()
const {
780 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
783 bool isVISrc_512V2B16()
const {
784 return isVISrc_512B16();
787 bool isVISrc_512_f32()
const {
788 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
791 bool isVISrc_512F16()
const {
792 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
795 bool isVISrc_512V2F16()
const {
796 return isVISrc_512F16() || isVISrc_512_b32();
799 bool isVISrc_1024_b32()
const {
800 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
803 bool isVISrc_1024B16()
const {
804 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
807 bool isVISrc_1024V2B16()
const {
808 return isVISrc_1024B16();
811 bool isVISrc_1024_f32()
const {
812 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
815 bool isVISrc_1024F16()
const {
816 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
819 bool isVISrc_1024V2F16()
const {
820 return isVISrc_1024F16() || isVISrc_1024_b32();
823 bool isAISrcB32()
const {
824 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
827 bool isAISrcB16()
const {
828 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
831 bool isAISrcV2B16()
const {
835 bool isAISrcF32()
const {
836 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
839 bool isAISrcF16()
const {
840 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
843 bool isAISrcV2F16()
const {
844 return isAISrcF16() || isAISrcB32();
847 bool isAISrc_64B64()
const {
848 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
851 bool isAISrc_64_f64()
const {
852 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
855 bool isAISrc_128_b32()
const {
856 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
859 bool isAISrc_128B16()
const {
860 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
863 bool isAISrc_128V2B16()
const {
864 return isAISrc_128B16();
867 bool isAISrc_128_f32()
const {
868 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
871 bool isAISrc_128F16()
const {
872 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
875 bool isAISrc_128V2F16()
const {
876 return isAISrc_128F16() || isAISrc_128_b32();
879 bool isVISrc_128_bf16()
const {
880 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
883 bool isVISrc_128_f16()
const {
884 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
887 bool isVISrc_128V2F16()
const {
888 return isVISrc_128_f16() || isVISrc_128_b32();
891 bool isAISrc_256B64()
const {
892 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
895 bool isAISrc_256_f64()
const {
896 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
899 bool isAISrc_512_b32()
const {
900 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
903 bool isAISrc_512B16()
const {
904 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
907 bool isAISrc_512V2B16()
const {
908 return isAISrc_512B16();
911 bool isAISrc_512_f32()
const {
912 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
915 bool isAISrc_512F16()
const {
916 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
919 bool isAISrc_512V2F16()
const {
920 return isAISrc_512F16() || isAISrc_512_b32();
923 bool isAISrc_1024_b32()
const {
924 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
927 bool isAISrc_1024B16()
const {
928 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
931 bool isAISrc_1024V2B16()
const {
932 return isAISrc_1024B16();
935 bool isAISrc_1024_f32()
const {
936 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
939 bool isAISrc_1024F16()
const {
940 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
943 bool isAISrc_1024V2F16()
const {
944 return isAISrc_1024F16() || isAISrc_1024_b32();
947 bool isKImmFP32()
const {
948 return isLiteralImm(MVT::f32);
951 bool isKImmFP16()
const {
952 return isLiteralImm(MVT::f16);
955 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
957 bool isMem()
const override {
961 bool isExpr()
const {
962 return Kind == Expression;
965 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
967 bool isSWaitCnt()
const;
968 bool isDepCtr()
const;
969 bool isSDelayALU()
const;
970 bool isHwreg()
const;
971 bool isSendMsg()
const;
972 bool isWaitEvent()
const;
973 bool isSplitBarrier()
const;
974 bool isSwizzle()
const;
975 bool isSMRDOffset8()
const;
976 bool isSMEMOffset()
const;
977 bool isSMRDLiteralOffset()
const;
979 bool isDPPCtrl()
const;
981 bool isGPRIdxMode()
const;
982 bool isS16Imm()
const;
983 bool isU16Imm()
const;
984 bool isEndpgm()
const;
986 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
987 return [
this,
P]() {
return P(*
this); };
992 return StringRef(Tok.Data, Tok.Length);
1000 void setImm(int64_t Val) {
1005 ImmTy getImmTy()
const {
1010 MCRegister
getReg()
const override {
1015 SMLoc getStartLoc()
const override {
1019 SMLoc getEndLoc()
const override {
1023 SMRange getLocRange()
const {
1024 return SMRange(StartLoc, EndLoc);
1027 int getMCOpIdx()
const {
return MCOpIdx; }
1029 Modifiers getModifiers()
const {
1030 assert(isRegKind() || isImmTy(ImmTyNone));
1031 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1034 void setModifiers(Modifiers Mods) {
1035 assert(isRegKind() || isImmTy(ImmTyNone));
1042 bool hasModifiers()
const {
1043 return getModifiers().hasModifiers();
1046 bool hasFPModifiers()
const {
1047 return getModifiers().hasFPModifiers();
1050 bool hasIntModifiers()
const {
1051 return getModifiers().hasIntModifiers();
1054 uint64_t applyInputFPModifiers(uint64_t Val,
unsigned Size)
const;
1056 void addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1058 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1060 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1062 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1064 addRegOperands(Inst,
N);
1066 addImmOperands(Inst,
N);
1069 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1070 Modifiers Mods = getModifiers();
1073 addRegOperands(Inst,
N);
1075 addImmOperands(Inst,
N,
false);
1079 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1080 assert(!hasIntModifiers());
1081 addRegOrImmWithInputModsOperands(Inst,
N);
1084 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1085 assert(!hasFPModifiers());
1086 addRegOrImmWithInputModsOperands(Inst,
N);
1089 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1090 Modifiers Mods = getModifiers();
1093 addRegOperands(Inst,
N);
1096 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1097 assert(!hasIntModifiers());
1098 addRegWithInputModsOperands(Inst,
N);
1101 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1102 assert(!hasFPModifiers());
1103 addRegWithInputModsOperands(Inst,
N);
1106 static void printImmTy(raw_ostream& OS, ImmTy
Type) {
1109 case ImmTyNone: OS <<
"None";
break;
1110 case ImmTyGDS: OS <<
"GDS";
break;
1111 case ImmTyLDS: OS <<
"LDS";
break;
1112 case ImmTyOffen: OS <<
"Offen";
break;
1113 case ImmTyIdxen: OS <<
"Idxen";
break;
1114 case ImmTyAddr64: OS <<
"Addr64";
break;
1115 case ImmTyOffset: OS <<
"Offset";
break;
1116 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1117 case ImmTyOffset0: OS <<
"Offset0";
break;
1118 case ImmTyOffset1: OS <<
"Offset1";
break;
1119 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1120 case ImmTyCPol: OS <<
"CPol";
break;
1121 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1122 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1123 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1124 case ImmTyTFE: OS <<
"TFE";
break;
1125 case ImmTyIsAsync: OS <<
"IsAsync";
break;
1126 case ImmTyD16: OS <<
"D16";
break;
1127 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1128 case ImmTyClamp: OS <<
"Clamp";
break;
1129 case ImmTyOModSI: OS <<
"OModSI";
break;
1130 case ImmTyDPP8: OS <<
"DPP8";
break;
1131 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1132 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1133 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1134 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1135 case ImmTyDppFI: OS <<
"DppFI";
break;
1136 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1137 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1138 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1139 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1140 case ImmTyDMask: OS <<
"DMask";
break;
1141 case ImmTyDim: OS <<
"Dim";
break;
1142 case ImmTyUNorm: OS <<
"UNorm";
break;
1143 case ImmTyDA: OS <<
"DA";
break;
1144 case ImmTyR128A16: OS <<
"R128A16";
break;
1145 case ImmTyA16: OS <<
"A16";
break;
1146 case ImmTyLWE: OS <<
"LWE";
break;
1147 case ImmTyOff: OS <<
"Off";
break;
1148 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1149 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1150 case ImmTyExpVM: OS <<
"ExpVM";
break;
1151 case ImmTyDone: OS <<
"Done";
break;
1152 case ImmTyRowEn: OS <<
"RowEn";
break;
1153 case ImmTyHwreg: OS <<
"Hwreg";
break;
1154 case ImmTySendMsg: OS <<
"SendMsg";
break;
1155 case ImmTyWaitEvent: OS <<
"WaitEvent";
break;
1156 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1157 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1158 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1159 case ImmTyOpSel: OS <<
"OpSel";
break;
1160 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1161 case ImmTyNegLo: OS <<
"NegLo";
break;
1162 case ImmTyNegHi: OS <<
"NegHi";
break;
1163 case ImmTySwizzle: OS <<
"Swizzle";
break;
1164 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1165 case ImmTyHigh: OS <<
"High";
break;
1166 case ImmTyBLGP: OS <<
"BLGP";
break;
1167 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1168 case ImmTyABID: OS <<
"ABID";
break;
1169 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1170 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1171 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1172 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1173 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1174 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1175 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1176 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1177 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1178 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1179 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1180 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1181 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1182 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1183 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1184 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1189 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1193 <<
" mods: " <<
Reg.Mods <<
'>';
1197 if (getImmTy() != ImmTyNone) {
1198 OS <<
" type: "; printImmTy(OS, getImmTy());
1200 OS <<
" mods: " <<
Imm.Mods <<
'>';
1213 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1214 int64_t Val, SMLoc Loc,
1215 ImmTy
Type = ImmTyNone,
1216 bool IsFPImm =
false) {
1217 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1219 Op->Imm.IsFPImm = IsFPImm;
1221 Op->Imm.Mods = Modifiers();
1227 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1228 StringRef Str, SMLoc Loc,
1229 bool HasExplicitEncodingSize =
true) {
1230 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1231 Res->Tok.Data = Str.data();
1232 Res->Tok.Length = Str.size();
1233 Res->StartLoc = Loc;
1238 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1239 MCRegister
Reg, SMLoc S, SMLoc
E) {
1240 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1241 Op->Reg.RegNo =
Reg;
1242 Op->Reg.Mods = Modifiers();
1248 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1249 const class MCExpr *Expr, SMLoc S) {
1250 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1259 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1268#define GET_REGISTER_MATCHER
1269#include "AMDGPUGenAsmMatcher.inc"
1270#undef GET_REGISTER_MATCHER
1271#undef GET_SUBTARGET_FEATURE_NAME
1276class KernelScopeInfo {
1277 int SgprIndexUnusedMin = -1;
1278 int VgprIndexUnusedMin = -1;
1279 int AgprIndexUnusedMin = -1;
1283 void usesSgprAt(
int i) {
1284 if (i >= SgprIndexUnusedMin) {
1285 SgprIndexUnusedMin = ++i;
1288 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1294 void usesVgprAt(
int i) {
1295 if (i >= VgprIndexUnusedMin) {
1296 VgprIndexUnusedMin = ++i;
1299 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1301 VgprIndexUnusedMin);
1307 void usesAgprAt(
int i) {
1312 if (i >= AgprIndexUnusedMin) {
1313 AgprIndexUnusedMin = ++i;
1316 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1321 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1323 VgprIndexUnusedMin);
1330 KernelScopeInfo() =
default;
1334 MSTI = Ctx->getSubtargetInfo();
1336 usesSgprAt(SgprIndexUnusedMin = -1);
1337 usesVgprAt(VgprIndexUnusedMin = -1);
1339 usesAgprAt(AgprIndexUnusedMin = -1);
1343 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1344 unsigned RegWidth) {
1347 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1350 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1353 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1362 MCAsmParser &Parser;
1364 unsigned ForcedEncodingSize = 0;
1365 bool ForcedDPP =
false;
1366 bool ForcedSDWA =
false;
1367 KernelScopeInfo KernelScope;
1368 const unsigned HwMode;
1373#define GET_ASSEMBLER_HEADER
1374#include "AMDGPUGenAsmMatcher.inc"
1379 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1381 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1386 void createConstantSymbol(StringRef Id, int64_t Val);
1388 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1389 bool OutOfRangeError(SMRange
Range);
1405 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1406 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1407 std::optional<bool> EnableWavefrontSize32,
1408 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1409 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1410 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1411 bool ParseDirectiveAMDGCNTarget();
1412 bool ParseDirectiveAMDHSACodeObjectVersion();
1413 bool ParseDirectiveAMDHSAKernel();
1414 bool ParseAMDKernelCodeTValue(StringRef
ID, AMDGPUMCKernelCodeT &Header);
1415 bool ParseDirectiveAMDKernelCodeT();
1417 bool subtargetHasRegister(
const MCRegisterInfo &
MRI, MCRegister
Reg);
1418 bool ParseDirectiveAMDGPUHsaKernel();
1420 bool ParseDirectiveISAVersion();
1421 bool ParseDirectiveHSAMetadata();
1422 bool ParseDirectivePALMetadataBegin();
1423 bool ParseDirectivePALMetadata();
1424 bool ParseDirectiveAMDGPULDS();
1428 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1429 const char *AssemblerDirectiveEnd,
1430 std::string &CollectString);
1432 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1433 RegisterKind RegKind, MCRegister Reg1, SMLoc Loc);
1434 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1435 unsigned &RegNum,
unsigned &RegWidth,
1436 bool RestoreOnFailure =
false);
1437 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1438 unsigned &RegNum,
unsigned &RegWidth,
1439 SmallVectorImpl<AsmToken> &Tokens);
1440 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1442 SmallVectorImpl<AsmToken> &Tokens);
1443 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1445 SmallVectorImpl<AsmToken> &Tokens);
1446 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1448 SmallVectorImpl<AsmToken> &Tokens);
1449 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &
SubReg);
1450 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1451 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1454 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1455 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1456 void initializeGprCountSymbol(RegisterKind RegKind);
1457 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1459 void cvtMubufImpl(MCInst &Inst,
const OperandVector &Operands,
1464 OperandMode_Default,
1468 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1470 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1471 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
1472 : MCTargetAsmParser(
Options, STI, MII), Parser(_Parser),
1473 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)) {
1476 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1480 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1481 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1482 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1484 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1485 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1486 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1489 initializeGprCountSymbol(IS_VGPR);
1490 initializeGprCountSymbol(IS_SGPR);
1495 createConstantSymbol(Symbol, Code);
1497 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1498 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1499 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1579 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1581 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1583 bool hasInv2PiInlineImm()
const {
1584 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1587 bool has64BitLiterals()
const {
1588 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1591 bool hasFlatOffsets()
const {
1592 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1595 bool hasTrue16Insts()
const {
1596 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1600 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1603 bool hasSGPR102_SGPR103()
const {
1607 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1609 bool hasIntClamp()
const {
1610 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1613 bool hasPartialNSAEncoding()
const {
1614 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1617 bool hasGloballyAddressableScratch()
const {
1618 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1631 AMDGPUTargetStreamer &getTargetStreamer() {
1632 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1633 return static_cast<AMDGPUTargetStreamer &
>(TS);
1639 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1642 const MCRegisterInfo *getMRI()
const {
1646 const MCInstrInfo *getMII()
const {
1652 const FeatureBitset &getFeatureBits()
const {
1653 return getSTI().getFeatureBits();
1656 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1657 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1658 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1660 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1661 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1662 bool isForcedDPP()
const {
return ForcedDPP; }
1663 bool isForcedSDWA()
const {
return ForcedSDWA; }
1664 ArrayRef<unsigned> getMatchedVariants()
const;
1665 StringRef getMatchedVariantName()
const;
1667 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1668 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1669 bool RestoreOnFailure);
1670 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1671 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1672 SMLoc &EndLoc)
override;
1673 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1674 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1675 unsigned Kind)
override;
1676 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1678 uint64_t &ErrorInfo,
1679 bool MatchingInlineAsm)
override;
1680 bool ParseDirective(AsmToken DirectiveID)
override;
1681 ParseStatus parseOperand(
OperandVector &Operands, StringRef Mnemonic,
1682 OperandMode
Mode = OperandMode_Default);
1683 StringRef parseMnemonicSuffix(StringRef Name);
1684 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1688 ParseStatus parseTokenOp(StringRef Name,
OperandVector &Operands);
1690 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1693 parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1694 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1695 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1697 ParseStatus parseOperandArrayWithPrefix(
1699 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1700 bool (*ConvertResult)(int64_t &) =
nullptr);
1704 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1705 bool IgnoreNegative =
false);
1706 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1708 ParseStatus parseScope(
OperandVector &Operands, int64_t &Scope);
1710 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1712 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1714 ArrayRef<const char *> Ids,
1716 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1718 ArrayRef<const char *> Ids,
1719 AMDGPUOperand::ImmTy
Type);
1722 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1723 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1724 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1725 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1726 bool parseSP3NegModifier();
1727 ParseStatus parseImm(
OperandVector &Operands,
bool HasSP3AbsModifier =
false,
1730 ParseStatus parseRegOrImm(
OperandVector &Operands,
bool HasSP3AbsMod =
false,
1732 ParseStatus parseRegOrImmWithFPInputMods(
OperandVector &Operands,
1733 bool AllowImm =
true);
1734 ParseStatus parseRegOrImmWithIntInputMods(
OperandVector &Operands,
1735 bool AllowImm =
true);
1736 ParseStatus parseRegWithFPInputMods(
OperandVector &Operands);
1737 ParseStatus parseRegWithIntInputMods(
OperandVector &Operands);
1740 AMDGPUOperand::ImmTy ImmTy);
1744 ParseStatus tryParseMatrixFMT(
OperandVector &Operands, StringRef Name,
1745 AMDGPUOperand::ImmTy
Type);
1748 ParseStatus tryParseMatrixScale(
OperandVector &Operands, StringRef Name,
1749 AMDGPUOperand::ImmTy
Type);
1752 ParseStatus tryParseMatrixScaleFmt(
OperandVector &Operands, StringRef Name,
1753 AMDGPUOperand::ImmTy
Type);
1757 ParseStatus parseDfmtNfmt(int64_t &
Format);
1758 ParseStatus parseUfmt(int64_t &
Format);
1759 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1761 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1764 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1765 ParseStatus parseNumericFormat(int64_t &
Format);
1769 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1770 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1774 bool parseCnt(int64_t &IntVal);
1777 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1778 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1781 bool parseDelay(int64_t &Delay);
1787 struct OperandInfoTy {
1790 bool IsSymbolic =
false;
1791 bool IsDefined =
false;
1793 constexpr OperandInfoTy(int64_t Val) : Val(Val) {}
1796 struct StructuredOpField : OperandInfoTy {
1800 bool IsDefined =
false;
1802 constexpr StructuredOpField(StringLiteral Id, StringLiteral Desc,
1803 unsigned Width, int64_t
Default)
1804 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1805 virtual ~StructuredOpField() =
default;
1807 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1808 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1812 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1814 return Error(Parser,
"not supported on this GPU");
1816 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1824 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1825 bool validateSendMsg(
const OperandInfoTy &Msg,
1826 const OperandInfoTy &
Op,
1827 const OperandInfoTy &Stream);
1829 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1830 OperandInfoTy &Width);
1832 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1834 SMLoc getFlatOffsetLoc(
const OperandVector &Operands)
const;
1835 SMLoc getSMEMOffsetLoc(
const OperandVector &Operands)
const;
1838 SMLoc getOperandLoc(
const OperandVector &Operands,
int MCOpIdx)
const;
1839 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1841 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1845 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1847 bool validateOffset(
const MCInst &Inst,
const OperandVector &Operands);
1848 bool validateFlatOffset(
const MCInst &Inst,
const OperandVector &Operands);
1849 bool validateSMEMOffset(
const MCInst &Inst,
const OperandVector &Operands);
1850 bool validateSOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1851 bool validateConstantBusLimitations(
const MCInst &Inst,
const OperandVector &Operands);
1852 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1854 bool validateVOPD(
const MCInst &Inst,
const OperandVector &Operands);
1855 bool tryVOPD(
const MCInst &Inst);
1856 bool tryVOPD3(
const MCInst &Inst);
1857 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1859 bool validateIntClampSupported(
const MCInst &Inst);
1860 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1861 bool validateMIMGGatherDMask(
const MCInst &Inst);
1862 bool validateMovrels(
const MCInst &Inst,
const OperandVector &Operands);
1863 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1864 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1865 bool validateMIMGD16(
const MCInst &Inst);
1866 bool validateMIMGDim(
const MCInst &Inst,
const OperandVector &Operands);
1867 bool validateTensorR128(
const MCInst &Inst);
1868 bool validateMIMGMSAA(
const MCInst &Inst);
1869 bool validateOpSel(
const MCInst &Inst);
1870 bool validateTrue16OpSel(
const MCInst &Inst);
1871 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1872 bool validateDPP(
const MCInst &Inst,
const OperandVector &Operands);
1873 bool validateVccOperand(MCRegister
Reg)
const;
1874 bool validateVOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1875 bool validateMAIAccWrite(
const MCInst &Inst,
const OperandVector &Operands);
1876 bool validateMAISrc2(
const MCInst &Inst,
const OperandVector &Operands);
1877 bool validateMFMA(
const MCInst &Inst,
const OperandVector &Operands);
1878 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1879 bool validateVGPRAlign(
const MCInst &Inst)
const;
1880 bool validateBLGP(
const MCInst &Inst,
const OperandVector &Operands);
1881 bool validateDS(
const MCInst &Inst,
const OperandVector &Operands);
1882 bool validateGWS(
const MCInst &Inst,
const OperandVector &Operands);
1883 bool validateDivScale(
const MCInst &Inst);
1884 bool validateWaitCnt(
const MCInst &Inst,
const OperandVector &Operands);
1885 bool validateCoherencyBits(
const MCInst &Inst,
const OperandVector &Operands,
1887 bool validateTHAndScopeBits(
const MCInst &Inst,
const OperandVector &Operands,
1888 const unsigned CPol);
1889 bool validateTFE(
const MCInst &Inst,
const OperandVector &Operands);
1890 bool validateLdsDirect(
const MCInst &Inst,
const OperandVector &Operands);
1891 bool validateWMMA(
const MCInst &Inst,
const OperandVector &Operands);
1892 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1893 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1894 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1895 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1897 bool isSupportedMnemo(StringRef Mnemo,
1898 const FeatureBitset &FBS);
1899 bool isSupportedMnemo(StringRef Mnemo,
1900 const FeatureBitset &FBS,
1901 ArrayRef<unsigned> Variants);
1902 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1904 bool isId(
const StringRef Id)
const;
1905 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1907 StringRef getId()
const;
1908 bool trySkipId(
const StringRef Id);
1909 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1913 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1914 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1920 StringRef getTokenStr()
const;
1921 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1923 SMLoc getLoc()
const;
1927 void onBeginOfFile()
override;
1928 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1930 ParseStatus parseCustomOperand(
OperandVector &Operands,
unsigned MCK);
1940 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1941 const unsigned MaxVal,
const Twine &ErrMsg,
1943 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1944 const unsigned MinVal,
1945 const unsigned MaxVal,
1946 const StringRef ErrMsg);
1948 bool parseSwizzleOffset(int64_t &
Imm);
1949 bool parseSwizzleMacro(int64_t &
Imm);
1950 bool parseSwizzleQuadPerm(int64_t &
Imm);
1951 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1952 bool parseSwizzleBroadcast(int64_t &
Imm);
1953 bool parseSwizzleSwap(int64_t &
Imm);
1954 bool parseSwizzleReverse(int64_t &
Imm);
1955 bool parseSwizzleFFT(int64_t &
Imm);
1956 bool parseSwizzleRotate(int64_t &
Imm);
1959 int64_t parseGPRIdxMacro();
1961 void cvtMubuf(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
false); }
1962 void cvtMubufAtomic(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
true); }
1967 OptionalImmIndexMap &OptionalIdx);
1968 void cvtScaledMFMA(MCInst &Inst,
const OperandVector &Operands);
1969 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands);
1972 void cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands);
1975 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
1976 OptionalImmIndexMap &OptionalIdx);
1978 OptionalImmIndexMap &OptionalIdx);
1980 void cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands);
1981 void cvtVINTERP(MCInst &Inst,
const OperandVector &Operands);
1982 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1984 bool parseDimId(
unsigned &Encoding);
1986 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1989 bool isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands);
1990 int64_t parseDPPCtrlSel(StringRef Ctrl);
1991 int64_t parseDPPCtrlPerm();
1992 void cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8 =
false);
1994 cvtDPP(Inst, Operands,
true);
1996 void cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
1997 bool IsDPP8 =
false);
1998 void cvtVOP3DPP8(MCInst &Inst,
const OperandVector &Operands) {
1999 cvtVOP3DPP(Inst, Operands,
true);
2002 ParseStatus parseSDWASel(
OperandVector &Operands, StringRef Prefix,
2003 AMDGPUOperand::ImmTy
Type);
2005 void cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands);
2006 void cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands);
2007 void cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands);
2008 void cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands);
2009 void cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands);
2011 uint64_t BasicInstType,
2012 bool SkipDstVcc =
false,
2013 bool SkipSrcVcc =
false);
2122bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2132 if (!isImmTy(ImmTyNone)) {
2137 if (getModifiers().
Lit != LitModifier::None)
2147 if (type == MVT::f64 || type == MVT::i64) {
2149 AsmParser->hasInv2PiInlineImm());
2152 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2171 APFloat::rmNearestTiesToEven, &Lost);
2178 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2180 AsmParser->hasInv2PiInlineImm());
2185 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2186 AsmParser->hasInv2PiInlineImm());
2190 if (type == MVT::f64 || type == MVT::i64) {
2192 AsmParser->hasInv2PiInlineImm());
2201 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2202 type, AsmParser->hasInv2PiInlineImm());
2206 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2207 AsmParser->hasInv2PiInlineImm());
2210bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2212 if (!isImmTy(ImmTyNone)) {
2217 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2222 if (type == MVT::f64 && hasFPModifiers()) {
2242 if (type == MVT::f64) {
2247 if (type == MVT::i64) {
2260 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2261 : (type == MVT::v2i16) ? MVT::f32
2262 : (type == MVT::v2f32) ? MVT::f32
2265 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2269bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2270 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2273bool AMDGPUOperand::isVRegWithInputMods()
const {
2274 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2276 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2277 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2280template <
bool IsFake16>
2281bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2282 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2283 : AMDGPU::VGPR_16_Lo128RegClassID);
2286template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2287 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2288 : AMDGPU::VGPR_16RegClassID);
2291bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2292 if (AsmParser->isVI())
2294 if (AsmParser->isGFX9Plus())
2295 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2299bool AMDGPUOperand::isSDWAFP16Operand()
const {
2300 return isSDWAOperand(MVT::f16);
2303bool AMDGPUOperand::isSDWAFP32Operand()
const {
2304 return isSDWAOperand(MVT::f32);
2307bool AMDGPUOperand::isSDWAInt16Operand()
const {
2308 return isSDWAOperand(MVT::i16);
2311bool AMDGPUOperand::isSDWAInt32Operand()
const {
2312 return isSDWAOperand(MVT::i32);
2315bool AMDGPUOperand::isBoolReg()
const {
2316 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2317 (AsmParser->isWave32() && isSCSrc_b32()));
2320uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2322 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2325 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2337void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2347 addLiteralImmOperand(Inst,
Imm.Val,
2349 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2351 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2356void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2357 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2362 if (ApplyModifiers) {
2365 Val = applyInputFPModifiers(Val,
Size);
2369 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2371 bool CanUse64BitLiterals =
2372 AsmParser->has64BitLiterals() &&
2375 MCContext &Ctx = AsmParser->getContext();
2384 if (
Lit == LitModifier::None &&
2386 AsmParser->hasInv2PiInlineImm())) {
2394 bool HasMandatoryLiteral =
2397 if (
Literal.getLoBits(32) != 0 &&
2398 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2399 !HasMandatoryLiteral) {
2400 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2402 "Can't encode literal as exact 64-bit floating-point operand. "
2403 "Low 32-bits will be set to zero");
2404 Val &= 0xffffffff00000000u;
2410 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2416 Lit = LitModifier::Lit64;
2417 }
else if (
Lit == LitModifier::Lit) {
2431 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2433 Lit = LitModifier::Lit64;
2440 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2441 Literal == 0x3fc45f306725feed) {
2476 APFloat::rmNearestTiesToEven, &lost);
2480 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2487 if (
Lit != LitModifier::None) {
2517 if (
Lit == LitModifier::None &&
2527 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2534 if (
Lit == LitModifier::None &&
2542 if (!AsmParser->has64BitLiterals()) {
2543 Val =
static_cast<uint64_t
>(Val) << 32;
2550 if (
Lit == LitModifier::Lit ||
2552 Val =
static_cast<uint64_t
>(Val) << 32;
2556 if (
Lit == LitModifier::Lit)
2582 if (
Lit != LitModifier::None) {
2590void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2595bool AMDGPUOperand::isInlineValue()
const {
2603void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2614 if (Is == IS_VGPR) {
2618 return AMDGPU::VGPR_32RegClassID;
2620 return AMDGPU::VReg_64RegClassID;
2622 return AMDGPU::VReg_96RegClassID;
2624 return AMDGPU::VReg_128RegClassID;
2626 return AMDGPU::VReg_160RegClassID;
2628 return AMDGPU::VReg_192RegClassID;
2630 return AMDGPU::VReg_224RegClassID;
2632 return AMDGPU::VReg_256RegClassID;
2634 return AMDGPU::VReg_288RegClassID;
2636 return AMDGPU::VReg_320RegClassID;
2638 return AMDGPU::VReg_352RegClassID;
2640 return AMDGPU::VReg_384RegClassID;
2642 return AMDGPU::VReg_512RegClassID;
2644 return AMDGPU::VReg_1024RegClassID;
2646 }
else if (Is == IS_TTMP) {
2650 return AMDGPU::TTMP_32RegClassID;
2652 return AMDGPU::TTMP_64RegClassID;
2654 return AMDGPU::TTMP_128RegClassID;
2656 return AMDGPU::TTMP_256RegClassID;
2658 return AMDGPU::TTMP_512RegClassID;
2660 }
else if (Is == IS_SGPR) {
2664 return AMDGPU::SGPR_32RegClassID;
2666 return AMDGPU::SGPR_64RegClassID;
2668 return AMDGPU::SGPR_96RegClassID;
2670 return AMDGPU::SGPR_128RegClassID;
2672 return AMDGPU::SGPR_160RegClassID;
2674 return AMDGPU::SGPR_192RegClassID;
2676 return AMDGPU::SGPR_224RegClassID;
2678 return AMDGPU::SGPR_256RegClassID;
2680 return AMDGPU::SGPR_288RegClassID;
2682 return AMDGPU::SGPR_320RegClassID;
2684 return AMDGPU::SGPR_352RegClassID;
2686 return AMDGPU::SGPR_384RegClassID;
2688 return AMDGPU::SGPR_512RegClassID;
2690 }
else if (Is == IS_AGPR) {
2694 return AMDGPU::AGPR_32RegClassID;
2696 return AMDGPU::AReg_64RegClassID;
2698 return AMDGPU::AReg_96RegClassID;
2700 return AMDGPU::AReg_128RegClassID;
2702 return AMDGPU::AReg_160RegClassID;
2704 return AMDGPU::AReg_192RegClassID;
2706 return AMDGPU::AReg_224RegClassID;
2708 return AMDGPU::AReg_256RegClassID;
2710 return AMDGPU::AReg_288RegClassID;
2712 return AMDGPU::AReg_320RegClassID;
2714 return AMDGPU::AReg_352RegClassID;
2716 return AMDGPU::AReg_384RegClassID;
2718 return AMDGPU::AReg_512RegClassID;
2720 return AMDGPU::AReg_1024RegClassID;
2728 .
Case(
"exec", AMDGPU::EXEC)
2729 .
Case(
"vcc", AMDGPU::VCC)
2730 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2731 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2732 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2733 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2734 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2735 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2736 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2737 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2738 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2739 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2740 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2741 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2742 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2743 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2744 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2745 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2746 .
Case(
"m0", AMDGPU::M0)
2747 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2748 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2749 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2750 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2751 .
Case(
"scc", AMDGPU::SRC_SCC)
2752 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2753 .
Case(
"tba", AMDGPU::TBA)
2754 .
Case(
"tma", AMDGPU::TMA)
2755 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2756 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2757 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2758 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2759 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2760 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2761 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2762 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2763 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2764 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2765 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2766 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2767 .
Case(
"pc", AMDGPU::PC_REG)
2768 .
Case(
"null", AMDGPU::SGPR_NULL)
2772bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2773 SMLoc &EndLoc,
bool RestoreOnFailure) {
2774 auto R = parseRegister();
2775 if (!R)
return true;
2777 RegNo =
R->getReg();
2778 StartLoc =
R->getStartLoc();
2779 EndLoc =
R->getEndLoc();
2783bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2785 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2788ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2790 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2791 bool PendingErrors = getParser().hasPendingError();
2792 getParser().clearPendingErrors();
2800bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2801 RegisterKind RegKind,
2802 MCRegister Reg1, SMLoc Loc) {
2805 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2810 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2811 Reg = AMDGPU::FLAT_SCR;
2815 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2816 Reg = AMDGPU::XNACK_MASK;
2820 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2825 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2830 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2835 Error(Loc,
"register does not fit in the list");
2841 if (Reg1 !=
Reg + RegWidth / 32) {
2842 Error(Loc,
"registers in a list must have consecutive indices");
2860 {{
"ttmp"}, IS_TTMP},
2866 return Kind == IS_VGPR ||
2874 if (Str.starts_with(
Reg.Name))
2880 return !Str.getAsInteger(10, Num);
2884AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2885 const AsmToken &NextToken)
const {
2900 StringRef RegSuffix = Str.substr(
RegName.size());
2901 if (!RegSuffix.
empty()) {
2919AMDGPUAsmParser::isRegister()
2921 return isRegister(
getToken(), peekToken());
2924MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2925 unsigned SubReg,
unsigned RegWidth,
2929 unsigned AlignSize = 1;
2930 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2936 if (RegNum % AlignSize != 0) {
2937 Error(Loc,
"invalid register alignment");
2938 return MCRegister();
2941 unsigned RegIdx = RegNum / AlignSize;
2944 Error(Loc,
"invalid or unsupported register size");
2945 return MCRegister();
2949 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2950 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2951 Error(Loc,
"register index is out of range");
2952 return AMDGPU::NoRegister;
2955 if (RegKind == IS_VGPR && !
isGFX1250Plus() && RegIdx + RegWidth / 32 > 256) {
2956 Error(Loc,
"register index is out of range");
2957 return MCRegister();
2973bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2975 int64_t RegLo, RegHi;
2979 SMLoc FirstIdxLoc = getLoc();
2986 SecondIdxLoc = getLoc();
2997 Error(FirstIdxLoc,
"invalid register index");
3002 Error(SecondIdxLoc,
"invalid register index");
3006 if (RegLo > RegHi) {
3007 Error(FirstIdxLoc,
"first register index should not exceed second index");
3011 if (RegHi == RegLo) {
3012 StringRef RegSuffix = getTokenStr();
3013 if (RegSuffix ==
".l") {
3016 }
else if (RegSuffix ==
".h") {
3022 Num =
static_cast<unsigned>(RegLo);
3023 RegWidth = 32 * ((RegHi - RegLo) + 1);
3028MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3031 SmallVectorImpl<AsmToken> &Tokens) {
3037 RegKind = IS_SPECIAL;
3044MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3047 SmallVectorImpl<AsmToken> &Tokens) {
3049 StringRef
RegName = getTokenStr();
3050 auto Loc = getLoc();
3054 Error(Loc,
"invalid register name");
3055 return MCRegister();
3063 unsigned SubReg = NoSubRegister;
3064 if (!RegSuffix.
empty()) {
3072 Error(Loc,
"invalid register index");
3073 return MCRegister();
3078 if (!ParseRegRange(RegNum, RegWidth,
SubReg))
3079 return MCRegister();
3082 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
3085MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3086 unsigned &RegNum,
unsigned &RegWidth,
3087 SmallVectorImpl<AsmToken> &Tokens) {
3089 auto ListLoc = getLoc();
3092 "expected a register or a list of registers")) {
3093 return MCRegister();
3098 auto Loc = getLoc();
3099 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3100 return MCRegister();
3101 if (RegWidth != 32) {
3102 Error(Loc,
"expected a single 32-bit register");
3103 return MCRegister();
3107 RegisterKind NextRegKind;
3109 unsigned NextRegNum, NextRegWidth;
3112 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3113 NextRegNum, NextRegWidth,
3115 return MCRegister();
3117 if (NextRegWidth != 32) {
3118 Error(Loc,
"expected a single 32-bit register");
3119 return MCRegister();
3121 if (NextRegKind != RegKind) {
3122 Error(Loc,
"registers in a list must be of the same kind");
3123 return MCRegister();
3125 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3126 return MCRegister();
3130 "expected a comma or a closing square bracket")) {
3131 return MCRegister();
3135 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3140bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3141 MCRegister &
Reg,
unsigned &RegNum,
3143 SmallVectorImpl<AsmToken> &Tokens) {
3144 auto Loc = getLoc();
3148 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3150 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3152 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3157 assert(Parser.hasPendingError());
3161 if (!subtargetHasRegister(*
TRI,
Reg)) {
3162 if (
Reg == AMDGPU::SGPR_NULL) {
3163 Error(Loc,
"'null' operand is not supported on this GPU");
3166 " register not available on this GPU");
3174bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3175 MCRegister &
Reg,
unsigned &RegNum,
3177 bool RestoreOnFailure ) {
3181 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3182 if (RestoreOnFailure) {
3183 while (!Tokens.
empty()) {
3192std::optional<StringRef>
3193AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3196 return StringRef(
".amdgcn.next_free_vgpr");
3198 return StringRef(
".amdgcn.next_free_sgpr");
3200 return std::nullopt;
3204void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3205 auto SymbolName = getGprCountSymbolName(RegKind);
3206 assert(SymbolName &&
"initializing invalid register kind");
3212bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3213 unsigned DwordRegIndex,
3214 unsigned RegWidth) {
3219 auto SymbolName = getGprCountSymbolName(RegKind);
3224 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3228 return !
Error(getLoc(),
3229 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3233 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3235 if (OldCount <= NewMax)
3241std::unique_ptr<AMDGPUOperand>
3242AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3244 SMLoc StartLoc = Tok.getLoc();
3245 SMLoc EndLoc = Tok.getEndLoc();
3246 RegisterKind RegKind;
3248 unsigned RegNum, RegWidth;
3250 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3254 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3257 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3258 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3261ParseStatus AMDGPUAsmParser::parseImm(
OperandVector &Operands,
3265 if (isRegister() || isModifier())
3268 if (
Lit == LitModifier::None) {
3269 if (trySkipId(
"lit"))
3270 Lit = LitModifier::Lit;
3271 else if (trySkipId(
"lit64"))
3272 Lit = LitModifier::Lit64;
3274 if (
Lit != LitModifier::None) {
3277 ParseStatus S = parseImm(Operands, HasSP3AbsModifier,
Lit);
3286 const auto& NextTok = peekToken();
3289 bool Negate =
false;
3297 AMDGPUOperand::Modifiers Mods;
3305 StringRef Num = getTokenStr();
3308 APFloat RealVal(APFloat::IEEEdouble());
3309 auto roundMode = APFloat::rmNearestTiesToEven;
3310 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3313 RealVal.changeSign();
3316 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3317 AMDGPUOperand::ImmTyNone,
true));
3318 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3319 Op.setModifiers(Mods);
3328 if (HasSP3AbsModifier) {
3337 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3340 if (Parser.parseExpression(Expr))
3344 if (Expr->evaluateAsAbsolute(IntVal)) {
3345 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3346 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3347 Op.setModifiers(Mods);
3349 if (
Lit != LitModifier::None)
3351 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3360ParseStatus AMDGPUAsmParser::parseReg(
OperandVector &Operands) {
3364 if (
auto R = parseRegister()) {
3372ParseStatus AMDGPUAsmParser::parseRegOrImm(
OperandVector &Operands,
3374 ParseStatus Res = parseReg(Operands);
3379 return parseImm(Operands, HasSP3AbsMod,
Lit);
3383AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3386 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3392AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3397AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3398 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3402AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3403 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3420AMDGPUAsmParser::isModifier() {
3423 AsmToken NextToken[2];
3424 peekTokens(NextToken);
3426 return isOperandModifier(Tok, NextToken[0]) ||
3427 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3428 isOpcodeModifierWithVal(Tok, NextToken[0]);
3454AMDGPUAsmParser::parseSP3NegModifier() {
3456 AsmToken NextToken[2];
3457 peekTokens(NextToken);
3460 (isRegister(NextToken[0], NextToken[1]) ||
3462 isId(NextToken[0],
"abs"))) {
3471AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
3479 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3481 SP3Neg = parseSP3NegModifier();
3484 Neg = trySkipId(
"neg");
3486 return Error(Loc,
"expected register or immediate");
3490 Abs = trySkipId(
"abs");
3495 if (trySkipId(
"lit")) {
3496 Lit = LitModifier::Lit;
3499 }
else if (trySkipId(
"lit64")) {
3500 Lit = LitModifier::Lit64;
3503 if (!has64BitLiterals())
3504 return Error(Loc,
"lit64 is not supported on this GPU");
3510 return Error(Loc,
"expected register or immediate");
3514 Res = parseRegOrImm(Operands, SP3Abs,
Lit);
3516 Res = parseReg(Operands);
3519 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3523 if (
Lit != LitModifier::None && !Operands.
back()->isImm())
3524 Error(Loc,
"expected immediate with lit modifier");
3526 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3532 if (
Lit != LitModifier::None &&
3536 AMDGPUOperand::Modifiers Mods;
3537 Mods.Abs = Abs || SP3Abs;
3538 Mods.Neg = Neg || SP3Neg;
3541 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3542 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3544 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3545 Op.setModifiers(Mods);
3551AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
3553 bool Sext = trySkipId(
"sext");
3554 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3559 Res = parseRegOrImm(Operands);
3561 Res = parseReg(Operands);
3569 AMDGPUOperand::Modifiers Mods;
3572 if (Mods.hasIntModifiers()) {
3573 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3575 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3576 Op.setModifiers(Mods);
3582ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
3583 return parseRegOrImmWithFPInputMods(Operands,
false);
3586ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
3587 return parseRegOrImmWithIntInputMods(Operands,
false);
3590ParseStatus AMDGPUAsmParser::parseVReg32OrOff(
OperandVector &Operands) {
3591 auto Loc = getLoc();
3592 if (trySkipId(
"off")) {
3593 Operands.
push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3594 AMDGPUOperand::ImmTyOff,
false));
3601 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3610unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3617 return Match_InvalidOperand;
3619 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3620 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3623 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3625 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3626 return Match_InvalidOperand;
3634 if (tryAnotherVOPDEncoding(Inst))
3635 return Match_InvalidOperand;
3637 return Match_Success;
3641 static const unsigned Variants[] = {
3651ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3652 if (isForcedDPP() && isForcedVOP3()) {
3656 if (getForcedEncodingSize() == 32) {
3661 if (isForcedVOP3()) {
3666 if (isForcedSDWA()) {
3672 if (isForcedDPP()) {
3680StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3681 if (isForcedDPP() && isForcedVOP3())
3684 if (getForcedEncodingSize() == 32)
3700AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3704 case AMDGPU::FLAT_SCR:
3706 case AMDGPU::VCC_LO:
3707 case AMDGPU::VCC_HI:
3714 return MCRegister();
3721bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3722 unsigned OpIdx)
const {
3779unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3785 case AMDGPU::V_LSHLREV_B64_e64:
3786 case AMDGPU::V_LSHLREV_B64_gfx10:
3787 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3788 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3789 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3790 case AMDGPU::V_LSHRREV_B64_e64:
3791 case AMDGPU::V_LSHRREV_B64_gfx10:
3792 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3793 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3794 case AMDGPU::V_ASHRREV_I64_e64:
3795 case AMDGPU::V_ASHRREV_I64_gfx10:
3796 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3797 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3798 case AMDGPU::V_LSHL_B64_e64:
3799 case AMDGPU::V_LSHR_B64_e64:
3800 case AMDGPU::V_ASHR_I64_e64:
3813 bool AddMandatoryLiterals =
false) {
3816 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3820 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3822 return {getNamedOperandIdx(Opcode, OpName::src0X),
3823 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3824 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3825 getNamedOperandIdx(Opcode, OpName::src0Y),
3826 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3827 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3832 return {getNamedOperandIdx(Opcode, OpName::src0),
3833 getNamedOperandIdx(Opcode, OpName::src1),
3834 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3837bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3840 return !isInlineConstant(Inst,
OpIdx);
3847 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3858 const unsigned Opcode = Inst.
getOpcode();
3859 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3862 if (!LaneSelOp.
isReg())
3865 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3868bool AMDGPUAsmParser::validateConstantBusLimitations(
3870 const unsigned Opcode = Inst.
getOpcode();
3871 const MCInstrDesc &
Desc = MII.
get(Opcode);
3872 MCRegister LastSGPR;
3873 unsigned ConstantBusUseCount = 0;
3874 unsigned NumLiterals = 0;
3875 unsigned LiteralSize;
3877 if (!(
Desc.TSFlags &
3892 SmallDenseSet<MCRegister> SGPRsUsed;
3893 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3895 SGPRsUsed.
insert(SGPRUsed);
3896 ++ConstantBusUseCount;
3901 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3903 for (
int OpIdx : OpIndices) {
3908 if (usesConstantBus(Inst,
OpIdx)) {
3917 if (SGPRsUsed.
insert(LastSGPR).second) {
3918 ++ConstantBusUseCount;
3938 if (NumLiterals == 0) {
3941 }
else if (LiteralSize !=
Size) {
3947 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3949 "invalid operand (violates constant bus restrictions)");
3956std::optional<unsigned>
3957AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3959 const unsigned Opcode = Inst.
getOpcode();
3965 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3966 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3975 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3976 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3977 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx13 ||
3978 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250 ||
3979 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx13;
3983 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3984 int I = getNamedOperandIdx(Opcode, OpName);
3988 int64_t
Imm =
Op.getImm();
3994 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3995 OpName::vsrc2Y, OpName::imm}) {
3996 int I = getNamedOperandIdx(Opcode, OpName);
4006 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
4007 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
4009 return InvalidCompOprIdx;
4012bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
4019 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
4020 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
4021 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
4023 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
4027 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
4028 if (!InvalidCompOprIdx.has_value())
4031 auto CompOprIdx = *InvalidCompOprIdx;
4034 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4035 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4036 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4038 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4039 if (CompOprIdx == VOPD::Component::DST) {
4041 Error(Loc,
"dst registers must be distinct");
4043 Error(Loc,
"one dst register must be even and the other odd");
4045 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4046 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4047 " operands must use different VGPR banks");
4055bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4057 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4058 if (!InvalidCompOprIdx.has_value())
4062 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4063 if (InvalidCompOprIdx.has_value()) {
4068 if (*InvalidCompOprIdx == VOPD::Component::DST)
4081bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4082 const unsigned Opcode = Inst.
getOpcode();
4097 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4098 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4099 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4100 int I = getNamedOperandIdx(Opcode, OpName);
4107 return !tryVOPD3(Inst);
4112bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4113 const unsigned Opcode = Inst.
getOpcode();
4118 return tryVOPD(Inst);
4119 return tryVOPD3(Inst);
4122bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4128 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4139bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4147 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4148 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4149 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4157 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4158 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4163 bool IsPackedD16 =
false;
4167 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4168 IsPackedD16 = D16Idx >= 0;
4173 if ((VDataSize / 4) ==
DataSize + TFESize)
4178 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4180 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4182 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4186bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4195 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4197 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4199 ? AMDGPU::OpName::srsrc
4200 : AMDGPU::OpName::rsrc;
4201 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4202 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4203 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4207 assert(SrsrcIdx > VAddr0Idx);
4210 if (BaseOpcode->
BVH) {
4211 if (IsA16 == BaseOpcode->
A16)
4213 Error(IDLoc,
"image address size does not match a16");
4219 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4220 unsigned ActualAddrSize =
4221 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4223 unsigned ExpectedAddrSize =
4227 if (hasPartialNSAEncoding() &&
4230 int VAddrLastIdx = SrsrcIdx - 1;
4231 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4233 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4236 if (ExpectedAddrSize > 12)
4237 ExpectedAddrSize = 16;
4242 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4246 if (ActualAddrSize == ExpectedAddrSize)
4249 Error(IDLoc,
"image address size does not match dim and a16");
4253bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4260 if (!
Desc.mayLoad() || !
Desc.mayStore())
4263 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4270 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4273bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4281 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4289 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4292bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4307 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4308 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4315bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4323 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4326 if (!BaseOpcode->
MSAA)
4329 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4335 return DimInfo->
MSAA;
4341 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4342 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4343 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4353bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4362 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4365 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4373 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4377bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4382 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4385 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4388 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4395 Error(getOperandLoc(Operands, Src0Idx),
4396 "source operand must be either a VGPR or an inline constant");
4403bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4406 const MCInstrDesc &
Desc = MII.
get(Opcode);
4409 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4412 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4416 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4417 Error(getOperandLoc(Operands, Src2Idx),
4418 "inline constants are not allowed for this operand");
4425bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4433 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4434 if (BlgpIdx != -1) {
4435 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4436 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4446 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4447 Error(getOperandLoc(Operands, Src0Idx),
4448 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4453 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4454 Error(getOperandLoc(Operands, Src1Idx),
4455 "wrong register tuple size for blgp value " + Twine(BLGP));
4463 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4467 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4471 MCRegister Src2Reg = Src2.
getReg();
4473 if (Src2Reg == DstReg)
4478 .getSizeInBits() <= 128)
4481 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4482 Error(getOperandLoc(Operands, Src2Idx),
4483 "source 2 operand must not partially overlap with dst");
4490bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4494 case V_DIV_SCALE_F32_gfx6_gfx7:
4495 case V_DIV_SCALE_F32_vi:
4496 case V_DIV_SCALE_F32_gfx10:
4497 case V_DIV_SCALE_F64_gfx6_gfx7:
4498 case V_DIV_SCALE_F64_vi:
4499 case V_DIV_SCALE_F64_gfx10:
4505 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4506 AMDGPU::OpName::src2_modifiers,
4507 AMDGPU::OpName::src2_modifiers}) {
4518bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4526 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4535bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4542 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4550 case AMDGPU::V_SUBREV_F32_e32:
4551 case AMDGPU::V_SUBREV_F32_e64:
4552 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4553 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4554 case AMDGPU::V_SUBREV_F32_e32_vi:
4555 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4556 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4557 case AMDGPU::V_SUBREV_F32_e64_vi:
4559 case AMDGPU::V_SUBREV_CO_U32_e32:
4560 case AMDGPU::V_SUBREV_CO_U32_e64:
4561 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4562 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4564 case AMDGPU::V_SUBBREV_U32_e32:
4565 case AMDGPU::V_SUBBREV_U32_e64:
4566 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4567 case AMDGPU::V_SUBBREV_U32_e32_vi:
4568 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4569 case AMDGPU::V_SUBBREV_U32_e64_vi:
4571 case AMDGPU::V_SUBREV_U32_e32:
4572 case AMDGPU::V_SUBREV_U32_e64:
4573 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4574 case AMDGPU::V_SUBREV_U32_e32_vi:
4575 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4576 case AMDGPU::V_SUBREV_U32_e64_vi:
4578 case AMDGPU::V_SUBREV_F16_e32:
4579 case AMDGPU::V_SUBREV_F16_e64:
4580 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4581 case AMDGPU::V_SUBREV_F16_e32_vi:
4582 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4583 case AMDGPU::V_SUBREV_F16_e64_vi:
4585 case AMDGPU::V_SUBREV_U16_e32:
4586 case AMDGPU::V_SUBREV_U16_e64:
4587 case AMDGPU::V_SUBREV_U16_e32_vi:
4588 case AMDGPU::V_SUBREV_U16_e64_vi:
4590 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4591 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4592 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4594 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4595 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4597 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4598 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4600 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4601 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4603 case AMDGPU::V_LSHRREV_B32_e32:
4604 case AMDGPU::V_LSHRREV_B32_e64:
4605 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4606 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4607 case AMDGPU::V_LSHRREV_B32_e32_vi:
4608 case AMDGPU::V_LSHRREV_B32_e64_vi:
4609 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4610 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4612 case AMDGPU::V_ASHRREV_I32_e32:
4613 case AMDGPU::V_ASHRREV_I32_e64:
4614 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4615 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4616 case AMDGPU::V_ASHRREV_I32_e32_vi:
4617 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4618 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4619 case AMDGPU::V_ASHRREV_I32_e64_vi:
4621 case AMDGPU::V_LSHLREV_B32_e32:
4622 case AMDGPU::V_LSHLREV_B32_e64:
4623 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4624 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4625 case AMDGPU::V_LSHLREV_B32_e32_vi:
4626 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4627 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4628 case AMDGPU::V_LSHLREV_B32_e64_vi:
4630 case AMDGPU::V_LSHLREV_B16_e32:
4631 case AMDGPU::V_LSHLREV_B16_e64:
4632 case AMDGPU::V_LSHLREV_B16_e32_vi:
4633 case AMDGPU::V_LSHLREV_B16_e64_vi:
4634 case AMDGPU::V_LSHLREV_B16_gfx10:
4636 case AMDGPU::V_LSHRREV_B16_e32:
4637 case AMDGPU::V_LSHRREV_B16_e64:
4638 case AMDGPU::V_LSHRREV_B16_e32_vi:
4639 case AMDGPU::V_LSHRREV_B16_e64_vi:
4640 case AMDGPU::V_LSHRREV_B16_gfx10:
4642 case AMDGPU::V_ASHRREV_I16_e32:
4643 case AMDGPU::V_ASHRREV_I16_e64:
4644 case AMDGPU::V_ASHRREV_I16_e32_vi:
4645 case AMDGPU::V_ASHRREV_I16_e64_vi:
4646 case AMDGPU::V_ASHRREV_I16_gfx10:
4648 case AMDGPU::V_LSHLREV_B64_e64:
4649 case AMDGPU::V_LSHLREV_B64_gfx10:
4650 case AMDGPU::V_LSHLREV_B64_vi:
4652 case AMDGPU::V_LSHRREV_B64_e64:
4653 case AMDGPU::V_LSHRREV_B64_gfx10:
4654 case AMDGPU::V_LSHRREV_B64_vi:
4656 case AMDGPU::V_ASHRREV_I64_e64:
4657 case AMDGPU::V_ASHRREV_I64_gfx10:
4658 case AMDGPU::V_ASHRREV_I64_vi:
4660 case AMDGPU::V_PK_LSHLREV_B16:
4661 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4662 case AMDGPU::V_PK_LSHLREV_B16_vi:
4664 case AMDGPU::V_PK_LSHRREV_B16:
4665 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4666 case AMDGPU::V_PK_LSHRREV_B16_vi:
4667 case AMDGPU::V_PK_ASHRREV_I16:
4668 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4669 case AMDGPU::V_PK_ASHRREV_I16_vi:
4676bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4678 using namespace SIInstrFlags;
4679 const unsigned Opcode = Inst.
getOpcode();
4680 const MCInstrDesc &
Desc = MII.
get(Opcode);
4685 if ((
Desc.TSFlags & Enc) == 0)
4688 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4689 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4693 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4696 Error(getOperandLoc(Operands, SrcIdx),
4697 "lds_direct is not supported on this GPU");
4702 Error(getOperandLoc(Operands, SrcIdx),
4703 "lds_direct cannot be used with this instruction");
4707 if (SrcName != OpName::src0) {
4708 Error(getOperandLoc(Operands, SrcIdx),
4709 "lds_direct may be used as src0 only");
4718SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4719 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4720 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4721 if (
Op.isFlatOffset())
4722 return Op.getStartLoc();
4727bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4730 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4736 return validateFlatOffset(Inst, Operands);
4739 return validateSMEMOffset(Inst, Operands);
4745 const unsigned OffsetSize = 24;
4746 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4747 Error(getFlatOffsetLoc(Operands),
4748 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4749 "-bit unsigned offset for buffer ops");
4753 const unsigned OffsetSize = 16;
4754 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4755 Error(getFlatOffsetLoc(Operands),
4756 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4763bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4770 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4774 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4775 Error(getFlatOffsetLoc(Operands),
4776 "flat offset modifier is not supported on this GPU");
4783 bool AllowNegative =
4786 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4787 Error(getFlatOffsetLoc(Operands),
4788 Twine(
"expected a ") +
4789 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4790 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4797SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4799 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4800 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4801 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4802 return Op.getStartLoc();
4807bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4817 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4831 Error(getSMEMOffsetLoc(Operands),
4833 ?
"expected a 23-bit unsigned offset for buffer ops"
4834 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4835 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4836 :
"expected a 21-bit signed offset");
4841bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4844 const MCInstrDesc &
Desc = MII.
get(Opcode);
4848 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4849 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4851 const int OpIndices[] = { Src0Idx, Src1Idx };
4853 unsigned NumExprs = 0;
4854 unsigned NumLiterals = 0;
4857 for (
int OpIdx : OpIndices) {
4858 if (
OpIdx == -1)
break;
4864 std::optional<int64_t>
Imm;
4867 }
else if (MO.
isExpr()) {
4876 if (!
Imm.has_value()) {
4878 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4882 if (NumLiterals == 0 || LiteralValue !=
Value) {
4890 if (NumLiterals + NumExprs <= 1)
4893 Error(getOperandLoc(Operands, Src1Idx),
4894 "only one unique literal operand is allowed");
4898bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4901 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4911 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4912 if (OpSelIdx != -1) {
4916 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4917 if (OpSelHiIdx != -1) {
4926 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4936 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4937 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4938 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4939 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4941 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4942 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4948 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4950 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4960 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4961 if (Src2Idx != -1) {
4962 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4972bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4973 if (!hasTrue16Insts())
4975 const MCRegisterInfo *
MRI = getMRI();
4977 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4983 if (OpSelOpValue == 0)
4985 unsigned OpCount = 0;
4986 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4987 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4988 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4993 MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(
Op.getReg())) {
4995 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4996 if (OpSelOpIsHi != VGPRSuffixIsHi)
5005bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
5006 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
5019 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
5030 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
5031 AMDGPU::OpName::src1_modifiers,
5032 AMDGPU::OpName::src2_modifiers};
5034 for (
unsigned i = 0; i < 3; ++i) {
5044bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5047 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5048 if (DppCtrlIdx >= 0) {
5055 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5056 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5057 :
"DP ALU dpp only supports row_newbcast");
5062 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5063 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5066 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5068 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5071 Error(getOperandLoc(Operands, Src1Idx),
5072 "invalid operand for instruction");
5076 Error(getInstLoc(Operands),
5077 "src1 immediate operand invalid for instruction");
5087bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5088 return (
Reg == AMDGPU::VCC && isWave64()) ||
5089 (
Reg == AMDGPU::VCC_LO && isWave32());
5093bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5096 const MCInstrDesc &
Desc = MII.
get(Opcode);
5097 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5099 !HasMandatoryLiteral && !
isVOPD(Opcode))
5104 std::optional<unsigned> LiteralOpIdx;
5107 for (
int OpIdx : OpIndices) {
5117 std::optional<int64_t>
Imm;
5123 bool IsAnotherLiteral =
false;
5124 if (!
Imm.has_value()) {
5126 IsAnotherLiteral =
true;
5127 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5132 HasMandatoryLiteral);
5138 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5140 "invalid operand for instruction");
5144 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5151 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5152 !getFeatureBits()[FeatureVOP3Literal]) {
5154 "literal operands are not supported");
5158 if (LiteralOpIdx && IsAnotherLiteral) {
5159 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5160 getOperandLoc(Operands, *LiteralOpIdx)),
5161 "only one unique literal operand is allowed");
5165 if (IsAnotherLiteral)
5166 LiteralOpIdx =
OpIdx;
5189bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5197 ? AMDGPU::OpName::data0
5198 : AMDGPU::OpName::vdata;
5200 const MCRegisterInfo *
MRI = getMRI();
5206 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5210 auto FB = getFeatureBits();
5211 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5212 if (DataAreg < 0 || DstAreg < 0)
5214 return DstAreg == DataAreg;
5217 return DstAreg < 1 && DataAreg < 1;
5220bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5221 auto FB = getFeatureBits();
5222 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5226 const MCRegisterInfo *
MRI = getMRI();
5229 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5232 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5236 case AMDGPU::DS_LOAD_TR6_B96:
5237 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5241 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5242 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5246 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5247 if (VAddrIdx != -1) {
5249 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5250 if ((
Sub - AMDGPU::VGPR0) & 1)
5255 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5256 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5261 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5262 const MCRegisterClass &AGPR32 =
MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
5268 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5281SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5282 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5283 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5285 return Op.getStartLoc();
5290bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5293 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5296 SMLoc BLGPLoc = getBLGPLoc(Operands);
5299 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5300 auto FB = getFeatureBits();
5301 bool UsesNeg =
false;
5302 if (FB[AMDGPU::FeatureGFX940Insts]) {
5304 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5305 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5306 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5307 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5312 if (IsNeg == UsesNeg)
5316 UsesNeg ?
"invalid modifier: blgp is not supported"
5317 :
"invalid modifier: neg is not supported");
5322bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5328 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5329 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5330 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5331 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5334 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5337 if (
Reg == AMDGPU::SGPR_NULL)
5340 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5344bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5350 return validateGWS(Inst, Operands);
5355 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5360 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5361 Error(S,
"gds modifier is not supported on this GPU");
5369bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5371 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5375 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5376 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5379 const MCRegisterInfo *
MRI = getMRI();
5380 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5382 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5385 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5387 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5394bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5397 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5398 AMDGPU::OpName::cpol);
5406 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5409 Error(S,
"scale_offset is not supported on this GPU");
5412 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5415 Error(S,
"nv is not supported on this GPU");
5420 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5423 Error(S,
"scale_offset is not supported for this instruction");
5427 return validateTHAndScopeBits(Inst, Operands, CPol);
5432 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5433 Error(S,
"cache policy is not supported for SMRD instructions");
5437 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5446 if (!(TSFlags & AllowSCCModifier)) {
5447 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5451 "scc modifier is not supported for this instruction on this GPU");
5462 :
"instruction must use glc");
5467 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5470 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5472 :
"instruction must not use glc");
5480bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5482 const unsigned CPol) {
5486 const unsigned Opcode = Inst.
getOpcode();
5487 const MCInstrDesc &TID = MII.
get(Opcode);
5490 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5497 return PrintError(
"th:TH_ATOMIC_RETURN requires a destination operand");
5502 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5510 return PrintError(
"invalid th value for SMEM instruction");
5517 return PrintError(
"scope and th combination is not valid");
5523 return PrintError(
"invalid th value for atomic instructions");
5526 return PrintError(
"invalid th value for store instructions");
5529 return PrintError(
"invalid th value for load instructions");
5535bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5538 if (
Desc.mayStore() &&
5540 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5541 if (Loc != getInstLoc(Operands)) {
5542 Error(Loc,
"TFE modifier has no meaning for store instructions");
5550bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5556 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5557 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5561 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5569 Error(getOperandLoc(Operands, SrcIdx),
5570 "wrong register tuple size for " +
5575 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5576 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5579bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5581 if (!validateLdsDirect(Inst, Operands))
5583 if (!validateTrue16OpSel(Inst)) {
5584 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5585 "op_sel operand conflicts with 16-bit operand suffix");
5588 if (!validateSOPLiteral(Inst, Operands))
5590 if (!validateVOPLiteral(Inst, Operands)) {
5593 if (!validateConstantBusLimitations(Inst, Operands)) {
5596 if (!validateVOPD(Inst, Operands)) {
5599 if (!validateIntClampSupported(Inst)) {
5600 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5601 "integer clamping is not supported on this GPU");
5604 if (!validateOpSel(Inst)) {
5605 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5606 "invalid op_sel operand");
5609 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5610 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5611 "invalid neg_lo operand");
5614 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5615 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5616 "invalid neg_hi operand");
5619 if (!validateDPP(Inst, Operands)) {
5623 if (!validateMIMGD16(Inst)) {
5624 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5625 "d16 modifier is not supported on this GPU");
5628 if (!validateMIMGDim(Inst, Operands)) {
5629 Error(IDLoc,
"missing dim operand");
5632 if (!validateTensorR128(Inst)) {
5633 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5634 "instruction must set modifier r128=0");
5637 if (!validateMIMGMSAA(Inst)) {
5638 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5639 "invalid dim; must be MSAA type");
5642 if (!validateMIMGDataSize(Inst, IDLoc)) {
5645 if (!validateMIMGAddrSize(Inst, IDLoc))
5647 if (!validateMIMGAtomicDMask(Inst)) {
5648 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5649 "invalid atomic image dmask");
5652 if (!validateMIMGGatherDMask(Inst)) {
5653 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5654 "invalid image_gather dmask: only one bit must be set");
5657 if (!validateMovrels(Inst, Operands)) {
5660 if (!validateOffset(Inst, Operands)) {
5663 if (!validateMAIAccWrite(Inst, Operands)) {
5666 if (!validateMAISrc2(Inst, Operands)) {
5669 if (!validateMFMA(Inst, Operands)) {
5672 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5676 if (!validateAGPRLdSt(Inst)) {
5677 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5678 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5679 :
"invalid register class: agpr loads and stores not supported on this GPU"
5683 if (!validateVGPRAlign(Inst)) {
5685 "invalid register class: vgpr tuples must be 64 bit aligned");
5688 if (!validateDS(Inst, Operands)) {
5692 if (!validateBLGP(Inst, Operands)) {
5696 if (!validateDivScale(Inst)) {
5697 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5700 if (!validateWaitCnt(Inst, Operands)) {
5703 if (!validateTFE(Inst, Operands)) {
5706 if (!validateWMMA(Inst, Operands)) {
5715 unsigned VariantID = 0);
5719 unsigned VariantID);
5721bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5726bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5727 const FeatureBitset &FBS,
5728 ArrayRef<unsigned> Variants) {
5729 for (
auto Variant : Variants) {
5737bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5739 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5742 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5747 getParser().clearPendingErrors();
5751 StringRef VariantName = getMatchedVariantName();
5752 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5755 " variant of this instruction is not supported"));
5759 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5760 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5762 FeatureBitset FeaturesWS32 = getFeatureBits();
5763 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5764 .
flip(AMDGPU::FeatureWavefrontSize32);
5765 FeatureBitset AvailableFeaturesWS32 =
5766 ComputeAvailableFeatures(FeaturesWS32);
5768 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5769 return Error(IDLoc,
"instruction requires wavesize=32");
5773 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5774 return Error(IDLoc,
"instruction not supported on this GPU");
5779 return Error(IDLoc,
"invalid instruction" + Suggestion);
5785 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5786 if (
Op.isToken() && InvalidOprIdx > 1) {
5787 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5788 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5793bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5796 uint64_t &ErrorInfo,
5797 bool MatchingInlineAsm) {
5800 unsigned Result = Match_Success;
5801 for (
auto Variant : getMatchedVariants()) {
5803 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5808 if (R == Match_Success || R == Match_MissingFeature ||
5809 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5810 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5811 Result != Match_MissingFeature)) {
5815 if (R == Match_Success)
5819 if (Result == Match_Success) {
5820 if (!validateInstruction(Inst, IDLoc, Operands)) {
5827 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5828 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5834 case Match_MissingFeature:
5838 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5840 case Match_InvalidOperand: {
5841 SMLoc ErrorLoc = IDLoc;
5842 if (ErrorInfo != ~0ULL) {
5843 if (ErrorInfo >= Operands.
size()) {
5844 return Error(IDLoc,
"too few operands for instruction");
5846 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5847 if (ErrorLoc == SMLoc())
5851 return Error(ErrorLoc,
"invalid VOPDY instruction");
5853 return Error(ErrorLoc,
"invalid operand for instruction");
5856 case Match_MnemonicFail:
5862bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5867 if (getParser().parseAbsoluteExpression(Tmp)) {
5870 Ret =
static_cast<uint32_t
>(Tmp);
5874bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5875 if (!getSTI().getTargetTriple().isAMDGCN())
5876 return TokError(
"directive only supported for amdgcn architecture");
5878 std::string TargetIDDirective;
5879 SMLoc TargetStart = getTok().getLoc();
5880 if (getParser().parseEscapedString(TargetIDDirective))
5883 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5884 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5885 return getParser().Error(TargetRange.
Start,
5886 (Twine(
".amdgcn_target directive's target id ") +
5887 Twine(TargetIDDirective) +
5888 Twine(
" does not match the specified target id ") +
5889 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5894bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5898bool AMDGPUAsmParser::calculateGPRBlocks(
5899 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5900 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5901 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5902 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5903 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5909 const MCExpr *
NumSGPRs = NextFreeSGPR;
5910 int64_t EvaluatedSGPRs;
5915 unsigned MaxAddressableNumSGPRs =
5918 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5919 !Features.
test(FeatureSGPRInitBug) &&
5920 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5921 return OutOfRangeError(SGPRRange);
5923 const MCExpr *ExtraSGPRs =
5927 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5928 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5929 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5930 return OutOfRangeError(SGPRRange);
5932 if (Features.
test(FeatureSGPRInitBug))
5939 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5940 unsigned Granule) ->
const MCExpr * {
5944 const MCExpr *AlignToGPR =
5946 const MCExpr *DivGPR =
5952 VGPRBlocks = GetNumGPRBlocks(
5961bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5962 if (!getSTI().getTargetTriple().isAMDGCN())
5963 return TokError(
"directive only supported for amdgcn architecture");
5966 return TokError(
"directive only supported for amdhsa OS");
5968 StringRef KernelName;
5969 if (getParser().parseIdentifier(KernelName))
5972 AMDGPU::MCKernelDescriptor KD =
5984 const MCExpr *NextFreeVGPR = ZeroExpr;
5986 const MCExpr *NamedBarCnt = ZeroExpr;
5987 uint64_t SharedVGPRCount = 0;
5988 uint64_t PreloadLength = 0;
5989 uint64_t PreloadOffset = 0;
5991 const MCExpr *NextFreeSGPR = ZeroExpr;
5994 unsigned ImpliedUserSGPRCount = 0;
5998 std::optional<unsigned> ExplicitUserSGPRCount;
5999 const MCExpr *ReserveVCC = OneExpr;
6000 const MCExpr *ReserveFlatScr = OneExpr;
6001 std::optional<bool> EnableWavefrontSize32;
6007 SMRange IDRange = getTok().getLocRange();
6008 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6011 if (
ID ==
".end_amdhsa_kernel")
6015 return TokError(
".amdhsa_ directives cannot be repeated");
6017 SMLoc ValStart = getLoc();
6018 const MCExpr *ExprVal;
6019 if (getParser().parseExpression(ExprVal))
6021 SMLoc ValEnd = getLoc();
6022 SMRange ValRange = SMRange(ValStart, ValEnd);
6025 uint64_t Val = IVal;
6026 bool EvaluatableExpr;
6027 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6029 return OutOfRangeError(ValRange);
6033#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6034 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6035 return OutOfRangeError(RANGE); \
6036 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6041#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6043 return Error(IDRange.Start, "directive should have resolvable expression", \
6046 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6049 return OutOfRangeError(ValRange);
6051 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6054 return OutOfRangeError(ValRange);
6056 }
else if (
ID ==
".amdhsa_kernarg_size") {
6058 return OutOfRangeError(ValRange);
6060 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6062 ExplicitUserSGPRCount = Val;
6063 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6067 "directive is not supported with architected flat scratch",
6070 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6073 ImpliedUserSGPRCount += 4;
6074 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6077 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6080 return OutOfRangeError(ValRange);
6084 ImpliedUserSGPRCount += Val;
6085 PreloadLength = Val;
6087 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6090 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6093 return OutOfRangeError(ValRange);
6097 PreloadOffset = Val;
6098 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6101 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6104 ImpliedUserSGPRCount += 2;
6105 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6108 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6111 ImpliedUserSGPRCount += 2;
6112 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6115 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6118 ImpliedUserSGPRCount += 2;
6119 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6122 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6125 ImpliedUserSGPRCount += 2;
6126 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6129 "directive is not supported with architected flat scratch",
6133 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6136 ImpliedUserSGPRCount += 2;
6137 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6140 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6143 ImpliedUserSGPRCount += 1;
6144 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6146 if (IVersion.
Major < 10)
6147 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6148 EnableWavefrontSize32 = Val;
6150 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6152 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6154 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6156 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6159 "directive is not supported with architected flat scratch",
6162 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6164 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6168 "directive is not supported without architected flat scratch",
6171 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6173 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6175 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6177 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6179 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6181 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6183 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6185 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6187 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6189 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6191 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6193 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6194 VGPRRange = ValRange;
6195 NextFreeVGPR = ExprVal;
6196 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6197 SGPRRange = ValRange;
6198 NextFreeSGPR = ExprVal;
6199 }
else if (
ID ==
".amdhsa_accum_offset") {
6201 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6202 AccumOffset = ExprVal;
6203 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6205 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6206 NamedBarCnt = ExprVal;
6207 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6209 return OutOfRangeError(ValRange);
6210 ReserveVCC = ExprVal;
6211 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6212 if (IVersion.
Major < 7)
6213 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6216 "directive is not supported with architected flat scratch",
6219 return OutOfRangeError(ValRange);
6220 ReserveFlatScr = ExprVal;
6221 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6222 if (IVersion.
Major < 8)
6223 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6225 return OutOfRangeError(ValRange);
6226 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6227 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6229 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6231 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6233 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6235 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6237 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6239 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6241 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6243 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6245 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6246 if (IVersion.
Major >= 12)
6247 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6249 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6251 }
else if (
ID ==
".amdhsa_ieee_mode") {
6252 if (IVersion.
Major >= 12)
6253 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6255 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6257 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6258 if (IVersion.
Major < 9)
6259 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6261 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6263 }
else if (
ID ==
".amdhsa_tg_split") {
6265 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6268 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6271 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6273 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6275 }
else if (
ID ==
".amdhsa_memory_ordered") {
6276 if (IVersion.
Major < 10)
6277 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6279 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6281 }
else if (
ID ==
".amdhsa_forward_progress") {
6282 if (IVersion.
Major < 10)
6283 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6285 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6287 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6289 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6290 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6292 SharedVGPRCount = Val;
6294 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6296 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6297 if (IVersion.
Major < 11)
6298 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6299 if (IVersion.
Major == 11) {
6301 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6305 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6308 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6311 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6313 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6315 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6317 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6320 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6322 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6324 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6326 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6328 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6330 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6332 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6334 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6336 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6338 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6339 if (IVersion.
Major < 12)
6340 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6342 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6345 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6348#undef PARSE_BITS_ENTRY
6351 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6352 return TokError(
".amdhsa_next_free_vgpr directive is required");
6354 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6355 return TokError(
".amdhsa_next_free_sgpr directive is required");
6357 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6362 if (PreloadLength) {
6368 const MCExpr *VGPRBlocks;
6369 const MCExpr *SGPRBlocks;
6370 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6371 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6372 EnableWavefrontSize32, NextFreeVGPR,
6373 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6377 int64_t EvaluatedVGPRBlocks;
6378 bool VGPRBlocksEvaluatable =
6379 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6380 if (VGPRBlocksEvaluatable &&
6382 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6383 return OutOfRangeError(VGPRRange);
6387 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6388 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6390 int64_t EvaluatedSGPRBlocks;
6391 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6393 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6394 return OutOfRangeError(SGPRRange);
6397 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6398 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6400 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6401 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6402 "enabled user SGPRs");
6406 return TokError(
"too many user SGPRs enabled");
6410 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6411 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6415 return TokError(
"too many user SGPRs enabled");
6419 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6420 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6425 return TokError(
"Kernarg size should be resolvable");
6426 uint64_t kernarg_size = IVal;
6427 if (PreloadLength && kernarg_size &&
6428 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6429 return TokError(
"Kernarg preload length + offset is larger than the "
6430 "kernarg segment size");
6433 if (!Seen.
contains(
".amdhsa_accum_offset"))
6434 return TokError(
".amdhsa_accum_offset directive is required");
6435 int64_t EvaluatedAccum;
6436 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6437 uint64_t UEvaluatedAccum = EvaluatedAccum;
6438 if (AccumEvaluatable &&
6439 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6440 return TokError(
"accum_offset should be in range [4..256] in "
6443 int64_t EvaluatedNumVGPR;
6444 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6447 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6448 return TokError(
"accum_offset exceeds total VGPR allocation");
6454 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6455 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6461 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6462 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6465 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6467 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6468 return TokError(
"shared_vgpr_count directive not valid on "
6469 "wavefront size 32");
6472 if (VGPRBlocksEvaluatable &&
6473 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6475 return TokError(
"shared_vgpr_count*2 + "
6476 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6481 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6482 NextFreeVGPR, NextFreeSGPR,
6483 ReserveVCC, ReserveFlatScr);
6487bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6489 if (ParseAsAbsoluteExpression(
Version))
6492 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6496bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6497 AMDGPUMCKernelCodeT &
C) {
6500 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6501 Parser.eatToEndOfStatement();
6505 SmallString<40> ErrStr;
6506 raw_svector_ostream Err(ErrStr);
6507 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6508 return TokError(Err.
str());
6512 if (
ID ==
"enable_wavefront_size32") {
6515 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6517 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6520 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6524 if (
ID ==
"wavefront_size") {
6525 if (
C.wavefront_size == 5) {
6527 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6529 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6530 }
else if (
C.wavefront_size == 6) {
6532 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6539bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6540 AMDGPUMCKernelCodeT KernelCode;
6549 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6552 if (
ID ==
".end_amd_kernel_code_t")
6555 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6560 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6565bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6566 StringRef KernelName;
6567 if (!parseId(KernelName,
"expected symbol name"))
6570 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6577bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6578 if (!getSTI().getTargetTriple().isAMDGCN()) {
6579 return Error(getLoc(),
6580 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6584 auto TargetIDDirective = getLexer().getTok().getStringContents();
6585 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6586 return Error(getParser().getTok().getLoc(),
"target id must match options");
6588 getTargetStreamer().EmitISAVersion();
6594bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6597 std::string HSAMetadataString;
6602 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6603 return Error(getLoc(),
"invalid HSA metadata");
6610bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6611 const char *AssemblerDirectiveEnd,
6612 std::string &CollectString) {
6614 raw_string_ostream CollectStream(CollectString);
6616 getLexer().setSkipSpace(
false);
6618 bool FoundEnd =
false;
6621 CollectStream << getTokenStr();
6625 if (trySkipId(AssemblerDirectiveEnd)) {
6630 CollectStream << Parser.parseStringToEndOfStatement()
6631 <<
getContext().getAsmInfo()->getSeparatorString();
6633 Parser.eatToEndOfStatement();
6636 getLexer().setSkipSpace(
true);
6639 return TokError(Twine(
"expected directive ") +
6640 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6647bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6653 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6654 if (!PALMetadata->setFromString(
String))
6655 return Error(getLoc(),
"invalid PAL metadata");
6660bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6662 return Error(getLoc(),
6664 "not available on non-amdpal OSes")).str());
6667 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6668 PALMetadata->setLegacy();
6671 if (ParseAsAbsoluteExpression(
Key)) {
6672 return TokError(Twine(
"invalid value in ") +
6676 return TokError(Twine(
"expected an even number of values in ") +
6679 if (ParseAsAbsoluteExpression(
Value)) {
6680 return TokError(Twine(
"invalid value in ") +
6683 PALMetadata->setRegister(
Key,
Value);
6692bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6693 if (getParser().checkForValidSection())
6697 SMLoc NameLoc = getLoc();
6698 if (getParser().parseIdentifier(Name))
6699 return TokError(
"expected identifier in directive");
6702 if (getParser().parseComma())
6708 SMLoc SizeLoc = getLoc();
6709 if (getParser().parseAbsoluteExpression(
Size))
6712 return Error(SizeLoc,
"size must be non-negative");
6713 if (
Size > LocalMemorySize)
6714 return Error(SizeLoc,
"size is too large");
6716 int64_t Alignment = 4;
6718 SMLoc AlignLoc = getLoc();
6719 if (getParser().parseAbsoluteExpression(Alignment))
6722 return Error(AlignLoc,
"alignment must be a power of two");
6727 if (Alignment >= 1u << 31)
6728 return Error(AlignLoc,
"alignment is too large");
6734 Symbol->redefineIfPossible();
6735 if (!
Symbol->isUndefined())
6736 return Error(NameLoc,
"invalid symbol redefinition");
6738 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6742bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6743 StringRef IDVal = DirectiveID.
getString();
6746 if (IDVal ==
".amdhsa_kernel")
6747 return ParseDirectiveAMDHSAKernel();
6749 if (IDVal ==
".amdhsa_code_object_version")
6750 return ParseDirectiveAMDHSACodeObjectVersion();
6754 return ParseDirectiveHSAMetadata();
6756 if (IDVal ==
".amd_kernel_code_t")
6757 return ParseDirectiveAMDKernelCodeT();
6759 if (IDVal ==
".amdgpu_hsa_kernel")
6760 return ParseDirectiveAMDGPUHsaKernel();
6762 if (IDVal ==
".amd_amdgpu_isa")
6763 return ParseDirectiveISAVersion();
6767 Twine(
" directive is "
6768 "not available on non-amdhsa OSes"))
6773 if (IDVal ==
".amdgcn_target")
6774 return ParseDirectiveAMDGCNTarget();
6776 if (IDVal ==
".amdgpu_lds")
6777 return ParseDirectiveAMDGPULDS();
6780 return ParseDirectivePALMetadataBegin();
6783 return ParseDirectivePALMetadata();
6788bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
6790 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
6794 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
6795 return hasSGPR104_SGPR105();
6798 case SRC_SHARED_BASE_LO:
6799 case SRC_SHARED_BASE:
6800 case SRC_SHARED_LIMIT_LO:
6801 case SRC_SHARED_LIMIT:
6802 case SRC_PRIVATE_BASE_LO:
6803 case SRC_PRIVATE_BASE:
6804 case SRC_PRIVATE_LIMIT_LO:
6805 case SRC_PRIVATE_LIMIT:
6807 case SRC_FLAT_SCRATCH_BASE_LO:
6808 case SRC_FLAT_SCRATCH_BASE_HI:
6809 return hasGloballyAddressableScratch();
6810 case SRC_POPS_EXITING_WAVE_ID:
6822 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6851 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
6852 return hasSGPR102_SGPR103();
6857ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6860 ParseStatus Res = parseVOPD(Operands);
6865 Res = MatchOperandParserImpl(Operands, Mnemonic);
6877 SMLoc LBraceLoc = getLoc();
6882 auto Loc = getLoc();
6883 Res = parseReg(Operands);
6885 Error(Loc,
"expected a register");
6889 RBraceLoc = getLoc();
6894 "expected a comma or a closing square bracket"))
6898 if (Operands.
size() - Prefix > 1) {
6900 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6901 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6907 return parseRegOrImm(Operands);
6910StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6912 setForcedEncodingSize(0);
6913 setForcedDPP(
false);
6914 setForcedSDWA(
false);
6916 if (
Name.consume_back(
"_e64_dpp")) {
6918 setForcedEncodingSize(64);
6921 if (
Name.consume_back(
"_e64")) {
6922 setForcedEncodingSize(64);
6925 if (
Name.consume_back(
"_e32")) {
6926 setForcedEncodingSize(32);
6929 if (
Name.consume_back(
"_dpp")) {
6933 if (
Name.consume_back(
"_sdwa")) {
6934 setForcedSDWA(
true);
6942 unsigned VariantID);
6948 Name = parseMnemonicSuffix(Name);
6954 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6956 bool IsMIMG = Name.starts_with(
"image_");
6959 OperandMode
Mode = OperandMode_Default;
6961 Mode = OperandMode_NSA;
6965 checkUnsupportedInstruction(Name, NameLoc);
6966 if (!Parser.hasPendingError()) {
6969 :
"not a valid operand.";
6970 Error(getLoc(), Msg);
6989ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6992 if (!trySkipId(Name))
6995 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6999ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7008ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7009 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7010 std::function<
bool(int64_t &)> ConvertResult) {
7014 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7018 if (ConvertResult && !ConvertResult(
Value)) {
7019 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7022 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7026ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7027 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7028 bool (*ConvertResult)(int64_t &)) {
7037 const unsigned MaxSize = 4;
7041 for (
int I = 0; ; ++
I) {
7043 SMLoc Loc = getLoc();
7047 if (
Op != 0 &&
Op != 1)
7048 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7055 if (
I + 1 == MaxSize)
7056 return Error(getLoc(),
"expected a closing square bracket");
7062 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7066ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7068 AMDGPUOperand::ImmTy ImmTy,
7069 bool IgnoreNegative) {
7073 if (trySkipId(Name)) {
7075 }
else if (trySkipId(
"no", Name)) {
7084 return Error(S,
"r128 modifier is not supported on this GPU");
7085 if (Name ==
"a16" && !
hasA16())
7086 return Error(S,
"a16 modifier is not supported on this GPU");
7088 if (Bit == 0 && Name ==
"gds") {
7089 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7091 return Error(S,
"nogds is not allowed");
7094 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7095 ImmTy = AMDGPUOperand::ImmTyR128A16;
7097 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7101unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7102 bool &Disabling)
const {
7103 Disabling =
Id.consume_front(
"no");
7106 return StringSwitch<unsigned>(Id)
7113 return StringSwitch<unsigned>(Id)
7121ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7123 SMLoc StringLoc = getLoc();
7125 int64_t CPolVal = 0;
7134 ResTH = parseTH(Operands, TH);
7145 ResScope = parseScope(Operands, Scope);
7158 if (trySkipId(
"nv")) {
7162 }
else if (trySkipId(
"no",
"nv")) {
7169 if (trySkipId(
"scale_offset")) {
7173 }
else if (trySkipId(
"no",
"scale_offset")) {
7186 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7187 AMDGPUOperand::ImmTyCPol));
7191 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7192 SMLoc OpLoc = getLoc();
7193 unsigned Enabled = 0, Seen = 0;
7197 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7204 return Error(S,
"dlc modifier is not supported on this GPU");
7207 return Error(S,
"scc modifier is not supported on this GPU");
7210 return Error(S,
"duplicate cache policy modifier");
7222 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7226ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7231 ParseStatus Res = parseStringOrIntWithPrefix(
7232 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7241ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7246 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7250 if (
Value ==
"TH_DEFAULT")
7252 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7253 Value ==
"TH_LOAD_NT_WB") {
7254 return Error(StringLoc,
"invalid th value");
7255 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7257 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7259 }
else if (
Value.consume_front(
"TH_STORE_")) {
7262 return Error(StringLoc,
"invalid th value");
7265 if (
Value ==
"BYPASS")
7270 TH |= StringSwitch<int64_t>(
Value)
7280 .Default(0xffffffff);
7282 TH |= StringSwitch<int64_t>(
Value)
7293 .Default(0xffffffff);
7296 if (TH == 0xffffffff)
7297 return Error(StringLoc,
"invalid th value");
7304 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7305 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7306 std::optional<unsigned> InsertAt = std::nullopt) {
7307 auto i = OptionalIdx.find(ImmT);
7308 if (i != OptionalIdx.end()) {
7309 unsigned Idx = i->second;
7310 const AMDGPUOperand &
Op =
7311 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7315 Op.addImmOperands(Inst, 1);
7317 if (InsertAt.has_value())
7324ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7330 StringLoc = getLoc();
7335ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7336 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7341 SMLoc StringLoc = getLoc();
7345 Value = getTokenStr();
7349 if (
Value == Ids[IntVal])
7354 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7355 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7360ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7361 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7362 AMDGPUOperand::ImmTy
Type) {
7366 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7368 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7377bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7381 SMLoc Loc = getLoc();
7383 auto Res = parseIntWithPrefix(Pref, Val);
7389 if (Val < 0 || Val > MaxVal) {
7390 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7398ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7399 AMDGPUOperand::ImmTy ImmTy) {
7400 const char *Pref =
"index_key";
7402 SMLoc Loc = getLoc();
7403 auto Res = parseIntWithPrefix(Pref, ImmVal);
7407 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7408 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7409 (ImmVal < 0 || ImmVal > 1))
7410 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7412 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7413 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7415 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7419ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7420 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7423ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7424 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7427ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7428 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7431ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7433 AMDGPUOperand::ImmTy
Type) {
7438ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7439 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7440 AMDGPUOperand::ImmTyMatrixAFMT);
7443ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7444 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7445 AMDGPUOperand::ImmTyMatrixBFMT);
7448ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7450 AMDGPUOperand::ImmTy
Type) {
7455ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7456 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7457 AMDGPUOperand::ImmTyMatrixAScale);
7460ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7461 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7462 AMDGPUOperand::ImmTyMatrixBScale);
7465ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7467 AMDGPUOperand::ImmTy
Type) {
7472ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7473 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7474 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7477ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7478 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7479 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7484ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7485 using namespace llvm::AMDGPU::MTBUFFormat;
7491 for (
int I = 0;
I < 2; ++
I) {
7492 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7495 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7500 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7506 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7509 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7510 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7516ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7517 using namespace llvm::AMDGPU::MTBUFFormat;
7521 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7524 if (Fmt == UFMT_UNDEF)
7531bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7533 StringRef FormatStr,
7535 using namespace llvm::AMDGPU::MTBUFFormat;
7539 if (
Format != DFMT_UNDEF) {
7545 if (
Format != NFMT_UNDEF) {
7550 Error(Loc,
"unsupported format");
7554ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7557 using namespace llvm::AMDGPU::MTBUFFormat;
7561 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7566 SMLoc Loc = getLoc();
7567 if (!parseId(Str,
"expected a format string") ||
7568 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7570 if (Dfmt == DFMT_UNDEF)
7571 return Error(Loc,
"duplicate numeric format");
7572 if (Nfmt == NFMT_UNDEF)
7573 return Error(Loc,
"duplicate data format");
7576 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7577 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7581 if (Ufmt == UFMT_UNDEF)
7582 return Error(FormatLoc,
"unsupported format");
7591ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7594 using namespace llvm::AMDGPU::MTBUFFormat;
7597 if (Id == UFMT_UNDEF)
7601 return Error(Loc,
"unified format is not supported on this GPU");
7607ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7608 using namespace llvm::AMDGPU::MTBUFFormat;
7609 SMLoc Loc = getLoc();
7614 return Error(Loc,
"out of range format");
7619ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7620 using namespace llvm::AMDGPU::MTBUFFormat;
7626 StringRef FormatStr;
7627 SMLoc Loc = getLoc();
7628 if (!parseId(FormatStr,
"expected a format string"))
7631 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7633 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7643 return parseNumericFormat(
Format);
7646ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7647 using namespace llvm::AMDGPU::MTBUFFormat;
7651 SMLoc Loc = getLoc();
7661 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7673 Res = parseRegOrImm(Operands);
7680 Res = parseSymbolicOrNumericFormat(
Format);
7685 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7686 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7693 return Error(getLoc(),
"duplicate format");
7697ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7699 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7701 Res = parseIntWithPrefix(
"inst_offset", Operands,
7702 AMDGPUOperand::ImmTyInstOffset);
7707ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7709 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7711 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7715ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7717 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7720 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7729void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7730 OptionalImmIndexMap OptionalIdx;
7732 unsigned OperandIdx[4];
7733 unsigned EnMask = 0;
7736 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7737 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7742 OperandIdx[SrcIdx] = Inst.
size();
7743 Op.addRegOperands(Inst, 1);
7750 OperandIdx[SrcIdx] = Inst.
size();
7756 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7757 Op.addImmOperands(Inst, 1);
7761 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7765 OptionalIdx[
Op.getImmTy()] = i;
7771 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7778 for (
auto i = 0; i < SrcIdx; ++i) {
7780 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7805 IntVal =
encode(ISA, IntVal, CntVal);
7806 if (CntVal !=
decode(ISA, IntVal)) {
7808 IntVal =
encode(ISA, IntVal, -1);
7816bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7818 SMLoc CntLoc = getLoc();
7819 StringRef CntName = getTokenStr();
7826 SMLoc ValLoc = getLoc();
7835 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7837 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7839 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7842 Error(CntLoc,
"invalid counter name " + CntName);
7847 Error(ValLoc,
"too large value for " + CntName);
7856 Error(getLoc(),
"expected a counter name");
7864ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7871 if (!parseCnt(Waitcnt))
7879 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7883bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7884 SMLoc FieldLoc = getLoc();
7885 StringRef FieldName = getTokenStr();
7890 SMLoc ValueLoc = getLoc();
7897 if (FieldName ==
"instid0") {
7899 }
else if (FieldName ==
"instskip") {
7901 }
else if (FieldName ==
"instid1") {
7904 Error(FieldLoc,
"invalid field name " + FieldName);
7923 .Case(
"VALU_DEP_1", 1)
7924 .Case(
"VALU_DEP_2", 2)
7925 .Case(
"VALU_DEP_3", 3)
7926 .Case(
"VALU_DEP_4", 4)
7927 .Case(
"TRANS32_DEP_1", 5)
7928 .Case(
"TRANS32_DEP_2", 6)
7929 .Case(
"TRANS32_DEP_3", 7)
7930 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7931 .Case(
"SALU_CYCLE_1", 9)
7932 .Case(
"SALU_CYCLE_2", 10)
7933 .Case(
"SALU_CYCLE_3", 11)
7941 Delay |=
Value << Shift;
7945ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7951 if (!parseDelay(Delay))
7959 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7964AMDGPUOperand::isSWaitCnt()
const {
7968bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7974void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7975 StringRef DepCtrName) {
7978 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7981 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7984 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7987 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7994bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7996 using namespace llvm::AMDGPU::DepCtr;
7998 SMLoc DepCtrLoc = getLoc();
7999 StringRef DepCtrName = getTokenStr();
8009 unsigned PrevOprMask = UsedOprMask;
8010 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8013 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8022 Error(getLoc(),
"expected a counter name");
8027 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
8028 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8032ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
8033 using namespace llvm::AMDGPU::DepCtr;
8036 SMLoc Loc = getLoc();
8039 unsigned UsedOprMask = 0;
8041 if (!parseDepCtr(DepCtr, UsedOprMask))
8049 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8053bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8059ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8061 OperandInfoTy &Width) {
8062 using namespace llvm::AMDGPU::Hwreg;
8068 HwReg.Loc = getLoc();
8071 HwReg.IsSymbolic =
true;
8073 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8081 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8091 Width.Loc = getLoc();
8099ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8100 using namespace llvm::AMDGPU::Hwreg;
8103 SMLoc Loc = getLoc();
8105 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8107 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8108 HwregOffset::Default);
8109 struct : StructuredOpField {
8110 using StructuredOpField::StructuredOpField;
8111 bool validate(AMDGPUAsmParser &Parser)
const override {
8113 return Error(Parser,
"only values from 1 to 32 are legal");
8116 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8117 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8120 Res = parseHwregFunc(HwReg,
Offset, Width);
8123 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8125 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8129 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8136 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8138 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8142bool AMDGPUOperand::isHwreg()
const {
8143 return isImmTy(ImmTyHwreg);
8151AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8153 OperandInfoTy &Stream) {
8154 using namespace llvm::AMDGPU::SendMsg;
8159 Msg.IsSymbolic =
true;
8161 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8166 Op.IsDefined =
true;
8169 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8172 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8177 Stream.IsDefined =
true;
8178 Stream.Loc = getLoc();
8188AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8189 const OperandInfoTy &
Op,
8190 const OperandInfoTy &Stream) {
8191 using namespace llvm::AMDGPU::SendMsg;
8196 bool Strict = Msg.IsSymbolic;
8200 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8205 Error(Msg.Loc,
"invalid message id");
8211 Error(
Op.Loc,
"message does not support operations");
8213 Error(Msg.Loc,
"missing message operation");
8219 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8221 Error(
Op.Loc,
"invalid operation id");
8226 Error(Stream.Loc,
"message operation does not support streams");
8230 Error(Stream.Loc,
"invalid message stream id");
8236ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8237 using namespace llvm::AMDGPU::SendMsg;
8240 SMLoc Loc = getLoc();
8244 OperandInfoTy
Op(OP_NONE_);
8245 OperandInfoTy Stream(STREAM_ID_NONE_);
8246 if (parseSendMsgBody(Msg,
Op, Stream) &&
8247 validateSendMsg(Msg,
Op, Stream)) {
8252 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8254 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8259 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8263bool AMDGPUOperand::isSendMsg()
const {
8264 return isImmTy(ImmTySendMsg);
8267ParseStatus AMDGPUAsmParser::parseWaitEvent(
OperandVector &Operands) {
8268 using namespace llvm::AMDGPU::WaitEvent;
8270 SMLoc Loc = getLoc();
8273 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8275 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8277 StructuredOpField *TargetBitfield =
8278 isGFX11() ? &DontWaitExportReady : &ExportReady;
8280 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8284 if (!validateStructuredOpFields({TargetBitfield}))
8286 ImmVal = TargetBitfield->Val;
8293 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8295 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8296 AMDGPUOperand::ImmTyWaitEvent));
8300bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8306ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8313 int Slot = StringSwitch<int>(Str)
8320 return Error(S,
"invalid interpolation slot");
8322 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8323 AMDGPUOperand::ImmTyInterpSlot));
8327ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8334 if (!Str.starts_with(
"attr"))
8335 return Error(S,
"invalid interpolation attribute");
8337 StringRef Chan = Str.take_back(2);
8338 int AttrChan = StringSwitch<int>(Chan)
8345 return Error(S,
"invalid or missing interpolation attribute channel");
8347 Str = Str.drop_back(2).drop_front(4);
8350 if (Str.getAsInteger(10, Attr))
8351 return Error(S,
"invalid or missing interpolation attribute number");
8354 return Error(S,
"out of bounds interpolation attribute number");
8358 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8359 AMDGPUOperand::ImmTyInterpAttr));
8360 Operands.
push_back(AMDGPUOperand::CreateImm(
8361 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8369ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8370 using namespace llvm::AMDGPU::Exp;
8380 return Error(S, (Id == ET_INVALID)
8381 ?
"invalid exp target"
8382 :
"exp target is not supported on this GPU");
8384 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8385 AMDGPUOperand::ImmTyExpTgt));
8394AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8399AMDGPUAsmParser::isId(
const StringRef Id)
const {
8405 return getTokenKind() ==
Kind;
8408StringRef AMDGPUAsmParser::getId()
const {
8413AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8422AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8424 StringRef Tok = getTokenStr();
8435 if (isId(Id) && peekToken().is(Kind)) {
8445 if (isToken(Kind)) {
8454 const StringRef ErrMsg) {
8455 if (!trySkipToken(Kind)) {
8456 Error(getLoc(), ErrMsg);
8463AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8467 if (Parser.parseExpression(Expr))
8470 if (Expr->evaluateAsAbsolute(
Imm))
8473 if (Expected.empty()) {
8474 Error(S,
"expected absolute expression");
8476 Error(S, Twine(
"expected ", Expected) +
8477 Twine(
" or an absolute expression"));
8487 if (Parser.parseExpression(Expr))
8491 if (Expr->evaluateAsAbsolute(IntVal)) {
8492 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8494 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8500AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8502 Val =
getToken().getStringContents();
8506 Error(getLoc(), ErrMsg);
8511AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8513 Val = getTokenStr();
8517 if (!ErrMsg.
empty())
8518 Error(getLoc(), ErrMsg);
8523AMDGPUAsmParser::getToken()
const {
8524 return Parser.getTok();
8527AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8530 : getLexer().peekTok(ShouldSkipSpace);
8535 auto TokCount = getLexer().peekTokens(Tokens);
8537 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8542AMDGPUAsmParser::getTokenKind()
const {
8543 return getLexer().getKind();
8547AMDGPUAsmParser::getLoc()
const {
8552AMDGPUAsmParser::getTokenStr()
const {
8557AMDGPUAsmParser::lex() {
8561SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8562 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8566SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8570SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8571 int MCOpIdx)
const {
8572 for (
const auto &
Op : Operands) {
8573 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8574 if (TargetOp.getMCOpIdx() == MCOpIdx)
8575 return TargetOp.getStartLoc();
8581AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8583 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8584 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8586 return Op.getStartLoc();
8588 return getInstLoc(Operands);
8592AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8594 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8595 return getOperandLoc(
Test, Operands);
8609 StringRef
Id = getTokenStr();
8610 SMLoc IdLoc = getLoc();
8616 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8617 if (
I == Fields.
end())
8618 return Error(IdLoc,
"unknown field");
8619 if ((*I)->IsDefined)
8620 return Error(IdLoc,
"duplicate field");
8623 (*I)->Loc = getLoc();
8626 (*I)->IsDefined =
true;
8633bool AMDGPUAsmParser::validateStructuredOpFields(
8635 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8636 return F->validate(*
this);
8647 const unsigned OrMask,
8648 const unsigned XorMask) {
8657bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8658 const unsigned MaxVal,
8659 const Twine &ErrMsg, SMLoc &Loc) {
8676AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8677 const unsigned MinVal,
8678 const unsigned MaxVal,
8679 const StringRef ErrMsg) {
8681 for (
unsigned i = 0; i < OpNum; ++i) {
8682 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8690AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8691 using namespace llvm::AMDGPU::Swizzle;
8694 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8695 "expected a 2-bit lane id")) {
8706AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8707 using namespace llvm::AMDGPU::Swizzle;
8713 if (!parseSwizzleOperand(GroupSize,
8715 "group size must be in the interval [2,32]",
8720 Error(Loc,
"group size must be a power of two");
8723 if (parseSwizzleOperand(LaneIdx,
8725 "lane id must be in the interval [0,group size - 1]",
8734AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8735 using namespace llvm::AMDGPU::Swizzle;
8740 if (!parseSwizzleOperand(GroupSize,
8742 "group size must be in the interval [2,32]",
8747 Error(Loc,
"group size must be a power of two");
8756AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8757 using namespace llvm::AMDGPU::Swizzle;
8762 if (!parseSwizzleOperand(GroupSize,
8764 "group size must be in the interval [1,16]",
8769 Error(Loc,
"group size must be a power of two");
8778AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8779 using namespace llvm::AMDGPU::Swizzle;
8786 SMLoc StrLoc = getLoc();
8787 if (!parseString(Ctl)) {
8790 if (Ctl.
size() != BITMASK_WIDTH) {
8791 Error(StrLoc,
"expected a 5-character mask");
8795 unsigned AndMask = 0;
8796 unsigned OrMask = 0;
8797 unsigned XorMask = 0;
8799 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8803 Error(StrLoc,
"invalid mask");
8824bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8825 using namespace llvm::AMDGPU::Swizzle;
8828 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8834 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8835 "FFT swizzle must be in the interval [0," +
8836 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8844bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8845 using namespace llvm::AMDGPU::Swizzle;
8848 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8855 if (!parseSwizzleOperand(
Direction, 0, 1,
8856 "direction must be 0 (left) or 1 (right)", Loc))
8860 if (!parseSwizzleOperand(
8861 RotateSize, 0, ROTATE_MAX_SIZE,
8862 "number of threads to rotate must be in the interval [0," +
8863 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8868 (RotateSize << ROTATE_SIZE_SHIFT);
8873AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8875 SMLoc OffsetLoc = getLoc();
8881 Error(OffsetLoc,
"expected a 16-bit offset");
8888AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8889 using namespace llvm::AMDGPU::Swizzle;
8893 SMLoc ModeLoc = getLoc();
8896 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8897 Ok = parseSwizzleQuadPerm(
Imm);
8898 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8899 Ok = parseSwizzleBitmaskPerm(
Imm);
8900 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8901 Ok = parseSwizzleBroadcast(
Imm);
8902 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8903 Ok = parseSwizzleSwap(
Imm);
8904 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8905 Ok = parseSwizzleReverse(
Imm);
8906 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8907 Ok = parseSwizzleFFT(
Imm);
8908 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8909 Ok = parseSwizzleRotate(
Imm);
8911 Error(ModeLoc,
"expected a swizzle mode");
8914 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8920ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8924 if (trySkipId(
"offset")) {
8928 if (trySkipId(
"swizzle")) {
8929 Ok = parseSwizzleMacro(
Imm);
8931 Ok = parseSwizzleOffset(
Imm);
8935 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8943AMDGPUOperand::isSwizzle()
const {
8944 return isImmTy(ImmTySwizzle);
8951int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8953 using namespace llvm::AMDGPU::VGPRIndexMode;
8965 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8966 if (trySkipId(IdSymbolic[ModeId])) {
8974 "expected a VGPR index mode or a closing parenthesis" :
8975 "expected a VGPR index mode");
8980 Error(S,
"duplicate VGPR index mode");
8988 "expected a comma or a closing parenthesis"))
8995ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8997 using namespace llvm::AMDGPU::VGPRIndexMode;
9003 Imm = parseGPRIdxMacro();
9007 if (getParser().parseAbsoluteExpression(
Imm))
9010 return Error(S,
"invalid immediate: only 4-bit values are legal");
9014 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9018bool AMDGPUOperand::isGPRIdxMode()
const {
9019 return isImmTy(ImmTyGprIdxMode);
9026ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
9031 if (isRegister() || isModifier())
9037 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
9038 assert(Opr.isImm() || Opr.isExpr());
9039 SMLoc Loc = Opr.getStartLoc();
9043 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9044 Error(Loc,
"expected an absolute expression or a label");
9045 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9046 Error(Loc,
"expected a 16-bit signed jump offset");
9056ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
9057 return parseReg(Operands);
9064void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
9067 OptionalImmIndexMap OptionalIdx;
9068 unsigned FirstOperandIdx = 1;
9069 bool IsAtomicReturn =
false;
9076 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9077 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9081 Op.addRegOperands(Inst, 1);
9085 if (IsAtomicReturn && i == FirstOperandIdx)
9086 Op.addRegOperands(Inst, 1);
9091 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9092 Op.addImmOperands(Inst, 1);
9104 OptionalIdx[
Op.getImmTy()] = i;
9118bool AMDGPUOperand::isSMRDOffset8()
const {
9122bool AMDGPUOperand::isSMEMOffset()
const {
9124 return isImmLiteral();
9127bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9162bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9163 if (BoundCtrl == 0 || BoundCtrl == 1) {
9171void AMDGPUAsmParser::onBeginOfFile() {
9172 if (!getParser().getStreamer().getTargetStreamer() ||
9176 if (!getTargetStreamer().getTargetID())
9177 getTargetStreamer().initializeTargetID(getSTI(),
9178 getSTI().getFeatureString());
9181 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9189bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9193 StringRef TokenId = getTokenStr();
9194 AGVK VK = StringSwitch<AGVK>(TokenId)
9195 .Case(
"max", AGVK::AGVK_Max)
9196 .Case(
"or", AGVK::AGVK_Or)
9197 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9198 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9199 .Case(
"alignto", AGVK::AGVK_AlignTo)
9200 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9201 .Default(AGVK::AGVK_None);
9205 uint64_t CommaCount = 0;
9210 if (Exprs.
empty()) {
9212 "empty " + Twine(TokenId) +
" expression");
9215 if (CommaCount + 1 != Exprs.
size()) {
9217 "mismatch of commas in " + Twine(TokenId) +
" expression");
9224 if (getParser().parseExpression(Expr, EndLoc))
9228 if (LastTokenWasComma)
9232 "unexpected token in " + Twine(TokenId) +
" expression");
9238 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9241ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9242 StringRef
Name = getTokenStr();
9243 if (Name ==
"mul") {
9244 return parseIntWithPrefix(
"mul", Operands,
9248 if (Name ==
"div") {
9249 return parseIntWithPrefix(
"div", Operands,
9260 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9265 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9266 AMDGPU::OpName::src2};
9274 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9279 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9281 if (
DstOp.isReg() &&
9282 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9286 if ((OpSel & (1 << SrcNum)) != 0)
9292void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9294 cvtVOP3P(Inst, Operands);
9298void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9299 OptionalImmIndexMap &OptionalIdx) {
9300 cvtVOP3P(Inst, Operands, OptionalIdx);
9309 &&
Desc.NumOperands > (OpNum + 1)
9311 &&
Desc.operands()[OpNum + 1].RegClass != -1
9313 &&
Desc.getOperandConstraint(OpNum + 1,
9317void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9319 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9320 AMDGPU::OpName::src2};
9321 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9322 AMDGPU::OpName::src1_modifiers,
9323 AMDGPU::OpName::src2_modifiers};
9324 for (
int J = 0; J < 3; ++J) {
9325 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9331 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9334 if ((OpSel & (1 << J)) != 0)
9337 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9344void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9346 OptionalImmIndexMap OptionalIdx;
9351 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9352 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9355 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9356 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9358 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9359 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9360 Op.isInterpAttrChan()) {
9362 }
else if (
Op.isImmModifier()) {
9363 OptionalIdx[
Op.getImmTy()] =
I;
9371 AMDGPUOperand::ImmTyHigh);
9375 AMDGPUOperand::ImmTyClamp);
9379 AMDGPUOperand::ImmTyOModSI);
9384 AMDGPUOperand::ImmTyOpSel);
9385 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9388 cvtOpSelHelper(Inst, OpSel);
9392void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9394 OptionalImmIndexMap OptionalIdx;
9399 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9400 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9403 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9404 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9406 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9407 }
else if (
Op.isImmModifier()) {
9408 OptionalIdx[
Op.getImmTy()] =
I;
9416 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9426 cvtOpSelHelper(Inst, OpSel);
9429void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9431 OptionalImmIndexMap OptionalIdx;
9434 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9438 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9439 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9441 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9442 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9447 if (NumOperands == CbszOpIdx) {
9452 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9453 }
else if (
Op.isImmModifier()) {
9454 OptionalIdx[
Op.getImmTy()] =
I;
9456 Op.addRegOrImmOperands(Inst, 1);
9461 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9462 if (CbszIdx != OptionalIdx.end()) {
9463 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9467 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9468 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9469 if (BlgpIdx != OptionalIdx.end()) {
9470 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9481 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9482 if (OpselIdx != OptionalIdx.end()) {
9483 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9487 unsigned OpSelHi = 0;
9488 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9489 if (OpselHiIdx != OptionalIdx.end()) {
9490 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9493 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9494 AMDGPU::OpName::src1_modifiers};
9496 for (
unsigned J = 0; J < 2; ++J) {
9497 unsigned ModVal = 0;
9498 if (OpSel & (1 << J))
9500 if (OpSelHi & (1 << J))
9503 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9508void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9509 OptionalImmIndexMap &OptionalIdx) {
9514 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9515 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9518 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9519 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9521 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9522 }
else if (
Op.isImmModifier()) {
9523 OptionalIdx[
Op.getImmTy()] =
I;
9525 Op.addRegOrImmOperands(Inst, 1);
9531 AMDGPUOperand::ImmTyScaleSel);
9535 AMDGPUOperand::ImmTyClamp);
9541 AMDGPUOperand::ImmTyByteSel);
9546 AMDGPUOperand::ImmTyOModSI);
9553 auto *it = Inst.
begin();
9554 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9562void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9563 OptionalImmIndexMap OptionalIdx;
9564 cvtVOP3(Inst, Operands, OptionalIdx);
9567void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9568 OptionalImmIndexMap &OptIdx) {
9574 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9575 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9576 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9577 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9578 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9579 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9580 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9581 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9589 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx11 ||
9590 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx11 ||
9591 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx11 ||
9592 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx11 ||
9593 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx11 ||
9594 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx11 ||
9595 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx11 ||
9596 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx11 ||
9597 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx11 ||
9598 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx11 ||
9599 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx11 ||
9600 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx11 ||
9601 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9602 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9603 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9604 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9605 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9606 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9607 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9608 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9609 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9610 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9611 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9612 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9613 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9614 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9615 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9616 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9617 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9618 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9619 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9620 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9621 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9622 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9623 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9624 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9625 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9626 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9630 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9631 if (BitOp3Idx != -1) {
9638 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9639 if (OpSelIdx != -1) {
9643 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9644 if (OpSelHiIdx != -1) {
9651 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9652 if (MatrixAFMTIdx != -1) {
9654 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9658 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9659 if (MatrixBFMTIdx != -1) {
9661 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9664 int MatrixAScaleIdx =
9665 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9666 if (MatrixAScaleIdx != -1) {
9668 AMDGPUOperand::ImmTyMatrixAScale, 0);
9671 int MatrixBScaleIdx =
9672 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9673 if (MatrixBScaleIdx != -1) {
9675 AMDGPUOperand::ImmTyMatrixBScale, 0);
9678 int MatrixAScaleFmtIdx =
9679 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9680 if (MatrixAScaleFmtIdx != -1) {
9682 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9685 int MatrixBScaleFmtIdx =
9686 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9687 if (MatrixBScaleFmtIdx != -1) {
9689 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9694 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9698 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9700 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9704 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9708 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9709 AMDGPU::OpName::src2};
9710 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9711 AMDGPU::OpName::src1_modifiers,
9712 AMDGPU::OpName::src2_modifiers};
9715 unsigned OpSelHi = 0;
9722 if (OpSelHiIdx != -1)
9731 for (
int J = 0; J < 3; ++J) {
9732 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9736 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9741 uint32_t ModVal = 0;
9744 if (SrcOp.
isReg() && getMRI()
9751 if ((OpSel & (1 << J)) != 0)
9755 if ((OpSelHi & (1 << J)) != 0)
9758 if ((NegLo & (1 << J)) != 0)
9761 if ((NegHi & (1 << J)) != 0)
9768void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9769 OptionalImmIndexMap OptIdx;
9770 cvtVOP3(Inst, Operands, OptIdx);
9771 cvtVOP3P(Inst, Operands, OptIdx);
9775 unsigned i,
unsigned Opc,
9777 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9778 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9780 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9783void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9786 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9789 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9790 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9792 OptionalImmIndexMap OptIdx;
9793 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9794 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9795 OptIdx[
Op.getImmTy()] = i;
9800 AMDGPUOperand::ImmTyIndexKey8bit);
9804 AMDGPUOperand::ImmTyIndexKey16bit);
9808 AMDGPUOperand::ImmTyIndexKey32bit);
9813 cvtVOP3P(Inst, Operands, OptIdx);
9820ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9828 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9829 SMLoc OpYLoc = getLoc();
9832 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9835 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9841void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9844 auto addOp = [&](uint16_t ParsedOprIdx) {
9845 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9847 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9851 Op.addRegOperands(Inst, 1);
9855 Op.addImmOperands(Inst, 1);
9867 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9871 const auto &CInfo = InstInfo[CompIdx];
9872 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9873 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9874 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9875 if (CInfo.hasSrc2Acc())
9876 addOp(CInfo.getIndexOfDstInParsedOperands());
9880 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9881 if (BitOp3Idx != -1) {
9882 OptionalImmIndexMap OptIdx;
9883 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9885 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9895bool AMDGPUOperand::isDPP8()
const {
9896 return isImmTy(ImmTyDPP8);
9899bool AMDGPUOperand::isDPPCtrl()
const {
9900 using namespace AMDGPU::DPP;
9902 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9905 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9906 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9907 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9908 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9909 (
Imm == DppCtrl::WAVE_SHL1) ||
9910 (
Imm == DppCtrl::WAVE_ROL1) ||
9911 (
Imm == DppCtrl::WAVE_SHR1) ||
9912 (
Imm == DppCtrl::WAVE_ROR1) ||
9913 (
Imm == DppCtrl::ROW_MIRROR) ||
9914 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9915 (
Imm == DppCtrl::BCAST15) ||
9916 (
Imm == DppCtrl::BCAST31) ||
9917 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9918 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9927bool AMDGPUOperand::isBLGP()
const {
9931bool AMDGPUOperand::isS16Imm()
const {
9935bool AMDGPUOperand::isU16Imm()
const {
9943bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9948 SMLoc Loc =
getToken().getEndLoc();
9949 Token = std::string(getTokenStr());
9951 if (getLoc() != Loc)
9956 if (!parseId(Suffix))
9960 StringRef DimId = Token;
9971ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9981 SMLoc Loc = getLoc();
9982 if (!parseDimId(Encoding))
9983 return Error(Loc,
"invalid dim value");
9985 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9986 AMDGPUOperand::ImmTyDim));
9994ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
10004 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10007 for (
size_t i = 0; i < 8; ++i) {
10011 SMLoc Loc = getLoc();
10012 if (getParser().parseAbsoluteExpression(Sels[i]))
10014 if (0 > Sels[i] || 7 < Sels[i])
10015 return Error(Loc,
"expected a 3-bit value");
10018 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10022 for (
size_t i = 0; i < 8; ++i)
10023 DPP8 |= (Sels[i] << (i * 3));
10025 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10030AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10032 if (Ctrl ==
"row_newbcast")
10035 if (Ctrl ==
"row_share" ||
10036 Ctrl ==
"row_xmask")
10039 if (Ctrl ==
"wave_shl" ||
10040 Ctrl ==
"wave_shr" ||
10041 Ctrl ==
"wave_rol" ||
10042 Ctrl ==
"wave_ror" ||
10043 Ctrl ==
"row_bcast")
10046 return Ctrl ==
"row_mirror" ||
10047 Ctrl ==
"row_half_mirror" ||
10048 Ctrl ==
"quad_perm" ||
10049 Ctrl ==
"row_shl" ||
10050 Ctrl ==
"row_shr" ||
10055AMDGPUAsmParser::parseDPPCtrlPerm() {
10058 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10062 for (
int i = 0; i < 4; ++i) {
10067 SMLoc Loc = getLoc();
10068 if (getParser().parseAbsoluteExpression(Temp))
10070 if (Temp < 0 || Temp > 3) {
10071 Error(Loc,
"expected a 2-bit value");
10075 Val += (Temp << i * 2);
10078 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10085AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10086 using namespace AMDGPU::DPP;
10091 SMLoc Loc = getLoc();
10093 if (getParser().parseAbsoluteExpression(Val))
10096 struct DppCtrlCheck {
10102 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10103 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10104 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10105 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10106 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10107 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10108 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10109 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10110 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10111 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10112 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10116 if (
Check.Ctrl == -1) {
10117 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10125 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10132ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10133 using namespace AMDGPU::DPP;
10136 !isSupportedDPPCtrl(getTokenStr(), Operands))
10139 SMLoc S = getLoc();
10145 if (Ctrl ==
"row_mirror") {
10146 Val = DppCtrl::ROW_MIRROR;
10147 }
else if (Ctrl ==
"row_half_mirror") {
10148 Val = DppCtrl::ROW_HALF_MIRROR;
10151 if (Ctrl ==
"quad_perm") {
10152 Val = parseDPPCtrlPerm();
10154 Val = parseDPPCtrlSel(Ctrl);
10163 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10167void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10169 OptionalImmIndexMap OptionalIdx;
10176 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10178 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10179 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10183 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10184 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10188 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10189 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10190 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10191 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10192 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10194 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10198 if (OldIdx == NumOperands) {
10200 constexpr int DST_IDX = 0;
10202 }
else if (Src2ModIdx == NumOperands) {
10212 if (IsVOP3CvtSrDpp) {
10221 if (TiedTo != -1) {
10226 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10228 if (IsDPP8 &&
Op.isDppFI()) {
10231 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10232 }
else if (
Op.isReg()) {
10233 Op.addRegOperands(Inst, 1);
10234 }
else if (
Op.isImm() &&
10236 Op.addImmOperands(Inst, 1);
10237 }
else if (
Op.isImm()) {
10238 OptionalIdx[
Op.getImmTy()] =
I;
10246 AMDGPUOperand::ImmTyClamp);
10252 AMDGPUOperand::ImmTyByteSel);
10259 cvtVOP3P(Inst, Operands, OptionalIdx);
10261 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10268 using namespace llvm::AMDGPU::DPP;
10278 AMDGPUOperand::ImmTyDppFI);
10282void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10283 OptionalImmIndexMap OptionalIdx;
10287 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10288 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10292 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10295 if (TiedTo != -1) {
10300 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10302 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10310 Op.addImmOperands(Inst, 1);
10312 Op.addRegWithFPInputModsOperands(Inst, 2);
10313 }
else if (
Op.isDppFI()) {
10315 }
else if (
Op.isReg()) {
10316 Op.addRegOperands(Inst, 1);
10322 Op.addRegWithFPInputModsOperands(Inst, 2);
10323 }
else if (
Op.isReg()) {
10324 Op.addRegOperands(Inst, 1);
10325 }
else if (
Op.isDPPCtrl()) {
10326 Op.addImmOperands(Inst, 1);
10327 }
else if (
Op.isImm()) {
10329 OptionalIdx[
Op.getImmTy()] =
I;
10337 using namespace llvm::AMDGPU::DPP;
10345 AMDGPUOperand::ImmTyDppFI);
10354ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10356 AMDGPUOperand::ImmTy
Type) {
10357 return parseStringOrIntWithPrefix(
10359 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10363ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10364 return parseStringOrIntWithPrefix(
10365 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10366 AMDGPUOperand::ImmTySDWADstUnused);
10369void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10373void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10377void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10381void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10385void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10389void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10390 uint64_t BasicInstType,
10393 using namespace llvm::AMDGPU::SDWA;
10395 OptionalImmIndexMap OptionalIdx;
10396 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10397 bool SkippedVcc =
false;
10401 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10402 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10405 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10406 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10407 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10408 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10426 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10427 }
else if (
Op.isImm()) {
10429 OptionalIdx[
Op.getImmTy()] =
I;
10433 SkippedVcc =
false;
10437 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10438 Opc != AMDGPU::V_NOP_sdwa_vi) {
10440 switch (BasicInstType) {
10444 AMDGPUOperand::ImmTyClamp, 0);
10448 AMDGPUOperand::ImmTyOModSI, 0);
10452 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10456 AMDGPUOperand::ImmTySDWADstUnused,
10457 DstUnused::UNUSED_PRESERVE);
10459 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10464 AMDGPUOperand::ImmTyClamp, 0);
10469 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10470 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10471 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10472 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10478 AMDGPUOperand::ImmTyClamp, 0);
10479 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10480 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10484 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10490 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10491 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10492 auto *it = Inst.
begin();
10494 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10506#define GET_MATCHER_IMPLEMENTATION
10507#define GET_MNEMONIC_SPELL_CHECKER
10508#define GET_MNEMONIC_CHECKER
10509#include "AMDGPUGenAsmMatcher.inc"
10515 return parseTokenOp(
"addr64",
Operands);
10517 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10519 return parseTokenOp(
"idxen",
Operands);
10521 return parseTokenOp(
"lds",
Operands);
10523 return parseTokenOp(
"offen",
Operands);
10525 return parseTokenOp(
"off",
Operands);
10526 case MCK_row_95_en:
10527 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10529 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10531 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10533 return tryCustomParseOperand(
Operands, MCK);
10538unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10544 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10547 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10549 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10551 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10553 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10555 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10557 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10559 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10560 case MCK_row_95_en:
10561 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10569 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10571 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10572 case MCK_SOPPBrTarget:
10573 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10574 case MCK_VReg32OrOff:
10575 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10576 case MCK_InterpSlot:
10577 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10578 case MCK_InterpAttr:
10579 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10580 case MCK_InterpAttrChan:
10581 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10583 case MCK_SReg_64_XEXEC:
10593 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10595 return Match_InvalidOperand;
10603ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10604 SMLoc S = getLoc();
10613 return Error(S,
"expected a 16-bit value");
10616 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10620bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10626bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, AMDGPU::OpName OpName)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static int IsAGPROperand(const MCInst &Inst, AMDGPU::OpName Name, const MCRegisterInfo *MRI)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
constexpr uint64_t MIMGFlags
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static bool IsRevOpcode(const unsigned Opcode)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static MCRegister getSpecialRegForName(StringRef RegName)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0, std::optional< unsigned > InsertAt=std::nullopt)
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Loop::LoopBounds::Direction Direction
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.
unsigned unsigned DefaultVal
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * 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)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - 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...
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...
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool 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 isGFX1170(const MCSubtargetInfo &STI)
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 bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ Default
The result values are 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