56enum RegisterKind { IS_UNKNOWN,
IS_VGPR, IS_SGPR,
IS_AGPR, IS_TTMP, IS_SPECIAL };
70 SMLoc StartLoc, EndLoc;
71 const AMDGPUAsmParser *AsmParser;
74 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
75 : Kind(Kind_), AsmParser(AsmParser_) {}
77 using Ptr = std::unique_ptr<AMDGPUOperand>;
85 bool hasFPModifiers()
const {
return Abs || Neg; }
86 bool hasIntModifiers()
const {
return Sext; }
87 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
89 int64_t getFPModifiersOperand()
const {
96 int64_t getIntModifiersOperand()
const {
102 int64_t getModifiersOperand()
const {
103 assert(!(hasFPModifiers() && hasIntModifiers())
104 &&
"fp and int modifiers should not be used simultaneously");
105 if (hasFPModifiers())
106 return getFPModifiersOperand();
107 if (hasIntModifiers())
108 return getIntModifiersOperand();
112 friend raw_ostream &
operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
186 ImmTyMatrixAScaleFmt,
187 ImmTyMatrixBScaleFmt,
220 mutable int MCOpIdx = -1;
223 bool isToken()
const override {
return Kind == Token; }
225 bool isSymbolRefExpr()
const {
229 bool isImm()
const override {
230 return Kind == Immediate;
233 bool isInlinableImm(MVT type)
const;
234 bool isLiteralImm(MVT type)
const;
236 bool isRegKind()
const {
237 return Kind == Register;
240 bool isReg()
const override {
241 return isRegKind() && !hasModifiers();
244 bool isRegOrInline(
unsigned RCID, MVT type)
const {
245 return isRegClass(RCID) || isInlinableImm(type);
249 return isRegOrInline(RCID, type) || isLiteralImm(type);
252 bool isRegOrImmWithInt16InputMods()
const {
256 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
258 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
261 bool isRegOrImmWithInt32InputMods()
const {
265 bool isRegOrInlineImmWithInt16InputMods()
const {
266 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
269 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
270 return isRegOrInline(
271 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
274 bool isRegOrInlineImmWithInt32InputMods()
const {
275 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
278 bool isRegOrImmWithInt64InputMods()
const {
282 bool isRegOrImmWithFP16InputMods()
const {
286 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
288 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
291 bool isRegOrImmWithFP32InputMods()
const {
295 bool isRegOrImmWithFP64InputMods()
const {
299 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
300 return isRegOrInline(
301 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
304 bool isRegOrInlineImmWithFP32InputMods()
const {
305 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
308 bool isRegOrInlineImmWithFP64InputMods()
const {
309 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
312 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
314 bool isVRegWithFP32InputMods()
const {
315 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
318 bool isVRegWithFP64InputMods()
const {
319 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
322 bool isPackedFP16InputMods()
const {
326 bool isPackedVGPRFP32InputMods()
const {
330 bool isVReg()
const {
331 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
332 isRegClass(AMDGPU::VReg_64RegClassID) ||
333 isRegClass(AMDGPU::VReg_96RegClassID) ||
334 isRegClass(AMDGPU::VReg_128RegClassID) ||
335 isRegClass(AMDGPU::VReg_160RegClassID) ||
336 isRegClass(AMDGPU::VReg_192RegClassID) ||
337 isRegClass(AMDGPU::VReg_256RegClassID) ||
338 isRegClass(AMDGPU::VReg_512RegClassID) ||
339 isRegClass(AMDGPU::VReg_1024RegClassID);
342 bool isVReg32()
const {
343 return isRegClass(AMDGPU::VGPR_32RegClassID);
346 bool isVReg32OrOff()
const {
347 return isOff() || isVReg32();
351 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
354 bool isAV_LdSt_32_Align2_RegOp()
const {
355 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
356 isRegClass(AMDGPU::AGPR_32RegClassID);
359 bool isVRegWithInputMods()
const;
360 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
361 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
363 bool isSDWAOperand(MVT type)
const;
364 bool isSDWAFP16Operand()
const;
365 bool isSDWAFP32Operand()
const;
366 bool isSDWAInt16Operand()
const;
367 bool isSDWAInt32Operand()
const;
369 bool isImmTy(ImmTy ImmT)
const {
370 return isImm() &&
Imm.Type == ImmT;
373 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
375 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
377 bool isImmModifier()
const {
378 return isImm() &&
Imm.Type != ImmTyNone;
381 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
382 bool isDim()
const {
return isImmTy(ImmTyDim); }
383 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
384 bool isOff()
const {
return isImmTy(ImmTyOff); }
385 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
386 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
387 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
388 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
389 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
390 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
391 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
392 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
393 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
394 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
395 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
396 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
397 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
398 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
399 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
400 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
401 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
402 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
403 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
404 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
405 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
406 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
407 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
408 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
409 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
410 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
411 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
412 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
413 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
414 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
415 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
416 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
417 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
418 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
419 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
420 bool isDone()
const {
return isImmTy(ImmTyDone); }
421 bool isRowEn()
const {
return isImmTy(ImmTyRowEn); }
423 bool isRegOrImm()
const {
424 return isReg() || isImm();
427 bool isRegClass(
unsigned RCID)
const;
431 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
432 return isRegOrInline(RCID, type) && !hasModifiers();
435 bool isSCSrcB16()
const {
436 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
439 bool isSCSrcV2B16()
const {
443 bool isSCSrc_b32()
const {
444 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
447 bool isSCSrc_b64()
const {
448 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
451 bool isBoolReg()
const;
453 bool isSCSrcF16()
const {
454 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
457 bool isSCSrcV2F16()
const {
461 bool isSCSrcF32()
const {
462 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
465 bool isSCSrcF64()
const {
466 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
469 bool isSSrc_b32()
const {
470 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
473 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
475 bool isSSrcV2B16()
const {
480 bool isSSrc_b64()
const {
483 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
484 (((
const MCTargetAsmParser *)AsmParser)
485 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
489 bool isSSrc_f32()
const {
490 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
493 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
495 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
497 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
499 bool isSSrcV2F16()
const {
504 bool isSSrcV2FP32()
const {
509 bool isSCSrcV2FP32()
const {
514 bool isSSrcV2INT32()
const {
519 bool isSCSrcV2INT32()
const {
521 return isSCSrc_b32();
524 bool isSSrcOrLds_b32()
const {
525 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
526 isLiteralImm(MVT::i32) || isExpr();
529 bool isVCSrc_b32()
const {
530 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
533 bool isVCSrc_b32_Lo256()
const {
534 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
537 bool isVCSrc_b64_Lo256()
const {
538 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
541 bool isVCSrc_b64()
const {
542 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
545 bool isVCSrcT_b16()
const {
546 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
549 bool isVCSrcTB16_Lo128()
const {
550 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
553 bool isVCSrcFake16B16_Lo128()
const {
554 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
557 bool isVCSrc_b16()
const {
558 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
561 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
563 bool isVCSrc_f32()
const {
564 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
567 bool isVCSrc_f64()
const {
568 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
571 bool isVCSrcTBF16()
const {
572 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
575 bool isVCSrcT_f16()
const {
576 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
579 bool isVCSrcT_bf16()
const {
580 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
583 bool isVCSrcTBF16_Lo128()
const {
584 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
587 bool isVCSrcTF16_Lo128()
const {
588 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
591 bool isVCSrcFake16BF16_Lo128()
const {
592 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
595 bool isVCSrcFake16F16_Lo128()
const {
596 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
599 bool isVCSrc_bf16()
const {
600 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
603 bool isVCSrc_f16()
const {
604 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
607 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
609 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
611 bool isVSrc_b32()
const {
612 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
615 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
617 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
619 bool isVSrcT_b16_Lo128()
const {
620 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
623 bool isVSrcFake16_b16_Lo128()
const {
624 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
627 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
629 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
631 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
633 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
635 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
637 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
639 bool isVSrc_f32()
const {
640 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
643 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
645 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
647 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
649 bool isVSrcT_bf16_Lo128()
const {
650 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
653 bool isVSrcT_f16_Lo128()
const {
654 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
657 bool isVSrcFake16_bf16_Lo128()
const {
658 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
661 bool isVSrcFake16_f16_Lo128()
const {
662 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
665 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
667 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
669 bool isVSrc_v2bf16()
const {
670 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
673 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
675 bool isVSrc_v2f16_splat()
const {
return isVSrc_v2f16(); }
677 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
679 bool isVISrcB32()
const {
680 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
683 bool isVISrcB16()
const {
684 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
687 bool isVISrcV2B16()
const {
691 bool isVISrcF32()
const {
692 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
695 bool isVISrcF16()
const {
696 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
699 bool isVISrcV2F16()
const {
700 return isVISrcF16() || isVISrcB32();
703 bool isVISrc_64_bf16()
const {
704 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
707 bool isVISrc_64_f16()
const {
708 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
711 bool isVISrc_64_b32()
const {
712 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
715 bool isVISrc_64B64()
const {
716 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
719 bool isVISrc_64_f64()
const {
720 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
723 bool isVISrc_64V2FP32()
const {
724 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
727 bool isVISrc_64V2INT32()
const {
728 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
731 bool isVISrc_256_b32()
const {
732 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
735 bool isVISrc_256_f32()
const {
736 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
739 bool isVISrc_256B64()
const {
740 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
743 bool isVISrc_256_f64()
const {
744 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
747 bool isVISrc_512_f64()
const {
748 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
751 bool isVISrc_128B16()
const {
752 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
755 bool isVISrc_128V2B16()
const {
756 return isVISrc_128B16();
759 bool isVISrc_128_b32()
const {
760 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
763 bool isVISrc_128_f32()
const {
764 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
767 bool isVISrc_256V2FP32()
const {
768 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
771 bool isVISrc_256V2INT32()
const {
772 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
775 bool isVISrc_512_b32()
const {
776 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
779 bool isVISrc_512B16()
const {
780 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
783 bool isVISrc_512V2B16()
const {
784 return isVISrc_512B16();
787 bool isVISrc_512_f32()
const {
788 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
791 bool isVISrc_512F16()
const {
792 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
795 bool isVISrc_512V2F16()
const {
796 return isVISrc_512F16() || isVISrc_512_b32();
799 bool isVISrc_1024_b32()
const {
800 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
803 bool isVISrc_1024B16()
const {
804 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
807 bool isVISrc_1024V2B16()
const {
808 return isVISrc_1024B16();
811 bool isVISrc_1024_f32()
const {
812 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
815 bool isVISrc_1024F16()
const {
816 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
819 bool isVISrc_1024V2F16()
const {
820 return isVISrc_1024F16() || isVISrc_1024_b32();
823 bool isAISrcB32()
const {
824 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
827 bool isAISrcB16()
const {
828 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
831 bool isAISrcV2B16()
const {
835 bool isAISrcF32()
const {
836 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
839 bool isAISrcF16()
const {
840 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
843 bool isAISrcV2F16()
const {
844 return isAISrcF16() || isAISrcB32();
847 bool isAISrc_64B64()
const {
848 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
851 bool isAISrc_64_f64()
const {
852 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
855 bool isAISrc_128_b32()
const {
856 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
859 bool isAISrc_128B16()
const {
860 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
863 bool isAISrc_128V2B16()
const {
864 return isAISrc_128B16();
867 bool isAISrc_128_f32()
const {
868 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
871 bool isAISrc_128F16()
const {
872 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
875 bool isAISrc_128V2F16()
const {
876 return isAISrc_128F16() || isAISrc_128_b32();
879 bool isVISrc_128_bf16()
const {
880 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
883 bool isVISrc_128_f16()
const {
884 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
887 bool isVISrc_128V2F16()
const {
888 return isVISrc_128_f16() || isVISrc_128_b32();
891 bool isAISrc_256B64()
const {
892 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
895 bool isAISrc_256_f64()
const {
896 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
899 bool isAISrc_512_b32()
const {
900 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
903 bool isAISrc_512B16()
const {
904 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
907 bool isAISrc_512V2B16()
const {
908 return isAISrc_512B16();
911 bool isAISrc_512_f32()
const {
912 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
915 bool isAISrc_512F16()
const {
916 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
919 bool isAISrc_512V2F16()
const {
920 return isAISrc_512F16() || isAISrc_512_b32();
923 bool isAISrc_1024_b32()
const {
924 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
927 bool isAISrc_1024B16()
const {
928 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
931 bool isAISrc_1024V2B16()
const {
932 return isAISrc_1024B16();
935 bool isAISrc_1024_f32()
const {
936 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
939 bool isAISrc_1024F16()
const {
940 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
943 bool isAISrc_1024V2F16()
const {
944 return isAISrc_1024F16() || isAISrc_1024_b32();
947 bool isKImmFP32()
const {
948 return isLiteralImm(MVT::f32);
951 bool isKImmFP16()
const {
952 return isLiteralImm(MVT::f16);
955 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
957 bool isMem()
const override {
961 bool isExpr()
const {
962 return Kind == Expression;
965 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
967 bool isSWaitCnt()
const;
968 bool isDepCtr()
const;
969 bool isSDelayALU()
const;
970 bool isHwreg()
const;
971 bool isSendMsg()
const;
972 bool isWaitEvent()
const;
973 bool isSplitBarrier()
const;
974 bool isSwizzle()
const;
975 bool isSMRDOffset8()
const;
976 bool isSMEMOffset()
const;
977 bool isSMRDLiteralOffset()
const;
979 bool isDPPCtrl()
const;
981 bool isGPRIdxMode()
const;
982 bool isS16Imm()
const;
983 bool isU16Imm()
const;
984 bool isEndpgm()
const;
986 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
987 return [
this,
P]() {
return P(*
this); };
992 return StringRef(Tok.Data, Tok.Length);
1000 void setImm(int64_t Val) {
1005 ImmTy getImmTy()
const {
1010 MCRegister
getReg()
const override {
1015 SMLoc getStartLoc()
const override {
1019 SMLoc getEndLoc()
const override {
1023 SMRange getLocRange()
const {
1024 return SMRange(StartLoc, EndLoc);
1027 int getMCOpIdx()
const {
return MCOpIdx; }
1029 Modifiers getModifiers()
const {
1030 assert(isRegKind() || isImmTy(ImmTyNone));
1031 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1034 void setModifiers(Modifiers Mods) {
1035 assert(isRegKind() || isImmTy(ImmTyNone));
1042 bool hasModifiers()
const {
1043 return getModifiers().hasModifiers();
1046 bool hasFPModifiers()
const {
1047 return getModifiers().hasFPModifiers();
1050 bool hasIntModifiers()
const {
1051 return getModifiers().hasIntModifiers();
1054 uint64_t applyInputFPModifiers(uint64_t Val,
unsigned Size)
const;
1056 void addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1058 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1060 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1062 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1064 addRegOperands(Inst,
N);
1066 addImmOperands(Inst,
N);
1069 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1070 Modifiers Mods = getModifiers();
1073 addRegOperands(Inst,
N);
1075 addImmOperands(Inst,
N,
false);
1079 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1080 assert(!hasIntModifiers());
1081 addRegOrImmWithInputModsOperands(Inst,
N);
1084 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1085 assert(!hasFPModifiers());
1086 addRegOrImmWithInputModsOperands(Inst,
N);
1089 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1090 Modifiers Mods = getModifiers();
1093 addRegOperands(Inst,
N);
1096 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1097 assert(!hasIntModifiers());
1098 addRegWithInputModsOperands(Inst,
N);
1101 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1102 assert(!hasFPModifiers());
1103 addRegWithInputModsOperands(Inst,
N);
1106 static void printImmTy(raw_ostream& OS, ImmTy
Type) {
1109 case ImmTyNone: OS <<
"None";
break;
1110 case ImmTyGDS: OS <<
"GDS";
break;
1111 case ImmTyLDS: OS <<
"LDS";
break;
1112 case ImmTyOffen: OS <<
"Offen";
break;
1113 case ImmTyIdxen: OS <<
"Idxen";
break;
1114 case ImmTyAddr64: OS <<
"Addr64";
break;
1115 case ImmTyOffset: OS <<
"Offset";
break;
1116 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1117 case ImmTyOffset0: OS <<
"Offset0";
break;
1118 case ImmTyOffset1: OS <<
"Offset1";
break;
1119 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1120 case ImmTyCPol: OS <<
"CPol";
break;
1121 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1122 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1123 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1124 case ImmTyTFE: OS <<
"TFE";
break;
1125 case ImmTyIsAsync: OS <<
"IsAsync";
break;
1126 case ImmTyD16: OS <<
"D16";
break;
1127 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1128 case ImmTyClamp: OS <<
"Clamp";
break;
1129 case ImmTyOModSI: OS <<
"OModSI";
break;
1130 case ImmTyDPP8: OS <<
"DPP8";
break;
1131 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1132 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1133 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1134 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1135 case ImmTyDppFI: OS <<
"DppFI";
break;
1136 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1137 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1138 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1139 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1140 case ImmTyDMask: OS <<
"DMask";
break;
1141 case ImmTyDim: OS <<
"Dim";
break;
1142 case ImmTyUNorm: OS <<
"UNorm";
break;
1143 case ImmTyDA: OS <<
"DA";
break;
1144 case ImmTyR128A16: OS <<
"R128A16";
break;
1145 case ImmTyA16: OS <<
"A16";
break;
1146 case ImmTyLWE: OS <<
"LWE";
break;
1147 case ImmTyOff: OS <<
"Off";
break;
1148 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1149 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1150 case ImmTyExpVM: OS <<
"ExpVM";
break;
1151 case ImmTyDone: OS <<
"Done";
break;
1152 case ImmTyRowEn: OS <<
"RowEn";
break;
1153 case ImmTyHwreg: OS <<
"Hwreg";
break;
1154 case ImmTySendMsg: OS <<
"SendMsg";
break;
1155 case ImmTyWaitEvent: OS <<
"WaitEvent";
break;
1156 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1157 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1158 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1159 case ImmTyOpSel: OS <<
"OpSel";
break;
1160 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1161 case ImmTyNegLo: OS <<
"NegLo";
break;
1162 case ImmTyNegHi: OS <<
"NegHi";
break;
1163 case ImmTySwizzle: OS <<
"Swizzle";
break;
1164 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1165 case ImmTyHigh: OS <<
"High";
break;
1166 case ImmTyBLGP: OS <<
"BLGP";
break;
1167 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1168 case ImmTyABID: OS <<
"ABID";
break;
1169 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1170 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1171 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1172 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1173 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1174 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1175 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1176 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1177 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1178 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1179 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1180 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1181 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1182 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1183 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1184 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1189 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1193 <<
" mods: " <<
Reg.Mods <<
'>';
1197 if (getImmTy() != ImmTyNone) {
1198 OS <<
" type: "; printImmTy(OS, getImmTy());
1200 OS <<
" mods: " <<
Imm.Mods <<
'>';
1213 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1214 int64_t Val, SMLoc Loc,
1215 ImmTy
Type = ImmTyNone,
1216 bool IsFPImm =
false) {
1217 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1219 Op->Imm.IsFPImm = IsFPImm;
1221 Op->Imm.Mods = Modifiers();
1227 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1228 StringRef Str, SMLoc Loc,
1229 bool HasExplicitEncodingSize =
true) {
1230 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1231 Res->Tok.Data = Str.data();
1232 Res->Tok.Length = Str.size();
1233 Res->StartLoc = Loc;
1238 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1239 MCRegister
Reg, SMLoc S, SMLoc
E) {
1240 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1241 Op->Reg.RegNo =
Reg;
1242 Op->Reg.Mods = Modifiers();
1248 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1249 const class MCExpr *Expr, SMLoc S) {
1250 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1259 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1268#define GET_REGISTER_MATCHER
1269#include "AMDGPUGenAsmMatcher.inc"
1270#undef GET_REGISTER_MATCHER
1271#undef GET_SUBTARGET_FEATURE_NAME
1276class KernelScopeInfo {
1277 int SgprIndexUnusedMin = -1;
1278 int VgprIndexUnusedMin = -1;
1279 int AgprIndexUnusedMin = -1;
1283 void usesSgprAt(
int i) {
1284 if (i >= SgprIndexUnusedMin) {
1285 SgprIndexUnusedMin = ++i;
1288 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1294 void usesVgprAt(
int i) {
1295 if (i >= VgprIndexUnusedMin) {
1296 VgprIndexUnusedMin = ++i;
1299 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1301 VgprIndexUnusedMin);
1307 void usesAgprAt(
int i) {
1312 if (i >= AgprIndexUnusedMin) {
1313 AgprIndexUnusedMin = ++i;
1316 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1321 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1323 VgprIndexUnusedMin);
1330 KernelScopeInfo() =
default;
1334 MSTI = Ctx->getSubtargetInfo();
1336 usesSgprAt(SgprIndexUnusedMin = -1);
1337 usesVgprAt(VgprIndexUnusedMin = -1);
1339 usesAgprAt(AgprIndexUnusedMin = -1);
1343 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1344 unsigned RegWidth) {
1347 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1350 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1353 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1362 MCAsmParser &Parser;
1364 unsigned ForcedEncodingSize = 0;
1365 bool ForcedDPP =
false;
1366 bool ForcedSDWA =
false;
1367 KernelScopeInfo KernelScope;
1368 const unsigned HwMode;
1373#define GET_ASSEMBLER_HEADER
1374#include "AMDGPUGenAsmMatcher.inc"
1379 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1381 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1386 void createConstantSymbol(StringRef Id, int64_t Val);
1388 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1389 bool OutOfRangeError(SMRange
Range);
1405 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1406 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1407 std::optional<bool> EnableWavefrontSize32,
1408 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1409 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1410 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1411 bool ParseDirectiveAMDGCNTarget();
1412 bool ParseDirectiveAMDHSACodeObjectVersion();
1413 bool ParseDirectiveAMDHSAKernel();
1414 bool ParseAMDKernelCodeTValue(StringRef
ID, AMDGPUMCKernelCodeT &Header);
1415 bool ParseDirectiveAMDKernelCodeT();
1417 bool subtargetHasRegister(
const MCRegisterInfo &MRI, MCRegister
Reg);
1418 bool ParseDirectiveAMDGPUHsaKernel();
1420 bool ParseDirectiveISAVersion();
1421 bool ParseDirectiveHSAMetadata();
1422 bool ParseDirectivePALMetadataBegin();
1423 bool ParseDirectivePALMetadata();
1424 bool ParseDirectiveAMDGPULDS();
1428 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1429 const char *AssemblerDirectiveEnd,
1430 std::string &CollectString);
1432 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1433 RegisterKind RegKind, MCRegister Reg1, SMLoc Loc);
1434 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1435 unsigned &RegNum,
unsigned &RegWidth,
1436 bool RestoreOnFailure =
false);
1437 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1438 unsigned &RegNum,
unsigned &RegWidth,
1439 SmallVectorImpl<AsmToken> &Tokens);
1440 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1442 SmallVectorImpl<AsmToken> &Tokens);
1443 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1445 SmallVectorImpl<AsmToken> &Tokens);
1446 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1448 SmallVectorImpl<AsmToken> &Tokens);
1449 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &SubReg);
1450 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1451 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1454 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1455 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1456 void initializeGprCountSymbol(RegisterKind RegKind);
1457 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1459 void cvtMubufImpl(MCInst &Inst,
const OperandVector &Operands,
1464 OperandMode_Default,
1468 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1470 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1471 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
1472 : MCTargetAsmParser(
Options, STI, MII), Parser(_Parser),
1473 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)) {
1476 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1480 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1481 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1482 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1484 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1485 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1486 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1489 initializeGprCountSymbol(IS_VGPR);
1490 initializeGprCountSymbol(IS_SGPR);
1495 createConstantSymbol(Symbol, Code);
1497 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1498 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1499 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1579 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1581 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1583 bool hasInv2PiInlineImm()
const {
1584 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1587 bool has64BitLiterals()
const {
1588 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1591 bool hasFlatOffsets()
const {
1592 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1595 bool hasTrue16Insts()
const {
1596 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1600 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1603 bool hasSGPR102_SGPR103()
const {
1607 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1609 bool hasIntClamp()
const {
1610 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1613 bool hasPartialNSAEncoding()
const {
1614 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1617 bool hasGloballyAddressableScratch()
const {
1618 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1631 AMDGPUTargetStreamer &getTargetStreamer() {
1632 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1633 return static_cast<AMDGPUTargetStreamer &
>(TS);
1639 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1642 const MCRegisterInfo *getMRI()
const {
1646 const MCInstrInfo *getMII()
const {
1652 const FeatureBitset &getFeatureBits()
const {
1653 return getSTI().getFeatureBits();
1656 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1657 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1658 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1660 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1661 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1662 bool isForcedDPP()
const {
return ForcedDPP; }
1663 bool isForcedSDWA()
const {
return ForcedSDWA; }
1664 ArrayRef<unsigned> getMatchedVariants()
const;
1665 StringRef getMatchedVariantName()
const;
1667 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1668 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1669 bool RestoreOnFailure);
1670 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1671 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1672 SMLoc &EndLoc)
override;
1673 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1674 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1675 unsigned Kind)
override;
1676 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1678 uint64_t &ErrorInfo,
1679 bool MatchingInlineAsm)
override;
1680 bool ParseDirective(AsmToken DirectiveID)
override;
1681 ParseStatus parseOperand(
OperandVector &Operands, StringRef Mnemonic,
1682 OperandMode
Mode = OperandMode_Default);
1683 StringRef parseMnemonicSuffix(StringRef Name);
1684 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1688 ParseStatus parseTokenOp(StringRef Name,
OperandVector &Operands);
1690 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1693 parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1694 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1695 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1697 ParseStatus parseOperandArrayWithPrefix(
1699 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1700 bool (*ConvertResult)(int64_t &) =
nullptr);
1704 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1705 bool IgnoreNegative =
false);
1706 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1708 ParseStatus parseScope(
OperandVector &Operands, int64_t &Scope);
1710 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1712 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1714 ArrayRef<const char *> Ids,
1716 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1718 ArrayRef<const char *> Ids,
1719 AMDGPUOperand::ImmTy
Type);
1722 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1723 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1724 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1725 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1726 bool parseSP3NegModifier();
1727 ParseStatus parseImm(
OperandVector &Operands,
bool HasSP3AbsModifier =
false,
1730 ParseStatus parseRegOrImm(
OperandVector &Operands,
bool HasSP3AbsMod =
false,
1732 ParseStatus parseRegOrImmWithFPInputMods(
OperandVector &Operands,
1733 bool AllowImm =
true);
1734 ParseStatus parseRegOrImmWithIntInputMods(
OperandVector &Operands,
1735 bool AllowImm =
true);
1736 ParseStatus parseRegWithFPInputMods(
OperandVector &Operands);
1737 ParseStatus parseRegWithIntInputMods(
OperandVector &Operands);
1740 AMDGPUOperand::ImmTy ImmTy);
1744 ParseStatus tryParseMatrixFMT(
OperandVector &Operands, StringRef Name,
1745 AMDGPUOperand::ImmTy
Type);
1748 ParseStatus tryParseMatrixScale(
OperandVector &Operands, StringRef Name,
1749 AMDGPUOperand::ImmTy
Type);
1752 ParseStatus tryParseMatrixScaleFmt(
OperandVector &Operands, StringRef Name,
1753 AMDGPUOperand::ImmTy
Type);
1757 ParseStatus parseDfmtNfmt(int64_t &
Format);
1758 ParseStatus parseUfmt(int64_t &
Format);
1759 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1761 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1764 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1765 ParseStatus parseNumericFormat(int64_t &
Format);
1769 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1770 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1774 bool parseCnt(int64_t &IntVal);
1777 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1778 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1781 bool parseDelay(int64_t &Delay);
1787 struct OperandInfoTy {
1790 bool IsSymbolic =
false;
1791 bool IsDefined =
false;
1793 constexpr OperandInfoTy(int64_t Val) : Val(Val) {}
1796 struct StructuredOpField : OperandInfoTy {
1800 bool IsDefined =
false;
1802 constexpr StructuredOpField(StringLiteral Id, StringLiteral Desc,
1803 unsigned Width, int64_t
Default)
1804 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1805 virtual ~StructuredOpField() =
default;
1807 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1808 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1812 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1814 return Error(Parser,
"not supported on this GPU");
1816 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1824 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1825 bool validateSendMsg(
const OperandInfoTy &Msg,
1826 const OperandInfoTy &
Op,
1827 const OperandInfoTy &Stream);
1829 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1830 OperandInfoTy &Width);
1832 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1834 SMLoc getFlatOffsetLoc(
const OperandVector &Operands)
const;
1835 SMLoc getSMEMOffsetLoc(
const OperandVector &Operands)
const;
1838 SMLoc getOperandLoc(
const OperandVector &Operands,
int MCOpIdx)
const;
1839 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1841 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1845 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1847 bool validateOffset(
const MCInst &Inst,
const OperandVector &Operands);
1848 bool validateFlatOffset(
const MCInst &Inst,
const OperandVector &Operands);
1849 bool validateSMEMOffset(
const MCInst &Inst,
const OperandVector &Operands);
1850 bool validateSOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1851 bool validateConstantBusLimitations(
const MCInst &Inst,
const OperandVector &Operands);
1852 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1854 bool validateVOPD(
const MCInst &Inst,
const OperandVector &Operands);
1855 bool tryVOPD(
const MCInst &Inst);
1856 bool tryVOPD3(
const MCInst &Inst);
1857 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1859 bool validateIntClampSupported(
const MCInst &Inst);
1860 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1861 bool validateMIMGGatherDMask(
const MCInst &Inst);
1862 bool validateMovrels(
const MCInst &Inst,
const OperandVector &Operands);
1863 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1864 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1865 bool validateMIMGD16(
const MCInst &Inst);
1866 bool validateMIMGDim(
const MCInst &Inst,
const OperandVector &Operands);
1867 bool validateTensorR128(
const MCInst &Inst);
1868 bool validateMIMGMSAA(
const MCInst &Inst);
1869 bool validateOpSel(
const MCInst &Inst);
1870 bool validateTrue16OpSel(
const MCInst &Inst);
1871 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1872 bool validateDPP(
const MCInst &Inst,
const OperandVector &Operands);
1873 bool validateVccOperand(MCRegister
Reg)
const;
1874 bool validateVOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1875 bool validateMAIAccWrite(
const MCInst &Inst,
const OperandVector &Operands);
1876 bool validateMAISrc2(
const MCInst &Inst,
const OperandVector &Operands);
1877 bool validateMFMA(
const MCInst &Inst,
const OperandVector &Operands);
1878 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1879 bool validateVGPRAlign(
const MCInst &Inst)
const;
1880 bool validateBLGP(
const MCInst &Inst,
const OperandVector &Operands);
1881 bool validateDS(
const MCInst &Inst,
const OperandVector &Operands);
1882 bool validateGWS(
const MCInst &Inst,
const OperandVector &Operands);
1883 bool validateDivScale(
const MCInst &Inst);
1884 bool validateWaitCnt(
const MCInst &Inst,
const OperandVector &Operands);
1885 bool validateCoherencyBits(
const MCInst &Inst,
const OperandVector &Operands,
1887 bool validateTHAndScopeBits(
const MCInst &Inst,
const OperandVector &Operands,
1888 const unsigned CPol);
1889 bool validateTFE(
const MCInst &Inst,
const OperandVector &Operands);
1890 bool validateLdsDirect(
const MCInst &Inst,
const OperandVector &Operands);
1891 bool validateWMMA(
const MCInst &Inst,
const OperandVector &Operands);
1892 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1893 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1894 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1895 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1897 bool isSupportedMnemo(StringRef Mnemo,
1898 const FeatureBitset &FBS);
1899 bool isSupportedMnemo(StringRef Mnemo,
1900 const FeatureBitset &FBS,
1901 ArrayRef<unsigned> Variants);
1902 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1904 bool isId(
const StringRef Id)
const;
1905 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1907 StringRef getId()
const;
1908 bool trySkipId(
const StringRef Id);
1909 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1913 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1914 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1920 StringRef getTokenStr()
const;
1921 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1923 SMLoc getLoc()
const;
1927 void onBeginOfFile()
override;
1928 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1930 ParseStatus parseCustomOperand(
OperandVector &Operands,
unsigned MCK);
1940 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1941 const unsigned MaxVal,
const Twine &ErrMsg,
1943 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1944 const unsigned MinVal,
1945 const unsigned MaxVal,
1946 const StringRef ErrMsg);
1948 bool parseSwizzleOffset(int64_t &
Imm);
1949 bool parseSwizzleMacro(int64_t &
Imm);
1950 bool parseSwizzleQuadPerm(int64_t &
Imm);
1951 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1952 bool parseSwizzleBroadcast(int64_t &
Imm);
1953 bool parseSwizzleSwap(int64_t &
Imm);
1954 bool parseSwizzleReverse(int64_t &
Imm);
1955 bool parseSwizzleFFT(int64_t &
Imm);
1956 bool parseSwizzleRotate(int64_t &
Imm);
1959 int64_t parseGPRIdxMacro();
1961 void cvtMubuf(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
false); }
1962 void cvtMubufAtomic(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
true); }
1967 OptionalImmIndexMap &OptionalIdx);
1968 void cvtScaledMFMA(MCInst &Inst,
const OperandVector &Operands);
1969 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands);
1972 void cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands);
1975 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
1976 OptionalImmIndexMap &OptionalIdx);
1978 OptionalImmIndexMap &OptionalIdx);
1980 void cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands);
1981 void cvtVINTERP(MCInst &Inst,
const OperandVector &Operands);
1982 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1984 bool parseDimId(
unsigned &Encoding);
1986 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1989 bool isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands);
1990 int64_t parseDPPCtrlSel(StringRef Ctrl);
1991 int64_t parseDPPCtrlPerm();
1992 void cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8 =
false);
1994 cvtDPP(Inst, Operands,
true);
1996 void cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
1997 bool IsDPP8 =
false);
1998 void cvtVOP3DPP8(MCInst &Inst,
const OperandVector &Operands) {
1999 cvtVOP3DPP(Inst, Operands,
true);
2002 ParseStatus parseSDWASel(
OperandVector &Operands, StringRef Prefix,
2003 AMDGPUOperand::ImmTy
Type);
2005 void cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands);
2006 void cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands);
2007 void cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands);
2008 void cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands);
2009 void cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands);
2011 uint64_t BasicInstType,
2012 bool SkipDstVcc =
false,
2013 bool SkipSrcVcc =
false);
2122bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2132 if (!isImmTy(ImmTyNone)) {
2137 if (getModifiers().
Lit != LitModifier::None)
2147 if (type == MVT::f64 || type == MVT::i64) {
2149 AsmParser->hasInv2PiInlineImm());
2152 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2171 APFloat::rmNearestTiesToEven, &Lost);
2178 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2180 AsmParser->hasInv2PiInlineImm());
2185 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2186 AsmParser->hasInv2PiInlineImm());
2190 if (type == MVT::f64 || type == MVT::i64) {
2192 AsmParser->hasInv2PiInlineImm());
2201 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2202 type, AsmParser->hasInv2PiInlineImm());
2206 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2207 AsmParser->hasInv2PiInlineImm());
2210bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2212 if (!isImmTy(ImmTyNone)) {
2217 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2222 if (type == MVT::f64 && hasFPModifiers()) {
2242 if (type == MVT::f64) {
2247 if (type == MVT::i64) {
2260 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2261 : (type == MVT::v2i16) ? MVT::f32
2262 : (type == MVT::v2f32) ? MVT::f32
2265 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2269bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2270 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2273bool AMDGPUOperand::isVRegWithInputMods()
const {
2274 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2276 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2277 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2280template <
bool IsFake16>
2281bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2282 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2283 : AMDGPU::VGPR_16_Lo128RegClassID);
2286template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2287 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2288 : AMDGPU::VGPR_16RegClassID);
2291bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2292 if (AsmParser->isVI())
2294 if (AsmParser->isGFX9Plus())
2295 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2299bool AMDGPUOperand::isSDWAFP16Operand()
const {
2300 return isSDWAOperand(MVT::f16);
2303bool AMDGPUOperand::isSDWAFP32Operand()
const {
2304 return isSDWAOperand(MVT::f32);
2307bool AMDGPUOperand::isSDWAInt16Operand()
const {
2308 return isSDWAOperand(MVT::i16);
2311bool AMDGPUOperand::isSDWAInt32Operand()
const {
2312 return isSDWAOperand(MVT::i32);
2315bool AMDGPUOperand::isBoolReg()
const {
2316 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2317 (AsmParser->isWave32() && isSCSrc_b32()));
2320uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2322 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2325 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2337void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2347 addLiteralImmOperand(Inst,
Imm.Val,
2349 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2351 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2356void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2357 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2362 if (ApplyModifiers) {
2365 Val = applyInputFPModifiers(Val,
Size);
2369 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2371 bool CanUse64BitLiterals =
2372 AsmParser->has64BitLiterals() &&
2375 MCContext &Ctx = AsmParser->getContext();
2384 if (
Lit == LitModifier::None &&
2386 AsmParser->hasInv2PiInlineImm())) {
2394 bool HasMandatoryLiteral =
2397 if (
Literal.getLoBits(32) != 0 &&
2398 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2399 !HasMandatoryLiteral) {
2400 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2402 "Can't encode literal as exact 64-bit floating-point operand. "
2403 "Low 32-bits will be set to zero");
2404 Val &= 0xffffffff00000000u;
2410 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2416 Lit = LitModifier::Lit64;
2417 }
else if (
Lit == LitModifier::Lit) {
2431 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2433 Lit = LitModifier::Lit64;
2440 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2441 Literal == 0x3fc45f306725feed) {
2476 APFloat::rmNearestTiesToEven, &lost);
2480 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2487 if (
Lit != LitModifier::None) {
2517 if (
Lit == LitModifier::None &&
2527 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2534 if (
Lit == LitModifier::None &&
2542 if (!AsmParser->has64BitLiterals()) {
2543 Val =
static_cast<uint64_t
>(Val) << 32;
2550 if (
Lit == LitModifier::Lit ||
2552 Val =
static_cast<uint64_t
>(Val) << 32;
2556 if (
Lit == LitModifier::Lit)
2582 if (
Lit != LitModifier::None) {
2590void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2595bool AMDGPUOperand::isInlineValue()
const {
2603void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2614 if (Is == IS_VGPR) {
2618 return AMDGPU::VGPR_32RegClassID;
2620 return AMDGPU::VReg_64RegClassID;
2622 return AMDGPU::VReg_96RegClassID;
2624 return AMDGPU::VReg_128RegClassID;
2626 return AMDGPU::VReg_160RegClassID;
2628 return AMDGPU::VReg_192RegClassID;
2630 return AMDGPU::VReg_224RegClassID;
2632 return AMDGPU::VReg_256RegClassID;
2634 return AMDGPU::VReg_288RegClassID;
2636 return AMDGPU::VReg_320RegClassID;
2638 return AMDGPU::VReg_352RegClassID;
2640 return AMDGPU::VReg_384RegClassID;
2642 return AMDGPU::VReg_512RegClassID;
2644 return AMDGPU::VReg_1024RegClassID;
2646 }
else if (Is == IS_TTMP) {
2650 return AMDGPU::TTMP_32RegClassID;
2652 return AMDGPU::TTMP_64RegClassID;
2654 return AMDGPU::TTMP_128RegClassID;
2656 return AMDGPU::TTMP_256RegClassID;
2658 return AMDGPU::TTMP_512RegClassID;
2660 }
else if (Is == IS_SGPR) {
2664 return AMDGPU::SGPR_32RegClassID;
2666 return AMDGPU::SGPR_64RegClassID;
2668 return AMDGPU::SGPR_96RegClassID;
2670 return AMDGPU::SGPR_128RegClassID;
2672 return AMDGPU::SGPR_160RegClassID;
2674 return AMDGPU::SGPR_192RegClassID;
2676 return AMDGPU::SGPR_224RegClassID;
2678 return AMDGPU::SGPR_256RegClassID;
2680 return AMDGPU::SGPR_288RegClassID;
2682 return AMDGPU::SGPR_320RegClassID;
2684 return AMDGPU::SGPR_352RegClassID;
2686 return AMDGPU::SGPR_384RegClassID;
2688 return AMDGPU::SGPR_512RegClassID;
2690 }
else if (Is == IS_AGPR) {
2694 return AMDGPU::AGPR_32RegClassID;
2696 return AMDGPU::AReg_64RegClassID;
2698 return AMDGPU::AReg_96RegClassID;
2700 return AMDGPU::AReg_128RegClassID;
2702 return AMDGPU::AReg_160RegClassID;
2704 return AMDGPU::AReg_192RegClassID;
2706 return AMDGPU::AReg_224RegClassID;
2708 return AMDGPU::AReg_256RegClassID;
2710 return AMDGPU::AReg_288RegClassID;
2712 return AMDGPU::AReg_320RegClassID;
2714 return AMDGPU::AReg_352RegClassID;
2716 return AMDGPU::AReg_384RegClassID;
2718 return AMDGPU::AReg_512RegClassID;
2720 return AMDGPU::AReg_1024RegClassID;
2728 .
Case(
"exec", AMDGPU::EXEC)
2729 .
Case(
"vcc", AMDGPU::VCC)
2730 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2731 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2732 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2733 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2734 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2735 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2736 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2737 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2738 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2739 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2740 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2741 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2742 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2743 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2744 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2745 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2746 .
Case(
"m0", AMDGPU::M0)
2747 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2748 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2749 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2750 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2751 .
Case(
"scc", AMDGPU::SRC_SCC)
2752 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2753 .
Case(
"tba", AMDGPU::TBA)
2754 .
Case(
"tma", AMDGPU::TMA)
2755 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2756 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2757 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2758 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2759 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2760 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2761 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2762 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2763 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2764 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2765 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2766 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2767 .
Case(
"pc", AMDGPU::PC_REG)
2768 .
Case(
"null", AMDGPU::SGPR_NULL)
2772bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2773 SMLoc &EndLoc,
bool RestoreOnFailure) {
2774 auto R = parseRegister();
2775 if (!R)
return true;
2777 RegNo =
R->getReg();
2778 StartLoc =
R->getStartLoc();
2779 EndLoc =
R->getEndLoc();
2783bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2785 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2788ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2790 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2791 bool PendingErrors = getParser().hasPendingError();
2792 getParser().clearPendingErrors();
2800bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2801 RegisterKind RegKind,
2802 MCRegister Reg1, SMLoc Loc) {
2805 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2810 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2811 Reg = AMDGPU::FLAT_SCR;
2815 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2816 Reg = AMDGPU::XNACK_MASK;
2820 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2825 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2830 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2835 Error(Loc,
"register does not fit in the list");
2841 if (Reg1 !=
Reg + RegWidth / 32) {
2842 Error(Loc,
"registers in a list must have consecutive indices");
2860 {{
"ttmp"}, IS_TTMP},
2866 return Kind == IS_VGPR ||
2874 if (Str.starts_with(
Reg.Name))
2880 return !Str.getAsInteger(10, Num);
2884AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2885 const AsmToken &NextToken)
const {
2900 StringRef RegSuffix = Str.substr(
RegName.size());
2901 if (!RegSuffix.
empty()) {
2919AMDGPUAsmParser::isRegister()
2921 return isRegister(
getToken(), peekToken());
2924MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2925 unsigned SubReg,
unsigned RegWidth,
2929 unsigned AlignSize = 1;
2930 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2936 if (RegNum % AlignSize != 0) {
2937 Error(Loc,
"invalid register alignment");
2938 return MCRegister();
2941 unsigned RegIdx = RegNum / AlignSize;
2944 Error(Loc,
"invalid or unsupported register size");
2945 return MCRegister();
2949 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2950 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2951 Error(Loc,
"register index is out of range");
2952 return AMDGPU::NoRegister;
2955 if (RegKind == IS_VGPR && !
isGFX1250Plus() && RegIdx + RegWidth / 32 > 256) {
2956 Error(Loc,
"register index is out of range");
2957 return MCRegister();
2973bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2975 int64_t RegLo, RegHi;
2979 SMLoc FirstIdxLoc = getLoc();
2986 SecondIdxLoc = getLoc();
2997 Error(FirstIdxLoc,
"invalid register index");
3002 Error(SecondIdxLoc,
"invalid register index");
3006 if (RegLo > RegHi) {
3007 Error(FirstIdxLoc,
"first register index should not exceed second index");
3011 if (RegHi == RegLo) {
3012 StringRef RegSuffix = getTokenStr();
3013 if (RegSuffix ==
".l") {
3014 SubReg = AMDGPU::lo16;
3016 }
else if (RegSuffix ==
".h") {
3017 SubReg = AMDGPU::hi16;
3022 Num =
static_cast<unsigned>(RegLo);
3023 RegWidth = 32 * ((RegHi - RegLo) + 1);
3028MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3031 SmallVectorImpl<AsmToken> &Tokens) {
3037 RegKind = IS_SPECIAL;
3044MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3047 SmallVectorImpl<AsmToken> &Tokens) {
3049 StringRef
RegName = getTokenStr();
3050 auto Loc = getLoc();
3054 Error(Loc,
"invalid register name");
3055 return MCRegister();
3063 unsigned SubReg = NoSubRegister;
3064 if (!RegSuffix.
empty()) {
3066 SubReg = AMDGPU::lo16;
3068 SubReg = AMDGPU::hi16;
3072 Error(Loc,
"invalid register index");
3073 return MCRegister();
3078 if (!ParseRegRange(RegNum, RegWidth, SubReg))
3079 return MCRegister();
3082 return getRegularReg(RegKind, RegNum, SubReg, RegWidth, Loc);
3085MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3086 unsigned &RegNum,
unsigned &RegWidth,
3087 SmallVectorImpl<AsmToken> &Tokens) {
3089 auto ListLoc = getLoc();
3092 "expected a register or a list of registers")) {
3093 return MCRegister();
3098 auto Loc = getLoc();
3099 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3100 return MCRegister();
3101 if (RegWidth != 32) {
3102 Error(Loc,
"expected a single 32-bit register");
3103 return MCRegister();
3107 RegisterKind NextRegKind;
3109 unsigned NextRegNum, NextRegWidth;
3112 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3113 NextRegNum, NextRegWidth,
3115 return MCRegister();
3117 if (NextRegWidth != 32) {
3118 Error(Loc,
"expected a single 32-bit register");
3119 return MCRegister();
3121 if (NextRegKind != RegKind) {
3122 Error(Loc,
"registers in a list must be of the same kind");
3123 return MCRegister();
3125 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3126 return MCRegister();
3130 "expected a comma or a closing square bracket")) {
3131 return MCRegister();
3135 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3140bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3141 MCRegister &
Reg,
unsigned &RegNum,
3143 SmallVectorImpl<AsmToken> &Tokens) {
3144 auto Loc = getLoc();
3148 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3150 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3152 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3157 assert(Parser.hasPendingError());
3161 if (!subtargetHasRegister(*
TRI,
Reg)) {
3162 if (
Reg == AMDGPU::SGPR_NULL) {
3163 Error(Loc,
"'null' operand is not supported on this GPU");
3166 " register not available on this GPU");
3174bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3175 MCRegister &
Reg,
unsigned &RegNum,
3177 bool RestoreOnFailure ) {
3181 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3182 if (RestoreOnFailure) {
3183 while (!Tokens.
empty()) {
3192std::optional<StringRef>
3193AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3196 return StringRef(
".amdgcn.next_free_vgpr");
3198 return StringRef(
".amdgcn.next_free_sgpr");
3200 return std::nullopt;
3204void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3205 auto SymbolName = getGprCountSymbolName(RegKind);
3206 assert(SymbolName &&
"initializing invalid register kind");
3212bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3213 unsigned DwordRegIndex,
3214 unsigned RegWidth) {
3219 auto SymbolName = getGprCountSymbolName(RegKind);
3224 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3228 return !
Error(getLoc(),
3229 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3233 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3235 if (OldCount <= NewMax)
3241std::unique_ptr<AMDGPUOperand>
3242AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3244 SMLoc StartLoc = Tok.getLoc();
3245 SMLoc EndLoc = Tok.getEndLoc();
3246 RegisterKind RegKind;
3248 unsigned RegNum, RegWidth;
3250 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3254 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3257 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3258 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3261ParseStatus AMDGPUAsmParser::parseImm(
OperandVector &Operands,
3265 if (isRegister() || isModifier())
3268 if (
Lit == LitModifier::None) {
3269 if (trySkipId(
"lit"))
3270 Lit = LitModifier::Lit;
3271 else if (trySkipId(
"lit64"))
3272 Lit = LitModifier::Lit64;
3274 if (
Lit != LitModifier::None) {
3277 ParseStatus S = parseImm(Operands, HasSP3AbsModifier,
Lit);
3286 const auto& NextTok = peekToken();
3289 bool Negate =
false;
3297 AMDGPUOperand::Modifiers Mods;
3305 StringRef Num = getTokenStr();
3308 APFloat RealVal(APFloat::IEEEdouble());
3309 auto roundMode = APFloat::rmNearestTiesToEven;
3310 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3313 RealVal.changeSign();
3316 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3317 AMDGPUOperand::ImmTyNone,
true));
3318 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3319 Op.setModifiers(Mods);
3328 if (HasSP3AbsModifier) {
3337 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3340 if (Parser.parseExpression(Expr))
3344 if (Expr->evaluateAsAbsolute(IntVal)) {
3345 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3346 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3347 Op.setModifiers(Mods);
3349 if (
Lit != LitModifier::None)
3351 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3360ParseStatus AMDGPUAsmParser::parseReg(
OperandVector &Operands) {
3364 if (
auto R = parseRegister()) {
3372ParseStatus AMDGPUAsmParser::parseRegOrImm(
OperandVector &Operands,
3374 ParseStatus Res = parseReg(Operands);
3379 return parseImm(Operands, HasSP3AbsMod,
Lit);
3383AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3386 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3392AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3397AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3398 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3402AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3403 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3420AMDGPUAsmParser::isModifier() {
3423 AsmToken NextToken[2];
3424 peekTokens(NextToken);
3426 return isOperandModifier(Tok, NextToken[0]) ||
3427 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3428 isOpcodeModifierWithVal(Tok, NextToken[0]);
3454AMDGPUAsmParser::parseSP3NegModifier() {
3456 AsmToken NextToken[2];
3457 peekTokens(NextToken);
3460 (isRegister(NextToken[0], NextToken[1]) ||
3462 isId(NextToken[0],
"abs"))) {
3471AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
3479 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3481 SP3Neg = parseSP3NegModifier();
3484 Neg = trySkipId(
"neg");
3486 return Error(Loc,
"expected register or immediate");
3490 Abs = trySkipId(
"abs");
3495 if (trySkipId(
"lit")) {
3496 Lit = LitModifier::Lit;
3499 }
else if (trySkipId(
"lit64")) {
3500 Lit = LitModifier::Lit64;
3503 if (!has64BitLiterals())
3504 return Error(Loc,
"lit64 is not supported on this GPU");
3510 return Error(Loc,
"expected register or immediate");
3514 Res = parseRegOrImm(Operands, SP3Abs,
Lit);
3516 Res = parseReg(Operands);
3519 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3523 if (
Lit != LitModifier::None && !Operands.
back()->isImm())
3524 Error(Loc,
"expected immediate with lit modifier");
3526 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3532 if (
Lit != LitModifier::None &&
3536 AMDGPUOperand::Modifiers Mods;
3537 Mods.Abs = Abs || SP3Abs;
3538 Mods.Neg = Neg || SP3Neg;
3541 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3542 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3544 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3545 Op.setModifiers(Mods);
3551AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
3553 bool Sext = trySkipId(
"sext");
3554 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3559 Res = parseRegOrImm(Operands);
3561 Res = parseReg(Operands);
3569 AMDGPUOperand::Modifiers Mods;
3572 if (Mods.hasIntModifiers()) {
3573 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3575 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3576 Op.setModifiers(Mods);
3582ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
3583 return parseRegOrImmWithFPInputMods(Operands,
false);
3586ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
3587 return parseRegOrImmWithIntInputMods(Operands,
false);
3590ParseStatus AMDGPUAsmParser::parseVReg32OrOff(
OperandVector &Operands) {
3591 auto Loc = getLoc();
3592 if (trySkipId(
"off")) {
3593 Operands.
push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3594 AMDGPUOperand::ImmTyOff,
false));
3601 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3610unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3617 return Match_InvalidOperand;
3619 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3620 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3623 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3625 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3626 return Match_InvalidOperand;
3634 if (tryAnotherVOPDEncoding(Inst))
3635 return Match_InvalidOperand;
3637 return Match_Success;
3641 static const unsigned Variants[] = {
3651ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3652 if (isForcedDPP() && isForcedVOP3()) {
3656 if (getForcedEncodingSize() == 32) {
3661 if (isForcedVOP3()) {
3666 if (isForcedSDWA()) {
3672 if (isForcedDPP()) {
3680StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3681 if (isForcedDPP() && isForcedVOP3())
3684 if (getForcedEncodingSize() == 32)
3700AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3704 case AMDGPU::FLAT_SCR:
3706 case AMDGPU::VCC_LO:
3707 case AMDGPU::VCC_HI:
3714 return MCRegister();
3721bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3722 unsigned OpIdx)
const {
3779unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3785 case AMDGPU::V_LSHLREV_B64_e64:
3786 case AMDGPU::V_LSHLREV_B64_gfx10:
3787 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3788 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3789 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3790 case AMDGPU::V_LSHRREV_B64_e64:
3791 case AMDGPU::V_LSHRREV_B64_gfx10:
3792 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3793 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3794 case AMDGPU::V_ASHRREV_I64_e64:
3795 case AMDGPU::V_ASHRREV_I64_gfx10:
3796 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3797 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3798 case AMDGPU::V_LSHL_B64_e64:
3799 case AMDGPU::V_LSHR_B64_e64:
3800 case AMDGPU::V_ASHR_I64_e64:
3813 bool AddMandatoryLiterals =
false) {
3816 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3820 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3822 return {getNamedOperandIdx(Opcode, OpName::src0X),
3823 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3824 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3825 getNamedOperandIdx(Opcode, OpName::src0Y),
3826 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3827 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3832 return {getNamedOperandIdx(Opcode, OpName::src0),
3833 getNamedOperandIdx(Opcode, OpName::src1),
3834 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3837bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3840 return !isInlineConstant(Inst,
OpIdx);
3847 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3858 const unsigned Opcode = Inst.
getOpcode();
3859 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3862 if (!LaneSelOp.
isReg())
3865 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3868bool AMDGPUAsmParser::validateConstantBusLimitations(
3870 const unsigned Opcode = Inst.
getOpcode();
3871 const MCInstrDesc &
Desc = MII.
get(Opcode);
3872 MCRegister LastSGPR;
3873 unsigned ConstantBusUseCount = 0;
3874 unsigned NumLiterals = 0;
3875 unsigned LiteralSize;
3877 if (!(
Desc.TSFlags &
3892 SmallDenseSet<MCRegister> SGPRsUsed;
3893 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3895 SGPRsUsed.
insert(SGPRUsed);
3896 ++ConstantBusUseCount;
3901 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3903 for (
int OpIdx : OpIndices) {
3908 if (usesConstantBus(Inst,
OpIdx)) {
3917 if (SGPRsUsed.
insert(LastSGPR).second) {
3918 ++ConstantBusUseCount;
3938 if (NumLiterals == 0) {
3941 }
else if (LiteralSize !=
Size) {
3947 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3949 "invalid operand (violates constant bus restrictions)");
3956std::optional<unsigned>
3957AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3959 const unsigned Opcode = Inst.
getOpcode();
3965 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3966 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3975 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3976 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3977 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx13 ||
3978 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250 ||
3979 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx13;
3983 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3984 int I = getNamedOperandIdx(Opcode, OpName);
3988 int64_t
Imm =
Op.getImm();
3994 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3995 OpName::vsrc2Y, OpName::imm}) {
3996 int I = getNamedOperandIdx(Opcode, OpName);
4006 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
4007 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
4009 return InvalidCompOprIdx;
4012bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
4019 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
4020 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
4021 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
4023 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
4027 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
4028 if (!InvalidCompOprIdx.has_value())
4031 auto CompOprIdx = *InvalidCompOprIdx;
4034 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4035 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4036 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4038 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4039 if (CompOprIdx == VOPD::Component::DST) {
4041 Error(Loc,
"dst registers must be distinct");
4043 Error(Loc,
"one dst register must be even and the other odd");
4045 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4046 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4047 " operands must use different VGPR banks");
4055bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4057 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4058 if (!InvalidCompOprIdx.has_value())
4062 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4063 if (InvalidCompOprIdx.has_value()) {
4068 if (*InvalidCompOprIdx == VOPD::Component::DST)
4081bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4082 const unsigned Opcode = Inst.
getOpcode();
4097 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4098 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4099 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4100 int I = getNamedOperandIdx(Opcode, OpName);
4107 return !tryVOPD3(Inst);
4112bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4113 const unsigned Opcode = Inst.
getOpcode();
4118 return tryVOPD(Inst);
4119 return tryVOPD3(Inst);
4122bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4128 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4139bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4147 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4148 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4149 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4157 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4158 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4163 bool IsPackedD16 =
false;
4167 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4168 IsPackedD16 = D16Idx >= 0;
4173 if ((VDataSize / 4) ==
DataSize + TFESize)
4178 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4180 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4182 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4186bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4195 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4197 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4199 ? AMDGPU::OpName::srsrc
4200 : AMDGPU::OpName::rsrc;
4201 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4202 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4203 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4207 assert(SrsrcIdx > VAddr0Idx);
4210 if (BaseOpcode->
BVH) {
4211 if (IsA16 == BaseOpcode->
A16)
4213 Error(IDLoc,
"image address size does not match a16");
4219 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4220 unsigned ActualAddrSize =
4221 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4223 unsigned ExpectedAddrSize =
4227 if (hasPartialNSAEncoding() &&
4230 int VAddrLastIdx = SrsrcIdx - 1;
4231 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4233 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4236 if (ExpectedAddrSize > 12)
4237 ExpectedAddrSize = 16;
4242 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4246 if (ActualAddrSize == ExpectedAddrSize)
4249 Error(IDLoc,
"image address size does not match dim and a16");
4253bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4260 if (!
Desc.mayLoad() || !
Desc.mayStore())
4263 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4270 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4273bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4281 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4289 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4292bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4307 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4308 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4315bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4323 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4326 if (!BaseOpcode->
MSAA)
4329 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4335 return DimInfo->
MSAA;
4341 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4342 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4343 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4353bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4362 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4365 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4373 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4377bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4382 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4385 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4388 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4395 Error(getOperandLoc(Operands, Src0Idx),
4396 "source operand must be either a VGPR or an inline constant");
4403bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4406 const MCInstrDesc &
Desc = MII.
get(Opcode);
4409 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4412 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4416 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4417 Error(getOperandLoc(Operands, Src2Idx),
4418 "inline constants are not allowed for this operand");
4425bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4433 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4434 if (BlgpIdx != -1) {
4435 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4436 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4446 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4447 Error(getOperandLoc(Operands, Src0Idx),
4448 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4453 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4454 Error(getOperandLoc(Operands, Src1Idx),
4455 "wrong register tuple size for blgp value " + Twine(BLGP));
4463 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4467 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4471 MCRegister Src2Reg = Src2.
getReg();
4473 if (Src2Reg == DstReg)
4478 .getSizeInBits() <= 128)
4481 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4482 Error(getOperandLoc(Operands, Src2Idx),
4483 "source 2 operand must not partially overlap with dst");
4490bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4494 case V_DIV_SCALE_F32_gfx6_gfx7:
4495 case V_DIV_SCALE_F32_vi:
4496 case V_DIV_SCALE_F32_gfx10:
4497 case V_DIV_SCALE_F64_gfx6_gfx7:
4498 case V_DIV_SCALE_F64_vi:
4499 case V_DIV_SCALE_F64_gfx10:
4505 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4506 AMDGPU::OpName::src2_modifiers,
4507 AMDGPU::OpName::src2_modifiers}) {
4518bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4526 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4535bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4542 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4550 case AMDGPU::V_SUBREV_F32_e32:
4551 case AMDGPU::V_SUBREV_F32_e64:
4552 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4553 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4554 case AMDGPU::V_SUBREV_F32_e32_vi:
4555 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4556 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4557 case AMDGPU::V_SUBREV_F32_e64_vi:
4559 case AMDGPU::V_SUBREV_CO_U32_e32:
4560 case AMDGPU::V_SUBREV_CO_U32_e64:
4561 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4562 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4564 case AMDGPU::V_SUBBREV_U32_e32:
4565 case AMDGPU::V_SUBBREV_U32_e64:
4566 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4567 case AMDGPU::V_SUBBREV_U32_e32_vi:
4568 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4569 case AMDGPU::V_SUBBREV_U32_e64_vi:
4571 case AMDGPU::V_SUBREV_U32_e32:
4572 case AMDGPU::V_SUBREV_U32_e64:
4573 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4574 case AMDGPU::V_SUBREV_U32_e32_vi:
4575 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4576 case AMDGPU::V_SUBREV_U32_e64_vi:
4578 case AMDGPU::V_SUBREV_F16_e32:
4579 case AMDGPU::V_SUBREV_F16_e64:
4580 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4581 case AMDGPU::V_SUBREV_F16_e32_vi:
4582 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4583 case AMDGPU::V_SUBREV_F16_e64_vi:
4585 case AMDGPU::V_SUBREV_U16_e32:
4586 case AMDGPU::V_SUBREV_U16_e64:
4587 case AMDGPU::V_SUBREV_U16_e32_vi:
4588 case AMDGPU::V_SUBREV_U16_e64_vi:
4590 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4591 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4592 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4594 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4595 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4597 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4598 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4600 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4601 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4603 case AMDGPU::V_LSHRREV_B32_e32:
4604 case AMDGPU::V_LSHRREV_B32_e64:
4605 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4606 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4607 case AMDGPU::V_LSHRREV_B32_e32_vi:
4608 case AMDGPU::V_LSHRREV_B32_e64_vi:
4609 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4610 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4612 case AMDGPU::V_ASHRREV_I32_e32:
4613 case AMDGPU::V_ASHRREV_I32_e64:
4614 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4615 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4616 case AMDGPU::V_ASHRREV_I32_e32_vi:
4617 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4618 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4619 case AMDGPU::V_ASHRREV_I32_e64_vi:
4621 case AMDGPU::V_LSHLREV_B32_e32:
4622 case AMDGPU::V_LSHLREV_B32_e64:
4623 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4624 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4625 case AMDGPU::V_LSHLREV_B32_e32_vi:
4626 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4627 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4628 case AMDGPU::V_LSHLREV_B32_e64_vi:
4630 case AMDGPU::V_LSHLREV_B16_e32:
4631 case AMDGPU::V_LSHLREV_B16_e64:
4632 case AMDGPU::V_LSHLREV_B16_e32_vi:
4633 case AMDGPU::V_LSHLREV_B16_e64_vi:
4634 case AMDGPU::V_LSHLREV_B16_gfx10:
4636 case AMDGPU::V_LSHRREV_B16_e32:
4637 case AMDGPU::V_LSHRREV_B16_e64:
4638 case AMDGPU::V_LSHRREV_B16_e32_vi:
4639 case AMDGPU::V_LSHRREV_B16_e64_vi:
4640 case AMDGPU::V_LSHRREV_B16_gfx10:
4642 case AMDGPU::V_ASHRREV_I16_e32:
4643 case AMDGPU::V_ASHRREV_I16_e64:
4644 case AMDGPU::V_ASHRREV_I16_e32_vi:
4645 case AMDGPU::V_ASHRREV_I16_e64_vi:
4646 case AMDGPU::V_ASHRREV_I16_gfx10:
4648 case AMDGPU::V_LSHLREV_B64_e64:
4649 case AMDGPU::V_LSHLREV_B64_gfx10:
4650 case AMDGPU::V_LSHLREV_B64_vi:
4652 case AMDGPU::V_LSHRREV_B64_e64:
4653 case AMDGPU::V_LSHRREV_B64_gfx10:
4654 case AMDGPU::V_LSHRREV_B64_vi:
4656 case AMDGPU::V_ASHRREV_I64_e64:
4657 case AMDGPU::V_ASHRREV_I64_gfx10:
4658 case AMDGPU::V_ASHRREV_I64_vi:
4660 case AMDGPU::V_PK_LSHLREV_B16:
4661 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4662 case AMDGPU::V_PK_LSHLREV_B16_vi:
4664 case AMDGPU::V_PK_LSHRREV_B16:
4665 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4666 case AMDGPU::V_PK_LSHRREV_B16_vi:
4667 case AMDGPU::V_PK_ASHRREV_I16:
4668 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4669 case AMDGPU::V_PK_ASHRREV_I16_vi:
4676bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4678 using namespace SIInstrFlags;
4679 const unsigned Opcode = Inst.
getOpcode();
4680 const MCInstrDesc &
Desc = MII.
get(Opcode);
4685 if ((
Desc.TSFlags & Enc) == 0)
4688 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4689 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4693 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4696 Error(getOperandLoc(Operands, SrcIdx),
4697 "lds_direct is not supported on this GPU");
4702 Error(getOperandLoc(Operands, SrcIdx),
4703 "lds_direct cannot be used with this instruction");
4707 if (SrcName != OpName::src0) {
4708 Error(getOperandLoc(Operands, SrcIdx),
4709 "lds_direct may be used as src0 only");
4718SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4719 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4720 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4721 if (
Op.isFlatOffset())
4722 return Op.getStartLoc();
4727bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4730 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4736 return validateFlatOffset(Inst, Operands);
4739 return validateSMEMOffset(Inst, Operands);
4745 const unsigned OffsetSize = 24;
4746 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4747 Error(getFlatOffsetLoc(Operands),
4748 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4749 "-bit unsigned offset for buffer ops");
4753 const unsigned OffsetSize = 16;
4754 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4755 Error(getFlatOffsetLoc(Operands),
4756 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4763bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4770 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4774 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4775 Error(getFlatOffsetLoc(Operands),
4776 "flat offset modifier is not supported on this GPU");
4783 bool AllowNegative =
4786 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4787 Error(getFlatOffsetLoc(Operands),
4788 Twine(
"expected a ") +
4789 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4790 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4797SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4799 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4800 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4801 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4802 return Op.getStartLoc();
4807bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4817 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4831 Error(getSMEMOffsetLoc(Operands),
4833 ?
"expected a 23-bit unsigned offset for buffer ops"
4834 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4835 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4836 :
"expected a 21-bit signed offset");
4841bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4844 const MCInstrDesc &
Desc = MII.
get(Opcode);
4848 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4849 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4851 const int OpIndices[] = { Src0Idx, Src1Idx };
4853 unsigned NumExprs = 0;
4854 unsigned NumLiterals = 0;
4857 for (
int OpIdx : OpIndices) {
4858 if (
OpIdx == -1)
break;
4864 std::optional<int64_t>
Imm;
4867 }
else if (MO.
isExpr()) {
4876 if (!
Imm.has_value()) {
4878 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4882 if (NumLiterals == 0 || LiteralValue !=
Value) {
4890 if (NumLiterals + NumExprs <= 1)
4893 Error(getOperandLoc(Operands, Src1Idx),
4894 "only one unique literal operand is allowed");
4898bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4901 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4911 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4912 if (OpSelIdx != -1) {
4916 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4917 if (OpSelHiIdx != -1) {
4926 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4936 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4937 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4938 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4939 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4941 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4942 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4948 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4950 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4960 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4961 if (Src2Idx != -1) {
4962 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4972bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4973 if (!hasTrue16Insts())
4975 const MCRegisterInfo *MRI = getMRI();
4977 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4983 if (OpSelOpValue == 0)
4985 unsigned OpCount = 0;
4986 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4987 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4988 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4995 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4996 if (OpSelOpIsHi != VGPRSuffixIsHi)
5005bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
5006 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
5019 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
5030 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
5031 AMDGPU::OpName::src1_modifiers,
5032 AMDGPU::OpName::src2_modifiers};
5034 for (
unsigned i = 0; i < 3; ++i) {
5044bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5047 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5048 if (DppCtrlIdx >= 0) {
5055 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5056 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5057 :
"DP ALU dpp only supports row_newbcast");
5062 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5063 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5066 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5068 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5071 Error(getOperandLoc(Operands, Src1Idx),
5072 "invalid operand for instruction");
5076 Error(getInstLoc(Operands),
5077 "src1 immediate operand invalid for instruction");
5087bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5088 return (
Reg == AMDGPU::VCC && isWave64()) ||
5089 (
Reg == AMDGPU::VCC_LO && isWave32());
5093bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5096 const MCInstrDesc &
Desc = MII.
get(Opcode);
5097 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5099 !HasMandatoryLiteral && !
isVOPD(Opcode))
5104 std::optional<unsigned> LiteralOpIdx;
5107 for (
int OpIdx : OpIndices) {
5117 std::optional<int64_t>
Imm;
5123 bool IsAnotherLiteral =
false;
5124 if (!
Imm.has_value()) {
5126 IsAnotherLiteral =
true;
5127 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5132 HasMandatoryLiteral);
5138 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5140 "invalid operand for instruction");
5144 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5151 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5152 !getFeatureBits()[FeatureVOP3Literal]) {
5154 "literal operands are not supported");
5158 if (LiteralOpIdx && IsAnotherLiteral) {
5159 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5160 getOperandLoc(Operands, *LiteralOpIdx)),
5161 "only one unique literal operand is allowed");
5165 if (IsAnotherLiteral)
5166 LiteralOpIdx =
OpIdx;
5189bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5197 ? AMDGPU::OpName::data0
5198 : AMDGPU::OpName::vdata;
5200 const MCRegisterInfo *MRI = getMRI();
5201 int DstAreg =
IsAGPROperand(Inst, AMDGPU::OpName::vdst, MRI);
5205 int Data2Areg =
IsAGPROperand(Inst, AMDGPU::OpName::data1, MRI);
5206 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5210 auto FB = getFeatureBits();
5211 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5212 if (DataAreg < 0 || DstAreg < 0)
5214 return DstAreg == DataAreg;
5217 return DstAreg < 1 && DataAreg < 1;
5220bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5221 auto FB = getFeatureBits();
5222 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5226 const MCRegisterInfo *MRI = getMRI();
5229 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5232 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5236 case AMDGPU::DS_LOAD_TR6_B96:
5237 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5241 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5242 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5246 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5247 if (VAddrIdx != -1) {
5250 if ((
Sub - AMDGPU::VGPR0) & 1)
5255 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5256 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5261 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5262 const MCRegisterClass &AGPR32 = MRI->
getRegClass(AMDGPU::AGPR_32RegClassID);
5281SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5282 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5283 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5285 return Op.getStartLoc();
5290bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5293 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5296 SMLoc BLGPLoc = getBLGPLoc(Operands);
5299 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5300 auto FB = getFeatureBits();
5301 bool UsesNeg =
false;
5302 if (FB[AMDGPU::FeatureGFX940Insts]) {
5304 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5305 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5306 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5307 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5312 if (IsNeg == UsesNeg)
5316 UsesNeg ?
"invalid modifier: blgp is not supported"
5317 :
"invalid modifier: neg is not supported");
5322bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5328 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5329 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5330 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5331 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5334 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5337 if (
Reg == AMDGPU::SGPR_NULL)
5340 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5344bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5350 return validateGWS(Inst, Operands);
5355 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5360 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5361 Error(S,
"gds modifier is not supported on this GPU");
5369bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5371 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5375 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5376 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5379 const MCRegisterInfo *MRI = getMRI();
5380 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5382 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5385 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5387 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5394bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5397 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5398 AMDGPU::OpName::cpol);
5406 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5409 Error(S,
"scale_offset is not supported on this GPU");
5412 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5415 Error(S,
"nv is not supported on this GPU");
5420 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5423 Error(S,
"scale_offset is not supported for this instruction");
5427 return validateTHAndScopeBits(Inst, Operands, CPol);
5432 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5433 Error(S,
"cache policy is not supported for SMRD instructions");
5437 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5446 if (!(TSFlags & AllowSCCModifier)) {
5447 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5451 "scc modifier is not supported for this instruction on this GPU");
5462 :
"instruction must use glc");
5467 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5470 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5472 :
"instruction must not use glc");
5480bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5482 const unsigned CPol) {
5486 const unsigned Opcode = Inst.
getOpcode();
5487 const MCInstrDesc &TID = MII.
get(Opcode);
5490 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5497 return PrintError(
"th:TH_ATOMIC_RETURN requires a destination operand");
5502 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5510 return PrintError(
"invalid th value for SMEM instruction");
5517 return PrintError(
"scope and th combination is not valid");
5523 return PrintError(
"invalid th value for atomic instructions");
5526 return PrintError(
"invalid th value for store instructions");
5529 return PrintError(
"invalid th value for load instructions");
5535bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5538 if (
Desc.mayStore() &&
5540 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5541 if (Loc != getInstLoc(Operands)) {
5542 Error(Loc,
"TFE modifier has no meaning for store instructions");
5550bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5556 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5557 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5561 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5569 Error(getOperandLoc(Operands, SrcIdx),
5570 "wrong register tuple size for " +
5575 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5576 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5579bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5581 if (!validateLdsDirect(Inst, Operands))
5583 if (!validateTrue16OpSel(Inst)) {
5584 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5585 "op_sel operand conflicts with 16-bit operand suffix");
5588 if (!validateSOPLiteral(Inst, Operands))
5590 if (!validateVOPLiteral(Inst, Operands)) {
5593 if (!validateConstantBusLimitations(Inst, Operands)) {
5596 if (!validateVOPD(Inst, Operands)) {
5599 if (!validateIntClampSupported(Inst)) {
5600 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5601 "integer clamping is not supported on this GPU");
5604 if (!validateOpSel(Inst)) {
5605 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5606 "invalid op_sel operand");
5609 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5610 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5611 "invalid neg_lo operand");
5614 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5615 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5616 "invalid neg_hi operand");
5619 if (!validateDPP(Inst, Operands)) {
5623 if (!validateMIMGD16(Inst)) {
5624 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5625 "d16 modifier is not supported on this GPU");
5628 if (!validateMIMGDim(Inst, Operands)) {
5629 Error(IDLoc,
"missing dim operand");
5632 if (!validateTensorR128(Inst)) {
5633 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5634 "instruction must set modifier r128=0");
5637 if (!validateMIMGMSAA(Inst)) {
5638 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5639 "invalid dim; must be MSAA type");
5642 if (!validateMIMGDataSize(Inst, IDLoc)) {
5645 if (!validateMIMGAddrSize(Inst, IDLoc))
5647 if (!validateMIMGAtomicDMask(Inst)) {
5648 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5649 "invalid atomic image dmask");
5652 if (!validateMIMGGatherDMask(Inst)) {
5653 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5654 "invalid image_gather dmask: only one bit must be set");
5657 if (!validateMovrels(Inst, Operands)) {
5660 if (!validateOffset(Inst, Operands)) {
5663 if (!validateMAIAccWrite(Inst, Operands)) {
5666 if (!validateMAISrc2(Inst, Operands)) {
5669 if (!validateMFMA(Inst, Operands)) {
5672 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5676 if (!validateAGPRLdSt(Inst)) {
5677 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5678 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5679 :
"invalid register class: agpr loads and stores not supported on this GPU"
5683 if (!validateVGPRAlign(Inst)) {
5685 "invalid register class: vgpr tuples must be 64 bit aligned");
5688 if (!validateDS(Inst, Operands)) {
5692 if (!validateBLGP(Inst, Operands)) {
5696 if (!validateDivScale(Inst)) {
5697 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5700 if (!validateWaitCnt(Inst, Operands)) {
5703 if (!validateTFE(Inst, Operands)) {
5706 if (!validateWMMA(Inst, Operands)) {
5715 unsigned VariantID = 0);
5719 unsigned VariantID);
5721bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5726bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5727 const FeatureBitset &FBS,
5728 ArrayRef<unsigned> Variants) {
5729 for (
auto Variant : Variants) {
5737bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5739 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5742 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5747 getParser().clearPendingErrors();
5751 StringRef VariantName = getMatchedVariantName();
5752 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5755 " variant of this instruction is not supported"));
5759 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5760 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5762 FeatureBitset FeaturesWS32 = getFeatureBits();
5763 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5764 .
flip(AMDGPU::FeatureWavefrontSize32);
5765 FeatureBitset AvailableFeaturesWS32 =
5766 ComputeAvailableFeatures(FeaturesWS32);
5768 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5769 return Error(IDLoc,
"instruction requires wavesize=32");
5773 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5774 return Error(IDLoc,
"instruction not supported on this GPU");
5779 return Error(IDLoc,
"invalid instruction" + Suggestion);
5785 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5786 if (
Op.isToken() && InvalidOprIdx > 1) {
5787 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5788 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5793bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5796 uint64_t &ErrorInfo,
5797 bool MatchingInlineAsm) {
5800 unsigned Result = Match_Success;
5801 for (
auto Variant : getMatchedVariants()) {
5803 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5808 if (R == Match_Success || R == Match_MissingFeature ||
5809 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5810 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5811 Result != Match_MissingFeature)) {
5815 if (R == Match_Success)
5819 if (Result == Match_Success) {
5820 if (!validateInstruction(Inst, IDLoc, Operands)) {
5827 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5828 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5834 case Match_MissingFeature:
5838 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5840 case Match_InvalidOperand: {
5841 SMLoc ErrorLoc = IDLoc;
5842 if (ErrorInfo != ~0ULL) {
5843 if (ErrorInfo >= Operands.
size()) {
5844 return Error(IDLoc,
"too few operands for instruction");
5846 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5847 if (ErrorLoc == SMLoc())
5851 return Error(ErrorLoc,
"invalid VOPDY instruction");
5853 return Error(ErrorLoc,
"invalid operand for instruction");
5856 case Match_MnemonicFail:
5862bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5867 if (getParser().parseAbsoluteExpression(Tmp)) {
5870 Ret =
static_cast<uint32_t
>(Tmp);
5874bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5875 if (!getSTI().getTargetTriple().isAMDGCN())
5876 return TokError(
"directive only supported for amdgcn architecture");
5878 std::string TargetIDDirective;
5879 SMLoc TargetStart = getTok().getLoc();
5880 if (getParser().parseEscapedString(TargetIDDirective))
5883 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5884 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5885 return getParser().Error(TargetRange.
Start,
5886 (Twine(
".amdgcn_target directive's target id ") +
5887 Twine(TargetIDDirective) +
5888 Twine(
" does not match the specified target id ") +
5889 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5894bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5898bool AMDGPUAsmParser::calculateGPRBlocks(
5899 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5900 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5901 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5902 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5903 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5909 const MCExpr *
NumSGPRs = NextFreeSGPR;
5910 int64_t EvaluatedSGPRs;
5915 unsigned MaxAddressableNumSGPRs =
5918 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5919 !Features.
test(FeatureSGPRInitBug) &&
5920 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5921 return OutOfRangeError(SGPRRange);
5923 const MCExpr *ExtraSGPRs =
5927 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5928 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5929 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5930 return OutOfRangeError(SGPRRange);
5932 if (Features.
test(FeatureSGPRInitBug))
5939 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5940 unsigned Granule) ->
const MCExpr * {
5944 const MCExpr *AlignToGPR =
5946 const MCExpr *DivGPR =
5952 VGPRBlocks = GetNumGPRBlocks(
5961bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5962 if (!getSTI().getTargetTriple().isAMDGCN())
5963 return TokError(
"directive only supported for amdgcn architecture");
5966 return TokError(
"directive only supported for amdhsa OS");
5968 StringRef KernelName;
5969 if (getParser().parseIdentifier(KernelName))
5972 AMDGPU::MCKernelDescriptor KD =
5984 const MCExpr *NextFreeVGPR = ZeroExpr;
5986 const MCExpr *NamedBarCnt = ZeroExpr;
5987 uint64_t SharedVGPRCount = 0;
5988 uint64_t PreloadLength = 0;
5989 uint64_t PreloadOffset = 0;
5991 const MCExpr *NextFreeSGPR = ZeroExpr;
5994 unsigned ImpliedUserSGPRCount = 0;
5998 std::optional<unsigned> ExplicitUserSGPRCount;
5999 const MCExpr *ReserveVCC = OneExpr;
6000 const MCExpr *ReserveFlatScr = OneExpr;
6001 std::optional<bool> EnableWavefrontSize32;
6007 SMRange IDRange = getTok().getLocRange();
6008 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6011 if (
ID ==
".end_amdhsa_kernel")
6015 return TokError(
".amdhsa_ directives cannot be repeated");
6017 SMLoc ValStart = getLoc();
6018 const MCExpr *ExprVal;
6019 if (getParser().parseExpression(ExprVal))
6021 SMLoc ValEnd = getLoc();
6022 SMRange ValRange = SMRange(ValStart, ValEnd);
6025 uint64_t Val = IVal;
6026 bool EvaluatableExpr;
6027 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6029 return OutOfRangeError(ValRange);
6033#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6034 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6035 return OutOfRangeError(RANGE); \
6036 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6041#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6043 return Error(IDRange.Start, "directive should have resolvable expression", \
6046 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6049 return OutOfRangeError(ValRange);
6051 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6054 return OutOfRangeError(ValRange);
6056 }
else if (
ID ==
".amdhsa_kernarg_size") {
6058 return OutOfRangeError(ValRange);
6060 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6062 ExplicitUserSGPRCount = Val;
6063 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6067 "directive is not supported with architected flat scratch",
6070 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6073 ImpliedUserSGPRCount += 4;
6074 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6077 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6080 return OutOfRangeError(ValRange);
6084 ImpliedUserSGPRCount += Val;
6085 PreloadLength = Val;
6087 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6090 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6093 return OutOfRangeError(ValRange);
6097 PreloadOffset = Val;
6098 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6101 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6104 ImpliedUserSGPRCount += 2;
6105 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6108 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6111 ImpliedUserSGPRCount += 2;
6112 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6115 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6118 ImpliedUserSGPRCount += 2;
6119 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6122 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6125 ImpliedUserSGPRCount += 2;
6126 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6129 "directive is not supported with architected flat scratch",
6133 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6136 ImpliedUserSGPRCount += 2;
6137 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6140 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6143 ImpliedUserSGPRCount += 1;
6144 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6146 if (IVersion.
Major < 10)
6147 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6148 EnableWavefrontSize32 = Val;
6150 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6152 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6154 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6156 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6159 "directive is not supported with architected flat scratch",
6162 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6164 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6168 "directive is not supported without architected flat scratch",
6171 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6173 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6175 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6177 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6179 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6181 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6183 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6185 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6187 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6189 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6191 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6193 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6194 VGPRRange = ValRange;
6195 NextFreeVGPR = ExprVal;
6196 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6197 SGPRRange = ValRange;
6198 NextFreeSGPR = ExprVal;
6199 }
else if (
ID ==
".amdhsa_accum_offset") {
6201 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6202 AccumOffset = ExprVal;
6203 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6205 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6206 NamedBarCnt = ExprVal;
6207 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6209 return OutOfRangeError(ValRange);
6210 ReserveVCC = ExprVal;
6211 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6212 if (IVersion.
Major < 7)
6213 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6216 "directive is not supported with architected flat scratch",
6219 return OutOfRangeError(ValRange);
6220 ReserveFlatScr = ExprVal;
6221 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6222 if (IVersion.
Major < 8)
6223 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6225 return OutOfRangeError(ValRange);
6226 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6227 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6229 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6231 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6233 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6235 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6237 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6239 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6241 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6243 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6245 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6246 if (!getSTI().hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6247 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6250 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6252 }
else if (
ID ==
".amdhsa_ieee_mode") {
6253 if (!getSTI().hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6254 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6257 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6259 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6260 if (IVersion.
Major < 9)
6261 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6263 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6265 }
else if (
ID ==
".amdhsa_tg_split") {
6267 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6270 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6273 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6275 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6277 }
else if (
ID ==
".amdhsa_memory_ordered") {
6278 if (IVersion.
Major < 10)
6279 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6281 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6283 }
else if (
ID ==
".amdhsa_forward_progress") {
6284 if (IVersion.
Major < 10)
6285 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6287 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6289 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6291 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6292 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6294 SharedVGPRCount = Val;
6296 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6298 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6299 if (IVersion.
Major < 11)
6300 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6301 if (IVersion.
Major == 11) {
6303 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6307 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6310 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6313 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6315 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6317 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6319 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6322 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6324 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6326 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6328 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6330 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6332 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6334 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6336 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6338 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6340 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6341 if (IVersion.
Major < 12)
6342 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6344 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6347 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6350#undef PARSE_BITS_ENTRY
6353 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6354 return TokError(
".amdhsa_next_free_vgpr directive is required");
6356 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6357 return TokError(
".amdhsa_next_free_sgpr directive is required");
6359 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6364 if (PreloadLength) {
6370 const MCExpr *VGPRBlocks;
6371 const MCExpr *SGPRBlocks;
6372 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6373 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6374 EnableWavefrontSize32, NextFreeVGPR,
6375 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6379 int64_t EvaluatedVGPRBlocks;
6380 bool VGPRBlocksEvaluatable =
6381 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6382 if (VGPRBlocksEvaluatable &&
6384 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6385 return OutOfRangeError(VGPRRange);
6389 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6390 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6392 int64_t EvaluatedSGPRBlocks;
6393 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6395 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6396 return OutOfRangeError(SGPRRange);
6399 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6400 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6402 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6403 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6404 "enabled user SGPRs");
6408 return TokError(
"too many user SGPRs enabled");
6412 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6413 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6417 return TokError(
"too many user SGPRs enabled");
6421 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6422 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6427 return TokError(
"Kernarg size should be resolvable");
6428 uint64_t kernarg_size = IVal;
6429 if (PreloadLength && kernarg_size &&
6430 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6431 return TokError(
"Kernarg preload length + offset is larger than the "
6432 "kernarg segment size");
6435 if (!Seen.
contains(
".amdhsa_accum_offset"))
6436 return TokError(
".amdhsa_accum_offset directive is required");
6437 int64_t EvaluatedAccum;
6438 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6439 uint64_t UEvaluatedAccum = EvaluatedAccum;
6440 if (AccumEvaluatable &&
6441 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6442 return TokError(
"accum_offset should be in range [4..256] in "
6445 int64_t EvaluatedNumVGPR;
6446 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6449 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6450 return TokError(
"accum_offset exceeds total VGPR allocation");
6456 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6457 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6463 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6464 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6467 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6469 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6470 return TokError(
"shared_vgpr_count directive not valid on "
6471 "wavefront size 32");
6474 if (VGPRBlocksEvaluatable &&
6475 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6477 return TokError(
"shared_vgpr_count*2 + "
6478 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6483 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6484 NextFreeVGPR, NextFreeSGPR,
6485 ReserveVCC, ReserveFlatScr);
6489bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6491 if (ParseAsAbsoluteExpression(
Version))
6494 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6498bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6499 AMDGPUMCKernelCodeT &
C) {
6502 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6503 Parser.eatToEndOfStatement();
6507 SmallString<40> ErrStr;
6508 raw_svector_ostream Err(ErrStr);
6509 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6510 return TokError(Err.
str());
6514 if (
ID ==
"enable_wavefront_size32") {
6517 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6519 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6522 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6526 if (
ID ==
"wavefront_size") {
6527 if (
C.wavefront_size == 5) {
6529 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6531 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6532 }
else if (
C.wavefront_size == 6) {
6534 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6541bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6542 AMDGPUMCKernelCodeT KernelCode;
6551 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6554 if (
ID ==
".end_amd_kernel_code_t")
6557 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6562 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6567bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6568 StringRef KernelName;
6569 if (!parseId(KernelName,
"expected symbol name"))
6572 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6579bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6580 if (!getSTI().getTargetTriple().isAMDGCN()) {
6581 return Error(getLoc(),
6582 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6586 auto TargetIDDirective = getLexer().getTok().getStringContents();
6587 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6588 return Error(getParser().getTok().getLoc(),
"target id must match options");
6590 getTargetStreamer().EmitISAVersion();
6596bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6599 std::string HSAMetadataString;
6604 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6605 return Error(getLoc(),
"invalid HSA metadata");
6612bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6613 const char *AssemblerDirectiveEnd,
6614 std::string &CollectString) {
6616 raw_string_ostream CollectStream(CollectString);
6618 getLexer().setSkipSpace(
false);
6620 bool FoundEnd =
false;
6623 CollectStream << getTokenStr();
6627 if (trySkipId(AssemblerDirectiveEnd)) {
6632 CollectStream << Parser.parseStringToEndOfStatement()
6633 <<
getContext().getAsmInfo()->getSeparatorString();
6635 Parser.eatToEndOfStatement();
6638 getLexer().setSkipSpace(
true);
6641 return TokError(Twine(
"expected directive ") +
6642 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6649bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6655 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6656 if (!PALMetadata->setFromString(
String))
6657 return Error(getLoc(),
"invalid PAL metadata");
6662bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6664 return Error(getLoc(),
6666 "not available on non-amdpal OSes")).str());
6669 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6670 PALMetadata->setLegacy();
6673 if (ParseAsAbsoluteExpression(
Key)) {
6674 return TokError(Twine(
"invalid value in ") +
6678 return TokError(Twine(
"expected an even number of values in ") +
6681 if (ParseAsAbsoluteExpression(
Value)) {
6682 return TokError(Twine(
"invalid value in ") +
6685 PALMetadata->setRegister(
Key,
Value);
6694bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6695 if (getParser().checkForValidSection())
6699 SMLoc NameLoc = getLoc();
6700 if (getParser().parseIdentifier(Name))
6701 return TokError(
"expected identifier in directive");
6704 if (getParser().parseComma())
6710 SMLoc SizeLoc = getLoc();
6711 if (getParser().parseAbsoluteExpression(
Size))
6714 return Error(SizeLoc,
"size must be non-negative");
6715 if (
Size > LocalMemorySize)
6716 return Error(SizeLoc,
"size is too large");
6718 int64_t Alignment = 4;
6720 SMLoc AlignLoc = getLoc();
6721 if (getParser().parseAbsoluteExpression(Alignment))
6724 return Error(AlignLoc,
"alignment must be a power of two");
6729 if (Alignment >= 1u << 31)
6730 return Error(AlignLoc,
"alignment is too large");
6736 Symbol->redefineIfPossible();
6737 if (!
Symbol->isUndefined())
6738 return Error(NameLoc,
"invalid symbol redefinition");
6740 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6744bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6745 StringRef IDVal = DirectiveID.
getString();
6748 if (IDVal ==
".amdhsa_kernel")
6749 return ParseDirectiveAMDHSAKernel();
6751 if (IDVal ==
".amdhsa_code_object_version")
6752 return ParseDirectiveAMDHSACodeObjectVersion();
6756 return ParseDirectiveHSAMetadata();
6758 if (IDVal ==
".amd_kernel_code_t")
6759 return ParseDirectiveAMDKernelCodeT();
6761 if (IDVal ==
".amdgpu_hsa_kernel")
6762 return ParseDirectiveAMDGPUHsaKernel();
6764 if (IDVal ==
".amd_amdgpu_isa")
6765 return ParseDirectiveISAVersion();
6769 Twine(
" directive is "
6770 "not available on non-amdhsa OSes"))
6775 if (IDVal ==
".amdgcn_target")
6776 return ParseDirectiveAMDGCNTarget();
6778 if (IDVal ==
".amdgpu_lds")
6779 return ParseDirectiveAMDGPULDS();
6782 return ParseDirectivePALMetadataBegin();
6785 return ParseDirectivePALMetadata();
6790bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &MRI,
6797 return hasSGPR104_SGPR105();
6800 case SRC_SHARED_BASE_LO:
6801 case SRC_SHARED_BASE:
6802 case SRC_SHARED_LIMIT_LO:
6803 case SRC_SHARED_LIMIT:
6804 case SRC_PRIVATE_BASE_LO:
6805 case SRC_PRIVATE_BASE:
6806 case SRC_PRIVATE_LIMIT_LO:
6807 case SRC_PRIVATE_LIMIT:
6809 case SRC_FLAT_SCRATCH_BASE_LO:
6810 case SRC_FLAT_SCRATCH_BASE_HI:
6811 return hasGloballyAddressableScratch();
6812 case SRC_POPS_EXITING_WAVE_ID:
6824 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6854 return hasSGPR102_SGPR103();
6859ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6862 ParseStatus Res = parseVOPD(Operands);
6867 Res = MatchOperandParserImpl(Operands, Mnemonic);
6879 SMLoc LBraceLoc = getLoc();
6884 auto Loc = getLoc();
6885 Res = parseReg(Operands);
6887 Error(Loc,
"expected a register");
6891 RBraceLoc = getLoc();
6896 "expected a comma or a closing square bracket"))
6900 if (Operands.
size() - Prefix > 1) {
6902 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6903 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6909 return parseRegOrImm(Operands);
6912StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6914 setForcedEncodingSize(0);
6915 setForcedDPP(
false);
6916 setForcedSDWA(
false);
6918 if (
Name.consume_back(
"_e64_dpp")) {
6920 setForcedEncodingSize(64);
6923 if (
Name.consume_back(
"_e64")) {
6924 setForcedEncodingSize(64);
6927 if (
Name.consume_back(
"_e32")) {
6928 setForcedEncodingSize(32);
6931 if (
Name.consume_back(
"_dpp")) {
6935 if (
Name.consume_back(
"_sdwa")) {
6936 setForcedSDWA(
true);
6944 unsigned VariantID);
6950 Name = parseMnemonicSuffix(Name);
6956 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6958 bool IsMIMG = Name.starts_with(
"image_");
6961 OperandMode
Mode = OperandMode_Default;
6963 Mode = OperandMode_NSA;
6967 checkUnsupportedInstruction(Name, NameLoc);
6968 if (!Parser.hasPendingError()) {
6971 :
"not a valid operand.";
6972 Error(getLoc(), Msg);
6991ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6994 if (!trySkipId(Name))
6997 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
7001ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7010ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7011 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7012 std::function<
bool(int64_t &)> ConvertResult) {
7016 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7020 if (ConvertResult && !ConvertResult(
Value)) {
7021 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7024 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7028ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7029 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7030 bool (*ConvertResult)(int64_t &)) {
7039 const unsigned MaxSize = 4;
7043 for (
int I = 0; ; ++
I) {
7045 SMLoc Loc = getLoc();
7049 if (
Op != 0 &&
Op != 1)
7050 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7057 if (
I + 1 == MaxSize)
7058 return Error(getLoc(),
"expected a closing square bracket");
7064 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7068ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7070 AMDGPUOperand::ImmTy ImmTy,
7071 bool IgnoreNegative) {
7075 if (trySkipId(Name)) {
7077 }
else if (trySkipId(
"no", Name)) {
7086 return Error(S,
"r128 modifier is not supported on this GPU");
7087 if (Name ==
"a16" && !
hasA16())
7088 return Error(S,
"a16 modifier is not supported on this GPU");
7090 if (Bit == 0 && Name ==
"gds") {
7091 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7093 return Error(S,
"nogds is not allowed");
7096 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7097 ImmTy = AMDGPUOperand::ImmTyR128A16;
7099 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7103unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7104 bool &Disabling)
const {
7105 Disabling =
Id.consume_front(
"no");
7108 return StringSwitch<unsigned>(Id)
7115 return StringSwitch<unsigned>(Id)
7123ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7125 SMLoc StringLoc = getLoc();
7127 int64_t CPolVal = 0;
7136 ResTH = parseTH(Operands, TH);
7147 ResScope = parseScope(Operands, Scope);
7160 if (trySkipId(
"nv")) {
7164 }
else if (trySkipId(
"no",
"nv")) {
7171 if (trySkipId(
"scale_offset")) {
7175 }
else if (trySkipId(
"no",
"scale_offset")) {
7188 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7189 AMDGPUOperand::ImmTyCPol));
7193 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7194 SMLoc OpLoc = getLoc();
7195 unsigned Enabled = 0, Seen = 0;
7199 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7206 return Error(S,
"dlc modifier is not supported on this GPU");
7209 return Error(S,
"scc modifier is not supported on this GPU");
7212 return Error(S,
"duplicate cache policy modifier");
7224 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7228ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7233 ParseStatus Res = parseStringOrIntWithPrefix(
7234 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7243ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7248 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7252 if (
Value ==
"TH_DEFAULT")
7254 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7255 Value ==
"TH_LOAD_NT_WB") {
7256 return Error(StringLoc,
"invalid th value");
7257 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7259 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7261 }
else if (
Value.consume_front(
"TH_STORE_")) {
7264 return Error(StringLoc,
"invalid th value");
7267 if (
Value ==
"BYPASS")
7272 TH |= StringSwitch<int64_t>(
Value)
7282 .Default(0xffffffff);
7284 TH |= StringSwitch<int64_t>(
Value)
7295 .Default(0xffffffff);
7298 if (TH == 0xffffffff)
7299 return Error(StringLoc,
"invalid th value");
7306 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7307 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7308 std::optional<unsigned> InsertAt = std::nullopt) {
7309 auto i = OptionalIdx.find(ImmT);
7310 if (i != OptionalIdx.end()) {
7311 unsigned Idx = i->second;
7312 const AMDGPUOperand &
Op =
7313 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7317 Op.addImmOperands(Inst, 1);
7319 if (InsertAt.has_value())
7326ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7332 StringLoc = getLoc();
7337ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7338 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7343 SMLoc StringLoc = getLoc();
7347 Value = getTokenStr();
7351 if (
Value == Ids[IntVal])
7356 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7357 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7362ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7363 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7364 AMDGPUOperand::ImmTy
Type) {
7368 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7370 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7379bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7383 SMLoc Loc = getLoc();
7385 auto Res = parseIntWithPrefix(Pref, Val);
7391 if (Val < 0 || Val > MaxVal) {
7392 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7400ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7401 AMDGPUOperand::ImmTy ImmTy) {
7402 const char *Pref =
"index_key";
7404 SMLoc Loc = getLoc();
7405 auto Res = parseIntWithPrefix(Pref, ImmVal);
7409 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7410 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7411 (ImmVal < 0 || ImmVal > 1))
7412 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7414 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7415 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7417 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7421ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7422 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7425ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7426 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7429ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7430 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7433ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7435 AMDGPUOperand::ImmTy
Type) {
7440ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7441 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7442 AMDGPUOperand::ImmTyMatrixAFMT);
7445ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7446 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7447 AMDGPUOperand::ImmTyMatrixBFMT);
7450ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7452 AMDGPUOperand::ImmTy
Type) {
7457ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7458 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7459 AMDGPUOperand::ImmTyMatrixAScale);
7462ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7463 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7464 AMDGPUOperand::ImmTyMatrixBScale);
7467ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7469 AMDGPUOperand::ImmTy
Type) {
7474ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7475 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7476 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7479ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7480 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7481 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7486ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7487 using namespace llvm::AMDGPU::MTBUFFormat;
7493 for (
int I = 0;
I < 2; ++
I) {
7494 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7497 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7502 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7508 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7511 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7512 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7518ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7519 using namespace llvm::AMDGPU::MTBUFFormat;
7523 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7526 if (Fmt == UFMT_UNDEF)
7533bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7535 StringRef FormatStr,
7537 using namespace llvm::AMDGPU::MTBUFFormat;
7541 if (
Format != DFMT_UNDEF) {
7547 if (
Format != NFMT_UNDEF) {
7552 Error(Loc,
"unsupported format");
7556ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7559 using namespace llvm::AMDGPU::MTBUFFormat;
7563 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7568 SMLoc Loc = getLoc();
7569 if (!parseId(Str,
"expected a format string") ||
7570 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7572 if (Dfmt == DFMT_UNDEF)
7573 return Error(Loc,
"duplicate numeric format");
7574 if (Nfmt == NFMT_UNDEF)
7575 return Error(Loc,
"duplicate data format");
7578 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7579 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7583 if (Ufmt == UFMT_UNDEF)
7584 return Error(FormatLoc,
"unsupported format");
7593ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7596 using namespace llvm::AMDGPU::MTBUFFormat;
7599 if (Id == UFMT_UNDEF)
7603 return Error(Loc,
"unified format is not supported on this GPU");
7609ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7610 using namespace llvm::AMDGPU::MTBUFFormat;
7611 SMLoc Loc = getLoc();
7616 return Error(Loc,
"out of range format");
7621ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7622 using namespace llvm::AMDGPU::MTBUFFormat;
7628 StringRef FormatStr;
7629 SMLoc Loc = getLoc();
7630 if (!parseId(FormatStr,
"expected a format string"))
7633 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7635 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7645 return parseNumericFormat(
Format);
7648ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7649 using namespace llvm::AMDGPU::MTBUFFormat;
7653 SMLoc Loc = getLoc();
7663 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7675 Res = parseRegOrImm(Operands);
7682 Res = parseSymbolicOrNumericFormat(
Format);
7687 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7688 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7695 return Error(getLoc(),
"duplicate format");
7699ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7701 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7703 Res = parseIntWithPrefix(
"inst_offset", Operands,
7704 AMDGPUOperand::ImmTyInstOffset);
7709ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7711 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7713 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7717ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7719 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7722 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7731void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7732 OptionalImmIndexMap OptionalIdx;
7734 unsigned OperandIdx[4];
7735 unsigned EnMask = 0;
7738 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7739 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7744 OperandIdx[SrcIdx] = Inst.
size();
7745 Op.addRegOperands(Inst, 1);
7752 OperandIdx[SrcIdx] = Inst.
size();
7758 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7759 Op.addImmOperands(Inst, 1);
7763 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7767 OptionalIdx[
Op.getImmTy()] = i;
7773 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7780 for (
auto i = 0; i < SrcIdx; ++i) {
7782 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7807 IntVal =
encode(ISA, IntVal, CntVal);
7808 if (CntVal !=
decode(ISA, IntVal)) {
7810 IntVal =
encode(ISA, IntVal, -1);
7818bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7820 SMLoc CntLoc = getLoc();
7821 StringRef CntName = getTokenStr();
7828 SMLoc ValLoc = getLoc();
7837 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7839 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7841 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7844 Error(CntLoc,
"invalid counter name " + CntName);
7849 Error(ValLoc,
"too large value for " + CntName);
7858 Error(getLoc(),
"expected a counter name");
7866ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7873 if (!parseCnt(Waitcnt))
7881 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7885bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7886 SMLoc FieldLoc = getLoc();
7887 StringRef FieldName = getTokenStr();
7892 SMLoc ValueLoc = getLoc();
7899 if (FieldName ==
"instid0") {
7901 }
else if (FieldName ==
"instskip") {
7903 }
else if (FieldName ==
"instid1") {
7906 Error(FieldLoc,
"invalid field name " + FieldName);
7925 .Case(
"VALU_DEP_1", 1)
7926 .Case(
"VALU_DEP_2", 2)
7927 .Case(
"VALU_DEP_3", 3)
7928 .Case(
"VALU_DEP_4", 4)
7929 .Case(
"TRANS32_DEP_1", 5)
7930 .Case(
"TRANS32_DEP_2", 6)
7931 .Case(
"TRANS32_DEP_3", 7)
7932 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7933 .Case(
"SALU_CYCLE_1", 9)
7934 .Case(
"SALU_CYCLE_2", 10)
7935 .Case(
"SALU_CYCLE_3", 11)
7943 Delay |=
Value << Shift;
7947ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7953 if (!parseDelay(Delay))
7961 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7966AMDGPUOperand::isSWaitCnt()
const {
7970bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7976void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7977 StringRef DepCtrName) {
7980 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7983 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7986 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7989 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7996bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7998 using namespace llvm::AMDGPU::DepCtr;
8000 SMLoc DepCtrLoc = getLoc();
8001 StringRef DepCtrName = getTokenStr();
8011 unsigned PrevOprMask = UsedOprMask;
8012 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8015 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8024 Error(getLoc(),
"expected a counter name");
8029 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
8030 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8034ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
8035 using namespace llvm::AMDGPU::DepCtr;
8038 SMLoc Loc = getLoc();
8041 unsigned UsedOprMask = 0;
8043 if (!parseDepCtr(DepCtr, UsedOprMask))
8051 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8055bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8061ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8063 OperandInfoTy &Width) {
8064 using namespace llvm::AMDGPU::Hwreg;
8070 HwReg.Loc = getLoc();
8073 HwReg.IsSymbolic =
true;
8075 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8083 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8093 Width.Loc = getLoc();
8101ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8102 using namespace llvm::AMDGPU::Hwreg;
8105 SMLoc Loc = getLoc();
8107 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8109 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8110 HwregOffset::Default);
8111 struct : StructuredOpField {
8112 using StructuredOpField::StructuredOpField;
8113 bool validate(AMDGPUAsmParser &Parser)
const override {
8115 return Error(Parser,
"only values from 1 to 32 are legal");
8118 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8119 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8122 Res = parseHwregFunc(HwReg,
Offset, Width);
8125 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8127 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8131 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8138 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8140 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8144bool AMDGPUOperand::isHwreg()
const {
8145 return isImmTy(ImmTyHwreg);
8153AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8155 OperandInfoTy &Stream) {
8156 using namespace llvm::AMDGPU::SendMsg;
8161 Msg.IsSymbolic =
true;
8163 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8168 Op.IsDefined =
true;
8171 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8174 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8179 Stream.IsDefined =
true;
8180 Stream.Loc = getLoc();
8190AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8191 const OperandInfoTy &
Op,
8192 const OperandInfoTy &Stream) {
8193 using namespace llvm::AMDGPU::SendMsg;
8198 bool Strict = Msg.IsSymbolic;
8202 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8207 Error(Msg.Loc,
"invalid message id");
8213 Error(
Op.Loc,
"message does not support operations");
8215 Error(Msg.Loc,
"missing message operation");
8221 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8223 Error(
Op.Loc,
"invalid operation id");
8228 Error(Stream.Loc,
"message operation does not support streams");
8232 Error(Stream.Loc,
"invalid message stream id");
8238ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8239 using namespace llvm::AMDGPU::SendMsg;
8242 SMLoc Loc = getLoc();
8246 OperandInfoTy
Op(OP_NONE_);
8247 OperandInfoTy Stream(STREAM_ID_NONE_);
8248 if (parseSendMsgBody(Msg,
Op, Stream) &&
8249 validateSendMsg(Msg,
Op, Stream)) {
8254 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8256 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8261 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8265bool AMDGPUOperand::isSendMsg()
const {
8266 return isImmTy(ImmTySendMsg);
8269ParseStatus AMDGPUAsmParser::parseWaitEvent(
OperandVector &Operands) {
8270 using namespace llvm::AMDGPU::WaitEvent;
8272 SMLoc Loc = getLoc();
8275 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8277 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8279 StructuredOpField *TargetBitfield =
8280 isGFX11() ? &DontWaitExportReady : &ExportReady;
8282 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8286 if (!validateStructuredOpFields({TargetBitfield}))
8288 ImmVal = TargetBitfield->Val;
8295 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8297 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8298 AMDGPUOperand::ImmTyWaitEvent));
8302bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8308ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8315 int Slot = StringSwitch<int>(Str)
8322 return Error(S,
"invalid interpolation slot");
8324 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8325 AMDGPUOperand::ImmTyInterpSlot));
8329ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8336 if (!Str.starts_with(
"attr"))
8337 return Error(S,
"invalid interpolation attribute");
8339 StringRef Chan = Str.take_back(2);
8340 int AttrChan = StringSwitch<int>(Chan)
8347 return Error(S,
"invalid or missing interpolation attribute channel");
8349 Str = Str.drop_back(2).drop_front(4);
8352 if (Str.getAsInteger(10, Attr))
8353 return Error(S,
"invalid or missing interpolation attribute number");
8356 return Error(S,
"out of bounds interpolation attribute number");
8360 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8361 AMDGPUOperand::ImmTyInterpAttr));
8362 Operands.
push_back(AMDGPUOperand::CreateImm(
8363 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8371ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8372 using namespace llvm::AMDGPU::Exp;
8382 return Error(S, (Id == ET_INVALID)
8383 ?
"invalid exp target"
8384 :
"exp target is not supported on this GPU");
8386 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8387 AMDGPUOperand::ImmTyExpTgt));
8396AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8401AMDGPUAsmParser::isId(
const StringRef Id)
const {
8407 return getTokenKind() ==
Kind;
8410StringRef AMDGPUAsmParser::getId()
const {
8415AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8424AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8426 StringRef Tok = getTokenStr();
8437 if (isId(Id) && peekToken().is(Kind)) {
8447 if (isToken(Kind)) {
8456 const StringRef ErrMsg) {
8457 if (!trySkipToken(Kind)) {
8458 Error(getLoc(), ErrMsg);
8465AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8469 if (Parser.parseExpression(Expr))
8472 if (Expr->evaluateAsAbsolute(
Imm))
8475 if (Expected.empty()) {
8476 Error(S,
"expected absolute expression");
8478 Error(S, Twine(
"expected ", Expected) +
8479 Twine(
" or an absolute expression"));
8489 if (Parser.parseExpression(Expr))
8493 if (Expr->evaluateAsAbsolute(IntVal)) {
8494 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8496 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8502AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8504 Val =
getToken().getStringContents();
8508 Error(getLoc(), ErrMsg);
8513AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8515 Val = getTokenStr();
8519 if (!ErrMsg.
empty())
8520 Error(getLoc(), ErrMsg);
8525AMDGPUAsmParser::getToken()
const {
8526 return Parser.getTok();
8529AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8532 : getLexer().peekTok(ShouldSkipSpace);
8537 auto TokCount = getLexer().peekTokens(Tokens);
8539 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8544AMDGPUAsmParser::getTokenKind()
const {
8545 return getLexer().getKind();
8549AMDGPUAsmParser::getLoc()
const {
8554AMDGPUAsmParser::getTokenStr()
const {
8559AMDGPUAsmParser::lex() {
8563SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8564 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8568SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8572SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8573 int MCOpIdx)
const {
8574 for (
const auto &
Op : Operands) {
8575 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8576 if (TargetOp.getMCOpIdx() == MCOpIdx)
8577 return TargetOp.getStartLoc();
8583AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8585 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8586 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8588 return Op.getStartLoc();
8590 return getInstLoc(Operands);
8594AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8596 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8597 return getOperandLoc(
Test, Operands);
8611 StringRef
Id = getTokenStr();
8612 SMLoc IdLoc = getLoc();
8618 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8619 if (
I == Fields.
end())
8620 return Error(IdLoc,
"unknown field");
8621 if ((*I)->IsDefined)
8622 return Error(IdLoc,
"duplicate field");
8625 (*I)->Loc = getLoc();
8628 (*I)->IsDefined =
true;
8635bool AMDGPUAsmParser::validateStructuredOpFields(
8637 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8638 return F->validate(*
this);
8649 const unsigned OrMask,
8650 const unsigned XorMask) {
8659bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8660 const unsigned MaxVal,
8661 const Twine &ErrMsg, SMLoc &Loc) {
8678AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8679 const unsigned MinVal,
8680 const unsigned MaxVal,
8681 const StringRef ErrMsg) {
8683 for (
unsigned i = 0; i < OpNum; ++i) {
8684 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8692AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8693 using namespace llvm::AMDGPU::Swizzle;
8696 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8697 "expected a 2-bit lane id")) {
8708AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8709 using namespace llvm::AMDGPU::Swizzle;
8715 if (!parseSwizzleOperand(GroupSize,
8717 "group size must be in the interval [2,32]",
8722 Error(Loc,
"group size must be a power of two");
8725 if (parseSwizzleOperand(LaneIdx,
8727 "lane id must be in the interval [0,group size - 1]",
8736AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8737 using namespace llvm::AMDGPU::Swizzle;
8742 if (!parseSwizzleOperand(GroupSize,
8744 "group size must be in the interval [2,32]",
8749 Error(Loc,
"group size must be a power of two");
8758AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8759 using namespace llvm::AMDGPU::Swizzle;
8764 if (!parseSwizzleOperand(GroupSize,
8766 "group size must be in the interval [1,16]",
8771 Error(Loc,
"group size must be a power of two");
8780AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8781 using namespace llvm::AMDGPU::Swizzle;
8788 SMLoc StrLoc = getLoc();
8789 if (!parseString(Ctl)) {
8792 if (Ctl.
size() != BITMASK_WIDTH) {
8793 Error(StrLoc,
"expected a 5-character mask");
8797 unsigned AndMask = 0;
8798 unsigned OrMask = 0;
8799 unsigned XorMask = 0;
8801 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8805 Error(StrLoc,
"invalid mask");
8826bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8827 using namespace llvm::AMDGPU::Swizzle;
8830 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8836 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8837 "FFT swizzle must be in the interval [0," +
8838 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8846bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8847 using namespace llvm::AMDGPU::Swizzle;
8850 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8857 if (!parseSwizzleOperand(
Direction, 0, 1,
8858 "direction must be 0 (left) or 1 (right)", Loc))
8862 if (!parseSwizzleOperand(
8863 RotateSize, 0, ROTATE_MAX_SIZE,
8864 "number of threads to rotate must be in the interval [0," +
8865 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8870 (RotateSize << ROTATE_SIZE_SHIFT);
8875AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8877 SMLoc OffsetLoc = getLoc();
8883 Error(OffsetLoc,
"expected a 16-bit offset");
8890AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8891 using namespace llvm::AMDGPU::Swizzle;
8895 SMLoc ModeLoc = getLoc();
8898 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8899 Ok = parseSwizzleQuadPerm(
Imm);
8900 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8901 Ok = parseSwizzleBitmaskPerm(
Imm);
8902 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8903 Ok = parseSwizzleBroadcast(
Imm);
8904 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8905 Ok = parseSwizzleSwap(
Imm);
8906 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8907 Ok = parseSwizzleReverse(
Imm);
8908 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8909 Ok = parseSwizzleFFT(
Imm);
8910 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8911 Ok = parseSwizzleRotate(
Imm);
8913 Error(ModeLoc,
"expected a swizzle mode");
8916 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8922ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8926 if (trySkipId(
"offset")) {
8930 if (trySkipId(
"swizzle")) {
8931 Ok = parseSwizzleMacro(
Imm);
8933 Ok = parseSwizzleOffset(
Imm);
8937 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8945AMDGPUOperand::isSwizzle()
const {
8946 return isImmTy(ImmTySwizzle);
8953int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8955 using namespace llvm::AMDGPU::VGPRIndexMode;
8967 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8968 if (trySkipId(IdSymbolic[ModeId])) {
8976 "expected a VGPR index mode or a closing parenthesis" :
8977 "expected a VGPR index mode");
8982 Error(S,
"duplicate VGPR index mode");
8990 "expected a comma or a closing parenthesis"))
8997ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8999 using namespace llvm::AMDGPU::VGPRIndexMode;
9005 Imm = parseGPRIdxMacro();
9009 if (getParser().parseAbsoluteExpression(
Imm))
9012 return Error(S,
"invalid immediate: only 4-bit values are legal");
9016 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9020bool AMDGPUOperand::isGPRIdxMode()
const {
9021 return isImmTy(ImmTyGprIdxMode);
9028ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
9033 if (isRegister() || isModifier())
9039 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
9040 assert(Opr.isImm() || Opr.isExpr());
9041 SMLoc Loc = Opr.getStartLoc();
9045 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9046 Error(Loc,
"expected an absolute expression or a label");
9047 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9048 Error(Loc,
"expected a 16-bit signed jump offset");
9058ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
9059 return parseReg(Operands);
9066void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
9069 OptionalImmIndexMap OptionalIdx;
9070 unsigned FirstOperandIdx = 1;
9071 bool IsAtomicReturn =
false;
9078 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9079 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9083 Op.addRegOperands(Inst, 1);
9087 if (IsAtomicReturn && i == FirstOperandIdx)
9088 Op.addRegOperands(Inst, 1);
9093 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9094 Op.addImmOperands(Inst, 1);
9106 OptionalIdx[
Op.getImmTy()] = i;
9120bool AMDGPUOperand::isSMRDOffset8()
const {
9124bool AMDGPUOperand::isSMEMOffset()
const {
9126 return isImmLiteral();
9129bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9164bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9165 if (BoundCtrl == 0 || BoundCtrl == 1) {
9173void AMDGPUAsmParser::onBeginOfFile() {
9174 if (!getParser().getStreamer().getTargetStreamer() ||
9178 if (!getTargetStreamer().getTargetID())
9179 getTargetStreamer().initializeTargetID(getSTI(),
9180 getSTI().getFeatureString());
9183 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9191bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9195 StringRef TokenId = getTokenStr();
9196 AGVK VK = StringSwitch<AGVK>(TokenId)
9197 .Case(
"max", AGVK::AGVK_Max)
9198 .Case(
"or", AGVK::AGVK_Or)
9199 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9200 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9201 .Case(
"alignto", AGVK::AGVK_AlignTo)
9202 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9203 .Default(AGVK::AGVK_None);
9207 uint64_t CommaCount = 0;
9212 if (Exprs.
empty()) {
9214 "empty " + Twine(TokenId) +
" expression");
9217 if (CommaCount + 1 != Exprs.
size()) {
9219 "mismatch of commas in " + Twine(TokenId) +
" expression");
9226 if (getParser().parseExpression(Expr, EndLoc))
9230 if (LastTokenWasComma)
9234 "unexpected token in " + Twine(TokenId) +
" expression");
9240 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9243ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9244 StringRef
Name = getTokenStr();
9245 if (Name ==
"mul") {
9246 return parseIntWithPrefix(
"mul", Operands,
9250 if (Name ==
"div") {
9251 return parseIntWithPrefix(
"div", Operands,
9262 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9267 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9268 AMDGPU::OpName::src2};
9276 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9281 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9283 if (
DstOp.isReg() &&
9288 if ((OpSel & (1 << SrcNum)) != 0)
9294void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9296 cvtVOP3P(Inst, Operands);
9300void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9301 OptionalImmIndexMap &OptionalIdx) {
9302 cvtVOP3P(Inst, Operands, OptionalIdx);
9311 &&
Desc.NumOperands > (OpNum + 1)
9313 &&
Desc.operands()[OpNum + 1].RegClass != -1
9315 &&
Desc.getOperandConstraint(OpNum + 1,
9319void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9321 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9322 AMDGPU::OpName::src2};
9323 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9324 AMDGPU::OpName::src1_modifiers,
9325 AMDGPU::OpName::src2_modifiers};
9326 for (
int J = 0; J < 3; ++J) {
9327 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9333 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9336 if ((OpSel & (1 << J)) != 0)
9339 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9346void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9348 OptionalImmIndexMap OptionalIdx;
9353 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9354 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9357 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9358 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9360 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9361 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9362 Op.isInterpAttrChan()) {
9364 }
else if (
Op.isImmModifier()) {
9365 OptionalIdx[
Op.getImmTy()] =
I;
9373 AMDGPUOperand::ImmTyHigh);
9377 AMDGPUOperand::ImmTyClamp);
9381 AMDGPUOperand::ImmTyOModSI);
9386 AMDGPUOperand::ImmTyOpSel);
9387 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9390 cvtOpSelHelper(Inst, OpSel);
9394void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9396 OptionalImmIndexMap OptionalIdx;
9401 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9402 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9405 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9406 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9408 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9409 }
else if (
Op.isImmModifier()) {
9410 OptionalIdx[
Op.getImmTy()] =
I;
9418 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9428 cvtOpSelHelper(Inst, OpSel);
9431void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9433 OptionalImmIndexMap OptionalIdx;
9436 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9440 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9441 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9443 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9444 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9449 if (NumOperands == CbszOpIdx) {
9454 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9455 }
else if (
Op.isImmModifier()) {
9456 OptionalIdx[
Op.getImmTy()] =
I;
9458 Op.addRegOrImmOperands(Inst, 1);
9463 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9464 if (CbszIdx != OptionalIdx.end()) {
9465 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9469 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9470 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9471 if (BlgpIdx != OptionalIdx.end()) {
9472 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9483 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9484 if (OpselIdx != OptionalIdx.end()) {
9485 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9489 unsigned OpSelHi = 0;
9490 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9491 if (OpselHiIdx != OptionalIdx.end()) {
9492 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9495 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9496 AMDGPU::OpName::src1_modifiers};
9498 for (
unsigned J = 0; J < 2; ++J) {
9499 unsigned ModVal = 0;
9500 if (OpSel & (1 << J))
9502 if (OpSelHi & (1 << J))
9505 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9510void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9511 OptionalImmIndexMap &OptionalIdx) {
9516 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9517 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9520 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9521 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9523 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9524 }
else if (
Op.isImmModifier()) {
9525 OptionalIdx[
Op.getImmTy()] =
I;
9527 Op.addRegOrImmOperands(Inst, 1);
9533 AMDGPUOperand::ImmTyScaleSel);
9537 AMDGPUOperand::ImmTyClamp);
9543 AMDGPUOperand::ImmTyByteSel);
9548 AMDGPUOperand::ImmTyOModSI);
9555 auto *it = Inst.
begin();
9556 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9564void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9565 OptionalImmIndexMap OptionalIdx;
9566 cvtVOP3(Inst, Operands, OptionalIdx);
9569void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9570 OptionalImmIndexMap &OptIdx) {
9576 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9577 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9578 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9579 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9580 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9581 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9582 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9583 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9591 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx11 ||
9592 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx11 ||
9593 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx11 ||
9594 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx11 ||
9595 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx11 ||
9596 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx11 ||
9597 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx11 ||
9598 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx11 ||
9599 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx11 ||
9600 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx11 ||
9601 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx11 ||
9602 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx11 ||
9603 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9604 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9605 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9606 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9607 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9608 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9609 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9610 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9611 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9612 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9613 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9614 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9615 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9616 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9617 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9618 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9619 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9620 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9621 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9622 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9623 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9624 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9625 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9626 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9627 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9628 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9632 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9633 if (BitOp3Idx != -1) {
9640 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9641 if (OpSelIdx != -1) {
9645 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9646 if (OpSelHiIdx != -1) {
9647 int DefaultVal =
IsPacked ? -1 : 0;
9653 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9654 if (MatrixAFMTIdx != -1) {
9656 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9660 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9661 if (MatrixBFMTIdx != -1) {
9663 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9666 int MatrixAScaleIdx =
9667 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9668 if (MatrixAScaleIdx != -1) {
9670 AMDGPUOperand::ImmTyMatrixAScale, 0);
9673 int MatrixBScaleIdx =
9674 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9675 if (MatrixBScaleIdx != -1) {
9677 AMDGPUOperand::ImmTyMatrixBScale, 0);
9680 int MatrixAScaleFmtIdx =
9681 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9682 if (MatrixAScaleFmtIdx != -1) {
9684 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9687 int MatrixBScaleFmtIdx =
9688 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9689 if (MatrixBScaleFmtIdx != -1) {
9691 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9696 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9700 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9702 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9706 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9710 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9711 AMDGPU::OpName::src2};
9712 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9713 AMDGPU::OpName::src1_modifiers,
9714 AMDGPU::OpName::src2_modifiers};
9717 unsigned OpSelHi = 0;
9724 if (OpSelHiIdx != -1)
9733 for (
int J = 0; J < 3; ++J) {
9734 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9738 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9743 uint32_t ModVal = 0;
9746 if (SrcOp.
isReg() && getMRI()
9753 if ((OpSel & (1 << J)) != 0)
9757 if ((OpSelHi & (1 << J)) != 0)
9760 if ((NegLo & (1 << J)) != 0)
9763 if ((NegHi & (1 << J)) != 0)
9770void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9771 OptionalImmIndexMap OptIdx;
9772 cvtVOP3(Inst, Operands, OptIdx);
9773 cvtVOP3P(Inst, Operands, OptIdx);
9777 unsigned i,
unsigned Opc,
9779 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9780 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9782 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9785void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9788 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9791 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9792 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9794 OptionalImmIndexMap OptIdx;
9795 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9796 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9797 OptIdx[
Op.getImmTy()] = i;
9802 AMDGPUOperand::ImmTyIndexKey8bit);
9806 AMDGPUOperand::ImmTyIndexKey16bit);
9810 AMDGPUOperand::ImmTyIndexKey32bit);
9815 cvtVOP3P(Inst, Operands, OptIdx);
9822ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9830 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9831 SMLoc OpYLoc = getLoc();
9834 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9837 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9843void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9846 auto addOp = [&](uint16_t ParsedOprIdx) {
9847 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9849 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9853 Op.addRegOperands(Inst, 1);
9857 Op.addImmOperands(Inst, 1);
9869 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9873 const auto &CInfo = InstInfo[CompIdx];
9874 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9875 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9876 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9877 if (CInfo.hasSrc2Acc())
9878 addOp(CInfo.getIndexOfDstInParsedOperands());
9882 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9883 if (BitOp3Idx != -1) {
9884 OptionalImmIndexMap OptIdx;
9885 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9887 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9897bool AMDGPUOperand::isDPP8()
const {
9898 return isImmTy(ImmTyDPP8);
9901bool AMDGPUOperand::isDPPCtrl()
const {
9902 using namespace AMDGPU::DPP;
9904 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9907 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9908 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9909 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9910 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9911 (
Imm == DppCtrl::WAVE_SHL1) ||
9912 (
Imm == DppCtrl::WAVE_ROL1) ||
9913 (
Imm == DppCtrl::WAVE_SHR1) ||
9914 (
Imm == DppCtrl::WAVE_ROR1) ||
9915 (
Imm == DppCtrl::ROW_MIRROR) ||
9916 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9917 (
Imm == DppCtrl::BCAST15) ||
9918 (
Imm == DppCtrl::BCAST31) ||
9919 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9920 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9929bool AMDGPUOperand::isBLGP()
const {
9933bool AMDGPUOperand::isS16Imm()
const {
9937bool AMDGPUOperand::isU16Imm()
const {
9945bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9950 SMLoc Loc =
getToken().getEndLoc();
9951 Token = std::string(getTokenStr());
9953 if (getLoc() != Loc)
9958 if (!parseId(Suffix))
9962 StringRef DimId = Token;
9973ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9983 SMLoc Loc = getLoc();
9984 if (!parseDimId(Encoding))
9985 return Error(Loc,
"invalid dim value");
9987 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9988 AMDGPUOperand::ImmTyDim));
9996ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
10006 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10009 for (
size_t i = 0; i < 8; ++i) {
10013 SMLoc Loc = getLoc();
10014 if (getParser().parseAbsoluteExpression(Sels[i]))
10016 if (0 > Sels[i] || 7 < Sels[i])
10017 return Error(Loc,
"expected a 3-bit value");
10020 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10024 for (
size_t i = 0; i < 8; ++i)
10025 DPP8 |= (Sels[i] << (i * 3));
10027 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10032AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10034 if (Ctrl ==
"row_newbcast")
10037 if (Ctrl ==
"row_share" ||
10038 Ctrl ==
"row_xmask")
10041 if (Ctrl ==
"wave_shl" ||
10042 Ctrl ==
"wave_shr" ||
10043 Ctrl ==
"wave_rol" ||
10044 Ctrl ==
"wave_ror" ||
10045 Ctrl ==
"row_bcast")
10048 return Ctrl ==
"row_mirror" ||
10049 Ctrl ==
"row_half_mirror" ||
10050 Ctrl ==
"quad_perm" ||
10051 Ctrl ==
"row_shl" ||
10052 Ctrl ==
"row_shr" ||
10057AMDGPUAsmParser::parseDPPCtrlPerm() {
10060 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10064 for (
int i = 0; i < 4; ++i) {
10069 SMLoc Loc = getLoc();
10070 if (getParser().parseAbsoluteExpression(Temp))
10072 if (Temp < 0 || Temp > 3) {
10073 Error(Loc,
"expected a 2-bit value");
10077 Val += (Temp << i * 2);
10080 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10087AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10088 using namespace AMDGPU::DPP;
10093 SMLoc Loc = getLoc();
10095 if (getParser().parseAbsoluteExpression(Val))
10098 struct DppCtrlCheck {
10104 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10105 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10106 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10107 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10108 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10109 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10110 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10111 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10112 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10113 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10114 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10118 if (
Check.Ctrl == -1) {
10119 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10127 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10134ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10135 using namespace AMDGPU::DPP;
10138 !isSupportedDPPCtrl(getTokenStr(), Operands))
10141 SMLoc S = getLoc();
10147 if (Ctrl ==
"row_mirror") {
10148 Val = DppCtrl::ROW_MIRROR;
10149 }
else if (Ctrl ==
"row_half_mirror") {
10150 Val = DppCtrl::ROW_HALF_MIRROR;
10153 if (Ctrl ==
"quad_perm") {
10154 Val = parseDPPCtrlPerm();
10156 Val = parseDPPCtrlSel(Ctrl);
10165 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10169void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10171 OptionalImmIndexMap OptionalIdx;
10178 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10180 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10181 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10185 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10186 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10190 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10191 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10192 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10193 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10194 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10196 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10200 if (OldIdx == NumOperands) {
10202 constexpr int DST_IDX = 0;
10204 }
else if (Src2ModIdx == NumOperands) {
10214 if (IsVOP3CvtSrDpp) {
10223 if (TiedTo != -1) {
10228 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10230 if (IsDPP8 &&
Op.isDppFI()) {
10233 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10234 }
else if (
Op.isReg()) {
10235 Op.addRegOperands(Inst, 1);
10236 }
else if (
Op.isImm() &&
10238 Op.addImmOperands(Inst, 1);
10239 }
else if (
Op.isImm()) {
10240 OptionalIdx[
Op.getImmTy()] =
I;
10248 AMDGPUOperand::ImmTyClamp);
10254 AMDGPUOperand::ImmTyByteSel);
10261 cvtVOP3P(Inst, Operands, OptionalIdx);
10263 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10270 using namespace llvm::AMDGPU::DPP;
10280 AMDGPUOperand::ImmTyDppFI);
10284void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10285 OptionalImmIndexMap OptionalIdx;
10289 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10290 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10294 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10297 if (TiedTo != -1) {
10302 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10304 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10312 Op.addImmOperands(Inst, 1);
10314 Op.addRegWithFPInputModsOperands(Inst, 2);
10315 }
else if (
Op.isDppFI()) {
10317 }
else if (
Op.isReg()) {
10318 Op.addRegOperands(Inst, 1);
10324 Op.addRegWithFPInputModsOperands(Inst, 2);
10325 }
else if (
Op.isReg()) {
10326 Op.addRegOperands(Inst, 1);
10327 }
else if (
Op.isDPPCtrl()) {
10328 Op.addImmOperands(Inst, 1);
10329 }
else if (
Op.isImm()) {
10331 OptionalIdx[
Op.getImmTy()] =
I;
10339 using namespace llvm::AMDGPU::DPP;
10347 AMDGPUOperand::ImmTyDppFI);
10356ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10358 AMDGPUOperand::ImmTy
Type) {
10359 return parseStringOrIntWithPrefix(
10361 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10365ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10366 return parseStringOrIntWithPrefix(
10367 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10368 AMDGPUOperand::ImmTySDWADstUnused);
10371void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10375void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10379void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10383void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10387void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10391void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10392 uint64_t BasicInstType,
10395 using namespace llvm::AMDGPU::SDWA;
10397 OptionalImmIndexMap OptionalIdx;
10398 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10399 bool SkippedVcc =
false;
10403 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10404 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10407 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10408 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10409 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10410 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10428 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10429 }
else if (
Op.isImm()) {
10431 OptionalIdx[
Op.getImmTy()] =
I;
10435 SkippedVcc =
false;
10439 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10440 Opc != AMDGPU::V_NOP_sdwa_vi) {
10442 switch (BasicInstType) {
10446 AMDGPUOperand::ImmTyClamp, 0);
10450 AMDGPUOperand::ImmTyOModSI, 0);
10454 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10458 AMDGPUOperand::ImmTySDWADstUnused,
10459 DstUnused::UNUSED_PRESERVE);
10461 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10466 AMDGPUOperand::ImmTyClamp, 0);
10471 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10472 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10473 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10474 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10480 AMDGPUOperand::ImmTyClamp, 0);
10481 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10482 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10486 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10492 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10493 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10494 auto *it = Inst.
begin();
10496 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10508#define GET_MATCHER_IMPLEMENTATION
10509#define GET_MNEMONIC_SPELL_CHECKER
10510#define GET_MNEMONIC_CHECKER
10511#include "AMDGPUGenAsmMatcher.inc"
10517 return parseTokenOp(
"addr64",
Operands);
10519 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10521 return parseTokenOp(
"idxen",
Operands);
10523 return parseTokenOp(
"lds",
Operands);
10525 return parseTokenOp(
"offen",
Operands);
10527 return parseTokenOp(
"off",
Operands);
10528 case MCK_row_95_en:
10529 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10531 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10533 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10535 return tryCustomParseOperand(
Operands, MCK);
10540unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10546 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10549 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10551 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10553 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10555 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10557 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10559 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10561 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10562 case MCK_row_95_en:
10563 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10571 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10573 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10574 case MCK_SOPPBrTarget:
10575 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10576 case MCK_VReg32OrOff:
10577 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10578 case MCK_InterpSlot:
10579 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10580 case MCK_InterpAttr:
10581 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10582 case MCK_InterpAttrChan:
10583 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10585 case MCK_SReg_64_XEXEC:
10595 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10597 return Match_InvalidOperand;
10605ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10606 SMLoc S = getLoc();
10615 return Error(S,
"expected a 16-bit value");
10618 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10622bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10628bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, AMDGPU::OpName OpName)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static int IsAGPROperand(const MCInst &Inst, AMDGPU::OpName Name, const MCRegisterInfo *MRI)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
constexpr uint64_t MIMGFlags
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static bool IsRevOpcode(const unsigned Opcode)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static MCRegister getSpecialRegForName(StringRef RegName)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0, std::optional< unsigned > InsertAt=std::nullopt)
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Loop::LoopBounds::Direction Direction
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
MachineInstr unsigned OpIdx
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static 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 isGFX1170(const MCSubtargetInfo &STI)
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
bool isGFX1250Plus(const MCSubtargetInfo &STI)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
@ Valid
The data is already valid.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
FunctionAddr VTableAddr uintptr_t uintptr_t Version
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ Default
The result values are uniform if and only if all operands are uniform.
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
Instruction set architecture version.
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
const MCExpr * compute_pgm_rsrc1
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * group_segment_fixed_size
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * kernel_code_properties
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size