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_gfx12 ||
3974 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3975 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx13 ||
3976 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250 ||
3977 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx13;
3981 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3982 int I = getNamedOperandIdx(Opcode, OpName);
3986 int64_t
Imm =
Op.getImm();
3992 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3993 OpName::vsrc2Y, OpName::imm}) {
3994 int I = getNamedOperandIdx(Opcode, OpName);
4004 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
4005 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
4007 return InvalidCompOprIdx;
4010bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
4017 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
4018 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
4019 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
4021 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
4025 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
4026 if (!InvalidCompOprIdx.has_value())
4029 auto CompOprIdx = *InvalidCompOprIdx;
4032 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4033 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4034 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4036 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4037 if (CompOprIdx == VOPD::Component::DST) {
4039 Error(Loc,
"dst registers must be distinct");
4041 Error(Loc,
"one dst register must be even and the other odd");
4043 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4044 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4045 " operands must use different VGPR banks");
4053bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4055 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4056 if (!InvalidCompOprIdx.has_value())
4060 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4061 if (InvalidCompOprIdx.has_value()) {
4066 if (*InvalidCompOprIdx == VOPD::Component::DST)
4079bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4080 const unsigned Opcode = Inst.
getOpcode();
4095 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4096 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4097 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4098 int I = getNamedOperandIdx(Opcode, OpName);
4105 return !tryVOPD3(Inst);
4110bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4111 const unsigned Opcode = Inst.
getOpcode();
4116 return tryVOPD(Inst);
4117 return tryVOPD3(Inst);
4120bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4126 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4137bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4145 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4146 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4147 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4155 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4156 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4161 bool IsPackedD16 =
false;
4165 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4166 IsPackedD16 = D16Idx >= 0;
4171 if ((VDataSize / 4) ==
DataSize + TFESize)
4176 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4178 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4180 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4184bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4193 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4195 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4197 ? AMDGPU::OpName::srsrc
4198 : AMDGPU::OpName::rsrc;
4199 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4200 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4201 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4205 assert(SrsrcIdx > VAddr0Idx);
4208 if (BaseOpcode->
BVH) {
4209 if (IsA16 == BaseOpcode->
A16)
4211 Error(IDLoc,
"image address size does not match a16");
4217 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4218 unsigned ActualAddrSize =
4219 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4221 unsigned ExpectedAddrSize =
4225 if (hasPartialNSAEncoding() &&
4228 int VAddrLastIdx = SrsrcIdx - 1;
4229 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4231 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4234 if (ExpectedAddrSize > 12)
4235 ExpectedAddrSize = 16;
4240 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4244 if (ActualAddrSize == ExpectedAddrSize)
4247 Error(IDLoc,
"image address size does not match dim and a16");
4251bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4258 if (!
Desc.mayLoad() || !
Desc.mayStore())
4261 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4268 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4271bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4279 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4287 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4290bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4305 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4306 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4313bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4321 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4324 if (!BaseOpcode->
MSAA)
4327 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4333 return DimInfo->
MSAA;
4339 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4340 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4341 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4351bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4360 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4363 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4371 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4375bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4380 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4383 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4386 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4393 Error(getOperandLoc(Operands, Src0Idx),
4394 "source operand must be either a VGPR or an inline constant");
4401bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4404 const MCInstrDesc &
Desc = MII.
get(Opcode);
4407 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4410 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4414 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4415 Error(getOperandLoc(Operands, Src2Idx),
4416 "inline constants are not allowed for this operand");
4423bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4431 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4432 if (BlgpIdx != -1) {
4433 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4434 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4444 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4445 Error(getOperandLoc(Operands, Src0Idx),
4446 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4451 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4452 Error(getOperandLoc(Operands, Src1Idx),
4453 "wrong register tuple size for blgp value " + Twine(BLGP));
4461 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4465 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4469 MCRegister Src2Reg = Src2.
getReg();
4471 if (Src2Reg == DstReg)
4476 .getSizeInBits() <= 128)
4479 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4480 Error(getOperandLoc(Operands, Src2Idx),
4481 "source 2 operand must not partially overlap with dst");
4488bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4492 case V_DIV_SCALE_F32_gfx6_gfx7:
4493 case V_DIV_SCALE_F32_vi:
4494 case V_DIV_SCALE_F32_gfx10:
4495 case V_DIV_SCALE_F64_gfx6_gfx7:
4496 case V_DIV_SCALE_F64_vi:
4497 case V_DIV_SCALE_F64_gfx10:
4503 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4504 AMDGPU::OpName::src2_modifiers,
4505 AMDGPU::OpName::src2_modifiers}) {
4516bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4524 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4533bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4540 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4548 case AMDGPU::V_SUBREV_F32_e32:
4549 case AMDGPU::V_SUBREV_F32_e64:
4550 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4551 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4552 case AMDGPU::V_SUBREV_F32_e32_vi:
4553 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4554 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4555 case AMDGPU::V_SUBREV_F32_e64_vi:
4557 case AMDGPU::V_SUBREV_CO_U32_e32:
4558 case AMDGPU::V_SUBREV_CO_U32_e64:
4559 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4560 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4562 case AMDGPU::V_SUBBREV_U32_e32:
4563 case AMDGPU::V_SUBBREV_U32_e64:
4564 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4565 case AMDGPU::V_SUBBREV_U32_e32_vi:
4566 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4567 case AMDGPU::V_SUBBREV_U32_e64_vi:
4569 case AMDGPU::V_SUBREV_U32_e32:
4570 case AMDGPU::V_SUBREV_U32_e64:
4571 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4572 case AMDGPU::V_SUBREV_U32_e32_vi:
4573 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4574 case AMDGPU::V_SUBREV_U32_e64_vi:
4576 case AMDGPU::V_SUBREV_F16_e32:
4577 case AMDGPU::V_SUBREV_F16_e64:
4578 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4579 case AMDGPU::V_SUBREV_F16_e32_vi:
4580 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4581 case AMDGPU::V_SUBREV_F16_e64_vi:
4583 case AMDGPU::V_SUBREV_U16_e32:
4584 case AMDGPU::V_SUBREV_U16_e64:
4585 case AMDGPU::V_SUBREV_U16_e32_vi:
4586 case AMDGPU::V_SUBREV_U16_e64_vi:
4588 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4589 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4590 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4592 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4593 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4595 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4596 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4598 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4599 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4601 case AMDGPU::V_LSHRREV_B32_e32:
4602 case AMDGPU::V_LSHRREV_B32_e64:
4603 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4604 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4605 case AMDGPU::V_LSHRREV_B32_e32_vi:
4606 case AMDGPU::V_LSHRREV_B32_e64_vi:
4607 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4608 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4610 case AMDGPU::V_ASHRREV_I32_e32:
4611 case AMDGPU::V_ASHRREV_I32_e64:
4612 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4613 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4614 case AMDGPU::V_ASHRREV_I32_e32_vi:
4615 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4616 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4617 case AMDGPU::V_ASHRREV_I32_e64_vi:
4619 case AMDGPU::V_LSHLREV_B32_e32:
4620 case AMDGPU::V_LSHLREV_B32_e64:
4621 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4622 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4623 case AMDGPU::V_LSHLREV_B32_e32_vi:
4624 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4625 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4626 case AMDGPU::V_LSHLREV_B32_e64_vi:
4628 case AMDGPU::V_LSHLREV_B16_e32:
4629 case AMDGPU::V_LSHLREV_B16_e64:
4630 case AMDGPU::V_LSHLREV_B16_e32_vi:
4631 case AMDGPU::V_LSHLREV_B16_e64_vi:
4632 case AMDGPU::V_LSHLREV_B16_gfx10:
4634 case AMDGPU::V_LSHRREV_B16_e32:
4635 case AMDGPU::V_LSHRREV_B16_e64:
4636 case AMDGPU::V_LSHRREV_B16_e32_vi:
4637 case AMDGPU::V_LSHRREV_B16_e64_vi:
4638 case AMDGPU::V_LSHRREV_B16_gfx10:
4640 case AMDGPU::V_ASHRREV_I16_e32:
4641 case AMDGPU::V_ASHRREV_I16_e64:
4642 case AMDGPU::V_ASHRREV_I16_e32_vi:
4643 case AMDGPU::V_ASHRREV_I16_e64_vi:
4644 case AMDGPU::V_ASHRREV_I16_gfx10:
4646 case AMDGPU::V_LSHLREV_B64_e64:
4647 case AMDGPU::V_LSHLREV_B64_gfx10:
4648 case AMDGPU::V_LSHLREV_B64_vi:
4650 case AMDGPU::V_LSHRREV_B64_e64:
4651 case AMDGPU::V_LSHRREV_B64_gfx10:
4652 case AMDGPU::V_LSHRREV_B64_vi:
4654 case AMDGPU::V_ASHRREV_I64_e64:
4655 case AMDGPU::V_ASHRREV_I64_gfx10:
4656 case AMDGPU::V_ASHRREV_I64_vi:
4658 case AMDGPU::V_PK_LSHLREV_B16:
4659 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4660 case AMDGPU::V_PK_LSHLREV_B16_vi:
4662 case AMDGPU::V_PK_LSHRREV_B16:
4663 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4664 case AMDGPU::V_PK_LSHRREV_B16_vi:
4665 case AMDGPU::V_PK_ASHRREV_I16:
4666 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4667 case AMDGPU::V_PK_ASHRREV_I16_vi:
4674bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4676 using namespace SIInstrFlags;
4677 const unsigned Opcode = Inst.
getOpcode();
4678 const MCInstrDesc &
Desc = MII.
get(Opcode);
4683 if ((
Desc.TSFlags & Enc) == 0)
4686 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4687 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4691 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4694 Error(getOperandLoc(Operands, SrcIdx),
4695 "lds_direct is not supported on this GPU");
4700 Error(getOperandLoc(Operands, SrcIdx),
4701 "lds_direct cannot be used with this instruction");
4705 if (SrcName != OpName::src0) {
4706 Error(getOperandLoc(Operands, SrcIdx),
4707 "lds_direct may be used as src0 only");
4716SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4717 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4718 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4719 if (
Op.isFlatOffset())
4720 return Op.getStartLoc();
4725bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4728 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4734 return validateFlatOffset(Inst, Operands);
4737 return validateSMEMOffset(Inst, Operands);
4743 const unsigned OffsetSize = 24;
4744 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4745 Error(getFlatOffsetLoc(Operands),
4746 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4747 "-bit unsigned offset for buffer ops");
4751 const unsigned OffsetSize = 16;
4752 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4753 Error(getFlatOffsetLoc(Operands),
4754 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4761bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4768 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4772 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4773 Error(getFlatOffsetLoc(Operands),
4774 "flat offset modifier is not supported on this GPU");
4781 bool AllowNegative =
4784 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4785 Error(getFlatOffsetLoc(Operands),
4786 Twine(
"expected a ") +
4787 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4788 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4795SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4797 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4798 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4799 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4800 return Op.getStartLoc();
4805bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4815 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4829 Error(getSMEMOffsetLoc(Operands),
4831 ?
"expected a 23-bit unsigned offset for buffer ops"
4832 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4833 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4834 :
"expected a 21-bit signed offset");
4839bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4842 const MCInstrDesc &
Desc = MII.
get(Opcode);
4846 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4847 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4849 const int OpIndices[] = { Src0Idx, Src1Idx };
4851 unsigned NumExprs = 0;
4852 unsigned NumLiterals = 0;
4855 for (
int OpIdx : OpIndices) {
4856 if (
OpIdx == -1)
break;
4862 std::optional<int64_t>
Imm;
4865 }
else if (MO.
isExpr()) {
4874 if (!
Imm.has_value()) {
4876 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4880 if (NumLiterals == 0 || LiteralValue !=
Value) {
4888 if (NumLiterals + NumExprs <= 1)
4891 Error(getOperandLoc(Operands, Src1Idx),
4892 "only one unique literal operand is allowed");
4896bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4899 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4909 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4910 if (OpSelIdx != -1) {
4914 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4915 if (OpSelHiIdx != -1) {
4924 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4934 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4935 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4936 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4937 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4939 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4940 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4946 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4948 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4958 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4959 if (Src2Idx != -1) {
4960 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4970bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4971 if (!hasTrue16Insts())
4973 const MCRegisterInfo *MRI = getMRI();
4975 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4981 if (OpSelOpValue == 0)
4983 unsigned OpCount = 0;
4984 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4985 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4986 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4993 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4994 if (OpSelOpIsHi != VGPRSuffixIsHi)
5003bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
5004 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
5017 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
5028 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
5029 AMDGPU::OpName::src1_modifiers,
5030 AMDGPU::OpName::src2_modifiers};
5032 for (
unsigned i = 0; i < 3; ++i) {
5042bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5045 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5046 if (DppCtrlIdx >= 0) {
5053 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5054 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5055 :
"DP ALU dpp only supports row_newbcast");
5060 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5061 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5064 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5066 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5069 Error(getOperandLoc(Operands, Src1Idx),
5070 "invalid operand for instruction");
5074 Error(getInstLoc(Operands),
5075 "src1 immediate operand invalid for instruction");
5085bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5086 return (
Reg == AMDGPU::VCC && isWave64()) ||
5087 (
Reg == AMDGPU::VCC_LO && isWave32());
5091bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5094 const MCInstrDesc &
Desc = MII.
get(Opcode);
5095 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5097 !HasMandatoryLiteral && !
isVOPD(Opcode))
5102 std::optional<unsigned> LiteralOpIdx;
5105 for (
int OpIdx : OpIndices) {
5115 std::optional<int64_t>
Imm;
5121 bool IsAnotherLiteral =
false;
5122 if (!
Imm.has_value()) {
5124 IsAnotherLiteral =
true;
5125 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5130 HasMandatoryLiteral);
5136 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5138 "invalid operand for instruction");
5142 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5149 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5150 !getFeatureBits()[FeatureVOP3Literal]) {
5152 "literal operands are not supported");
5156 if (LiteralOpIdx && IsAnotherLiteral) {
5157 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5158 getOperandLoc(Operands, *LiteralOpIdx)),
5159 "only one unique literal operand is allowed");
5163 if (IsAnotherLiteral)
5164 LiteralOpIdx =
OpIdx;
5187bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5195 ? AMDGPU::OpName::data0
5196 : AMDGPU::OpName::vdata;
5198 const MCRegisterInfo *MRI = getMRI();
5199 int DstAreg =
IsAGPROperand(Inst, AMDGPU::OpName::vdst, MRI);
5203 int Data2Areg =
IsAGPROperand(Inst, AMDGPU::OpName::data1, MRI);
5204 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5208 auto FB = getFeatureBits();
5209 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5210 if (DataAreg < 0 || DstAreg < 0)
5212 return DstAreg == DataAreg;
5215 return DstAreg < 1 && DataAreg < 1;
5218bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5219 auto FB = getFeatureBits();
5220 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5224 const MCRegisterInfo *MRI = getMRI();
5227 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5230 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5234 case AMDGPU::DS_LOAD_TR6_B96:
5235 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5239 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5240 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5244 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5245 if (VAddrIdx != -1) {
5248 if ((
Sub - AMDGPU::VGPR0) & 1)
5253 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5254 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5259 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5260 const MCRegisterClass &AGPR32 = MRI->
getRegClass(AMDGPU::AGPR_32RegClassID);
5279SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5280 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5281 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5283 return Op.getStartLoc();
5288bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5291 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5294 SMLoc BLGPLoc = getBLGPLoc(Operands);
5297 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5298 auto FB = getFeatureBits();
5299 bool UsesNeg =
false;
5300 if (FB[AMDGPU::FeatureGFX940Insts]) {
5302 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5303 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5304 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5305 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5310 if (IsNeg == UsesNeg)
5314 UsesNeg ?
"invalid modifier: blgp is not supported"
5315 :
"invalid modifier: neg is not supported");
5320bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5326 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5327 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5328 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5329 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5332 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5335 if (
Reg == AMDGPU::SGPR_NULL)
5338 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5342bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5348 return validateGWS(Inst, Operands);
5353 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5358 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5359 Error(S,
"gds modifier is not supported on this GPU");
5367bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5369 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5373 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5374 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5377 const MCRegisterInfo *MRI = getMRI();
5378 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5380 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5383 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5385 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5392bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5395 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5396 AMDGPU::OpName::cpol);
5404 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5407 Error(S,
"scale_offset is not supported on this GPU");
5410 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5413 Error(S,
"nv is not supported on this GPU");
5418 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5421 Error(S,
"scale_offset is not supported for this instruction");
5425 return validateTHAndScopeBits(Inst, Operands, CPol);
5430 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5431 Error(S,
"cache policy is not supported for SMRD instructions");
5435 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5444 if (!(TSFlags & AllowSCCModifier)) {
5445 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5449 "scc modifier is not supported for this instruction on this GPU");
5460 :
"instruction must use glc");
5465 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5468 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5470 :
"instruction must not use glc");
5478bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5480 const unsigned CPol) {
5484 const unsigned Opcode = Inst.
getOpcode();
5485 const MCInstrDesc &TID = MII.
get(Opcode);
5488 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5495 return PrintError(
"th:TH_ATOMIC_RETURN requires a destination operand");
5500 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5508 return PrintError(
"invalid th value for SMEM instruction");
5515 return PrintError(
"scope and th combination is not valid");
5521 return PrintError(
"invalid th value for atomic instructions");
5524 return PrintError(
"invalid th value for store instructions");
5527 return PrintError(
"invalid th value for load instructions");
5533bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5536 if (
Desc.mayStore() &&
5538 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5539 if (Loc != getInstLoc(Operands)) {
5540 Error(Loc,
"TFE modifier has no meaning for store instructions");
5548bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5554 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5555 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5559 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5567 Error(getOperandLoc(Operands, SrcIdx),
5568 "wrong register tuple size for " +
5573 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5574 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5577bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5579 if (!validateLdsDirect(Inst, Operands))
5581 if (!validateTrue16OpSel(Inst)) {
5582 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5583 "op_sel operand conflicts with 16-bit operand suffix");
5586 if (!validateSOPLiteral(Inst, Operands))
5588 if (!validateVOPLiteral(Inst, Operands)) {
5591 if (!validateConstantBusLimitations(Inst, Operands)) {
5594 if (!validateVOPD(Inst, Operands)) {
5597 if (!validateIntClampSupported(Inst)) {
5598 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5599 "integer clamping is not supported on this GPU");
5602 if (!validateOpSel(Inst)) {
5603 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5604 "invalid op_sel operand");
5607 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5608 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5609 "invalid neg_lo operand");
5612 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5613 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5614 "invalid neg_hi operand");
5617 if (!validateDPP(Inst, Operands)) {
5621 if (!validateMIMGD16(Inst)) {
5622 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5623 "d16 modifier is not supported on this GPU");
5626 if (!validateMIMGDim(Inst, Operands)) {
5627 Error(IDLoc,
"missing dim operand");
5630 if (!validateTensorR128(Inst)) {
5631 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5632 "instruction must set modifier r128=0");
5635 if (!validateMIMGMSAA(Inst)) {
5636 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5637 "invalid dim; must be MSAA type");
5640 if (!validateMIMGDataSize(Inst, IDLoc)) {
5643 if (!validateMIMGAddrSize(Inst, IDLoc))
5645 if (!validateMIMGAtomicDMask(Inst)) {
5646 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5647 "invalid atomic image dmask");
5650 if (!validateMIMGGatherDMask(Inst)) {
5651 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5652 "invalid image_gather dmask: only one bit must be set");
5655 if (!validateMovrels(Inst, Operands)) {
5658 if (!validateOffset(Inst, Operands)) {
5661 if (!validateMAIAccWrite(Inst, Operands)) {
5664 if (!validateMAISrc2(Inst, Operands)) {
5667 if (!validateMFMA(Inst, Operands)) {
5670 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5674 if (!validateAGPRLdSt(Inst)) {
5675 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5676 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5677 :
"invalid register class: agpr loads and stores not supported on this GPU"
5681 if (!validateVGPRAlign(Inst)) {
5683 "invalid register class: vgpr tuples must be 64 bit aligned");
5686 if (!validateDS(Inst, Operands)) {
5690 if (!validateBLGP(Inst, Operands)) {
5694 if (!validateDivScale(Inst)) {
5695 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5698 if (!validateWaitCnt(Inst, Operands)) {
5701 if (!validateTFE(Inst, Operands)) {
5704 if (!validateWMMA(Inst, Operands)) {
5713 unsigned VariantID = 0);
5717 unsigned VariantID);
5719bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5724bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5725 const FeatureBitset &FBS,
5726 ArrayRef<unsigned> Variants) {
5727 for (
auto Variant : Variants) {
5735bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5737 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5740 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5745 getParser().clearPendingErrors();
5749 StringRef VariantName = getMatchedVariantName();
5750 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5753 " variant of this instruction is not supported"));
5757 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5758 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5760 FeatureBitset FeaturesWS32 = getFeatureBits();
5761 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5762 .
flip(AMDGPU::FeatureWavefrontSize32);
5763 FeatureBitset AvailableFeaturesWS32 =
5764 ComputeAvailableFeatures(FeaturesWS32);
5766 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5767 return Error(IDLoc,
"instruction requires wavesize=32");
5771 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5772 return Error(IDLoc,
"instruction not supported on this GPU");
5777 return Error(IDLoc,
"invalid instruction" + Suggestion);
5783 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5784 if (
Op.isToken() && InvalidOprIdx > 1) {
5785 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5786 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5791bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5794 uint64_t &ErrorInfo,
5795 bool MatchingInlineAsm) {
5798 unsigned Result = Match_Success;
5799 for (
auto Variant : getMatchedVariants()) {
5801 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5806 if (R == Match_Success || R == Match_MissingFeature ||
5807 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5808 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5809 Result != Match_MissingFeature)) {
5813 if (R == Match_Success)
5817 if (Result == Match_Success) {
5818 if (!validateInstruction(Inst, IDLoc, Operands)) {
5825 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5826 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5832 case Match_MissingFeature:
5836 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5838 case Match_InvalidOperand: {
5839 SMLoc ErrorLoc = IDLoc;
5840 if (ErrorInfo != ~0ULL) {
5841 if (ErrorInfo >= Operands.
size()) {
5842 return Error(IDLoc,
"too few operands for instruction");
5844 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5845 if (ErrorLoc == SMLoc())
5849 return Error(ErrorLoc,
"invalid VOPDY instruction");
5851 return Error(ErrorLoc,
"invalid operand for instruction");
5854 case Match_MnemonicFail:
5860bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5865 if (getParser().parseAbsoluteExpression(Tmp)) {
5868 Ret =
static_cast<uint32_t
>(Tmp);
5872bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5873 if (!getSTI().getTargetTriple().isAMDGCN())
5874 return TokError(
"directive only supported for amdgcn architecture");
5876 std::string TargetIDDirective;
5877 SMLoc TargetStart = getTok().getLoc();
5878 if (getParser().parseEscapedString(TargetIDDirective))
5881 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5882 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5883 return getParser().Error(TargetRange.
Start,
5884 (Twine(
".amdgcn_target directive's target id ") +
5885 Twine(TargetIDDirective) +
5886 Twine(
" does not match the specified target id ") +
5887 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5892bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5896bool AMDGPUAsmParser::calculateGPRBlocks(
5897 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5898 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5899 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5900 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5901 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5907 const MCExpr *
NumSGPRs = NextFreeSGPR;
5908 int64_t EvaluatedSGPRs;
5913 unsigned MaxAddressableNumSGPRs =
5916 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5917 !Features.
test(FeatureSGPRInitBug) &&
5918 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5919 return OutOfRangeError(SGPRRange);
5921 const MCExpr *ExtraSGPRs =
5925 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5926 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5927 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5928 return OutOfRangeError(SGPRRange);
5930 if (Features.
test(FeatureSGPRInitBug))
5937 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5938 unsigned Granule) ->
const MCExpr * {
5942 const MCExpr *AlignToGPR =
5944 const MCExpr *DivGPR =
5950 VGPRBlocks = GetNumGPRBlocks(
5959bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5960 if (!getSTI().getTargetTriple().isAMDGCN())
5961 return TokError(
"directive only supported for amdgcn architecture");
5964 return TokError(
"directive only supported for amdhsa OS");
5966 StringRef KernelName;
5967 if (getParser().parseIdentifier(KernelName))
5970 AMDGPU::MCKernelDescriptor KD =
5982 const MCExpr *NextFreeVGPR = ZeroExpr;
5984 const MCExpr *NamedBarCnt = ZeroExpr;
5985 uint64_t SharedVGPRCount = 0;
5986 uint64_t PreloadLength = 0;
5987 uint64_t PreloadOffset = 0;
5989 const MCExpr *NextFreeSGPR = ZeroExpr;
5992 unsigned ImpliedUserSGPRCount = 0;
5996 std::optional<unsigned> ExplicitUserSGPRCount;
5997 const MCExpr *ReserveVCC = OneExpr;
5998 const MCExpr *ReserveFlatScr = OneExpr;
5999 std::optional<bool> EnableWavefrontSize32;
6005 SMRange IDRange = getTok().getLocRange();
6006 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6009 if (
ID ==
".end_amdhsa_kernel")
6013 return TokError(
".amdhsa_ directives cannot be repeated");
6015 SMLoc ValStart = getLoc();
6016 const MCExpr *ExprVal;
6017 if (getParser().parseExpression(ExprVal))
6019 SMLoc ValEnd = getLoc();
6020 SMRange ValRange = SMRange(ValStart, ValEnd);
6023 uint64_t Val = IVal;
6024 bool EvaluatableExpr;
6025 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6027 return OutOfRangeError(ValRange);
6031#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6032 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6033 return OutOfRangeError(RANGE); \
6034 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6039#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6041 return Error(IDRange.Start, "directive should have resolvable expression", \
6044 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6047 return OutOfRangeError(ValRange);
6049 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6052 return OutOfRangeError(ValRange);
6054 }
else if (
ID ==
".amdhsa_kernarg_size") {
6056 return OutOfRangeError(ValRange);
6058 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6060 ExplicitUserSGPRCount = Val;
6061 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6065 "directive is not supported with architected flat scratch",
6068 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6071 ImpliedUserSGPRCount += 4;
6072 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6075 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6078 return OutOfRangeError(ValRange);
6082 ImpliedUserSGPRCount += Val;
6083 PreloadLength = Val;
6085 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6088 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6091 return OutOfRangeError(ValRange);
6095 PreloadOffset = Val;
6096 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6099 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6102 ImpliedUserSGPRCount += 2;
6103 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6106 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6109 ImpliedUserSGPRCount += 2;
6110 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6113 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6116 ImpliedUserSGPRCount += 2;
6117 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6120 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6123 ImpliedUserSGPRCount += 2;
6124 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6127 "directive is not supported with architected flat scratch",
6131 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6134 ImpliedUserSGPRCount += 2;
6135 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6138 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6141 ImpliedUserSGPRCount += 1;
6142 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6144 if (IVersion.
Major < 10)
6145 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6146 EnableWavefrontSize32 = Val;
6148 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6150 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6152 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6154 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6157 "directive is not supported with architected flat scratch",
6160 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6162 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6166 "directive is not supported without architected flat scratch",
6169 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6171 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6173 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6175 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6177 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6179 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6181 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6183 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6185 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6187 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6189 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6191 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6192 VGPRRange = ValRange;
6193 NextFreeVGPR = ExprVal;
6194 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6195 SGPRRange = ValRange;
6196 NextFreeSGPR = ExprVal;
6197 }
else if (
ID ==
".amdhsa_accum_offset") {
6199 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6200 AccumOffset = ExprVal;
6201 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6203 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6204 NamedBarCnt = ExprVal;
6205 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6207 return OutOfRangeError(ValRange);
6208 ReserveVCC = ExprVal;
6209 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6210 if (IVersion.
Major < 7)
6211 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6214 "directive is not supported with architected flat scratch",
6217 return OutOfRangeError(ValRange);
6218 ReserveFlatScr = ExprVal;
6219 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6220 if (IVersion.
Major < 8)
6221 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6223 return OutOfRangeError(ValRange);
6224 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6225 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6227 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6229 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6231 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6233 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6235 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6237 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6239 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6241 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6243 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6244 if (!getSTI().hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6245 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6248 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6250 }
else if (
ID ==
".amdhsa_ieee_mode") {
6251 if (!getSTI().hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6252 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6255 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6257 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6258 if (IVersion.
Major < 9)
6259 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6261 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6263 }
else if (
ID ==
".amdhsa_tg_split") {
6265 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6268 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6271 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6273 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6275 }
else if (
ID ==
".amdhsa_memory_ordered") {
6276 if (IVersion.
Major < 10)
6277 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6279 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6281 }
else if (
ID ==
".amdhsa_forward_progress") {
6282 if (IVersion.
Major < 10)
6283 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6285 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6287 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6289 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6290 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6292 SharedVGPRCount = Val;
6294 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6296 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6297 if (IVersion.
Major < 11)
6298 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6299 if (IVersion.
Major == 11) {
6301 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6305 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6308 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6311 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6313 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6315 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6317 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6320 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6322 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6324 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6326 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6328 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6330 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6332 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6334 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6336 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6338 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6339 if (IVersion.
Major < 12)
6340 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6342 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6345 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6348#undef PARSE_BITS_ENTRY
6351 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6352 return TokError(
".amdhsa_next_free_vgpr directive is required");
6354 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6355 return TokError(
".amdhsa_next_free_sgpr directive is required");
6357 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6362 if (PreloadLength) {
6368 const MCExpr *VGPRBlocks;
6369 const MCExpr *SGPRBlocks;
6370 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6371 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6372 EnableWavefrontSize32, NextFreeVGPR,
6373 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6377 int64_t EvaluatedVGPRBlocks;
6378 bool VGPRBlocksEvaluatable =
6379 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6380 if (VGPRBlocksEvaluatable &&
6382 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6383 return OutOfRangeError(VGPRRange);
6387 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6388 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6390 int64_t EvaluatedSGPRBlocks;
6391 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6393 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6394 return OutOfRangeError(SGPRRange);
6397 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6398 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6400 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6401 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6402 "enabled user SGPRs");
6406 return TokError(
"too many user SGPRs enabled");
6410 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6411 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6415 return TokError(
"too many user SGPRs enabled");
6419 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6420 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6425 return TokError(
"Kernarg size should be resolvable");
6426 uint64_t kernarg_size = IVal;
6427 if (PreloadLength && kernarg_size &&
6428 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6429 return TokError(
"Kernarg preload length + offset is larger than the "
6430 "kernarg segment size");
6433 if (!Seen.
contains(
".amdhsa_accum_offset"))
6434 return TokError(
".amdhsa_accum_offset directive is required");
6435 int64_t EvaluatedAccum;
6436 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6437 uint64_t UEvaluatedAccum = EvaluatedAccum;
6438 if (AccumEvaluatable &&
6439 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6440 return TokError(
"accum_offset should be in range [4..256] in "
6443 int64_t EvaluatedNumVGPR;
6444 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6447 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6448 return TokError(
"accum_offset exceeds total VGPR allocation");
6454 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6455 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6461 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6462 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6465 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6467 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6468 return TokError(
"shared_vgpr_count directive not valid on "
6469 "wavefront size 32");
6472 if (VGPRBlocksEvaluatable &&
6473 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6475 return TokError(
"shared_vgpr_count*2 + "
6476 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6481 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6482 NextFreeVGPR, NextFreeSGPR,
6483 ReserveVCC, ReserveFlatScr);
6487bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6489 if (ParseAsAbsoluteExpression(
Version))
6492 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6496bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6497 AMDGPUMCKernelCodeT &
C) {
6500 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6501 Parser.eatToEndOfStatement();
6505 SmallString<40> ErrStr;
6506 raw_svector_ostream Err(ErrStr);
6507 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6508 return TokError(Err.
str());
6512 if (
ID ==
"enable_wavefront_size32") {
6515 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6517 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6520 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6524 if (
ID ==
"wavefront_size") {
6525 if (
C.wavefront_size == 5) {
6527 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6529 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6530 }
else if (
C.wavefront_size == 6) {
6532 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6539bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6540 AMDGPUMCKernelCodeT KernelCode;
6549 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6552 if (
ID ==
".end_amd_kernel_code_t")
6555 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6560 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6565bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6566 StringRef KernelName;
6567 if (!parseId(KernelName,
"expected symbol name"))
6570 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6577bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6578 if (!getSTI().getTargetTriple().isAMDGCN()) {
6579 return Error(getLoc(),
6580 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6584 auto TargetIDDirective = getLexer().getTok().getStringContents();
6585 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6586 return Error(getParser().getTok().getLoc(),
"target id must match options");
6588 getTargetStreamer().EmitISAVersion();
6594bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6597 std::string HSAMetadataString;
6602 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6603 return Error(getLoc(),
"invalid HSA metadata");
6610bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6611 const char *AssemblerDirectiveEnd,
6612 std::string &CollectString) {
6614 raw_string_ostream CollectStream(CollectString);
6616 getLexer().setSkipSpace(
false);
6618 bool FoundEnd =
false;
6621 CollectStream << getTokenStr();
6625 if (trySkipId(AssemblerDirectiveEnd)) {
6630 CollectStream << Parser.parseStringToEndOfStatement()
6631 <<
getContext().getAsmInfo()->getSeparatorString();
6633 Parser.eatToEndOfStatement();
6636 getLexer().setSkipSpace(
true);
6639 return TokError(Twine(
"expected directive ") +
6640 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6647bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6653 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6654 if (!PALMetadata->setFromString(
String))
6655 return Error(getLoc(),
"invalid PAL metadata");
6660bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6662 return Error(getLoc(),
6664 "not available on non-amdpal OSes")).str());
6667 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6668 PALMetadata->setLegacy();
6671 if (ParseAsAbsoluteExpression(
Key)) {
6672 return TokError(Twine(
"invalid value in ") +
6676 return TokError(Twine(
"expected an even number of values in ") +
6679 if (ParseAsAbsoluteExpression(
Value)) {
6680 return TokError(Twine(
"invalid value in ") +
6683 PALMetadata->setRegister(
Key,
Value);
6692bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6693 if (getParser().checkForValidSection())
6697 SMLoc NameLoc = getLoc();
6698 if (getParser().parseIdentifier(Name))
6699 return TokError(
"expected identifier in directive");
6702 if (getParser().parseComma())
6708 SMLoc SizeLoc = getLoc();
6709 if (getParser().parseAbsoluteExpression(
Size))
6712 return Error(SizeLoc,
"size must be non-negative");
6713 if (
Size > LocalMemorySize)
6714 return Error(SizeLoc,
"size is too large");
6716 int64_t Alignment = 4;
6718 SMLoc AlignLoc = getLoc();
6719 if (getParser().parseAbsoluteExpression(Alignment))
6722 return Error(AlignLoc,
"alignment must be a power of two");
6727 if (Alignment >= 1u << 31)
6728 return Error(AlignLoc,
"alignment is too large");
6734 Symbol->redefineIfPossible();
6735 if (!
Symbol->isUndefined())
6736 return Error(NameLoc,
"invalid symbol redefinition");
6738 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6742bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6743 StringRef IDVal = DirectiveID.
getString();
6746 if (IDVal ==
".amdhsa_kernel")
6747 return ParseDirectiveAMDHSAKernel();
6749 if (IDVal ==
".amdhsa_code_object_version")
6750 return ParseDirectiveAMDHSACodeObjectVersion();
6754 return ParseDirectiveHSAMetadata();
6756 if (IDVal ==
".amd_kernel_code_t")
6757 return ParseDirectiveAMDKernelCodeT();
6759 if (IDVal ==
".amdgpu_hsa_kernel")
6760 return ParseDirectiveAMDGPUHsaKernel();
6762 if (IDVal ==
".amd_amdgpu_isa")
6763 return ParseDirectiveISAVersion();
6767 Twine(
" directive is "
6768 "not available on non-amdhsa OSes"))
6773 if (IDVal ==
".amdgcn_target")
6774 return ParseDirectiveAMDGCNTarget();
6776 if (IDVal ==
".amdgpu_lds")
6777 return ParseDirectiveAMDGPULDS();
6780 return ParseDirectivePALMetadataBegin();
6783 return ParseDirectivePALMetadata();
6788bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &MRI,
6795 return hasSGPR104_SGPR105();
6798 case SRC_SHARED_BASE_LO:
6799 case SRC_SHARED_BASE:
6800 case SRC_SHARED_LIMIT_LO:
6801 case SRC_SHARED_LIMIT:
6802 case SRC_PRIVATE_BASE_LO:
6803 case SRC_PRIVATE_BASE:
6804 case SRC_PRIVATE_LIMIT_LO:
6805 case SRC_PRIVATE_LIMIT:
6807 case SRC_FLAT_SCRATCH_BASE_LO:
6808 case SRC_FLAT_SCRATCH_BASE_HI:
6809 return hasGloballyAddressableScratch();
6810 case SRC_POPS_EXITING_WAVE_ID:
6822 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6852 return hasSGPR102_SGPR103();
6857ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6860 ParseStatus Res = parseVOPD(Operands);
6865 Res = MatchOperandParserImpl(Operands, Mnemonic);
6877 SMLoc LBraceLoc = getLoc();
6882 auto Loc = getLoc();
6883 Res = parseReg(Operands);
6885 Error(Loc,
"expected a register");
6889 RBraceLoc = getLoc();
6894 "expected a comma or a closing square bracket"))
6898 if (Operands.
size() - Prefix > 1) {
6900 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6901 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6907 return parseRegOrImm(Operands);
6910StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6912 setForcedEncodingSize(0);
6913 setForcedDPP(
false);
6914 setForcedSDWA(
false);
6916 if (
Name.consume_back(
"_e64_dpp")) {
6918 setForcedEncodingSize(64);
6921 if (
Name.consume_back(
"_e64")) {
6922 setForcedEncodingSize(64);
6925 if (
Name.consume_back(
"_e32")) {
6926 setForcedEncodingSize(32);
6929 if (
Name.consume_back(
"_dpp")) {
6933 if (
Name.consume_back(
"_sdwa")) {
6934 setForcedSDWA(
true);
6942 unsigned VariantID);
6948 Name = parseMnemonicSuffix(Name);
6954 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6956 bool IsMIMG = Name.starts_with(
"image_");
6959 OperandMode
Mode = OperandMode_Default;
6961 Mode = OperandMode_NSA;
6965 checkUnsupportedInstruction(Name, NameLoc);
6966 if (!Parser.hasPendingError()) {
6969 :
"not a valid operand.";
6970 Error(getLoc(), Msg);
6989ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6992 if (!trySkipId(Name))
6995 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6999ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7008ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7009 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7010 std::function<
bool(int64_t &)> ConvertResult) {
7014 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7018 if (ConvertResult && !ConvertResult(
Value)) {
7019 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7022 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7026ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7027 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7028 bool (*ConvertResult)(int64_t &)) {
7037 const unsigned MaxSize = 4;
7041 for (
int I = 0; ; ++
I) {
7043 SMLoc Loc = getLoc();
7047 if (
Op != 0 &&
Op != 1)
7048 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7055 if (
I + 1 == MaxSize)
7056 return Error(getLoc(),
"expected a closing square bracket");
7062 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7066ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7068 AMDGPUOperand::ImmTy ImmTy,
7069 bool IgnoreNegative) {
7073 if (trySkipId(Name)) {
7075 }
else if (trySkipId(
"no", Name)) {
7084 return Error(S,
"r128 modifier is not supported on this GPU");
7085 if (Name ==
"a16" && !
hasA16())
7086 return Error(S,
"a16 modifier is not supported on this GPU");
7088 if (Bit == 0 && Name ==
"gds") {
7089 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7091 return Error(S,
"nogds is not allowed");
7094 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7095 ImmTy = AMDGPUOperand::ImmTyR128A16;
7097 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7101unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7102 bool &Disabling)
const {
7103 Disabling =
Id.consume_front(
"no");
7106 return StringSwitch<unsigned>(Id)
7113 return StringSwitch<unsigned>(Id)
7121ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7123 SMLoc StringLoc = getLoc();
7125 int64_t CPolVal = 0;
7134 ResTH = parseTH(Operands, TH);
7145 ResScope = parseScope(Operands, Scope);
7158 if (trySkipId(
"nv")) {
7162 }
else if (trySkipId(
"no",
"nv")) {
7169 if (trySkipId(
"scale_offset")) {
7173 }
else if (trySkipId(
"no",
"scale_offset")) {
7186 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7187 AMDGPUOperand::ImmTyCPol));
7191 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7192 SMLoc OpLoc = getLoc();
7193 unsigned Enabled = 0, Seen = 0;
7197 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7204 return Error(S,
"dlc modifier is not supported on this GPU");
7207 return Error(S,
"scc modifier is not supported on this GPU");
7210 return Error(S,
"duplicate cache policy modifier");
7222 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7226ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7231 ParseStatus Res = parseStringOrIntWithPrefix(
7232 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7241ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7246 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7250 if (
Value ==
"TH_DEFAULT")
7252 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7253 Value ==
"TH_LOAD_NT_WB") {
7254 return Error(StringLoc,
"invalid th value");
7255 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7257 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7259 }
else if (
Value.consume_front(
"TH_STORE_")) {
7262 return Error(StringLoc,
"invalid th value");
7265 if (
Value ==
"BYPASS")
7270 TH |= StringSwitch<int64_t>(
Value)
7280 .Default(0xffffffff);
7282 TH |= StringSwitch<int64_t>(
Value)
7293 .Default(0xffffffff);
7296 if (TH == 0xffffffff)
7297 return Error(StringLoc,
"invalid th value");
7304 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7305 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7306 std::optional<unsigned> InsertAt = std::nullopt) {
7307 auto i = OptionalIdx.find(ImmT);
7308 if (i != OptionalIdx.end()) {
7309 unsigned Idx = i->second;
7310 const AMDGPUOperand &
Op =
7311 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7315 Op.addImmOperands(Inst, 1);
7317 if (InsertAt.has_value())
7324ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7330 StringLoc = getLoc();
7335ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7336 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7341 SMLoc StringLoc = getLoc();
7345 Value = getTokenStr();
7349 if (
Value == Ids[IntVal])
7354 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7355 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7360ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7361 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7362 AMDGPUOperand::ImmTy
Type) {
7366 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7368 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7377bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7381 SMLoc Loc = getLoc();
7383 auto Res = parseIntWithPrefix(Pref, Val);
7389 if (Val < 0 || Val > MaxVal) {
7390 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7398ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7399 AMDGPUOperand::ImmTy ImmTy) {
7400 const char *Pref =
"index_key";
7402 SMLoc Loc = getLoc();
7403 auto Res = parseIntWithPrefix(Pref, ImmVal);
7407 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7408 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7409 (ImmVal < 0 || ImmVal > 1))
7410 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7412 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7413 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7415 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7419ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7420 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7423ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7424 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7427ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7428 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7431ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7433 AMDGPUOperand::ImmTy
Type) {
7438ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7439 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7440 AMDGPUOperand::ImmTyMatrixAFMT);
7443ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7444 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7445 AMDGPUOperand::ImmTyMatrixBFMT);
7448ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7450 AMDGPUOperand::ImmTy
Type) {
7455ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7456 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7457 AMDGPUOperand::ImmTyMatrixAScale);
7460ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7461 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7462 AMDGPUOperand::ImmTyMatrixBScale);
7465ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7467 AMDGPUOperand::ImmTy
Type) {
7472ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7473 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7474 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7477ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7478 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7479 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7484ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7485 using namespace llvm::AMDGPU::MTBUFFormat;
7491 for (
int I = 0;
I < 2; ++
I) {
7492 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7495 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7500 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7506 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7509 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7510 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7516ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7517 using namespace llvm::AMDGPU::MTBUFFormat;
7521 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7524 if (Fmt == UFMT_UNDEF)
7531bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7533 StringRef FormatStr,
7535 using namespace llvm::AMDGPU::MTBUFFormat;
7539 if (
Format != DFMT_UNDEF) {
7545 if (
Format != NFMT_UNDEF) {
7550 Error(Loc,
"unsupported format");
7554ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7557 using namespace llvm::AMDGPU::MTBUFFormat;
7561 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7566 SMLoc Loc = getLoc();
7567 if (!parseId(Str,
"expected a format string") ||
7568 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7570 if (Dfmt == DFMT_UNDEF)
7571 return Error(Loc,
"duplicate numeric format");
7572 if (Nfmt == NFMT_UNDEF)
7573 return Error(Loc,
"duplicate data format");
7576 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7577 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7581 if (Ufmt == UFMT_UNDEF)
7582 return Error(FormatLoc,
"unsupported format");
7591ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7594 using namespace llvm::AMDGPU::MTBUFFormat;
7597 if (Id == UFMT_UNDEF)
7601 return Error(Loc,
"unified format is not supported on this GPU");
7607ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7608 using namespace llvm::AMDGPU::MTBUFFormat;
7609 SMLoc Loc = getLoc();
7614 return Error(Loc,
"out of range format");
7619ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7620 using namespace llvm::AMDGPU::MTBUFFormat;
7626 StringRef FormatStr;
7627 SMLoc Loc = getLoc();
7628 if (!parseId(FormatStr,
"expected a format string"))
7631 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7633 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7643 return parseNumericFormat(
Format);
7646ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7647 using namespace llvm::AMDGPU::MTBUFFormat;
7651 SMLoc Loc = getLoc();
7661 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7673 Res = parseRegOrImm(Operands);
7680 Res = parseSymbolicOrNumericFormat(
Format);
7685 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7686 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7693 return Error(getLoc(),
"duplicate format");
7697ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7699 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7701 Res = parseIntWithPrefix(
"inst_offset", Operands,
7702 AMDGPUOperand::ImmTyInstOffset);
7707ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7709 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7711 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7715ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7717 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7720 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7729void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7730 OptionalImmIndexMap OptionalIdx;
7732 unsigned OperandIdx[4];
7733 unsigned EnMask = 0;
7736 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7737 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7742 OperandIdx[SrcIdx] = Inst.
size();
7743 Op.addRegOperands(Inst, 1);
7750 OperandIdx[SrcIdx] = Inst.
size();
7756 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7757 Op.addImmOperands(Inst, 1);
7761 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7765 OptionalIdx[
Op.getImmTy()] = i;
7771 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7778 for (
auto i = 0; i < SrcIdx; ++i) {
7780 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7805 IntVal =
encode(ISA, IntVal, CntVal);
7806 if (CntVal !=
decode(ISA, IntVal)) {
7808 IntVal =
encode(ISA, IntVal, -1);
7816bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7818 SMLoc CntLoc = getLoc();
7819 StringRef CntName = getTokenStr();
7826 SMLoc ValLoc = getLoc();
7835 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7837 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7839 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7842 Error(CntLoc,
"invalid counter name " + CntName);
7847 Error(ValLoc,
"too large value for " + CntName);
7856 Error(getLoc(),
"expected a counter name");
7864ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7871 if (!parseCnt(Waitcnt))
7879 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7883bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7884 SMLoc FieldLoc = getLoc();
7885 StringRef FieldName = getTokenStr();
7890 SMLoc ValueLoc = getLoc();
7897 if (FieldName ==
"instid0") {
7899 }
else if (FieldName ==
"instskip") {
7901 }
else if (FieldName ==
"instid1") {
7904 Error(FieldLoc,
"invalid field name " + FieldName);
7923 .Case(
"VALU_DEP_1", 1)
7924 .Case(
"VALU_DEP_2", 2)
7925 .Case(
"VALU_DEP_3", 3)
7926 .Case(
"VALU_DEP_4", 4)
7927 .Case(
"TRANS32_DEP_1", 5)
7928 .Case(
"TRANS32_DEP_2", 6)
7929 .Case(
"TRANS32_DEP_3", 7)
7930 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7931 .Case(
"SALU_CYCLE_1", 9)
7932 .Case(
"SALU_CYCLE_2", 10)
7933 .Case(
"SALU_CYCLE_3", 11)
7941 Delay |=
Value << Shift;
7945ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7951 if (!parseDelay(Delay))
7959 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7964AMDGPUOperand::isSWaitCnt()
const {
7968bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7974void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7975 StringRef DepCtrName) {
7978 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7981 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7984 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7987 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7994bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7996 using namespace llvm::AMDGPU::DepCtr;
7998 SMLoc DepCtrLoc = getLoc();
7999 StringRef DepCtrName = getTokenStr();
8009 unsigned PrevOprMask = UsedOprMask;
8010 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8013 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8022 Error(getLoc(),
"expected a counter name");
8027 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
8028 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8032ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
8033 using namespace llvm::AMDGPU::DepCtr;
8036 SMLoc Loc = getLoc();
8039 unsigned UsedOprMask = 0;
8041 if (!parseDepCtr(DepCtr, UsedOprMask))
8049 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8053bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8059ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8061 OperandInfoTy &Width) {
8062 using namespace llvm::AMDGPU::Hwreg;
8068 HwReg.Loc = getLoc();
8071 HwReg.IsSymbolic =
true;
8073 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8081 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8091 Width.Loc = getLoc();
8099ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8100 using namespace llvm::AMDGPU::Hwreg;
8103 SMLoc Loc = getLoc();
8105 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8107 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8108 HwregOffset::Default);
8109 struct : StructuredOpField {
8110 using StructuredOpField::StructuredOpField;
8111 bool validate(AMDGPUAsmParser &Parser)
const override {
8113 return Error(Parser,
"only values from 1 to 32 are legal");
8116 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8117 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8120 Res = parseHwregFunc(HwReg,
Offset, Width);
8123 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8125 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8129 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8136 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8138 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8142bool AMDGPUOperand::isHwreg()
const {
8143 return isImmTy(ImmTyHwreg);
8151AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8153 OperandInfoTy &Stream) {
8154 using namespace llvm::AMDGPU::SendMsg;
8159 Msg.IsSymbolic =
true;
8161 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8166 Op.IsDefined =
true;
8169 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8172 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8177 Stream.IsDefined =
true;
8178 Stream.Loc = getLoc();
8188AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8189 const OperandInfoTy &
Op,
8190 const OperandInfoTy &Stream) {
8191 using namespace llvm::AMDGPU::SendMsg;
8196 bool Strict = Msg.IsSymbolic;
8200 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8205 Error(Msg.Loc,
"invalid message id");
8211 Error(
Op.Loc,
"message does not support operations");
8213 Error(Msg.Loc,
"missing message operation");
8219 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8221 Error(
Op.Loc,
"invalid operation id");
8226 Error(Stream.Loc,
"message operation does not support streams");
8230 Error(Stream.Loc,
"invalid message stream id");
8236ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8237 using namespace llvm::AMDGPU::SendMsg;
8240 SMLoc Loc = getLoc();
8244 OperandInfoTy
Op(OP_NONE_);
8245 OperandInfoTy Stream(STREAM_ID_NONE_);
8246 if (parseSendMsgBody(Msg,
Op, Stream) &&
8247 validateSendMsg(Msg,
Op, Stream)) {
8252 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8254 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8259 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8263bool AMDGPUOperand::isSendMsg()
const {
8264 return isImmTy(ImmTySendMsg);
8267ParseStatus AMDGPUAsmParser::parseWaitEvent(
OperandVector &Operands) {
8268 using namespace llvm::AMDGPU::WaitEvent;
8270 SMLoc Loc = getLoc();
8273 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8275 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8277 StructuredOpField *TargetBitfield =
8278 isGFX11() ? &DontWaitExportReady : &ExportReady;
8280 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8284 if (!validateStructuredOpFields({TargetBitfield}))
8286 ImmVal = TargetBitfield->Val;
8293 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8295 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8296 AMDGPUOperand::ImmTyWaitEvent));
8300bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8306ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8313 int Slot = StringSwitch<int>(Str)
8320 return Error(S,
"invalid interpolation slot");
8322 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8323 AMDGPUOperand::ImmTyInterpSlot));
8327ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8334 if (!Str.starts_with(
"attr"))
8335 return Error(S,
"invalid interpolation attribute");
8337 StringRef Chan = Str.take_back(2);
8338 int AttrChan = StringSwitch<int>(Chan)
8345 return Error(S,
"invalid or missing interpolation attribute channel");
8347 Str = Str.drop_back(2).drop_front(4);
8350 if (Str.getAsInteger(10, Attr))
8351 return Error(S,
"invalid or missing interpolation attribute number");
8354 return Error(S,
"out of bounds interpolation attribute number");
8358 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8359 AMDGPUOperand::ImmTyInterpAttr));
8360 Operands.
push_back(AMDGPUOperand::CreateImm(
8361 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8369ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8370 using namespace llvm::AMDGPU::Exp;
8380 return Error(S, (Id == ET_INVALID)
8381 ?
"invalid exp target"
8382 :
"exp target is not supported on this GPU");
8384 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8385 AMDGPUOperand::ImmTyExpTgt));
8394AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8399AMDGPUAsmParser::isId(
const StringRef Id)
const {
8405 return getTokenKind() ==
Kind;
8408StringRef AMDGPUAsmParser::getId()
const {
8413AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8422AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8424 StringRef Tok = getTokenStr();
8435 if (isId(Id) && peekToken().is(Kind)) {
8445 if (isToken(Kind)) {
8454 const StringRef ErrMsg) {
8455 if (!trySkipToken(Kind)) {
8456 Error(getLoc(), ErrMsg);
8463AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8467 if (Parser.parseExpression(Expr))
8470 if (Expr->evaluateAsAbsolute(
Imm))
8473 if (Expected.empty()) {
8474 Error(S,
"expected absolute expression");
8476 Error(S, Twine(
"expected ", Expected) +
8477 Twine(
" or an absolute expression"));
8487 if (Parser.parseExpression(Expr))
8491 if (Expr->evaluateAsAbsolute(IntVal)) {
8492 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8494 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8500AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8502 Val =
getToken().getStringContents();
8506 Error(getLoc(), ErrMsg);
8511AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8513 Val = getTokenStr();
8517 if (!ErrMsg.
empty())
8518 Error(getLoc(), ErrMsg);
8523AMDGPUAsmParser::getToken()
const {
8524 return Parser.getTok();
8527AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8530 : getLexer().peekTok(ShouldSkipSpace);
8535 auto TokCount = getLexer().peekTokens(Tokens);
8537 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8542AMDGPUAsmParser::getTokenKind()
const {
8543 return getLexer().getKind();
8547AMDGPUAsmParser::getLoc()
const {
8552AMDGPUAsmParser::getTokenStr()
const {
8557AMDGPUAsmParser::lex() {
8561SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8562 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8566SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8570SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8571 int MCOpIdx)
const {
8572 for (
const auto &
Op : Operands) {
8573 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8574 if (TargetOp.getMCOpIdx() == MCOpIdx)
8575 return TargetOp.getStartLoc();
8581AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8583 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8584 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8586 return Op.getStartLoc();
8588 return getInstLoc(Operands);
8592AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8594 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8595 return getOperandLoc(
Test, Operands);
8609 StringRef
Id = getTokenStr();
8610 SMLoc IdLoc = getLoc();
8616 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8617 if (
I == Fields.
end())
8618 return Error(IdLoc,
"unknown field");
8619 if ((*I)->IsDefined)
8620 return Error(IdLoc,
"duplicate field");
8623 (*I)->Loc = getLoc();
8626 (*I)->IsDefined =
true;
8633bool AMDGPUAsmParser::validateStructuredOpFields(
8635 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8636 return F->validate(*
this);
8647 const unsigned OrMask,
8648 const unsigned XorMask) {
8657bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8658 const unsigned MaxVal,
8659 const Twine &ErrMsg, SMLoc &Loc) {
8676AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8677 const unsigned MinVal,
8678 const unsigned MaxVal,
8679 const StringRef ErrMsg) {
8681 for (
unsigned i = 0; i < OpNum; ++i) {
8682 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8690AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8691 using namespace llvm::AMDGPU::Swizzle;
8694 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8695 "expected a 2-bit lane id")) {
8706AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8707 using namespace llvm::AMDGPU::Swizzle;
8713 if (!parseSwizzleOperand(GroupSize,
8715 "group size must be in the interval [2,32]",
8720 Error(Loc,
"group size must be a power of two");
8723 if (parseSwizzleOperand(LaneIdx,
8725 "lane id must be in the interval [0,group size - 1]",
8734AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8735 using namespace llvm::AMDGPU::Swizzle;
8740 if (!parseSwizzleOperand(GroupSize,
8742 "group size must be in the interval [2,32]",
8747 Error(Loc,
"group size must be a power of two");
8756AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8757 using namespace llvm::AMDGPU::Swizzle;
8762 if (!parseSwizzleOperand(GroupSize,
8764 "group size must be in the interval [1,16]",
8769 Error(Loc,
"group size must be a power of two");
8778AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8779 using namespace llvm::AMDGPU::Swizzle;
8786 SMLoc StrLoc = getLoc();
8787 if (!parseString(Ctl)) {
8790 if (Ctl.
size() != BITMASK_WIDTH) {
8791 Error(StrLoc,
"expected a 5-character mask");
8795 unsigned AndMask = 0;
8796 unsigned OrMask = 0;
8797 unsigned XorMask = 0;
8799 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8803 Error(StrLoc,
"invalid mask");
8824bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8825 using namespace llvm::AMDGPU::Swizzle;
8828 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8834 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8835 "FFT swizzle must be in the interval [0," +
8836 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8844bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8845 using namespace llvm::AMDGPU::Swizzle;
8848 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8855 if (!parseSwizzleOperand(
Direction, 0, 1,
8856 "direction must be 0 (left) or 1 (right)", Loc))
8860 if (!parseSwizzleOperand(
8861 RotateSize, 0, ROTATE_MAX_SIZE,
8862 "number of threads to rotate must be in the interval [0," +
8863 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8868 (RotateSize << ROTATE_SIZE_SHIFT);
8873AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8875 SMLoc OffsetLoc = getLoc();
8881 Error(OffsetLoc,
"expected a 16-bit offset");
8888AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8889 using namespace llvm::AMDGPU::Swizzle;
8893 SMLoc ModeLoc = getLoc();
8896 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8897 Ok = parseSwizzleQuadPerm(
Imm);
8898 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8899 Ok = parseSwizzleBitmaskPerm(
Imm);
8900 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8901 Ok = parseSwizzleBroadcast(
Imm);
8902 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8903 Ok = parseSwizzleSwap(
Imm);
8904 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8905 Ok = parseSwizzleReverse(
Imm);
8906 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8907 Ok = parseSwizzleFFT(
Imm);
8908 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8909 Ok = parseSwizzleRotate(
Imm);
8911 Error(ModeLoc,
"expected a swizzle mode");
8914 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8920ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8924 if (trySkipId(
"offset")) {
8928 if (trySkipId(
"swizzle")) {
8929 Ok = parseSwizzleMacro(
Imm);
8931 Ok = parseSwizzleOffset(
Imm);
8935 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8943AMDGPUOperand::isSwizzle()
const {
8944 return isImmTy(ImmTySwizzle);
8951int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8953 using namespace llvm::AMDGPU::VGPRIndexMode;
8965 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8966 if (trySkipId(IdSymbolic[ModeId])) {
8974 "expected a VGPR index mode or a closing parenthesis" :
8975 "expected a VGPR index mode");
8980 Error(S,
"duplicate VGPR index mode");
8988 "expected a comma or a closing parenthesis"))
8995ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8997 using namespace llvm::AMDGPU::VGPRIndexMode;
9003 Imm = parseGPRIdxMacro();
9007 if (getParser().parseAbsoluteExpression(
Imm))
9010 return Error(S,
"invalid immediate: only 4-bit values are legal");
9014 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9018bool AMDGPUOperand::isGPRIdxMode()
const {
9019 return isImmTy(ImmTyGprIdxMode);
9026ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
9031 if (isRegister() || isModifier())
9037 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
9038 assert(Opr.isImm() || Opr.isExpr());
9039 SMLoc Loc = Opr.getStartLoc();
9043 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9044 Error(Loc,
"expected an absolute expression or a label");
9045 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9046 Error(Loc,
"expected a 16-bit signed jump offset");
9056ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
9057 return parseReg(Operands);
9064void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
9067 OptionalImmIndexMap OptionalIdx;
9068 unsigned FirstOperandIdx = 1;
9069 bool IsAtomicReturn =
false;
9076 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9077 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9081 Op.addRegOperands(Inst, 1);
9085 if (IsAtomicReturn && i == FirstOperandIdx)
9086 Op.addRegOperands(Inst, 1);
9091 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9092 Op.addImmOperands(Inst, 1);
9104 OptionalIdx[
Op.getImmTy()] = i;
9118bool AMDGPUOperand::isSMRDOffset8()
const {
9122bool AMDGPUOperand::isSMEMOffset()
const {
9124 return isImmLiteral();
9127bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9162bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9163 if (BoundCtrl == 0 || BoundCtrl == 1) {
9171void AMDGPUAsmParser::onBeginOfFile() {
9172 if (!getParser().getStreamer().getTargetStreamer() ||
9176 if (!getTargetStreamer().getTargetID())
9177 getTargetStreamer().initializeTargetID(getSTI(),
9178 getSTI().getFeatureString());
9181 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9189bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9193 StringRef TokenId = getTokenStr();
9194 AGVK VK = StringSwitch<AGVK>(TokenId)
9195 .Case(
"max", AGVK::AGVK_Max)
9196 .Case(
"or", AGVK::AGVK_Or)
9197 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9198 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9199 .Case(
"alignto", AGVK::AGVK_AlignTo)
9200 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9201 .Default(AGVK::AGVK_None);
9205 uint64_t CommaCount = 0;
9210 if (Exprs.
empty()) {
9212 "empty " + Twine(TokenId) +
" expression");
9215 if (CommaCount + 1 != Exprs.
size()) {
9217 "mismatch of commas in " + Twine(TokenId) +
" expression");
9224 if (getParser().parseExpression(Expr, EndLoc))
9228 if (LastTokenWasComma)
9232 "unexpected token in " + Twine(TokenId) +
" expression");
9238 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9241ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9242 StringRef
Name = getTokenStr();
9243 if (Name ==
"mul") {
9244 return parseIntWithPrefix(
"mul", Operands,
9248 if (Name ==
"div") {
9249 return parseIntWithPrefix(
"div", Operands,
9260 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9265 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9266 AMDGPU::OpName::src2};
9274 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9279 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9281 if (
DstOp.isReg() &&
9286 if ((OpSel & (1 << SrcNum)) != 0)
9292void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9294 cvtVOP3P(Inst, Operands);
9298void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9299 OptionalImmIndexMap &OptionalIdx) {
9300 cvtVOP3P(Inst, Operands, OptionalIdx);
9309 &&
Desc.NumOperands > (OpNum + 1)
9311 &&
Desc.operands()[OpNum + 1].RegClass != -1
9313 &&
Desc.getOperandConstraint(OpNum + 1,
9317void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9319 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9320 AMDGPU::OpName::src2};
9321 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9322 AMDGPU::OpName::src1_modifiers,
9323 AMDGPU::OpName::src2_modifiers};
9324 for (
int J = 0; J < 3; ++J) {
9325 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9331 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9334 if ((OpSel & (1 << J)) != 0)
9337 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9344void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9346 OptionalImmIndexMap OptionalIdx;
9351 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9352 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9355 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9356 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9358 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9359 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9360 Op.isInterpAttrChan()) {
9362 }
else if (
Op.isImmModifier()) {
9363 OptionalIdx[
Op.getImmTy()] =
I;
9371 AMDGPUOperand::ImmTyHigh);
9375 AMDGPUOperand::ImmTyClamp);
9379 AMDGPUOperand::ImmTyOModSI);
9384 AMDGPUOperand::ImmTyOpSel);
9385 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9388 cvtOpSelHelper(Inst, OpSel);
9392void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9394 OptionalImmIndexMap OptionalIdx;
9399 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9400 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9403 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9404 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9406 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9407 }
else if (
Op.isImmModifier()) {
9408 OptionalIdx[
Op.getImmTy()] =
I;
9416 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9426 cvtOpSelHelper(Inst, OpSel);
9429void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9431 OptionalImmIndexMap OptionalIdx;
9434 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9438 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9439 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9441 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9442 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9447 if (NumOperands == CbszOpIdx) {
9452 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9453 }
else if (
Op.isImmModifier()) {
9454 OptionalIdx[
Op.getImmTy()] =
I;
9456 Op.addRegOrImmOperands(Inst, 1);
9461 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9462 if (CbszIdx != OptionalIdx.end()) {
9463 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9467 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9468 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9469 if (BlgpIdx != OptionalIdx.end()) {
9470 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9481 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9482 if (OpselIdx != OptionalIdx.end()) {
9483 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9487 unsigned OpSelHi = 0;
9488 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9489 if (OpselHiIdx != OptionalIdx.end()) {
9490 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9493 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9494 AMDGPU::OpName::src1_modifiers};
9496 for (
unsigned J = 0; J < 2; ++J) {
9497 unsigned ModVal = 0;
9498 if (OpSel & (1 << J))
9500 if (OpSelHi & (1 << J))
9503 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9508void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9509 OptionalImmIndexMap &OptionalIdx) {
9514 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9515 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9518 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9519 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9521 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9522 }
else if (
Op.isImmModifier()) {
9523 OptionalIdx[
Op.getImmTy()] =
I;
9525 Op.addRegOrImmOperands(Inst, 1);
9531 AMDGPUOperand::ImmTyScaleSel);
9535 AMDGPUOperand::ImmTyClamp);
9541 AMDGPUOperand::ImmTyByteSel);
9546 AMDGPUOperand::ImmTyOModSI);
9553 auto *it = Inst.
begin();
9554 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9562void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9563 OptionalImmIndexMap OptionalIdx;
9564 cvtVOP3(Inst, Operands, OptionalIdx);
9567void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9568 OptionalImmIndexMap &OptIdx) {
9574 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9575 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9576 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9577 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9578 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9579 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9580 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9581 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9589 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx11 ||
9590 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx11 ||
9591 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx11 ||
9592 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx11 ||
9593 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx11 ||
9594 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx11 ||
9595 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx11 ||
9596 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx11 ||
9597 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx11 ||
9598 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx11 ||
9599 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx11 ||
9600 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx11 ||
9601 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9602 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9603 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9604 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9605 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9606 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9607 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9608 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9609 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9610 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9611 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9612 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9613 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9614 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9615 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9616 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9617 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9618 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9619 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9620 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9621 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9622 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9623 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9624 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9625 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9626 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9630 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9631 if (BitOp3Idx != -1) {
9638 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9639 if (OpSelIdx != -1) {
9643 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9644 if (OpSelHiIdx != -1) {
9645 int DefaultVal =
IsPacked ? -1 : 0;
9651 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9652 if (MatrixAFMTIdx != -1) {
9654 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9658 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9659 if (MatrixBFMTIdx != -1) {
9661 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9664 int MatrixAScaleIdx =
9665 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9666 if (MatrixAScaleIdx != -1) {
9668 AMDGPUOperand::ImmTyMatrixAScale, 0);
9671 int MatrixBScaleIdx =
9672 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9673 if (MatrixBScaleIdx != -1) {
9675 AMDGPUOperand::ImmTyMatrixBScale, 0);
9678 int MatrixAScaleFmtIdx =
9679 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9680 if (MatrixAScaleFmtIdx != -1) {
9682 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9685 int MatrixBScaleFmtIdx =
9686 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9687 if (MatrixBScaleFmtIdx != -1) {
9689 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9694 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9698 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9700 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9704 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9708 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9709 AMDGPU::OpName::src2};
9710 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9711 AMDGPU::OpName::src1_modifiers,
9712 AMDGPU::OpName::src2_modifiers};
9715 unsigned OpSelHi = 0;
9722 if (OpSelHiIdx != -1)
9731 for (
int J = 0; J < 3; ++J) {
9732 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9736 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9741 uint32_t ModVal = 0;
9744 if (SrcOp.
isReg() && getMRI()
9751 if ((OpSel & (1 << J)) != 0)
9755 if ((OpSelHi & (1 << J)) != 0)
9758 if ((NegLo & (1 << J)) != 0)
9761 if ((NegHi & (1 << J)) != 0)
9768void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9769 OptionalImmIndexMap OptIdx;
9770 cvtVOP3(Inst, Operands, OptIdx);
9771 cvtVOP3P(Inst, Operands, OptIdx);
9775 unsigned i,
unsigned Opc,
9777 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9778 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9780 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9783void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9786 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9789 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9790 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9792 OptionalImmIndexMap OptIdx;
9793 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9794 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9795 OptIdx[
Op.getImmTy()] = i;
9800 AMDGPUOperand::ImmTyIndexKey8bit);
9804 AMDGPUOperand::ImmTyIndexKey16bit);
9808 AMDGPUOperand::ImmTyIndexKey32bit);
9813 cvtVOP3P(Inst, Operands, OptIdx);
9820ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9828 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9829 SMLoc OpYLoc = getLoc();
9832 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9835 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9841void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9844 auto addOp = [&](uint16_t ParsedOprIdx) {
9845 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9847 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9851 Op.addRegOperands(Inst, 1);
9855 Op.addImmOperands(Inst, 1);
9867 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9871 const auto &CInfo = InstInfo[CompIdx];
9872 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9873 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9874 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9875 if (CInfo.hasSrc2Acc())
9876 addOp(CInfo.getIndexOfDstInParsedOperands());
9880 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9881 if (BitOp3Idx != -1) {
9882 OptionalImmIndexMap OptIdx;
9883 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9885 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9895bool AMDGPUOperand::isDPP8()
const {
9896 return isImmTy(ImmTyDPP8);
9899bool AMDGPUOperand::isDPPCtrl()
const {
9900 using namespace AMDGPU::DPP;
9902 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9905 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9906 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9907 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9908 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9909 (
Imm == DppCtrl::WAVE_SHL1) ||
9910 (
Imm == DppCtrl::WAVE_ROL1) ||
9911 (
Imm == DppCtrl::WAVE_SHR1) ||
9912 (
Imm == DppCtrl::WAVE_ROR1) ||
9913 (
Imm == DppCtrl::ROW_MIRROR) ||
9914 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9915 (
Imm == DppCtrl::BCAST15) ||
9916 (
Imm == DppCtrl::BCAST31) ||
9917 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9918 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9927bool AMDGPUOperand::isBLGP()
const {
9931bool AMDGPUOperand::isS16Imm()
const {
9935bool AMDGPUOperand::isU16Imm()
const {
9943bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9948 SMLoc Loc =
getToken().getEndLoc();
9949 Token = std::string(getTokenStr());
9951 if (getLoc() != Loc)
9956 if (!parseId(Suffix))
9960 StringRef DimId = Token;
9971ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9981 SMLoc Loc = getLoc();
9982 if (!parseDimId(Encoding))
9983 return Error(Loc,
"invalid dim value");
9985 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9986 AMDGPUOperand::ImmTyDim));
9994ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
10004 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10007 for (
size_t i = 0; i < 8; ++i) {
10011 SMLoc Loc = getLoc();
10012 if (getParser().parseAbsoluteExpression(Sels[i]))
10014 if (0 > Sels[i] || 7 < Sels[i])
10015 return Error(Loc,
"expected a 3-bit value");
10018 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10022 for (
size_t i = 0; i < 8; ++i)
10023 DPP8 |= (Sels[i] << (i * 3));
10025 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10030AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10032 if (Ctrl ==
"row_newbcast")
10035 if (Ctrl ==
"row_share" ||
10036 Ctrl ==
"row_xmask")
10039 if (Ctrl ==
"wave_shl" ||
10040 Ctrl ==
"wave_shr" ||
10041 Ctrl ==
"wave_rol" ||
10042 Ctrl ==
"wave_ror" ||
10043 Ctrl ==
"row_bcast")
10046 return Ctrl ==
"row_mirror" ||
10047 Ctrl ==
"row_half_mirror" ||
10048 Ctrl ==
"quad_perm" ||
10049 Ctrl ==
"row_shl" ||
10050 Ctrl ==
"row_shr" ||
10055AMDGPUAsmParser::parseDPPCtrlPerm() {
10058 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10062 for (
int i = 0; i < 4; ++i) {
10067 SMLoc Loc = getLoc();
10068 if (getParser().parseAbsoluteExpression(Temp))
10070 if (Temp < 0 || Temp > 3) {
10071 Error(Loc,
"expected a 2-bit value");
10075 Val += (Temp << i * 2);
10078 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10085AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10086 using namespace AMDGPU::DPP;
10091 SMLoc Loc = getLoc();
10093 if (getParser().parseAbsoluteExpression(Val))
10096 struct DppCtrlCheck {
10102 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10103 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10104 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10105 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10106 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10107 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10108 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10109 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10110 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10111 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10112 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10116 if (
Check.Ctrl == -1) {
10117 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10125 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10132ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10133 using namespace AMDGPU::DPP;
10136 !isSupportedDPPCtrl(getTokenStr(), Operands))
10139 SMLoc S = getLoc();
10145 if (Ctrl ==
"row_mirror") {
10146 Val = DppCtrl::ROW_MIRROR;
10147 }
else if (Ctrl ==
"row_half_mirror") {
10148 Val = DppCtrl::ROW_HALF_MIRROR;
10151 if (Ctrl ==
"quad_perm") {
10152 Val = parseDPPCtrlPerm();
10154 Val = parseDPPCtrlSel(Ctrl);
10163 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10167void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10169 OptionalImmIndexMap OptionalIdx;
10176 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10178 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10179 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10183 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10184 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10188 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10189 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10190 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10191 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10192 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10194 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10198 if (OldIdx == NumOperands) {
10200 constexpr int DST_IDX = 0;
10202 }
else if (Src2ModIdx == NumOperands) {
10212 if (IsVOP3CvtSrDpp) {
10221 if (TiedTo != -1) {
10226 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10228 if (IsDPP8 &&
Op.isDppFI()) {
10231 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10232 }
else if (
Op.isReg()) {
10233 Op.addRegOperands(Inst, 1);
10234 }
else if (
Op.isImm() &&
10236 Op.addImmOperands(Inst, 1);
10237 }
else if (
Op.isImm()) {
10238 OptionalIdx[
Op.getImmTy()] =
I;
10246 AMDGPUOperand::ImmTyClamp);
10252 AMDGPUOperand::ImmTyByteSel);
10259 cvtVOP3P(Inst, Operands, OptionalIdx);
10261 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10268 using namespace llvm::AMDGPU::DPP;
10278 AMDGPUOperand::ImmTyDppFI);
10282void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10283 OptionalImmIndexMap OptionalIdx;
10287 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10288 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10292 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10295 if (TiedTo != -1) {
10300 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10302 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10310 Op.addImmOperands(Inst, 1);
10312 Op.addRegWithFPInputModsOperands(Inst, 2);
10313 }
else if (
Op.isDppFI()) {
10315 }
else if (
Op.isReg()) {
10316 Op.addRegOperands(Inst, 1);
10322 Op.addRegWithFPInputModsOperands(Inst, 2);
10323 }
else if (
Op.isReg()) {
10324 Op.addRegOperands(Inst, 1);
10325 }
else if (
Op.isDPPCtrl()) {
10326 Op.addImmOperands(Inst, 1);
10327 }
else if (
Op.isImm()) {
10329 OptionalIdx[
Op.getImmTy()] =
I;
10337 using namespace llvm::AMDGPU::DPP;
10345 AMDGPUOperand::ImmTyDppFI);
10354ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10356 AMDGPUOperand::ImmTy
Type) {
10357 return parseStringOrIntWithPrefix(
10359 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10363ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10364 return parseStringOrIntWithPrefix(
10365 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10366 AMDGPUOperand::ImmTySDWADstUnused);
10369void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10373void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10377void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10381void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10385void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10389void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10390 uint64_t BasicInstType,
10393 using namespace llvm::AMDGPU::SDWA;
10395 OptionalImmIndexMap OptionalIdx;
10396 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10397 bool SkippedVcc =
false;
10401 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10402 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10405 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10406 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10407 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10408 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10426 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10427 }
else if (
Op.isImm()) {
10429 OptionalIdx[
Op.getImmTy()] =
I;
10433 SkippedVcc =
false;
10437 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10438 Opc != AMDGPU::V_NOP_sdwa_vi) {
10440 switch (BasicInstType) {
10444 AMDGPUOperand::ImmTyClamp, 0);
10448 AMDGPUOperand::ImmTyOModSI, 0);
10452 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10456 AMDGPUOperand::ImmTySDWADstUnused,
10457 DstUnused::UNUSED_PRESERVE);
10459 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10464 AMDGPUOperand::ImmTyClamp, 0);
10469 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10470 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10471 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10472 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10478 AMDGPUOperand::ImmTyClamp, 0);
10479 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10480 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10484 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10490 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10491 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10492 auto *it = Inst.
begin();
10494 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10506#define GET_MATCHER_IMPLEMENTATION
10507#define GET_MNEMONIC_SPELL_CHECKER
10508#define GET_MNEMONIC_CHECKER
10509#include "AMDGPUGenAsmMatcher.inc"
10515 return parseTokenOp(
"addr64",
Operands);
10517 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10519 return parseTokenOp(
"idxen",
Operands);
10521 return parseTokenOp(
"lds",
Operands);
10523 return parseTokenOp(
"offen",
Operands);
10525 return parseTokenOp(
"off",
Operands);
10526 case MCK_row_95_en:
10527 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10529 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10531 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10533 return tryCustomParseOperand(
Operands, MCK);
10538unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10544 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10547 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10549 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10551 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10553 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10555 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10557 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10559 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10560 case MCK_row_95_en:
10561 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10569 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10571 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10572 case MCK_SOPPBrTarget:
10573 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10574 case MCK_VReg32OrOff:
10575 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10576 case MCK_InterpSlot:
10577 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10578 case MCK_InterpAttr:
10579 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10580 case MCK_InterpAttrChan:
10581 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10583 case MCK_SReg_64_XEXEC:
10593 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10595 return Match_InvalidOperand;
10603ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10604 SMLoc S = getLoc();
10613 return Error(S,
"expected a 16-bit value");
10616 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10620bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10626bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
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 TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
static const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
int16_t getOpRegClassID(const MCOperandInfo &OpInfo, unsigned HwModeId) const
Return the ID of the register class to use for OpInfo, for the active HwMode HwModeId.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
void setReg(MCRegister Reg)
Set the register number.
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterClass - Base class of TargetRegisterClass.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool regsOverlap(MCRegister RegA, MCRegister RegB) const
Returns true if the two registers are equal or alias each other.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isVariable() const
isVariable - Check if this is a variable symbol.
LLVM_ABI void setVariableValue(const MCExpr *Value)
void setRedefinable(bool Value)
Mark this symbol as redefinable.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
uint64_t getScalarSizeInBits() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
unsigned getTgtId(const StringRef Name)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI)
static constexpr CustomOperand Operands[]
unsigned getVGPREncodingGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI)
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
constexpr const char *const ModMatrixFmt[]
constexpr const char *const ModMatrixScaleFmt[]
constexpr const char *const ModMatrixScale[]
bool isPackedFP32Inst(unsigned Opc)
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
bool isInlineValue(MCRegister Reg)
bool isPKFMACF16InlineConstant(uint32_t Literal, bool IsGFX11Plus)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
bool isSGPR(MCRegister Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
uint8_t wmmaScaleF8F6F4FormatToNumRegs(unsigned Fmt)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
unsigned getTemporalHintType(const MCInstrDesc TID)
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
bool isGFX10(const MCSubtargetInfo &STI)
LLVM_READONLY bool isLitExpr(const MCExpr *Expr)
bool isInlinableLiteralV2BF16(uint32_t Literal)
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
bool hasA16(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset, bool IsBuffer)
bool isGFX12Plus(const MCSubtargetInfo &STI)
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool isHsaAbi(const MCSubtargetInfo &STI)
bool isGFX11(const MCSubtargetInfo &STI)
const int OPR_VAL_INVALID
bool getSMEMIsBuffer(unsigned Opc)
bool isGFX13(const MCSubtargetInfo &STI)
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
CanBeVOPD getCanBeVOPD(unsigned Opc, unsigned EncodingFamily, bool VOPD3)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
bool isSI(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isGFX9(const MCSubtargetInfo &STI)
unsigned getVOPDEncodingFamily(const MCSubtargetInfo &ST)
bool isGFX10_AEncoding(const MCSubtargetInfo &STI)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool hasMAIInsts(const MCSubtargetInfo &STI)
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool isGFX13Plus(const MCSubtargetInfo &STI)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_IMM_V2FP16_SPLAT
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
bool isGFX1250Plus(const MCSubtargetInfo &STI)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
@ Valid
The data is already valid.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
FunctionAddr VTableAddr uintptr_t uintptr_t Version
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ Default
The result values are uniform if and only if all operands are uniform.
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
Instruction set architecture version.
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
const MCExpr * compute_pgm_rsrc1
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * group_segment_fixed_size
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * kernel_code_properties
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size