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);
182 ImmTyMatrixAScaleFmt,
183 ImmTyMatrixBScaleFmt,
216 mutable int MCOpIdx = -1;
219 bool isToken()
const override {
return Kind == Token; }
221 bool isSymbolRefExpr()
const {
225 bool isImm()
const override {
226 return Kind == Immediate;
229 bool isInlinableImm(MVT type)
const;
230 bool isLiteralImm(MVT type)
const;
232 bool isRegKind()
const {
233 return Kind == Register;
236 bool isReg()
const override {
237 return isRegKind() && !hasModifiers();
240 bool isRegOrInline(
unsigned RCID, MVT type)
const {
241 return isRegClass(RCID) || isInlinableImm(type);
245 return isRegOrInline(RCID, type) || isLiteralImm(type);
248 bool isRegOrImmWithInt16InputMods()
const {
252 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
254 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
257 bool isRegOrImmWithInt32InputMods()
const {
261 bool isRegOrInlineImmWithInt16InputMods()
const {
262 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
265 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
266 return isRegOrInline(
267 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
270 bool isRegOrInlineImmWithInt32InputMods()
const {
271 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
274 bool isRegOrImmWithInt64InputMods()
const {
278 bool isRegOrImmWithFP16InputMods()
const {
282 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
284 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
287 bool isRegOrImmWithFP32InputMods()
const {
291 bool isRegOrImmWithFP64InputMods()
const {
295 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
296 return isRegOrInline(
297 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
300 bool isRegOrInlineImmWithFP32InputMods()
const {
301 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
304 bool isRegOrInlineImmWithFP64InputMods()
const {
305 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
308 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
310 bool isVRegWithFP32InputMods()
const {
311 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
314 bool isVRegWithFP64InputMods()
const {
315 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
318 bool isPackedFP16InputMods()
const {
322 bool isPackedVGPRFP32InputMods()
const {
326 bool isVReg()
const {
327 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
328 isRegClass(AMDGPU::VReg_64RegClassID) ||
329 isRegClass(AMDGPU::VReg_96RegClassID) ||
330 isRegClass(AMDGPU::VReg_128RegClassID) ||
331 isRegClass(AMDGPU::VReg_160RegClassID) ||
332 isRegClass(AMDGPU::VReg_192RegClassID) ||
333 isRegClass(AMDGPU::VReg_256RegClassID) ||
334 isRegClass(AMDGPU::VReg_512RegClassID) ||
335 isRegClass(AMDGPU::VReg_1024RegClassID);
338 bool isVReg32()
const {
339 return isRegClass(AMDGPU::VGPR_32RegClassID);
342 bool isVReg32OrOff()
const {
343 return isOff() || isVReg32();
347 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
350 bool isAV_LdSt_32_Align2_RegOp()
const {
351 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
352 isRegClass(AMDGPU::AGPR_32RegClassID);
355 bool isVRegWithInputMods()
const;
356 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
357 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
359 bool isSDWAOperand(MVT type)
const;
360 bool isSDWAFP16Operand()
const;
361 bool isSDWAFP32Operand()
const;
362 bool isSDWAInt16Operand()
const;
363 bool isSDWAInt32Operand()
const;
365 bool isImmTy(ImmTy ImmT)
const {
366 return isImm() &&
Imm.Type == ImmT;
369 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
371 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
373 bool isImmModifier()
const {
374 return isImm() &&
Imm.Type != ImmTyNone;
377 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
378 bool isDim()
const {
return isImmTy(ImmTyDim); }
379 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
380 bool isOff()
const {
return isImmTy(ImmTyOff); }
381 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
382 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
383 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
384 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
385 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
386 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
387 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
388 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
389 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
390 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
391 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
392 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
393 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
394 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
395 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
396 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
397 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
398 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
399 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
400 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
401 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
402 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
403 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
404 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
405 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
406 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
407 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
408 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
409 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
410 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
411 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
412 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
413 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
414 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
415 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
417 bool isRegOrImm()
const {
418 return isReg() || isImm();
421 bool isRegClass(
unsigned RCID)
const;
425 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
426 return isRegOrInline(RCID, type) && !hasModifiers();
429 bool isSCSrcB16()
const {
430 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
433 bool isSCSrcV2B16()
const {
437 bool isSCSrc_b32()
const {
438 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
441 bool isSCSrc_b64()
const {
442 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
445 bool isBoolReg()
const;
447 bool isSCSrcF16()
const {
448 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
451 bool isSCSrcV2F16()
const {
455 bool isSCSrcF32()
const {
456 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
459 bool isSCSrcF64()
const {
460 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
463 bool isSSrc_b32()
const {
464 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
467 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
469 bool isSSrcV2B16()
const {
474 bool isSSrc_b64()
const {
477 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
478 (((
const MCTargetAsmParser *)AsmParser)
479 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
483 bool isSSrc_f32()
const {
484 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
487 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
489 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
491 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
493 bool isSSrcV2F16()
const {
498 bool isSSrcV2FP32()
const {
503 bool isSCSrcV2FP32()
const {
508 bool isSSrcV2INT32()
const {
513 bool isSCSrcV2INT32()
const {
515 return isSCSrc_b32();
518 bool isSSrcOrLds_b32()
const {
519 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
520 isLiteralImm(MVT::i32) || isExpr();
523 bool isVCSrc_b32()
const {
524 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
527 bool isVCSrc_b32_Lo256()
const {
528 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
531 bool isVCSrc_b64_Lo256()
const {
532 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
535 bool isVCSrc_b64()
const {
536 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
539 bool isVCSrcT_b16()
const {
540 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
543 bool isVCSrcTB16_Lo128()
const {
544 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
547 bool isVCSrcFake16B16_Lo128()
const {
548 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
551 bool isVCSrc_b16()
const {
552 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
555 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
557 bool isVCSrc_f32()
const {
558 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
561 bool isVCSrc_f64()
const {
562 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
565 bool isVCSrcTBF16()
const {
566 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
569 bool isVCSrcT_f16()
const {
570 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
573 bool isVCSrcT_bf16()
const {
574 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
577 bool isVCSrcTBF16_Lo128()
const {
578 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
581 bool isVCSrcTF16_Lo128()
const {
582 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
585 bool isVCSrcFake16BF16_Lo128()
const {
586 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
589 bool isVCSrcFake16F16_Lo128()
const {
590 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
593 bool isVCSrc_bf16()
const {
594 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
597 bool isVCSrc_f16()
const {
598 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
601 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
603 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
605 bool isVSrc_b32()
const {
606 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
609 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
611 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
613 bool isVSrcT_b16_Lo128()
const {
614 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
617 bool isVSrcFake16_b16_Lo128()
const {
618 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
621 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
623 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
625 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
627 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
629 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
631 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
633 bool isVSrc_f32()
const {
634 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
637 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
639 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
641 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
643 bool isVSrcT_bf16_Lo128()
const {
644 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
647 bool isVSrcT_f16_Lo128()
const {
648 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
651 bool isVSrcFake16_bf16_Lo128()
const {
652 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
655 bool isVSrcFake16_f16_Lo128()
const {
656 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
659 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
661 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
663 bool isVSrc_v2bf16()
const {
664 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
667 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
669 bool isVSrc_v2f16_splat()
const {
return isVSrc_v2f16(); }
671 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
673 bool isVISrcB32()
const {
674 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
677 bool isVISrcB16()
const {
678 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
681 bool isVISrcV2B16()
const {
685 bool isVISrcF32()
const {
686 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
689 bool isVISrcF16()
const {
690 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
693 bool isVISrcV2F16()
const {
694 return isVISrcF16() || isVISrcB32();
697 bool isVISrc_64_bf16()
const {
698 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
701 bool isVISrc_64_f16()
const {
702 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
705 bool isVISrc_64_b32()
const {
706 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
709 bool isVISrc_64B64()
const {
710 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
713 bool isVISrc_64_f64()
const {
714 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
717 bool isVISrc_64V2FP32()
const {
718 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
721 bool isVISrc_64V2INT32()
const {
722 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
725 bool isVISrc_256_b32()
const {
726 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
729 bool isVISrc_256_f32()
const {
730 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
733 bool isVISrc_256B64()
const {
734 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
737 bool isVISrc_256_f64()
const {
738 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
741 bool isVISrc_512_f64()
const {
742 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
745 bool isVISrc_128B16()
const {
746 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
749 bool isVISrc_128V2B16()
const {
750 return isVISrc_128B16();
753 bool isVISrc_128_b32()
const {
754 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
757 bool isVISrc_128_f32()
const {
758 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
761 bool isVISrc_256V2FP32()
const {
762 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
765 bool isVISrc_256V2INT32()
const {
766 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
769 bool isVISrc_512_b32()
const {
770 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
773 bool isVISrc_512B16()
const {
774 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
777 bool isVISrc_512V2B16()
const {
778 return isVISrc_512B16();
781 bool isVISrc_512_f32()
const {
782 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
785 bool isVISrc_512F16()
const {
786 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
789 bool isVISrc_512V2F16()
const {
790 return isVISrc_512F16() || isVISrc_512_b32();
793 bool isVISrc_1024_b32()
const {
794 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
797 bool isVISrc_1024B16()
const {
798 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
801 bool isVISrc_1024V2B16()
const {
802 return isVISrc_1024B16();
805 bool isVISrc_1024_f32()
const {
806 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
809 bool isVISrc_1024F16()
const {
810 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
813 bool isVISrc_1024V2F16()
const {
814 return isVISrc_1024F16() || isVISrc_1024_b32();
817 bool isAISrcB32()
const {
818 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
821 bool isAISrcB16()
const {
822 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
825 bool isAISrcV2B16()
const {
829 bool isAISrcF32()
const {
830 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
833 bool isAISrcF16()
const {
834 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
837 bool isAISrcV2F16()
const {
838 return isAISrcF16() || isAISrcB32();
841 bool isAISrc_64B64()
const {
842 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
845 bool isAISrc_64_f64()
const {
846 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
849 bool isAISrc_128_b32()
const {
850 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
853 bool isAISrc_128B16()
const {
854 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
857 bool isAISrc_128V2B16()
const {
858 return isAISrc_128B16();
861 bool isAISrc_128_f32()
const {
862 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
865 bool isAISrc_128F16()
const {
866 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
869 bool isAISrc_128V2F16()
const {
870 return isAISrc_128F16() || isAISrc_128_b32();
873 bool isVISrc_128_bf16()
const {
874 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
877 bool isVISrc_128_f16()
const {
878 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
881 bool isVISrc_128V2F16()
const {
882 return isVISrc_128_f16() || isVISrc_128_b32();
885 bool isAISrc_256B64()
const {
886 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
889 bool isAISrc_256_f64()
const {
890 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
893 bool isAISrc_512_b32()
const {
894 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
897 bool isAISrc_512B16()
const {
898 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
901 bool isAISrc_512V2B16()
const {
902 return isAISrc_512B16();
905 bool isAISrc_512_f32()
const {
906 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
909 bool isAISrc_512F16()
const {
910 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
913 bool isAISrc_512V2F16()
const {
914 return isAISrc_512F16() || isAISrc_512_b32();
917 bool isAISrc_1024_b32()
const {
918 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
921 bool isAISrc_1024B16()
const {
922 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
925 bool isAISrc_1024V2B16()
const {
926 return isAISrc_1024B16();
929 bool isAISrc_1024_f32()
const {
930 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
933 bool isAISrc_1024F16()
const {
934 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
937 bool isAISrc_1024V2F16()
const {
938 return isAISrc_1024F16() || isAISrc_1024_b32();
941 bool isKImmFP32()
const {
942 return isLiteralImm(MVT::f32);
945 bool isKImmFP16()
const {
946 return isLiteralImm(MVT::f16);
949 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
951 bool isMem()
const override {
955 bool isExpr()
const {
956 return Kind == Expression;
959 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
961 bool isSWaitCnt()
const;
962 bool isDepCtr()
const;
963 bool isSDelayALU()
const;
964 bool isHwreg()
const;
965 bool isSendMsg()
const;
966 bool isSplitBarrier()
const;
967 bool isSwizzle()
const;
968 bool isSMRDOffset8()
const;
969 bool isSMEMOffset()
const;
970 bool isSMRDLiteralOffset()
const;
972 bool isDPPCtrl()
const;
974 bool isGPRIdxMode()
const;
975 bool isS16Imm()
const;
976 bool isU16Imm()
const;
977 bool isEndpgm()
const;
979 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
980 return [
this,
P]() {
return P(*
this); };
985 return StringRef(Tok.Data, Tok.Length);
993 void setImm(int64_t Val) {
998 ImmTy getImmTy()
const {
1003 MCRegister
getReg()
const override {
1008 SMLoc getStartLoc()
const override {
1012 SMLoc getEndLoc()
const override {
1016 SMRange getLocRange()
const {
1017 return SMRange(StartLoc, EndLoc);
1020 int getMCOpIdx()
const {
return MCOpIdx; }
1022 Modifiers getModifiers()
const {
1023 assert(isRegKind() || isImmTy(ImmTyNone));
1024 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1027 void setModifiers(Modifiers Mods) {
1028 assert(isRegKind() || isImmTy(ImmTyNone));
1035 bool hasModifiers()
const {
1036 return getModifiers().hasModifiers();
1039 bool hasFPModifiers()
const {
1040 return getModifiers().hasFPModifiers();
1043 bool hasIntModifiers()
const {
1044 return getModifiers().hasIntModifiers();
1047 uint64_t applyInputFPModifiers(uint64_t Val,
unsigned Size)
const;
1049 void addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1051 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1053 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1055 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1057 addRegOperands(Inst,
N);
1059 addImmOperands(Inst,
N);
1062 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1063 Modifiers Mods = getModifiers();
1066 addRegOperands(Inst,
N);
1068 addImmOperands(Inst,
N,
false);
1072 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1073 assert(!hasIntModifiers());
1074 addRegOrImmWithInputModsOperands(Inst,
N);
1077 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1078 assert(!hasFPModifiers());
1079 addRegOrImmWithInputModsOperands(Inst,
N);
1082 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1083 Modifiers Mods = getModifiers();
1086 addRegOperands(Inst,
N);
1089 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1090 assert(!hasIntModifiers());
1091 addRegWithInputModsOperands(Inst,
N);
1094 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1095 assert(!hasFPModifiers());
1096 addRegWithInputModsOperands(Inst,
N);
1099 static void printImmTy(raw_ostream& OS, ImmTy
Type) {
1102 case ImmTyNone: OS <<
"None";
break;
1103 case ImmTyGDS: OS <<
"GDS";
break;
1104 case ImmTyLDS: OS <<
"LDS";
break;
1105 case ImmTyOffen: OS <<
"Offen";
break;
1106 case ImmTyIdxen: OS <<
"Idxen";
break;
1107 case ImmTyAddr64: OS <<
"Addr64";
break;
1108 case ImmTyOffset: OS <<
"Offset";
break;
1109 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1110 case ImmTyOffset0: OS <<
"Offset0";
break;
1111 case ImmTyOffset1: OS <<
"Offset1";
break;
1112 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1113 case ImmTyCPol: OS <<
"CPol";
break;
1114 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1115 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1116 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1117 case ImmTyTFE: OS <<
"TFE";
break;
1118 case ImmTyD16: OS <<
"D16";
break;
1119 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1120 case ImmTyClamp: OS <<
"Clamp";
break;
1121 case ImmTyOModSI: OS <<
"OModSI";
break;
1122 case ImmTyDPP8: OS <<
"DPP8";
break;
1123 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1124 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1125 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1126 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1127 case ImmTyDppFI: OS <<
"DppFI";
break;
1128 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1129 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1130 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1131 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1132 case ImmTyDMask: OS <<
"DMask";
break;
1133 case ImmTyDim: OS <<
"Dim";
break;
1134 case ImmTyUNorm: OS <<
"UNorm";
break;
1135 case ImmTyDA: OS <<
"DA";
break;
1136 case ImmTyR128A16: OS <<
"R128A16";
break;
1137 case ImmTyA16: OS <<
"A16";
break;
1138 case ImmTyLWE: OS <<
"LWE";
break;
1139 case ImmTyOff: OS <<
"Off";
break;
1140 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1141 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1142 case ImmTyExpVM: OS <<
"ExpVM";
break;
1143 case ImmTyHwreg: OS <<
"Hwreg";
break;
1144 case ImmTySendMsg: OS <<
"SendMsg";
break;
1145 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1146 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1147 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1148 case ImmTyOpSel: OS <<
"OpSel";
break;
1149 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1150 case ImmTyNegLo: OS <<
"NegLo";
break;
1151 case ImmTyNegHi: OS <<
"NegHi";
break;
1152 case ImmTySwizzle: OS <<
"Swizzle";
break;
1153 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1154 case ImmTyHigh: OS <<
"High";
break;
1155 case ImmTyBLGP: OS <<
"BLGP";
break;
1156 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1157 case ImmTyABID: OS <<
"ABID";
break;
1158 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1159 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1160 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1161 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1162 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1163 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1164 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1165 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1166 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1167 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1168 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1169 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1170 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1171 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1172 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1173 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1178 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1182 <<
" mods: " <<
Reg.Mods <<
'>';
1186 if (getImmTy() != ImmTyNone) {
1187 OS <<
" type: "; printImmTy(OS, getImmTy());
1189 OS <<
" mods: " <<
Imm.Mods <<
'>';
1202 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1203 int64_t Val, SMLoc Loc,
1204 ImmTy
Type = ImmTyNone,
1205 bool IsFPImm =
false) {
1206 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1208 Op->Imm.IsFPImm = IsFPImm;
1210 Op->Imm.Mods = Modifiers();
1216 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1217 StringRef Str, SMLoc Loc,
1218 bool HasExplicitEncodingSize =
true) {
1219 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1220 Res->Tok.Data = Str.data();
1221 Res->Tok.Length = Str.size();
1222 Res->StartLoc = Loc;
1227 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1228 MCRegister
Reg, SMLoc S, SMLoc
E) {
1229 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1230 Op->Reg.RegNo =
Reg;
1231 Op->Reg.Mods = Modifiers();
1237 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1238 const class MCExpr *Expr, SMLoc S) {
1239 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1248 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1257#define GET_REGISTER_MATCHER
1258#include "AMDGPUGenAsmMatcher.inc"
1259#undef GET_REGISTER_MATCHER
1260#undef GET_SUBTARGET_FEATURE_NAME
1265class KernelScopeInfo {
1266 int SgprIndexUnusedMin = -1;
1267 int VgprIndexUnusedMin = -1;
1268 int AgprIndexUnusedMin = -1;
1272 void usesSgprAt(
int i) {
1273 if (i >= SgprIndexUnusedMin) {
1274 SgprIndexUnusedMin = ++i;
1277 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1283 void usesVgprAt(
int i) {
1284 if (i >= VgprIndexUnusedMin) {
1285 VgprIndexUnusedMin = ++i;
1288 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1290 VgprIndexUnusedMin);
1296 void usesAgprAt(
int i) {
1301 if (i >= AgprIndexUnusedMin) {
1302 AgprIndexUnusedMin = ++i;
1305 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1310 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1312 VgprIndexUnusedMin);
1319 KernelScopeInfo() =
default;
1323 MSTI = Ctx->getSubtargetInfo();
1325 usesSgprAt(SgprIndexUnusedMin = -1);
1326 usesVgprAt(VgprIndexUnusedMin = -1);
1328 usesAgprAt(AgprIndexUnusedMin = -1);
1332 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1333 unsigned RegWidth) {
1336 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1339 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1342 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1351 MCAsmParser &Parser;
1353 unsigned ForcedEncodingSize = 0;
1354 bool ForcedDPP =
false;
1355 bool ForcedSDWA =
false;
1356 KernelScopeInfo KernelScope;
1357 const unsigned HwMode;
1362#define GET_ASSEMBLER_HEADER
1363#include "AMDGPUGenAsmMatcher.inc"
1368 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1370 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1375 void createConstantSymbol(StringRef Id, int64_t Val);
1377 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1378 bool OutOfRangeError(SMRange
Range);
1394 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1395 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1396 std::optional<bool> EnableWavefrontSize32,
1397 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1398 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1399 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1400 bool ParseDirectiveAMDGCNTarget();
1401 bool ParseDirectiveAMDHSACodeObjectVersion();
1402 bool ParseDirectiveAMDHSAKernel();
1403 bool ParseAMDKernelCodeTValue(StringRef
ID, AMDGPUMCKernelCodeT &Header);
1404 bool ParseDirectiveAMDKernelCodeT();
1406 bool subtargetHasRegister(
const MCRegisterInfo &
MRI, MCRegister
Reg);
1407 bool ParseDirectiveAMDGPUHsaKernel();
1409 bool ParseDirectiveISAVersion();
1410 bool ParseDirectiveHSAMetadata();
1411 bool ParseDirectivePALMetadataBegin();
1412 bool ParseDirectivePALMetadata();
1413 bool ParseDirectiveAMDGPULDS();
1417 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1418 const char *AssemblerDirectiveEnd,
1419 std::string &CollectString);
1421 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1422 RegisterKind RegKind, MCRegister Reg1, SMLoc Loc);
1423 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1424 unsigned &RegNum,
unsigned &RegWidth,
1425 bool RestoreOnFailure =
false);
1426 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1427 unsigned &RegNum,
unsigned &RegWidth,
1428 SmallVectorImpl<AsmToken> &Tokens);
1429 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1431 SmallVectorImpl<AsmToken> &Tokens);
1432 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1434 SmallVectorImpl<AsmToken> &Tokens);
1435 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1437 SmallVectorImpl<AsmToken> &Tokens);
1438 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &
SubReg);
1439 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1440 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1443 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1444 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1445 void initializeGprCountSymbol(RegisterKind RegKind);
1446 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1448 void cvtMubufImpl(MCInst &Inst,
const OperandVector &Operands,
1453 OperandMode_Default,
1457 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1459 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1460 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
1461 : MCTargetAsmParser(
Options, STI, MII), Parser(_Parser),
1462 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)) {
1465 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1469 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1470 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1471 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1473 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1474 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1475 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1478 initializeGprCountSymbol(IS_VGPR);
1479 initializeGprCountSymbol(IS_SGPR);
1484 createConstantSymbol(Symbol, Code);
1486 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1487 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1488 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1560 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1562 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1564 bool hasInv2PiInlineImm()
const {
1565 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1568 bool has64BitLiterals()
const {
1569 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1572 bool hasFlatOffsets()
const {
1573 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1576 bool hasTrue16Insts()
const {
1577 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1581 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1584 bool hasSGPR102_SGPR103()
const {
1588 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1590 bool hasIntClamp()
const {
1591 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1594 bool hasPartialNSAEncoding()
const {
1595 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1598 bool hasGloballyAddressableScratch()
const {
1599 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1612 AMDGPUTargetStreamer &getTargetStreamer() {
1613 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1614 return static_cast<AMDGPUTargetStreamer &
>(TS);
1620 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1623 const MCRegisterInfo *getMRI()
const {
1627 const MCInstrInfo *getMII()
const {
1633 const FeatureBitset &getFeatureBits()
const {
1634 return getSTI().getFeatureBits();
1637 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1638 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1639 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1641 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1642 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1643 bool isForcedDPP()
const {
return ForcedDPP; }
1644 bool isForcedSDWA()
const {
return ForcedSDWA; }
1645 ArrayRef<unsigned> getMatchedVariants()
const;
1646 StringRef getMatchedVariantName()
const;
1648 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1649 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1650 bool RestoreOnFailure);
1651 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1652 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1653 SMLoc &EndLoc)
override;
1654 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1655 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1656 unsigned Kind)
override;
1657 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1659 uint64_t &ErrorInfo,
1660 bool MatchingInlineAsm)
override;
1661 bool ParseDirective(AsmToken DirectiveID)
override;
1662 ParseStatus parseOperand(
OperandVector &Operands, StringRef Mnemonic,
1663 OperandMode
Mode = OperandMode_Default);
1664 StringRef parseMnemonicSuffix(StringRef Name);
1665 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
1669 ParseStatus parseTokenOp(StringRef Name,
OperandVector &Operands);
1671 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1674 parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1675 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1676 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1678 ParseStatus parseOperandArrayWithPrefix(
1680 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1681 bool (*ConvertResult)(int64_t &) =
nullptr);
1685 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1686 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1688 ParseStatus parseScope(
OperandVector &Operands, int64_t &Scope);
1690 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1692 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1694 ArrayRef<const char *> Ids,
1696 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1698 ArrayRef<const char *> Ids,
1699 AMDGPUOperand::ImmTy
Type);
1702 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1703 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1704 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1705 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1706 bool parseSP3NegModifier();
1707 ParseStatus parseImm(
OperandVector &Operands,
bool HasSP3AbsModifier =
false,
1710 ParseStatus parseRegOrImm(
OperandVector &Operands,
bool HasSP3AbsMod =
false,
1712 ParseStatus parseRegOrImmWithFPInputMods(
OperandVector &Operands,
1713 bool AllowImm =
true);
1714 ParseStatus parseRegOrImmWithIntInputMods(
OperandVector &Operands,
1715 bool AllowImm =
true);
1716 ParseStatus parseRegWithFPInputMods(
OperandVector &Operands);
1717 ParseStatus parseRegWithIntInputMods(
OperandVector &Operands);
1720 AMDGPUOperand::ImmTy ImmTy);
1724 ParseStatus tryParseMatrixFMT(
OperandVector &Operands, StringRef Name,
1725 AMDGPUOperand::ImmTy
Type);
1728 ParseStatus tryParseMatrixScale(
OperandVector &Operands, StringRef Name,
1729 AMDGPUOperand::ImmTy
Type);
1732 ParseStatus tryParseMatrixScaleFmt(
OperandVector &Operands, StringRef Name,
1733 AMDGPUOperand::ImmTy
Type);
1737 ParseStatus parseDfmtNfmt(int64_t &
Format);
1738 ParseStatus parseUfmt(int64_t &
Format);
1739 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1741 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1744 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1745 ParseStatus parseNumericFormat(int64_t &
Format);
1749 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1750 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1754 bool parseCnt(int64_t &IntVal);
1757 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1758 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1761 bool parseDelay(int64_t &Delay);
1767 struct OperandInfoTy {
1770 bool IsSymbolic =
false;
1771 bool IsDefined =
false;
1773 OperandInfoTy(int64_t Val) : Val(Val) {}
1776 struct StructuredOpField : OperandInfoTy {
1780 bool IsDefined =
false;
1782 StructuredOpField(StringLiteral Id, StringLiteral Desc,
unsigned Width,
1784 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1785 virtual ~StructuredOpField() =
default;
1787 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1788 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1792 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1794 return Error(Parser,
"not supported on this GPU");
1796 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1804 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1805 bool validateSendMsg(
const OperandInfoTy &Msg,
1806 const OperandInfoTy &
Op,
1807 const OperandInfoTy &Stream);
1809 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1810 OperandInfoTy &Width);
1812 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1814 SMLoc getFlatOffsetLoc(
const OperandVector &Operands)
const;
1815 SMLoc getSMEMOffsetLoc(
const OperandVector &Operands)
const;
1818 SMLoc getOperandLoc(
const OperandVector &Operands,
int MCOpIdx)
const;
1819 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1821 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1825 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1827 bool validateOffset(
const MCInst &Inst,
const OperandVector &Operands);
1828 bool validateFlatOffset(
const MCInst &Inst,
const OperandVector &Operands);
1829 bool validateSMEMOffset(
const MCInst &Inst,
const OperandVector &Operands);
1830 bool validateSOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1831 bool validateConstantBusLimitations(
const MCInst &Inst,
const OperandVector &Operands);
1832 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1834 bool validateVOPD(
const MCInst &Inst,
const OperandVector &Operands);
1835 bool tryVOPD(
const MCInst &Inst);
1836 bool tryVOPD3(
const MCInst &Inst);
1837 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1839 bool validateIntClampSupported(
const MCInst &Inst);
1840 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1841 bool validateMIMGGatherDMask(
const MCInst &Inst);
1842 bool validateMovrels(
const MCInst &Inst,
const OperandVector &Operands);
1843 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1844 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1845 bool validateMIMGD16(
const MCInst &Inst);
1846 bool validateMIMGDim(
const MCInst &Inst,
const OperandVector &Operands);
1847 bool validateTensorR128(
const MCInst &Inst);
1848 bool validateMIMGMSAA(
const MCInst &Inst);
1849 bool validateOpSel(
const MCInst &Inst);
1850 bool validateTrue16OpSel(
const MCInst &Inst);
1851 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1852 bool validateDPP(
const MCInst &Inst,
const OperandVector &Operands);
1853 bool validateVccOperand(MCRegister
Reg)
const;
1854 bool validateVOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1855 bool validateMAIAccWrite(
const MCInst &Inst,
const OperandVector &Operands);
1856 bool validateMAISrc2(
const MCInst &Inst,
const OperandVector &Operands);
1857 bool validateMFMA(
const MCInst &Inst,
const OperandVector &Operands);
1858 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1859 bool validateVGPRAlign(
const MCInst &Inst)
const;
1860 bool validateBLGP(
const MCInst &Inst,
const OperandVector &Operands);
1861 bool validateDS(
const MCInst &Inst,
const OperandVector &Operands);
1862 bool validateGWS(
const MCInst &Inst,
const OperandVector &Operands);
1863 bool validateDivScale(
const MCInst &Inst);
1864 bool validateWaitCnt(
const MCInst &Inst,
const OperandVector &Operands);
1865 bool validateCoherencyBits(
const MCInst &Inst,
const OperandVector &Operands,
1867 bool validateTHAndScopeBits(
const MCInst &Inst,
const OperandVector &Operands,
1868 const unsigned CPol);
1869 bool validateTFE(
const MCInst &Inst,
const OperandVector &Operands);
1870 bool validateLdsDirect(
const MCInst &Inst,
const OperandVector &Operands);
1871 bool validateWMMA(
const MCInst &Inst,
const OperandVector &Operands);
1872 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1873 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1874 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1875 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1877 bool isSupportedMnemo(StringRef Mnemo,
1878 const FeatureBitset &FBS);
1879 bool isSupportedMnemo(StringRef Mnemo,
1880 const FeatureBitset &FBS,
1881 ArrayRef<unsigned> Variants);
1882 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1884 bool isId(
const StringRef Id)
const;
1885 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1887 StringRef getId()
const;
1888 bool trySkipId(
const StringRef Id);
1889 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1893 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1894 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1900 StringRef getTokenStr()
const;
1901 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1903 SMLoc getLoc()
const;
1907 void onBeginOfFile()
override;
1908 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1910 ParseStatus parseCustomOperand(
OperandVector &Operands,
unsigned MCK);
1919 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1920 const unsigned MaxVal,
const Twine &ErrMsg,
1922 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1923 const unsigned MinVal,
1924 const unsigned MaxVal,
1925 const StringRef ErrMsg);
1927 bool parseSwizzleOffset(int64_t &
Imm);
1928 bool parseSwizzleMacro(int64_t &
Imm);
1929 bool parseSwizzleQuadPerm(int64_t &
Imm);
1930 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1931 bool parseSwizzleBroadcast(int64_t &
Imm);
1932 bool parseSwizzleSwap(int64_t &
Imm);
1933 bool parseSwizzleReverse(int64_t &
Imm);
1934 bool parseSwizzleFFT(int64_t &
Imm);
1935 bool parseSwizzleRotate(int64_t &
Imm);
1938 int64_t parseGPRIdxMacro();
1940 void cvtMubuf(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
false); }
1941 void cvtMubufAtomic(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
true); }
1946 OptionalImmIndexMap &OptionalIdx);
1947 void cvtScaledMFMA(MCInst &Inst,
const OperandVector &Operands);
1948 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands);
1951 void cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands);
1954 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
1955 OptionalImmIndexMap &OptionalIdx);
1957 OptionalImmIndexMap &OptionalIdx);
1959 void cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands);
1960 void cvtVINTERP(MCInst &Inst,
const OperandVector &Operands);
1961 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1963 bool parseDimId(
unsigned &Encoding);
1965 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1968 bool isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands);
1969 int64_t parseDPPCtrlSel(StringRef Ctrl);
1970 int64_t parseDPPCtrlPerm();
1971 void cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8 =
false);
1973 cvtDPP(Inst, Operands,
true);
1975 void cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
1976 bool IsDPP8 =
false);
1977 void cvtVOP3DPP8(MCInst &Inst,
const OperandVector &Operands) {
1978 cvtVOP3DPP(Inst, Operands,
true);
1981 ParseStatus parseSDWASel(
OperandVector &Operands, StringRef Prefix,
1982 AMDGPUOperand::ImmTy
Type);
1984 void cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands);
1985 void cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands);
1986 void cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands);
1987 void cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands);
1988 void cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands);
1990 uint64_t BasicInstType,
1991 bool SkipDstVcc =
false,
1992 bool SkipSrcVcc =
false);
2101bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2111 if (!isImmTy(ImmTyNone)) {
2116 if (getModifiers().
Lit != LitModifier::None)
2126 if (type == MVT::f64 || type == MVT::i64) {
2128 AsmParser->hasInv2PiInlineImm());
2131 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2150 APFloat::rmNearestTiesToEven, &Lost);
2157 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2159 AsmParser->hasInv2PiInlineImm());
2164 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2165 AsmParser->hasInv2PiInlineImm());
2169 if (type == MVT::f64 || type == MVT::i64) {
2171 AsmParser->hasInv2PiInlineImm());
2180 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2181 type, AsmParser->hasInv2PiInlineImm());
2185 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2186 AsmParser->hasInv2PiInlineImm());
2189bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2191 if (!isImmTy(ImmTyNone)) {
2196 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2201 if (type == MVT::f64 && hasFPModifiers()) {
2221 if (type == MVT::f64) {
2226 if (type == MVT::i64) {
2239 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2240 : (type == MVT::v2i16) ? MVT::f32
2241 : (type == MVT::v2f32) ? MVT::f32
2244 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2248bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2249 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2252bool AMDGPUOperand::isVRegWithInputMods()
const {
2253 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2255 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2256 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2259template <
bool IsFake16>
2260bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2261 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2262 : AMDGPU::VGPR_16_Lo128RegClassID);
2265template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2266 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2267 : AMDGPU::VGPR_16RegClassID);
2270bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2271 if (AsmParser->isVI())
2273 if (AsmParser->isGFX9Plus())
2274 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2278bool AMDGPUOperand::isSDWAFP16Operand()
const {
2279 return isSDWAOperand(MVT::f16);
2282bool AMDGPUOperand::isSDWAFP32Operand()
const {
2283 return isSDWAOperand(MVT::f32);
2286bool AMDGPUOperand::isSDWAInt16Operand()
const {
2287 return isSDWAOperand(MVT::i16);
2290bool AMDGPUOperand::isSDWAInt32Operand()
const {
2291 return isSDWAOperand(MVT::i32);
2294bool AMDGPUOperand::isBoolReg()
const {
2295 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2296 (AsmParser->isWave32() && isSCSrc_b32()));
2299uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2301 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2304 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2316void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2326 addLiteralImmOperand(Inst,
Imm.Val,
2328 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2330 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2335void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2336 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2341 if (ApplyModifiers) {
2344 Val = applyInputFPModifiers(Val,
Size);
2348 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2350 bool CanUse64BitLiterals =
2351 AsmParser->has64BitLiterals() &&
2354 MCContext &Ctx = AsmParser->getContext();
2363 if (
Lit == LitModifier::None &&
2365 AsmParser->hasInv2PiInlineImm())) {
2373 bool HasMandatoryLiteral =
2376 if (
Literal.getLoBits(32) != 0 &&
2377 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2378 !HasMandatoryLiteral) {
2379 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2381 "Can't encode literal as exact 64-bit floating-point operand. "
2382 "Low 32-bits will be set to zero");
2383 Val &= 0xffffffff00000000u;
2389 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2395 Lit = LitModifier::Lit64;
2396 }
else if (
Lit == LitModifier::Lit) {
2410 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2412 Lit = LitModifier::Lit64;
2419 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2420 Literal == 0x3fc45f306725feed) {
2455 APFloat::rmNearestTiesToEven, &lost);
2459 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2466 if (
Lit != LitModifier::None) {
2496 if (
Lit == LitModifier::None &&
2506 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2513 if (
Lit == LitModifier::None &&
2521 if (!AsmParser->has64BitLiterals()) {
2522 Val =
static_cast<uint64_t
>(Val) << 32;
2529 if (
Lit == LitModifier::Lit ||
2531 Val =
static_cast<uint64_t
>(Val) << 32;
2535 if (
Lit == LitModifier::Lit)
2561 if (
Lit != LitModifier::None) {
2569void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2574bool AMDGPUOperand::isInlineValue()
const {
2582void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2593 if (Is == IS_VGPR) {
2597 return AMDGPU::VGPR_32RegClassID;
2599 return AMDGPU::VReg_64RegClassID;
2601 return AMDGPU::VReg_96RegClassID;
2603 return AMDGPU::VReg_128RegClassID;
2605 return AMDGPU::VReg_160RegClassID;
2607 return AMDGPU::VReg_192RegClassID;
2609 return AMDGPU::VReg_224RegClassID;
2611 return AMDGPU::VReg_256RegClassID;
2613 return AMDGPU::VReg_288RegClassID;
2615 return AMDGPU::VReg_320RegClassID;
2617 return AMDGPU::VReg_352RegClassID;
2619 return AMDGPU::VReg_384RegClassID;
2621 return AMDGPU::VReg_512RegClassID;
2623 return AMDGPU::VReg_1024RegClassID;
2625 }
else if (Is == IS_TTMP) {
2629 return AMDGPU::TTMP_32RegClassID;
2631 return AMDGPU::TTMP_64RegClassID;
2633 return AMDGPU::TTMP_128RegClassID;
2635 return AMDGPU::TTMP_256RegClassID;
2637 return AMDGPU::TTMP_512RegClassID;
2639 }
else if (Is == IS_SGPR) {
2643 return AMDGPU::SGPR_32RegClassID;
2645 return AMDGPU::SGPR_64RegClassID;
2647 return AMDGPU::SGPR_96RegClassID;
2649 return AMDGPU::SGPR_128RegClassID;
2651 return AMDGPU::SGPR_160RegClassID;
2653 return AMDGPU::SGPR_192RegClassID;
2655 return AMDGPU::SGPR_224RegClassID;
2657 return AMDGPU::SGPR_256RegClassID;
2659 return AMDGPU::SGPR_288RegClassID;
2661 return AMDGPU::SGPR_320RegClassID;
2663 return AMDGPU::SGPR_352RegClassID;
2665 return AMDGPU::SGPR_384RegClassID;
2667 return AMDGPU::SGPR_512RegClassID;
2669 }
else if (Is == IS_AGPR) {
2673 return AMDGPU::AGPR_32RegClassID;
2675 return AMDGPU::AReg_64RegClassID;
2677 return AMDGPU::AReg_96RegClassID;
2679 return AMDGPU::AReg_128RegClassID;
2681 return AMDGPU::AReg_160RegClassID;
2683 return AMDGPU::AReg_192RegClassID;
2685 return AMDGPU::AReg_224RegClassID;
2687 return AMDGPU::AReg_256RegClassID;
2689 return AMDGPU::AReg_288RegClassID;
2691 return AMDGPU::AReg_320RegClassID;
2693 return AMDGPU::AReg_352RegClassID;
2695 return AMDGPU::AReg_384RegClassID;
2697 return AMDGPU::AReg_512RegClassID;
2699 return AMDGPU::AReg_1024RegClassID;
2707 .
Case(
"exec", AMDGPU::EXEC)
2708 .
Case(
"vcc", AMDGPU::VCC)
2709 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2710 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2711 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2712 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2713 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2714 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2715 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2716 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2717 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2718 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2719 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2720 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2721 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2722 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2723 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2724 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2725 .
Case(
"m0", AMDGPU::M0)
2726 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2727 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2728 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2729 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2730 .
Case(
"scc", AMDGPU::SRC_SCC)
2731 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2732 .
Case(
"tba", AMDGPU::TBA)
2733 .
Case(
"tma", AMDGPU::TMA)
2734 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2735 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2736 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2737 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2738 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2739 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2740 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2741 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2742 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2743 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2744 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2745 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2746 .
Case(
"pc", AMDGPU::PC_REG)
2747 .
Case(
"null", AMDGPU::SGPR_NULL)
2751bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2752 SMLoc &EndLoc,
bool RestoreOnFailure) {
2753 auto R = parseRegister();
2754 if (!R)
return true;
2756 RegNo =
R->getReg();
2757 StartLoc =
R->getStartLoc();
2758 EndLoc =
R->getEndLoc();
2762bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2764 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2767ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2769 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2770 bool PendingErrors = getParser().hasPendingError();
2771 getParser().clearPendingErrors();
2779bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2780 RegisterKind RegKind,
2781 MCRegister Reg1, SMLoc Loc) {
2784 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2789 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2790 Reg = AMDGPU::FLAT_SCR;
2794 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2795 Reg = AMDGPU::XNACK_MASK;
2799 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2804 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2809 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2814 Error(Loc,
"register does not fit in the list");
2820 if (Reg1 !=
Reg + RegWidth / 32) {
2821 Error(Loc,
"registers in a list must have consecutive indices");
2839 {{
"ttmp"}, IS_TTMP},
2845 return Kind == IS_VGPR ||
2853 if (Str.starts_with(
Reg.Name))
2859 return !Str.getAsInteger(10, Num);
2863AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2864 const AsmToken &NextToken)
const {
2879 StringRef RegSuffix = Str.substr(
RegName.size());
2880 if (!RegSuffix.
empty()) {
2898AMDGPUAsmParser::isRegister()
2900 return isRegister(
getToken(), peekToken());
2903MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2904 unsigned SubReg,
unsigned RegWidth,
2908 unsigned AlignSize = 1;
2909 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2915 if (RegNum % AlignSize != 0) {
2916 Error(Loc,
"invalid register alignment");
2917 return MCRegister();
2920 unsigned RegIdx = RegNum / AlignSize;
2923 Error(Loc,
"invalid or unsupported register size");
2924 return MCRegister();
2928 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2929 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2930 Error(Loc,
"register index is out of range");
2931 return AMDGPU::NoRegister;
2934 if (RegKind == IS_VGPR && !
isGFX1250() && RegIdx + RegWidth / 32 > 256) {
2935 Error(Loc,
"register index is out of range");
2936 return MCRegister();
2952bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2954 int64_t RegLo, RegHi;
2958 SMLoc FirstIdxLoc = getLoc();
2965 SecondIdxLoc = getLoc();
2976 Error(FirstIdxLoc,
"invalid register index");
2981 Error(SecondIdxLoc,
"invalid register index");
2985 if (RegLo > RegHi) {
2986 Error(FirstIdxLoc,
"first register index should not exceed second index");
2990 if (RegHi == RegLo) {
2991 StringRef RegSuffix = getTokenStr();
2992 if (RegSuffix ==
".l") {
2995 }
else if (RegSuffix ==
".h") {
3001 Num =
static_cast<unsigned>(RegLo);
3002 RegWidth = 32 * ((RegHi - RegLo) + 1);
3007MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3010 SmallVectorImpl<AsmToken> &Tokens) {
3016 RegKind = IS_SPECIAL;
3023MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3026 SmallVectorImpl<AsmToken> &Tokens) {
3028 StringRef
RegName = getTokenStr();
3029 auto Loc = getLoc();
3033 Error(Loc,
"invalid register name");
3034 return MCRegister();
3042 unsigned SubReg = NoSubRegister;
3043 if (!RegSuffix.
empty()) {
3051 Error(Loc,
"invalid register index");
3052 return MCRegister();
3057 if (!ParseRegRange(RegNum, RegWidth,
SubReg))
3058 return MCRegister();
3061 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
3064MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3065 unsigned &RegNum,
unsigned &RegWidth,
3066 SmallVectorImpl<AsmToken> &Tokens) {
3068 auto ListLoc = getLoc();
3071 "expected a register or a list of registers")) {
3072 return MCRegister();
3077 auto Loc = getLoc();
3078 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3079 return MCRegister();
3080 if (RegWidth != 32) {
3081 Error(Loc,
"expected a single 32-bit register");
3082 return MCRegister();
3086 RegisterKind NextRegKind;
3088 unsigned NextRegNum, NextRegWidth;
3091 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3092 NextRegNum, NextRegWidth,
3094 return MCRegister();
3096 if (NextRegWidth != 32) {
3097 Error(Loc,
"expected a single 32-bit register");
3098 return MCRegister();
3100 if (NextRegKind != RegKind) {
3101 Error(Loc,
"registers in a list must be of the same kind");
3102 return MCRegister();
3104 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3105 return MCRegister();
3109 "expected a comma or a closing square bracket")) {
3110 return MCRegister();
3114 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3119bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3120 MCRegister &
Reg,
unsigned &RegNum,
3122 SmallVectorImpl<AsmToken> &Tokens) {
3123 auto Loc = getLoc();
3127 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3129 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3131 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3136 assert(Parser.hasPendingError());
3140 if (!subtargetHasRegister(*
TRI,
Reg)) {
3141 if (
Reg == AMDGPU::SGPR_NULL) {
3142 Error(Loc,
"'null' operand is not supported on this GPU");
3145 " register not available on this GPU");
3153bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3154 MCRegister &
Reg,
unsigned &RegNum,
3156 bool RestoreOnFailure ) {
3160 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3161 if (RestoreOnFailure) {
3162 while (!Tokens.
empty()) {
3171std::optional<StringRef>
3172AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3175 return StringRef(
".amdgcn.next_free_vgpr");
3177 return StringRef(
".amdgcn.next_free_sgpr");
3179 return std::nullopt;
3183void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3184 auto SymbolName = getGprCountSymbolName(RegKind);
3185 assert(SymbolName &&
"initializing invalid register kind");
3191bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3192 unsigned DwordRegIndex,
3193 unsigned RegWidth) {
3198 auto SymbolName = getGprCountSymbolName(RegKind);
3203 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3207 return !
Error(getLoc(),
3208 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3212 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3214 if (OldCount <= NewMax)
3220std::unique_ptr<AMDGPUOperand>
3221AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3223 SMLoc StartLoc = Tok.getLoc();
3224 SMLoc EndLoc = Tok.getEndLoc();
3225 RegisterKind RegKind;
3227 unsigned RegNum, RegWidth;
3229 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3233 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3236 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3237 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3240ParseStatus AMDGPUAsmParser::parseImm(
OperandVector &Operands,
3244 if (isRegister() || isModifier())
3247 if (
Lit == LitModifier::None) {
3248 if (trySkipId(
"lit"))
3249 Lit = LitModifier::Lit;
3250 else if (trySkipId(
"lit64"))
3251 Lit = LitModifier::Lit64;
3253 if (
Lit != LitModifier::None) {
3256 ParseStatus S = parseImm(Operands, HasSP3AbsModifier,
Lit);
3265 const auto& NextTok = peekToken();
3268 bool Negate =
false;
3276 AMDGPUOperand::Modifiers Mods;
3284 StringRef Num = getTokenStr();
3287 APFloat RealVal(APFloat::IEEEdouble());
3288 auto roundMode = APFloat::rmNearestTiesToEven;
3289 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3292 RealVal.changeSign();
3295 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3296 AMDGPUOperand::ImmTyNone,
true));
3297 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3298 Op.setModifiers(Mods);
3307 if (HasSP3AbsModifier) {
3316 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3319 if (Parser.parseExpression(Expr))
3323 if (Expr->evaluateAsAbsolute(IntVal)) {
3324 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3325 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3326 Op.setModifiers(Mods);
3328 if (
Lit != LitModifier::None)
3330 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3339ParseStatus AMDGPUAsmParser::parseReg(
OperandVector &Operands) {
3343 if (
auto R = parseRegister()) {
3351ParseStatus AMDGPUAsmParser::parseRegOrImm(
OperandVector &Operands,
3353 ParseStatus Res = parseReg(Operands);
3358 return parseImm(Operands, HasSP3AbsMod,
Lit);
3362AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3365 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3371AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3376AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3377 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3381AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3382 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3399AMDGPUAsmParser::isModifier() {
3402 AsmToken NextToken[2];
3403 peekTokens(NextToken);
3405 return isOperandModifier(Tok, NextToken[0]) ||
3406 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3407 isOpcodeModifierWithVal(Tok, NextToken[0]);
3433AMDGPUAsmParser::parseSP3NegModifier() {
3435 AsmToken NextToken[2];
3436 peekTokens(NextToken);
3439 (isRegister(NextToken[0], NextToken[1]) ||
3441 isId(NextToken[0],
"abs"))) {
3450AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
3458 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3460 SP3Neg = parseSP3NegModifier();
3463 Neg = trySkipId(
"neg");
3465 return Error(Loc,
"expected register or immediate");
3469 Abs = trySkipId(
"abs");
3474 if (trySkipId(
"lit")) {
3475 Lit = LitModifier::Lit;
3478 }
else if (trySkipId(
"lit64")) {
3479 Lit = LitModifier::Lit64;
3482 if (!has64BitLiterals())
3483 return Error(Loc,
"lit64 is not supported on this GPU");
3489 return Error(Loc,
"expected register or immediate");
3493 Res = parseRegOrImm(Operands, SP3Abs,
Lit);
3495 Res = parseReg(Operands);
3498 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3502 if (
Lit != LitModifier::None && !Operands.
back()->isImm())
3503 Error(Loc,
"expected immediate with lit modifier");
3505 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3511 if (
Lit != LitModifier::None &&
3515 AMDGPUOperand::Modifiers Mods;
3516 Mods.Abs = Abs || SP3Abs;
3517 Mods.Neg = Neg || SP3Neg;
3520 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3521 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3523 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3524 Op.setModifiers(Mods);
3530AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
3532 bool Sext = trySkipId(
"sext");
3533 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3538 Res = parseRegOrImm(Operands);
3540 Res = parseReg(Operands);
3548 AMDGPUOperand::Modifiers Mods;
3551 if (Mods.hasIntModifiers()) {
3552 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3554 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3555 Op.setModifiers(Mods);
3561ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
3562 return parseRegOrImmWithFPInputMods(Operands,
false);
3565ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
3566 return parseRegOrImmWithIntInputMods(Operands,
false);
3569ParseStatus AMDGPUAsmParser::parseVReg32OrOff(
OperandVector &Operands) {
3570 auto Loc = getLoc();
3571 if (trySkipId(
"off")) {
3572 Operands.
push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3573 AMDGPUOperand::ImmTyOff,
false));
3580 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3589unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3596 return Match_InvalidOperand;
3598 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3599 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3602 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3604 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3605 return Match_InvalidOperand;
3613 if (tryAnotherVOPDEncoding(Inst))
3614 return Match_InvalidOperand;
3616 return Match_Success;
3620 static const unsigned Variants[] = {
3630ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3631 if (isForcedDPP() && isForcedVOP3()) {
3635 if (getForcedEncodingSize() == 32) {
3640 if (isForcedVOP3()) {
3645 if (isForcedSDWA()) {
3651 if (isForcedDPP()) {
3659StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3660 if (isForcedDPP() && isForcedVOP3())
3663 if (getForcedEncodingSize() == 32)
3679AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3683 case AMDGPU::FLAT_SCR:
3685 case AMDGPU::VCC_LO:
3686 case AMDGPU::VCC_HI:
3693 return MCRegister();
3700bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3701 unsigned OpIdx)
const {
3758unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3764 case AMDGPU::V_LSHLREV_B64_e64:
3765 case AMDGPU::V_LSHLREV_B64_gfx10:
3766 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3767 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3768 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3769 case AMDGPU::V_LSHRREV_B64_e64:
3770 case AMDGPU::V_LSHRREV_B64_gfx10:
3771 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3772 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3773 case AMDGPU::V_ASHRREV_I64_e64:
3774 case AMDGPU::V_ASHRREV_I64_gfx10:
3775 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3776 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3777 case AMDGPU::V_LSHL_B64_e64:
3778 case AMDGPU::V_LSHR_B64_e64:
3779 case AMDGPU::V_ASHR_I64_e64:
3792 bool AddMandatoryLiterals =
false) {
3795 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3799 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3801 return {getNamedOperandIdx(Opcode, OpName::src0X),
3802 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3803 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3804 getNamedOperandIdx(Opcode, OpName::src0Y),
3805 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3806 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3811 return {getNamedOperandIdx(Opcode, OpName::src0),
3812 getNamedOperandIdx(Opcode, OpName::src1),
3813 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3816bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3819 return !isInlineConstant(Inst,
OpIdx);
3826 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3837 const unsigned Opcode = Inst.
getOpcode();
3838 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3841 if (!LaneSelOp.
isReg())
3844 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3847bool AMDGPUAsmParser::validateConstantBusLimitations(
3849 const unsigned Opcode = Inst.
getOpcode();
3850 const MCInstrDesc &
Desc = MII.
get(Opcode);
3851 MCRegister LastSGPR;
3852 unsigned ConstantBusUseCount = 0;
3853 unsigned NumLiterals = 0;
3854 unsigned LiteralSize;
3856 if (!(
Desc.TSFlags &
3871 SmallDenseSet<MCRegister> SGPRsUsed;
3872 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3874 SGPRsUsed.
insert(SGPRUsed);
3875 ++ConstantBusUseCount;
3880 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3882 for (
int OpIdx : OpIndices) {
3887 if (usesConstantBus(Inst,
OpIdx)) {
3896 if (SGPRsUsed.
insert(LastSGPR).second) {
3897 ++ConstantBusUseCount;
3917 if (NumLiterals == 0) {
3920 }
else if (LiteralSize !=
Size) {
3926 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3928 "invalid operand (violates constant bus restrictions)");
3935std::optional<unsigned>
3936AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3938 const unsigned Opcode = Inst.
getOpcode();
3944 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3945 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3953 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3954 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3955 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250;
3959 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3960 int I = getNamedOperandIdx(Opcode, OpName);
3964 int64_t
Imm =
Op.getImm();
3970 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3971 OpName::vsrc2Y, OpName::imm}) {
3972 int I = getNamedOperandIdx(Opcode, OpName);
3982 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3983 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3985 return InvalidCompOprIdx;
3988bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
3995 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
3996 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
3997 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
3999 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
4003 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
4004 if (!InvalidCompOprIdx.has_value())
4007 auto CompOprIdx = *InvalidCompOprIdx;
4010 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4011 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4012 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4014 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4015 if (CompOprIdx == VOPD::Component::DST) {
4017 Error(Loc,
"dst registers must be distinct");
4019 Error(Loc,
"one dst register must be even and the other odd");
4021 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4022 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4023 " operands must use different VGPR banks");
4031bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4033 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4034 if (!InvalidCompOprIdx.has_value())
4038 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4039 if (InvalidCompOprIdx.has_value()) {
4044 if (*InvalidCompOprIdx == VOPD::Component::DST)
4057bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4058 const unsigned Opcode = Inst.
getOpcode();
4073 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4074 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4075 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4076 int I = getNamedOperandIdx(Opcode, OpName);
4083 return !tryVOPD3(Inst);
4088bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4089 const unsigned Opcode = Inst.
getOpcode();
4094 return tryVOPD(Inst);
4095 return tryVOPD3(Inst);
4098bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4104 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4115bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4123 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4124 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4125 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4133 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4134 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4139 bool IsPackedD16 =
false;
4143 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4144 IsPackedD16 = D16Idx >= 0;
4149 if ((VDataSize / 4) ==
DataSize + TFESize)
4154 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4156 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4158 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4162bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4171 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4173 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4175 ? AMDGPU::OpName::srsrc
4176 : AMDGPU::OpName::rsrc;
4177 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4178 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4179 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4183 assert(SrsrcIdx > VAddr0Idx);
4186 if (BaseOpcode->
BVH) {
4187 if (IsA16 == BaseOpcode->
A16)
4189 Error(IDLoc,
"image address size does not match a16");
4195 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4196 unsigned ActualAddrSize =
4197 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4199 unsigned ExpectedAddrSize =
4203 if (hasPartialNSAEncoding() &&
4206 int VAddrLastIdx = SrsrcIdx - 1;
4207 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4209 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4212 if (ExpectedAddrSize > 12)
4213 ExpectedAddrSize = 16;
4218 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4222 if (ActualAddrSize == ExpectedAddrSize)
4225 Error(IDLoc,
"image address size does not match dim and a16");
4229bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4236 if (!
Desc.mayLoad() || !
Desc.mayStore())
4239 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4246 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4249bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4257 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4265 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4268bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4283 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4284 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4291bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4299 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4302 if (!BaseOpcode->
MSAA)
4305 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4311 return DimInfo->
MSAA;
4317 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4318 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4319 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4329bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4338 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4341 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4349 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4353bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4358 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4361 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4364 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4371 Error(getOperandLoc(Operands, Src0Idx),
4372 "source operand must be either a VGPR or an inline constant");
4379bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4382 const MCInstrDesc &
Desc = MII.
get(Opcode);
4385 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4388 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4392 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4393 Error(getOperandLoc(Operands, Src2Idx),
4394 "inline constants are not allowed for this operand");
4401bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4409 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4410 if (BlgpIdx != -1) {
4411 if (
const MFMA_F8F6F4_Info *
Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4412 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4422 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4423 Error(getOperandLoc(Operands, Src0Idx),
4424 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4429 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4430 Error(getOperandLoc(Operands, Src1Idx),
4431 "wrong register tuple size for blgp value " + Twine(BLGP));
4439 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4443 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4447 MCRegister Src2Reg = Src2.
getReg();
4449 if (Src2Reg == DstReg)
4454 .getSizeInBits() <= 128)
4457 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4458 Error(getOperandLoc(Operands, Src2Idx),
4459 "source 2 operand must not partially overlap with dst");
4466bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4470 case V_DIV_SCALE_F32_gfx6_gfx7:
4471 case V_DIV_SCALE_F32_vi:
4472 case V_DIV_SCALE_F32_gfx10:
4473 case V_DIV_SCALE_F64_gfx6_gfx7:
4474 case V_DIV_SCALE_F64_vi:
4475 case V_DIV_SCALE_F64_gfx10:
4481 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4482 AMDGPU::OpName::src2_modifiers,
4483 AMDGPU::OpName::src2_modifiers}) {
4494bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4502 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4511bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4518 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4526 case AMDGPU::V_SUBREV_F32_e32:
4527 case AMDGPU::V_SUBREV_F32_e64:
4528 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4529 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4530 case AMDGPU::V_SUBREV_F32_e32_vi:
4531 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4532 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4533 case AMDGPU::V_SUBREV_F32_e64_vi:
4535 case AMDGPU::V_SUBREV_CO_U32_e32:
4536 case AMDGPU::V_SUBREV_CO_U32_e64:
4537 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4538 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4540 case AMDGPU::V_SUBBREV_U32_e32:
4541 case AMDGPU::V_SUBBREV_U32_e64:
4542 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4543 case AMDGPU::V_SUBBREV_U32_e32_vi:
4544 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4545 case AMDGPU::V_SUBBREV_U32_e64_vi:
4547 case AMDGPU::V_SUBREV_U32_e32:
4548 case AMDGPU::V_SUBREV_U32_e64:
4549 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4550 case AMDGPU::V_SUBREV_U32_e32_vi:
4551 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4552 case AMDGPU::V_SUBREV_U32_e64_vi:
4554 case AMDGPU::V_SUBREV_F16_e32:
4555 case AMDGPU::V_SUBREV_F16_e64:
4556 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4557 case AMDGPU::V_SUBREV_F16_e32_vi:
4558 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4559 case AMDGPU::V_SUBREV_F16_e64_vi:
4561 case AMDGPU::V_SUBREV_U16_e32:
4562 case AMDGPU::V_SUBREV_U16_e64:
4563 case AMDGPU::V_SUBREV_U16_e32_vi:
4564 case AMDGPU::V_SUBREV_U16_e64_vi:
4566 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4567 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4568 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4570 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4571 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4573 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4574 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4576 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4577 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4579 case AMDGPU::V_LSHRREV_B32_e32:
4580 case AMDGPU::V_LSHRREV_B32_e64:
4581 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4582 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4583 case AMDGPU::V_LSHRREV_B32_e32_vi:
4584 case AMDGPU::V_LSHRREV_B32_e64_vi:
4585 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4586 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4588 case AMDGPU::V_ASHRREV_I32_e32:
4589 case AMDGPU::V_ASHRREV_I32_e64:
4590 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4591 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4592 case AMDGPU::V_ASHRREV_I32_e32_vi:
4593 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4594 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4595 case AMDGPU::V_ASHRREV_I32_e64_vi:
4597 case AMDGPU::V_LSHLREV_B32_e32:
4598 case AMDGPU::V_LSHLREV_B32_e64:
4599 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4600 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4601 case AMDGPU::V_LSHLREV_B32_e32_vi:
4602 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4603 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4604 case AMDGPU::V_LSHLREV_B32_e64_vi:
4606 case AMDGPU::V_LSHLREV_B16_e32:
4607 case AMDGPU::V_LSHLREV_B16_e64:
4608 case AMDGPU::V_LSHLREV_B16_e32_vi:
4609 case AMDGPU::V_LSHLREV_B16_e64_vi:
4610 case AMDGPU::V_LSHLREV_B16_gfx10:
4612 case AMDGPU::V_LSHRREV_B16_e32:
4613 case AMDGPU::V_LSHRREV_B16_e64:
4614 case AMDGPU::V_LSHRREV_B16_e32_vi:
4615 case AMDGPU::V_LSHRREV_B16_e64_vi:
4616 case AMDGPU::V_LSHRREV_B16_gfx10:
4618 case AMDGPU::V_ASHRREV_I16_e32:
4619 case AMDGPU::V_ASHRREV_I16_e64:
4620 case AMDGPU::V_ASHRREV_I16_e32_vi:
4621 case AMDGPU::V_ASHRREV_I16_e64_vi:
4622 case AMDGPU::V_ASHRREV_I16_gfx10:
4624 case AMDGPU::V_LSHLREV_B64_e64:
4625 case AMDGPU::V_LSHLREV_B64_gfx10:
4626 case AMDGPU::V_LSHLREV_B64_vi:
4628 case AMDGPU::V_LSHRREV_B64_e64:
4629 case AMDGPU::V_LSHRREV_B64_gfx10:
4630 case AMDGPU::V_LSHRREV_B64_vi:
4632 case AMDGPU::V_ASHRREV_I64_e64:
4633 case AMDGPU::V_ASHRREV_I64_gfx10:
4634 case AMDGPU::V_ASHRREV_I64_vi:
4636 case AMDGPU::V_PK_LSHLREV_B16:
4637 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4638 case AMDGPU::V_PK_LSHLREV_B16_vi:
4640 case AMDGPU::V_PK_LSHRREV_B16:
4641 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4642 case AMDGPU::V_PK_LSHRREV_B16_vi:
4643 case AMDGPU::V_PK_ASHRREV_I16:
4644 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4645 case AMDGPU::V_PK_ASHRREV_I16_vi:
4652bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4654 using namespace SIInstrFlags;
4655 const unsigned Opcode = Inst.
getOpcode();
4656 const MCInstrDesc &
Desc = MII.
get(Opcode);
4661 if ((
Desc.TSFlags & Enc) == 0)
4664 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4665 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4669 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4672 Error(getOperandLoc(Operands, SrcIdx),
4673 "lds_direct is not supported on this GPU");
4678 Error(getOperandLoc(Operands, SrcIdx),
4679 "lds_direct cannot be used with this instruction");
4683 if (SrcName != OpName::src0) {
4684 Error(getOperandLoc(Operands, SrcIdx),
4685 "lds_direct may be used as src0 only");
4694SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4695 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4696 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4697 if (
Op.isFlatOffset())
4698 return Op.getStartLoc();
4703bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4706 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4712 return validateFlatOffset(Inst, Operands);
4715 return validateSMEMOffset(Inst, Operands);
4721 const unsigned OffsetSize = 24;
4722 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4723 Error(getFlatOffsetLoc(Operands),
4724 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4725 "-bit unsigned offset for buffer ops");
4729 const unsigned OffsetSize = 16;
4730 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4731 Error(getFlatOffsetLoc(Operands),
4732 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4739bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4746 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4750 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4751 Error(getFlatOffsetLoc(Operands),
4752 "flat offset modifier is not supported on this GPU");
4759 bool AllowNegative =
4762 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4763 Error(getFlatOffsetLoc(Operands),
4764 Twine(
"expected a ") +
4765 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4766 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4773SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4775 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4776 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4777 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4778 return Op.getStartLoc();
4783bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4793 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4807 Error(getSMEMOffsetLoc(Operands),
4809 ?
"expected a 23-bit unsigned offset for buffer ops"
4810 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4811 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4812 :
"expected a 21-bit signed offset");
4817bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4820 const MCInstrDesc &
Desc = MII.
get(Opcode);
4824 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4825 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4827 const int OpIndices[] = { Src0Idx, Src1Idx };
4829 unsigned NumExprs = 0;
4830 unsigned NumLiterals = 0;
4833 for (
int OpIdx : OpIndices) {
4834 if (
OpIdx == -1)
break;
4840 std::optional<int64_t>
Imm;
4843 }
else if (MO.
isExpr()) {
4852 if (!
Imm.has_value()) {
4854 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4858 if (NumLiterals == 0 || LiteralValue !=
Value) {
4866 if (NumLiterals + NumExprs <= 1)
4869 Error(getOperandLoc(Operands, Src1Idx),
4870 "only one unique literal operand is allowed");
4874bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4877 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4887 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4888 if (OpSelIdx != -1) {
4892 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4893 if (OpSelHiIdx != -1) {
4902 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4912 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4913 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4914 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4915 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4917 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4918 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4924 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4926 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4936 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4937 if (Src2Idx != -1) {
4938 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4948bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4949 if (!hasTrue16Insts())
4951 const MCRegisterInfo *
MRI = getMRI();
4953 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4959 if (OpSelOpValue == 0)
4961 unsigned OpCount = 0;
4962 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4963 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4964 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4969 MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(
Op.getReg())) {
4971 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4972 if (OpSelOpIsHi != VGPRSuffixIsHi)
4981bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4982 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4995 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
5006 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
5007 AMDGPU::OpName::src1_modifiers,
5008 AMDGPU::OpName::src2_modifiers};
5010 for (
unsigned i = 0; i < 3; ++i) {
5020bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5023 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5024 if (DppCtrlIdx >= 0) {
5031 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5032 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5033 :
"DP ALU dpp only supports row_newbcast");
5038 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5039 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5042 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5044 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5047 Error(getOperandLoc(Operands, Src1Idx),
5048 "invalid operand for instruction");
5052 Error(getInstLoc(Operands),
5053 "src1 immediate operand invalid for instruction");
5063bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5064 return (
Reg == AMDGPU::VCC && isWave64()) ||
5065 (
Reg == AMDGPU::VCC_LO && isWave32());
5069bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5072 const MCInstrDesc &
Desc = MII.
get(Opcode);
5073 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5075 !HasMandatoryLiteral && !
isVOPD(Opcode))
5080 std::optional<unsigned> LiteralOpIdx;
5083 for (
int OpIdx : OpIndices) {
5093 std::optional<int64_t>
Imm;
5099 bool IsAnotherLiteral =
false;
5100 if (!
Imm.has_value()) {
5102 IsAnotherLiteral =
true;
5103 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5108 HasMandatoryLiteral);
5114 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5116 "invalid operand for instruction");
5120 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5127 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5128 !getFeatureBits()[FeatureVOP3Literal]) {
5130 "literal operands are not supported");
5134 if (LiteralOpIdx && IsAnotherLiteral) {
5135 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5136 getOperandLoc(Operands, *LiteralOpIdx)),
5137 "only one unique literal operand is allowed");
5141 if (IsAnotherLiteral)
5142 LiteralOpIdx =
OpIdx;
5165bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5173 ? AMDGPU::OpName::data0
5174 : AMDGPU::OpName::vdata;
5176 const MCRegisterInfo *
MRI = getMRI();
5182 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5186 auto FB = getFeatureBits();
5187 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5188 if (DataAreg < 0 || DstAreg < 0)
5190 return DstAreg == DataAreg;
5193 return DstAreg < 1 && DataAreg < 1;
5196bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5197 auto FB = getFeatureBits();
5198 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5202 const MCRegisterInfo *
MRI = getMRI();
5205 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5208 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5212 case AMDGPU::DS_LOAD_TR6_B96:
5213 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5217 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5218 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5222 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5223 if (VAddrIdx != -1) {
5225 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5226 if ((
Sub - AMDGPU::VGPR0) & 1)
5231 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5232 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5237 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5238 const MCRegisterClass &AGPR32 =
MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
5244 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5257SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5258 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5259 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5261 return Op.getStartLoc();
5266bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5269 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5272 SMLoc BLGPLoc = getBLGPLoc(Operands);
5275 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5276 auto FB = getFeatureBits();
5277 bool UsesNeg =
false;
5278 if (FB[AMDGPU::FeatureGFX940Insts]) {
5280 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5281 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5282 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5283 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5288 if (IsNeg == UsesNeg)
5292 UsesNeg ?
"invalid modifier: blgp is not supported"
5293 :
"invalid modifier: neg is not supported");
5298bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5304 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5305 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5306 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5307 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5310 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5313 if (
Reg == AMDGPU::SGPR_NULL)
5316 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5320bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5326 return validateGWS(Inst, Operands);
5331 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5336 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5337 Error(S,
"gds modifier is not supported on this GPU");
5345bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5347 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5351 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5352 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5355 const MCRegisterInfo *
MRI = getMRI();
5356 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5358 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5361 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5363 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5370bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5373 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5374 AMDGPU::OpName::cpol);
5382 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5385 Error(S,
"scale_offset is not supported on this GPU");
5388 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5391 Error(S,
"nv is not supported on this GPU");
5396 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5399 Error(S,
"scale_offset is not supported for this instruction");
5403 return validateTHAndScopeBits(Inst, Operands, CPol);
5408 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5409 Error(S,
"cache policy is not supported for SMRD instructions");
5413 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5422 if (!(TSFlags & AllowSCCModifier)) {
5423 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5427 "scc modifier is not supported for this instruction on this GPU");
5438 :
"instruction must use glc");
5443 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5446 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5448 :
"instruction must not use glc");
5456bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5458 const unsigned CPol) {
5462 const unsigned Opcode = Inst.
getOpcode();
5463 const MCInstrDesc &TID = MII.
get(Opcode);
5466 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5474 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5482 return PrintError(
"invalid th value for SMEM instruction");
5489 return PrintError(
"scope and th combination is not valid");
5495 return PrintError(
"invalid th value for atomic instructions");
5498 return PrintError(
"invalid th value for store instructions");
5501 return PrintError(
"invalid th value for load instructions");
5507bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5510 if (
Desc.mayStore() &&
5512 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5513 if (Loc != getInstLoc(Operands)) {
5514 Error(Loc,
"TFE modifier has no meaning for store instructions");
5522bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5528 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5529 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5533 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5541 static const char *FmtNames[] = {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
5542 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
5545 Error(getOperandLoc(Operands, SrcIdx),
5546 "wrong register tuple size for " + Twine(FmtNames[Fmt]));
5550 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5551 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5554bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5556 if (!validateLdsDirect(Inst, Operands))
5558 if (!validateTrue16OpSel(Inst)) {
5559 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5560 "op_sel operand conflicts with 16-bit operand suffix");
5563 if (!validateSOPLiteral(Inst, Operands))
5565 if (!validateVOPLiteral(Inst, Operands)) {
5568 if (!validateConstantBusLimitations(Inst, Operands)) {
5571 if (!validateVOPD(Inst, Operands)) {
5574 if (!validateIntClampSupported(Inst)) {
5575 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5576 "integer clamping is not supported on this GPU");
5579 if (!validateOpSel(Inst)) {
5580 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5581 "invalid op_sel operand");
5584 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5585 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5586 "invalid neg_lo operand");
5589 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5590 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5591 "invalid neg_hi operand");
5594 if (!validateDPP(Inst, Operands)) {
5598 if (!validateMIMGD16(Inst)) {
5599 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5600 "d16 modifier is not supported on this GPU");
5603 if (!validateMIMGDim(Inst, Operands)) {
5604 Error(IDLoc,
"missing dim operand");
5607 if (!validateTensorR128(Inst)) {
5608 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5609 "instruction must set modifier r128=0");
5612 if (!validateMIMGMSAA(Inst)) {
5613 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5614 "invalid dim; must be MSAA type");
5617 if (!validateMIMGDataSize(Inst, IDLoc)) {
5620 if (!validateMIMGAddrSize(Inst, IDLoc))
5622 if (!validateMIMGAtomicDMask(Inst)) {
5623 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5624 "invalid atomic image dmask");
5627 if (!validateMIMGGatherDMask(Inst)) {
5628 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5629 "invalid image_gather dmask: only one bit must be set");
5632 if (!validateMovrels(Inst, Operands)) {
5635 if (!validateOffset(Inst, Operands)) {
5638 if (!validateMAIAccWrite(Inst, Operands)) {
5641 if (!validateMAISrc2(Inst, Operands)) {
5644 if (!validateMFMA(Inst, Operands)) {
5647 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5651 if (!validateAGPRLdSt(Inst)) {
5652 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5653 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5654 :
"invalid register class: agpr loads and stores not supported on this GPU"
5658 if (!validateVGPRAlign(Inst)) {
5660 "invalid register class: vgpr tuples must be 64 bit aligned");
5663 if (!validateDS(Inst, Operands)) {
5667 if (!validateBLGP(Inst, Operands)) {
5671 if (!validateDivScale(Inst)) {
5672 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5675 if (!validateWaitCnt(Inst, Operands)) {
5678 if (!validateTFE(Inst, Operands)) {
5681 if (!validateWMMA(Inst, Operands)) {
5690 unsigned VariantID = 0);
5694 unsigned VariantID);
5696bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5701bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5702 const FeatureBitset &FBS,
5703 ArrayRef<unsigned> Variants) {
5704 for (
auto Variant : Variants) {
5712bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5714 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5717 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5722 getParser().clearPendingErrors();
5726 StringRef VariantName = getMatchedVariantName();
5727 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5730 " variant of this instruction is not supported"));
5734 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5735 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5737 FeatureBitset FeaturesWS32 = getFeatureBits();
5738 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5739 .
flip(AMDGPU::FeatureWavefrontSize32);
5740 FeatureBitset AvailableFeaturesWS32 =
5741 ComputeAvailableFeatures(FeaturesWS32);
5743 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5744 return Error(IDLoc,
"instruction requires wavesize=32");
5748 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5749 return Error(IDLoc,
"instruction not supported on this GPU");
5754 return Error(IDLoc,
"invalid instruction" + Suggestion);
5760 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5761 if (
Op.isToken() && InvalidOprIdx > 1) {
5762 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5763 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5768bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5771 uint64_t &ErrorInfo,
5772 bool MatchingInlineAsm) {
5775 unsigned Result = Match_Success;
5776 for (
auto Variant : getMatchedVariants()) {
5778 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5783 if (R == Match_Success || R == Match_MissingFeature ||
5784 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5785 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5786 Result != Match_MissingFeature)) {
5790 if (R == Match_Success)
5794 if (Result == Match_Success) {
5795 if (!validateInstruction(Inst, IDLoc, Operands)) {
5802 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5803 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5809 case Match_MissingFeature:
5813 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5815 case Match_InvalidOperand: {
5816 SMLoc ErrorLoc = IDLoc;
5817 if (ErrorInfo != ~0ULL) {
5818 if (ErrorInfo >= Operands.
size()) {
5819 return Error(IDLoc,
"too few operands for instruction");
5821 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5822 if (ErrorLoc == SMLoc())
5826 return Error(ErrorLoc,
"invalid VOPDY instruction");
5828 return Error(ErrorLoc,
"invalid operand for instruction");
5831 case Match_MnemonicFail:
5837bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5842 if (getParser().parseAbsoluteExpression(Tmp)) {
5845 Ret =
static_cast<uint32_t
>(Tmp);
5849bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5850 if (!getSTI().getTargetTriple().isAMDGCN())
5851 return TokError(
"directive only supported for amdgcn architecture");
5853 std::string TargetIDDirective;
5854 SMLoc TargetStart = getTok().getLoc();
5855 if (getParser().parseEscapedString(TargetIDDirective))
5858 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5859 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5860 return getParser().Error(TargetRange.
Start,
5861 (Twine(
".amdgcn_target directive's target id ") +
5862 Twine(TargetIDDirective) +
5863 Twine(
" does not match the specified target id ") +
5864 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5869bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5873bool AMDGPUAsmParser::calculateGPRBlocks(
5874 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5875 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5876 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5877 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5878 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5884 const MCExpr *
NumSGPRs = NextFreeSGPR;
5885 int64_t EvaluatedSGPRs;
5890 unsigned MaxAddressableNumSGPRs =
5893 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5894 !Features.
test(FeatureSGPRInitBug) &&
5895 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5896 return OutOfRangeError(SGPRRange);
5898 const MCExpr *ExtraSGPRs =
5902 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5903 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5904 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5905 return OutOfRangeError(SGPRRange);
5907 if (Features.
test(FeatureSGPRInitBug))
5914 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5915 unsigned Granule) ->
const MCExpr * {
5919 const MCExpr *AlignToGPR =
5921 const MCExpr *DivGPR =
5927 VGPRBlocks = GetNumGPRBlocks(
5936bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5937 if (!getSTI().getTargetTriple().isAMDGCN())
5938 return TokError(
"directive only supported for amdgcn architecture");
5941 return TokError(
"directive only supported for amdhsa OS");
5943 StringRef KernelName;
5944 if (getParser().parseIdentifier(KernelName))
5947 AMDGPU::MCKernelDescriptor KD =
5959 const MCExpr *NextFreeVGPR = ZeroExpr;
5961 const MCExpr *NamedBarCnt = ZeroExpr;
5962 uint64_t SharedVGPRCount = 0;
5963 uint64_t PreloadLength = 0;
5964 uint64_t PreloadOffset = 0;
5966 const MCExpr *NextFreeSGPR = ZeroExpr;
5969 unsigned ImpliedUserSGPRCount = 0;
5973 std::optional<unsigned> ExplicitUserSGPRCount;
5974 const MCExpr *ReserveVCC = OneExpr;
5975 const MCExpr *ReserveFlatScr = OneExpr;
5976 std::optional<bool> EnableWavefrontSize32;
5982 SMRange IDRange = getTok().getLocRange();
5983 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5986 if (
ID ==
".end_amdhsa_kernel")
5990 return TokError(
".amdhsa_ directives cannot be repeated");
5992 SMLoc ValStart = getLoc();
5993 const MCExpr *ExprVal;
5994 if (getParser().parseExpression(ExprVal))
5996 SMLoc ValEnd = getLoc();
5997 SMRange ValRange = SMRange(ValStart, ValEnd);
6000 uint64_t Val = IVal;
6001 bool EvaluatableExpr;
6002 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6004 return OutOfRangeError(ValRange);
6008#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6009 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6010 return OutOfRangeError(RANGE); \
6011 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6016#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6018 return Error(IDRange.Start, "directive should have resolvable expression", \
6021 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6024 return OutOfRangeError(ValRange);
6026 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6029 return OutOfRangeError(ValRange);
6031 }
else if (
ID ==
".amdhsa_kernarg_size") {
6033 return OutOfRangeError(ValRange);
6035 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6037 ExplicitUserSGPRCount = Val;
6038 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6042 "directive is not supported with architected flat scratch",
6045 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6048 ImpliedUserSGPRCount += 4;
6049 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6052 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6055 return OutOfRangeError(ValRange);
6059 ImpliedUserSGPRCount += Val;
6060 PreloadLength = Val;
6062 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6065 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6068 return OutOfRangeError(ValRange);
6072 PreloadOffset = Val;
6073 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6076 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6079 ImpliedUserSGPRCount += 2;
6080 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6083 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6086 ImpliedUserSGPRCount += 2;
6087 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6090 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6093 ImpliedUserSGPRCount += 2;
6094 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6097 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6100 ImpliedUserSGPRCount += 2;
6101 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6104 "directive is not supported with architected flat scratch",
6108 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6111 ImpliedUserSGPRCount += 2;
6112 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6115 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6118 ImpliedUserSGPRCount += 1;
6119 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6121 if (IVersion.
Major < 10)
6122 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6123 EnableWavefrontSize32 = Val;
6125 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6127 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6129 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6131 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6134 "directive is not supported with architected flat scratch",
6137 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6139 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6143 "directive is not supported without architected flat scratch",
6146 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6148 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6150 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6152 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6154 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6156 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6158 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6160 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6162 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6164 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6166 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6168 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6169 VGPRRange = ValRange;
6170 NextFreeVGPR = ExprVal;
6171 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6172 SGPRRange = ValRange;
6173 NextFreeSGPR = ExprVal;
6174 }
else if (
ID ==
".amdhsa_accum_offset") {
6176 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6177 AccumOffset = ExprVal;
6178 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6180 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6181 NamedBarCnt = ExprVal;
6182 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6184 return OutOfRangeError(ValRange);
6185 ReserveVCC = ExprVal;
6186 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6187 if (IVersion.
Major < 7)
6188 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6191 "directive is not supported with architected flat scratch",
6194 return OutOfRangeError(ValRange);
6195 ReserveFlatScr = ExprVal;
6196 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6197 if (IVersion.
Major < 8)
6198 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6200 return OutOfRangeError(ValRange);
6201 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6202 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6204 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6206 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6208 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6210 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6212 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6214 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6216 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6218 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6220 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6221 if (IVersion.
Major >= 12)
6222 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6224 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6226 }
else if (
ID ==
".amdhsa_ieee_mode") {
6227 if (IVersion.
Major >= 12)
6228 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6230 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6232 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6233 if (IVersion.
Major < 9)
6234 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6236 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6238 }
else if (
ID ==
".amdhsa_tg_split") {
6240 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6243 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6246 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6248 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6250 }
else if (
ID ==
".amdhsa_memory_ordered") {
6251 if (IVersion.
Major < 10)
6252 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6254 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6256 }
else if (
ID ==
".amdhsa_forward_progress") {
6257 if (IVersion.
Major < 10)
6258 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6260 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6262 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6264 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6265 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6267 SharedVGPRCount = Val;
6269 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6271 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6272 if (IVersion.
Major < 11)
6273 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6274 if (IVersion.
Major == 11) {
6276 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6280 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6283 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6286 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6288 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6290 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6292 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6295 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6297 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6299 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6301 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6303 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6305 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6307 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6309 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6311 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6313 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6314 if (IVersion.
Major < 12)
6315 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6317 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6320 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6323#undef PARSE_BITS_ENTRY
6326 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6327 return TokError(
".amdhsa_next_free_vgpr directive is required");
6329 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6330 return TokError(
".amdhsa_next_free_sgpr directive is required");
6332 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6337 if (PreloadLength) {
6343 const MCExpr *VGPRBlocks;
6344 const MCExpr *SGPRBlocks;
6345 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6346 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6347 EnableWavefrontSize32, NextFreeVGPR,
6348 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6352 int64_t EvaluatedVGPRBlocks;
6353 bool VGPRBlocksEvaluatable =
6354 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6355 if (VGPRBlocksEvaluatable &&
6357 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6358 return OutOfRangeError(VGPRRange);
6362 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6363 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6365 int64_t EvaluatedSGPRBlocks;
6366 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6368 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6369 return OutOfRangeError(SGPRRange);
6372 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6373 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6375 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6376 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6377 "enabled user SGPRs");
6381 return TokError(
"too many user SGPRs enabled");
6385 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6386 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6390 return TokError(
"too many user SGPRs enabled");
6394 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6395 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6400 return TokError(
"Kernarg size should be resolvable");
6401 uint64_t kernarg_size = IVal;
6402 if (PreloadLength && kernarg_size &&
6403 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6404 return TokError(
"Kernarg preload length + offset is larger than the "
6405 "kernarg segment size");
6408 if (!Seen.
contains(
".amdhsa_accum_offset"))
6409 return TokError(
".amdhsa_accum_offset directive is required");
6410 int64_t EvaluatedAccum;
6411 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6412 uint64_t UEvaluatedAccum = EvaluatedAccum;
6413 if (AccumEvaluatable &&
6414 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6415 return TokError(
"accum_offset should be in range [4..256] in "
6418 int64_t EvaluatedNumVGPR;
6419 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6422 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6423 return TokError(
"accum_offset exceeds total VGPR allocation");
6429 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6430 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6436 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6437 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6440 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6442 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6443 return TokError(
"shared_vgpr_count directive not valid on "
6444 "wavefront size 32");
6447 if (VGPRBlocksEvaluatable &&
6448 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6450 return TokError(
"shared_vgpr_count*2 + "
6451 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6456 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6457 NextFreeVGPR, NextFreeSGPR,
6458 ReserveVCC, ReserveFlatScr);
6462bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6464 if (ParseAsAbsoluteExpression(
Version))
6467 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6471bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6472 AMDGPUMCKernelCodeT &
C) {
6475 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6476 Parser.eatToEndOfStatement();
6480 SmallString<40> ErrStr;
6481 raw_svector_ostream Err(ErrStr);
6482 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6483 return TokError(Err.
str());
6487 if (
ID ==
"enable_wavefront_size32") {
6490 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6492 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6495 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6499 if (
ID ==
"wavefront_size") {
6500 if (
C.wavefront_size == 5) {
6502 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6504 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6505 }
else if (
C.wavefront_size == 6) {
6507 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6514bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6515 AMDGPUMCKernelCodeT KernelCode;
6524 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6527 if (
ID ==
".end_amd_kernel_code_t")
6530 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6535 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6540bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6541 StringRef KernelName;
6542 if (!parseId(KernelName,
"expected symbol name"))
6545 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6552bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6553 if (!getSTI().getTargetTriple().isAMDGCN()) {
6554 return Error(getLoc(),
6555 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6559 auto TargetIDDirective = getLexer().getTok().getStringContents();
6560 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6561 return Error(getParser().getTok().getLoc(),
"target id must match options");
6563 getTargetStreamer().EmitISAVersion();
6569bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6572 std::string HSAMetadataString;
6577 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6578 return Error(getLoc(),
"invalid HSA metadata");
6585bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6586 const char *AssemblerDirectiveEnd,
6587 std::string &CollectString) {
6589 raw_string_ostream CollectStream(CollectString);
6591 getLexer().setSkipSpace(
false);
6593 bool FoundEnd =
false;
6596 CollectStream << getTokenStr();
6600 if (trySkipId(AssemblerDirectiveEnd)) {
6605 CollectStream << Parser.parseStringToEndOfStatement()
6606 <<
getContext().getAsmInfo()->getSeparatorString();
6608 Parser.eatToEndOfStatement();
6611 getLexer().setSkipSpace(
true);
6614 return TokError(Twine(
"expected directive ") +
6615 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6622bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6628 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6629 if (!PALMetadata->setFromString(
String))
6630 return Error(getLoc(),
"invalid PAL metadata");
6635bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6637 return Error(getLoc(),
6639 "not available on non-amdpal OSes")).str());
6642 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6643 PALMetadata->setLegacy();
6646 if (ParseAsAbsoluteExpression(
Key)) {
6647 return TokError(Twine(
"invalid value in ") +
6651 return TokError(Twine(
"expected an even number of values in ") +
6654 if (ParseAsAbsoluteExpression(
Value)) {
6655 return TokError(Twine(
"invalid value in ") +
6658 PALMetadata->setRegister(
Key,
Value);
6667bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6668 if (getParser().checkForValidSection())
6672 SMLoc NameLoc = getLoc();
6673 if (getParser().parseIdentifier(Name))
6674 return TokError(
"expected identifier in directive");
6677 if (getParser().parseComma())
6683 SMLoc SizeLoc = getLoc();
6684 if (getParser().parseAbsoluteExpression(
Size))
6687 return Error(SizeLoc,
"size must be non-negative");
6688 if (
Size > LocalMemorySize)
6689 return Error(SizeLoc,
"size is too large");
6691 int64_t Alignment = 4;
6693 SMLoc AlignLoc = getLoc();
6694 if (getParser().parseAbsoluteExpression(Alignment))
6697 return Error(AlignLoc,
"alignment must be a power of two");
6702 if (Alignment >= 1u << 31)
6703 return Error(AlignLoc,
"alignment is too large");
6709 Symbol->redefineIfPossible();
6710 if (!
Symbol->isUndefined())
6711 return Error(NameLoc,
"invalid symbol redefinition");
6713 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6717bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6718 StringRef IDVal = DirectiveID.
getString();
6721 if (IDVal ==
".amdhsa_kernel")
6722 return ParseDirectiveAMDHSAKernel();
6724 if (IDVal ==
".amdhsa_code_object_version")
6725 return ParseDirectiveAMDHSACodeObjectVersion();
6729 return ParseDirectiveHSAMetadata();
6731 if (IDVal ==
".amd_kernel_code_t")
6732 return ParseDirectiveAMDKernelCodeT();
6734 if (IDVal ==
".amdgpu_hsa_kernel")
6735 return ParseDirectiveAMDGPUHsaKernel();
6737 if (IDVal ==
".amd_amdgpu_isa")
6738 return ParseDirectiveISAVersion();
6742 Twine(
" directive is "
6743 "not available on non-amdhsa OSes"))
6748 if (IDVal ==
".amdgcn_target")
6749 return ParseDirectiveAMDGCNTarget();
6751 if (IDVal ==
".amdgpu_lds")
6752 return ParseDirectiveAMDGPULDS();
6755 return ParseDirectivePALMetadataBegin();
6758 return ParseDirectivePALMetadata();
6763bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
6765 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
6769 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
6770 return hasSGPR104_SGPR105();
6773 case SRC_SHARED_BASE_LO:
6774 case SRC_SHARED_BASE:
6775 case SRC_SHARED_LIMIT_LO:
6776 case SRC_SHARED_LIMIT:
6777 case SRC_PRIVATE_BASE_LO:
6778 case SRC_PRIVATE_BASE:
6779 case SRC_PRIVATE_LIMIT_LO:
6780 case SRC_PRIVATE_LIMIT:
6782 case SRC_FLAT_SCRATCH_BASE_LO:
6783 case SRC_FLAT_SCRATCH_BASE_HI:
6784 return hasGloballyAddressableScratch();
6785 case SRC_POPS_EXITING_WAVE_ID:
6797 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6826 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
6827 return hasSGPR102_SGPR103();
6832ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6835 ParseStatus Res = parseVOPD(Operands);
6840 Res = MatchOperandParserImpl(Operands, Mnemonic);
6852 SMLoc LBraceLoc = getLoc();
6857 auto Loc = getLoc();
6858 Res = parseReg(Operands);
6860 Error(Loc,
"expected a register");
6864 RBraceLoc = getLoc();
6869 "expected a comma or a closing square bracket"))
6873 if (Operands.
size() - Prefix > 1) {
6875 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6876 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6882 return parseRegOrImm(Operands);
6885StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6887 setForcedEncodingSize(0);
6888 setForcedDPP(
false);
6889 setForcedSDWA(
false);
6891 if (
Name.consume_back(
"_e64_dpp")) {
6893 setForcedEncodingSize(64);
6896 if (
Name.consume_back(
"_e64")) {
6897 setForcedEncodingSize(64);
6900 if (
Name.consume_back(
"_e32")) {
6901 setForcedEncodingSize(32);
6904 if (
Name.consume_back(
"_dpp")) {
6908 if (
Name.consume_back(
"_sdwa")) {
6909 setForcedSDWA(
true);
6917 unsigned VariantID);
6923 Name = parseMnemonicSuffix(Name);
6929 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6931 bool IsMIMG = Name.starts_with(
"image_");
6934 OperandMode
Mode = OperandMode_Default;
6936 Mode = OperandMode_NSA;
6940 checkUnsupportedInstruction(Name, NameLoc);
6941 if (!Parser.hasPendingError()) {
6944 :
"not a valid operand.";
6945 Error(getLoc(), Msg);
6964ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6967 if (!trySkipId(Name))
6970 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6974ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6983ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6984 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6985 std::function<
bool(int64_t &)> ConvertResult) {
6989 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
6993 if (ConvertResult && !ConvertResult(
Value)) {
6994 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
6997 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7001ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7002 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7003 bool (*ConvertResult)(int64_t &)) {
7012 const unsigned MaxSize = 4;
7016 for (
int I = 0; ; ++
I) {
7018 SMLoc Loc = getLoc();
7022 if (
Op != 0 &&
Op != 1)
7023 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7030 if (
I + 1 == MaxSize)
7031 return Error(getLoc(),
"expected a closing square bracket");
7037 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7041ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7043 AMDGPUOperand::ImmTy ImmTy) {
7047 if (trySkipId(Name)) {
7049 }
else if (trySkipId(
"no", Name)) {
7056 return Error(S,
"r128 modifier is not supported on this GPU");
7057 if (Name ==
"a16" && !
hasA16())
7058 return Error(S,
"a16 modifier is not supported on this GPU");
7060 if (Bit == 0 && Name ==
"gds") {
7061 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7063 return Error(S,
"nogds is not allowed");
7066 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7067 ImmTy = AMDGPUOperand::ImmTyR128A16;
7069 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7073unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7074 bool &Disabling)
const {
7075 Disabling =
Id.consume_front(
"no");
7078 return StringSwitch<unsigned>(Id)
7085 return StringSwitch<unsigned>(Id)
7093ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7095 SMLoc StringLoc = getLoc();
7097 int64_t CPolVal = 0;
7106 ResTH = parseTH(Operands, TH);
7117 ResScope = parseScope(Operands, Scope);
7130 if (trySkipId(
"nv")) {
7134 }
else if (trySkipId(
"no",
"nv")) {
7141 if (trySkipId(
"scale_offset")) {
7145 }
else if (trySkipId(
"no",
"scale_offset")) {
7158 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7159 AMDGPUOperand::ImmTyCPol));
7163 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7164 SMLoc OpLoc = getLoc();
7165 unsigned Enabled = 0, Seen = 0;
7169 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7176 return Error(S,
"dlc modifier is not supported on this GPU");
7179 return Error(S,
"scc modifier is not supported on this GPU");
7182 return Error(S,
"duplicate cache policy modifier");
7194 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7198ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7203 ParseStatus Res = parseStringOrIntWithPrefix(
7204 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7213ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7218 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7222 if (
Value ==
"TH_DEFAULT")
7224 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7225 Value ==
"TH_LOAD_NT_WB") {
7226 return Error(StringLoc,
"invalid th value");
7227 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7229 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7231 }
else if (
Value.consume_front(
"TH_STORE_")) {
7234 return Error(StringLoc,
"invalid th value");
7237 if (
Value ==
"BYPASS")
7242 TH |= StringSwitch<int64_t>(
Value)
7252 .Default(0xffffffff);
7254 TH |= StringSwitch<int64_t>(
Value)
7265 .Default(0xffffffff);
7268 if (TH == 0xffffffff)
7269 return Error(StringLoc,
"invalid th value");
7276 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7277 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7278 std::optional<unsigned> InsertAt = std::nullopt) {
7279 auto i = OptionalIdx.find(ImmT);
7280 if (i != OptionalIdx.end()) {
7281 unsigned Idx = i->second;
7282 const AMDGPUOperand &
Op =
7283 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7287 Op.addImmOperands(Inst, 1);
7289 if (InsertAt.has_value())
7296ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7302 StringLoc = getLoc();
7307ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7308 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7313 SMLoc StringLoc = getLoc();
7317 Value = getTokenStr();
7321 if (
Value == Ids[IntVal])
7326 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7327 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7332ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7333 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7334 AMDGPUOperand::ImmTy
Type) {
7338 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7340 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7349bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7353 SMLoc Loc = getLoc();
7355 auto Res = parseIntWithPrefix(Pref, Val);
7361 if (Val < 0 || Val > MaxVal) {
7362 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7370ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7371 AMDGPUOperand::ImmTy ImmTy) {
7372 const char *Pref =
"index_key";
7374 SMLoc Loc = getLoc();
7375 auto Res = parseIntWithPrefix(Pref, ImmVal);
7379 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7380 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7381 (ImmVal < 0 || ImmVal > 1))
7382 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7384 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7385 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7387 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7391ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7392 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7395ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7396 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7399ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7400 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7403ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7405 AMDGPUOperand::ImmTy
Type) {
7406 return parseStringOrIntWithPrefix(Operands, Name,
7407 {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
7408 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
7413ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7414 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7415 AMDGPUOperand::ImmTyMatrixAFMT);
7418ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7419 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7420 AMDGPUOperand::ImmTyMatrixBFMT);
7423ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7425 AMDGPUOperand::ImmTy
Type) {
7426 return parseStringOrIntWithPrefix(
7427 Operands, Name, {
"MATRIX_SCALE_ROW0",
"MATRIX_SCALE_ROW1"},
Type);
7430ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7431 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7432 AMDGPUOperand::ImmTyMatrixAScale);
7435ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7436 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7437 AMDGPUOperand::ImmTyMatrixBScale);
7440ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7442 AMDGPUOperand::ImmTy
Type) {
7443 return parseStringOrIntWithPrefix(
7445 {
"MATRIX_SCALE_FMT_E8",
"MATRIX_SCALE_FMT_E5M3",
"MATRIX_SCALE_FMT_E4M3"},
7449ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7450 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7451 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7454ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7455 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7456 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7461ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7462 using namespace llvm::AMDGPU::MTBUFFormat;
7468 for (
int I = 0;
I < 2; ++
I) {
7469 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7472 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7477 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7483 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7486 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7487 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7493ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7494 using namespace llvm::AMDGPU::MTBUFFormat;
7498 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7501 if (Fmt == UFMT_UNDEF)
7508bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7510 StringRef FormatStr,
7512 using namespace llvm::AMDGPU::MTBUFFormat;
7516 if (
Format != DFMT_UNDEF) {
7522 if (
Format != NFMT_UNDEF) {
7527 Error(Loc,
"unsupported format");
7531ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7534 using namespace llvm::AMDGPU::MTBUFFormat;
7538 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7543 SMLoc Loc = getLoc();
7544 if (!parseId(Str,
"expected a format string") ||
7545 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7547 if (Dfmt == DFMT_UNDEF)
7548 return Error(Loc,
"duplicate numeric format");
7549 if (Nfmt == NFMT_UNDEF)
7550 return Error(Loc,
"duplicate data format");
7553 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7554 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7558 if (Ufmt == UFMT_UNDEF)
7559 return Error(FormatLoc,
"unsupported format");
7568ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7571 using namespace llvm::AMDGPU::MTBUFFormat;
7574 if (Id == UFMT_UNDEF)
7578 return Error(Loc,
"unified format is not supported on this GPU");
7584ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7585 using namespace llvm::AMDGPU::MTBUFFormat;
7586 SMLoc Loc = getLoc();
7591 return Error(Loc,
"out of range format");
7596ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7597 using namespace llvm::AMDGPU::MTBUFFormat;
7603 StringRef FormatStr;
7604 SMLoc Loc = getLoc();
7605 if (!parseId(FormatStr,
"expected a format string"))
7608 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7610 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7620 return parseNumericFormat(
Format);
7623ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7624 using namespace llvm::AMDGPU::MTBUFFormat;
7628 SMLoc Loc = getLoc();
7638 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7650 Res = parseRegOrImm(Operands);
7657 Res = parseSymbolicOrNumericFormat(
Format);
7662 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7663 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7670 return Error(getLoc(),
"duplicate format");
7674ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7676 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7678 Res = parseIntWithPrefix(
"inst_offset", Operands,
7679 AMDGPUOperand::ImmTyInstOffset);
7684ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7686 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7688 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7692ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7694 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7697 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7706void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7707 OptionalImmIndexMap OptionalIdx;
7709 unsigned OperandIdx[4];
7710 unsigned EnMask = 0;
7713 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7714 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7719 OperandIdx[SrcIdx] = Inst.
size();
7720 Op.addRegOperands(Inst, 1);
7727 OperandIdx[SrcIdx] = Inst.
size();
7733 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7734 Op.addImmOperands(Inst, 1);
7738 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7742 OptionalIdx[
Op.getImmTy()] = i;
7748 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7755 for (
auto i = 0; i < SrcIdx; ++i) {
7757 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7782 IntVal =
encode(ISA, IntVal, CntVal);
7783 if (CntVal !=
decode(ISA, IntVal)) {
7785 IntVal =
encode(ISA, IntVal, -1);
7793bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7795 SMLoc CntLoc = getLoc();
7796 StringRef CntName = getTokenStr();
7803 SMLoc ValLoc = getLoc();
7812 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7814 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7816 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7819 Error(CntLoc,
"invalid counter name " + CntName);
7824 Error(ValLoc,
"too large value for " + CntName);
7833 Error(getLoc(),
"expected a counter name");
7841ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7848 if (!parseCnt(Waitcnt))
7856 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7860bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7861 SMLoc FieldLoc = getLoc();
7862 StringRef FieldName = getTokenStr();
7867 SMLoc ValueLoc = getLoc();
7874 if (FieldName ==
"instid0") {
7876 }
else if (FieldName ==
"instskip") {
7878 }
else if (FieldName ==
"instid1") {
7881 Error(FieldLoc,
"invalid field name " + FieldName);
7900 .Case(
"VALU_DEP_1", 1)
7901 .Case(
"VALU_DEP_2", 2)
7902 .Case(
"VALU_DEP_3", 3)
7903 .Case(
"VALU_DEP_4", 4)
7904 .Case(
"TRANS32_DEP_1", 5)
7905 .Case(
"TRANS32_DEP_2", 6)
7906 .Case(
"TRANS32_DEP_3", 7)
7907 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7908 .Case(
"SALU_CYCLE_1", 9)
7909 .Case(
"SALU_CYCLE_2", 10)
7910 .Case(
"SALU_CYCLE_3", 11)
7918 Delay |=
Value << Shift;
7922ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7928 if (!parseDelay(Delay))
7936 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7941AMDGPUOperand::isSWaitCnt()
const {
7945bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7951void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7952 StringRef DepCtrName) {
7955 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7958 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7961 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7964 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7971bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7973 using namespace llvm::AMDGPU::DepCtr;
7975 SMLoc DepCtrLoc = getLoc();
7976 StringRef DepCtrName = getTokenStr();
7986 unsigned PrevOprMask = UsedOprMask;
7987 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7990 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7999 Error(getLoc(),
"expected a counter name");
8004 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
8005 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8009ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
8010 using namespace llvm::AMDGPU::DepCtr;
8013 SMLoc Loc = getLoc();
8016 unsigned UsedOprMask = 0;
8018 if (!parseDepCtr(DepCtr, UsedOprMask))
8026 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8030bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8036ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8038 OperandInfoTy &Width) {
8039 using namespace llvm::AMDGPU::Hwreg;
8045 HwReg.Loc = getLoc();
8048 HwReg.IsSymbolic =
true;
8050 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8058 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8068 Width.Loc = getLoc();
8076ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8077 using namespace llvm::AMDGPU::Hwreg;
8080 SMLoc Loc = getLoc();
8082 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8084 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8085 HwregOffset::Default);
8086 struct : StructuredOpField {
8087 using StructuredOpField::StructuredOpField;
8088 bool validate(AMDGPUAsmParser &Parser)
const override {
8090 return Error(Parser,
"only values from 1 to 32 are legal");
8093 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8094 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8097 Res = parseHwregFunc(HwReg,
Offset, Width);
8100 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8102 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8106 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8113 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8115 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8119bool AMDGPUOperand::isHwreg()
const {
8120 return isImmTy(ImmTyHwreg);
8128AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8130 OperandInfoTy &Stream) {
8131 using namespace llvm::AMDGPU::SendMsg;
8136 Msg.IsSymbolic =
true;
8138 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8143 Op.IsDefined =
true;
8146 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8149 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8154 Stream.IsDefined =
true;
8155 Stream.Loc = getLoc();
8165AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8166 const OperandInfoTy &
Op,
8167 const OperandInfoTy &Stream) {
8168 using namespace llvm::AMDGPU::SendMsg;
8173 bool Strict = Msg.IsSymbolic;
8177 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8182 Error(Msg.Loc,
"invalid message id");
8188 Error(
Op.Loc,
"message does not support operations");
8190 Error(Msg.Loc,
"missing message operation");
8196 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8198 Error(
Op.Loc,
"invalid operation id");
8203 Error(Stream.Loc,
"message operation does not support streams");
8207 Error(Stream.Loc,
"invalid message stream id");
8213ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8214 using namespace llvm::AMDGPU::SendMsg;
8217 SMLoc Loc = getLoc();
8221 OperandInfoTy
Op(OP_NONE_);
8222 OperandInfoTy Stream(STREAM_ID_NONE_);
8223 if (parseSendMsgBody(Msg,
Op, Stream) &&
8224 validateSendMsg(Msg,
Op, Stream)) {
8229 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8231 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8236 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8240bool AMDGPUOperand::isSendMsg()
const {
8241 return isImmTy(ImmTySendMsg);
8248ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8255 int Slot = StringSwitch<int>(Str)
8262 return Error(S,
"invalid interpolation slot");
8264 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8265 AMDGPUOperand::ImmTyInterpSlot));
8269ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8276 if (!Str.starts_with(
"attr"))
8277 return Error(S,
"invalid interpolation attribute");
8279 StringRef Chan = Str.take_back(2);
8280 int AttrChan = StringSwitch<int>(Chan)
8287 return Error(S,
"invalid or missing interpolation attribute channel");
8289 Str = Str.drop_back(2).drop_front(4);
8292 if (Str.getAsInteger(10, Attr))
8293 return Error(S,
"invalid or missing interpolation attribute number");
8296 return Error(S,
"out of bounds interpolation attribute number");
8300 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8301 AMDGPUOperand::ImmTyInterpAttr));
8302 Operands.
push_back(AMDGPUOperand::CreateImm(
8303 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8311ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8312 using namespace llvm::AMDGPU::Exp;
8322 return Error(S, (Id == ET_INVALID)
8323 ?
"invalid exp target"
8324 :
"exp target is not supported on this GPU");
8326 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8327 AMDGPUOperand::ImmTyExpTgt));
8336AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8341AMDGPUAsmParser::isId(
const StringRef Id)
const {
8347 return getTokenKind() ==
Kind;
8350StringRef AMDGPUAsmParser::getId()
const {
8355AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8364AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8366 StringRef Tok = getTokenStr();
8377 if (isId(Id) && peekToken().is(Kind)) {
8387 if (isToken(Kind)) {
8396 const StringRef ErrMsg) {
8397 if (!trySkipToken(Kind)) {
8398 Error(getLoc(), ErrMsg);
8405AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8409 if (Parser.parseExpression(Expr))
8412 if (Expr->evaluateAsAbsolute(
Imm))
8415 if (Expected.empty()) {
8416 Error(S,
"expected absolute expression");
8418 Error(S, Twine(
"expected ", Expected) +
8419 Twine(
" or an absolute expression"));
8429 if (Parser.parseExpression(Expr))
8433 if (Expr->evaluateAsAbsolute(IntVal)) {
8434 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8436 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8442AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8444 Val =
getToken().getStringContents();
8448 Error(getLoc(), ErrMsg);
8453AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8455 Val = getTokenStr();
8459 if (!ErrMsg.
empty())
8460 Error(getLoc(), ErrMsg);
8465AMDGPUAsmParser::getToken()
const {
8466 return Parser.getTok();
8469AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8472 : getLexer().peekTok(ShouldSkipSpace);
8477 auto TokCount = getLexer().peekTokens(Tokens);
8479 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8484AMDGPUAsmParser::getTokenKind()
const {
8485 return getLexer().getKind();
8489AMDGPUAsmParser::getLoc()
const {
8494AMDGPUAsmParser::getTokenStr()
const {
8499AMDGPUAsmParser::lex() {
8503SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8504 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8508SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8512SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8513 int MCOpIdx)
const {
8514 for (
const auto &
Op : Operands) {
8515 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8516 if (TargetOp.getMCOpIdx() == MCOpIdx)
8517 return TargetOp.getStartLoc();
8523AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8525 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8526 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8528 return Op.getStartLoc();
8530 return getInstLoc(Operands);
8534AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8536 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8537 return getOperandLoc(
Test, Operands);
8551 StringRef
Id = getTokenStr();
8552 SMLoc IdLoc = getLoc();
8558 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8559 if (
I == Fields.
end())
8560 return Error(IdLoc,
"unknown field");
8561 if ((*I)->IsDefined)
8562 return Error(IdLoc,
"duplicate field");
8565 (*I)->Loc = getLoc();
8568 (*I)->IsDefined =
true;
8575bool AMDGPUAsmParser::validateStructuredOpFields(
8577 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8578 return F->validate(*
this);
8589 const unsigned OrMask,
8590 const unsigned XorMask) {
8599bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8600 const unsigned MaxVal,
8601 const Twine &ErrMsg, SMLoc &Loc) {
8618AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8619 const unsigned MinVal,
8620 const unsigned MaxVal,
8621 const StringRef ErrMsg) {
8623 for (
unsigned i = 0; i < OpNum; ++i) {
8624 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8632AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8633 using namespace llvm::AMDGPU::Swizzle;
8636 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8637 "expected a 2-bit lane id")) {
8648AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8649 using namespace llvm::AMDGPU::Swizzle;
8655 if (!parseSwizzleOperand(GroupSize,
8657 "group size must be in the interval [2,32]",
8662 Error(Loc,
"group size must be a power of two");
8665 if (parseSwizzleOperand(LaneIdx,
8667 "lane id must be in the interval [0,group size - 1]",
8676AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8677 using namespace llvm::AMDGPU::Swizzle;
8682 if (!parseSwizzleOperand(GroupSize,
8684 "group size must be in the interval [2,32]",
8689 Error(Loc,
"group size must be a power of two");
8698AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8699 using namespace llvm::AMDGPU::Swizzle;
8704 if (!parseSwizzleOperand(GroupSize,
8706 "group size must be in the interval [1,16]",
8711 Error(Loc,
"group size must be a power of two");
8720AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8721 using namespace llvm::AMDGPU::Swizzle;
8728 SMLoc StrLoc = getLoc();
8729 if (!parseString(Ctl)) {
8732 if (Ctl.
size() != BITMASK_WIDTH) {
8733 Error(StrLoc,
"expected a 5-character mask");
8737 unsigned AndMask = 0;
8738 unsigned OrMask = 0;
8739 unsigned XorMask = 0;
8741 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8745 Error(StrLoc,
"invalid mask");
8766bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8767 using namespace llvm::AMDGPU::Swizzle;
8770 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8776 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8777 "FFT swizzle must be in the interval [0," +
8778 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8786bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8787 using namespace llvm::AMDGPU::Swizzle;
8790 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8797 if (!parseSwizzleOperand(
Direction, 0, 1,
8798 "direction must be 0 (left) or 1 (right)", Loc))
8802 if (!parseSwizzleOperand(
8803 RotateSize, 0, ROTATE_MAX_SIZE,
8804 "number of threads to rotate must be in the interval [0," +
8805 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8810 (RotateSize << ROTATE_SIZE_SHIFT);
8815AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8817 SMLoc OffsetLoc = getLoc();
8823 Error(OffsetLoc,
"expected a 16-bit offset");
8830AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8831 using namespace llvm::AMDGPU::Swizzle;
8835 SMLoc ModeLoc = getLoc();
8838 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8839 Ok = parseSwizzleQuadPerm(
Imm);
8840 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8841 Ok = parseSwizzleBitmaskPerm(
Imm);
8842 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8843 Ok = parseSwizzleBroadcast(
Imm);
8844 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8845 Ok = parseSwizzleSwap(
Imm);
8846 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8847 Ok = parseSwizzleReverse(
Imm);
8848 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8849 Ok = parseSwizzleFFT(
Imm);
8850 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8851 Ok = parseSwizzleRotate(
Imm);
8853 Error(ModeLoc,
"expected a swizzle mode");
8856 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8862ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8866 if (trySkipId(
"offset")) {
8870 if (trySkipId(
"swizzle")) {
8871 Ok = parseSwizzleMacro(
Imm);
8873 Ok = parseSwizzleOffset(
Imm);
8877 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8885AMDGPUOperand::isSwizzle()
const {
8886 return isImmTy(ImmTySwizzle);
8893int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8895 using namespace llvm::AMDGPU::VGPRIndexMode;
8907 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8908 if (trySkipId(IdSymbolic[ModeId])) {
8916 "expected a VGPR index mode or a closing parenthesis" :
8917 "expected a VGPR index mode");
8922 Error(S,
"duplicate VGPR index mode");
8930 "expected a comma or a closing parenthesis"))
8937ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8939 using namespace llvm::AMDGPU::VGPRIndexMode;
8945 Imm = parseGPRIdxMacro();
8949 if (getParser().parseAbsoluteExpression(
Imm))
8952 return Error(S,
"invalid immediate: only 4-bit values are legal");
8956 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8960bool AMDGPUOperand::isGPRIdxMode()
const {
8961 return isImmTy(ImmTyGprIdxMode);
8968ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
8973 if (isRegister() || isModifier())
8979 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
8980 assert(Opr.isImm() || Opr.isExpr());
8981 SMLoc Loc = Opr.getStartLoc();
8985 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8986 Error(Loc,
"expected an absolute expression or a label");
8987 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8988 Error(Loc,
"expected a 16-bit signed jump offset");
8998ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
8999 return parseReg(Operands);
9006void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
9009 OptionalImmIndexMap OptionalIdx;
9010 unsigned FirstOperandIdx = 1;
9011 bool IsAtomicReturn =
false;
9018 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9019 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9023 Op.addRegOperands(Inst, 1);
9027 if (IsAtomicReturn && i == FirstOperandIdx)
9028 Op.addRegOperands(Inst, 1);
9033 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9034 Op.addImmOperands(Inst, 1);
9046 OptionalIdx[
Op.getImmTy()] = i;
9060bool AMDGPUOperand::isSMRDOffset8()
const {
9064bool AMDGPUOperand::isSMEMOffset()
const {
9066 return isImmLiteral();
9069bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9104bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9105 if (BoundCtrl == 0 || BoundCtrl == 1) {
9113void AMDGPUAsmParser::onBeginOfFile() {
9114 if (!getParser().getStreamer().getTargetStreamer() ||
9118 if (!getTargetStreamer().getTargetID())
9119 getTargetStreamer().initializeTargetID(getSTI(),
9120 getSTI().getFeatureString());
9123 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9131bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9135 StringRef TokenId = getTokenStr();
9136 AGVK VK = StringSwitch<AGVK>(TokenId)
9137 .Case(
"max", AGVK::AGVK_Max)
9138 .Case(
"or", AGVK::AGVK_Or)
9139 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9140 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9141 .Case(
"alignto", AGVK::AGVK_AlignTo)
9142 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9143 .Default(AGVK::AGVK_None);
9147 uint64_t CommaCount = 0;
9152 if (Exprs.
empty()) {
9154 "empty " + Twine(TokenId) +
" expression");
9157 if (CommaCount + 1 != Exprs.
size()) {
9159 "mismatch of commas in " + Twine(TokenId) +
" expression");
9166 if (getParser().parseExpression(Expr, EndLoc))
9170 if (LastTokenWasComma)
9174 "unexpected token in " + Twine(TokenId) +
" expression");
9180 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9183ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9184 StringRef
Name = getTokenStr();
9185 if (Name ==
"mul") {
9186 return parseIntWithPrefix(
"mul", Operands,
9190 if (Name ==
"div") {
9191 return parseIntWithPrefix(
"div", Operands,
9202 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9207 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9208 AMDGPU::OpName::src2};
9216 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9221 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9223 if (
DstOp.isReg() &&
9224 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9228 if ((OpSel & (1 << SrcNum)) != 0)
9234void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9236 cvtVOP3P(Inst, Operands);
9240void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9241 OptionalImmIndexMap &OptionalIdx) {
9242 cvtVOP3P(Inst, Operands, OptionalIdx);
9251 &&
Desc.NumOperands > (OpNum + 1)
9253 &&
Desc.operands()[OpNum + 1].RegClass != -1
9255 &&
Desc.getOperandConstraint(OpNum + 1,
9259void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9261 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9262 AMDGPU::OpName::src2};
9263 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9264 AMDGPU::OpName::src1_modifiers,
9265 AMDGPU::OpName::src2_modifiers};
9266 for (
int J = 0; J < 3; ++J) {
9267 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9273 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9276 if ((OpSel & (1 << J)) != 0)
9279 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9286void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9288 OptionalImmIndexMap OptionalIdx;
9293 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9294 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9297 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9298 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9300 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9301 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9302 Op.isInterpAttrChan()) {
9304 }
else if (
Op.isImmModifier()) {
9305 OptionalIdx[
Op.getImmTy()] =
I;
9313 AMDGPUOperand::ImmTyHigh);
9317 AMDGPUOperand::ImmTyClamp);
9321 AMDGPUOperand::ImmTyOModSI);
9326 AMDGPUOperand::ImmTyOpSel);
9327 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9330 cvtOpSelHelper(Inst, OpSel);
9334void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9336 OptionalImmIndexMap OptionalIdx;
9341 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9342 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9345 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9346 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9348 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9349 }
else if (
Op.isImmModifier()) {
9350 OptionalIdx[
Op.getImmTy()] =
I;
9358 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9368 cvtOpSelHelper(Inst, OpSel);
9371void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9373 OptionalImmIndexMap OptionalIdx;
9376 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9380 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9381 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9383 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9384 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9389 if (NumOperands == CbszOpIdx) {
9394 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9395 }
else if (
Op.isImmModifier()) {
9396 OptionalIdx[
Op.getImmTy()] =
I;
9398 Op.addRegOrImmOperands(Inst, 1);
9403 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9404 if (CbszIdx != OptionalIdx.end()) {
9405 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9409 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9410 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9411 if (BlgpIdx != OptionalIdx.end()) {
9412 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9423 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9424 if (OpselIdx != OptionalIdx.end()) {
9425 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9429 unsigned OpSelHi = 0;
9430 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9431 if (OpselHiIdx != OptionalIdx.end()) {
9432 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9435 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9436 AMDGPU::OpName::src1_modifiers};
9438 for (
unsigned J = 0; J < 2; ++J) {
9439 unsigned ModVal = 0;
9440 if (OpSel & (1 << J))
9442 if (OpSelHi & (1 << J))
9445 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9450void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9451 OptionalImmIndexMap &OptionalIdx) {
9456 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9457 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9460 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9461 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9463 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9464 }
else if (
Op.isImmModifier()) {
9465 OptionalIdx[
Op.getImmTy()] =
I;
9467 Op.addRegOrImmOperands(Inst, 1);
9473 AMDGPUOperand::ImmTyScaleSel);
9477 AMDGPUOperand::ImmTyClamp);
9483 AMDGPUOperand::ImmTyByteSel);
9488 AMDGPUOperand::ImmTyOModSI);
9495 auto *it = Inst.
begin();
9496 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9504void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9505 OptionalImmIndexMap OptionalIdx;
9506 cvtVOP3(Inst, Operands, OptionalIdx);
9509void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9510 OptionalImmIndexMap &OptIdx) {
9516 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9517 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9518 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9519 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9520 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9521 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9529 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9530 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9531 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9532 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9533 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9534 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9535 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9536 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9537 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9538 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9539 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9540 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9541 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9542 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9543 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9544 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9545 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9546 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9547 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9548 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9549 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9550 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9551 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9552 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9553 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9554 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9558 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9559 if (BitOp3Idx != -1) {
9566 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9567 if (OpSelIdx != -1) {
9571 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9572 if (OpSelHiIdx != -1) {
9579 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9580 if (MatrixAFMTIdx != -1) {
9582 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9586 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9587 if (MatrixBFMTIdx != -1) {
9589 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9592 int MatrixAScaleIdx =
9593 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9594 if (MatrixAScaleIdx != -1) {
9596 AMDGPUOperand::ImmTyMatrixAScale, 0);
9599 int MatrixBScaleIdx =
9600 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9601 if (MatrixBScaleIdx != -1) {
9603 AMDGPUOperand::ImmTyMatrixBScale, 0);
9606 int MatrixAScaleFmtIdx =
9607 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9608 if (MatrixAScaleFmtIdx != -1) {
9610 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9613 int MatrixBScaleFmtIdx =
9614 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9615 if (MatrixBScaleFmtIdx != -1) {
9617 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9622 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9626 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9628 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9632 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9636 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9637 AMDGPU::OpName::src2};
9638 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9639 AMDGPU::OpName::src1_modifiers,
9640 AMDGPU::OpName::src2_modifiers};
9643 unsigned OpSelHi = 0;
9650 if (OpSelHiIdx != -1)
9659 for (
int J = 0; J < 3; ++J) {
9660 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9664 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9669 uint32_t ModVal = 0;
9672 if (SrcOp.
isReg() && getMRI()
9679 if ((OpSel & (1 << J)) != 0)
9683 if ((OpSelHi & (1 << J)) != 0)
9686 if ((NegLo & (1 << J)) != 0)
9689 if ((NegHi & (1 << J)) != 0)
9696void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9697 OptionalImmIndexMap OptIdx;
9698 cvtVOP3(Inst, Operands, OptIdx);
9699 cvtVOP3P(Inst, Operands, OptIdx);
9703 unsigned i,
unsigned Opc,
9705 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9706 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9708 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9711void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9714 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9717 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9718 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9720 OptionalImmIndexMap OptIdx;
9721 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9722 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9723 OptIdx[
Op.getImmTy()] = i;
9728 AMDGPUOperand::ImmTyIndexKey8bit);
9732 AMDGPUOperand::ImmTyIndexKey16bit);
9736 AMDGPUOperand::ImmTyIndexKey32bit);
9741 cvtVOP3P(Inst, Operands, OptIdx);
9748ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9756 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9757 SMLoc OpYLoc = getLoc();
9760 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9763 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9769void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9772 auto addOp = [&](uint16_t ParsedOprIdx) {
9773 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9775 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9779 Op.addRegOperands(Inst, 1);
9783 Op.addImmOperands(Inst, 1);
9795 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9799 const auto &CInfo = InstInfo[CompIdx];
9800 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9801 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9802 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9803 if (CInfo.hasSrc2Acc())
9804 addOp(CInfo.getIndexOfDstInParsedOperands());
9808 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9809 if (BitOp3Idx != -1) {
9810 OptionalImmIndexMap OptIdx;
9811 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9813 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9823bool AMDGPUOperand::isDPP8()
const {
9824 return isImmTy(ImmTyDPP8);
9827bool AMDGPUOperand::isDPPCtrl()
const {
9828 using namespace AMDGPU::DPP;
9830 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9833 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9834 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9835 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9836 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9837 (
Imm == DppCtrl::WAVE_SHL1) ||
9838 (
Imm == DppCtrl::WAVE_ROL1) ||
9839 (
Imm == DppCtrl::WAVE_SHR1) ||
9840 (
Imm == DppCtrl::WAVE_ROR1) ||
9841 (
Imm == DppCtrl::ROW_MIRROR) ||
9842 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9843 (
Imm == DppCtrl::BCAST15) ||
9844 (
Imm == DppCtrl::BCAST31) ||
9845 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9846 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9855bool AMDGPUOperand::isBLGP()
const {
9859bool AMDGPUOperand::isS16Imm()
const {
9863bool AMDGPUOperand::isU16Imm()
const {
9871bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9876 SMLoc Loc =
getToken().getEndLoc();
9877 Token = std::string(getTokenStr());
9879 if (getLoc() != Loc)
9884 if (!parseId(Suffix))
9888 StringRef DimId = Token;
9899ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9909 SMLoc Loc = getLoc();
9910 if (!parseDimId(Encoding))
9911 return Error(Loc,
"invalid dim value");
9913 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9914 AMDGPUOperand::ImmTyDim));
9922ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
9932 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9935 for (
size_t i = 0; i < 8; ++i) {
9939 SMLoc Loc = getLoc();
9940 if (getParser().parseAbsoluteExpression(Sels[i]))
9942 if (0 > Sels[i] || 7 < Sels[i])
9943 return Error(Loc,
"expected a 3-bit value");
9950 for (
size_t i = 0; i < 8; ++i)
9951 DPP8 |= (Sels[i] << (i * 3));
9953 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9958AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
9960 if (Ctrl ==
"row_newbcast")
9963 if (Ctrl ==
"row_share" ||
9964 Ctrl ==
"row_xmask")
9967 if (Ctrl ==
"wave_shl" ||
9968 Ctrl ==
"wave_shr" ||
9969 Ctrl ==
"wave_rol" ||
9970 Ctrl ==
"wave_ror" ||
9971 Ctrl ==
"row_bcast")
9974 return Ctrl ==
"row_mirror" ||
9975 Ctrl ==
"row_half_mirror" ||
9976 Ctrl ==
"quad_perm" ||
9977 Ctrl ==
"row_shl" ||
9978 Ctrl ==
"row_shr" ||
9983AMDGPUAsmParser::parseDPPCtrlPerm() {
9986 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9990 for (
int i = 0; i < 4; ++i) {
9995 SMLoc Loc = getLoc();
9996 if (getParser().parseAbsoluteExpression(Temp))
9998 if (Temp < 0 || Temp > 3) {
9999 Error(Loc,
"expected a 2-bit value");
10003 Val += (Temp << i * 2);
10006 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10013AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10014 using namespace AMDGPU::DPP;
10019 SMLoc Loc = getLoc();
10021 if (getParser().parseAbsoluteExpression(Val))
10024 struct DppCtrlCheck {
10030 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10031 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10032 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10033 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10034 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10035 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10036 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10037 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10038 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10039 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10040 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10044 if (
Check.Ctrl == -1) {
10045 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10053 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10060ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10061 using namespace AMDGPU::DPP;
10064 !isSupportedDPPCtrl(getTokenStr(), Operands))
10067 SMLoc S = getLoc();
10073 if (Ctrl ==
"row_mirror") {
10074 Val = DppCtrl::ROW_MIRROR;
10075 }
else if (Ctrl ==
"row_half_mirror") {
10076 Val = DppCtrl::ROW_HALF_MIRROR;
10079 if (Ctrl ==
"quad_perm") {
10080 Val = parseDPPCtrlPerm();
10082 Val = parseDPPCtrlSel(Ctrl);
10091 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10095void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10097 OptionalImmIndexMap OptionalIdx;
10104 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10106 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10107 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10111 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10112 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10116 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10117 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10118 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10119 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10120 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10122 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10126 if (OldIdx == NumOperands) {
10128 constexpr int DST_IDX = 0;
10130 }
else if (Src2ModIdx == NumOperands) {
10140 if (IsVOP3CvtSrDpp) {
10149 if (TiedTo != -1) {
10154 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10156 if (IsDPP8 &&
Op.isDppFI()) {
10159 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10160 }
else if (
Op.isReg()) {
10161 Op.addRegOperands(Inst, 1);
10162 }
else if (
Op.isImm() &&
10164 Op.addImmOperands(Inst, 1);
10165 }
else if (
Op.isImm()) {
10166 OptionalIdx[
Op.getImmTy()] =
I;
10174 AMDGPUOperand::ImmTyClamp);
10180 AMDGPUOperand::ImmTyByteSel);
10187 cvtVOP3P(Inst, Operands, OptionalIdx);
10189 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10196 using namespace llvm::AMDGPU::DPP;
10206 AMDGPUOperand::ImmTyDppFI);
10210void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10211 OptionalImmIndexMap OptionalIdx;
10215 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10216 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10220 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10223 if (TiedTo != -1) {
10228 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10230 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10238 Op.addImmOperands(Inst, 1);
10240 Op.addRegWithFPInputModsOperands(Inst, 2);
10241 }
else if (
Op.isDppFI()) {
10243 }
else if (
Op.isReg()) {
10244 Op.addRegOperands(Inst, 1);
10250 Op.addRegWithFPInputModsOperands(Inst, 2);
10251 }
else if (
Op.isReg()) {
10252 Op.addRegOperands(Inst, 1);
10253 }
else if (
Op.isDPPCtrl()) {
10254 Op.addImmOperands(Inst, 1);
10255 }
else if (
Op.isImm()) {
10257 OptionalIdx[
Op.getImmTy()] =
I;
10265 using namespace llvm::AMDGPU::DPP;
10273 AMDGPUOperand::ImmTyDppFI);
10282ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10284 AMDGPUOperand::ImmTy
Type) {
10285 return parseStringOrIntWithPrefix(
10287 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10291ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10292 return parseStringOrIntWithPrefix(
10293 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10294 AMDGPUOperand::ImmTySDWADstUnused);
10297void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10301void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10305void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10309void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10313void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10317void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10318 uint64_t BasicInstType,
10321 using namespace llvm::AMDGPU::SDWA;
10323 OptionalImmIndexMap OptionalIdx;
10324 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10325 bool SkippedVcc =
false;
10329 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10330 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10333 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10334 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10335 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10336 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10354 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10355 }
else if (
Op.isImm()) {
10357 OptionalIdx[
Op.getImmTy()] =
I;
10361 SkippedVcc =
false;
10365 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10366 Opc != AMDGPU::V_NOP_sdwa_vi) {
10368 switch (BasicInstType) {
10372 AMDGPUOperand::ImmTyClamp, 0);
10376 AMDGPUOperand::ImmTyOModSI, 0);
10380 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10384 AMDGPUOperand::ImmTySDWADstUnused,
10385 DstUnused::UNUSED_PRESERVE);
10387 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10392 AMDGPUOperand::ImmTyClamp, 0);
10397 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10398 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10399 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10400 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10406 AMDGPUOperand::ImmTyClamp, 0);
10407 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10408 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10412 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10418 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10419 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10420 auto *it = Inst.
begin();
10422 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10434#define GET_MATCHER_IMPLEMENTATION
10435#define GET_MNEMONIC_SPELL_CHECKER
10436#define GET_MNEMONIC_CHECKER
10437#include "AMDGPUGenAsmMatcher.inc"
10443 return parseTokenOp(
"addr64",
Operands);
10445 return parseTokenOp(
"done",
Operands);
10447 return parseTokenOp(
"idxen",
Operands);
10449 return parseTokenOp(
"lds",
Operands);
10451 return parseTokenOp(
"offen",
Operands);
10453 return parseTokenOp(
"off",
Operands);
10454 case MCK_row_95_en:
10455 return parseTokenOp(
"row_en",
Operands);
10457 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10459 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10461 return tryCustomParseOperand(
Operands, MCK);
10466unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10472 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10475 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10477 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10479 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10481 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10483 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10485 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10493 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10495 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10496 case MCK_SOPPBrTarget:
10497 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10498 case MCK_VReg32OrOff:
10499 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10500 case MCK_InterpSlot:
10501 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10502 case MCK_InterpAttr:
10503 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10504 case MCK_InterpAttrChan:
10505 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10507 case MCK_SReg_64_XEXEC:
10517 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10519 return Match_InvalidOperand;
10527ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10528 SMLoc S = getLoc();
10537 return Error(S,
"expected a 16-bit value");
10540 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10544bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10550bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, AMDGPU::OpName OpName)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static int IsAGPROperand(const MCInst &Inst, AMDGPU::OpName Name, const MCRegisterInfo *MRI)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
constexpr uint64_t MIMGFlags
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static bool IsRevOpcode(const unsigned Opcode)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static MCRegister getSpecialRegForName(StringRef RegName)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0, std::optional< unsigned > InsertAt=std::nullopt)
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Loop::LoopBounds::Direction Direction
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
MachineInstr unsigned OpIdx
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
unsigned unsigned DefaultVal
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
static const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
int16_t getOpRegClassID(const MCOperandInfo &OpInfo, unsigned HwModeId) const
Return the ID of the register class to use for OpInfo, for the active HwMode HwModeId.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
void setReg(MCRegister Reg)
Set the register number.
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterClass - Base class of TargetRegisterClass.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isVariable() const
isVariable - Check if this is a variable symbol.
LLVM_ABI void setVariableValue(const MCExpr *Value)
void setRedefinable(bool Value)
Mark this symbol as redefinable.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
uint64_t getScalarSizeInBits() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
unsigned getTgtId(const StringRef Name)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI)
static constexpr CustomOperand Operands[]
unsigned getVGPREncodingGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI)
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
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)
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 hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_IMM_V2FP16_SPLAT
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
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