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);
1566 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1568 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1570 bool hasInv2PiInlineImm()
const {
1571 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1574 bool has64BitLiterals()
const {
1575 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1578 bool hasFlatOffsets()
const {
1579 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1582 bool hasTrue16Insts()
const {
1583 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1587 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1590 bool hasSGPR102_SGPR103()
const {
1594 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1596 bool hasIntClamp()
const {
1597 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1600 bool hasPartialNSAEncoding()
const {
1601 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1604 bool hasGloballyAddressableScratch()
const {
1605 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1618 AMDGPUTargetStreamer &getTargetStreamer() {
1619 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1620 return static_cast<AMDGPUTargetStreamer &
>(TS);
1626 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1629 const MCRegisterInfo *getMRI()
const {
1633 const MCInstrInfo *getMII()
const {
1639 const FeatureBitset &getFeatureBits()
const {
1640 return getSTI().getFeatureBits();
1643 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1644 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1645 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1647 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1648 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1649 bool isForcedDPP()
const {
return ForcedDPP; }
1650 bool isForcedSDWA()
const {
return ForcedSDWA; }
1651 ArrayRef<unsigned> getMatchedVariants()
const;
1652 StringRef getMatchedVariantName()
const;
1654 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1655 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1656 bool RestoreOnFailure);
1657 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1658 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1659 SMLoc &EndLoc)
override;
1660 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1661 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1662 unsigned Kind)
override;
1663 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1665 uint64_t &ErrorInfo,
1666 bool MatchingInlineAsm)
override;
1667 bool ParseDirective(AsmToken DirectiveID)
override;
1668 ParseStatus parseOperand(
OperandVector &Operands, StringRef Mnemonic,
1669 OperandMode
Mode = OperandMode_Default);
1670 StringRef parseMnemonicSuffix(StringRef Name);
1671 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1675 ParseStatus parseTokenOp(StringRef Name,
OperandVector &Operands);
1677 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1680 parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1681 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1682 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1684 ParseStatus parseOperandArrayWithPrefix(
1686 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1687 bool (*ConvertResult)(int64_t &) =
nullptr);
1691 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1692 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1694 ParseStatus parseScope(
OperandVector &Operands, int64_t &Scope);
1696 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1698 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1700 ArrayRef<const char *> Ids,
1702 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1704 ArrayRef<const char *> Ids,
1705 AMDGPUOperand::ImmTy
Type);
1708 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1709 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1710 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1711 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1712 bool parseSP3NegModifier();
1713 ParseStatus parseImm(
OperandVector &Operands,
bool HasSP3AbsModifier =
false,
1716 ParseStatus parseRegOrImm(
OperandVector &Operands,
bool HasSP3AbsMod =
false,
1718 ParseStatus parseRegOrImmWithFPInputMods(
OperandVector &Operands,
1719 bool AllowImm =
true);
1720 ParseStatus parseRegOrImmWithIntInputMods(
OperandVector &Operands,
1721 bool AllowImm =
true);
1722 ParseStatus parseRegWithFPInputMods(
OperandVector &Operands);
1723 ParseStatus parseRegWithIntInputMods(
OperandVector &Operands);
1726 AMDGPUOperand::ImmTy ImmTy);
1730 ParseStatus tryParseMatrixFMT(
OperandVector &Operands, StringRef Name,
1731 AMDGPUOperand::ImmTy
Type);
1734 ParseStatus tryParseMatrixScale(
OperandVector &Operands, StringRef Name,
1735 AMDGPUOperand::ImmTy
Type);
1738 ParseStatus tryParseMatrixScaleFmt(
OperandVector &Operands, StringRef Name,
1739 AMDGPUOperand::ImmTy
Type);
1743 ParseStatus parseDfmtNfmt(int64_t &
Format);
1744 ParseStatus parseUfmt(int64_t &
Format);
1745 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1747 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1750 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1751 ParseStatus parseNumericFormat(int64_t &
Format);
1755 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1756 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1760 bool parseCnt(int64_t &IntVal);
1763 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1764 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1767 bool parseDelay(int64_t &Delay);
1773 struct OperandInfoTy {
1776 bool IsSymbolic =
false;
1777 bool IsDefined =
false;
1779 OperandInfoTy(int64_t Val) : Val(Val) {}
1782 struct StructuredOpField : OperandInfoTy {
1786 bool IsDefined =
false;
1788 StructuredOpField(StringLiteral Id, StringLiteral Desc,
unsigned Width,
1790 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1791 virtual ~StructuredOpField() =
default;
1793 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1794 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1798 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1800 return Error(Parser,
"not supported on this GPU");
1802 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1810 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1811 bool validateSendMsg(
const OperandInfoTy &Msg,
1812 const OperandInfoTy &
Op,
1813 const OperandInfoTy &Stream);
1815 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1816 OperandInfoTy &Width);
1818 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1820 SMLoc getFlatOffsetLoc(
const OperandVector &Operands)
const;
1821 SMLoc getSMEMOffsetLoc(
const OperandVector &Operands)
const;
1824 SMLoc getOperandLoc(
const OperandVector &Operands,
int MCOpIdx)
const;
1825 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1827 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1831 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1833 bool validateOffset(
const MCInst &Inst,
const OperandVector &Operands);
1834 bool validateFlatOffset(
const MCInst &Inst,
const OperandVector &Operands);
1835 bool validateSMEMOffset(
const MCInst &Inst,
const OperandVector &Operands);
1836 bool validateSOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1837 bool validateConstantBusLimitations(
const MCInst &Inst,
const OperandVector &Operands);
1838 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1840 bool validateVOPD(
const MCInst &Inst,
const OperandVector &Operands);
1841 bool tryVOPD(
const MCInst &Inst);
1842 bool tryVOPD3(
const MCInst &Inst);
1843 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1845 bool validateIntClampSupported(
const MCInst &Inst);
1846 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1847 bool validateMIMGGatherDMask(
const MCInst &Inst);
1848 bool validateMovrels(
const MCInst &Inst,
const OperandVector &Operands);
1849 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1850 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1851 bool validateMIMGD16(
const MCInst &Inst);
1852 bool validateMIMGDim(
const MCInst &Inst,
const OperandVector &Operands);
1853 bool validateTensorR128(
const MCInst &Inst);
1854 bool validateMIMGMSAA(
const MCInst &Inst);
1855 bool validateOpSel(
const MCInst &Inst);
1856 bool validateTrue16OpSel(
const MCInst &Inst);
1857 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1858 bool validateDPP(
const MCInst &Inst,
const OperandVector &Operands);
1859 bool validateVccOperand(MCRegister
Reg)
const;
1860 bool validateVOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1861 bool validateMAIAccWrite(
const MCInst &Inst,
const OperandVector &Operands);
1862 bool validateMAISrc2(
const MCInst &Inst,
const OperandVector &Operands);
1863 bool validateMFMA(
const MCInst &Inst,
const OperandVector &Operands);
1864 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1865 bool validateVGPRAlign(
const MCInst &Inst)
const;
1866 bool validateBLGP(
const MCInst &Inst,
const OperandVector &Operands);
1867 bool validateDS(
const MCInst &Inst,
const OperandVector &Operands);
1868 bool validateGWS(
const MCInst &Inst,
const OperandVector &Operands);
1869 bool validateDivScale(
const MCInst &Inst);
1870 bool validateWaitCnt(
const MCInst &Inst,
const OperandVector &Operands);
1871 bool validateCoherencyBits(
const MCInst &Inst,
const OperandVector &Operands,
1873 bool validateTHAndScopeBits(
const MCInst &Inst,
const OperandVector &Operands,
1874 const unsigned CPol);
1875 bool validateTFE(
const MCInst &Inst,
const OperandVector &Operands);
1876 bool validateLdsDirect(
const MCInst &Inst,
const OperandVector &Operands);
1877 bool validateWMMA(
const MCInst &Inst,
const OperandVector &Operands);
1878 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1879 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1880 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1881 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1883 bool isSupportedMnemo(StringRef Mnemo,
1884 const FeatureBitset &FBS);
1885 bool isSupportedMnemo(StringRef Mnemo,
1886 const FeatureBitset &FBS,
1887 ArrayRef<unsigned> Variants);
1888 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1890 bool isId(
const StringRef Id)
const;
1891 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1893 StringRef getId()
const;
1894 bool trySkipId(
const StringRef Id);
1895 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1899 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1900 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1906 StringRef getTokenStr()
const;
1907 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1909 SMLoc getLoc()
const;
1913 void onBeginOfFile()
override;
1914 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1916 ParseStatus parseCustomOperand(
OperandVector &Operands,
unsigned MCK);
1925 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1926 const unsigned MaxVal,
const Twine &ErrMsg,
1928 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1929 const unsigned MinVal,
1930 const unsigned MaxVal,
1931 const StringRef ErrMsg);
1933 bool parseSwizzleOffset(int64_t &
Imm);
1934 bool parseSwizzleMacro(int64_t &
Imm);
1935 bool parseSwizzleQuadPerm(int64_t &
Imm);
1936 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1937 bool parseSwizzleBroadcast(int64_t &
Imm);
1938 bool parseSwizzleSwap(int64_t &
Imm);
1939 bool parseSwizzleReverse(int64_t &
Imm);
1940 bool parseSwizzleFFT(int64_t &
Imm);
1941 bool parseSwizzleRotate(int64_t &
Imm);
1944 int64_t parseGPRIdxMacro();
1946 void cvtMubuf(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
false); }
1947 void cvtMubufAtomic(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
true); }
1952 OptionalImmIndexMap &OptionalIdx);
1953 void cvtScaledMFMA(MCInst &Inst,
const OperandVector &Operands);
1954 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands);
1957 void cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands);
1960 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
1961 OptionalImmIndexMap &OptionalIdx);
1963 OptionalImmIndexMap &OptionalIdx);
1965 void cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands);
1966 void cvtVINTERP(MCInst &Inst,
const OperandVector &Operands);
1967 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1969 bool parseDimId(
unsigned &Encoding);
1971 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1974 bool isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands);
1975 int64_t parseDPPCtrlSel(StringRef Ctrl);
1976 int64_t parseDPPCtrlPerm();
1977 void cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8 =
false);
1979 cvtDPP(Inst, Operands,
true);
1981 void cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
1982 bool IsDPP8 =
false);
1983 void cvtVOP3DPP8(MCInst &Inst,
const OperandVector &Operands) {
1984 cvtVOP3DPP(Inst, Operands,
true);
1987 ParseStatus parseSDWASel(
OperandVector &Operands, StringRef Prefix,
1988 AMDGPUOperand::ImmTy
Type);
1990 void cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands);
1991 void cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands);
1992 void cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands);
1993 void cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands);
1994 void cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands);
1996 uint64_t BasicInstType,
1997 bool SkipDstVcc =
false,
1998 bool SkipSrcVcc =
false);
2107bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2117 if (!isImmTy(ImmTyNone)) {
2122 if (getModifiers().
Lit != LitModifier::None)
2132 if (type == MVT::f64 || type == MVT::i64) {
2134 AsmParser->hasInv2PiInlineImm());
2137 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2156 APFloat::rmNearestTiesToEven, &Lost);
2163 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2165 AsmParser->hasInv2PiInlineImm());
2170 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2171 AsmParser->hasInv2PiInlineImm());
2175 if (type == MVT::f64 || type == MVT::i64) {
2177 AsmParser->hasInv2PiInlineImm());
2186 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2187 type, AsmParser->hasInv2PiInlineImm());
2191 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2192 AsmParser->hasInv2PiInlineImm());
2195bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2197 if (!isImmTy(ImmTyNone)) {
2202 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2207 if (type == MVT::f64 && hasFPModifiers()) {
2227 if (type == MVT::f64) {
2232 if (type == MVT::i64) {
2245 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2246 : (type == MVT::v2i16) ? MVT::f32
2247 : (type == MVT::v2f32) ? MVT::f32
2250 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2254bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2255 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2258bool AMDGPUOperand::isVRegWithInputMods()
const {
2259 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2261 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2262 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2265template <
bool IsFake16>
2266bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2267 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2268 : AMDGPU::VGPR_16_Lo128RegClassID);
2271template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2272 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2273 : AMDGPU::VGPR_16RegClassID);
2276bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2277 if (AsmParser->isVI())
2279 if (AsmParser->isGFX9Plus())
2280 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2284bool AMDGPUOperand::isSDWAFP16Operand()
const {
2285 return isSDWAOperand(MVT::f16);
2288bool AMDGPUOperand::isSDWAFP32Operand()
const {
2289 return isSDWAOperand(MVT::f32);
2292bool AMDGPUOperand::isSDWAInt16Operand()
const {
2293 return isSDWAOperand(MVT::i16);
2296bool AMDGPUOperand::isSDWAInt32Operand()
const {
2297 return isSDWAOperand(MVT::i32);
2300bool AMDGPUOperand::isBoolReg()
const {
2301 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2302 (AsmParser->isWave32() && isSCSrc_b32()));
2305uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2307 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2310 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2322void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2332 addLiteralImmOperand(Inst,
Imm.Val,
2334 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2336 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2341void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2342 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2347 if (ApplyModifiers) {
2350 Val = applyInputFPModifiers(Val,
Size);
2354 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2356 bool CanUse64BitLiterals =
2357 AsmParser->has64BitLiterals() &&
2360 MCContext &Ctx = AsmParser->getContext();
2369 if (
Lit == LitModifier::None &&
2371 AsmParser->hasInv2PiInlineImm())) {
2379 bool HasMandatoryLiteral =
2382 if (
Literal.getLoBits(32) != 0 &&
2383 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2384 !HasMandatoryLiteral) {
2385 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2387 "Can't encode literal as exact 64-bit floating-point operand. "
2388 "Low 32-bits will be set to zero");
2389 Val &= 0xffffffff00000000u;
2395 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2401 Lit = LitModifier::Lit64;
2402 }
else if (
Lit == LitModifier::Lit) {
2416 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2418 Lit = LitModifier::Lit64;
2425 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2426 Literal == 0x3fc45f306725feed) {
2461 APFloat::rmNearestTiesToEven, &lost);
2465 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2472 if (
Lit != LitModifier::None) {
2502 if (
Lit == LitModifier::None &&
2512 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2519 if (
Lit == LitModifier::None &&
2527 if (!AsmParser->has64BitLiterals()) {
2528 Val =
static_cast<uint64_t
>(Val) << 32;
2535 if (
Lit == LitModifier::Lit ||
2537 Val =
static_cast<uint64_t
>(Val) << 32;
2541 if (
Lit == LitModifier::Lit)
2567 if (
Lit != LitModifier::None) {
2575void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2580bool AMDGPUOperand::isInlineValue()
const {
2588void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2599 if (Is == IS_VGPR) {
2603 return AMDGPU::VGPR_32RegClassID;
2605 return AMDGPU::VReg_64RegClassID;
2607 return AMDGPU::VReg_96RegClassID;
2609 return AMDGPU::VReg_128RegClassID;
2611 return AMDGPU::VReg_160RegClassID;
2613 return AMDGPU::VReg_192RegClassID;
2615 return AMDGPU::VReg_224RegClassID;
2617 return AMDGPU::VReg_256RegClassID;
2619 return AMDGPU::VReg_288RegClassID;
2621 return AMDGPU::VReg_320RegClassID;
2623 return AMDGPU::VReg_352RegClassID;
2625 return AMDGPU::VReg_384RegClassID;
2627 return AMDGPU::VReg_512RegClassID;
2629 return AMDGPU::VReg_1024RegClassID;
2631 }
else if (Is == IS_TTMP) {
2635 return AMDGPU::TTMP_32RegClassID;
2637 return AMDGPU::TTMP_64RegClassID;
2639 return AMDGPU::TTMP_128RegClassID;
2641 return AMDGPU::TTMP_256RegClassID;
2643 return AMDGPU::TTMP_512RegClassID;
2645 }
else if (Is == IS_SGPR) {
2649 return AMDGPU::SGPR_32RegClassID;
2651 return AMDGPU::SGPR_64RegClassID;
2653 return AMDGPU::SGPR_96RegClassID;
2655 return AMDGPU::SGPR_128RegClassID;
2657 return AMDGPU::SGPR_160RegClassID;
2659 return AMDGPU::SGPR_192RegClassID;
2661 return AMDGPU::SGPR_224RegClassID;
2663 return AMDGPU::SGPR_256RegClassID;
2665 return AMDGPU::SGPR_288RegClassID;
2667 return AMDGPU::SGPR_320RegClassID;
2669 return AMDGPU::SGPR_352RegClassID;
2671 return AMDGPU::SGPR_384RegClassID;
2673 return AMDGPU::SGPR_512RegClassID;
2675 }
else if (Is == IS_AGPR) {
2679 return AMDGPU::AGPR_32RegClassID;
2681 return AMDGPU::AReg_64RegClassID;
2683 return AMDGPU::AReg_96RegClassID;
2685 return AMDGPU::AReg_128RegClassID;
2687 return AMDGPU::AReg_160RegClassID;
2689 return AMDGPU::AReg_192RegClassID;
2691 return AMDGPU::AReg_224RegClassID;
2693 return AMDGPU::AReg_256RegClassID;
2695 return AMDGPU::AReg_288RegClassID;
2697 return AMDGPU::AReg_320RegClassID;
2699 return AMDGPU::AReg_352RegClassID;
2701 return AMDGPU::AReg_384RegClassID;
2703 return AMDGPU::AReg_512RegClassID;
2705 return AMDGPU::AReg_1024RegClassID;
2713 .
Case(
"exec", AMDGPU::EXEC)
2714 .
Case(
"vcc", AMDGPU::VCC)
2715 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2716 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2717 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2718 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2719 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2720 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2721 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2722 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2723 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2724 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2725 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2726 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2727 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2728 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2729 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2730 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2731 .
Case(
"m0", AMDGPU::M0)
2732 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2733 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2734 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2735 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2736 .
Case(
"scc", AMDGPU::SRC_SCC)
2737 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2738 .
Case(
"tba", AMDGPU::TBA)
2739 .
Case(
"tma", AMDGPU::TMA)
2740 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2741 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2742 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2743 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2744 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2745 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2746 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2747 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2748 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2749 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2750 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2751 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2752 .
Case(
"pc", AMDGPU::PC_REG)
2753 .
Case(
"null", AMDGPU::SGPR_NULL)
2757bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2758 SMLoc &EndLoc,
bool RestoreOnFailure) {
2759 auto R = parseRegister();
2760 if (!R)
return true;
2762 RegNo =
R->getReg();
2763 StartLoc =
R->getStartLoc();
2764 EndLoc =
R->getEndLoc();
2768bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2770 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2773ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2775 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2776 bool PendingErrors = getParser().hasPendingError();
2777 getParser().clearPendingErrors();
2785bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2786 RegisterKind RegKind,
2787 MCRegister Reg1, SMLoc Loc) {
2790 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2795 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2796 Reg = AMDGPU::FLAT_SCR;
2800 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2801 Reg = AMDGPU::XNACK_MASK;
2805 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2810 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2815 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2820 Error(Loc,
"register does not fit in the list");
2826 if (Reg1 !=
Reg + RegWidth / 32) {
2827 Error(Loc,
"registers in a list must have consecutive indices");
2845 {{
"ttmp"}, IS_TTMP},
2851 return Kind == IS_VGPR ||
2859 if (Str.starts_with(
Reg.Name))
2865 return !Str.getAsInteger(10, Num);
2869AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2870 const AsmToken &NextToken)
const {
2885 StringRef RegSuffix = Str.substr(
RegName.size());
2886 if (!RegSuffix.
empty()) {
2904AMDGPUAsmParser::isRegister()
2906 return isRegister(
getToken(), peekToken());
2909MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2910 unsigned SubReg,
unsigned RegWidth,
2914 unsigned AlignSize = 1;
2915 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2921 if (RegNum % AlignSize != 0) {
2922 Error(Loc,
"invalid register alignment");
2923 return MCRegister();
2926 unsigned RegIdx = RegNum / AlignSize;
2929 Error(Loc,
"invalid or unsupported register size");
2930 return MCRegister();
2934 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2935 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2936 Error(Loc,
"register index is out of range");
2937 return AMDGPU::NoRegister;
2940 if (RegKind == IS_VGPR && !
isGFX1250Plus() && RegIdx + RegWidth / 32 > 256) {
2941 Error(Loc,
"register index is out of range");
2942 return MCRegister();
2958bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2960 int64_t RegLo, RegHi;
2964 SMLoc FirstIdxLoc = getLoc();
2971 SecondIdxLoc = getLoc();
2982 Error(FirstIdxLoc,
"invalid register index");
2987 Error(SecondIdxLoc,
"invalid register index");
2991 if (RegLo > RegHi) {
2992 Error(FirstIdxLoc,
"first register index should not exceed second index");
2996 if (RegHi == RegLo) {
2997 StringRef RegSuffix = getTokenStr();
2998 if (RegSuffix ==
".l") {
3001 }
else if (RegSuffix ==
".h") {
3007 Num =
static_cast<unsigned>(RegLo);
3008 RegWidth = 32 * ((RegHi - RegLo) + 1);
3013MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3016 SmallVectorImpl<AsmToken> &Tokens) {
3022 RegKind = IS_SPECIAL;
3029MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3032 SmallVectorImpl<AsmToken> &Tokens) {
3034 StringRef
RegName = getTokenStr();
3035 auto Loc = getLoc();
3039 Error(Loc,
"invalid register name");
3040 return MCRegister();
3048 unsigned SubReg = NoSubRegister;
3049 if (!RegSuffix.
empty()) {
3057 Error(Loc,
"invalid register index");
3058 return MCRegister();
3063 if (!ParseRegRange(RegNum, RegWidth,
SubReg))
3064 return MCRegister();
3067 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
3070MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3071 unsigned &RegNum,
unsigned &RegWidth,
3072 SmallVectorImpl<AsmToken> &Tokens) {
3074 auto ListLoc = getLoc();
3077 "expected a register or a list of registers")) {
3078 return MCRegister();
3083 auto Loc = getLoc();
3084 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3085 return MCRegister();
3086 if (RegWidth != 32) {
3087 Error(Loc,
"expected a single 32-bit register");
3088 return MCRegister();
3092 RegisterKind NextRegKind;
3094 unsigned NextRegNum, NextRegWidth;
3097 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3098 NextRegNum, NextRegWidth,
3100 return MCRegister();
3102 if (NextRegWidth != 32) {
3103 Error(Loc,
"expected a single 32-bit register");
3104 return MCRegister();
3106 if (NextRegKind != RegKind) {
3107 Error(Loc,
"registers in a list must be of the same kind");
3108 return MCRegister();
3110 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3111 return MCRegister();
3115 "expected a comma or a closing square bracket")) {
3116 return MCRegister();
3120 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3125bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3126 MCRegister &
Reg,
unsigned &RegNum,
3128 SmallVectorImpl<AsmToken> &Tokens) {
3129 auto Loc = getLoc();
3133 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3135 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3137 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3142 assert(Parser.hasPendingError());
3146 if (!subtargetHasRegister(*
TRI,
Reg)) {
3147 if (
Reg == AMDGPU::SGPR_NULL) {
3148 Error(Loc,
"'null' operand is not supported on this GPU");
3151 " register not available on this GPU");
3159bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3160 MCRegister &
Reg,
unsigned &RegNum,
3162 bool RestoreOnFailure ) {
3166 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3167 if (RestoreOnFailure) {
3168 while (!Tokens.
empty()) {
3177std::optional<StringRef>
3178AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3181 return StringRef(
".amdgcn.next_free_vgpr");
3183 return StringRef(
".amdgcn.next_free_sgpr");
3185 return std::nullopt;
3189void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3190 auto SymbolName = getGprCountSymbolName(RegKind);
3191 assert(SymbolName &&
"initializing invalid register kind");
3197bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3198 unsigned DwordRegIndex,
3199 unsigned RegWidth) {
3204 auto SymbolName = getGprCountSymbolName(RegKind);
3209 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3213 return !
Error(getLoc(),
3214 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3218 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3220 if (OldCount <= NewMax)
3226std::unique_ptr<AMDGPUOperand>
3227AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3229 SMLoc StartLoc = Tok.getLoc();
3230 SMLoc EndLoc = Tok.getEndLoc();
3231 RegisterKind RegKind;
3233 unsigned RegNum, RegWidth;
3235 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3239 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3242 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3243 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3246ParseStatus AMDGPUAsmParser::parseImm(
OperandVector &Operands,
3250 if (isRegister() || isModifier())
3253 if (
Lit == LitModifier::None) {
3254 if (trySkipId(
"lit"))
3255 Lit = LitModifier::Lit;
3256 else if (trySkipId(
"lit64"))
3257 Lit = LitModifier::Lit64;
3259 if (
Lit != LitModifier::None) {
3262 ParseStatus S = parseImm(Operands, HasSP3AbsModifier,
Lit);
3271 const auto& NextTok = peekToken();
3274 bool Negate =
false;
3282 AMDGPUOperand::Modifiers Mods;
3290 StringRef Num = getTokenStr();
3293 APFloat RealVal(APFloat::IEEEdouble());
3294 auto roundMode = APFloat::rmNearestTiesToEven;
3295 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3298 RealVal.changeSign();
3301 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3302 AMDGPUOperand::ImmTyNone,
true));
3303 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3304 Op.setModifiers(Mods);
3313 if (HasSP3AbsModifier) {
3322 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3325 if (Parser.parseExpression(Expr))
3329 if (Expr->evaluateAsAbsolute(IntVal)) {
3330 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3331 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3332 Op.setModifiers(Mods);
3334 if (
Lit != LitModifier::None)
3336 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3345ParseStatus AMDGPUAsmParser::parseReg(
OperandVector &Operands) {
3349 if (
auto R = parseRegister()) {
3357ParseStatus AMDGPUAsmParser::parseRegOrImm(
OperandVector &Operands,
3359 ParseStatus Res = parseReg(Operands);
3364 return parseImm(Operands, HasSP3AbsMod,
Lit);
3368AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3371 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3377AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3382AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3383 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3387AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3388 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3405AMDGPUAsmParser::isModifier() {
3408 AsmToken NextToken[2];
3409 peekTokens(NextToken);
3411 return isOperandModifier(Tok, NextToken[0]) ||
3412 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3413 isOpcodeModifierWithVal(Tok, NextToken[0]);
3439AMDGPUAsmParser::parseSP3NegModifier() {
3441 AsmToken NextToken[2];
3442 peekTokens(NextToken);
3445 (isRegister(NextToken[0], NextToken[1]) ||
3447 isId(NextToken[0],
"abs"))) {
3456AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
3464 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3466 SP3Neg = parseSP3NegModifier();
3469 Neg = trySkipId(
"neg");
3471 return Error(Loc,
"expected register or immediate");
3475 Abs = trySkipId(
"abs");
3480 if (trySkipId(
"lit")) {
3481 Lit = LitModifier::Lit;
3484 }
else if (trySkipId(
"lit64")) {
3485 Lit = LitModifier::Lit64;
3488 if (!has64BitLiterals())
3489 return Error(Loc,
"lit64 is not supported on this GPU");
3495 return Error(Loc,
"expected register or immediate");
3499 Res = parseRegOrImm(Operands, SP3Abs,
Lit);
3501 Res = parseReg(Operands);
3504 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3508 if (
Lit != LitModifier::None && !Operands.
back()->isImm())
3509 Error(Loc,
"expected immediate with lit modifier");
3511 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3517 if (
Lit != LitModifier::None &&
3521 AMDGPUOperand::Modifiers Mods;
3522 Mods.Abs = Abs || SP3Abs;
3523 Mods.Neg = Neg || SP3Neg;
3526 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3527 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3529 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3530 Op.setModifiers(Mods);
3536AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
3538 bool Sext = trySkipId(
"sext");
3539 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3544 Res = parseRegOrImm(Operands);
3546 Res = parseReg(Operands);
3554 AMDGPUOperand::Modifiers Mods;
3557 if (Mods.hasIntModifiers()) {
3558 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3560 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3561 Op.setModifiers(Mods);
3567ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
3568 return parseRegOrImmWithFPInputMods(Operands,
false);
3571ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
3572 return parseRegOrImmWithIntInputMods(Operands,
false);
3575ParseStatus AMDGPUAsmParser::parseVReg32OrOff(
OperandVector &Operands) {
3576 auto Loc = getLoc();
3577 if (trySkipId(
"off")) {
3578 Operands.
push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3579 AMDGPUOperand::ImmTyOff,
false));
3586 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3595unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3602 return Match_InvalidOperand;
3604 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3605 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3608 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3610 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3611 return Match_InvalidOperand;
3619 if (tryAnotherVOPDEncoding(Inst))
3620 return Match_InvalidOperand;
3622 return Match_Success;
3626 static const unsigned Variants[] = {
3636ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3637 if (isForcedDPP() && isForcedVOP3()) {
3641 if (getForcedEncodingSize() == 32) {
3646 if (isForcedVOP3()) {
3651 if (isForcedSDWA()) {
3657 if (isForcedDPP()) {
3665StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3666 if (isForcedDPP() && isForcedVOP3())
3669 if (getForcedEncodingSize() == 32)
3685AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3689 case AMDGPU::FLAT_SCR:
3691 case AMDGPU::VCC_LO:
3692 case AMDGPU::VCC_HI:
3699 return MCRegister();
3706bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3707 unsigned OpIdx)
const {
3764unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3770 case AMDGPU::V_LSHLREV_B64_e64:
3771 case AMDGPU::V_LSHLREV_B64_gfx10:
3772 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3773 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3774 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3775 case AMDGPU::V_LSHRREV_B64_e64:
3776 case AMDGPU::V_LSHRREV_B64_gfx10:
3777 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3778 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3779 case AMDGPU::V_ASHRREV_I64_e64:
3780 case AMDGPU::V_ASHRREV_I64_gfx10:
3781 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3782 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3783 case AMDGPU::V_LSHL_B64_e64:
3784 case AMDGPU::V_LSHR_B64_e64:
3785 case AMDGPU::V_ASHR_I64_e64:
3798 bool AddMandatoryLiterals =
false) {
3801 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3805 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3807 return {getNamedOperandIdx(Opcode, OpName::src0X),
3808 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3809 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3810 getNamedOperandIdx(Opcode, OpName::src0Y),
3811 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3812 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3817 return {getNamedOperandIdx(Opcode, OpName::src0),
3818 getNamedOperandIdx(Opcode, OpName::src1),
3819 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3822bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3825 return !isInlineConstant(Inst,
OpIdx);
3832 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3843 const unsigned Opcode = Inst.
getOpcode();
3844 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3847 if (!LaneSelOp.
isReg())
3850 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3853bool AMDGPUAsmParser::validateConstantBusLimitations(
3855 const unsigned Opcode = Inst.
getOpcode();
3856 const MCInstrDesc &
Desc = MII.
get(Opcode);
3857 MCRegister LastSGPR;
3858 unsigned ConstantBusUseCount = 0;
3859 unsigned NumLiterals = 0;
3860 unsigned LiteralSize;
3862 if (!(
Desc.TSFlags &
3877 SmallDenseSet<MCRegister> SGPRsUsed;
3878 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3880 SGPRsUsed.
insert(SGPRUsed);
3881 ++ConstantBusUseCount;
3886 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3888 for (
int OpIdx : OpIndices) {
3893 if (usesConstantBus(Inst,
OpIdx)) {
3902 if (SGPRsUsed.
insert(LastSGPR).second) {
3903 ++ConstantBusUseCount;
3923 if (NumLiterals == 0) {
3926 }
else if (LiteralSize !=
Size) {
3932 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3934 "invalid operand (violates constant bus restrictions)");
3941std::optional<unsigned>
3942AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3944 const unsigned Opcode = Inst.
getOpcode();
3950 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3951 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3959 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3960 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3961 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250;
3965 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3966 int I = getNamedOperandIdx(Opcode, OpName);
3970 int64_t
Imm =
Op.getImm();
3976 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3977 OpName::vsrc2Y, OpName::imm}) {
3978 int I = getNamedOperandIdx(Opcode, OpName);
3988 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3989 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3991 return InvalidCompOprIdx;
3994bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
4001 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
4002 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
4003 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
4005 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
4009 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
4010 if (!InvalidCompOprIdx.has_value())
4013 auto CompOprIdx = *InvalidCompOprIdx;
4016 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4017 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4018 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4020 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4021 if (CompOprIdx == VOPD::Component::DST) {
4023 Error(Loc,
"dst registers must be distinct");
4025 Error(Loc,
"one dst register must be even and the other odd");
4027 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4028 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4029 " operands must use different VGPR banks");
4037bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4039 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4040 if (!InvalidCompOprIdx.has_value())
4044 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4045 if (InvalidCompOprIdx.has_value()) {
4050 if (*InvalidCompOprIdx == VOPD::Component::DST)
4063bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4064 const unsigned Opcode = Inst.
getOpcode();
4079 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4080 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4081 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4082 int I = getNamedOperandIdx(Opcode, OpName);
4089 return !tryVOPD3(Inst);
4094bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4095 const unsigned Opcode = Inst.
getOpcode();
4100 return tryVOPD(Inst);
4101 return tryVOPD3(Inst);
4104bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4110 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4121bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4129 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4130 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4131 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4139 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4140 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4145 bool IsPackedD16 =
false;
4149 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4150 IsPackedD16 = D16Idx >= 0;
4155 if ((VDataSize / 4) ==
DataSize + TFESize)
4160 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4162 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4164 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4168bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4177 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4179 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4181 ? AMDGPU::OpName::srsrc
4182 : AMDGPU::OpName::rsrc;
4183 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4184 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4185 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4189 assert(SrsrcIdx > VAddr0Idx);
4192 if (BaseOpcode->
BVH) {
4193 if (IsA16 == BaseOpcode->
A16)
4195 Error(IDLoc,
"image address size does not match a16");
4201 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4202 unsigned ActualAddrSize =
4203 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4205 unsigned ExpectedAddrSize =
4209 if (hasPartialNSAEncoding() &&
4212 int VAddrLastIdx = SrsrcIdx - 1;
4213 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4215 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4218 if (ExpectedAddrSize > 12)
4219 ExpectedAddrSize = 16;
4224 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4228 if (ActualAddrSize == ExpectedAddrSize)
4231 Error(IDLoc,
"image address size does not match dim and a16");
4235bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4242 if (!
Desc.mayLoad() || !
Desc.mayStore())
4245 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4252 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4255bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4263 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4271 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4274bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4289 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4290 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4297bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4305 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4308 if (!BaseOpcode->
MSAA)
4311 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4317 return DimInfo->
MSAA;
4323 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4324 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4325 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4335bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4344 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4347 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4355 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4359bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4364 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4367 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4370 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4377 Error(getOperandLoc(Operands, Src0Idx),
4378 "source operand must be either a VGPR or an inline constant");
4385bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4388 const MCInstrDesc &
Desc = MII.
get(Opcode);
4391 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4394 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4398 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4399 Error(getOperandLoc(Operands, Src2Idx),
4400 "inline constants are not allowed for this operand");
4407bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4415 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4416 if (BlgpIdx != -1) {
4417 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4418 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4428 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4429 Error(getOperandLoc(Operands, Src0Idx),
4430 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4435 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4436 Error(getOperandLoc(Operands, Src1Idx),
4437 "wrong register tuple size for blgp value " + Twine(BLGP));
4445 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4449 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4453 MCRegister Src2Reg = Src2.
getReg();
4455 if (Src2Reg == DstReg)
4460 .getSizeInBits() <= 128)
4463 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4464 Error(getOperandLoc(Operands, Src2Idx),
4465 "source 2 operand must not partially overlap with dst");
4472bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4476 case V_DIV_SCALE_F32_gfx6_gfx7:
4477 case V_DIV_SCALE_F32_vi:
4478 case V_DIV_SCALE_F32_gfx10:
4479 case V_DIV_SCALE_F64_gfx6_gfx7:
4480 case V_DIV_SCALE_F64_vi:
4481 case V_DIV_SCALE_F64_gfx10:
4487 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4488 AMDGPU::OpName::src2_modifiers,
4489 AMDGPU::OpName::src2_modifiers}) {
4500bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4508 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4517bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4524 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4532 case AMDGPU::V_SUBREV_F32_e32:
4533 case AMDGPU::V_SUBREV_F32_e64:
4534 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4535 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4536 case AMDGPU::V_SUBREV_F32_e32_vi:
4537 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4538 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4539 case AMDGPU::V_SUBREV_F32_e64_vi:
4541 case AMDGPU::V_SUBREV_CO_U32_e32:
4542 case AMDGPU::V_SUBREV_CO_U32_e64:
4543 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4544 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4546 case AMDGPU::V_SUBBREV_U32_e32:
4547 case AMDGPU::V_SUBBREV_U32_e64:
4548 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4549 case AMDGPU::V_SUBBREV_U32_e32_vi:
4550 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4551 case AMDGPU::V_SUBBREV_U32_e64_vi:
4553 case AMDGPU::V_SUBREV_U32_e32:
4554 case AMDGPU::V_SUBREV_U32_e64:
4555 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4556 case AMDGPU::V_SUBREV_U32_e32_vi:
4557 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4558 case AMDGPU::V_SUBREV_U32_e64_vi:
4560 case AMDGPU::V_SUBREV_F16_e32:
4561 case AMDGPU::V_SUBREV_F16_e64:
4562 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4563 case AMDGPU::V_SUBREV_F16_e32_vi:
4564 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4565 case AMDGPU::V_SUBREV_F16_e64_vi:
4567 case AMDGPU::V_SUBREV_U16_e32:
4568 case AMDGPU::V_SUBREV_U16_e64:
4569 case AMDGPU::V_SUBREV_U16_e32_vi:
4570 case AMDGPU::V_SUBREV_U16_e64_vi:
4572 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4573 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4574 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4576 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4577 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4579 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4580 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4582 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4583 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4585 case AMDGPU::V_LSHRREV_B32_e32:
4586 case AMDGPU::V_LSHRREV_B32_e64:
4587 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4588 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4589 case AMDGPU::V_LSHRREV_B32_e32_vi:
4590 case AMDGPU::V_LSHRREV_B32_e64_vi:
4591 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4592 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4594 case AMDGPU::V_ASHRREV_I32_e32:
4595 case AMDGPU::V_ASHRREV_I32_e64:
4596 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4597 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4598 case AMDGPU::V_ASHRREV_I32_e32_vi:
4599 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4600 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4601 case AMDGPU::V_ASHRREV_I32_e64_vi:
4603 case AMDGPU::V_LSHLREV_B32_e32:
4604 case AMDGPU::V_LSHLREV_B32_e64:
4605 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4606 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4607 case AMDGPU::V_LSHLREV_B32_e32_vi:
4608 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4609 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4610 case AMDGPU::V_LSHLREV_B32_e64_vi:
4612 case AMDGPU::V_LSHLREV_B16_e32:
4613 case AMDGPU::V_LSHLREV_B16_e64:
4614 case AMDGPU::V_LSHLREV_B16_e32_vi:
4615 case AMDGPU::V_LSHLREV_B16_e64_vi:
4616 case AMDGPU::V_LSHLREV_B16_gfx10:
4618 case AMDGPU::V_LSHRREV_B16_e32:
4619 case AMDGPU::V_LSHRREV_B16_e64:
4620 case AMDGPU::V_LSHRREV_B16_e32_vi:
4621 case AMDGPU::V_LSHRREV_B16_e64_vi:
4622 case AMDGPU::V_LSHRREV_B16_gfx10:
4624 case AMDGPU::V_ASHRREV_I16_e32:
4625 case AMDGPU::V_ASHRREV_I16_e64:
4626 case AMDGPU::V_ASHRREV_I16_e32_vi:
4627 case AMDGPU::V_ASHRREV_I16_e64_vi:
4628 case AMDGPU::V_ASHRREV_I16_gfx10:
4630 case AMDGPU::V_LSHLREV_B64_e64:
4631 case AMDGPU::V_LSHLREV_B64_gfx10:
4632 case AMDGPU::V_LSHLREV_B64_vi:
4634 case AMDGPU::V_LSHRREV_B64_e64:
4635 case AMDGPU::V_LSHRREV_B64_gfx10:
4636 case AMDGPU::V_LSHRREV_B64_vi:
4638 case AMDGPU::V_ASHRREV_I64_e64:
4639 case AMDGPU::V_ASHRREV_I64_gfx10:
4640 case AMDGPU::V_ASHRREV_I64_vi:
4642 case AMDGPU::V_PK_LSHLREV_B16:
4643 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4644 case AMDGPU::V_PK_LSHLREV_B16_vi:
4646 case AMDGPU::V_PK_LSHRREV_B16:
4647 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4648 case AMDGPU::V_PK_LSHRREV_B16_vi:
4649 case AMDGPU::V_PK_ASHRREV_I16:
4650 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4651 case AMDGPU::V_PK_ASHRREV_I16_vi:
4658bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4660 using namespace SIInstrFlags;
4661 const unsigned Opcode = Inst.
getOpcode();
4662 const MCInstrDesc &
Desc = MII.
get(Opcode);
4667 if ((
Desc.TSFlags & Enc) == 0)
4670 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4671 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4675 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4678 Error(getOperandLoc(Operands, SrcIdx),
4679 "lds_direct is not supported on this GPU");
4684 Error(getOperandLoc(Operands, SrcIdx),
4685 "lds_direct cannot be used with this instruction");
4689 if (SrcName != OpName::src0) {
4690 Error(getOperandLoc(Operands, SrcIdx),
4691 "lds_direct may be used as src0 only");
4700SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4701 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4702 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4703 if (
Op.isFlatOffset())
4704 return Op.getStartLoc();
4709bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4712 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4718 return validateFlatOffset(Inst, Operands);
4721 return validateSMEMOffset(Inst, Operands);
4727 const unsigned OffsetSize = 24;
4728 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4729 Error(getFlatOffsetLoc(Operands),
4730 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4731 "-bit unsigned offset for buffer ops");
4735 const unsigned OffsetSize = 16;
4736 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4737 Error(getFlatOffsetLoc(Operands),
4738 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4745bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4752 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4756 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4757 Error(getFlatOffsetLoc(Operands),
4758 "flat offset modifier is not supported on this GPU");
4765 bool AllowNegative =
4768 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4769 Error(getFlatOffsetLoc(Operands),
4770 Twine(
"expected a ") +
4771 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4772 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4779SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4781 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4782 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4783 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4784 return Op.getStartLoc();
4789bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4799 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4813 Error(getSMEMOffsetLoc(Operands),
4815 ?
"expected a 23-bit unsigned offset for buffer ops"
4816 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4817 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4818 :
"expected a 21-bit signed offset");
4823bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4826 const MCInstrDesc &
Desc = MII.
get(Opcode);
4830 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4831 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4833 const int OpIndices[] = { Src0Idx, Src1Idx };
4835 unsigned NumExprs = 0;
4836 unsigned NumLiterals = 0;
4839 for (
int OpIdx : OpIndices) {
4840 if (
OpIdx == -1)
break;
4846 std::optional<int64_t>
Imm;
4849 }
else if (MO.
isExpr()) {
4858 if (!
Imm.has_value()) {
4860 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4864 if (NumLiterals == 0 || LiteralValue !=
Value) {
4872 if (NumLiterals + NumExprs <= 1)
4875 Error(getOperandLoc(Operands, Src1Idx),
4876 "only one unique literal operand is allowed");
4880bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4883 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4893 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4894 if (OpSelIdx != -1) {
4898 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4899 if (OpSelHiIdx != -1) {
4908 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4918 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4919 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4920 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4921 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4923 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4924 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4930 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4932 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4942 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4943 if (Src2Idx != -1) {
4944 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4954bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4955 if (!hasTrue16Insts())
4957 const MCRegisterInfo *
MRI = getMRI();
4959 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4965 if (OpSelOpValue == 0)
4967 unsigned OpCount = 0;
4968 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4969 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4970 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4975 MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(
Op.getReg())) {
4977 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4978 if (OpSelOpIsHi != VGPRSuffixIsHi)
4987bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4988 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
5001 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
5012 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
5013 AMDGPU::OpName::src1_modifiers,
5014 AMDGPU::OpName::src2_modifiers};
5016 for (
unsigned i = 0; i < 3; ++i) {
5026bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5029 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5030 if (DppCtrlIdx >= 0) {
5037 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5038 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5039 :
"DP ALU dpp only supports row_newbcast");
5044 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5045 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5048 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5050 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5053 Error(getOperandLoc(Operands, Src1Idx),
5054 "invalid operand for instruction");
5058 Error(getInstLoc(Operands),
5059 "src1 immediate operand invalid for instruction");
5069bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5070 return (
Reg == AMDGPU::VCC && isWave64()) ||
5071 (
Reg == AMDGPU::VCC_LO && isWave32());
5075bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5078 const MCInstrDesc &
Desc = MII.
get(Opcode);
5079 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5081 !HasMandatoryLiteral && !
isVOPD(Opcode))
5086 std::optional<unsigned> LiteralOpIdx;
5089 for (
int OpIdx : OpIndices) {
5099 std::optional<int64_t>
Imm;
5105 bool IsAnotherLiteral =
false;
5106 if (!
Imm.has_value()) {
5108 IsAnotherLiteral =
true;
5109 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5114 HasMandatoryLiteral);
5120 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5122 "invalid operand for instruction");
5126 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5133 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5134 !getFeatureBits()[FeatureVOP3Literal]) {
5136 "literal operands are not supported");
5140 if (LiteralOpIdx && IsAnotherLiteral) {
5141 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5142 getOperandLoc(Operands, *LiteralOpIdx)),
5143 "only one unique literal operand is allowed");
5147 if (IsAnotherLiteral)
5148 LiteralOpIdx =
OpIdx;
5171bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5179 ? AMDGPU::OpName::data0
5180 : AMDGPU::OpName::vdata;
5182 const MCRegisterInfo *
MRI = getMRI();
5188 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5192 auto FB = getFeatureBits();
5193 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5194 if (DataAreg < 0 || DstAreg < 0)
5196 return DstAreg == DataAreg;
5199 return DstAreg < 1 && DataAreg < 1;
5202bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5203 auto FB = getFeatureBits();
5204 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5208 const MCRegisterInfo *
MRI = getMRI();
5211 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5214 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5218 case AMDGPU::DS_LOAD_TR6_B96:
5219 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5223 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5224 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5228 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5229 if (VAddrIdx != -1) {
5231 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5232 if ((
Sub - AMDGPU::VGPR0) & 1)
5237 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5238 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5243 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5244 const MCRegisterClass &AGPR32 =
MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
5250 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5263SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5264 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5265 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5267 return Op.getStartLoc();
5272bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5275 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5278 SMLoc BLGPLoc = getBLGPLoc(Operands);
5281 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5282 auto FB = getFeatureBits();
5283 bool UsesNeg =
false;
5284 if (FB[AMDGPU::FeatureGFX940Insts]) {
5286 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5287 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5288 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5289 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5294 if (IsNeg == UsesNeg)
5298 UsesNeg ?
"invalid modifier: blgp is not supported"
5299 :
"invalid modifier: neg is not supported");
5304bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5310 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5311 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5312 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5313 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5316 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5319 if (
Reg == AMDGPU::SGPR_NULL)
5322 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5326bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5332 return validateGWS(Inst, Operands);
5337 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5342 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5343 Error(S,
"gds modifier is not supported on this GPU");
5351bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5353 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5357 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5358 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5361 const MCRegisterInfo *
MRI = getMRI();
5362 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5364 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5367 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5369 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5376bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5379 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5380 AMDGPU::OpName::cpol);
5388 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5391 Error(S,
"scale_offset is not supported on this GPU");
5394 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5397 Error(S,
"nv is not supported on this GPU");
5402 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5405 Error(S,
"scale_offset is not supported for this instruction");
5409 return validateTHAndScopeBits(Inst, Operands, CPol);
5414 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5415 Error(S,
"cache policy is not supported for SMRD instructions");
5419 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5428 if (!(TSFlags & AllowSCCModifier)) {
5429 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5433 "scc modifier is not supported for this instruction on this GPU");
5444 :
"instruction must use glc");
5449 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5452 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5454 :
"instruction must not use glc");
5462bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5464 const unsigned CPol) {
5468 const unsigned Opcode = Inst.
getOpcode();
5469 const MCInstrDesc &TID = MII.
get(Opcode);
5472 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5480 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5488 return PrintError(
"invalid th value for SMEM instruction");
5495 return PrintError(
"scope and th combination is not valid");
5501 return PrintError(
"invalid th value for atomic instructions");
5504 return PrintError(
"invalid th value for store instructions");
5507 return PrintError(
"invalid th value for load instructions");
5513bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5516 if (
Desc.mayStore() &&
5518 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5519 if (Loc != getInstLoc(Operands)) {
5520 Error(Loc,
"TFE modifier has no meaning for store instructions");
5528bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5534 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5535 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5539 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5547 static const char *FmtNames[] = {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
5548 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
5551 Error(getOperandLoc(Operands, SrcIdx),
5552 "wrong register tuple size for " + Twine(FmtNames[Fmt]));
5556 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5557 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5560bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5562 if (!validateLdsDirect(Inst, Operands))
5564 if (!validateTrue16OpSel(Inst)) {
5565 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5566 "op_sel operand conflicts with 16-bit operand suffix");
5569 if (!validateSOPLiteral(Inst, Operands))
5571 if (!validateVOPLiteral(Inst, Operands)) {
5574 if (!validateConstantBusLimitations(Inst, Operands)) {
5577 if (!validateVOPD(Inst, Operands)) {
5580 if (!validateIntClampSupported(Inst)) {
5581 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5582 "integer clamping is not supported on this GPU");
5585 if (!validateOpSel(Inst)) {
5586 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5587 "invalid op_sel operand");
5590 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5591 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5592 "invalid neg_lo operand");
5595 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5596 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5597 "invalid neg_hi operand");
5600 if (!validateDPP(Inst, Operands)) {
5604 if (!validateMIMGD16(Inst)) {
5605 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5606 "d16 modifier is not supported on this GPU");
5609 if (!validateMIMGDim(Inst, Operands)) {
5610 Error(IDLoc,
"missing dim operand");
5613 if (!validateTensorR128(Inst)) {
5614 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5615 "instruction must set modifier r128=0");
5618 if (!validateMIMGMSAA(Inst)) {
5619 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5620 "invalid dim; must be MSAA type");
5623 if (!validateMIMGDataSize(Inst, IDLoc)) {
5626 if (!validateMIMGAddrSize(Inst, IDLoc))
5628 if (!validateMIMGAtomicDMask(Inst)) {
5629 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5630 "invalid atomic image dmask");
5633 if (!validateMIMGGatherDMask(Inst)) {
5634 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5635 "invalid image_gather dmask: only one bit must be set");
5638 if (!validateMovrels(Inst, Operands)) {
5641 if (!validateOffset(Inst, Operands)) {
5644 if (!validateMAIAccWrite(Inst, Operands)) {
5647 if (!validateMAISrc2(Inst, Operands)) {
5650 if (!validateMFMA(Inst, Operands)) {
5653 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5657 if (!validateAGPRLdSt(Inst)) {
5658 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5659 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5660 :
"invalid register class: agpr loads and stores not supported on this GPU"
5664 if (!validateVGPRAlign(Inst)) {
5666 "invalid register class: vgpr tuples must be 64 bit aligned");
5669 if (!validateDS(Inst, Operands)) {
5673 if (!validateBLGP(Inst, Operands)) {
5677 if (!validateDivScale(Inst)) {
5678 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5681 if (!validateWaitCnt(Inst, Operands)) {
5684 if (!validateTFE(Inst, Operands)) {
5687 if (!validateWMMA(Inst, Operands)) {
5696 unsigned VariantID = 0);
5700 unsigned VariantID);
5702bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5707bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5708 const FeatureBitset &FBS,
5709 ArrayRef<unsigned> Variants) {
5710 for (
auto Variant : Variants) {
5718bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5720 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5723 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5728 getParser().clearPendingErrors();
5732 StringRef VariantName = getMatchedVariantName();
5733 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5736 " variant of this instruction is not supported"));
5740 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5741 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5743 FeatureBitset FeaturesWS32 = getFeatureBits();
5744 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5745 .
flip(AMDGPU::FeatureWavefrontSize32);
5746 FeatureBitset AvailableFeaturesWS32 =
5747 ComputeAvailableFeatures(FeaturesWS32);
5749 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5750 return Error(IDLoc,
"instruction requires wavesize=32");
5754 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5755 return Error(IDLoc,
"instruction not supported on this GPU");
5760 return Error(IDLoc,
"invalid instruction" + Suggestion);
5766 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5767 if (
Op.isToken() && InvalidOprIdx > 1) {
5768 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5769 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5774bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5777 uint64_t &ErrorInfo,
5778 bool MatchingInlineAsm) {
5781 unsigned Result = Match_Success;
5782 for (
auto Variant : getMatchedVariants()) {
5784 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5789 if (R == Match_Success || R == Match_MissingFeature ||
5790 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5791 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5792 Result != Match_MissingFeature)) {
5796 if (R == Match_Success)
5800 if (Result == Match_Success) {
5801 if (!validateInstruction(Inst, IDLoc, Operands)) {
5808 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5809 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5815 case Match_MissingFeature:
5819 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5821 case Match_InvalidOperand: {
5822 SMLoc ErrorLoc = IDLoc;
5823 if (ErrorInfo != ~0ULL) {
5824 if (ErrorInfo >= Operands.
size()) {
5825 return Error(IDLoc,
"too few operands for instruction");
5827 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5828 if (ErrorLoc == SMLoc())
5832 return Error(ErrorLoc,
"invalid VOPDY instruction");
5834 return Error(ErrorLoc,
"invalid operand for instruction");
5837 case Match_MnemonicFail:
5843bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5848 if (getParser().parseAbsoluteExpression(Tmp)) {
5851 Ret =
static_cast<uint32_t
>(Tmp);
5855bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5856 if (!getSTI().getTargetTriple().isAMDGCN())
5857 return TokError(
"directive only supported for amdgcn architecture");
5859 std::string TargetIDDirective;
5860 SMLoc TargetStart = getTok().getLoc();
5861 if (getParser().parseEscapedString(TargetIDDirective))
5864 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5865 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5866 return getParser().Error(TargetRange.
Start,
5867 (Twine(
".amdgcn_target directive's target id ") +
5868 Twine(TargetIDDirective) +
5869 Twine(
" does not match the specified target id ") +
5870 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5875bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5879bool AMDGPUAsmParser::calculateGPRBlocks(
5880 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5881 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5882 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5883 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5884 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5890 const MCExpr *
NumSGPRs = NextFreeSGPR;
5891 int64_t EvaluatedSGPRs;
5896 unsigned MaxAddressableNumSGPRs =
5899 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5900 !Features.
test(FeatureSGPRInitBug) &&
5901 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5902 return OutOfRangeError(SGPRRange);
5904 const MCExpr *ExtraSGPRs =
5908 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5909 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5910 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5911 return OutOfRangeError(SGPRRange);
5913 if (Features.
test(FeatureSGPRInitBug))
5920 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5921 unsigned Granule) ->
const MCExpr * {
5925 const MCExpr *AlignToGPR =
5927 const MCExpr *DivGPR =
5933 VGPRBlocks = GetNumGPRBlocks(
5942bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5943 if (!getSTI().getTargetTriple().isAMDGCN())
5944 return TokError(
"directive only supported for amdgcn architecture");
5947 return TokError(
"directive only supported for amdhsa OS");
5949 StringRef KernelName;
5950 if (getParser().parseIdentifier(KernelName))
5953 AMDGPU::MCKernelDescriptor KD =
5965 const MCExpr *NextFreeVGPR = ZeroExpr;
5967 const MCExpr *NamedBarCnt = ZeroExpr;
5968 uint64_t SharedVGPRCount = 0;
5969 uint64_t PreloadLength = 0;
5970 uint64_t PreloadOffset = 0;
5972 const MCExpr *NextFreeSGPR = ZeroExpr;
5975 unsigned ImpliedUserSGPRCount = 0;
5979 std::optional<unsigned> ExplicitUserSGPRCount;
5980 const MCExpr *ReserveVCC = OneExpr;
5981 const MCExpr *ReserveFlatScr = OneExpr;
5982 std::optional<bool> EnableWavefrontSize32;
5988 SMRange IDRange = getTok().getLocRange();
5989 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5992 if (
ID ==
".end_amdhsa_kernel")
5996 return TokError(
".amdhsa_ directives cannot be repeated");
5998 SMLoc ValStart = getLoc();
5999 const MCExpr *ExprVal;
6000 if (getParser().parseExpression(ExprVal))
6002 SMLoc ValEnd = getLoc();
6003 SMRange ValRange = SMRange(ValStart, ValEnd);
6006 uint64_t Val = IVal;
6007 bool EvaluatableExpr;
6008 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6010 return OutOfRangeError(ValRange);
6014#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6015 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6016 return OutOfRangeError(RANGE); \
6017 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6022#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6024 return Error(IDRange.Start, "directive should have resolvable expression", \
6027 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6030 return OutOfRangeError(ValRange);
6032 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6035 return OutOfRangeError(ValRange);
6037 }
else if (
ID ==
".amdhsa_kernarg_size") {
6039 return OutOfRangeError(ValRange);
6041 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6043 ExplicitUserSGPRCount = Val;
6044 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6048 "directive is not supported with architected flat scratch",
6051 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6054 ImpliedUserSGPRCount += 4;
6055 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6058 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6061 return OutOfRangeError(ValRange);
6065 ImpliedUserSGPRCount += Val;
6066 PreloadLength = Val;
6068 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6071 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6074 return OutOfRangeError(ValRange);
6078 PreloadOffset = Val;
6079 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6082 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6085 ImpliedUserSGPRCount += 2;
6086 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6089 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6092 ImpliedUserSGPRCount += 2;
6093 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6096 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6099 ImpliedUserSGPRCount += 2;
6100 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6103 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6106 ImpliedUserSGPRCount += 2;
6107 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6110 "directive is not supported with architected flat scratch",
6114 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6117 ImpliedUserSGPRCount += 2;
6118 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6121 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6124 ImpliedUserSGPRCount += 1;
6125 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6127 if (IVersion.
Major < 10)
6128 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6129 EnableWavefrontSize32 = Val;
6131 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6133 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6135 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6137 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6140 "directive is not supported with architected flat scratch",
6143 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6145 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6149 "directive is not supported without architected flat scratch",
6152 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6154 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6156 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6158 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6160 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6162 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6164 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6166 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6168 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6170 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6172 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6174 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6175 VGPRRange = ValRange;
6176 NextFreeVGPR = ExprVal;
6177 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6178 SGPRRange = ValRange;
6179 NextFreeSGPR = ExprVal;
6180 }
else if (
ID ==
".amdhsa_accum_offset") {
6182 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6183 AccumOffset = ExprVal;
6184 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6186 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6187 NamedBarCnt = ExprVal;
6188 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6190 return OutOfRangeError(ValRange);
6191 ReserveVCC = ExprVal;
6192 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6193 if (IVersion.
Major < 7)
6194 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6197 "directive is not supported with architected flat scratch",
6200 return OutOfRangeError(ValRange);
6201 ReserveFlatScr = ExprVal;
6202 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6203 if (IVersion.
Major < 8)
6204 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6206 return OutOfRangeError(ValRange);
6207 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6208 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6210 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6212 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6214 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6216 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6218 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6220 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6222 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6224 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6226 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6227 if (IVersion.
Major >= 12)
6228 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6230 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6232 }
else if (
ID ==
".amdhsa_ieee_mode") {
6233 if (IVersion.
Major >= 12)
6234 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6236 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6238 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6239 if (IVersion.
Major < 9)
6240 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6242 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6244 }
else if (
ID ==
".amdhsa_tg_split") {
6246 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6249 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6252 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6254 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6256 }
else if (
ID ==
".amdhsa_memory_ordered") {
6257 if (IVersion.
Major < 10)
6258 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6260 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6262 }
else if (
ID ==
".amdhsa_forward_progress") {
6263 if (IVersion.
Major < 10)
6264 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6266 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6268 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6270 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6271 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6273 SharedVGPRCount = Val;
6275 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6277 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6278 if (IVersion.
Major < 11)
6279 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6280 if (IVersion.
Major == 11) {
6282 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6286 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6289 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6292 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6294 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6296 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6298 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6301 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6303 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6305 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6307 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6309 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6311 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6313 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6315 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6317 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6319 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6320 if (IVersion.
Major < 12)
6321 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6323 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6326 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6329#undef PARSE_BITS_ENTRY
6332 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6333 return TokError(
".amdhsa_next_free_vgpr directive is required");
6335 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6336 return TokError(
".amdhsa_next_free_sgpr directive is required");
6338 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6343 if (PreloadLength) {
6349 const MCExpr *VGPRBlocks;
6350 const MCExpr *SGPRBlocks;
6351 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6352 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6353 EnableWavefrontSize32, NextFreeVGPR,
6354 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6358 int64_t EvaluatedVGPRBlocks;
6359 bool VGPRBlocksEvaluatable =
6360 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6361 if (VGPRBlocksEvaluatable &&
6363 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6364 return OutOfRangeError(VGPRRange);
6368 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6369 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6371 int64_t EvaluatedSGPRBlocks;
6372 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6374 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6375 return OutOfRangeError(SGPRRange);
6378 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6379 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6381 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6382 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6383 "enabled user SGPRs");
6387 return TokError(
"too many user SGPRs enabled");
6391 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6392 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6396 return TokError(
"too many user SGPRs enabled");
6400 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6401 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6406 return TokError(
"Kernarg size should be resolvable");
6407 uint64_t kernarg_size = IVal;
6408 if (PreloadLength && kernarg_size &&
6409 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6410 return TokError(
"Kernarg preload length + offset is larger than the "
6411 "kernarg segment size");
6414 if (!Seen.
contains(
".amdhsa_accum_offset"))
6415 return TokError(
".amdhsa_accum_offset directive is required");
6416 int64_t EvaluatedAccum;
6417 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6418 uint64_t UEvaluatedAccum = EvaluatedAccum;
6419 if (AccumEvaluatable &&
6420 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6421 return TokError(
"accum_offset should be in range [4..256] in "
6424 int64_t EvaluatedNumVGPR;
6425 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6428 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6429 return TokError(
"accum_offset exceeds total VGPR allocation");
6435 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6436 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6442 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6443 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6446 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6448 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6449 return TokError(
"shared_vgpr_count directive not valid on "
6450 "wavefront size 32");
6453 if (VGPRBlocksEvaluatable &&
6454 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6456 return TokError(
"shared_vgpr_count*2 + "
6457 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6462 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6463 NextFreeVGPR, NextFreeSGPR,
6464 ReserveVCC, ReserveFlatScr);
6468bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6470 if (ParseAsAbsoluteExpression(
Version))
6473 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6477bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6478 AMDGPUMCKernelCodeT &
C) {
6481 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6482 Parser.eatToEndOfStatement();
6486 SmallString<40> ErrStr;
6487 raw_svector_ostream Err(ErrStr);
6488 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6489 return TokError(Err.
str());
6493 if (
ID ==
"enable_wavefront_size32") {
6496 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6498 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6501 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6505 if (
ID ==
"wavefront_size") {
6506 if (
C.wavefront_size == 5) {
6508 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6510 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6511 }
else if (
C.wavefront_size == 6) {
6513 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6520bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6521 AMDGPUMCKernelCodeT KernelCode;
6530 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6533 if (
ID ==
".end_amd_kernel_code_t")
6536 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6541 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6546bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6547 StringRef KernelName;
6548 if (!parseId(KernelName,
"expected symbol name"))
6551 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6558bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6559 if (!getSTI().getTargetTriple().isAMDGCN()) {
6560 return Error(getLoc(),
6561 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6565 auto TargetIDDirective = getLexer().getTok().getStringContents();
6566 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6567 return Error(getParser().getTok().getLoc(),
"target id must match options");
6569 getTargetStreamer().EmitISAVersion();
6575bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6578 std::string HSAMetadataString;
6583 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6584 return Error(getLoc(),
"invalid HSA metadata");
6591bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6592 const char *AssemblerDirectiveEnd,
6593 std::string &CollectString) {
6595 raw_string_ostream CollectStream(CollectString);
6597 getLexer().setSkipSpace(
false);
6599 bool FoundEnd =
false;
6602 CollectStream << getTokenStr();
6606 if (trySkipId(AssemblerDirectiveEnd)) {
6611 CollectStream << Parser.parseStringToEndOfStatement()
6612 <<
getContext().getAsmInfo()->getSeparatorString();
6614 Parser.eatToEndOfStatement();
6617 getLexer().setSkipSpace(
true);
6620 return TokError(Twine(
"expected directive ") +
6621 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6628bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6634 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6635 if (!PALMetadata->setFromString(
String))
6636 return Error(getLoc(),
"invalid PAL metadata");
6641bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6643 return Error(getLoc(),
6645 "not available on non-amdpal OSes")).str());
6648 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6649 PALMetadata->setLegacy();
6652 if (ParseAsAbsoluteExpression(
Key)) {
6653 return TokError(Twine(
"invalid value in ") +
6657 return TokError(Twine(
"expected an even number of values in ") +
6660 if (ParseAsAbsoluteExpression(
Value)) {
6661 return TokError(Twine(
"invalid value in ") +
6664 PALMetadata->setRegister(
Key,
Value);
6673bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6674 if (getParser().checkForValidSection())
6678 SMLoc NameLoc = getLoc();
6679 if (getParser().parseIdentifier(Name))
6680 return TokError(
"expected identifier in directive");
6683 if (getParser().parseComma())
6689 SMLoc SizeLoc = getLoc();
6690 if (getParser().parseAbsoluteExpression(
Size))
6693 return Error(SizeLoc,
"size must be non-negative");
6694 if (
Size > LocalMemorySize)
6695 return Error(SizeLoc,
"size is too large");
6697 int64_t Alignment = 4;
6699 SMLoc AlignLoc = getLoc();
6700 if (getParser().parseAbsoluteExpression(Alignment))
6703 return Error(AlignLoc,
"alignment must be a power of two");
6708 if (Alignment >= 1u << 31)
6709 return Error(AlignLoc,
"alignment is too large");
6715 Symbol->redefineIfPossible();
6716 if (!
Symbol->isUndefined())
6717 return Error(NameLoc,
"invalid symbol redefinition");
6719 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6723bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6724 StringRef IDVal = DirectiveID.
getString();
6727 if (IDVal ==
".amdhsa_kernel")
6728 return ParseDirectiveAMDHSAKernel();
6730 if (IDVal ==
".amdhsa_code_object_version")
6731 return ParseDirectiveAMDHSACodeObjectVersion();
6735 return ParseDirectiveHSAMetadata();
6737 if (IDVal ==
".amd_kernel_code_t")
6738 return ParseDirectiveAMDKernelCodeT();
6740 if (IDVal ==
".amdgpu_hsa_kernel")
6741 return ParseDirectiveAMDGPUHsaKernel();
6743 if (IDVal ==
".amd_amdgpu_isa")
6744 return ParseDirectiveISAVersion();
6748 Twine(
" directive is "
6749 "not available on non-amdhsa OSes"))
6754 if (IDVal ==
".amdgcn_target")
6755 return ParseDirectiveAMDGCNTarget();
6757 if (IDVal ==
".amdgpu_lds")
6758 return ParseDirectiveAMDGPULDS();
6761 return ParseDirectivePALMetadataBegin();
6764 return ParseDirectivePALMetadata();
6769bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
6771 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
6775 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
6776 return hasSGPR104_SGPR105();
6779 case SRC_SHARED_BASE_LO:
6780 case SRC_SHARED_BASE:
6781 case SRC_SHARED_LIMIT_LO:
6782 case SRC_SHARED_LIMIT:
6783 case SRC_PRIVATE_BASE_LO:
6784 case SRC_PRIVATE_BASE:
6785 case SRC_PRIVATE_LIMIT_LO:
6786 case SRC_PRIVATE_LIMIT:
6788 case SRC_FLAT_SCRATCH_BASE_LO:
6789 case SRC_FLAT_SCRATCH_BASE_HI:
6790 return hasGloballyAddressableScratch();
6791 case SRC_POPS_EXITING_WAVE_ID:
6803 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6832 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
6833 return hasSGPR102_SGPR103();
6838ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6841 ParseStatus Res = parseVOPD(Operands);
6846 Res = MatchOperandParserImpl(Operands, Mnemonic);
6858 SMLoc LBraceLoc = getLoc();
6863 auto Loc = getLoc();
6864 Res = parseReg(Operands);
6866 Error(Loc,
"expected a register");
6870 RBraceLoc = getLoc();
6875 "expected a comma or a closing square bracket"))
6879 if (Operands.
size() - Prefix > 1) {
6881 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6882 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6888 return parseRegOrImm(Operands);
6891StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6893 setForcedEncodingSize(0);
6894 setForcedDPP(
false);
6895 setForcedSDWA(
false);
6897 if (
Name.consume_back(
"_e64_dpp")) {
6899 setForcedEncodingSize(64);
6902 if (
Name.consume_back(
"_e64")) {
6903 setForcedEncodingSize(64);
6906 if (
Name.consume_back(
"_e32")) {
6907 setForcedEncodingSize(32);
6910 if (
Name.consume_back(
"_dpp")) {
6914 if (
Name.consume_back(
"_sdwa")) {
6915 setForcedSDWA(
true);
6923 unsigned VariantID);
6929 Name = parseMnemonicSuffix(Name);
6935 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6937 bool IsMIMG = Name.starts_with(
"image_");
6940 OperandMode
Mode = OperandMode_Default;
6942 Mode = OperandMode_NSA;
6946 checkUnsupportedInstruction(Name, NameLoc);
6947 if (!Parser.hasPendingError()) {
6950 :
"not a valid operand.";
6951 Error(getLoc(), Msg);
6970ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6973 if (!trySkipId(Name))
6976 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6980ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6989ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6990 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6991 std::function<
bool(int64_t &)> ConvertResult) {
6995 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
6999 if (ConvertResult && !ConvertResult(
Value)) {
7000 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7003 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7007ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7008 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7009 bool (*ConvertResult)(int64_t &)) {
7018 const unsigned MaxSize = 4;
7022 for (
int I = 0; ; ++
I) {
7024 SMLoc Loc = getLoc();
7028 if (
Op != 0 &&
Op != 1)
7029 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7036 if (
I + 1 == MaxSize)
7037 return Error(getLoc(),
"expected a closing square bracket");
7043 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7047ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7049 AMDGPUOperand::ImmTy ImmTy) {
7053 if (trySkipId(Name)) {
7055 }
else if (trySkipId(
"no", Name)) {
7062 return Error(S,
"r128 modifier is not supported on this GPU");
7063 if (Name ==
"a16" && !
hasA16())
7064 return Error(S,
"a16 modifier is not supported on this GPU");
7066 if (Bit == 0 && Name ==
"gds") {
7067 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7069 return Error(S,
"nogds is not allowed");
7072 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7073 ImmTy = AMDGPUOperand::ImmTyR128A16;
7075 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7079unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7080 bool &Disabling)
const {
7081 Disabling =
Id.consume_front(
"no");
7084 return StringSwitch<unsigned>(Id)
7091 return StringSwitch<unsigned>(Id)
7099ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7101 SMLoc StringLoc = getLoc();
7103 int64_t CPolVal = 0;
7112 ResTH = parseTH(Operands, TH);
7123 ResScope = parseScope(Operands, Scope);
7136 if (trySkipId(
"nv")) {
7140 }
else if (trySkipId(
"no",
"nv")) {
7147 if (trySkipId(
"scale_offset")) {
7151 }
else if (trySkipId(
"no",
"scale_offset")) {
7164 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7165 AMDGPUOperand::ImmTyCPol));
7169 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7170 SMLoc OpLoc = getLoc();
7171 unsigned Enabled = 0, Seen = 0;
7175 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7182 return Error(S,
"dlc modifier is not supported on this GPU");
7185 return Error(S,
"scc modifier is not supported on this GPU");
7188 return Error(S,
"duplicate cache policy modifier");
7200 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7204ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7209 ParseStatus Res = parseStringOrIntWithPrefix(
7210 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7219ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7224 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7228 if (
Value ==
"TH_DEFAULT")
7230 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7231 Value ==
"TH_LOAD_NT_WB") {
7232 return Error(StringLoc,
"invalid th value");
7233 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7235 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7237 }
else if (
Value.consume_front(
"TH_STORE_")) {
7240 return Error(StringLoc,
"invalid th value");
7243 if (
Value ==
"BYPASS")
7248 TH |= StringSwitch<int64_t>(
Value)
7258 .Default(0xffffffff);
7260 TH |= StringSwitch<int64_t>(
Value)
7271 .Default(0xffffffff);
7274 if (TH == 0xffffffff)
7275 return Error(StringLoc,
"invalid th value");
7282 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7283 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7284 std::optional<unsigned> InsertAt = std::nullopt) {
7285 auto i = OptionalIdx.find(ImmT);
7286 if (i != OptionalIdx.end()) {
7287 unsigned Idx = i->second;
7288 const AMDGPUOperand &
Op =
7289 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7293 Op.addImmOperands(Inst, 1);
7295 if (InsertAt.has_value())
7302ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7308 StringLoc = getLoc();
7313ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7314 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7319 SMLoc StringLoc = getLoc();
7323 Value = getTokenStr();
7327 if (
Value == Ids[IntVal])
7332 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7333 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7338ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7339 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7340 AMDGPUOperand::ImmTy
Type) {
7344 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7346 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7355bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7359 SMLoc Loc = getLoc();
7361 auto Res = parseIntWithPrefix(Pref, Val);
7367 if (Val < 0 || Val > MaxVal) {
7368 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7376ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7377 AMDGPUOperand::ImmTy ImmTy) {
7378 const char *Pref =
"index_key";
7380 SMLoc Loc = getLoc();
7381 auto Res = parseIntWithPrefix(Pref, ImmVal);
7385 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7386 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7387 (ImmVal < 0 || ImmVal > 1))
7388 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7390 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7391 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7393 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7397ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7398 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7401ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7402 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7405ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7406 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7409ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7411 AMDGPUOperand::ImmTy
Type) {
7412 return parseStringOrIntWithPrefix(Operands, Name,
7413 {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
7414 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
7419ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7420 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7421 AMDGPUOperand::ImmTyMatrixAFMT);
7424ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7425 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7426 AMDGPUOperand::ImmTyMatrixBFMT);
7429ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7431 AMDGPUOperand::ImmTy
Type) {
7432 return parseStringOrIntWithPrefix(
7433 Operands, Name, {
"MATRIX_SCALE_ROW0",
"MATRIX_SCALE_ROW1"},
Type);
7436ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7437 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7438 AMDGPUOperand::ImmTyMatrixAScale);
7441ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7442 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7443 AMDGPUOperand::ImmTyMatrixBScale);
7446ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7448 AMDGPUOperand::ImmTy
Type) {
7449 return parseStringOrIntWithPrefix(
7451 {
"MATRIX_SCALE_FMT_E8",
"MATRIX_SCALE_FMT_E5M3",
"MATRIX_SCALE_FMT_E4M3"},
7455ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7456 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7457 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7460ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7461 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7462 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7467ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7468 using namespace llvm::AMDGPU::MTBUFFormat;
7474 for (
int I = 0;
I < 2; ++
I) {
7475 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7478 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7483 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7489 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7492 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7493 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7499ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7500 using namespace llvm::AMDGPU::MTBUFFormat;
7504 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7507 if (Fmt == UFMT_UNDEF)
7514bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7516 StringRef FormatStr,
7518 using namespace llvm::AMDGPU::MTBUFFormat;
7522 if (
Format != DFMT_UNDEF) {
7528 if (
Format != NFMT_UNDEF) {
7533 Error(Loc,
"unsupported format");
7537ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7540 using namespace llvm::AMDGPU::MTBUFFormat;
7544 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7549 SMLoc Loc = getLoc();
7550 if (!parseId(Str,
"expected a format string") ||
7551 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7553 if (Dfmt == DFMT_UNDEF)
7554 return Error(Loc,
"duplicate numeric format");
7555 if (Nfmt == NFMT_UNDEF)
7556 return Error(Loc,
"duplicate data format");
7559 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7560 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7564 if (Ufmt == UFMT_UNDEF)
7565 return Error(FormatLoc,
"unsupported format");
7574ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7577 using namespace llvm::AMDGPU::MTBUFFormat;
7580 if (Id == UFMT_UNDEF)
7584 return Error(Loc,
"unified format is not supported on this GPU");
7590ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7591 using namespace llvm::AMDGPU::MTBUFFormat;
7592 SMLoc Loc = getLoc();
7597 return Error(Loc,
"out of range format");
7602ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7603 using namespace llvm::AMDGPU::MTBUFFormat;
7609 StringRef FormatStr;
7610 SMLoc Loc = getLoc();
7611 if (!parseId(FormatStr,
"expected a format string"))
7614 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7616 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7626 return parseNumericFormat(
Format);
7629ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7630 using namespace llvm::AMDGPU::MTBUFFormat;
7634 SMLoc Loc = getLoc();
7644 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7656 Res = parseRegOrImm(Operands);
7663 Res = parseSymbolicOrNumericFormat(
Format);
7668 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7669 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7676 return Error(getLoc(),
"duplicate format");
7680ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7682 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7684 Res = parseIntWithPrefix(
"inst_offset", Operands,
7685 AMDGPUOperand::ImmTyInstOffset);
7690ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7692 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7694 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7698ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7700 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7703 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7712void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7713 OptionalImmIndexMap OptionalIdx;
7715 unsigned OperandIdx[4];
7716 unsigned EnMask = 0;
7719 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7720 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7725 OperandIdx[SrcIdx] = Inst.
size();
7726 Op.addRegOperands(Inst, 1);
7733 OperandIdx[SrcIdx] = Inst.
size();
7739 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7740 Op.addImmOperands(Inst, 1);
7744 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7748 OptionalIdx[
Op.getImmTy()] = i;
7754 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7761 for (
auto i = 0; i < SrcIdx; ++i) {
7763 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7788 IntVal =
encode(ISA, IntVal, CntVal);
7789 if (CntVal !=
decode(ISA, IntVal)) {
7791 IntVal =
encode(ISA, IntVal, -1);
7799bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7801 SMLoc CntLoc = getLoc();
7802 StringRef CntName = getTokenStr();
7809 SMLoc ValLoc = getLoc();
7818 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7820 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7822 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7825 Error(CntLoc,
"invalid counter name " + CntName);
7830 Error(ValLoc,
"too large value for " + CntName);
7839 Error(getLoc(),
"expected a counter name");
7847ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7854 if (!parseCnt(Waitcnt))
7862 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7866bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7867 SMLoc FieldLoc = getLoc();
7868 StringRef FieldName = getTokenStr();
7873 SMLoc ValueLoc = getLoc();
7880 if (FieldName ==
"instid0") {
7882 }
else if (FieldName ==
"instskip") {
7884 }
else if (FieldName ==
"instid1") {
7887 Error(FieldLoc,
"invalid field name " + FieldName);
7906 .Case(
"VALU_DEP_1", 1)
7907 .Case(
"VALU_DEP_2", 2)
7908 .Case(
"VALU_DEP_3", 3)
7909 .Case(
"VALU_DEP_4", 4)
7910 .Case(
"TRANS32_DEP_1", 5)
7911 .Case(
"TRANS32_DEP_2", 6)
7912 .Case(
"TRANS32_DEP_3", 7)
7913 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7914 .Case(
"SALU_CYCLE_1", 9)
7915 .Case(
"SALU_CYCLE_2", 10)
7916 .Case(
"SALU_CYCLE_3", 11)
7924 Delay |=
Value << Shift;
7928ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7934 if (!parseDelay(Delay))
7942 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7947AMDGPUOperand::isSWaitCnt()
const {
7951bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7957void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7958 StringRef DepCtrName) {
7961 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7964 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7967 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7970 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7977bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7979 using namespace llvm::AMDGPU::DepCtr;
7981 SMLoc DepCtrLoc = getLoc();
7982 StringRef DepCtrName = getTokenStr();
7992 unsigned PrevOprMask = UsedOprMask;
7993 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7996 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8005 Error(getLoc(),
"expected a counter name");
8010 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
8011 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8015ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
8016 using namespace llvm::AMDGPU::DepCtr;
8019 SMLoc Loc = getLoc();
8022 unsigned UsedOprMask = 0;
8024 if (!parseDepCtr(DepCtr, UsedOprMask))
8032 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8036bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8042ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8044 OperandInfoTy &Width) {
8045 using namespace llvm::AMDGPU::Hwreg;
8051 HwReg.Loc = getLoc();
8054 HwReg.IsSymbolic =
true;
8056 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8064 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8074 Width.Loc = getLoc();
8082ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8083 using namespace llvm::AMDGPU::Hwreg;
8086 SMLoc Loc = getLoc();
8088 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8090 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8091 HwregOffset::Default);
8092 struct : StructuredOpField {
8093 using StructuredOpField::StructuredOpField;
8094 bool validate(AMDGPUAsmParser &Parser)
const override {
8096 return Error(Parser,
"only values from 1 to 32 are legal");
8099 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8100 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8103 Res = parseHwregFunc(HwReg,
Offset, Width);
8106 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8108 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8112 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8119 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8121 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8125bool AMDGPUOperand::isHwreg()
const {
8126 return isImmTy(ImmTyHwreg);
8134AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8136 OperandInfoTy &Stream) {
8137 using namespace llvm::AMDGPU::SendMsg;
8142 Msg.IsSymbolic =
true;
8144 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8149 Op.IsDefined =
true;
8152 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8155 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8160 Stream.IsDefined =
true;
8161 Stream.Loc = getLoc();
8171AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8172 const OperandInfoTy &
Op,
8173 const OperandInfoTy &Stream) {
8174 using namespace llvm::AMDGPU::SendMsg;
8179 bool Strict = Msg.IsSymbolic;
8183 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8188 Error(Msg.Loc,
"invalid message id");
8194 Error(
Op.Loc,
"message does not support operations");
8196 Error(Msg.Loc,
"missing message operation");
8202 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8204 Error(
Op.Loc,
"invalid operation id");
8209 Error(Stream.Loc,
"message operation does not support streams");
8213 Error(Stream.Loc,
"invalid message stream id");
8219ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8220 using namespace llvm::AMDGPU::SendMsg;
8223 SMLoc Loc = getLoc();
8227 OperandInfoTy
Op(OP_NONE_);
8228 OperandInfoTy Stream(STREAM_ID_NONE_);
8229 if (parseSendMsgBody(Msg,
Op, Stream) &&
8230 validateSendMsg(Msg,
Op, Stream)) {
8235 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8237 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8242 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8246bool AMDGPUOperand::isSendMsg()
const {
8247 return isImmTy(ImmTySendMsg);
8254ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8261 int Slot = StringSwitch<int>(Str)
8268 return Error(S,
"invalid interpolation slot");
8270 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8271 AMDGPUOperand::ImmTyInterpSlot));
8275ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8282 if (!Str.starts_with(
"attr"))
8283 return Error(S,
"invalid interpolation attribute");
8285 StringRef Chan = Str.take_back(2);
8286 int AttrChan = StringSwitch<int>(Chan)
8293 return Error(S,
"invalid or missing interpolation attribute channel");
8295 Str = Str.drop_back(2).drop_front(4);
8298 if (Str.getAsInteger(10, Attr))
8299 return Error(S,
"invalid or missing interpolation attribute number");
8302 return Error(S,
"out of bounds interpolation attribute number");
8306 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8307 AMDGPUOperand::ImmTyInterpAttr));
8308 Operands.
push_back(AMDGPUOperand::CreateImm(
8309 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8317ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8318 using namespace llvm::AMDGPU::Exp;
8328 return Error(S, (Id == ET_INVALID)
8329 ?
"invalid exp target"
8330 :
"exp target is not supported on this GPU");
8332 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8333 AMDGPUOperand::ImmTyExpTgt));
8342AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8347AMDGPUAsmParser::isId(
const StringRef Id)
const {
8353 return getTokenKind() ==
Kind;
8356StringRef AMDGPUAsmParser::getId()
const {
8361AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8370AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8372 StringRef Tok = getTokenStr();
8383 if (isId(Id) && peekToken().is(Kind)) {
8393 if (isToken(Kind)) {
8402 const StringRef ErrMsg) {
8403 if (!trySkipToken(Kind)) {
8404 Error(getLoc(), ErrMsg);
8411AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8415 if (Parser.parseExpression(Expr))
8418 if (Expr->evaluateAsAbsolute(
Imm))
8421 if (Expected.empty()) {
8422 Error(S,
"expected absolute expression");
8424 Error(S, Twine(
"expected ", Expected) +
8425 Twine(
" or an absolute expression"));
8435 if (Parser.parseExpression(Expr))
8439 if (Expr->evaluateAsAbsolute(IntVal)) {
8440 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8442 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8448AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8450 Val =
getToken().getStringContents();
8454 Error(getLoc(), ErrMsg);
8459AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8461 Val = getTokenStr();
8465 if (!ErrMsg.
empty())
8466 Error(getLoc(), ErrMsg);
8471AMDGPUAsmParser::getToken()
const {
8472 return Parser.getTok();
8475AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8478 : getLexer().peekTok(ShouldSkipSpace);
8483 auto TokCount = getLexer().peekTokens(Tokens);
8485 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8490AMDGPUAsmParser::getTokenKind()
const {
8491 return getLexer().getKind();
8495AMDGPUAsmParser::getLoc()
const {
8500AMDGPUAsmParser::getTokenStr()
const {
8505AMDGPUAsmParser::lex() {
8509SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8510 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8514SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8518SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8519 int MCOpIdx)
const {
8520 for (
const auto &
Op : Operands) {
8521 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8522 if (TargetOp.getMCOpIdx() == MCOpIdx)
8523 return TargetOp.getStartLoc();
8529AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8531 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8532 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8534 return Op.getStartLoc();
8536 return getInstLoc(Operands);
8540AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8542 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8543 return getOperandLoc(
Test, Operands);
8557 StringRef
Id = getTokenStr();
8558 SMLoc IdLoc = getLoc();
8564 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8565 if (
I == Fields.
end())
8566 return Error(IdLoc,
"unknown field");
8567 if ((*I)->IsDefined)
8568 return Error(IdLoc,
"duplicate field");
8571 (*I)->Loc = getLoc();
8574 (*I)->IsDefined =
true;
8581bool AMDGPUAsmParser::validateStructuredOpFields(
8583 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8584 return F->validate(*
this);
8595 const unsigned OrMask,
8596 const unsigned XorMask) {
8605bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8606 const unsigned MaxVal,
8607 const Twine &ErrMsg, SMLoc &Loc) {
8624AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8625 const unsigned MinVal,
8626 const unsigned MaxVal,
8627 const StringRef ErrMsg) {
8629 for (
unsigned i = 0; i < OpNum; ++i) {
8630 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8638AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8639 using namespace llvm::AMDGPU::Swizzle;
8642 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8643 "expected a 2-bit lane id")) {
8654AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8655 using namespace llvm::AMDGPU::Swizzle;
8661 if (!parseSwizzleOperand(GroupSize,
8663 "group size must be in the interval [2,32]",
8668 Error(Loc,
"group size must be a power of two");
8671 if (parseSwizzleOperand(LaneIdx,
8673 "lane id must be in the interval [0,group size - 1]",
8682AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8683 using namespace llvm::AMDGPU::Swizzle;
8688 if (!parseSwizzleOperand(GroupSize,
8690 "group size must be in the interval [2,32]",
8695 Error(Loc,
"group size must be a power of two");
8704AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8705 using namespace llvm::AMDGPU::Swizzle;
8710 if (!parseSwizzleOperand(GroupSize,
8712 "group size must be in the interval [1,16]",
8717 Error(Loc,
"group size must be a power of two");
8726AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8727 using namespace llvm::AMDGPU::Swizzle;
8734 SMLoc StrLoc = getLoc();
8735 if (!parseString(Ctl)) {
8738 if (Ctl.
size() != BITMASK_WIDTH) {
8739 Error(StrLoc,
"expected a 5-character mask");
8743 unsigned AndMask = 0;
8744 unsigned OrMask = 0;
8745 unsigned XorMask = 0;
8747 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8751 Error(StrLoc,
"invalid mask");
8772bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8773 using namespace llvm::AMDGPU::Swizzle;
8776 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8782 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8783 "FFT swizzle must be in the interval [0," +
8784 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8792bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8793 using namespace llvm::AMDGPU::Swizzle;
8796 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8803 if (!parseSwizzleOperand(
Direction, 0, 1,
8804 "direction must be 0 (left) or 1 (right)", Loc))
8808 if (!parseSwizzleOperand(
8809 RotateSize, 0, ROTATE_MAX_SIZE,
8810 "number of threads to rotate must be in the interval [0," +
8811 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8816 (RotateSize << ROTATE_SIZE_SHIFT);
8821AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8823 SMLoc OffsetLoc = getLoc();
8829 Error(OffsetLoc,
"expected a 16-bit offset");
8836AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8837 using namespace llvm::AMDGPU::Swizzle;
8841 SMLoc ModeLoc = getLoc();
8844 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8845 Ok = parseSwizzleQuadPerm(
Imm);
8846 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8847 Ok = parseSwizzleBitmaskPerm(
Imm);
8848 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8849 Ok = parseSwizzleBroadcast(
Imm);
8850 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8851 Ok = parseSwizzleSwap(
Imm);
8852 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8853 Ok = parseSwizzleReverse(
Imm);
8854 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8855 Ok = parseSwizzleFFT(
Imm);
8856 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8857 Ok = parseSwizzleRotate(
Imm);
8859 Error(ModeLoc,
"expected a swizzle mode");
8862 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8868ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8872 if (trySkipId(
"offset")) {
8876 if (trySkipId(
"swizzle")) {
8877 Ok = parseSwizzleMacro(
Imm);
8879 Ok = parseSwizzleOffset(
Imm);
8883 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8891AMDGPUOperand::isSwizzle()
const {
8892 return isImmTy(ImmTySwizzle);
8899int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8901 using namespace llvm::AMDGPU::VGPRIndexMode;
8913 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8914 if (trySkipId(IdSymbolic[ModeId])) {
8922 "expected a VGPR index mode or a closing parenthesis" :
8923 "expected a VGPR index mode");
8928 Error(S,
"duplicate VGPR index mode");
8936 "expected a comma or a closing parenthesis"))
8943ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8945 using namespace llvm::AMDGPU::VGPRIndexMode;
8951 Imm = parseGPRIdxMacro();
8955 if (getParser().parseAbsoluteExpression(
Imm))
8958 return Error(S,
"invalid immediate: only 4-bit values are legal");
8962 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8966bool AMDGPUOperand::isGPRIdxMode()
const {
8967 return isImmTy(ImmTyGprIdxMode);
8974ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
8979 if (isRegister() || isModifier())
8985 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
8986 assert(Opr.isImm() || Opr.isExpr());
8987 SMLoc Loc = Opr.getStartLoc();
8991 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8992 Error(Loc,
"expected an absolute expression or a label");
8993 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8994 Error(Loc,
"expected a 16-bit signed jump offset");
9004ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
9005 return parseReg(Operands);
9012void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
9015 OptionalImmIndexMap OptionalIdx;
9016 unsigned FirstOperandIdx = 1;
9017 bool IsAtomicReturn =
false;
9024 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9025 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9029 Op.addRegOperands(Inst, 1);
9033 if (IsAtomicReturn && i == FirstOperandIdx)
9034 Op.addRegOperands(Inst, 1);
9039 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9040 Op.addImmOperands(Inst, 1);
9052 OptionalIdx[
Op.getImmTy()] = i;
9066bool AMDGPUOperand::isSMRDOffset8()
const {
9070bool AMDGPUOperand::isSMEMOffset()
const {
9072 return isImmLiteral();
9075bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9110bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9111 if (BoundCtrl == 0 || BoundCtrl == 1) {
9119void AMDGPUAsmParser::onBeginOfFile() {
9120 if (!getParser().getStreamer().getTargetStreamer() ||
9124 if (!getTargetStreamer().getTargetID())
9125 getTargetStreamer().initializeTargetID(getSTI(),
9126 getSTI().getFeatureString());
9129 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9137bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9141 StringRef TokenId = getTokenStr();
9142 AGVK VK = StringSwitch<AGVK>(TokenId)
9143 .Case(
"max", AGVK::AGVK_Max)
9144 .Case(
"or", AGVK::AGVK_Or)
9145 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9146 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9147 .Case(
"alignto", AGVK::AGVK_AlignTo)
9148 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9149 .Default(AGVK::AGVK_None);
9153 uint64_t CommaCount = 0;
9158 if (Exprs.
empty()) {
9160 "empty " + Twine(TokenId) +
" expression");
9163 if (CommaCount + 1 != Exprs.
size()) {
9165 "mismatch of commas in " + Twine(TokenId) +
" expression");
9172 if (getParser().parseExpression(Expr, EndLoc))
9176 if (LastTokenWasComma)
9180 "unexpected token in " + Twine(TokenId) +
" expression");
9186 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9189ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9190 StringRef
Name = getTokenStr();
9191 if (Name ==
"mul") {
9192 return parseIntWithPrefix(
"mul", Operands,
9196 if (Name ==
"div") {
9197 return parseIntWithPrefix(
"div", Operands,
9208 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9213 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9214 AMDGPU::OpName::src2};
9222 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9227 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9229 if (
DstOp.isReg() &&
9230 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9234 if ((OpSel & (1 << SrcNum)) != 0)
9240void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9242 cvtVOP3P(Inst, Operands);
9246void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9247 OptionalImmIndexMap &OptionalIdx) {
9248 cvtVOP3P(Inst, Operands, OptionalIdx);
9257 &&
Desc.NumOperands > (OpNum + 1)
9259 &&
Desc.operands()[OpNum + 1].RegClass != -1
9261 &&
Desc.getOperandConstraint(OpNum + 1,
9265void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9267 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9268 AMDGPU::OpName::src2};
9269 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9270 AMDGPU::OpName::src1_modifiers,
9271 AMDGPU::OpName::src2_modifiers};
9272 for (
int J = 0; J < 3; ++J) {
9273 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9279 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9282 if ((OpSel & (1 << J)) != 0)
9285 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9292void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9294 OptionalImmIndexMap OptionalIdx;
9299 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9300 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9303 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9304 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9306 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9307 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9308 Op.isInterpAttrChan()) {
9310 }
else if (
Op.isImmModifier()) {
9311 OptionalIdx[
Op.getImmTy()] =
I;
9319 AMDGPUOperand::ImmTyHigh);
9323 AMDGPUOperand::ImmTyClamp);
9327 AMDGPUOperand::ImmTyOModSI);
9332 AMDGPUOperand::ImmTyOpSel);
9333 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9336 cvtOpSelHelper(Inst, OpSel);
9340void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9342 OptionalImmIndexMap OptionalIdx;
9347 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9348 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9351 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9352 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9354 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9355 }
else if (
Op.isImmModifier()) {
9356 OptionalIdx[
Op.getImmTy()] =
I;
9364 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9374 cvtOpSelHelper(Inst, OpSel);
9377void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9379 OptionalImmIndexMap OptionalIdx;
9382 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9386 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9387 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9389 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9390 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9395 if (NumOperands == CbszOpIdx) {
9400 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9401 }
else if (
Op.isImmModifier()) {
9402 OptionalIdx[
Op.getImmTy()] =
I;
9404 Op.addRegOrImmOperands(Inst, 1);
9409 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9410 if (CbszIdx != OptionalIdx.end()) {
9411 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9415 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9416 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9417 if (BlgpIdx != OptionalIdx.end()) {
9418 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9429 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9430 if (OpselIdx != OptionalIdx.end()) {
9431 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9435 unsigned OpSelHi = 0;
9436 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9437 if (OpselHiIdx != OptionalIdx.end()) {
9438 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9441 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9442 AMDGPU::OpName::src1_modifiers};
9444 for (
unsigned J = 0; J < 2; ++J) {
9445 unsigned ModVal = 0;
9446 if (OpSel & (1 << J))
9448 if (OpSelHi & (1 << J))
9451 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9456void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9457 OptionalImmIndexMap &OptionalIdx) {
9462 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9463 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9466 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9467 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9469 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9470 }
else if (
Op.isImmModifier()) {
9471 OptionalIdx[
Op.getImmTy()] =
I;
9473 Op.addRegOrImmOperands(Inst, 1);
9479 AMDGPUOperand::ImmTyScaleSel);
9483 AMDGPUOperand::ImmTyClamp);
9489 AMDGPUOperand::ImmTyByteSel);
9494 AMDGPUOperand::ImmTyOModSI);
9501 auto *it = Inst.
begin();
9502 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9510void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9511 OptionalImmIndexMap OptionalIdx;
9512 cvtVOP3(Inst, Operands, OptionalIdx);
9515void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9516 OptionalImmIndexMap &OptIdx) {
9522 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9523 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9524 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9525 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9526 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9527 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9535 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9536 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9537 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9538 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9539 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9540 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9541 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9542 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9543 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9544 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9545 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9546 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9547 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9548 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9549 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9550 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9551 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9552 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9553 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9554 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9555 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9556 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9557 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9558 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9559 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9560 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9564 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9565 if (BitOp3Idx != -1) {
9572 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9573 if (OpSelIdx != -1) {
9577 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9578 if (OpSelHiIdx != -1) {
9585 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9586 if (MatrixAFMTIdx != -1) {
9588 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9592 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9593 if (MatrixBFMTIdx != -1) {
9595 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9598 int MatrixAScaleIdx =
9599 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9600 if (MatrixAScaleIdx != -1) {
9602 AMDGPUOperand::ImmTyMatrixAScale, 0);
9605 int MatrixBScaleIdx =
9606 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9607 if (MatrixBScaleIdx != -1) {
9609 AMDGPUOperand::ImmTyMatrixBScale, 0);
9612 int MatrixAScaleFmtIdx =
9613 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9614 if (MatrixAScaleFmtIdx != -1) {
9616 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9619 int MatrixBScaleFmtIdx =
9620 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9621 if (MatrixBScaleFmtIdx != -1) {
9623 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9628 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9632 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9634 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9638 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9642 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9643 AMDGPU::OpName::src2};
9644 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9645 AMDGPU::OpName::src1_modifiers,
9646 AMDGPU::OpName::src2_modifiers};
9649 unsigned OpSelHi = 0;
9656 if (OpSelHiIdx != -1)
9665 for (
int J = 0; J < 3; ++J) {
9666 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9670 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9675 uint32_t ModVal = 0;
9678 if (SrcOp.
isReg() && getMRI()
9685 if ((OpSel & (1 << J)) != 0)
9689 if ((OpSelHi & (1 << J)) != 0)
9692 if ((NegLo & (1 << J)) != 0)
9695 if ((NegHi & (1 << J)) != 0)
9702void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9703 OptionalImmIndexMap OptIdx;
9704 cvtVOP3(Inst, Operands, OptIdx);
9705 cvtVOP3P(Inst, Operands, OptIdx);
9709 unsigned i,
unsigned Opc,
9711 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9712 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9714 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9717void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9720 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9723 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9724 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9726 OptionalImmIndexMap OptIdx;
9727 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9728 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9729 OptIdx[
Op.getImmTy()] = i;
9734 AMDGPUOperand::ImmTyIndexKey8bit);
9738 AMDGPUOperand::ImmTyIndexKey16bit);
9742 AMDGPUOperand::ImmTyIndexKey32bit);
9747 cvtVOP3P(Inst, Operands, OptIdx);
9754ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9762 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9763 SMLoc OpYLoc = getLoc();
9766 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9769 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9775void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9778 auto addOp = [&](uint16_t ParsedOprIdx) {
9779 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9781 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9785 Op.addRegOperands(Inst, 1);
9789 Op.addImmOperands(Inst, 1);
9801 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9805 const auto &CInfo = InstInfo[CompIdx];
9806 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9807 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9808 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9809 if (CInfo.hasSrc2Acc())
9810 addOp(CInfo.getIndexOfDstInParsedOperands());
9814 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9815 if (BitOp3Idx != -1) {
9816 OptionalImmIndexMap OptIdx;
9817 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9819 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9829bool AMDGPUOperand::isDPP8()
const {
9830 return isImmTy(ImmTyDPP8);
9833bool AMDGPUOperand::isDPPCtrl()
const {
9834 using namespace AMDGPU::DPP;
9836 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9839 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9840 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9841 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9842 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9843 (
Imm == DppCtrl::WAVE_SHL1) ||
9844 (
Imm == DppCtrl::WAVE_ROL1) ||
9845 (
Imm == DppCtrl::WAVE_SHR1) ||
9846 (
Imm == DppCtrl::WAVE_ROR1) ||
9847 (
Imm == DppCtrl::ROW_MIRROR) ||
9848 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9849 (
Imm == DppCtrl::BCAST15) ||
9850 (
Imm == DppCtrl::BCAST31) ||
9851 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9852 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9861bool AMDGPUOperand::isBLGP()
const {
9865bool AMDGPUOperand::isS16Imm()
const {
9869bool AMDGPUOperand::isU16Imm()
const {
9877bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9882 SMLoc Loc =
getToken().getEndLoc();
9883 Token = std::string(getTokenStr());
9885 if (getLoc() != Loc)
9890 if (!parseId(Suffix))
9894 StringRef DimId = Token;
9905ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9915 SMLoc Loc = getLoc();
9916 if (!parseDimId(Encoding))
9917 return Error(Loc,
"invalid dim value");
9919 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9920 AMDGPUOperand::ImmTyDim));
9928ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
9938 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9941 for (
size_t i = 0; i < 8; ++i) {
9945 SMLoc Loc = getLoc();
9946 if (getParser().parseAbsoluteExpression(Sels[i]))
9948 if (0 > Sels[i] || 7 < Sels[i])
9949 return Error(Loc,
"expected a 3-bit value");
9956 for (
size_t i = 0; i < 8; ++i)
9957 DPP8 |= (Sels[i] << (i * 3));
9959 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9964AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
9966 if (Ctrl ==
"row_newbcast")
9969 if (Ctrl ==
"row_share" ||
9970 Ctrl ==
"row_xmask")
9973 if (Ctrl ==
"wave_shl" ||
9974 Ctrl ==
"wave_shr" ||
9975 Ctrl ==
"wave_rol" ||
9976 Ctrl ==
"wave_ror" ||
9977 Ctrl ==
"row_bcast")
9980 return Ctrl ==
"row_mirror" ||
9981 Ctrl ==
"row_half_mirror" ||
9982 Ctrl ==
"quad_perm" ||
9983 Ctrl ==
"row_shl" ||
9984 Ctrl ==
"row_shr" ||
9989AMDGPUAsmParser::parseDPPCtrlPerm() {
9992 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9996 for (
int i = 0; i < 4; ++i) {
10001 SMLoc Loc = getLoc();
10002 if (getParser().parseAbsoluteExpression(Temp))
10004 if (Temp < 0 || Temp > 3) {
10005 Error(Loc,
"expected a 2-bit value");
10009 Val += (Temp << i * 2);
10012 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10019AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10020 using namespace AMDGPU::DPP;
10025 SMLoc Loc = getLoc();
10027 if (getParser().parseAbsoluteExpression(Val))
10030 struct DppCtrlCheck {
10036 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10037 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10038 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10039 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10040 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10041 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10042 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10043 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10044 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10045 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10046 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10050 if (
Check.Ctrl == -1) {
10051 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10059 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10066ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10067 using namespace AMDGPU::DPP;
10070 !isSupportedDPPCtrl(getTokenStr(), Operands))
10073 SMLoc S = getLoc();
10079 if (Ctrl ==
"row_mirror") {
10080 Val = DppCtrl::ROW_MIRROR;
10081 }
else if (Ctrl ==
"row_half_mirror") {
10082 Val = DppCtrl::ROW_HALF_MIRROR;
10085 if (Ctrl ==
"quad_perm") {
10086 Val = parseDPPCtrlPerm();
10088 Val = parseDPPCtrlSel(Ctrl);
10097 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10101void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10103 OptionalImmIndexMap OptionalIdx;
10110 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10112 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10113 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10117 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10118 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10122 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10123 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10124 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10125 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10126 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10128 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10132 if (OldIdx == NumOperands) {
10134 constexpr int DST_IDX = 0;
10136 }
else if (Src2ModIdx == NumOperands) {
10146 if (IsVOP3CvtSrDpp) {
10155 if (TiedTo != -1) {
10160 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10162 if (IsDPP8 &&
Op.isDppFI()) {
10165 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10166 }
else if (
Op.isReg()) {
10167 Op.addRegOperands(Inst, 1);
10168 }
else if (
Op.isImm() &&
10170 Op.addImmOperands(Inst, 1);
10171 }
else if (
Op.isImm()) {
10172 OptionalIdx[
Op.getImmTy()] =
I;
10180 AMDGPUOperand::ImmTyClamp);
10186 AMDGPUOperand::ImmTyByteSel);
10193 cvtVOP3P(Inst, Operands, OptionalIdx);
10195 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10202 using namespace llvm::AMDGPU::DPP;
10212 AMDGPUOperand::ImmTyDppFI);
10216void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10217 OptionalImmIndexMap OptionalIdx;
10221 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10222 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10226 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10229 if (TiedTo != -1) {
10234 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10236 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10244 Op.addImmOperands(Inst, 1);
10246 Op.addRegWithFPInputModsOperands(Inst, 2);
10247 }
else if (
Op.isDppFI()) {
10249 }
else if (
Op.isReg()) {
10250 Op.addRegOperands(Inst, 1);
10256 Op.addRegWithFPInputModsOperands(Inst, 2);
10257 }
else if (
Op.isReg()) {
10258 Op.addRegOperands(Inst, 1);
10259 }
else if (
Op.isDPPCtrl()) {
10260 Op.addImmOperands(Inst, 1);
10261 }
else if (
Op.isImm()) {
10263 OptionalIdx[
Op.getImmTy()] =
I;
10271 using namespace llvm::AMDGPU::DPP;
10279 AMDGPUOperand::ImmTyDppFI);
10288ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10290 AMDGPUOperand::ImmTy
Type) {
10291 return parseStringOrIntWithPrefix(
10293 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10297ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10298 return parseStringOrIntWithPrefix(
10299 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10300 AMDGPUOperand::ImmTySDWADstUnused);
10303void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10307void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10311void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10315void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10319void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10323void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10324 uint64_t BasicInstType,
10327 using namespace llvm::AMDGPU::SDWA;
10329 OptionalImmIndexMap OptionalIdx;
10330 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10331 bool SkippedVcc =
false;
10335 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10336 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10339 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10340 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10341 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10342 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10360 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10361 }
else if (
Op.isImm()) {
10363 OptionalIdx[
Op.getImmTy()] =
I;
10367 SkippedVcc =
false;
10371 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10372 Opc != AMDGPU::V_NOP_sdwa_vi) {
10374 switch (BasicInstType) {
10378 AMDGPUOperand::ImmTyClamp, 0);
10382 AMDGPUOperand::ImmTyOModSI, 0);
10386 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10390 AMDGPUOperand::ImmTySDWADstUnused,
10391 DstUnused::UNUSED_PRESERVE);
10393 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10398 AMDGPUOperand::ImmTyClamp, 0);
10403 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10404 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10405 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10406 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10412 AMDGPUOperand::ImmTyClamp, 0);
10413 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10414 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10418 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10424 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10425 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10426 auto *it = Inst.
begin();
10428 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10440#define GET_MATCHER_IMPLEMENTATION
10441#define GET_MNEMONIC_SPELL_CHECKER
10442#define GET_MNEMONIC_CHECKER
10443#include "AMDGPUGenAsmMatcher.inc"
10449 return parseTokenOp(
"addr64",
Operands);
10451 return parseTokenOp(
"done",
Operands);
10453 return parseTokenOp(
"idxen",
Operands);
10455 return parseTokenOp(
"lds",
Operands);
10457 return parseTokenOp(
"offen",
Operands);
10459 return parseTokenOp(
"off",
Operands);
10460 case MCK_row_95_en:
10461 return parseTokenOp(
"row_en",
Operands);
10463 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10465 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10467 return tryCustomParseOperand(
Operands, MCK);
10472unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10478 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10481 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10483 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10485 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10487 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10489 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10491 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10499 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10501 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10502 case MCK_SOPPBrTarget:
10503 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10504 case MCK_VReg32OrOff:
10505 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10506 case MCK_InterpSlot:
10507 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10508 case MCK_InterpAttr:
10509 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10510 case MCK_InterpAttrChan:
10511 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10513 case MCK_SReg_64_XEXEC:
10523 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10525 return Match_InvalidOperand;
10533ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10534 SMLoc S = getLoc();
10543 return Error(S,
"expected a 16-bit value");
10546 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10550bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10556bool 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")
#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)
bool isGFX13(const MCSubtargetInfo &STI)
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
CanBeVOPD getCanBeVOPD(unsigned Opc, unsigned EncodingFamily, bool VOPD3)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
bool isSI(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isGFX9(const MCSubtargetInfo &STI)
unsigned getVOPDEncodingFamily(const MCSubtargetInfo &ST)
bool isGFX10_AEncoding(const MCSubtargetInfo &STI)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool hasMAIInsts(const MCSubtargetInfo &STI)
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool isGFX13Plus(const MCSubtargetInfo &STI)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_IMM_V2FP16_SPLAT
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
bool isGFX1250Plus(const MCSubtargetInfo &STI)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
@ Valid
The data is already valid.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
FunctionAddr VTableAddr uintptr_t uintptr_t Version
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ Default
The result values are uniform if and only if all operands are uniform.
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
Instruction set architecture version.
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
const MCExpr * compute_pgm_rsrc1
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * group_segment_fixed_size
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * kernel_code_properties
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size