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);
1577 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1579 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1581 bool hasInv2PiInlineImm()
const {
1582 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1585 bool has64BitLiterals()
const {
1586 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1589 bool hasFlatOffsets()
const {
1590 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1593 bool hasTrue16Insts()
const {
1594 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1598 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1601 bool hasSGPR102_SGPR103()
const {
1605 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1607 bool hasIntClamp()
const {
1608 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1611 bool hasPartialNSAEncoding()
const {
1612 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1615 bool hasGloballyAddressableScratch()
const {
1616 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1629 AMDGPUTargetStreamer &getTargetStreamer() {
1630 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1631 return static_cast<AMDGPUTargetStreamer &
>(TS);
1637 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1640 const MCRegisterInfo *getMRI()
const {
1644 const MCInstrInfo *getMII()
const {
1650 const FeatureBitset &getFeatureBits()
const {
1651 return getSTI().getFeatureBits();
1654 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1655 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1656 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1658 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1659 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1660 bool isForcedDPP()
const {
return ForcedDPP; }
1661 bool isForcedSDWA()
const {
return ForcedSDWA; }
1662 ArrayRef<unsigned> getMatchedVariants()
const;
1663 StringRef getMatchedVariantName()
const;
1665 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1666 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1667 bool RestoreOnFailure);
1668 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1669 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1670 SMLoc &EndLoc)
override;
1671 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1672 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1673 unsigned Kind)
override;
1674 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1676 uint64_t &ErrorInfo,
1677 bool MatchingInlineAsm)
override;
1678 bool ParseDirective(AsmToken DirectiveID)
override;
1679 ParseStatus parseOperand(
OperandVector &Operands, StringRef Mnemonic,
1680 OperandMode
Mode = OperandMode_Default);
1681 StringRef parseMnemonicSuffix(StringRef Name);
1682 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1686 ParseStatus parseTokenOp(StringRef Name,
OperandVector &Operands);
1688 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1691 parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1692 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1693 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1695 ParseStatus parseOperandArrayWithPrefix(
1697 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1698 bool (*ConvertResult)(int64_t &) =
nullptr);
1702 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1703 bool IgnoreNegative =
false);
1704 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1706 ParseStatus parseScope(
OperandVector &Operands, int64_t &Scope);
1708 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1710 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1712 ArrayRef<const char *> Ids,
1714 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1716 ArrayRef<const char *> Ids,
1717 AMDGPUOperand::ImmTy
Type);
1720 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1721 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1722 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1723 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1724 bool parseSP3NegModifier();
1725 ParseStatus parseImm(
OperandVector &Operands,
bool HasSP3AbsModifier =
false,
1728 ParseStatus parseRegOrImm(
OperandVector &Operands,
bool HasSP3AbsMod =
false,
1730 ParseStatus parseRegOrImmWithFPInputMods(
OperandVector &Operands,
1731 bool AllowImm =
true);
1732 ParseStatus parseRegOrImmWithIntInputMods(
OperandVector &Operands,
1733 bool AllowImm =
true);
1734 ParseStatus parseRegWithFPInputMods(
OperandVector &Operands);
1735 ParseStatus parseRegWithIntInputMods(
OperandVector &Operands);
1738 AMDGPUOperand::ImmTy ImmTy);
1742 ParseStatus tryParseMatrixFMT(
OperandVector &Operands, StringRef Name,
1743 AMDGPUOperand::ImmTy
Type);
1746 ParseStatus tryParseMatrixScale(
OperandVector &Operands, StringRef Name,
1747 AMDGPUOperand::ImmTy
Type);
1750 ParseStatus tryParseMatrixScaleFmt(
OperandVector &Operands, StringRef Name,
1751 AMDGPUOperand::ImmTy
Type);
1755 ParseStatus parseDfmtNfmt(int64_t &
Format);
1756 ParseStatus parseUfmt(int64_t &
Format);
1757 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1759 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1762 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1763 ParseStatus parseNumericFormat(int64_t &
Format);
1767 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1768 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1772 bool parseCnt(int64_t &IntVal);
1775 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1776 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1779 bool parseDelay(int64_t &Delay);
1785 struct OperandInfoTy {
1788 bool IsSymbolic =
false;
1789 bool IsDefined =
false;
1791 constexpr OperandInfoTy(int64_t Val) : Val(Val) {}
1794 struct StructuredOpField : OperandInfoTy {
1798 bool IsDefined =
false;
1800 constexpr StructuredOpField(StringLiteral Id, StringLiteral Desc,
1801 unsigned Width, int64_t
Default)
1802 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1803 virtual ~StructuredOpField() =
default;
1805 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1806 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1810 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1812 return Error(Parser,
"not supported on this GPU");
1814 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1822 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1823 bool validateSendMsg(
const OperandInfoTy &Msg,
1824 const OperandInfoTy &
Op,
1825 const OperandInfoTy &Stream);
1827 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1828 OperandInfoTy &Width);
1830 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1832 SMLoc getFlatOffsetLoc(
const OperandVector &Operands)
const;
1833 SMLoc getSMEMOffsetLoc(
const OperandVector &Operands)
const;
1836 SMLoc getOperandLoc(
const OperandVector &Operands,
int MCOpIdx)
const;
1837 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1839 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1843 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1845 bool validateOffset(
const MCInst &Inst,
const OperandVector &Operands);
1846 bool validateFlatOffset(
const MCInst &Inst,
const OperandVector &Operands);
1847 bool validateSMEMOffset(
const MCInst &Inst,
const OperandVector &Operands);
1848 bool validateSOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1849 bool validateConstantBusLimitations(
const MCInst &Inst,
const OperandVector &Operands);
1850 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1852 bool validateVOPD(
const MCInst &Inst,
const OperandVector &Operands);
1853 bool tryVOPD(
const MCInst &Inst);
1854 bool tryVOPD3(
const MCInst &Inst);
1855 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1857 bool validateIntClampSupported(
const MCInst &Inst);
1858 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1859 bool validateMIMGGatherDMask(
const MCInst &Inst);
1860 bool validateMovrels(
const MCInst &Inst,
const OperandVector &Operands);
1861 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1862 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1863 bool validateMIMGD16(
const MCInst &Inst);
1864 bool validateMIMGDim(
const MCInst &Inst,
const OperandVector &Operands);
1865 bool validateTensorR128(
const MCInst &Inst);
1866 bool validateMIMGMSAA(
const MCInst &Inst);
1867 bool validateOpSel(
const MCInst &Inst);
1868 bool validateTrue16OpSel(
const MCInst &Inst);
1869 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1870 bool validateDPP(
const MCInst &Inst,
const OperandVector &Operands);
1871 bool validateVccOperand(MCRegister
Reg)
const;
1872 bool validateVOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1873 bool validateMAIAccWrite(
const MCInst &Inst,
const OperandVector &Operands);
1874 bool validateMAISrc2(
const MCInst &Inst,
const OperandVector &Operands);
1875 bool validateMFMA(
const MCInst &Inst,
const OperandVector &Operands);
1876 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1877 bool validateVGPRAlign(
const MCInst &Inst)
const;
1878 bool validateBLGP(
const MCInst &Inst,
const OperandVector &Operands);
1879 bool validateDS(
const MCInst &Inst,
const OperandVector &Operands);
1880 bool validateGWS(
const MCInst &Inst,
const OperandVector &Operands);
1881 bool validateDivScale(
const MCInst &Inst);
1882 bool validateWaitCnt(
const MCInst &Inst,
const OperandVector &Operands);
1883 bool validateCoherencyBits(
const MCInst &Inst,
const OperandVector &Operands,
1885 bool validateTHAndScopeBits(
const MCInst &Inst,
const OperandVector &Operands,
1886 const unsigned CPol);
1887 bool validateTFE(
const MCInst &Inst,
const OperandVector &Operands);
1888 bool validateLdsDirect(
const MCInst &Inst,
const OperandVector &Operands);
1889 bool validateWMMA(
const MCInst &Inst,
const OperandVector &Operands);
1890 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1891 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1892 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1893 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1895 bool isSupportedMnemo(StringRef Mnemo,
1896 const FeatureBitset &FBS);
1897 bool isSupportedMnemo(StringRef Mnemo,
1898 const FeatureBitset &FBS,
1899 ArrayRef<unsigned> Variants);
1900 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1902 bool isId(
const StringRef Id)
const;
1903 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1905 StringRef getId()
const;
1906 bool trySkipId(
const StringRef Id);
1907 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1911 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1912 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1918 StringRef getTokenStr()
const;
1919 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1921 SMLoc getLoc()
const;
1925 void onBeginOfFile()
override;
1926 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1928 ParseStatus parseCustomOperand(
OperandVector &Operands,
unsigned MCK);
1938 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1939 const unsigned MaxVal,
const Twine &ErrMsg,
1941 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1942 const unsigned MinVal,
1943 const unsigned MaxVal,
1944 const StringRef ErrMsg);
1946 bool parseSwizzleOffset(int64_t &
Imm);
1947 bool parseSwizzleMacro(int64_t &
Imm);
1948 bool parseSwizzleQuadPerm(int64_t &
Imm);
1949 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1950 bool parseSwizzleBroadcast(int64_t &
Imm);
1951 bool parseSwizzleSwap(int64_t &
Imm);
1952 bool parseSwizzleReverse(int64_t &
Imm);
1953 bool parseSwizzleFFT(int64_t &
Imm);
1954 bool parseSwizzleRotate(int64_t &
Imm);
1957 int64_t parseGPRIdxMacro();
1959 void cvtMubuf(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
false); }
1960 void cvtMubufAtomic(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
true); }
1965 OptionalImmIndexMap &OptionalIdx);
1966 void cvtScaledMFMA(MCInst &Inst,
const OperandVector &Operands);
1967 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands);
1970 void cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands);
1973 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
1974 OptionalImmIndexMap &OptionalIdx);
1976 OptionalImmIndexMap &OptionalIdx);
1978 void cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands);
1979 void cvtVINTERP(MCInst &Inst,
const OperandVector &Operands);
1980 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1982 bool parseDimId(
unsigned &Encoding);
1984 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1987 bool isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands);
1988 int64_t parseDPPCtrlSel(StringRef Ctrl);
1989 int64_t parseDPPCtrlPerm();
1990 void cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8 =
false);
1992 cvtDPP(Inst, Operands,
true);
1994 void cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
1995 bool IsDPP8 =
false);
1996 void cvtVOP3DPP8(MCInst &Inst,
const OperandVector &Operands) {
1997 cvtVOP3DPP(Inst, Operands,
true);
2000 ParseStatus parseSDWASel(
OperandVector &Operands, StringRef Prefix,
2001 AMDGPUOperand::ImmTy
Type);
2003 void cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands);
2004 void cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands);
2005 void cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands);
2006 void cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands);
2007 void cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands);
2009 uint64_t BasicInstType,
2010 bool SkipDstVcc =
false,
2011 bool SkipSrcVcc =
false);
2120bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2130 if (!isImmTy(ImmTyNone)) {
2135 if (getModifiers().
Lit != LitModifier::None)
2145 if (type == MVT::f64 || type == MVT::i64) {
2147 AsmParser->hasInv2PiInlineImm());
2150 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2169 APFloat::rmNearestTiesToEven, &Lost);
2176 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2178 AsmParser->hasInv2PiInlineImm());
2183 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2184 AsmParser->hasInv2PiInlineImm());
2188 if (type == MVT::f64 || type == MVT::i64) {
2190 AsmParser->hasInv2PiInlineImm());
2199 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2200 type, AsmParser->hasInv2PiInlineImm());
2204 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2205 AsmParser->hasInv2PiInlineImm());
2208bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2210 if (!isImmTy(ImmTyNone)) {
2215 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2220 if (type == MVT::f64 && hasFPModifiers()) {
2240 if (type == MVT::f64) {
2245 if (type == MVT::i64) {
2258 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2259 : (type == MVT::v2i16) ? MVT::f32
2260 : (type == MVT::v2f32) ? MVT::f32
2263 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2267bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2268 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2271bool AMDGPUOperand::isVRegWithInputMods()
const {
2272 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2274 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2275 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2278template <
bool IsFake16>
2279bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2280 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2281 : AMDGPU::VGPR_16_Lo128RegClassID);
2284template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2285 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2286 : AMDGPU::VGPR_16RegClassID);
2289bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2290 if (AsmParser->isVI())
2292 if (AsmParser->isGFX9Plus())
2293 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2297bool AMDGPUOperand::isSDWAFP16Operand()
const {
2298 return isSDWAOperand(MVT::f16);
2301bool AMDGPUOperand::isSDWAFP32Operand()
const {
2302 return isSDWAOperand(MVT::f32);
2305bool AMDGPUOperand::isSDWAInt16Operand()
const {
2306 return isSDWAOperand(MVT::i16);
2309bool AMDGPUOperand::isSDWAInt32Operand()
const {
2310 return isSDWAOperand(MVT::i32);
2313bool AMDGPUOperand::isBoolReg()
const {
2314 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2315 (AsmParser->isWave32() && isSCSrc_b32()));
2318uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2320 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2323 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2335void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2345 addLiteralImmOperand(Inst,
Imm.Val,
2347 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2349 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2354void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2355 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2360 if (ApplyModifiers) {
2363 Val = applyInputFPModifiers(Val,
Size);
2367 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2369 bool CanUse64BitLiterals =
2370 AsmParser->has64BitLiterals() &&
2373 MCContext &Ctx = AsmParser->getContext();
2382 if (
Lit == LitModifier::None &&
2384 AsmParser->hasInv2PiInlineImm())) {
2392 bool HasMandatoryLiteral =
2395 if (
Literal.getLoBits(32) != 0 &&
2396 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2397 !HasMandatoryLiteral) {
2398 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2400 "Can't encode literal as exact 64-bit floating-point operand. "
2401 "Low 32-bits will be set to zero");
2402 Val &= 0xffffffff00000000u;
2408 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2414 Lit = LitModifier::Lit64;
2415 }
else if (
Lit == LitModifier::Lit) {
2429 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2431 Lit = LitModifier::Lit64;
2438 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2439 Literal == 0x3fc45f306725feed) {
2474 APFloat::rmNearestTiesToEven, &lost);
2478 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2485 if (
Lit != LitModifier::None) {
2515 if (
Lit == LitModifier::None &&
2525 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2532 if (
Lit == LitModifier::None &&
2540 if (!AsmParser->has64BitLiterals()) {
2541 Val =
static_cast<uint64_t
>(Val) << 32;
2548 if (
Lit == LitModifier::Lit ||
2550 Val =
static_cast<uint64_t
>(Val) << 32;
2554 if (
Lit == LitModifier::Lit)
2580 if (
Lit != LitModifier::None) {
2588void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2593bool AMDGPUOperand::isInlineValue()
const {
2601void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2612 if (Is == IS_VGPR) {
2616 return AMDGPU::VGPR_32RegClassID;
2618 return AMDGPU::VReg_64RegClassID;
2620 return AMDGPU::VReg_96RegClassID;
2622 return AMDGPU::VReg_128RegClassID;
2624 return AMDGPU::VReg_160RegClassID;
2626 return AMDGPU::VReg_192RegClassID;
2628 return AMDGPU::VReg_224RegClassID;
2630 return AMDGPU::VReg_256RegClassID;
2632 return AMDGPU::VReg_288RegClassID;
2634 return AMDGPU::VReg_320RegClassID;
2636 return AMDGPU::VReg_352RegClassID;
2638 return AMDGPU::VReg_384RegClassID;
2640 return AMDGPU::VReg_512RegClassID;
2642 return AMDGPU::VReg_1024RegClassID;
2644 }
else if (Is == IS_TTMP) {
2648 return AMDGPU::TTMP_32RegClassID;
2650 return AMDGPU::TTMP_64RegClassID;
2652 return AMDGPU::TTMP_128RegClassID;
2654 return AMDGPU::TTMP_256RegClassID;
2656 return AMDGPU::TTMP_512RegClassID;
2658 }
else if (Is == IS_SGPR) {
2662 return AMDGPU::SGPR_32RegClassID;
2664 return AMDGPU::SGPR_64RegClassID;
2666 return AMDGPU::SGPR_96RegClassID;
2668 return AMDGPU::SGPR_128RegClassID;
2670 return AMDGPU::SGPR_160RegClassID;
2672 return AMDGPU::SGPR_192RegClassID;
2674 return AMDGPU::SGPR_224RegClassID;
2676 return AMDGPU::SGPR_256RegClassID;
2678 return AMDGPU::SGPR_288RegClassID;
2680 return AMDGPU::SGPR_320RegClassID;
2682 return AMDGPU::SGPR_352RegClassID;
2684 return AMDGPU::SGPR_384RegClassID;
2686 return AMDGPU::SGPR_512RegClassID;
2688 }
else if (Is == IS_AGPR) {
2692 return AMDGPU::AGPR_32RegClassID;
2694 return AMDGPU::AReg_64RegClassID;
2696 return AMDGPU::AReg_96RegClassID;
2698 return AMDGPU::AReg_128RegClassID;
2700 return AMDGPU::AReg_160RegClassID;
2702 return AMDGPU::AReg_192RegClassID;
2704 return AMDGPU::AReg_224RegClassID;
2706 return AMDGPU::AReg_256RegClassID;
2708 return AMDGPU::AReg_288RegClassID;
2710 return AMDGPU::AReg_320RegClassID;
2712 return AMDGPU::AReg_352RegClassID;
2714 return AMDGPU::AReg_384RegClassID;
2716 return AMDGPU::AReg_512RegClassID;
2718 return AMDGPU::AReg_1024RegClassID;
2726 .
Case(
"exec", AMDGPU::EXEC)
2727 .
Case(
"vcc", AMDGPU::VCC)
2728 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2729 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2730 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2731 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2732 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2733 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2734 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2735 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2736 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2737 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2738 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2739 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2740 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2741 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2742 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2743 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2744 .
Case(
"m0", AMDGPU::M0)
2745 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2746 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2747 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2748 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2749 .
Case(
"scc", AMDGPU::SRC_SCC)
2750 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2751 .
Case(
"tba", AMDGPU::TBA)
2752 .
Case(
"tma", AMDGPU::TMA)
2753 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2754 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2755 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2756 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2757 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2758 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2759 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2760 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2761 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2762 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2763 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2764 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2765 .
Case(
"pc", AMDGPU::PC_REG)
2766 .
Case(
"null", AMDGPU::SGPR_NULL)
2770bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2771 SMLoc &EndLoc,
bool RestoreOnFailure) {
2772 auto R = parseRegister();
2773 if (!R)
return true;
2775 RegNo =
R->getReg();
2776 StartLoc =
R->getStartLoc();
2777 EndLoc =
R->getEndLoc();
2781bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2783 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2786ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2788 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2789 bool PendingErrors = getParser().hasPendingError();
2790 getParser().clearPendingErrors();
2798bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2799 RegisterKind RegKind,
2800 MCRegister Reg1, SMLoc Loc) {
2803 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2808 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2809 Reg = AMDGPU::FLAT_SCR;
2813 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2814 Reg = AMDGPU::XNACK_MASK;
2818 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2823 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2828 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2833 Error(Loc,
"register does not fit in the list");
2839 if (Reg1 !=
Reg + RegWidth / 32) {
2840 Error(Loc,
"registers in a list must have consecutive indices");
2858 {{
"ttmp"}, IS_TTMP},
2864 return Kind == IS_VGPR ||
2872 if (Str.starts_with(
Reg.Name))
2878 return !Str.getAsInteger(10, Num);
2882AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2883 const AsmToken &NextToken)
const {
2898 StringRef RegSuffix = Str.substr(
RegName.size());
2899 if (!RegSuffix.
empty()) {
2917AMDGPUAsmParser::isRegister()
2919 return isRegister(
getToken(), peekToken());
2922MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2923 unsigned SubReg,
unsigned RegWidth,
2927 unsigned AlignSize = 1;
2928 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2934 if (RegNum % AlignSize != 0) {
2935 Error(Loc,
"invalid register alignment");
2936 return MCRegister();
2939 unsigned RegIdx = RegNum / AlignSize;
2942 Error(Loc,
"invalid or unsupported register size");
2943 return MCRegister();
2947 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2948 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2949 Error(Loc,
"register index is out of range");
2950 return AMDGPU::NoRegister;
2953 if (RegKind == IS_VGPR && !
isGFX1250Plus() && RegIdx + RegWidth / 32 > 256) {
2954 Error(Loc,
"register index is out of range");
2955 return MCRegister();
2971bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2973 int64_t RegLo, RegHi;
2977 SMLoc FirstIdxLoc = getLoc();
2984 SecondIdxLoc = getLoc();
2995 Error(FirstIdxLoc,
"invalid register index");
3000 Error(SecondIdxLoc,
"invalid register index");
3004 if (RegLo > RegHi) {
3005 Error(FirstIdxLoc,
"first register index should not exceed second index");
3009 if (RegHi == RegLo) {
3010 StringRef RegSuffix = getTokenStr();
3011 if (RegSuffix ==
".l") {
3012 SubReg = AMDGPU::lo16;
3014 }
else if (RegSuffix ==
".h") {
3015 SubReg = AMDGPU::hi16;
3020 Num =
static_cast<unsigned>(RegLo);
3021 RegWidth = 32 * ((RegHi - RegLo) + 1);
3026MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3029 SmallVectorImpl<AsmToken> &Tokens) {
3035 RegKind = IS_SPECIAL;
3042MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3045 SmallVectorImpl<AsmToken> &Tokens) {
3047 StringRef
RegName = getTokenStr();
3048 auto Loc = getLoc();
3052 Error(Loc,
"invalid register name");
3053 return MCRegister();
3061 unsigned SubReg = NoSubRegister;
3062 if (!RegSuffix.
empty()) {
3064 SubReg = AMDGPU::lo16;
3066 SubReg = AMDGPU::hi16;
3070 Error(Loc,
"invalid register index");
3071 return MCRegister();
3076 if (!ParseRegRange(RegNum, RegWidth, SubReg))
3077 return MCRegister();
3080 return getRegularReg(RegKind, RegNum, SubReg, RegWidth, Loc);
3083MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3084 unsigned &RegNum,
unsigned &RegWidth,
3085 SmallVectorImpl<AsmToken> &Tokens) {
3087 auto ListLoc = getLoc();
3090 "expected a register or a list of registers")) {
3091 return MCRegister();
3096 auto Loc = getLoc();
3097 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3098 return MCRegister();
3099 if (RegWidth != 32) {
3100 Error(Loc,
"expected a single 32-bit register");
3101 return MCRegister();
3105 RegisterKind NextRegKind;
3107 unsigned NextRegNum, NextRegWidth;
3110 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3111 NextRegNum, NextRegWidth,
3113 return MCRegister();
3115 if (NextRegWidth != 32) {
3116 Error(Loc,
"expected a single 32-bit register");
3117 return MCRegister();
3119 if (NextRegKind != RegKind) {
3120 Error(Loc,
"registers in a list must be of the same kind");
3121 return MCRegister();
3123 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3124 return MCRegister();
3128 "expected a comma or a closing square bracket")) {
3129 return MCRegister();
3133 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3138bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3139 MCRegister &
Reg,
unsigned &RegNum,
3141 SmallVectorImpl<AsmToken> &Tokens) {
3142 auto Loc = getLoc();
3146 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3148 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3150 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3155 assert(Parser.hasPendingError());
3159 if (!subtargetHasRegister(*
TRI,
Reg)) {
3160 if (
Reg == AMDGPU::SGPR_NULL) {
3161 Error(Loc,
"'null' operand is not supported on this GPU");
3164 " register not available on this GPU");
3172bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3173 MCRegister &
Reg,
unsigned &RegNum,
3175 bool RestoreOnFailure ) {
3179 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3180 if (RestoreOnFailure) {
3181 while (!Tokens.
empty()) {
3190std::optional<StringRef>
3191AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3194 return StringRef(
".amdgcn.next_free_vgpr");
3196 return StringRef(
".amdgcn.next_free_sgpr");
3198 return std::nullopt;
3202void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3203 auto SymbolName = getGprCountSymbolName(RegKind);
3204 assert(SymbolName &&
"initializing invalid register kind");
3210bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3211 unsigned DwordRegIndex,
3212 unsigned RegWidth) {
3217 auto SymbolName = getGprCountSymbolName(RegKind);
3222 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3226 return !
Error(getLoc(),
3227 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3231 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3233 if (OldCount <= NewMax)
3239std::unique_ptr<AMDGPUOperand>
3240AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3242 SMLoc StartLoc = Tok.getLoc();
3243 SMLoc EndLoc = Tok.getEndLoc();
3244 RegisterKind RegKind;
3246 unsigned RegNum, RegWidth;
3248 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3252 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3255 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3256 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3259ParseStatus AMDGPUAsmParser::parseImm(
OperandVector &Operands,
3263 if (isRegister() || isModifier())
3266 if (
Lit == LitModifier::None) {
3267 if (trySkipId(
"lit"))
3268 Lit = LitModifier::Lit;
3269 else if (trySkipId(
"lit64"))
3270 Lit = LitModifier::Lit64;
3272 if (
Lit != LitModifier::None) {
3275 ParseStatus S = parseImm(Operands, HasSP3AbsModifier,
Lit);
3284 const auto& NextTok = peekToken();
3287 bool Negate =
false;
3295 AMDGPUOperand::Modifiers Mods;
3303 StringRef Num = getTokenStr();
3306 APFloat RealVal(APFloat::IEEEdouble());
3307 auto roundMode = APFloat::rmNearestTiesToEven;
3308 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3311 RealVal.changeSign();
3314 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3315 AMDGPUOperand::ImmTyNone,
true));
3316 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3317 Op.setModifiers(Mods);
3326 if (HasSP3AbsModifier) {
3335 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3338 if (Parser.parseExpression(Expr))
3342 if (Expr->evaluateAsAbsolute(IntVal)) {
3343 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3344 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3345 Op.setModifiers(Mods);
3347 if (
Lit != LitModifier::None)
3349 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3358ParseStatus AMDGPUAsmParser::parseReg(
OperandVector &Operands) {
3362 if (
auto R = parseRegister()) {
3370ParseStatus AMDGPUAsmParser::parseRegOrImm(
OperandVector &Operands,
3372 ParseStatus Res = parseReg(Operands);
3377 return parseImm(Operands, HasSP3AbsMod,
Lit);
3381AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3384 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3390AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3395AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3396 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3400AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3401 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3418AMDGPUAsmParser::isModifier() {
3421 AsmToken NextToken[2];
3422 peekTokens(NextToken);
3424 return isOperandModifier(Tok, NextToken[0]) ||
3425 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3426 isOpcodeModifierWithVal(Tok, NextToken[0]);
3452AMDGPUAsmParser::parseSP3NegModifier() {
3454 AsmToken NextToken[2];
3455 peekTokens(NextToken);
3458 (isRegister(NextToken[0], NextToken[1]) ||
3460 isId(NextToken[0],
"abs"))) {
3469AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
3477 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3479 SP3Neg = parseSP3NegModifier();
3482 Neg = trySkipId(
"neg");
3484 return Error(Loc,
"expected register or immediate");
3488 Abs = trySkipId(
"abs");
3493 if (trySkipId(
"lit")) {
3494 Lit = LitModifier::Lit;
3497 }
else if (trySkipId(
"lit64")) {
3498 Lit = LitModifier::Lit64;
3501 if (!has64BitLiterals())
3502 return Error(Loc,
"lit64 is not supported on this GPU");
3508 return Error(Loc,
"expected register or immediate");
3512 Res = parseRegOrImm(Operands, SP3Abs,
Lit);
3514 Res = parseReg(Operands);
3517 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3521 if (
Lit != LitModifier::None && !Operands.
back()->isImm())
3522 Error(Loc,
"expected immediate with lit modifier");
3524 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3530 if (
Lit != LitModifier::None &&
3534 AMDGPUOperand::Modifiers Mods;
3535 Mods.Abs = Abs || SP3Abs;
3536 Mods.Neg = Neg || SP3Neg;
3539 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3540 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3542 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3543 Op.setModifiers(Mods);
3549AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
3551 bool Sext = trySkipId(
"sext");
3552 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3557 Res = parseRegOrImm(Operands);
3559 Res = parseReg(Operands);
3567 AMDGPUOperand::Modifiers Mods;
3570 if (Mods.hasIntModifiers()) {
3571 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3573 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3574 Op.setModifiers(Mods);
3580ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
3581 return parseRegOrImmWithFPInputMods(Operands,
false);
3584ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
3585 return parseRegOrImmWithIntInputMods(Operands,
false);
3588ParseStatus AMDGPUAsmParser::parseVReg32OrOff(
OperandVector &Operands) {
3589 auto Loc = getLoc();
3590 if (trySkipId(
"off")) {
3591 Operands.
push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3592 AMDGPUOperand::ImmTyOff,
false));
3599 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3608unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3615 return Match_InvalidOperand;
3617 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3618 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3621 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3623 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3624 return Match_InvalidOperand;
3632 if (tryAnotherVOPDEncoding(Inst))
3633 return Match_InvalidOperand;
3635 return Match_Success;
3639 static const unsigned Variants[] = {
3649ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3650 if (isForcedDPP() && isForcedVOP3()) {
3654 if (getForcedEncodingSize() == 32) {
3659 if (isForcedVOP3()) {
3664 if (isForcedSDWA()) {
3670 if (isForcedDPP()) {
3678StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3679 if (isForcedDPP() && isForcedVOP3())
3682 if (getForcedEncodingSize() == 32)
3698AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3702 case AMDGPU::FLAT_SCR:
3704 case AMDGPU::VCC_LO:
3705 case AMDGPU::VCC_HI:
3712 return MCRegister();
3719bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3720 unsigned OpIdx)
const {
3777unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3783 case AMDGPU::V_LSHLREV_B64_e64:
3784 case AMDGPU::V_LSHLREV_B64_gfx10:
3785 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3786 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3787 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3788 case AMDGPU::V_LSHRREV_B64_e64:
3789 case AMDGPU::V_LSHRREV_B64_gfx10:
3790 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3791 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3792 case AMDGPU::V_ASHRREV_I64_e64:
3793 case AMDGPU::V_ASHRREV_I64_gfx10:
3794 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3795 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3796 case AMDGPU::V_LSHL_B64_e64:
3797 case AMDGPU::V_LSHR_B64_e64:
3798 case AMDGPU::V_ASHR_I64_e64:
3811 bool AddMandatoryLiterals =
false) {
3814 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3818 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3820 return {getNamedOperandIdx(Opcode, OpName::src0X),
3821 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3822 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3823 getNamedOperandIdx(Opcode, OpName::src0Y),
3824 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3825 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3830 return {getNamedOperandIdx(Opcode, OpName::src0),
3831 getNamedOperandIdx(Opcode, OpName::src1),
3832 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3835bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3838 return !isInlineConstant(Inst,
OpIdx);
3845 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3856 const unsigned Opcode = Inst.
getOpcode();
3857 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3860 if (!LaneSelOp.
isReg())
3863 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3866bool AMDGPUAsmParser::validateConstantBusLimitations(
3868 const unsigned Opcode = Inst.
getOpcode();
3869 const MCInstrDesc &
Desc = MII.
get(Opcode);
3870 MCRegister LastSGPR;
3871 unsigned ConstantBusUseCount = 0;
3872 unsigned NumLiterals = 0;
3873 unsigned LiteralSize;
3875 if (!(
Desc.TSFlags &
3890 SmallDenseSet<MCRegister> SGPRsUsed;
3891 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3893 SGPRsUsed.
insert(SGPRUsed);
3894 ++ConstantBusUseCount;
3899 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3901 for (
int OpIdx : OpIndices) {
3906 if (usesConstantBus(Inst,
OpIdx)) {
3915 if (SGPRsUsed.
insert(LastSGPR).second) {
3916 ++ConstantBusUseCount;
3936 if (NumLiterals == 0) {
3939 }
else if (LiteralSize !=
Size) {
3945 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3947 "invalid operand (violates constant bus restrictions)");
3954std::optional<unsigned>
3955AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3957 const unsigned Opcode = Inst.
getOpcode();
3963 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3964 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3973 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1170 ||
3974 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3975 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3976 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx13 ||
3977 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250 ||
3978 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx13;
3982 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3983 int I = getNamedOperandIdx(Opcode, OpName);
3987 int64_t
Imm =
Op.getImm();
3993 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3994 OpName::vsrc2Y, OpName::imm}) {
3995 int I = getNamedOperandIdx(Opcode, OpName);
4005 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
4006 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
4008 return InvalidCompOprIdx;
4011bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
4018 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
4019 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
4020 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
4022 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
4026 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
4027 if (!InvalidCompOprIdx.has_value())
4030 auto CompOprIdx = *InvalidCompOprIdx;
4033 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4034 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4035 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4037 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4038 if (CompOprIdx == VOPD::Component::DST) {
4040 Error(Loc,
"dst registers must be distinct");
4042 Error(Loc,
"one dst register must be even and the other odd");
4044 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4045 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4046 " operands must use different VGPR banks");
4054bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4056 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4057 if (!InvalidCompOprIdx.has_value())
4061 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4062 if (InvalidCompOprIdx.has_value()) {
4067 if (*InvalidCompOprIdx == VOPD::Component::DST)
4080bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4081 const unsigned Opcode = Inst.
getOpcode();
4096 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4097 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4098 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4099 int I = getNamedOperandIdx(Opcode, OpName);
4106 return !tryVOPD3(Inst);
4111bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4112 const unsigned Opcode = Inst.
getOpcode();
4117 return tryVOPD(Inst);
4118 return tryVOPD3(Inst);
4121bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4127 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4138bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4146 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4147 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4148 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4156 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4157 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4162 bool IsPackedD16 =
false;
4166 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4167 IsPackedD16 = D16Idx >= 0;
4172 if ((VDataSize / 4) ==
DataSize + TFESize)
4177 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4179 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4181 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4185bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4194 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4196 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4198 ? AMDGPU::OpName::srsrc
4199 : AMDGPU::OpName::rsrc;
4200 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4201 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4202 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4206 assert(SrsrcIdx > VAddr0Idx);
4209 if (BaseOpcode->
BVH) {
4210 if (IsA16 == BaseOpcode->
A16)
4212 Error(IDLoc,
"image address size does not match a16");
4218 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4219 unsigned ActualAddrSize =
4220 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4222 unsigned ExpectedAddrSize =
4226 if (hasPartialNSAEncoding() &&
4229 int VAddrLastIdx = SrsrcIdx - 1;
4230 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4232 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4235 if (ExpectedAddrSize > 12)
4236 ExpectedAddrSize = 16;
4241 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4245 if (ActualAddrSize == ExpectedAddrSize)
4248 Error(IDLoc,
"image address size does not match dim and a16");
4252bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4259 if (!
Desc.mayLoad() || !
Desc.mayStore())
4262 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4269 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4272bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4280 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4288 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4291bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4306 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4307 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4314bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4322 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4325 if (!BaseOpcode->
MSAA)
4328 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4334 return DimInfo->
MSAA;
4340 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4341 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4342 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4352bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4361 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4364 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4372 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4376bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4381 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4384 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4387 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4394 Error(getOperandLoc(Operands, Src0Idx),
4395 "source operand must be either a VGPR or an inline constant");
4402bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4405 const MCInstrDesc &
Desc = MII.
get(Opcode);
4408 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4411 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4415 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4416 Error(getOperandLoc(Operands, Src2Idx),
4417 "inline constants are not allowed for this operand");
4424bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4432 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4433 if (BlgpIdx != -1) {
4434 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4435 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4445 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4446 Error(getOperandLoc(Operands, Src0Idx),
4447 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4452 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4453 Error(getOperandLoc(Operands, Src1Idx),
4454 "wrong register tuple size for blgp value " + Twine(BLGP));
4462 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4466 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4470 MCRegister Src2Reg = Src2.
getReg();
4472 if (Src2Reg == DstReg)
4477 .getSizeInBits() <= 128)
4480 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4481 Error(getOperandLoc(Operands, Src2Idx),
4482 "source 2 operand must not partially overlap with dst");
4489bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4493 case V_DIV_SCALE_F32_gfx6_gfx7:
4494 case V_DIV_SCALE_F32_vi:
4495 case V_DIV_SCALE_F32_gfx10:
4496 case V_DIV_SCALE_F64_gfx6_gfx7:
4497 case V_DIV_SCALE_F64_vi:
4498 case V_DIV_SCALE_F64_gfx10:
4504 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4505 AMDGPU::OpName::src2_modifiers,
4506 AMDGPU::OpName::src2_modifiers}) {
4517bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4525 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4534bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4541 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4549 case AMDGPU::V_SUBREV_F32_e32:
4550 case AMDGPU::V_SUBREV_F32_e64:
4551 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4552 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4553 case AMDGPU::V_SUBREV_F32_e32_vi:
4554 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4555 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4556 case AMDGPU::V_SUBREV_F32_e64_vi:
4558 case AMDGPU::V_SUBREV_CO_U32_e32:
4559 case AMDGPU::V_SUBREV_CO_U32_e64:
4560 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4561 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4563 case AMDGPU::V_SUBBREV_U32_e32:
4564 case AMDGPU::V_SUBBREV_U32_e64:
4565 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4566 case AMDGPU::V_SUBBREV_U32_e32_vi:
4567 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4568 case AMDGPU::V_SUBBREV_U32_e64_vi:
4570 case AMDGPU::V_SUBREV_U32_e32:
4571 case AMDGPU::V_SUBREV_U32_e64:
4572 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4573 case AMDGPU::V_SUBREV_U32_e32_vi:
4574 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4575 case AMDGPU::V_SUBREV_U32_e64_vi:
4577 case AMDGPU::V_SUBREV_F16_e32:
4578 case AMDGPU::V_SUBREV_F16_e64:
4579 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4580 case AMDGPU::V_SUBREV_F16_e32_vi:
4581 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4582 case AMDGPU::V_SUBREV_F16_e64_vi:
4584 case AMDGPU::V_SUBREV_U16_e32:
4585 case AMDGPU::V_SUBREV_U16_e64:
4586 case AMDGPU::V_SUBREV_U16_e32_vi:
4587 case AMDGPU::V_SUBREV_U16_e64_vi:
4589 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4590 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4591 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4593 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4594 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4596 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4597 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4599 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4600 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4602 case AMDGPU::V_LSHRREV_B32_e32:
4603 case AMDGPU::V_LSHRREV_B32_e64:
4604 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4605 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4606 case AMDGPU::V_LSHRREV_B32_e32_vi:
4607 case AMDGPU::V_LSHRREV_B32_e64_vi:
4608 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4609 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4611 case AMDGPU::V_ASHRREV_I32_e32:
4612 case AMDGPU::V_ASHRREV_I32_e64:
4613 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4614 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4615 case AMDGPU::V_ASHRREV_I32_e32_vi:
4616 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4617 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4618 case AMDGPU::V_ASHRREV_I32_e64_vi:
4620 case AMDGPU::V_LSHLREV_B32_e32:
4621 case AMDGPU::V_LSHLREV_B32_e64:
4622 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4623 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4624 case AMDGPU::V_LSHLREV_B32_e32_vi:
4625 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4626 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4627 case AMDGPU::V_LSHLREV_B32_e64_vi:
4629 case AMDGPU::V_LSHLREV_B16_e32:
4630 case AMDGPU::V_LSHLREV_B16_e64:
4631 case AMDGPU::V_LSHLREV_B16_e32_vi:
4632 case AMDGPU::V_LSHLREV_B16_e64_vi:
4633 case AMDGPU::V_LSHLREV_B16_gfx10:
4635 case AMDGPU::V_LSHRREV_B16_e32:
4636 case AMDGPU::V_LSHRREV_B16_e64:
4637 case AMDGPU::V_LSHRREV_B16_e32_vi:
4638 case AMDGPU::V_LSHRREV_B16_e64_vi:
4639 case AMDGPU::V_LSHRREV_B16_gfx10:
4641 case AMDGPU::V_ASHRREV_I16_e32:
4642 case AMDGPU::V_ASHRREV_I16_e64:
4643 case AMDGPU::V_ASHRREV_I16_e32_vi:
4644 case AMDGPU::V_ASHRREV_I16_e64_vi:
4645 case AMDGPU::V_ASHRREV_I16_gfx10:
4647 case AMDGPU::V_LSHLREV_B64_e64:
4648 case AMDGPU::V_LSHLREV_B64_gfx10:
4649 case AMDGPU::V_LSHLREV_B64_vi:
4651 case AMDGPU::V_LSHRREV_B64_e64:
4652 case AMDGPU::V_LSHRREV_B64_gfx10:
4653 case AMDGPU::V_LSHRREV_B64_vi:
4655 case AMDGPU::V_ASHRREV_I64_e64:
4656 case AMDGPU::V_ASHRREV_I64_gfx10:
4657 case AMDGPU::V_ASHRREV_I64_vi:
4659 case AMDGPU::V_PK_LSHLREV_B16:
4660 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4661 case AMDGPU::V_PK_LSHLREV_B16_vi:
4663 case AMDGPU::V_PK_LSHRREV_B16:
4664 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4665 case AMDGPU::V_PK_LSHRREV_B16_vi:
4666 case AMDGPU::V_PK_ASHRREV_I16:
4667 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4668 case AMDGPU::V_PK_ASHRREV_I16_vi:
4675bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4677 using namespace SIInstrFlags;
4678 const unsigned Opcode = Inst.
getOpcode();
4679 const MCInstrDesc &
Desc = MII.
get(Opcode);
4684 if ((
Desc.TSFlags & Enc) == 0)
4687 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4688 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4692 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4695 Error(getOperandLoc(Operands, SrcIdx),
4696 "lds_direct is not supported on this GPU");
4701 Error(getOperandLoc(Operands, SrcIdx),
4702 "lds_direct cannot be used with this instruction");
4706 if (SrcName != OpName::src0) {
4707 Error(getOperandLoc(Operands, SrcIdx),
4708 "lds_direct may be used as src0 only");
4717SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4718 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4719 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4720 if (
Op.isFlatOffset())
4721 return Op.getStartLoc();
4726bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4729 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4735 return validateFlatOffset(Inst, Operands);
4738 return validateSMEMOffset(Inst, Operands);
4744 const unsigned OffsetSize = 24;
4745 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4746 Error(getFlatOffsetLoc(Operands),
4747 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4748 "-bit unsigned offset for buffer ops");
4752 const unsigned OffsetSize = 16;
4753 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4754 Error(getFlatOffsetLoc(Operands),
4755 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4762bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4769 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4773 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4774 Error(getFlatOffsetLoc(Operands),
4775 "flat offset modifier is not supported on this GPU");
4782 bool AllowNegative =
4785 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4786 Error(getFlatOffsetLoc(Operands),
4787 Twine(
"expected a ") +
4788 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4789 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4796SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4798 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4799 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4800 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4801 return Op.getStartLoc();
4806bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4816 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4830 Error(getSMEMOffsetLoc(Operands),
4832 ?
"expected a 23-bit unsigned offset for buffer ops"
4833 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4834 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4835 :
"expected a 21-bit signed offset");
4840bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4843 const MCInstrDesc &
Desc = MII.
get(Opcode);
4847 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4848 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4850 const int OpIndices[] = { Src0Idx, Src1Idx };
4852 unsigned NumExprs = 0;
4853 unsigned NumLiterals = 0;
4856 for (
int OpIdx : OpIndices) {
4857 if (
OpIdx == -1)
break;
4863 std::optional<int64_t>
Imm;
4866 }
else if (MO.
isExpr()) {
4875 if (!
Imm.has_value()) {
4877 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4881 if (NumLiterals == 0 || LiteralValue !=
Value) {
4889 if (NumLiterals + NumExprs <= 1)
4892 Error(getOperandLoc(Operands, Src1Idx),
4893 "only one unique literal operand is allowed");
4897bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4900 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4910 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4911 if (OpSelIdx != -1) {
4915 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4916 if (OpSelHiIdx != -1) {
4925 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4935 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4936 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4937 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4938 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4940 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4941 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4947 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4949 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4959 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4960 if (Src2Idx != -1) {
4961 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4971bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4972 if (!hasTrue16Insts())
4974 const MCRegisterInfo *MRI = getMRI();
4976 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4982 if (OpSelOpValue == 0)
4984 unsigned OpCount = 0;
4985 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4986 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4987 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4994 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4995 if (OpSelOpIsHi != VGPRSuffixIsHi)
5004bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
5005 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
5018 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
5029 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
5030 AMDGPU::OpName::src1_modifiers,
5031 AMDGPU::OpName::src2_modifiers};
5033 for (
unsigned i = 0; i < 3; ++i) {
5043bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5046 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5047 if (DppCtrlIdx >= 0) {
5054 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5055 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5056 :
"DP ALU dpp only supports row_newbcast");
5061 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5062 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5065 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5067 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5070 Error(getOperandLoc(Operands, Src1Idx),
5071 "invalid operand for instruction");
5075 Error(getInstLoc(Operands),
5076 "src1 immediate operand invalid for instruction");
5086bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5087 return (
Reg == AMDGPU::VCC && isWave64()) ||
5088 (
Reg == AMDGPU::VCC_LO && isWave32());
5092bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5095 const MCInstrDesc &
Desc = MII.
get(Opcode);
5096 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5098 !HasMandatoryLiteral && !
isVOPD(Opcode))
5103 std::optional<unsigned> LiteralOpIdx;
5106 for (
int OpIdx : OpIndices) {
5116 std::optional<int64_t>
Imm;
5122 bool IsAnotherLiteral =
false;
5123 if (!
Imm.has_value()) {
5125 IsAnotherLiteral =
true;
5126 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5131 HasMandatoryLiteral);
5137 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5139 "invalid operand for instruction");
5143 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5150 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5151 !getFeatureBits()[FeatureVOP3Literal]) {
5153 "literal operands are not supported");
5157 if (LiteralOpIdx && IsAnotherLiteral) {
5158 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5159 getOperandLoc(Operands, *LiteralOpIdx)),
5160 "only one unique literal operand is allowed");
5164 if (IsAnotherLiteral)
5165 LiteralOpIdx =
OpIdx;
5188bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5196 ? AMDGPU::OpName::data0
5197 : AMDGPU::OpName::vdata;
5199 const MCRegisterInfo *MRI = getMRI();
5200 int DstAreg =
IsAGPROperand(Inst, AMDGPU::OpName::vdst, MRI);
5204 int Data2Areg =
IsAGPROperand(Inst, AMDGPU::OpName::data1, MRI);
5205 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5209 auto FB = getFeatureBits();
5210 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5211 if (DataAreg < 0 || DstAreg < 0)
5213 return DstAreg == DataAreg;
5216 return DstAreg < 1 && DataAreg < 1;
5219bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5220 auto FB = getFeatureBits();
5221 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5225 const MCRegisterInfo *MRI = getMRI();
5228 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5231 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5235 case AMDGPU::DS_LOAD_TR6_B96:
5236 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5240 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5241 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5245 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5246 if (VAddrIdx != -1) {
5249 if ((
Sub - AMDGPU::VGPR0) & 1)
5254 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5255 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5260 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5261 const MCRegisterClass &AGPR32 = MRI->
getRegClass(AMDGPU::AGPR_32RegClassID);
5280SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5281 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5282 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5284 return Op.getStartLoc();
5289bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5292 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5295 SMLoc BLGPLoc = getBLGPLoc(Operands);
5298 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5299 auto FB = getFeatureBits();
5300 bool UsesNeg =
false;
5301 if (FB[AMDGPU::FeatureGFX940Insts]) {
5303 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5304 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5305 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5306 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5311 if (IsNeg == UsesNeg)
5315 UsesNeg ?
"invalid modifier: blgp is not supported"
5316 :
"invalid modifier: neg is not supported");
5321bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5327 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5328 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5329 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5330 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5333 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5336 if (
Reg == AMDGPU::SGPR_NULL)
5339 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5343bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5349 return validateGWS(Inst, Operands);
5354 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5359 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5360 Error(S,
"gds modifier is not supported on this GPU");
5368bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5370 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5374 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5375 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5378 const MCRegisterInfo *MRI = getMRI();
5379 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5381 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5384 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5386 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5393bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5396 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5397 AMDGPU::OpName::cpol);
5405 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5408 Error(S,
"scale_offset is not supported on this GPU");
5411 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5414 Error(S,
"nv is not supported on this GPU");
5419 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5422 Error(S,
"scale_offset is not supported for this instruction");
5426 return validateTHAndScopeBits(Inst, Operands, CPol);
5431 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5432 Error(S,
"cache policy is not supported for SMRD instructions");
5436 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5445 if (!(TSFlags & AllowSCCModifier)) {
5446 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5450 "scc modifier is not supported for this instruction on this GPU");
5461 :
"instruction must use glc");
5466 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5469 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5471 :
"instruction must not use glc");
5479bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5481 const unsigned CPol) {
5485 const unsigned Opcode = Inst.
getOpcode();
5486 const MCInstrDesc &TID = MII.
get(Opcode);
5489 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5496 return PrintError(
"th:TH_ATOMIC_RETURN requires a destination operand");
5501 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5509 return PrintError(
"invalid th value for SMEM instruction");
5516 return PrintError(
"scope and th combination is not valid");
5522 return PrintError(
"invalid th value for atomic instructions");
5525 return PrintError(
"invalid th value for store instructions");
5528 return PrintError(
"invalid th value for load instructions");
5534bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5537 if (
Desc.mayStore() &&
5539 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5540 if (Loc != getInstLoc(Operands)) {
5541 Error(Loc,
"TFE modifier has no meaning for store instructions");
5549bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5555 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5556 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5560 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5568 Error(getOperandLoc(Operands, SrcIdx),
5569 "wrong register tuple size for " +
5574 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5575 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5578bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5580 if (!validateLdsDirect(Inst, Operands))
5582 if (!validateTrue16OpSel(Inst)) {
5583 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5584 "op_sel operand conflicts with 16-bit operand suffix");
5587 if (!validateSOPLiteral(Inst, Operands))
5589 if (!validateVOPLiteral(Inst, Operands)) {
5592 if (!validateConstantBusLimitations(Inst, Operands)) {
5595 if (!validateVOPD(Inst, Operands)) {
5598 if (!validateIntClampSupported(Inst)) {
5599 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5600 "integer clamping is not supported on this GPU");
5603 if (!validateOpSel(Inst)) {
5604 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5605 "invalid op_sel operand");
5608 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5609 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5610 "invalid neg_lo operand");
5613 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5614 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5615 "invalid neg_hi operand");
5618 if (!validateDPP(Inst, Operands)) {
5622 if (!validateMIMGD16(Inst)) {
5623 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5624 "d16 modifier is not supported on this GPU");
5627 if (!validateMIMGDim(Inst, Operands)) {
5628 Error(IDLoc,
"missing dim operand");
5631 if (!validateTensorR128(Inst)) {
5632 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5633 "instruction must set modifier r128=0");
5636 if (!validateMIMGMSAA(Inst)) {
5637 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5638 "invalid dim; must be MSAA type");
5641 if (!validateMIMGDataSize(Inst, IDLoc)) {
5644 if (!validateMIMGAddrSize(Inst, IDLoc))
5646 if (!validateMIMGAtomicDMask(Inst)) {
5647 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5648 "invalid atomic image dmask");
5651 if (!validateMIMGGatherDMask(Inst)) {
5652 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5653 "invalid image_gather dmask: only one bit must be set");
5656 if (!validateMovrels(Inst, Operands)) {
5659 if (!validateOffset(Inst, Operands)) {
5662 if (!validateMAIAccWrite(Inst, Operands)) {
5665 if (!validateMAISrc2(Inst, Operands)) {
5668 if (!validateMFMA(Inst, Operands)) {
5671 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5675 if (!validateAGPRLdSt(Inst)) {
5676 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5677 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5678 :
"invalid register class: agpr loads and stores not supported on this GPU"
5682 if (!validateVGPRAlign(Inst)) {
5684 "invalid register class: vgpr tuples must be 64 bit aligned");
5687 if (!validateDS(Inst, Operands)) {
5691 if (!validateBLGP(Inst, Operands)) {
5695 if (!validateDivScale(Inst)) {
5696 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5699 if (!validateWaitCnt(Inst, Operands)) {
5702 if (!validateTFE(Inst, Operands)) {
5705 if (!validateWMMA(Inst, Operands)) {
5714 unsigned VariantID = 0);
5718 unsigned VariantID);
5720bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5725bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5726 const FeatureBitset &FBS,
5727 ArrayRef<unsigned> Variants) {
5728 for (
auto Variant : Variants) {
5736bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5738 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5741 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5746 getParser().clearPendingErrors();
5750 StringRef VariantName = getMatchedVariantName();
5751 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5754 " variant of this instruction is not supported"));
5758 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5759 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5761 FeatureBitset FeaturesWS32 = getFeatureBits();
5762 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5763 .
flip(AMDGPU::FeatureWavefrontSize32);
5764 FeatureBitset AvailableFeaturesWS32 =
5765 ComputeAvailableFeatures(FeaturesWS32);
5767 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5768 return Error(IDLoc,
"instruction requires wavesize=32");
5772 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5773 return Error(IDLoc,
"instruction not supported on this GPU");
5778 return Error(IDLoc,
"invalid instruction" + Suggestion);
5784 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5785 if (
Op.isToken() && InvalidOprIdx > 1) {
5786 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5787 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5792bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5795 uint64_t &ErrorInfo,
5796 bool MatchingInlineAsm) {
5799 unsigned Result = Match_Success;
5800 for (
auto Variant : getMatchedVariants()) {
5802 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5807 if (R == Match_Success || R == Match_MissingFeature ||
5808 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5809 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5810 Result != Match_MissingFeature)) {
5814 if (R == Match_Success)
5818 if (Result == Match_Success) {
5819 if (!validateInstruction(Inst, IDLoc, Operands)) {
5826 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5827 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5833 case Match_MissingFeature:
5837 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5839 case Match_InvalidOperand: {
5840 SMLoc ErrorLoc = IDLoc;
5841 if (ErrorInfo != ~0ULL) {
5842 if (ErrorInfo >= Operands.
size()) {
5843 return Error(IDLoc,
"too few operands for instruction");
5845 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5846 if (ErrorLoc == SMLoc())
5850 return Error(ErrorLoc,
"invalid VOPDY instruction");
5852 return Error(ErrorLoc,
"invalid operand for instruction");
5855 case Match_MnemonicFail:
5861bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5866 if (getParser().parseAbsoluteExpression(Tmp)) {
5869 Ret =
static_cast<uint32_t
>(Tmp);
5873bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5874 if (!getSTI().getTargetTriple().isAMDGCN())
5875 return TokError(
"directive only supported for amdgcn architecture");
5877 std::string TargetIDDirective;
5878 SMLoc TargetStart = getTok().getLoc();
5879 if (getParser().parseEscapedString(TargetIDDirective))
5882 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5883 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5884 return getParser().Error(TargetRange.
Start,
5885 (Twine(
".amdgcn_target directive's target id ") +
5886 Twine(TargetIDDirective) +
5887 Twine(
" does not match the specified target id ") +
5888 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5893bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5897bool AMDGPUAsmParser::calculateGPRBlocks(
5898 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5899 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5900 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5901 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5902 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5908 const MCExpr *
NumSGPRs = NextFreeSGPR;
5909 int64_t EvaluatedSGPRs;
5914 unsigned MaxAddressableNumSGPRs =
5917 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5918 !Features.
test(FeatureSGPRInitBug) &&
5919 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5920 return OutOfRangeError(SGPRRange);
5922 const MCExpr *ExtraSGPRs =
5926 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5927 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5928 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5929 return OutOfRangeError(SGPRRange);
5931 if (Features.
test(FeatureSGPRInitBug))
5938 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5939 unsigned Granule) ->
const MCExpr * {
5943 const MCExpr *AlignToGPR =
5945 const MCExpr *DivGPR =
5951 VGPRBlocks = GetNumGPRBlocks(
5960bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5961 if (!getSTI().getTargetTriple().isAMDGCN())
5962 return TokError(
"directive only supported for amdgcn architecture");
5965 return TokError(
"directive only supported for amdhsa OS");
5967 StringRef KernelName;
5968 if (getParser().parseIdentifier(KernelName))
5971 AMDGPU::MCKernelDescriptor KD =
5983 const MCExpr *NextFreeVGPR = ZeroExpr;
5985 const MCExpr *NamedBarCnt = ZeroExpr;
5986 uint64_t SharedVGPRCount = 0;
5987 uint64_t PreloadLength = 0;
5988 uint64_t PreloadOffset = 0;
5990 const MCExpr *NextFreeSGPR = ZeroExpr;
5993 unsigned ImpliedUserSGPRCount = 0;
5997 std::optional<unsigned> ExplicitUserSGPRCount;
5998 const MCExpr *ReserveVCC = OneExpr;
5999 const MCExpr *ReserveFlatScr = OneExpr;
6000 std::optional<bool> EnableWavefrontSize32;
6006 SMRange IDRange = getTok().getLocRange();
6007 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6010 if (
ID ==
".end_amdhsa_kernel")
6014 return TokError(
".amdhsa_ directives cannot be repeated");
6016 SMLoc ValStart = getLoc();
6017 const MCExpr *ExprVal;
6018 if (getParser().parseExpression(ExprVal))
6020 SMLoc ValEnd = getLoc();
6021 SMRange ValRange = SMRange(ValStart, ValEnd);
6024 uint64_t Val = IVal;
6025 bool EvaluatableExpr;
6026 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6028 return OutOfRangeError(ValRange);
6032#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6033 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6034 return OutOfRangeError(RANGE); \
6035 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6040#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6042 return Error(IDRange.Start, "directive should have resolvable expression", \
6045 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6048 return OutOfRangeError(ValRange);
6050 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6053 return OutOfRangeError(ValRange);
6055 }
else if (
ID ==
".amdhsa_kernarg_size") {
6057 return OutOfRangeError(ValRange);
6059 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6061 ExplicitUserSGPRCount = Val;
6062 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6066 "directive is not supported with architected flat scratch",
6069 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6072 ImpliedUserSGPRCount += 4;
6073 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6076 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6079 return OutOfRangeError(ValRange);
6083 ImpliedUserSGPRCount += Val;
6084 PreloadLength = Val;
6086 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6089 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6092 return OutOfRangeError(ValRange);
6096 PreloadOffset = Val;
6097 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6100 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6103 ImpliedUserSGPRCount += 2;
6104 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6107 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6110 ImpliedUserSGPRCount += 2;
6111 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6114 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6117 ImpliedUserSGPRCount += 2;
6118 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6121 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6124 ImpliedUserSGPRCount += 2;
6125 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6128 "directive is not supported with architected flat scratch",
6132 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6135 ImpliedUserSGPRCount += 2;
6136 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6139 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6142 ImpliedUserSGPRCount += 1;
6143 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6145 if (IVersion.
Major < 10)
6146 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6147 EnableWavefrontSize32 = Val;
6149 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6151 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6153 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6155 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6158 "directive is not supported with architected flat scratch",
6161 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6163 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6167 "directive is not supported without architected flat scratch",
6170 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6172 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6174 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6176 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6178 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6180 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6182 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6184 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6186 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6188 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6190 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6192 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6193 VGPRRange = ValRange;
6194 NextFreeVGPR = ExprVal;
6195 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6196 SGPRRange = ValRange;
6197 NextFreeSGPR = ExprVal;
6198 }
else if (
ID ==
".amdhsa_accum_offset") {
6200 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6201 AccumOffset = ExprVal;
6202 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6204 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6205 NamedBarCnt = ExprVal;
6206 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6208 return OutOfRangeError(ValRange);
6209 ReserveVCC = ExprVal;
6210 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6211 if (IVersion.
Major < 7)
6212 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6215 "directive is not supported with architected flat scratch",
6218 return OutOfRangeError(ValRange);
6219 ReserveFlatScr = ExprVal;
6220 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6221 if (IVersion.
Major < 8)
6222 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6224 return OutOfRangeError(ValRange);
6225 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6226 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6228 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6230 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6232 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6234 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6236 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6238 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6240 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6242 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6244 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6245 if (!getSTI().hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6246 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6249 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6251 }
else if (
ID ==
".amdhsa_ieee_mode") {
6252 if (!getSTI().hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6253 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6256 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6258 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6259 if (IVersion.
Major < 9)
6260 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6262 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6264 }
else if (
ID ==
".amdhsa_tg_split") {
6266 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6269 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6272 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6274 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6276 }
else if (
ID ==
".amdhsa_memory_ordered") {
6277 if (IVersion.
Major < 10)
6278 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6280 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6282 }
else if (
ID ==
".amdhsa_forward_progress") {
6283 if (IVersion.
Major < 10)
6284 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6286 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6288 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6290 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6291 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6293 SharedVGPRCount = Val;
6295 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6297 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6298 if (IVersion.
Major < 11)
6299 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6300 if (IVersion.
Major == 11) {
6302 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6306 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6309 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6312 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6314 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6316 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6318 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6321 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6323 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6325 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6327 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6329 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6331 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6333 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6335 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6337 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6339 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6340 if (IVersion.
Major < 12)
6341 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6343 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6346 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6349#undef PARSE_BITS_ENTRY
6352 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6353 return TokError(
".amdhsa_next_free_vgpr directive is required");
6355 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6356 return TokError(
".amdhsa_next_free_sgpr directive is required");
6358 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6363 if (PreloadLength) {
6369 const MCExpr *VGPRBlocks;
6370 const MCExpr *SGPRBlocks;
6371 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6372 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6373 EnableWavefrontSize32, NextFreeVGPR,
6374 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6378 int64_t EvaluatedVGPRBlocks;
6379 bool VGPRBlocksEvaluatable =
6380 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6381 if (VGPRBlocksEvaluatable &&
6383 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6384 return OutOfRangeError(VGPRRange);
6388 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6389 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6391 int64_t EvaluatedSGPRBlocks;
6392 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6394 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6395 return OutOfRangeError(SGPRRange);
6398 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6399 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6401 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6402 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6403 "enabled user SGPRs");
6407 return TokError(
"too many user SGPRs enabled");
6411 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6412 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6416 return TokError(
"too many user SGPRs enabled");
6420 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6421 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6426 return TokError(
"Kernarg size should be resolvable");
6427 uint64_t kernarg_size = IVal;
6428 if (PreloadLength && kernarg_size &&
6429 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6430 return TokError(
"Kernarg preload length + offset is larger than the "
6431 "kernarg segment size");
6434 if (!Seen.
contains(
".amdhsa_accum_offset"))
6435 return TokError(
".amdhsa_accum_offset directive is required");
6436 int64_t EvaluatedAccum;
6437 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6438 uint64_t UEvaluatedAccum = EvaluatedAccum;
6439 if (AccumEvaluatable &&
6440 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6441 return TokError(
"accum_offset should be in range [4..256] in "
6444 int64_t EvaluatedNumVGPR;
6445 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6448 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6449 return TokError(
"accum_offset exceeds total VGPR allocation");
6455 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6456 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6462 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6463 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6466 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6468 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6469 return TokError(
"shared_vgpr_count directive not valid on "
6470 "wavefront size 32");
6473 if (VGPRBlocksEvaluatable &&
6474 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6476 return TokError(
"shared_vgpr_count*2 + "
6477 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6482 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6483 NextFreeVGPR, NextFreeSGPR,
6484 ReserveVCC, ReserveFlatScr);
6488bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6490 if (ParseAsAbsoluteExpression(
Version))
6493 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6497bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6498 AMDGPUMCKernelCodeT &
C) {
6501 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6502 Parser.eatToEndOfStatement();
6506 SmallString<40> ErrStr;
6507 raw_svector_ostream Err(ErrStr);
6508 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6509 return TokError(Err.
str());
6513 if (
ID ==
"enable_wavefront_size32") {
6516 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6518 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6521 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6525 if (
ID ==
"wavefront_size") {
6526 if (
C.wavefront_size == 5) {
6528 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6530 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6531 }
else if (
C.wavefront_size == 6) {
6533 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6540bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6541 AMDGPUMCKernelCodeT KernelCode;
6550 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6553 if (
ID ==
".end_amd_kernel_code_t")
6556 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6561 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6566bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6567 StringRef KernelName;
6568 if (!parseId(KernelName,
"expected symbol name"))
6571 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6578bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6579 if (!getSTI().getTargetTriple().isAMDGCN()) {
6580 return Error(getLoc(),
6581 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6585 auto TargetIDDirective = getLexer().getTok().getStringContents();
6586 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6587 return Error(getParser().getTok().getLoc(),
"target id must match options");
6589 getTargetStreamer().EmitISAVersion();
6595bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6598 std::string HSAMetadataString;
6603 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6604 return Error(getLoc(),
"invalid HSA metadata");
6611bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6612 const char *AssemblerDirectiveEnd,
6613 std::string &CollectString) {
6615 raw_string_ostream CollectStream(CollectString);
6617 getLexer().setSkipSpace(
false);
6619 bool FoundEnd =
false;
6622 CollectStream << getTokenStr();
6626 if (trySkipId(AssemblerDirectiveEnd)) {
6631 CollectStream << Parser.parseStringToEndOfStatement()
6632 <<
getContext().getAsmInfo()->getSeparatorString();
6634 Parser.eatToEndOfStatement();
6637 getLexer().setSkipSpace(
true);
6640 return TokError(Twine(
"expected directive ") +
6641 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6648bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6654 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6655 if (!PALMetadata->setFromString(
String))
6656 return Error(getLoc(),
"invalid PAL metadata");
6661bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6663 return Error(getLoc(),
6665 "not available on non-amdpal OSes")).str());
6668 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6669 PALMetadata->setLegacy();
6672 if (ParseAsAbsoluteExpression(
Key)) {
6673 return TokError(Twine(
"invalid value in ") +
6677 return TokError(Twine(
"expected an even number of values in ") +
6680 if (ParseAsAbsoluteExpression(
Value)) {
6681 return TokError(Twine(
"invalid value in ") +
6684 PALMetadata->setRegister(
Key,
Value);
6693bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6694 if (getParser().checkForValidSection())
6698 SMLoc NameLoc = getLoc();
6699 if (getParser().parseIdentifier(Name))
6700 return TokError(
"expected identifier in directive");
6703 if (getParser().parseComma())
6709 SMLoc SizeLoc = getLoc();
6710 if (getParser().parseAbsoluteExpression(
Size))
6713 return Error(SizeLoc,
"size must be non-negative");
6714 if (
Size > LocalMemorySize)
6715 return Error(SizeLoc,
"size is too large");
6717 int64_t Alignment = 4;
6719 SMLoc AlignLoc = getLoc();
6720 if (getParser().parseAbsoluteExpression(Alignment))
6723 return Error(AlignLoc,
"alignment must be a power of two");
6728 if (Alignment >= 1u << 31)
6729 return Error(AlignLoc,
"alignment is too large");
6735 Symbol->redefineIfPossible();
6736 if (!
Symbol->isUndefined())
6737 return Error(NameLoc,
"invalid symbol redefinition");
6739 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6743bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6744 StringRef IDVal = DirectiveID.
getString();
6747 if (IDVal ==
".amdhsa_kernel")
6748 return ParseDirectiveAMDHSAKernel();
6750 if (IDVal ==
".amdhsa_code_object_version")
6751 return ParseDirectiveAMDHSACodeObjectVersion();
6755 return ParseDirectiveHSAMetadata();
6757 if (IDVal ==
".amd_kernel_code_t")
6758 return ParseDirectiveAMDKernelCodeT();
6760 if (IDVal ==
".amdgpu_hsa_kernel")
6761 return ParseDirectiveAMDGPUHsaKernel();
6763 if (IDVal ==
".amd_amdgpu_isa")
6764 return ParseDirectiveISAVersion();
6768 Twine(
" directive is "
6769 "not available on non-amdhsa OSes"))
6774 if (IDVal ==
".amdgcn_target")
6775 return ParseDirectiveAMDGCNTarget();
6777 if (IDVal ==
".amdgpu_lds")
6778 return ParseDirectiveAMDGPULDS();
6781 return ParseDirectivePALMetadataBegin();
6784 return ParseDirectivePALMetadata();
6789bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &MRI,
6796 return hasSGPR104_SGPR105();
6799 case SRC_SHARED_BASE_LO:
6800 case SRC_SHARED_BASE:
6801 case SRC_SHARED_LIMIT_LO:
6802 case SRC_SHARED_LIMIT:
6803 case SRC_PRIVATE_BASE_LO:
6804 case SRC_PRIVATE_BASE:
6805 case SRC_PRIVATE_LIMIT_LO:
6806 case SRC_PRIVATE_LIMIT:
6808 case SRC_FLAT_SCRATCH_BASE_LO:
6809 case SRC_FLAT_SCRATCH_BASE_HI:
6810 return hasGloballyAddressableScratch();
6811 case SRC_POPS_EXITING_WAVE_ID:
6823 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6853 return hasSGPR102_SGPR103();
6858ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6861 ParseStatus Res = parseVOPD(Operands);
6866 Res = MatchOperandParserImpl(Operands, Mnemonic);
6878 SMLoc LBraceLoc = getLoc();
6883 auto Loc = getLoc();
6884 Res = parseReg(Operands);
6886 Error(Loc,
"expected a register");
6890 RBraceLoc = getLoc();
6895 "expected a comma or a closing square bracket"))
6899 if (Operands.
size() - Prefix > 1) {
6901 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6902 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6908 return parseRegOrImm(Operands);
6911StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6913 setForcedEncodingSize(0);
6914 setForcedDPP(
false);
6915 setForcedSDWA(
false);
6917 if (
Name.consume_back(
"_e64_dpp")) {
6919 setForcedEncodingSize(64);
6922 if (
Name.consume_back(
"_e64")) {
6923 setForcedEncodingSize(64);
6926 if (
Name.consume_back(
"_e32")) {
6927 setForcedEncodingSize(32);
6930 if (
Name.consume_back(
"_dpp")) {
6934 if (
Name.consume_back(
"_sdwa")) {
6935 setForcedSDWA(
true);
6943 unsigned VariantID);
6949 Name = parseMnemonicSuffix(Name);
6955 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6957 bool IsMIMG = Name.starts_with(
"image_");
6960 OperandMode
Mode = OperandMode_Default;
6962 Mode = OperandMode_NSA;
6966 checkUnsupportedInstruction(Name, NameLoc);
6967 if (!Parser.hasPendingError()) {
6970 :
"not a valid operand.";
6971 Error(getLoc(), Msg);
6990ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6993 if (!trySkipId(Name))
6996 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
7000ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7009ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7010 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7011 std::function<
bool(int64_t &)> ConvertResult) {
7015 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7019 if (ConvertResult && !ConvertResult(
Value)) {
7020 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7023 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7027ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7028 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7029 bool (*ConvertResult)(int64_t &)) {
7038 const unsigned MaxSize = 4;
7042 for (
int I = 0; ; ++
I) {
7044 SMLoc Loc = getLoc();
7048 if (
Op != 0 &&
Op != 1)
7049 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7056 if (
I + 1 == MaxSize)
7057 return Error(getLoc(),
"expected a closing square bracket");
7063 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7067ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7069 AMDGPUOperand::ImmTy ImmTy,
7070 bool IgnoreNegative) {
7074 if (trySkipId(Name)) {
7076 }
else if (trySkipId(
"no", Name)) {
7085 return Error(S,
"r128 modifier is not supported on this GPU");
7086 if (Name ==
"a16" && !
hasA16())
7087 return Error(S,
"a16 modifier is not supported on this GPU");
7089 if (Bit == 0 && Name ==
"gds") {
7090 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7092 return Error(S,
"nogds is not allowed");
7095 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7096 ImmTy = AMDGPUOperand::ImmTyR128A16;
7098 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7102unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7103 bool &Disabling)
const {
7104 Disabling =
Id.consume_front(
"no");
7107 return StringSwitch<unsigned>(Id)
7114 return StringSwitch<unsigned>(Id)
7122ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7124 SMLoc StringLoc = getLoc();
7126 int64_t CPolVal = 0;
7135 ResTH = parseTH(Operands, TH);
7146 ResScope = parseScope(Operands, Scope);
7159 if (trySkipId(
"nv")) {
7163 }
else if (trySkipId(
"no",
"nv")) {
7170 if (trySkipId(
"scale_offset")) {
7174 }
else if (trySkipId(
"no",
"scale_offset")) {
7187 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7188 AMDGPUOperand::ImmTyCPol));
7192 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7193 SMLoc OpLoc = getLoc();
7194 unsigned Enabled = 0, Seen = 0;
7198 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7205 return Error(S,
"dlc modifier is not supported on this GPU");
7208 return Error(S,
"scc modifier is not supported on this GPU");
7211 return Error(S,
"duplicate cache policy modifier");
7223 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7227ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7232 ParseStatus Res = parseStringOrIntWithPrefix(
7233 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7242ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7247 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7251 if (
Value ==
"TH_DEFAULT")
7253 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7254 Value ==
"TH_LOAD_NT_WB") {
7255 return Error(StringLoc,
"invalid th value");
7256 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7258 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7260 }
else if (
Value.consume_front(
"TH_STORE_")) {
7263 return Error(StringLoc,
"invalid th value");
7266 if (
Value ==
"BYPASS")
7271 TH |= StringSwitch<int64_t>(
Value)
7281 .Default(0xffffffff);
7283 TH |= StringSwitch<int64_t>(
Value)
7294 .Default(0xffffffff);
7297 if (TH == 0xffffffff)
7298 return Error(StringLoc,
"invalid th value");
7305 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7306 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7307 std::optional<unsigned> InsertAt = std::nullopt) {
7308 auto i = OptionalIdx.find(ImmT);
7309 if (i != OptionalIdx.end()) {
7310 unsigned Idx = i->second;
7311 const AMDGPUOperand &
Op =
7312 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7316 Op.addImmOperands(Inst, 1);
7318 if (InsertAt.has_value())
7325ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7331 StringLoc = getLoc();
7336ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7337 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7342 SMLoc StringLoc = getLoc();
7346 Value = getTokenStr();
7350 if (
Value == Ids[IntVal])
7355 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7356 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7361ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7362 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7363 AMDGPUOperand::ImmTy
Type) {
7367 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7369 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7378bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7382 SMLoc Loc = getLoc();
7384 auto Res = parseIntWithPrefix(Pref, Val);
7390 if (Val < 0 || Val > MaxVal) {
7391 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7399ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7400 AMDGPUOperand::ImmTy ImmTy) {
7401 const char *Pref =
"index_key";
7403 SMLoc Loc = getLoc();
7404 auto Res = parseIntWithPrefix(Pref, ImmVal);
7408 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7409 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7410 (ImmVal < 0 || ImmVal > 1))
7411 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7413 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7414 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7416 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7420ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7421 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7424ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7425 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7428ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7429 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7432ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7434 AMDGPUOperand::ImmTy
Type) {
7439ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7440 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7441 AMDGPUOperand::ImmTyMatrixAFMT);
7444ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7445 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7446 AMDGPUOperand::ImmTyMatrixBFMT);
7449ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7451 AMDGPUOperand::ImmTy
Type) {
7456ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7457 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7458 AMDGPUOperand::ImmTyMatrixAScale);
7461ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7462 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7463 AMDGPUOperand::ImmTyMatrixBScale);
7466ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7468 AMDGPUOperand::ImmTy
Type) {
7473ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7474 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7475 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7478ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7479 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7480 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7485ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7486 using namespace llvm::AMDGPU::MTBUFFormat;
7492 for (
int I = 0;
I < 2; ++
I) {
7493 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7496 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7501 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7507 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7510 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7511 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7517ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7518 using namespace llvm::AMDGPU::MTBUFFormat;
7522 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7525 if (Fmt == UFMT_UNDEF)
7532bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7534 StringRef FormatStr,
7536 using namespace llvm::AMDGPU::MTBUFFormat;
7540 if (
Format != DFMT_UNDEF) {
7546 if (
Format != NFMT_UNDEF) {
7551 Error(Loc,
"unsupported format");
7555ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7558 using namespace llvm::AMDGPU::MTBUFFormat;
7562 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7567 SMLoc Loc = getLoc();
7568 if (!parseId(Str,
"expected a format string") ||
7569 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7571 if (Dfmt == DFMT_UNDEF)
7572 return Error(Loc,
"duplicate numeric format");
7573 if (Nfmt == NFMT_UNDEF)
7574 return Error(Loc,
"duplicate data format");
7577 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7578 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7582 if (Ufmt == UFMT_UNDEF)
7583 return Error(FormatLoc,
"unsupported format");
7592ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7595 using namespace llvm::AMDGPU::MTBUFFormat;
7598 if (Id == UFMT_UNDEF)
7602 return Error(Loc,
"unified format is not supported on this GPU");
7608ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7609 using namespace llvm::AMDGPU::MTBUFFormat;
7610 SMLoc Loc = getLoc();
7615 return Error(Loc,
"out of range format");
7620ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7621 using namespace llvm::AMDGPU::MTBUFFormat;
7627 StringRef FormatStr;
7628 SMLoc Loc = getLoc();
7629 if (!parseId(FormatStr,
"expected a format string"))
7632 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7634 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7644 return parseNumericFormat(
Format);
7647ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7648 using namespace llvm::AMDGPU::MTBUFFormat;
7652 SMLoc Loc = getLoc();
7662 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7674 Res = parseRegOrImm(Operands);
7681 Res = parseSymbolicOrNumericFormat(
Format);
7686 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7687 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7694 return Error(getLoc(),
"duplicate format");
7698ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7700 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7702 Res = parseIntWithPrefix(
"inst_offset", Operands,
7703 AMDGPUOperand::ImmTyInstOffset);
7708ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7710 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7712 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7716ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7718 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7721 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7730void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7731 OptionalImmIndexMap OptionalIdx;
7733 unsigned OperandIdx[4];
7734 unsigned EnMask = 0;
7737 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7738 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7743 OperandIdx[SrcIdx] = Inst.
size();
7744 Op.addRegOperands(Inst, 1);
7751 OperandIdx[SrcIdx] = Inst.
size();
7757 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7758 Op.addImmOperands(Inst, 1);
7762 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7766 OptionalIdx[
Op.getImmTy()] = i;
7772 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7779 for (
auto i = 0; i < SrcIdx; ++i) {
7781 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7806 IntVal =
encode(ISA, IntVal, CntVal);
7807 if (CntVal !=
decode(ISA, IntVal)) {
7809 IntVal =
encode(ISA, IntVal, -1);
7817bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7819 SMLoc CntLoc = getLoc();
7820 StringRef CntName = getTokenStr();
7827 SMLoc ValLoc = getLoc();
7836 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7838 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7840 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7843 Error(CntLoc,
"invalid counter name " + CntName);
7848 Error(ValLoc,
"too large value for " + CntName);
7857 Error(getLoc(),
"expected a counter name");
7865ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7872 if (!parseCnt(Waitcnt))
7880 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7884bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7885 SMLoc FieldLoc = getLoc();
7886 StringRef FieldName = getTokenStr();
7891 SMLoc ValueLoc = getLoc();
7898 if (FieldName ==
"instid0") {
7900 }
else if (FieldName ==
"instskip") {
7902 }
else if (FieldName ==
"instid1") {
7905 Error(FieldLoc,
"invalid field name " + FieldName);
7924 .Case(
"VALU_DEP_1", 1)
7925 .Case(
"VALU_DEP_2", 2)
7926 .Case(
"VALU_DEP_3", 3)
7927 .Case(
"VALU_DEP_4", 4)
7928 .Case(
"TRANS32_DEP_1", 5)
7929 .Case(
"TRANS32_DEP_2", 6)
7930 .Case(
"TRANS32_DEP_3", 7)
7931 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7932 .Case(
"SALU_CYCLE_1", 9)
7933 .Case(
"SALU_CYCLE_2", 10)
7934 .Case(
"SALU_CYCLE_3", 11)
7942 Delay |=
Value << Shift;
7946ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7952 if (!parseDelay(Delay))
7960 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7965AMDGPUOperand::isSWaitCnt()
const {
7969bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7975void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7976 StringRef DepCtrName) {
7979 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7982 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7985 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7988 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7995bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7997 using namespace llvm::AMDGPU::DepCtr;
7999 SMLoc DepCtrLoc = getLoc();
8000 StringRef DepCtrName = getTokenStr();
8010 unsigned PrevOprMask = UsedOprMask;
8011 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8014 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8023 Error(getLoc(),
"expected a counter name");
8028 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
8029 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8033ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
8034 using namespace llvm::AMDGPU::DepCtr;
8037 SMLoc Loc = getLoc();
8040 unsigned UsedOprMask = 0;
8042 if (!parseDepCtr(DepCtr, UsedOprMask))
8050 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8054bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8060ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8062 OperandInfoTy &Width) {
8063 using namespace llvm::AMDGPU::Hwreg;
8069 HwReg.Loc = getLoc();
8072 HwReg.IsSymbolic =
true;
8074 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8082 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8092 Width.Loc = getLoc();
8100ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8101 using namespace llvm::AMDGPU::Hwreg;
8104 SMLoc Loc = getLoc();
8106 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8108 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8109 HwregOffset::Default);
8110 struct : StructuredOpField {
8111 using StructuredOpField::StructuredOpField;
8112 bool validate(AMDGPUAsmParser &Parser)
const override {
8114 return Error(Parser,
"only values from 1 to 32 are legal");
8117 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8118 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8121 Res = parseHwregFunc(HwReg,
Offset, Width);
8124 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8126 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8130 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8137 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8139 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8143bool AMDGPUOperand::isHwreg()
const {
8144 return isImmTy(ImmTyHwreg);
8152AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8154 OperandInfoTy &Stream) {
8155 using namespace llvm::AMDGPU::SendMsg;
8160 Msg.IsSymbolic =
true;
8162 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8167 Op.IsDefined =
true;
8170 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8173 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8178 Stream.IsDefined =
true;
8179 Stream.Loc = getLoc();
8189AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8190 const OperandInfoTy &
Op,
8191 const OperandInfoTy &Stream) {
8192 using namespace llvm::AMDGPU::SendMsg;
8197 bool Strict = Msg.IsSymbolic;
8201 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8206 Error(Msg.Loc,
"invalid message id");
8212 Error(
Op.Loc,
"message does not support operations");
8214 Error(Msg.Loc,
"missing message operation");
8220 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8222 Error(
Op.Loc,
"invalid operation id");
8227 Error(Stream.Loc,
"message operation does not support streams");
8231 Error(Stream.Loc,
"invalid message stream id");
8237ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8238 using namespace llvm::AMDGPU::SendMsg;
8241 SMLoc Loc = getLoc();
8245 OperandInfoTy
Op(OP_NONE_);
8246 OperandInfoTy Stream(STREAM_ID_NONE_);
8247 if (parseSendMsgBody(Msg,
Op, Stream) &&
8248 validateSendMsg(Msg,
Op, Stream)) {
8253 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8255 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8260 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8264bool AMDGPUOperand::isSendMsg()
const {
8265 return isImmTy(ImmTySendMsg);
8268ParseStatus AMDGPUAsmParser::parseWaitEvent(
OperandVector &Operands) {
8269 using namespace llvm::AMDGPU::WaitEvent;
8271 SMLoc Loc = getLoc();
8274 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8276 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8278 StructuredOpField *TargetBitfield =
8279 isGFX11() ? &DontWaitExportReady : &ExportReady;
8281 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8285 if (!validateStructuredOpFields({TargetBitfield}))
8287 ImmVal = TargetBitfield->Val;
8294 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8296 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8297 AMDGPUOperand::ImmTyWaitEvent));
8301bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8307ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8314 int Slot = StringSwitch<int>(Str)
8321 return Error(S,
"invalid interpolation slot");
8323 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8324 AMDGPUOperand::ImmTyInterpSlot));
8328ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8335 if (!Str.starts_with(
"attr"))
8336 return Error(S,
"invalid interpolation attribute");
8338 StringRef Chan = Str.take_back(2);
8339 int AttrChan = StringSwitch<int>(Chan)
8346 return Error(S,
"invalid or missing interpolation attribute channel");
8348 Str = Str.drop_back(2).drop_front(4);
8351 if (Str.getAsInteger(10, Attr))
8352 return Error(S,
"invalid or missing interpolation attribute number");
8355 return Error(S,
"out of bounds interpolation attribute number");
8359 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8360 AMDGPUOperand::ImmTyInterpAttr));
8361 Operands.
push_back(AMDGPUOperand::CreateImm(
8362 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8370ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8371 using namespace llvm::AMDGPU::Exp;
8381 return Error(S, (Id == ET_INVALID)
8382 ?
"invalid exp target"
8383 :
"exp target is not supported on this GPU");
8385 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8386 AMDGPUOperand::ImmTyExpTgt));
8395AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8400AMDGPUAsmParser::isId(
const StringRef Id)
const {
8406 return getTokenKind() ==
Kind;
8409StringRef AMDGPUAsmParser::getId()
const {
8414AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8423AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8425 StringRef Tok = getTokenStr();
8436 if (isId(Id) && peekToken().is(Kind)) {
8446 if (isToken(Kind)) {
8455 const StringRef ErrMsg) {
8456 if (!trySkipToken(Kind)) {
8457 Error(getLoc(), ErrMsg);
8464AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8468 if (Parser.parseExpression(Expr))
8471 if (Expr->evaluateAsAbsolute(
Imm))
8474 if (Expected.empty()) {
8475 Error(S,
"expected absolute expression");
8477 Error(S, Twine(
"expected ", Expected) +
8478 Twine(
" or an absolute expression"));
8488 if (Parser.parseExpression(Expr))
8492 if (Expr->evaluateAsAbsolute(IntVal)) {
8493 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8495 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8501AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8503 Val =
getToken().getStringContents();
8507 Error(getLoc(), ErrMsg);
8512AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8514 Val = getTokenStr();
8518 if (!ErrMsg.
empty())
8519 Error(getLoc(), ErrMsg);
8524AMDGPUAsmParser::getToken()
const {
8525 return Parser.getTok();
8528AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8531 : getLexer().peekTok(ShouldSkipSpace);
8536 auto TokCount = getLexer().peekTokens(Tokens);
8538 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8543AMDGPUAsmParser::getTokenKind()
const {
8544 return getLexer().getKind();
8548AMDGPUAsmParser::getLoc()
const {
8553AMDGPUAsmParser::getTokenStr()
const {
8558AMDGPUAsmParser::lex() {
8562SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8563 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8567SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8571SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8572 int MCOpIdx)
const {
8573 for (
const auto &
Op : Operands) {
8574 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8575 if (TargetOp.getMCOpIdx() == MCOpIdx)
8576 return TargetOp.getStartLoc();
8582AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8584 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8585 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8587 return Op.getStartLoc();
8589 return getInstLoc(Operands);
8593AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8595 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8596 return getOperandLoc(
Test, Operands);
8610 StringRef
Id = getTokenStr();
8611 SMLoc IdLoc = getLoc();
8617 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8618 if (
I == Fields.
end())
8619 return Error(IdLoc,
"unknown field");
8620 if ((*I)->IsDefined)
8621 return Error(IdLoc,
"duplicate field");
8624 (*I)->Loc = getLoc();
8627 (*I)->IsDefined =
true;
8634bool AMDGPUAsmParser::validateStructuredOpFields(
8636 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8637 return F->validate(*
this);
8648 const unsigned OrMask,
8649 const unsigned XorMask) {
8658bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8659 const unsigned MaxVal,
8660 const Twine &ErrMsg, SMLoc &Loc) {
8677AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8678 const unsigned MinVal,
8679 const unsigned MaxVal,
8680 const StringRef ErrMsg) {
8682 for (
unsigned i = 0; i < OpNum; ++i) {
8683 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8691AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8692 using namespace llvm::AMDGPU::Swizzle;
8695 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8696 "expected a 2-bit lane id")) {
8707AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8708 using namespace llvm::AMDGPU::Swizzle;
8714 if (!parseSwizzleOperand(GroupSize,
8716 "group size must be in the interval [2,32]",
8721 Error(Loc,
"group size must be a power of two");
8724 if (parseSwizzleOperand(LaneIdx,
8726 "lane id must be in the interval [0,group size - 1]",
8735AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8736 using namespace llvm::AMDGPU::Swizzle;
8741 if (!parseSwizzleOperand(GroupSize,
8743 "group size must be in the interval [2,32]",
8748 Error(Loc,
"group size must be a power of two");
8757AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8758 using namespace llvm::AMDGPU::Swizzle;
8763 if (!parseSwizzleOperand(GroupSize,
8765 "group size must be in the interval [1,16]",
8770 Error(Loc,
"group size must be a power of two");
8779AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8780 using namespace llvm::AMDGPU::Swizzle;
8787 SMLoc StrLoc = getLoc();
8788 if (!parseString(Ctl)) {
8791 if (Ctl.
size() != BITMASK_WIDTH) {
8792 Error(StrLoc,
"expected a 5-character mask");
8796 unsigned AndMask = 0;
8797 unsigned OrMask = 0;
8798 unsigned XorMask = 0;
8800 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8804 Error(StrLoc,
"invalid mask");
8825bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8826 using namespace llvm::AMDGPU::Swizzle;
8829 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8835 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8836 "FFT swizzle must be in the interval [0," +
8837 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8845bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8846 using namespace llvm::AMDGPU::Swizzle;
8849 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8856 if (!parseSwizzleOperand(
Direction, 0, 1,
8857 "direction must be 0 (left) or 1 (right)", Loc))
8861 if (!parseSwizzleOperand(
8862 RotateSize, 0, ROTATE_MAX_SIZE,
8863 "number of threads to rotate must be in the interval [0," +
8864 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8869 (RotateSize << ROTATE_SIZE_SHIFT);
8874AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8876 SMLoc OffsetLoc = getLoc();
8882 Error(OffsetLoc,
"expected a 16-bit offset");
8889AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8890 using namespace llvm::AMDGPU::Swizzle;
8894 SMLoc ModeLoc = getLoc();
8897 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8898 Ok = parseSwizzleQuadPerm(
Imm);
8899 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8900 Ok = parseSwizzleBitmaskPerm(
Imm);
8901 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8902 Ok = parseSwizzleBroadcast(
Imm);
8903 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8904 Ok = parseSwizzleSwap(
Imm);
8905 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8906 Ok = parseSwizzleReverse(
Imm);
8907 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8908 Ok = parseSwizzleFFT(
Imm);
8909 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8910 Ok = parseSwizzleRotate(
Imm);
8912 Error(ModeLoc,
"expected a swizzle mode");
8915 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8921ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8925 if (trySkipId(
"offset")) {
8929 if (trySkipId(
"swizzle")) {
8930 Ok = parseSwizzleMacro(
Imm);
8932 Ok = parseSwizzleOffset(
Imm);
8936 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8944AMDGPUOperand::isSwizzle()
const {
8945 return isImmTy(ImmTySwizzle);
8952int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8954 using namespace llvm::AMDGPU::VGPRIndexMode;
8966 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8967 if (trySkipId(IdSymbolic[ModeId])) {
8975 "expected a VGPR index mode or a closing parenthesis" :
8976 "expected a VGPR index mode");
8981 Error(S,
"duplicate VGPR index mode");
8989 "expected a comma or a closing parenthesis"))
8996ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8998 using namespace llvm::AMDGPU::VGPRIndexMode;
9004 Imm = parseGPRIdxMacro();
9008 if (getParser().parseAbsoluteExpression(
Imm))
9011 return Error(S,
"invalid immediate: only 4-bit values are legal");
9015 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9019bool AMDGPUOperand::isGPRIdxMode()
const {
9020 return isImmTy(ImmTyGprIdxMode);
9027ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
9032 if (isRegister() || isModifier())
9038 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
9039 assert(Opr.isImm() || Opr.isExpr());
9040 SMLoc Loc = Opr.getStartLoc();
9044 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9045 Error(Loc,
"expected an absolute expression or a label");
9046 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9047 Error(Loc,
"expected a 16-bit signed jump offset");
9057ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
9058 return parseReg(Operands);
9065void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
9068 OptionalImmIndexMap OptionalIdx;
9069 unsigned FirstOperandIdx = 1;
9070 bool IsAtomicReturn =
false;
9077 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9078 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9082 Op.addRegOperands(Inst, 1);
9086 if (IsAtomicReturn && i == FirstOperandIdx)
9087 Op.addRegOperands(Inst, 1);
9092 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9093 Op.addImmOperands(Inst, 1);
9105 OptionalIdx[
Op.getImmTy()] = i;
9119bool AMDGPUOperand::isSMRDOffset8()
const {
9123bool AMDGPUOperand::isSMEMOffset()
const {
9125 return isImmLiteral();
9128bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9163bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9164 if (BoundCtrl == 0 || BoundCtrl == 1) {
9172void AMDGPUAsmParser::onBeginOfFile() {
9173 if (!getParser().getStreamer().getTargetStreamer() ||
9177 if (!getTargetStreamer().getTargetID())
9178 getTargetStreamer().initializeTargetID(getSTI(),
9179 getSTI().getFeatureString());
9182 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9190bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9194 StringRef TokenId = getTokenStr();
9195 AGVK VK = StringSwitch<AGVK>(TokenId)
9196 .Case(
"max", AGVK::AGVK_Max)
9197 .Case(
"or", AGVK::AGVK_Or)
9198 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9199 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9200 .Case(
"alignto", AGVK::AGVK_AlignTo)
9201 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9202 .Default(AGVK::AGVK_None);
9206 uint64_t CommaCount = 0;
9211 if (Exprs.
empty()) {
9213 "empty " + Twine(TokenId) +
" expression");
9216 if (CommaCount + 1 != Exprs.
size()) {
9218 "mismatch of commas in " + Twine(TokenId) +
" expression");
9225 if (getParser().parseExpression(Expr, EndLoc))
9229 if (LastTokenWasComma)
9233 "unexpected token in " + Twine(TokenId) +
" expression");
9239 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9242ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9243 StringRef
Name = getTokenStr();
9244 if (Name ==
"mul") {
9245 return parseIntWithPrefix(
"mul", Operands,
9249 if (Name ==
"div") {
9250 return parseIntWithPrefix(
"div", Operands,
9261 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9266 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9267 AMDGPU::OpName::src2};
9275 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9280 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9282 if (
DstOp.isReg() &&
9287 if ((OpSel & (1 << SrcNum)) != 0)
9293void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9295 cvtVOP3P(Inst, Operands);
9299void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9300 OptionalImmIndexMap &OptionalIdx) {
9301 cvtVOP3P(Inst, Operands, OptionalIdx);
9310 &&
Desc.NumOperands > (OpNum + 1)
9312 &&
Desc.operands()[OpNum + 1].RegClass != -1
9314 &&
Desc.getOperandConstraint(OpNum + 1,
9318void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9320 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9321 AMDGPU::OpName::src2};
9322 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9323 AMDGPU::OpName::src1_modifiers,
9324 AMDGPU::OpName::src2_modifiers};
9325 for (
int J = 0; J < 3; ++J) {
9326 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9332 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9335 if ((OpSel & (1 << J)) != 0)
9338 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9345void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9347 OptionalImmIndexMap OptionalIdx;
9352 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9353 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9356 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9357 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9359 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9360 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9361 Op.isInterpAttrChan()) {
9363 }
else if (
Op.isImmModifier()) {
9364 OptionalIdx[
Op.getImmTy()] =
I;
9372 AMDGPUOperand::ImmTyHigh);
9376 AMDGPUOperand::ImmTyClamp);
9380 AMDGPUOperand::ImmTyOModSI);
9385 AMDGPUOperand::ImmTyOpSel);
9386 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9389 cvtOpSelHelper(Inst, OpSel);
9393void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9395 OptionalImmIndexMap OptionalIdx;
9400 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9401 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9404 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9405 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9407 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9408 }
else if (
Op.isImmModifier()) {
9409 OptionalIdx[
Op.getImmTy()] =
I;
9417 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9427 cvtOpSelHelper(Inst, OpSel);
9430void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9432 OptionalImmIndexMap OptionalIdx;
9435 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9439 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9440 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9442 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9443 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9448 if (NumOperands == CbszOpIdx) {
9453 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9454 }
else if (
Op.isImmModifier()) {
9455 OptionalIdx[
Op.getImmTy()] =
I;
9457 Op.addRegOrImmOperands(Inst, 1);
9462 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9463 if (CbszIdx != OptionalIdx.end()) {
9464 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9468 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9469 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9470 if (BlgpIdx != OptionalIdx.end()) {
9471 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9482 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9483 if (OpselIdx != OptionalIdx.end()) {
9484 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9488 unsigned OpSelHi = 0;
9489 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9490 if (OpselHiIdx != OptionalIdx.end()) {
9491 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9494 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9495 AMDGPU::OpName::src1_modifiers};
9497 for (
unsigned J = 0; J < 2; ++J) {
9498 unsigned ModVal = 0;
9499 if (OpSel & (1 << J))
9501 if (OpSelHi & (1 << J))
9504 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9509void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9510 OptionalImmIndexMap &OptionalIdx) {
9515 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9516 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9519 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9520 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9522 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9523 }
else if (
Op.isImmModifier()) {
9524 OptionalIdx[
Op.getImmTy()] =
I;
9526 Op.addRegOrImmOperands(Inst, 1);
9532 AMDGPUOperand::ImmTyScaleSel);
9536 AMDGPUOperand::ImmTyClamp);
9542 AMDGPUOperand::ImmTyByteSel);
9547 AMDGPUOperand::ImmTyOModSI);
9554 auto *it = Inst.
begin();
9555 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9563void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9564 OptionalImmIndexMap OptionalIdx;
9565 cvtVOP3(Inst, Operands, OptionalIdx);
9568void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9569 OptionalImmIndexMap &OptIdx) {
9575 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9576 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9577 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9578 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9579 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9580 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9581 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9582 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9590 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx11 ||
9591 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx11 ||
9592 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx11 ||
9593 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx11 ||
9594 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx11 ||
9595 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx11 ||
9596 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx11 ||
9597 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx11 ||
9598 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx11 ||
9599 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx11 ||
9600 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx11 ||
9601 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx11 ||
9602 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9603 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9604 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9605 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9606 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9607 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9608 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9609 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9610 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9611 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9612 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9613 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9614 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9615 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9616 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9617 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9618 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9619 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9620 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9621 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9622 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9623 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9624 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9625 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9626 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9627 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9631 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9632 if (BitOp3Idx != -1) {
9639 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9640 if (OpSelIdx != -1) {
9644 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9645 if (OpSelHiIdx != -1) {
9646 int DefaultVal =
IsPacked ? -1 : 0;
9652 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9653 if (MatrixAFMTIdx != -1) {
9655 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9659 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9660 if (MatrixBFMTIdx != -1) {
9662 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9665 int MatrixAScaleIdx =
9666 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9667 if (MatrixAScaleIdx != -1) {
9669 AMDGPUOperand::ImmTyMatrixAScale, 0);
9672 int MatrixBScaleIdx =
9673 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9674 if (MatrixBScaleIdx != -1) {
9676 AMDGPUOperand::ImmTyMatrixBScale, 0);
9679 int MatrixAScaleFmtIdx =
9680 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9681 if (MatrixAScaleFmtIdx != -1) {
9683 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9686 int MatrixBScaleFmtIdx =
9687 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9688 if (MatrixBScaleFmtIdx != -1) {
9690 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9695 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9699 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9701 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9705 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9709 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9710 AMDGPU::OpName::src2};
9711 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9712 AMDGPU::OpName::src1_modifiers,
9713 AMDGPU::OpName::src2_modifiers};
9716 unsigned OpSelHi = 0;
9723 if (OpSelHiIdx != -1)
9732 for (
int J = 0; J < 3; ++J) {
9733 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9737 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9742 uint32_t ModVal = 0;
9745 if (SrcOp.
isReg() && getMRI()
9752 if ((OpSel & (1 << J)) != 0)
9756 if ((OpSelHi & (1 << J)) != 0)
9759 if ((NegLo & (1 << J)) != 0)
9762 if ((NegHi & (1 << J)) != 0)
9769void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9770 OptionalImmIndexMap OptIdx;
9771 cvtVOP3(Inst, Operands, OptIdx);
9772 cvtVOP3P(Inst, Operands, OptIdx);
9776 unsigned i,
unsigned Opc,
9778 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9779 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9781 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9784void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9787 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9790 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9791 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9793 OptionalImmIndexMap OptIdx;
9794 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9795 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9796 OptIdx[
Op.getImmTy()] = i;
9801 AMDGPUOperand::ImmTyIndexKey8bit);
9805 AMDGPUOperand::ImmTyIndexKey16bit);
9809 AMDGPUOperand::ImmTyIndexKey32bit);
9814 cvtVOP3P(Inst, Operands, OptIdx);
9821ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9829 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9830 SMLoc OpYLoc = getLoc();
9833 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9836 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9842void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9845 auto addOp = [&](uint16_t ParsedOprIdx) {
9846 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9848 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9852 Op.addRegOperands(Inst, 1);
9856 Op.addImmOperands(Inst, 1);
9868 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9872 const auto &CInfo = InstInfo[CompIdx];
9873 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9874 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9875 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9876 if (CInfo.hasSrc2Acc())
9877 addOp(CInfo.getIndexOfDstInParsedOperands());
9881 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9882 if (BitOp3Idx != -1) {
9883 OptionalImmIndexMap OptIdx;
9884 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9886 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9896bool AMDGPUOperand::isDPP8()
const {
9897 return isImmTy(ImmTyDPP8);
9900bool AMDGPUOperand::isDPPCtrl()
const {
9901 using namespace AMDGPU::DPP;
9903 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9906 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9907 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9908 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9909 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9910 (
Imm == DppCtrl::WAVE_SHL1) ||
9911 (
Imm == DppCtrl::WAVE_ROL1) ||
9912 (
Imm == DppCtrl::WAVE_SHR1) ||
9913 (
Imm == DppCtrl::WAVE_ROR1) ||
9914 (
Imm == DppCtrl::ROW_MIRROR) ||
9915 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9916 (
Imm == DppCtrl::BCAST15) ||
9917 (
Imm == DppCtrl::BCAST31) ||
9918 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9919 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9928bool AMDGPUOperand::isBLGP()
const {
9932bool AMDGPUOperand::isS16Imm()
const {
9936bool AMDGPUOperand::isU16Imm()
const {
9944bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9949 SMLoc Loc =
getToken().getEndLoc();
9950 Token = std::string(getTokenStr());
9952 if (getLoc() != Loc)
9957 if (!parseId(Suffix))
9961 StringRef DimId = Token;
9972ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9982 SMLoc Loc = getLoc();
9983 if (!parseDimId(Encoding))
9984 return Error(Loc,
"invalid dim value");
9986 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9987 AMDGPUOperand::ImmTyDim));
9995ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
10005 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10008 for (
size_t i = 0; i < 8; ++i) {
10012 SMLoc Loc = getLoc();
10013 if (getParser().parseAbsoluteExpression(Sels[i]))
10015 if (0 > Sels[i] || 7 < Sels[i])
10016 return Error(Loc,
"expected a 3-bit value");
10019 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10023 for (
size_t i = 0; i < 8; ++i)
10024 DPP8 |= (Sels[i] << (i * 3));
10026 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10031AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10033 if (Ctrl ==
"row_newbcast")
10036 if (Ctrl ==
"row_share" ||
10037 Ctrl ==
"row_xmask")
10040 if (Ctrl ==
"wave_shl" ||
10041 Ctrl ==
"wave_shr" ||
10042 Ctrl ==
"wave_rol" ||
10043 Ctrl ==
"wave_ror" ||
10044 Ctrl ==
"row_bcast")
10047 return Ctrl ==
"row_mirror" ||
10048 Ctrl ==
"row_half_mirror" ||
10049 Ctrl ==
"quad_perm" ||
10050 Ctrl ==
"row_shl" ||
10051 Ctrl ==
"row_shr" ||
10056AMDGPUAsmParser::parseDPPCtrlPerm() {
10059 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10063 for (
int i = 0; i < 4; ++i) {
10068 SMLoc Loc = getLoc();
10069 if (getParser().parseAbsoluteExpression(Temp))
10071 if (Temp < 0 || Temp > 3) {
10072 Error(Loc,
"expected a 2-bit value");
10076 Val += (Temp << i * 2);
10079 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10086AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10087 using namespace AMDGPU::DPP;
10092 SMLoc Loc = getLoc();
10094 if (getParser().parseAbsoluteExpression(Val))
10097 struct DppCtrlCheck {
10103 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10104 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10105 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10106 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10107 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10108 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10109 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10110 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10111 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10112 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10113 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10117 if (
Check.Ctrl == -1) {
10118 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10126 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10133ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10134 using namespace AMDGPU::DPP;
10137 !isSupportedDPPCtrl(getTokenStr(), Operands))
10140 SMLoc S = getLoc();
10146 if (Ctrl ==
"row_mirror") {
10147 Val = DppCtrl::ROW_MIRROR;
10148 }
else if (Ctrl ==
"row_half_mirror") {
10149 Val = DppCtrl::ROW_HALF_MIRROR;
10152 if (Ctrl ==
"quad_perm") {
10153 Val = parseDPPCtrlPerm();
10155 Val = parseDPPCtrlSel(Ctrl);
10164 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10168void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10170 OptionalImmIndexMap OptionalIdx;
10177 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10179 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10180 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10184 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10185 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10189 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10190 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10191 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10192 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10193 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10195 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10199 if (OldIdx == NumOperands) {
10201 constexpr int DST_IDX = 0;
10203 }
else if (Src2ModIdx == NumOperands) {
10213 if (IsVOP3CvtSrDpp) {
10222 if (TiedTo != -1) {
10227 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10229 if (IsDPP8 &&
Op.isDppFI()) {
10232 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10233 }
else if (
Op.isReg()) {
10234 Op.addRegOperands(Inst, 1);
10235 }
else if (
Op.isImm() &&
10237 Op.addImmOperands(Inst, 1);
10238 }
else if (
Op.isImm()) {
10239 OptionalIdx[
Op.getImmTy()] =
I;
10247 AMDGPUOperand::ImmTyClamp);
10253 AMDGPUOperand::ImmTyByteSel);
10260 cvtVOP3P(Inst, Operands, OptionalIdx);
10262 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10269 using namespace llvm::AMDGPU::DPP;
10279 AMDGPUOperand::ImmTyDppFI);
10283void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10284 OptionalImmIndexMap OptionalIdx;
10288 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10289 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10293 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10296 if (TiedTo != -1) {
10301 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10303 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10311 Op.addImmOperands(Inst, 1);
10313 Op.addRegWithFPInputModsOperands(Inst, 2);
10314 }
else if (
Op.isDppFI()) {
10316 }
else if (
Op.isReg()) {
10317 Op.addRegOperands(Inst, 1);
10323 Op.addRegWithFPInputModsOperands(Inst, 2);
10324 }
else if (
Op.isReg()) {
10325 Op.addRegOperands(Inst, 1);
10326 }
else if (
Op.isDPPCtrl()) {
10327 Op.addImmOperands(Inst, 1);
10328 }
else if (
Op.isImm()) {
10330 OptionalIdx[
Op.getImmTy()] =
I;
10338 using namespace llvm::AMDGPU::DPP;
10346 AMDGPUOperand::ImmTyDppFI);
10355ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10357 AMDGPUOperand::ImmTy
Type) {
10358 return parseStringOrIntWithPrefix(
10360 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10364ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10365 return parseStringOrIntWithPrefix(
10366 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10367 AMDGPUOperand::ImmTySDWADstUnused);
10370void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10374void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10378void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10382void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10386void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10390void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10391 uint64_t BasicInstType,
10394 using namespace llvm::AMDGPU::SDWA;
10396 OptionalImmIndexMap OptionalIdx;
10397 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10398 bool SkippedVcc =
false;
10402 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10403 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10406 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10407 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10408 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10409 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10427 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10428 }
else if (
Op.isImm()) {
10430 OptionalIdx[
Op.getImmTy()] =
I;
10434 SkippedVcc =
false;
10438 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10439 Opc != AMDGPU::V_NOP_sdwa_vi) {
10441 switch (BasicInstType) {
10445 AMDGPUOperand::ImmTyClamp, 0);
10449 AMDGPUOperand::ImmTyOModSI, 0);
10453 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10457 AMDGPUOperand::ImmTySDWADstUnused,
10458 DstUnused::UNUSED_PRESERVE);
10460 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10465 AMDGPUOperand::ImmTyClamp, 0);
10470 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10471 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10472 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10473 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10479 AMDGPUOperand::ImmTyClamp, 0);
10480 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10481 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10485 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10491 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10492 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10493 auto *it = Inst.
begin();
10495 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10507#define GET_MATCHER_IMPLEMENTATION
10508#define GET_MNEMONIC_SPELL_CHECKER
10509#define GET_MNEMONIC_CHECKER
10510#include "AMDGPUGenAsmMatcher.inc"
10516 return parseTokenOp(
"addr64",
Operands);
10518 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10520 return parseTokenOp(
"idxen",
Operands);
10522 return parseTokenOp(
"lds",
Operands);
10524 return parseTokenOp(
"offen",
Operands);
10526 return parseTokenOp(
"off",
Operands);
10527 case MCK_row_95_en:
10528 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10530 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10532 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10534 return tryCustomParseOperand(
Operands, MCK);
10539unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10545 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10548 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10550 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10552 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10554 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10556 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10558 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10560 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10561 case MCK_row_95_en:
10562 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10570 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10572 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10573 case MCK_SOPPBrTarget:
10574 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10575 case MCK_VReg32OrOff:
10576 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10577 case MCK_InterpSlot:
10578 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10579 case MCK_InterpAttr:
10580 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10581 case MCK_InterpAttrChan:
10582 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10584 case MCK_SReg_64_XEXEC:
10594 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10596 return Match_InvalidOperand;
10604ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10605 SMLoc S = getLoc();
10614 return Error(S,
"expected a 16-bit value");
10617 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10621bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10627bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, AMDGPU::OpName OpName)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static int IsAGPROperand(const MCInst &Inst, AMDGPU::OpName Name, const MCRegisterInfo *MRI)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
constexpr uint64_t MIMGFlags
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static bool IsRevOpcode(const unsigned Opcode)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static MCRegister getSpecialRegForName(StringRef RegName)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0, std::optional< unsigned > InsertAt=std::nullopt)
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(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.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static 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...
bool regsOverlap(MCRegister RegA, MCRegister RegB) const
Returns true if the two registers are equal or alias each other.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isVariable() const
isVariable - Check if this is a variable symbol.
LLVM_ABI void setVariableValue(const MCExpr *Value)
void setRedefinable(bool Value)
Mark this symbol as redefinable.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
uint64_t getScalarSizeInBits() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
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 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