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 (" +
5774 getSTI().
getCPU() +
")" +
": " + Mnemo);
5779 return Error(IDLoc,
"invalid instruction" + Suggestion);
5785 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5786 if (
Op.isToken() && InvalidOprIdx > 1) {
5787 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5788 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5793bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5796 uint64_t &ErrorInfo,
5797 bool MatchingInlineAsm) {
5800 unsigned Result = Match_Success;
5801 for (
auto Variant : getMatchedVariants()) {
5803 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5808 if (R == Match_Success || R == Match_MissingFeature ||
5809 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5810 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5811 Result != Match_MissingFeature)) {
5815 if (R == Match_Success)
5819 if (Result == Match_Success) {
5820 if (!validateInstruction(Inst, IDLoc, Operands)) {
5827 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5828 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5834 case Match_MissingFeature:
5838 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5840 case Match_InvalidOperand: {
5841 SMLoc ErrorLoc = IDLoc;
5842 if (ErrorInfo != ~0ULL) {
5843 if (ErrorInfo >= Operands.
size()) {
5844 return Error(IDLoc,
"too few operands for instruction");
5846 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5847 if (ErrorLoc == SMLoc())
5851 return Error(ErrorLoc,
"invalid VOPDY instruction");
5853 return Error(ErrorLoc,
"invalid operand for instruction");
5856 case Match_MnemonicFail:
5862bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5867 if (getParser().parseAbsoluteExpression(Tmp)) {
5870 Ret =
static_cast<uint32_t
>(Tmp);
5874bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5875 if (!getSTI().getTargetTriple().isAMDGCN())
5876 return TokError(
"directive only supported for amdgcn architecture");
5878 std::string TargetIDDirective;
5879 SMLoc TargetStart = getTok().getLoc();
5880 if (getParser().parseEscapedString(TargetIDDirective))
5883 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5884 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5885 return getParser().Error(TargetRange.
Start,
5886 (Twine(
".amdgcn_target directive's target id ") +
5887 Twine(TargetIDDirective) +
5888 Twine(
" does not match the specified target id ") +
5889 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5894bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5898bool AMDGPUAsmParser::calculateGPRBlocks(
5899 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5900 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5901 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5902 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5903 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5909 const MCExpr *
NumSGPRs = NextFreeSGPR;
5910 int64_t EvaluatedSGPRs;
5915 unsigned MaxAddressableNumSGPRs =
5918 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5919 !Features.
test(FeatureSGPRInitBug) &&
5920 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5921 return OutOfRangeError(SGPRRange);
5923 const MCExpr *ExtraSGPRs =
5927 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5928 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5929 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5930 return OutOfRangeError(SGPRRange);
5932 if (Features.
test(FeatureSGPRInitBug))
5939 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5940 unsigned Granule) ->
const MCExpr * {
5944 const MCExpr *AlignToGPR =
5946 const MCExpr *DivGPR =
5952 VGPRBlocks = GetNumGPRBlocks(
5961bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5962 if (!getSTI().getTargetTriple().isAMDGCN())
5963 return TokError(
"directive only supported for amdgcn architecture");
5966 return TokError(
"directive only supported for amdhsa OS");
5968 StringRef KernelName;
5969 if (getParser().parseIdentifier(KernelName))
5972 AMDGPU::MCKernelDescriptor KD =
5984 const MCExpr *NextFreeVGPR = ZeroExpr;
5986 const MCExpr *NamedBarCnt = ZeroExpr;
5987 uint64_t SharedVGPRCount = 0;
5988 uint64_t PreloadLength = 0;
5989 uint64_t PreloadOffset = 0;
5991 const MCExpr *NextFreeSGPR = ZeroExpr;
5994 unsigned ImpliedUserSGPRCount = 0;
5998 std::optional<unsigned> ExplicitUserSGPRCount;
5999 const MCExpr *ReserveVCC = OneExpr;
6000 const MCExpr *ReserveFlatScr = OneExpr;
6001 std::optional<bool> EnableWavefrontSize32;
6007 SMRange IDRange = getTok().getLocRange();
6008 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6011 if (
ID ==
".end_amdhsa_kernel")
6015 return TokError(
".amdhsa_ directives cannot be repeated");
6017 SMLoc ValStart = getLoc();
6018 const MCExpr *ExprVal;
6019 if (getParser().parseExpression(ExprVal))
6021 SMLoc ValEnd = getLoc();
6022 SMRange ValRange = SMRange(ValStart, ValEnd);
6025 uint64_t Val = IVal;
6026 bool EvaluatableExpr;
6027 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6029 return OutOfRangeError(ValRange);
6033#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6034 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6035 return OutOfRangeError(RANGE); \
6036 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6041#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6043 return Error(IDRange.Start, "directive should have resolvable expression", \
6046 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6049 return OutOfRangeError(ValRange);
6051 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6054 return OutOfRangeError(ValRange);
6056 }
else if (
ID ==
".amdhsa_kernarg_size") {
6058 return OutOfRangeError(ValRange);
6060 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6062 ExplicitUserSGPRCount = Val;
6063 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6067 "directive is not supported with architected flat scratch",
6070 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6073 ImpliedUserSGPRCount += 4;
6074 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6077 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6080 return OutOfRangeError(ValRange);
6084 ImpliedUserSGPRCount += Val;
6085 PreloadLength = Val;
6087 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6090 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6093 return OutOfRangeError(ValRange);
6097 PreloadOffset = Val;
6098 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6101 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6104 ImpliedUserSGPRCount += 2;
6105 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6108 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6111 ImpliedUserSGPRCount += 2;
6112 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6115 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6118 ImpliedUserSGPRCount += 2;
6119 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6122 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6125 ImpliedUserSGPRCount += 2;
6126 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6129 "directive is not supported with architected flat scratch",
6133 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6136 ImpliedUserSGPRCount += 2;
6137 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6140 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6143 ImpliedUserSGPRCount += 1;
6144 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6146 if (IVersion.
Major < 10)
6147 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6148 EnableWavefrontSize32 = Val;
6150 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6152 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6154 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6156 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6159 "directive is not supported with architected flat scratch",
6162 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6164 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6168 "directive is not supported without architected flat scratch",
6171 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6173 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6175 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6177 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6179 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6181 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6183 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6185 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6187 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6189 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6191 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6193 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6194 VGPRRange = ValRange;
6195 NextFreeVGPR = ExprVal;
6196 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6197 SGPRRange = ValRange;
6198 NextFreeSGPR = ExprVal;
6199 }
else if (
ID ==
".amdhsa_accum_offset") {
6201 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6202 AccumOffset = ExprVal;
6203 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6205 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6206 NamedBarCnt = ExprVal;
6207 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6209 return OutOfRangeError(ValRange);
6210 ReserveVCC = ExprVal;
6211 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6212 if (IVersion.
Major < 7)
6213 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6216 "directive is not supported with architected flat scratch",
6219 return OutOfRangeError(ValRange);
6220 ReserveFlatScr = ExprVal;
6221 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6222 if (IVersion.
Major < 8)
6223 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6225 return OutOfRangeError(ValRange);
6226 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6227 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6229 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6231 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6233 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6235 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6237 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6239 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6241 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6243 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6245 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6246 if (!getSTI().hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6247 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6250 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6252 }
else if (
ID ==
".amdhsa_ieee_mode") {
6253 if (!getSTI().hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6254 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6257 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6259 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6260 if (IVersion.
Major < 9)
6261 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6263 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6265 }
else if (
ID ==
".amdhsa_tg_split") {
6267 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6270 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6273 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6275 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6277 }
else if (
ID ==
".amdhsa_memory_ordered") {
6278 if (IVersion.
Major < 10)
6279 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6281 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6283 }
else if (
ID ==
".amdhsa_forward_progress") {
6284 if (IVersion.
Major < 10)
6285 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6287 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6289 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6291 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6292 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6294 SharedVGPRCount = Val;
6296 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6298 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6299 if (IVersion.
Major < 11)
6300 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6301 if (IVersion.
Major == 11) {
6303 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6307 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6310 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6313 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6315 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6317 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6319 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6322 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6324 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6326 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6328 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6330 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6332 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6334 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6336 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6338 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6340 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6341 if (IVersion.
Major < 12)
6342 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6344 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6347 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6350#undef PARSE_BITS_ENTRY
6353 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6354 return TokError(
".amdhsa_next_free_vgpr directive is required");
6356 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6357 return TokError(
".amdhsa_next_free_sgpr directive is required");
6359 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6364 if (PreloadLength) {
6370 const MCExpr *VGPRBlocks;
6371 const MCExpr *SGPRBlocks;
6372 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6373 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6374 EnableWavefrontSize32, NextFreeVGPR,
6375 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6379 int64_t EvaluatedVGPRBlocks;
6380 bool VGPRBlocksEvaluatable =
6381 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6382 if (VGPRBlocksEvaluatable &&
6384 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6385 return OutOfRangeError(VGPRRange);
6389 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6390 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6392 int64_t EvaluatedSGPRBlocks;
6393 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6395 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6396 return OutOfRangeError(SGPRRange);
6399 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6400 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6402 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6403 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6404 "enabled user SGPRs");
6408 return TokError(
"too many user SGPRs enabled");
6412 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6413 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6417 return TokError(
"too many user SGPRs enabled");
6421 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6422 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6427 return TokError(
"Kernarg size should be resolvable");
6428 uint64_t kernarg_size = IVal;
6429 if (PreloadLength && kernarg_size &&
6430 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6431 return TokError(
"Kernarg preload length + offset is larger than the "
6432 "kernarg segment size");
6435 if (!Seen.
contains(
".amdhsa_accum_offset"))
6436 return TokError(
".amdhsa_accum_offset directive is required");
6437 int64_t EvaluatedAccum;
6438 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6439 uint64_t UEvaluatedAccum = EvaluatedAccum;
6440 if (AccumEvaluatable &&
6441 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6442 return TokError(
"accum_offset should be in range [4..256] in "
6445 int64_t EvaluatedNumVGPR;
6446 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6449 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6450 return TokError(
"accum_offset exceeds total VGPR allocation");
6456 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6457 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6463 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6464 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6467 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6469 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6470 return TokError(
"shared_vgpr_count directive not valid on "
6471 "wavefront size 32");
6474 if (VGPRBlocksEvaluatable &&
6475 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6477 return TokError(
"shared_vgpr_count*2 + "
6478 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6483 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6484 NextFreeVGPR, NextFreeSGPR,
6485 ReserveVCC, ReserveFlatScr);
6489bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6491 if (ParseAsAbsoluteExpression(
Version))
6494 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6498bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6499 AMDGPUMCKernelCodeT &
C) {
6502 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6503 Parser.eatToEndOfStatement();
6507 SmallString<40> ErrStr;
6508 raw_svector_ostream Err(ErrStr);
6509 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6510 return TokError(Err.
str());
6514 if (
ID ==
"enable_wavefront_size32") {
6517 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6519 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6522 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6526 if (
ID ==
"wavefront_size") {
6527 if (
C.wavefront_size == 5) {
6529 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6531 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6532 }
else if (
C.wavefront_size == 6) {
6534 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6541bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6542 AMDGPUMCKernelCodeT KernelCode;
6551 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6554 if (
ID ==
".end_amd_kernel_code_t")
6557 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6562 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6567bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6568 StringRef KernelName;
6569 if (!parseId(KernelName,
"expected symbol name"))
6572 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6579bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6580 if (!getSTI().getTargetTriple().isAMDGCN()) {
6581 return Error(getLoc(),
6582 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6586 auto TargetIDDirective = getLexer().getTok().getStringContents();
6587 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6588 return Error(getParser().getTok().getLoc(),
"target id must match options");
6590 getTargetStreamer().EmitISAVersion();
6596bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6599 std::string HSAMetadataString;
6604 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6605 return Error(getLoc(),
"invalid HSA metadata");
6612bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6613 const char *AssemblerDirectiveEnd,
6614 std::string &CollectString) {
6616 raw_string_ostream CollectStream(CollectString);
6618 getLexer().setSkipSpace(
false);
6620 bool FoundEnd =
false;
6623 CollectStream << getTokenStr();
6627 if (trySkipId(AssemblerDirectiveEnd)) {
6632 CollectStream << Parser.parseStringToEndOfStatement()
6633 <<
getContext().getAsmInfo()->getSeparatorString();
6635 Parser.eatToEndOfStatement();
6638 getLexer().setSkipSpace(
true);
6641 return TokError(Twine(
"expected directive ") +
6642 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6649bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6655 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6656 if (!PALMetadata->setFromString(
String))
6657 return Error(getLoc(),
"invalid PAL metadata");
6662bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6664 return Error(getLoc(),
6666 "not available on non-amdpal OSes")).str());
6669 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6670 PALMetadata->setLegacy();
6673 if (ParseAsAbsoluteExpression(
Key)) {
6674 return TokError(Twine(
"invalid value in ") +
6678 return TokError(Twine(
"expected an even number of values in ") +
6681 if (ParseAsAbsoluteExpression(
Value)) {
6682 return TokError(Twine(
"invalid value in ") +
6685 PALMetadata->setRegister(
Key,
Value);
6694bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6695 if (getParser().checkForValidSection())
6699 SMLoc NameLoc = getLoc();
6700 if (getParser().parseIdentifier(Name))
6701 return TokError(
"expected identifier in directive");
6704 if (getParser().parseComma())
6710 SMLoc SizeLoc = getLoc();
6711 if (getParser().parseAbsoluteExpression(
Size))
6714 return Error(SizeLoc,
"size must be non-negative");
6715 if (
Size > LocalMemorySize)
6716 return Error(SizeLoc,
"size is too large");
6718 int64_t Alignment = 4;
6720 SMLoc AlignLoc = getLoc();
6721 if (getParser().parseAbsoluteExpression(Alignment))
6724 return Error(AlignLoc,
"alignment must be a power of two");
6729 if (Alignment >= 1u << 31)
6730 return Error(AlignLoc,
"alignment is too large");
6736 Symbol->redefineIfPossible();
6737 if (!
Symbol->isUndefined())
6738 return Error(NameLoc,
"invalid symbol redefinition");
6740 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6744bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6745 StringRef IDVal = DirectiveID.
getString();
6748 if (IDVal ==
".amdhsa_kernel")
6749 return ParseDirectiveAMDHSAKernel();
6751 if (IDVal ==
".amdhsa_code_object_version")
6752 return ParseDirectiveAMDHSACodeObjectVersion();
6756 return ParseDirectiveHSAMetadata();
6758 if (IDVal ==
".amd_kernel_code_t")
6759 return ParseDirectiveAMDKernelCodeT();
6761 if (IDVal ==
".amdgpu_hsa_kernel")
6762 return ParseDirectiveAMDGPUHsaKernel();
6764 if (IDVal ==
".amd_amdgpu_isa")
6765 return ParseDirectiveISAVersion();
6769 Twine(
" directive is "
6770 "not available on non-amdhsa OSes"))
6775 if (IDVal ==
".amdgcn_target")
6776 return ParseDirectiveAMDGCNTarget();
6778 if (IDVal ==
".amdgpu_lds")
6779 return ParseDirectiveAMDGPULDS();
6782 return ParseDirectivePALMetadataBegin();
6785 return ParseDirectivePALMetadata();
6790bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &MRI,
6797 return hasSGPR104_SGPR105();
6800 case SRC_SHARED_BASE_LO:
6801 case SRC_SHARED_BASE:
6802 case SRC_SHARED_LIMIT_LO:
6803 case SRC_SHARED_LIMIT:
6804 case SRC_PRIVATE_BASE_LO:
6805 case SRC_PRIVATE_BASE:
6806 case SRC_PRIVATE_LIMIT_LO:
6807 case SRC_PRIVATE_LIMIT:
6809 case SRC_FLAT_SCRATCH_BASE_LO:
6810 case SRC_FLAT_SCRATCH_BASE_HI:
6811 return hasGloballyAddressableScratch();
6812 case SRC_POPS_EXITING_WAVE_ID:
6824 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6854 return hasSGPR102_SGPR103();
6859ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6862 ParseStatus Res = parseVOPD(Operands);
6867 Res = MatchOperandParserImpl(Operands, Mnemonic);
6879 SMLoc LBraceLoc = getLoc();
6884 auto Loc = getLoc();
6885 Res = parseReg(Operands);
6887 Error(Loc,
"expected a register");
6891 RBraceLoc = getLoc();
6896 "expected a comma or a closing square bracket"))
6900 if (Operands.
size() - Prefix > 1) {
6902 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6903 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6909 return parseRegOrImm(Operands);
6912StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6914 setForcedEncodingSize(0);
6915 setForcedDPP(
false);
6916 setForcedSDWA(
false);
6918 if (
Name.consume_back(
"_e64_dpp")) {
6920 setForcedEncodingSize(64);
6923 if (
Name.consume_back(
"_e64")) {
6924 setForcedEncodingSize(64);
6927 if (
Name.consume_back(
"_e32")) {
6928 setForcedEncodingSize(32);
6931 if (
Name.consume_back(
"_dpp")) {
6935 if (
Name.consume_back(
"_sdwa")) {
6936 setForcedSDWA(
true);
6944 unsigned VariantID);
6950 Name = parseMnemonicSuffix(Name);
6956 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6958 bool IsMIMG = Name.starts_with(
"image_");
6961 OperandMode
Mode = OperandMode_Default;
6963 Mode = OperandMode_NSA;
6967 checkUnsupportedInstruction(Name, NameLoc);
6968 if (!Parser.hasPendingError()) {
6971 :
"not a valid operand.";
6972 Error(getLoc(), Msg);
6991ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6994 if (!trySkipId(Name))
6997 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
7001ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7010ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7011 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7012 std::function<
bool(int64_t &)> ConvertResult) {
7016 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7020 if (ConvertResult && !ConvertResult(
Value)) {
7021 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7024 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7028ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7029 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7030 bool (*ConvertResult)(int64_t &)) {
7039 const unsigned MaxSize = 4;
7043 for (
int I = 0; ; ++
I) {
7045 SMLoc Loc = getLoc();
7049 if (
Op != 0 &&
Op != 1)
7050 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7057 if (
I + 1 == MaxSize)
7058 return Error(getLoc(),
"expected a closing square bracket");
7064 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7068ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7070 AMDGPUOperand::ImmTy ImmTy,
7071 bool IgnoreNegative) {
7075 if (trySkipId(Name)) {
7077 }
else if (trySkipId(
"no", Name)) {
7086 return Error(S,
"r128 modifier is not supported on this GPU");
7087 if (Name ==
"a16" && !
hasA16())
7088 return Error(S,
"a16 modifier is not supported on this GPU");
7090 if (Bit == 0 && Name ==
"gds") {
7091 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7093 return Error(S,
"nogds is not allowed");
7096 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7097 ImmTy = AMDGPUOperand::ImmTyR128A16;
7099 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7103unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7104 bool &Disabling)
const {
7105 Disabling =
Id.consume_front(
"no");
7108 return StringSwitch<unsigned>(Id)
7115 return StringSwitch<unsigned>(Id)
7123ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7125 SMLoc StringLoc = getLoc();
7127 int64_t CPolVal = 0;
7136 ResTH = parseTH(Operands, TH);
7147 ResScope = parseScope(Operands, Scope);
7160 if (trySkipId(
"nv")) {
7164 }
else if (trySkipId(
"no",
"nv")) {
7171 if (trySkipId(
"scale_offset")) {
7175 }
else if (trySkipId(
"no",
"scale_offset")) {
7188 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7189 AMDGPUOperand::ImmTyCPol));
7193 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7194 SMLoc OpLoc = getLoc();
7195 unsigned Enabled = 0, Seen = 0;
7199 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7206 return Error(S,
"dlc modifier is not supported on this GPU");
7209 return Error(S,
"scc modifier is not supported on this GPU");
7212 return Error(S,
"duplicate cache policy modifier");
7224 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7228ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7233 ParseStatus Res = parseStringOrIntWithPrefix(
7234 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7243ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7248 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7252 if (
Value ==
"TH_DEFAULT")
7254 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7255 Value ==
"TH_LOAD_NT_WB") {
7256 return Error(StringLoc,
"invalid th value");
7257 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7259 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7261 }
else if (
Value.consume_front(
"TH_STORE_")) {
7264 return Error(StringLoc,
"invalid th value");
7267 if (
Value ==
"BYPASS")
7272 TH |= StringSwitch<int64_t>(
Value)
7282 .Default(0xffffffff);
7284 TH |= StringSwitch<int64_t>(
Value)
7295 .Default(0xffffffff);
7298 if (TH == 0xffffffff)
7299 return Error(StringLoc,
"invalid th value");
7306 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7307 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7308 std::optional<unsigned> InsertAt = std::nullopt) {
7309 auto i = OptionalIdx.find(ImmT);
7310 if (i != OptionalIdx.end()) {
7311 unsigned Idx = i->second;
7312 const AMDGPUOperand &
Op =
7313 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7317 Op.addImmOperands(Inst, 1);
7319 if (InsertAt.has_value())
7326ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7332 StringLoc = getLoc();
7337ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7338 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7343 SMLoc StringLoc = getLoc();
7347 Value = getTokenStr();
7351 if (
Value == Ids[IntVal])
7356 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7357 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7362ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7363 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7364 AMDGPUOperand::ImmTy
Type) {
7368 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7370 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7379bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7383 SMLoc Loc = getLoc();
7385 auto Res = parseIntWithPrefix(Pref, Val);
7391 if (Val < 0 || Val > MaxVal) {
7392 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7400ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7401 AMDGPUOperand::ImmTy ImmTy) {
7402 const char *Pref =
"index_key";
7404 SMLoc Loc = getLoc();
7405 auto Res = parseIntWithPrefix(Pref, ImmVal);
7409 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7410 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7411 (ImmVal < 0 || ImmVal > 1))
7412 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7414 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7415 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7417 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7421ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7422 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7425ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7426 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7429ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7430 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7433ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7435 AMDGPUOperand::ImmTy
Type) {
7440ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7441 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7442 AMDGPUOperand::ImmTyMatrixAFMT);
7445ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7446 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7447 AMDGPUOperand::ImmTyMatrixBFMT);
7450ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7452 AMDGPUOperand::ImmTy
Type) {
7457ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7458 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7459 AMDGPUOperand::ImmTyMatrixAScale);
7462ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7463 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7464 AMDGPUOperand::ImmTyMatrixBScale);
7467ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7469 AMDGPUOperand::ImmTy
Type) {
7474ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7475 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7476 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7479ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7480 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7481 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7486ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7487 using namespace llvm::AMDGPU::MTBUFFormat;
7493 for (
int I = 0;
I < 2; ++
I) {
7494 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7497 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7502 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7508 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7511 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7512 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7518ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7519 using namespace llvm::AMDGPU::MTBUFFormat;
7523 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7526 if (Fmt == UFMT_UNDEF)
7533bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7535 StringRef FormatStr,
7537 using namespace llvm::AMDGPU::MTBUFFormat;
7541 if (
Format != DFMT_UNDEF) {
7547 if (
Format != NFMT_UNDEF) {
7552 Error(Loc,
"unsupported format");
7556ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7559 using namespace llvm::AMDGPU::MTBUFFormat;
7563 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7568 SMLoc Loc = getLoc();
7569 if (!parseId(Str,
"expected a format string") ||
7570 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7572 if (Dfmt == DFMT_UNDEF)
7573 return Error(Loc,
"duplicate numeric format");
7574 if (Nfmt == NFMT_UNDEF)
7575 return Error(Loc,
"duplicate data format");
7578 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7579 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7583 if (Ufmt == UFMT_UNDEF)
7584 return Error(FormatLoc,
"unsupported format");
7593ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7596 using namespace llvm::AMDGPU::MTBUFFormat;
7599 if (Id == UFMT_UNDEF)
7603 return Error(Loc,
"unified format is not supported on this GPU");
7609ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7610 using namespace llvm::AMDGPU::MTBUFFormat;
7611 SMLoc Loc = getLoc();
7616 return Error(Loc,
"out of range format");
7621ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7622 using namespace llvm::AMDGPU::MTBUFFormat;
7628 StringRef FormatStr;
7629 SMLoc Loc = getLoc();
7630 if (!parseId(FormatStr,
"expected a format string"))
7633 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7635 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7645 return parseNumericFormat(
Format);
7648ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7649 using namespace llvm::AMDGPU::MTBUFFormat;
7653 SMLoc Loc = getLoc();
7663 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7675 Res = parseRegOrImm(Operands);
7682 Res = parseSymbolicOrNumericFormat(
Format);
7687 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7688 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7695 return Error(getLoc(),
"duplicate format");
7699ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7701 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7703 Res = parseIntWithPrefix(
"inst_offset", Operands,
7704 AMDGPUOperand::ImmTyInstOffset);
7709ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7711 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7713 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7717ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7719 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7722 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7731void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7732 OptionalImmIndexMap OptionalIdx;
7734 unsigned OperandIdx[4];
7735 unsigned EnMask = 0;
7738 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7739 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7744 OperandIdx[SrcIdx] = Inst.
size();
7745 Op.addRegOperands(Inst, 1);
7752 OperandIdx[SrcIdx] = Inst.
size();
7758 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7759 Op.addImmOperands(Inst, 1);
7763 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7767 OptionalIdx[
Op.getImmTy()] = i;
7773 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7780 for (
auto i = 0; i < SrcIdx; ++i) {
7782 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7807 IntVal =
encode(ISA, IntVal, CntVal);
7808 if (CntVal !=
decode(ISA, IntVal)) {
7810 IntVal =
encode(ISA, IntVal, -1);
7818bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7820 SMLoc CntLoc = getLoc();
7821 StringRef CntName = getTokenStr();
7828 SMLoc ValLoc = getLoc();
7837 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7839 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7841 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7844 Error(CntLoc,
"invalid counter name " + CntName);
7849 Error(ValLoc,
"too large value for " + CntName);
7858 Error(getLoc(),
"expected a counter name");
7866ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7873 if (!parseCnt(Waitcnt))
7881 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7885bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7886 SMLoc FieldLoc = getLoc();
7887 StringRef FieldName = getTokenStr();
7892 SMLoc ValueLoc = getLoc();
7899 if (FieldName ==
"instid0") {
7901 }
else if (FieldName ==
"instskip") {
7903 }
else if (FieldName ==
"instid1") {
7906 Error(FieldLoc,
"invalid field name " + FieldName);
7925 .Case(
"VALU_DEP_1", 1)
7926 .Case(
"VALU_DEP_2", 2)
7927 .Case(
"VALU_DEP_3", 3)
7928 .Case(
"VALU_DEP_4", 4)
7929 .Case(
"TRANS32_DEP_1", 5)
7930 .Case(
"TRANS32_DEP_2", 6)
7931 .Case(
"TRANS32_DEP_3", 7)
7932 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7933 .Case(
"SALU_CYCLE_1", 9)
7934 .Case(
"SALU_CYCLE_2", 10)
7935 .Case(
"SALU_CYCLE_3", 11)
7943 Delay |=
Value << Shift;
7947ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7953 if (!parseDelay(Delay))
7961 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7966AMDGPUOperand::isSWaitCnt()
const {
7970bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7976void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7977 StringRef DepCtrName) {
7980 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7983 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7986 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7989 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7996bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7998 using namespace llvm::AMDGPU::DepCtr;
8000 SMLoc DepCtrLoc = getLoc();
8001 StringRef DepCtrName = getTokenStr();
8011 unsigned PrevOprMask = UsedOprMask;
8012 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8015 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8024 Error(getLoc(),
"expected a counter name");
8029 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
8030 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8034ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
8035 using namespace llvm::AMDGPU::DepCtr;
8038 SMLoc Loc = getLoc();
8041 unsigned UsedOprMask = 0;
8043 if (!parseDepCtr(DepCtr, UsedOprMask))
8051 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8055bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8061ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8063 OperandInfoTy &Width) {
8064 using namespace llvm::AMDGPU::Hwreg;
8070 HwReg.Loc = getLoc();
8073 HwReg.IsSymbolic =
true;
8075 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8083 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8093 Width.Loc = getLoc();
8101ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8102 using namespace llvm::AMDGPU::Hwreg;
8105 SMLoc Loc = getLoc();
8107 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8109 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8110 HwregOffset::Default);
8111 struct : StructuredOpField {
8112 using StructuredOpField::StructuredOpField;
8113 bool validate(AMDGPUAsmParser &Parser)
const override {
8115 return Error(Parser,
"only values from 1 to 32 are legal");
8118 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8119 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8122 Res = parseHwregFunc(HwReg,
Offset, Width);
8125 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8127 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8131 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8138 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8140 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8144bool AMDGPUOperand::isHwreg()
const {
8145 return isImmTy(ImmTyHwreg);
8153AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8155 OperandInfoTy &Stream) {
8156 using namespace llvm::AMDGPU::SendMsg;
8161 Msg.IsSymbolic =
true;
8163 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8168 Op.IsDefined =
true;
8171 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8174 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8179 Stream.IsDefined =
true;
8180 Stream.Loc = getLoc();
8190AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8191 const OperandInfoTy &
Op,
8192 const OperandInfoTy &Stream) {
8193 using namespace llvm::AMDGPU::SendMsg;
8198 bool Strict = Msg.IsSymbolic;
8202 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8207 Error(Msg.Loc,
"invalid message id");
8213 Error(
Op.Loc,
"message does not support operations");
8215 Error(Msg.Loc,
"missing message operation");
8221 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8223 Error(
Op.Loc,
"invalid operation id");
8228 Error(Stream.Loc,
"message operation does not support streams");
8232 Error(Stream.Loc,
"invalid message stream id");
8238ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8239 using namespace llvm::AMDGPU::SendMsg;
8242 SMLoc Loc = getLoc();
8246 OperandInfoTy
Op(OP_NONE_);
8247 OperandInfoTy Stream(STREAM_ID_NONE_);
8248 if (parseSendMsgBody(Msg,
Op, Stream) &&
8249 validateSendMsg(Msg,
Op, Stream)) {
8254 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8256 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8261 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8265bool AMDGPUOperand::isSendMsg()
const {
8266 return isImmTy(ImmTySendMsg);
8269ParseStatus AMDGPUAsmParser::parseWaitEvent(
OperandVector &Operands) {
8270 using namespace llvm::AMDGPU::WaitEvent;
8272 SMLoc Loc = getLoc();
8275 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8277 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8279 StructuredOpField *TargetBitfield =
8280 isGFX11() ? &DontWaitExportReady : &ExportReady;
8282 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8286 if (!validateStructuredOpFields({TargetBitfield}))
8288 ImmVal = TargetBitfield->Val;
8295 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8297 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8298 AMDGPUOperand::ImmTyWaitEvent));
8302bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8308ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8315 int Slot = StringSwitch<int>(Str)
8322 return Error(S,
"invalid interpolation slot");
8324 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8325 AMDGPUOperand::ImmTyInterpSlot));
8329ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8336 if (!Str.starts_with(
"attr"))
8337 return Error(S,
"invalid interpolation attribute");
8339 StringRef Chan = Str.take_back(2);
8340 int AttrChan = StringSwitch<int>(Chan)
8347 return Error(S,
"invalid or missing interpolation attribute channel");
8349 Str = Str.drop_back(2).drop_front(4);
8352 if (Str.getAsInteger(10, Attr))
8353 return Error(S,
"invalid or missing interpolation attribute number");
8356 return Error(S,
"out of bounds interpolation attribute number");
8360 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8361 AMDGPUOperand::ImmTyInterpAttr));
8362 Operands.
push_back(AMDGPUOperand::CreateImm(
8363 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8371ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8372 using namespace llvm::AMDGPU::Exp;
8382 return Error(S, (Id == ET_INVALID)
8383 ?
"invalid exp target"
8384 :
"exp target is not supported on this GPU");
8386 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8387 AMDGPUOperand::ImmTyExpTgt));
8396AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8401AMDGPUAsmParser::isId(
const StringRef Id)
const {
8407 return getTokenKind() ==
Kind;
8410StringRef AMDGPUAsmParser::getId()
const {
8415AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8424AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8426 StringRef Tok = getTokenStr();
8437 if (isId(Id) && peekToken().is(Kind)) {
8447 if (isToken(Kind)) {
8456 const StringRef ErrMsg) {
8457 if (!trySkipToken(Kind)) {
8458 Error(getLoc(), ErrMsg);
8465AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8469 if (Parser.parseExpression(Expr))
8472 if (Expr->evaluateAsAbsolute(
Imm))
8475 if (Expected.empty()) {
8476 Error(S,
"expected absolute expression");
8478 Error(S, Twine(
"expected ", Expected) +
8479 Twine(
" or an absolute expression"));
8489 if (Parser.parseExpression(Expr))
8493 if (Expr->evaluateAsAbsolute(IntVal)) {
8494 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8496 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8502AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8504 Val =
getToken().getStringContents();
8508 Error(getLoc(), ErrMsg);
8513AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8515 Val = getTokenStr();
8519 if (!ErrMsg.
empty())
8520 Error(getLoc(), ErrMsg);
8525AMDGPUAsmParser::getToken()
const {
8526 return Parser.getTok();
8529AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8532 : getLexer().peekTok(ShouldSkipSpace);
8537 auto TokCount = getLexer().peekTokens(Tokens);
8539 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8544AMDGPUAsmParser::getTokenKind()
const {
8545 return getLexer().getKind();
8549AMDGPUAsmParser::getLoc()
const {
8554AMDGPUAsmParser::getTokenStr()
const {
8559AMDGPUAsmParser::lex() {
8563SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8564 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8568SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8572SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8573 int MCOpIdx)
const {
8574 for (
const auto &
Op : Operands) {
8575 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8576 if (TargetOp.getMCOpIdx() == MCOpIdx)
8577 return TargetOp.getStartLoc();
8583AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8585 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8586 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8588 return Op.getStartLoc();
8590 return getInstLoc(Operands);
8594AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8596 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8597 return getOperandLoc(
Test, Operands);
8611 StringRef
Id = getTokenStr();
8612 SMLoc IdLoc = getLoc();
8618 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8619 if (
I == Fields.
end())
8620 return Error(IdLoc,
"unknown field");
8621 if ((*I)->IsDefined)
8622 return Error(IdLoc,
"duplicate field");
8625 (*I)->Loc = getLoc();
8628 (*I)->IsDefined =
true;
8635bool AMDGPUAsmParser::validateStructuredOpFields(
8637 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8638 return F->validate(*
this);
8649 const unsigned OrMask,
8650 const unsigned XorMask) {
8659bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8660 const unsigned MaxVal,
8661 const Twine &ErrMsg, SMLoc &Loc) {
8678AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8679 const unsigned MinVal,
8680 const unsigned MaxVal,
8681 const StringRef ErrMsg) {
8683 for (
unsigned i = 0; i < OpNum; ++i) {
8684 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8692AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8693 using namespace llvm::AMDGPU::Swizzle;
8696 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8697 "expected a 2-bit lane id")) {
8708AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8709 using namespace llvm::AMDGPU::Swizzle;
8715 if (!parseSwizzleOperand(GroupSize,
8717 "group size must be in the interval [2,32]",
8722 Error(Loc,
"group size must be a power of two");
8725 if (parseSwizzleOperand(LaneIdx,
8727 "lane id must be in the interval [0,group size - 1]",
8736AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8737 using namespace llvm::AMDGPU::Swizzle;
8742 if (!parseSwizzleOperand(GroupSize,
8744 "group size must be in the interval [2,32]",
8749 Error(Loc,
"group size must be a power of two");
8758AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8759 using namespace llvm::AMDGPU::Swizzle;
8764 if (!parseSwizzleOperand(GroupSize,
8766 "group size must be in the interval [1,16]",
8771 Error(Loc,
"group size must be a power of two");
8780AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8781 using namespace llvm::AMDGPU::Swizzle;
8788 SMLoc StrLoc = getLoc();
8789 if (!parseString(Ctl)) {
8792 if (Ctl.
size() != BITMASK_WIDTH) {
8793 Error(StrLoc,
"expected a 5-character mask");
8797 unsigned AndMask = 0;
8798 unsigned OrMask = 0;
8799 unsigned XorMask = 0;
8801 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8805 Error(StrLoc,
"invalid mask");
8826bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8827 using namespace llvm::AMDGPU::Swizzle;
8830 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8836 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8837 "FFT swizzle must be in the interval [0," +
8838 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8846bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8847 using namespace llvm::AMDGPU::Swizzle;
8850 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8857 if (!parseSwizzleOperand(
Direction, 0, 1,
8858 "direction must be 0 (left) or 1 (right)", Loc))
8862 if (!parseSwizzleOperand(
8863 RotateSize, 0, ROTATE_MAX_SIZE,
8864 "number of threads to rotate must be in the interval [0," +
8865 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8870 (RotateSize << ROTATE_SIZE_SHIFT);
8875AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8877 SMLoc OffsetLoc = getLoc();
8883 Error(OffsetLoc,
"expected a 16-bit offset");
8890AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8891 using namespace llvm::AMDGPU::Swizzle;
8895 SMLoc ModeLoc = getLoc();
8898 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8899 Ok = parseSwizzleQuadPerm(
Imm);
8900 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8901 Ok = parseSwizzleBitmaskPerm(
Imm);
8902 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8903 Ok = parseSwizzleBroadcast(
Imm);
8904 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8905 Ok = parseSwizzleSwap(
Imm);
8906 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8907 Ok = parseSwizzleReverse(
Imm);
8908 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8909 Ok = parseSwizzleFFT(
Imm);
8910 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8911 Ok = parseSwizzleRotate(
Imm);
8913 Error(ModeLoc,
"expected a swizzle mode");
8916 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8922ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8926 if (trySkipId(
"offset")) {
8930 if (trySkipId(
"swizzle")) {
8931 Ok = parseSwizzleMacro(
Imm);
8933 Ok = parseSwizzleOffset(
Imm);
8937 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8945AMDGPUOperand::isSwizzle()
const {
8946 return isImmTy(ImmTySwizzle);
8953int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8955 using namespace llvm::AMDGPU::VGPRIndexMode;
8967 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8968 if (trySkipId(IdSymbolic[ModeId])) {
8976 "expected a VGPR index mode or a closing parenthesis" :
8977 "expected a VGPR index mode");
8982 Error(S,
"duplicate VGPR index mode");
8990 "expected a comma or a closing parenthesis"))
8997ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8999 using namespace llvm::AMDGPU::VGPRIndexMode;
9005 Imm = parseGPRIdxMacro();
9009 if (getParser().parseAbsoluteExpression(
Imm))
9012 return Error(S,
"invalid immediate: only 4-bit values are legal");
9016 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9020bool AMDGPUOperand::isGPRIdxMode()
const {
9021 return isImmTy(ImmTyGprIdxMode);
9028ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
9033 if (isRegister() || isModifier())
9039 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
9040 assert(Opr.isImm() || Opr.isExpr());
9041 SMLoc Loc = Opr.getStartLoc();
9045 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9046 Error(Loc,
"expected an absolute expression or a label");
9047 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9048 Error(Loc,
"expected a 16-bit signed jump offset");
9058ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
9059 return parseReg(Operands);
9066void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
9069 OptionalImmIndexMap OptionalIdx;
9070 unsigned FirstOperandIdx = 1;
9071 bool IsAtomicReturn =
false;
9078 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9079 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9083 Op.addRegOperands(Inst, 1);
9087 if (IsAtomicReturn && i == FirstOperandIdx)
9088 Op.addRegOperands(Inst, 1);
9093 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9094 Op.addImmOperands(Inst, 1);
9106 OptionalIdx[
Op.getImmTy()] = i;
9120bool AMDGPUOperand::isSMRDOffset8()
const {
9124bool AMDGPUOperand::isSMEMOffset()
const {
9126 return isImmLiteral();
9129bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9164bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9165 if (BoundCtrl == 0 || BoundCtrl == 1) {
9173void AMDGPUAsmParser::onBeginOfFile() {
9174 if (!getParser().getStreamer().getTargetStreamer() ||
9178 if (!getTargetStreamer().getTargetID())
9179 getTargetStreamer().initializeTargetID(getSTI(),
9180 getSTI().getFeatureString());
9183 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9191bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9195 StringRef TokenId = getTokenStr();
9196 AGVK VK = StringSwitch<AGVK>(TokenId)
9197 .Case(
"max", AGVK::AGVK_Max)
9198 .Case(
"or", AGVK::AGVK_Or)
9199 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9200 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9201 .Case(
"alignto", AGVK::AGVK_AlignTo)
9202 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9203 .Default(AGVK::AGVK_None);
9207 uint64_t CommaCount = 0;
9212 if (Exprs.
empty()) {
9214 "empty " + Twine(TokenId) +
" expression");
9217 if (CommaCount + 1 != Exprs.
size()) {
9219 "mismatch of commas in " + Twine(TokenId) +
" expression");
9226 if (getParser().parseExpression(Expr, EndLoc))
9230 if (LastTokenWasComma)
9234 "unexpected token in " + Twine(TokenId) +
" expression");
9240 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9243ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9244 StringRef
Name = getTokenStr();
9245 if (Name ==
"mul") {
9246 return parseIntWithPrefix(
"mul", Operands,
9250 if (Name ==
"div") {
9251 return parseIntWithPrefix(
"div", Operands,
9262 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9267 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9268 AMDGPU::OpName::src2};
9276 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9281 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9283 if (
DstOp.isReg() &&
9288 if ((OpSel & (1 << SrcNum)) != 0)
9294void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9296 cvtVOP3P(Inst, Operands);
9300void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9301 OptionalImmIndexMap &OptionalIdx) {
9302 cvtVOP3P(Inst, Operands, OptionalIdx);
9311 &&
Desc.NumOperands > (OpNum + 1)
9313 &&
Desc.operands()[OpNum + 1].RegClass != -1
9315 &&
Desc.getOperandConstraint(OpNum + 1,
9319void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9321 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9322 AMDGPU::OpName::src2};
9323 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9324 AMDGPU::OpName::src1_modifiers,
9325 AMDGPU::OpName::src2_modifiers};
9326 for (
int J = 0; J < 3; ++J) {
9327 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9333 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9336 if ((OpSel & (1 << J)) != 0)
9339 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9346void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9348 OptionalImmIndexMap OptionalIdx;
9353 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9354 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9357 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9358 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9360 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9361 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9362 Op.isInterpAttrChan()) {
9364 }
else if (
Op.isImmModifier()) {
9365 OptionalIdx[
Op.getImmTy()] =
I;
9373 AMDGPUOperand::ImmTyHigh);
9377 AMDGPUOperand::ImmTyClamp);
9381 AMDGPUOperand::ImmTyOModSI);
9386 AMDGPUOperand::ImmTyOpSel);
9387 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9390 cvtOpSelHelper(Inst, OpSel);
9394void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9396 OptionalImmIndexMap OptionalIdx;
9401 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9402 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9405 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9406 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9408 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9409 }
else if (
Op.isImmModifier()) {
9410 OptionalIdx[
Op.getImmTy()] =
I;
9418 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9428 cvtOpSelHelper(Inst, OpSel);
9431void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9433 OptionalImmIndexMap OptionalIdx;
9436 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9440 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9441 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9443 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9444 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9449 if (NumOperands == CbszOpIdx) {
9454 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9455 }
else if (
Op.isImmModifier()) {
9456 OptionalIdx[
Op.getImmTy()] =
I;
9458 Op.addRegOrImmOperands(Inst, 1);
9463 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9464 if (CbszIdx != OptionalIdx.end()) {
9465 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9469 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9470 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9471 if (BlgpIdx != OptionalIdx.end()) {
9472 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9483 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9484 if (OpselIdx != OptionalIdx.end()) {
9485 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9489 unsigned OpSelHi = 0;
9490 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9491 if (OpselHiIdx != OptionalIdx.end()) {
9492 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9495 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9496 AMDGPU::OpName::src1_modifiers};
9498 for (
unsigned J = 0; J < 2; ++J) {
9499 unsigned ModVal = 0;
9500 if (OpSel & (1 << J))
9502 if (OpSelHi & (1 << J))
9505 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9510void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9511 OptionalImmIndexMap &OptionalIdx) {
9516 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9517 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9520 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9521 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9523 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9524 }
else if (
Op.isImmModifier()) {
9525 OptionalIdx[
Op.getImmTy()] =
I;
9527 Op.addRegOrImmOperands(Inst, 1);
9533 AMDGPUOperand::ImmTyScaleSel);
9537 AMDGPUOperand::ImmTyClamp);
9543 AMDGPUOperand::ImmTyByteSel);
9548 AMDGPUOperand::ImmTyOModSI);
9555 auto *it = Inst.
begin();
9556 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9564void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9565 OptionalImmIndexMap OptionalIdx;
9566 cvtVOP3(Inst, Operands, OptionalIdx);
9569void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9570 OptionalImmIndexMap &OptIdx) {
9576 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9577 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9578 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9579 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9580 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9581 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9582 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9583 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9591 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx11 ||
9592 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx11 ||
9593 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx11 ||
9594 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx11 ||
9595 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx11 ||
9596 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx11 ||
9597 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx11 ||
9598 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx11 ||
9599 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx11 ||
9600 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx11 ||
9601 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx11 ||
9602 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx11 ||
9603 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9604 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9605 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9606 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9607 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9608 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9609 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9610 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9611 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9612 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9613 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9614 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9615 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9616 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9617 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9618 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9619 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9620 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9621 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9622 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9623 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9624 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9625 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9626 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9627 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9628 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9632 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9633 if (BitOp3Idx != -1) {
9640 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9641 if (OpSelIdx != -1) {
9645 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9646 if (OpSelHiIdx != -1) {
9647 int DefaultVal =
IsPacked ? -1 : 0;
9653 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9654 if (MatrixAFMTIdx != -1) {
9656 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9660 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9661 if (MatrixBFMTIdx != -1) {
9663 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9666 int MatrixAScaleIdx =
9667 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9668 if (MatrixAScaleIdx != -1) {
9670 AMDGPUOperand::ImmTyMatrixAScale, 0);
9673 int MatrixBScaleIdx =
9674 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9675 if (MatrixBScaleIdx != -1) {
9677 AMDGPUOperand::ImmTyMatrixBScale, 0);
9680 int MatrixAScaleFmtIdx =
9681 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9682 if (MatrixAScaleFmtIdx != -1) {
9684 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9687 int MatrixBScaleFmtIdx =
9688 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9689 if (MatrixBScaleFmtIdx != -1) {
9691 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9696 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9700 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9702 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9706 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9710 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9711 AMDGPU::OpName::src2};
9712 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9713 AMDGPU::OpName::src1_modifiers,
9714 AMDGPU::OpName::src2_modifiers};
9717 unsigned OpSelHi = 0;
9724 if (OpSelHiIdx != -1)
9733 for (
int J = 0; J < 3; ++J) {
9734 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9738 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9743 uint32_t ModVal = 0;
9746 if (SrcOp.
isReg() && getMRI()
9753 if ((OpSel & (1 << J)) != 0)
9757 if ((OpSelHi & (1 << J)) != 0)
9760 if ((NegLo & (1 << J)) != 0)
9763 if ((NegHi & (1 << J)) != 0)
9770void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9771 OptionalImmIndexMap OptIdx;
9772 cvtVOP3(Inst, Operands, OptIdx);
9773 cvtVOP3P(Inst, Operands, OptIdx);
9777 unsigned i,
unsigned Opc,
9779 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9780 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9782 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9785void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9788 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9791 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9792 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9794 OptionalImmIndexMap OptIdx;
9795 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9796 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9797 OptIdx[
Op.getImmTy()] = i;
9802 AMDGPUOperand::ImmTyIndexKey8bit);
9806 AMDGPUOperand::ImmTyIndexKey16bit);
9810 AMDGPUOperand::ImmTyIndexKey32bit);
9815 cvtVOP3P(Inst, Operands, OptIdx);
9822ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9830 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9831 SMLoc OpYLoc = getLoc();
9834 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9837 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9843void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9846 auto addOp = [&](uint16_t ParsedOprIdx) {
9847 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9849 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9853 Op.addRegOperands(Inst, 1);
9857 Op.addImmOperands(Inst, 1);
9869 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9873 const auto &CInfo = InstInfo[CompIdx];
9874 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9875 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9876 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9877 if (CInfo.hasSrc2Acc())
9878 addOp(CInfo.getIndexOfDstInParsedOperands());
9882 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9883 if (BitOp3Idx != -1) {
9884 OptionalImmIndexMap OptIdx;
9885 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9887 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9897bool AMDGPUOperand::isDPP8()
const {
9898 return isImmTy(ImmTyDPP8);
9901bool AMDGPUOperand::isDPPCtrl()
const {
9902 using namespace AMDGPU::DPP;
9904 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9907 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9908 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9909 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9910 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9911 (
Imm == DppCtrl::WAVE_SHL1) ||
9912 (
Imm == DppCtrl::WAVE_ROL1) ||
9913 (
Imm == DppCtrl::WAVE_SHR1) ||
9914 (
Imm == DppCtrl::WAVE_ROR1) ||
9915 (
Imm == DppCtrl::ROW_MIRROR) ||
9916 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9917 (
Imm == DppCtrl::BCAST15) ||
9918 (
Imm == DppCtrl::BCAST31) ||
9919 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9920 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9929bool AMDGPUOperand::isBLGP()
const {
9933bool AMDGPUOperand::isS16Imm()
const {
9937bool AMDGPUOperand::isU16Imm()
const {
9945bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9950 SMLoc Loc =
getToken().getEndLoc();
9951 Token = std::string(getTokenStr());
9953 if (getLoc() != Loc)
9958 if (!parseId(Suffix))
9962 StringRef DimId = Token;
9973ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9983 SMLoc Loc = getLoc();
9984 if (!parseDimId(Encoding))
9985 return Error(Loc,
"invalid dim value");
9987 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9988 AMDGPUOperand::ImmTyDim));
9996ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
10006 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10009 for (
size_t i = 0; i < 8; ++i) {
10013 SMLoc Loc = getLoc();
10014 if (getParser().parseAbsoluteExpression(Sels[i]))
10016 if (0 > Sels[i] || 7 < Sels[i])
10017 return Error(Loc,
"expected a 3-bit value");
10020 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10024 for (
size_t i = 0; i < 8; ++i)
10025 DPP8 |= (Sels[i] << (i * 3));
10027 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10032AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10034 if (Ctrl ==
"row_newbcast")
10037 if (Ctrl ==
"row_share" ||
10038 Ctrl ==
"row_xmask")
10041 if (Ctrl ==
"wave_shl" ||
10042 Ctrl ==
"wave_shr" ||
10043 Ctrl ==
"wave_rol" ||
10044 Ctrl ==
"wave_ror" ||
10045 Ctrl ==
"row_bcast")
10048 return Ctrl ==
"row_mirror" ||
10049 Ctrl ==
"row_half_mirror" ||
10050 Ctrl ==
"quad_perm" ||
10051 Ctrl ==
"row_shl" ||
10052 Ctrl ==
"row_shr" ||
10057AMDGPUAsmParser::parseDPPCtrlPerm() {
10060 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10064 for (
int i = 0; i < 4; ++i) {
10069 SMLoc Loc = getLoc();
10070 if (getParser().parseAbsoluteExpression(Temp))
10072 if (Temp < 0 || Temp > 3) {
10073 Error(Loc,
"expected a 2-bit value");
10077 Val += (Temp << i * 2);
10080 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10087AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10088 using namespace AMDGPU::DPP;
10093 SMLoc Loc = getLoc();
10095 if (getParser().parseAbsoluteExpression(Val))
10098 struct DppCtrlCheck {
10104 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10105 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10106 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10107 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10108 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10109 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10110 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10111 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10112 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10113 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10114 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10118 if (
Check.Ctrl == -1) {
10119 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10127 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10134ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10135 using namespace AMDGPU::DPP;
10138 !isSupportedDPPCtrl(getTokenStr(), Operands))
10141 SMLoc S = getLoc();
10147 if (Ctrl ==
"row_mirror") {
10148 Val = DppCtrl::ROW_MIRROR;
10149 }
else if (Ctrl ==
"row_half_mirror") {
10150 Val = DppCtrl::ROW_HALF_MIRROR;
10153 if (Ctrl ==
"quad_perm") {
10154 Val = parseDPPCtrlPerm();
10156 Val = parseDPPCtrlSel(Ctrl);
10165 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10169void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10171 OptionalImmIndexMap OptionalIdx;
10178 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10180 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10181 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10185 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10186 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10190 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10191 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10192 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10193 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10194 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10196 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10200 if (OldIdx == NumOperands) {
10202 constexpr int DST_IDX = 0;
10204 }
else if (Src2ModIdx == NumOperands) {
10214 if (IsVOP3CvtSrDpp) {
10223 if (TiedTo != -1) {
10228 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10230 if (IsDPP8 &&
Op.isDppFI()) {
10233 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10234 }
else if (
Op.isReg()) {
10235 Op.addRegOperands(Inst, 1);
10236 }
else if (
Op.isImm() &&
10238 Op.addImmOperands(Inst, 1);
10239 }
else if (
Op.isImm()) {
10240 OptionalIdx[
Op.getImmTy()] =
I;
10248 AMDGPUOperand::ImmTyClamp);
10254 AMDGPUOperand::ImmTyByteSel);
10261 cvtVOP3P(Inst, Operands, OptionalIdx);
10263 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10270 using namespace llvm::AMDGPU::DPP;
10280 AMDGPUOperand::ImmTyDppFI);
10284void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10285 OptionalImmIndexMap OptionalIdx;
10289 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10290 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10294 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10297 if (TiedTo != -1) {
10302 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10304 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10312 Op.addImmOperands(Inst, 1);
10314 Op.addRegWithFPInputModsOperands(Inst, 2);
10315 }
else if (
Op.isDppFI()) {
10317 }
else if (
Op.isReg()) {
10318 Op.addRegOperands(Inst, 1);
10324 Op.addRegWithFPInputModsOperands(Inst, 2);
10325 }
else if (
Op.isReg()) {
10326 Op.addRegOperands(Inst, 1);
10327 }
else if (
Op.isDPPCtrl()) {
10328 Op.addImmOperands(Inst, 1);
10329 }
else if (
Op.isImm()) {
10331 OptionalIdx[
Op.getImmTy()] =
I;
10339 using namespace llvm::AMDGPU::DPP;
10347 AMDGPUOperand::ImmTyDppFI);
10356ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10358 AMDGPUOperand::ImmTy
Type) {
10359 return parseStringOrIntWithPrefix(
10361 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10365ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10366 return parseStringOrIntWithPrefix(
10367 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10368 AMDGPUOperand::ImmTySDWADstUnused);
10371void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10375void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10379void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10383void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10387void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10391void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10392 uint64_t BasicInstType,
10395 using namespace llvm::AMDGPU::SDWA;
10397 OptionalImmIndexMap OptionalIdx;
10398 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10399 bool SkippedVcc =
false;
10403 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10404 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10407 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10408 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10409 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10410 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10428 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10429 }
else if (
Op.isImm()) {
10431 OptionalIdx[
Op.getImmTy()] =
I;
10435 SkippedVcc =
false;
10439 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10440 Opc != AMDGPU::V_NOP_sdwa_vi) {
10442 switch (BasicInstType) {
10446 AMDGPUOperand::ImmTyClamp, 0);
10450 AMDGPUOperand::ImmTyOModSI, 0);
10454 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10458 AMDGPUOperand::ImmTySDWADstUnused,
10459 DstUnused::UNUSED_PRESERVE);
10461 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10466 AMDGPUOperand::ImmTyClamp, 0);
10471 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10472 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10473 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10474 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10480 AMDGPUOperand::ImmTyClamp, 0);
10481 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10482 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10486 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10492 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10493 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10494 auto *it = Inst.
begin();
10496 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10508#define GET_MATCHER_IMPLEMENTATION
10509#define GET_MNEMONIC_SPELL_CHECKER
10510#define GET_MNEMONIC_CHECKER
10511#include "AMDGPUGenAsmMatcher.inc"
10517 return parseTokenOp(
"addr64",
Operands);
10519 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10521 return parseTokenOp(
"idxen",
Operands);
10523 return parseTokenOp(
"lds",
Operands);
10525 return parseTokenOp(
"offen",
Operands);
10527 return parseTokenOp(
"off",
Operands);
10528 case MCK_row_95_en:
10529 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10531 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10533 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10535 return tryCustomParseOperand(
Operands, MCK);
10540unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10546 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10549 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10551 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10553 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10555 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10557 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10559 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10561 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10562 case MCK_row_95_en:
10563 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10571 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10573 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10574 case MCK_SOPPBrTarget:
10575 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10576 case MCK_VReg32OrOff:
10577 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10578 case MCK_InterpSlot:
10579 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10580 case MCK_InterpAttr:
10581 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10582 case MCK_InterpAttrChan:
10583 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10585 case MCK_SReg_64_XEXEC:
10595 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10597 return Match_InvalidOperand;
10605ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10606 SMLoc S = getLoc();
10615 return Error(S,
"expected a 16-bit value");
10618 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10622bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10628bool 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 uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ Default
The result 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