70 enum KindTy { Token, Immediate, Register, Expression } Kind;
72 SMLoc StartLoc, EndLoc;
73 const AMDGPUAsmParser *AsmParser;
76 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
77 : Kind(Kind_), AsmParser(AsmParser_) {}
79 using Ptr = std::unique_ptr<AMDGPUOperand>;
87 bool hasFPModifiers()
const {
return Abs || Neg; }
88 bool hasIntModifiers()
const {
return Sext; }
89 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
90 bool isForcedLit()
const {
return Lit == LitModifier::Lit; }
91 bool isForcedLit64()
const {
return Lit == LitModifier::Lit64; }
93 int64_t getFPModifiersOperand()
const {
100 int64_t getIntModifiersOperand()
const {
106 int64_t getModifiersOperand()
const {
107 assert(!(hasFPModifiers() && hasIntModifiers()) &&
108 "fp and int modifiers should not be used simultaneously");
109 if (hasFPModifiers())
110 return getFPModifiersOperand();
111 if (hasIntModifiers())
112 return getIntModifiersOperand();
116 friend raw_ostream &
operator<<(raw_ostream &OS,
117 AMDGPUOperand::Modifiers Mods);
191 ImmTyMatrixAScaleFmt,
192 ImmTyMatrixBScaleFmt,
225 mutable int MCOpIdx = -1;
228 bool isToken()
const override {
return Kind == Token; }
230 bool isSymbolRefExpr()
const {
234 bool isImm()
const override {
return Kind == Immediate; }
236 bool isInlinableImm(MVT type)
const;
237 bool isLiteralImm(MVT type)
const;
239 bool isRegKind()
const {
return Kind == Register; }
241 bool isReg()
const override {
return isRegKind() && !hasModifiers(); }
243 bool isRegOrInline(
unsigned RCID, MVT type)
const {
244 return isRegClass(RCID) || isInlinableImm(type);
247 bool isRegOrInlineTarget(
unsigned TargetRCIdx, MVT type)
const {
248 return isRegClassTarget(TargetRCIdx) || isInlinableImm(type);
252 return isRegOrInline(RCID, type) || isLiteralImm(type);
255 bool isRegOrImmWithInputModsTarget(
unsigned TargetRCIdx, MVT type)
const {
256 return isRegOrInlineTarget(TargetRCIdx, type) || isLiteralImm(type);
259 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
261 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
264 bool isRegOrImmWithInt32InputMods()
const {
268 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
269 return isRegOrInline(
270 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
273 bool isRegOrInlineImmWithInt32InputMods()
const {
274 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
277 bool isRegOrImmWithInt64InputMods()
const {
278 return isRegOrImmWithInputModsTarget(AMDGPU::VS_64_AlignTarget, MVT::i64);
281 bool isRegOrImmWithFP16InputMods()
const {
285 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
287 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
290 bool isRegOrImmWithFPT16_LO16InputMods()
const {
294 bool isRegOrImmWithFP32InputMods()
const {
298 bool isRegOrImmWithFP64InputMods()
const {
299 return isRegOrImmWithInputModsTarget(AMDGPU::VS_64_AlignTarget, MVT::f64);
302 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
303 return isRegOrInline(
304 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
307 bool isRegOrInlineImmWithFP32InputMods()
const {
308 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
311 bool isRegOrInlineImmWithFP64InputMods()
const {
312 return isRegOrInlineTarget(AMDGPU::VS_64_AlignTarget, MVT::f64);
315 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
317 bool isVRegWithFP32InputMods()
const {
318 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
321 bool isVRegWithFP64InputMods()
const {
322 return isRegClassTarget(AMDGPU::VReg_64_AlignTarget);
325 bool isPackedFP16InputMods()
const {
329 bool isPackedVGPRFP32InputMods()
const {
333 bool isVReg32()
const {
return isRegClass(AMDGPU::VGPR_32RegClassID); }
335 bool isVReg32OrOff()
const {
return isOff() || isVReg32(); }
337 bool isRsrcReg32()
const {
return isRegClass(AMDGPU::RsrcReg32RegClassID); }
339 bool isNull()
const {
return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL; }
341 bool isAV_LdSt_32_Align2_RegOp()
const {
342 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
343 isRegClass(AMDGPU::AGPR_32RegClassID);
346 bool isVRegWithInputMods()
const;
347 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
348 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
349 bool isT16_LO16VRegWithInputMods()
const;
351 bool isSDWAOperand(MVT type)
const;
352 bool isSDWAFP16Operand()
const;
353 bool isSDWAFP32Operand()
const;
354 bool isSDWAInt16Operand()
const;
355 bool isSDWAInt32Operand()
const;
357 bool isImmTy(ImmTy ImmT)
const {
return isImm() &&
Imm.Type == ImmT; }
359 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
361 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
363 bool isImmModifier()
const {
return isImm() &&
Imm.Type != ImmTyNone; }
365 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
366 bool isDim()
const {
return isImmTy(ImmTyDim); }
367 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
368 bool isOff()
const {
return isImmTy(ImmTyOff); }
369 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
370 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
371 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
372 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
373 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
374 bool isFlatOffset()
const {
375 return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset);
377 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
378 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
379 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
380 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
381 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
382 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
383 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
384 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
385 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
386 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
387 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
388 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
389 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
390 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
391 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
392 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
393 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
394 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
395 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
396 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
397 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
398 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
399 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
400 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
401 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
402 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
403 bool isDone()
const {
return isImmTy(ImmTyDone); }
404 bool isRowEn()
const {
return isImmTy(ImmTyRowEn); }
406 bool isRegOrImm()
const {
return isReg() || isImm(); }
408 bool isRegClass(
unsigned RCID)
const;
411 bool isRegClassTarget(
unsigned TargetRCIdx)
const;
415 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
416 return isRegOrInline(RCID, type) && !hasModifiers();
419 bool isRegOrInlineNoModsTarget(
unsigned TargetRCIdx, MVT type)
const {
420 return isRegOrInlineTarget(TargetRCIdx, type) && !hasModifiers();
423 bool isSCSrcB16()
const {
424 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
427 bool isSCSrc_b32()
const {
428 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
431 bool isSCSrc_b64()
const {
432 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
435 bool isBoolReg()
const;
437 bool isSSrc_b32()
const {
438 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
441 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
443 bool isSSrc_b64()
const {
446 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
447 (((
const MCTargetAsmParser *)AsmParser)
448 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
452 bool isSSrc_f32()
const {
453 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
456 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
458 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
460 bool isSSrc_NoInline_f16()
const {
return isSSrc_f16(); }
462 bool isSSrcOrLds_b32()
const {
463 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
464 isLiteralImm(MVT::i32) || isExpr();
467 bool isVCSrc_b32()
const {
468 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
471 bool isVCSrc_b32_Lo256()
const {
472 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
475 bool isVCSrc_b64_Lo256()
const {
476 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
479 bool isVCSrc_b64()
const {
480 return isRegOrInlineNoModsTarget(AMDGPU::VS_64_AlignTarget, MVT::i64);
483 bool isVCSrcT_b16()
const {
484 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
487 bool isVCSrcTB16_Lo128()
const {
488 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
491 bool isVCSrcFake16B16_Lo128()
const {
492 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
495 bool isVCSrc_b16()
const {
496 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
499 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
501 bool isVCSrc_f32()
const {
502 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
505 bool isVCSrc_f64()
const {
506 return isRegOrInlineNoModsTarget(AMDGPU::VS_64_AlignTarget, MVT::f64);
509 bool isVCSrcTBF16()
const {
510 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
513 bool isVCSrcT_f16()
const {
514 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
517 bool isVCSrcT_bf16()
const {
518 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
521 bool isVCSrcTF16_LO16()
const {
522 return isRegOrInlineNoMods(AMDGPU::VS_16_LO16RegClassID, MVT::f16);
525 bool isVCSrcTBF16_Lo128()
const {
526 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
529 bool isVCSrcTF16_Lo128()
const {
530 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
533 bool isVCSrcFake16BF16_Lo128()
const {
534 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
537 bool isVCSrcFake16F16_Lo128()
const {
538 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
541 bool isVCSrc_bf16()
const {
542 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
545 bool isVCSrc_f16()
const {
546 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
549 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
551 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
553 bool isVSrc_b32()
const {
554 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
557 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
559 bool isVSrc_v2b64()
const {
560 return isRegOrInlineNoModsTarget(AMDGPU::VS_128_AlignTarget, MVT::i64) ||
561 isLiteralImm(MVT::i64);
564 bool isVSrc_v2f64()
const {
565 return isRegOrInlineNoModsTarget(AMDGPU::VS_128_AlignTarget, MVT::f64) ||
566 isLiteralImm(MVT::f64);
569 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
571 bool isVSrcT_b16_Lo128()
const {
572 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
575 bool isVSrcFake16_b16_Lo128()
const {
576 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
579 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
581 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
583 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
585 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
587 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
589 bool isVSrc_f32()
const {
590 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
593 bool isVSrc_f64()
const {
594 return isRegOrInlineNoModsTarget(AMDGPU::VS_64_AlignTarget, MVT::f64) ||
595 isLiteralImm(MVT::f64);
598 bool isVSrcT_bf16()
const {
599 return isVCSrcTBF16() || isLiteralImm(MVT::bf16);
602 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
604 bool isVSrcT_f16_LO16()
const {
605 return isVCSrcTF16_LO16() || isLiteralImm(MVT::f16);
608 bool isVSrcT_bf16_Lo128()
const {
609 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
612 bool isVSrcT_f16_Lo128()
const {
613 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
616 bool isVSrcFake16_bf16_Lo128()
const {
617 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
620 bool isVSrcFake16_f16_Lo128()
const {
621 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
624 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
626 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
628 bool isVSrc_v2bf16()
const {
629 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
632 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
634 bool isVSrc_v2f16_splat()
const {
return isVSrc_v2f16(); }
636 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
638 bool isVISrc_64_bf16()
const {
639 return isRegOrInlineNoModsTarget(AMDGPU::VReg_64_AlignTarget, MVT::bf16);
642 bool isVISrc_64_f16()
const {
643 return isRegOrInlineNoModsTarget(AMDGPU::VReg_64_AlignTarget, MVT::f16);
646 bool isVISrc_64_b32()
const {
647 return isRegOrInlineNoModsTarget(AMDGPU::VReg_64_AlignTarget, MVT::i32);
650 bool isVISrc_64_f64()
const {
651 return isRegOrInlineNoModsTarget(AMDGPU::VReg_64_AlignTarget, MVT::f64);
654 bool isVISrc_256_b32()
const {
655 return isRegOrInlineNoModsTarget(AMDGPU::VReg_256_AlignTarget, MVT::i32);
658 bool isVISrc_256_f32()
const {
659 return isRegOrInlineNoModsTarget(AMDGPU::VReg_256_AlignTarget, MVT::f32);
662 bool isVISrc_256_f64()
const {
663 return isRegOrInlineNoModsTarget(AMDGPU::VReg_256_AlignTarget, MVT::f64);
666 bool isVISrc_512_f64()
const {
667 return isRegOrInlineNoModsTarget(AMDGPU::VReg_512_AlignTarget, MVT::f64);
670 bool isVISrc_128_b32()
const {
671 return isRegOrInlineNoModsTarget(AMDGPU::VReg_128_AlignTarget, MVT::i32);
674 bool isVISrc_128_f32()
const {
675 return isRegOrInlineNoModsTarget(AMDGPU::VReg_128_AlignTarget, MVT::f32);
678 bool isVISrc_512_b32()
const {
679 return isRegOrInlineNoModsTarget(AMDGPU::VReg_512_AlignTarget, MVT::i32);
682 bool isVISrc_512_f32()
const {
683 return isRegOrInlineNoModsTarget(AMDGPU::VReg_512_AlignTarget, MVT::f32);
686 bool isVISrc_1024_b32()
const {
687 return isRegOrInlineNoModsTarget(AMDGPU::VReg_1024_AlignTarget, MVT::i32);
690 bool isVISrc_1024_f32()
const {
691 return isRegOrInlineNoModsTarget(AMDGPU::VReg_1024_AlignTarget, MVT::f32);
694 bool isAISrc_64_f64()
const {
695 return isRegOrInlineNoModsTarget(AMDGPU::AReg_64_AlignTarget, MVT::f64);
698 bool isAISrc_128_b32()
const {
699 return isRegOrInlineNoModsTarget(AMDGPU::AReg_128_AlignTarget, MVT::i32);
702 bool isAISrc_128_f32()
const {
703 return isRegOrInlineNoModsTarget(AMDGPU::AReg_128_AlignTarget, MVT::f32);
706 bool isVISrc_128_bf16()
const {
707 return isRegOrInlineNoModsTarget(AMDGPU::VReg_128_AlignTarget, MVT::bf16);
710 bool isVISrc_128_f16()
const {
711 return isRegOrInlineNoModsTarget(AMDGPU::VReg_128_AlignTarget, MVT::f16);
714 bool isAISrc_256_f64()
const {
715 return isRegOrInlineNoModsTarget(AMDGPU::AReg_256_AlignTarget, MVT::f64);
718 bool isAISrc_512_b32()
const {
719 return isRegOrInlineNoModsTarget(AMDGPU::AReg_512_AlignTarget, MVT::i32);
722 bool isAISrc_512_f32()
const {
723 return isRegOrInlineNoModsTarget(AMDGPU::AReg_512_AlignTarget, MVT::f32);
726 bool isAISrc_1024_b32()
const {
727 return isRegOrInlineNoModsTarget(AMDGPU::AReg_1024_AlignTarget, MVT::i32);
730 bool isAISrc_1024_f32()
const {
731 return isRegOrInlineNoModsTarget(AMDGPU::AReg_1024_AlignTarget, MVT::f32);
734 bool isKImmFP32()
const {
return isLiteralImm(MVT::f32); }
736 bool isKImmFP16()
const {
return isLiteralImm(MVT::f16); }
738 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
740 bool isMem()
const override {
return false; }
742 bool isExpr()
const {
return Kind == Expression; }
744 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
746 bool isSWaitCnt()
const;
747 bool isDepCtr()
const;
748 bool isSDelayALU()
const;
749 bool isHwreg()
const;
750 bool isSendMsg()
const;
751 bool isWaitEvent()
const;
752 bool isSplitBarrier()
const;
753 bool isSwizzle()
const;
754 bool isSMRDOffset8()
const;
755 bool isSMEMOffset()
const;
756 bool isSMRDLiteralOffset()
const;
758 bool isDPPCtrl()
const;
760 bool isGPRIdxMode()
const;
761 bool isS16Imm()
const;
762 bool isU16Imm()
const;
763 bool isEndpgm()
const;
765 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
766 return [
this,
P]() {
return P(*
this); };
771 return StringRef(Tok.Data, Tok.Length);
779 void setImm(int64_t Val) {
784 ImmTy getImmTy()
const {
789 MCRegister
getReg()
const override {
794 SMLoc getStartLoc()
const override {
return StartLoc; }
796 SMLoc getEndLoc()
const override {
return EndLoc; }
798 int getMCOpIdx()
const {
return MCOpIdx; }
800 Modifiers getModifiers()
const {
801 assert(isRegKind() || isImmTy(ImmTyNone));
802 return isRegKind() ?
Reg.Mods :
Imm.Mods;
805 void setModifiers(Modifiers Mods) {
806 assert(isRegKind() || isImmTy(ImmTyNone));
813 bool hasModifiers()
const {
return getModifiers().hasModifiers(); }
815 bool hasFPModifiers()
const {
return getModifiers().hasFPModifiers(); }
817 bool hasIntModifiers()
const {
return getModifiers().hasIntModifiers(); }
819 bool isForcedLit()
const {
820 return isImmLiteral() && getModifiers().isForcedLit();
823 bool isForcedLit64()
const {
824 return isImmLiteral() && getModifiers().isForcedLit64();
829 void addImmOperands(MCInst &Inst,
unsigned N,
830 bool ApplyModifiers =
true)
const;
832 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
833 bool ApplyModifiers)
const;
835 void addRegOperands(MCInst &Inst,
unsigned N)
const;
837 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
839 addRegOperands(Inst,
N);
841 addImmOperands(Inst,
N);
844 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
845 Modifiers Mods = getModifiers();
848 addRegOperands(Inst,
N);
850 addImmOperands(Inst,
N,
false);
854 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
855 assert(!hasIntModifiers());
856 addRegOrImmWithInputModsOperands(Inst,
N);
859 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
860 Modifiers Mods = getModifiers();
863 addRegOperands(Inst,
N);
866 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
867 assert(!hasIntModifiers());
868 addRegWithInputModsOperands(Inst,
N);
871 static void printImmTy(raw_ostream &OS, ImmTy
Type) {
874 case ImmTyNone: OS <<
"None";
break;
875 case ImmTyGDS: OS <<
"GDS";
break;
876 case ImmTyLDS: OS <<
"LDS";
break;
877 case ImmTyOffen: OS <<
"Offen";
break;
878 case ImmTyIdxen: OS <<
"Idxen";
break;
879 case ImmTyAddr64: OS <<
"Addr64";
break;
880 case ImmTyOffset: OS <<
"Offset";
break;
881 case ImmTyInstOffset: OS <<
"InstOffset";
break;
882 case ImmTyOffset0: OS <<
"Offset0";
break;
883 case ImmTyOffset1: OS <<
"Offset1";
break;
884 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
885 case ImmTyCPol: OS <<
"CPol";
break;
886 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
887 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
888 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
889 case ImmTyTFE: OS <<
"TFE";
break;
890 case ImmTyIsAsync: OS <<
"IsAsync";
break;
891 case ImmTyD16: OS <<
"D16";
break;
892 case ImmTyFORMAT: OS <<
"FORMAT";
break;
893 case ImmTyClamp: OS <<
"Clamp";
break;
894 case ImmTyOModSI: OS <<
"OModSI";
break;
895 case ImmTyDPP8: OS <<
"DPP8";
break;
896 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
897 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
898 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
899 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
900 case ImmTyDppFI: OS <<
"DppFI";
break;
901 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
902 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
903 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
904 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
905 case ImmTyDMask: OS <<
"DMask";
break;
906 case ImmTyDim: OS <<
"Dim";
break;
907 case ImmTyUNorm: OS <<
"UNorm";
break;
908 case ImmTyDA: OS <<
"DA";
break;
909 case ImmTyR128A16: OS <<
"R128A16";
break;
910 case ImmTyA16: OS <<
"A16";
break;
911 case ImmTyLWE: OS <<
"LWE";
break;
912 case ImmTyOff: OS <<
"Off";
break;
913 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
914 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
915 case ImmTyExpVM: OS <<
"ExpVM";
break;
916 case ImmTyDone: OS <<
"Done";
break;
917 case ImmTyRowEn: OS <<
"RowEn";
break;
918 case ImmTyHwreg: OS <<
"Hwreg";
break;
919 case ImmTySendMsg: OS <<
"SendMsg";
break;
920 case ImmTyWaitEvent: OS <<
"WaitEvent";
break;
921 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
922 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
923 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
924 case ImmTyOpSel: OS <<
"OpSel";
break;
925 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
926 case ImmTyNegLo: OS <<
"NegLo";
break;
927 case ImmTyNegHi: OS <<
"NegHi";
break;
928 case ImmTySwizzle: OS <<
"Swizzle";
break;
929 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
930 case ImmTyHigh: OS <<
"High";
break;
931 case ImmTyBLGP: OS <<
"BLGP";
break;
932 case ImmTyCBSZ: OS <<
"CBSZ";
break;
933 case ImmTyABID: OS <<
"ABID";
break;
934 case ImmTyEndpgm: OS <<
"Endpgm";
break;
935 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
936 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
937 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
938 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
939 case ImmTyBitOp3: OS <<
"BitOp3";
break;
940 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
941 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
942 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
943 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
944 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
945 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
946 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
947 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
948 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
949 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
954 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
958 <<
" mods: " <<
Reg.Mods <<
'>';
962 if (getImmTy() != ImmTyNone) {
964 printImmTy(OS, getImmTy());
966 OS <<
" mods: " <<
Imm.Mods <<
'>';
979 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
980 int64_t Val, SMLoc Loc,
981 ImmTy
Type = ImmTyNone,
982 bool IsFPImm =
false) {
983 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
985 Op->Imm.IsFPImm = IsFPImm;
987 Op->Imm.Mods = Modifiers();
993 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
994 StringRef Str, SMLoc Loc,
995 bool HasExplicitEncodingSize =
true) {
996 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
997 Res->Tok.Data = Str.data();
998 Res->Tok.Length = Str.size();
1004 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1005 MCRegister
Reg, SMLoc S, SMLoc
E) {
1006 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1007 Op->Reg.RegNo =
Reg;
1008 Op->Reg.Mods = Modifiers();
1014 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1015 const class MCExpr *Expr, SMLoc S) {
1016 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1025 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1034#define GET_REGISTER_MATCHER
1035#include "AMDGPUGenAsmMatcher.inc"
1036#undef GET_REGISTER_MATCHER
1037#undef GET_SUBTARGET_FEATURE_NAME
1042class KernelScopeInfo {
1043 int SgprIndexUnusedMin = -1;
1044 int VgprIndexUnusedMin = -1;
1045 int AgprIndexUnusedMin = -1;
1049 void usesSgprAt(
int i) {
1050 if (i >= SgprIndexUnusedMin) {
1051 SgprIndexUnusedMin = ++i;
1054 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1060 void usesVgprAt(
int i) {
1061 if (i >= VgprIndexUnusedMin) {
1062 VgprIndexUnusedMin = ++i;
1065 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1067 VgprIndexUnusedMin);
1073 void usesAgprAt(
int i) {
1078 if (i >= AgprIndexUnusedMin) {
1079 AgprIndexUnusedMin = ++i;
1082 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1087 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1089 VgprIndexUnusedMin);
1096 KernelScopeInfo() =
default;
1100 MSTI = Ctx->getSubtargetInfo();
1102 usesSgprAt(SgprIndexUnusedMin = -1);
1103 usesVgprAt(VgprIndexUnusedMin = -1);
1105 usesAgprAt(AgprIndexUnusedMin = -1);
1109 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1110 unsigned RegWidth) {
1113 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1116 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1119 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1128 MCAsmParser &Parser;
1130 unsigned ForcedEncodingSize = 0;
1131 bool ForcedDPP =
false;
1132 bool ForcedSDWA =
false;
1133 KernelScopeInfo KernelScope;
1134 const unsigned HwMode;
1136 const AMDGPU::IsaVersion ISA;
1141#define GET_ASSEMBLER_HEADER
1142#include "AMDGPUGenAsmMatcher.inc"
1147 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1149 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1153 std::optional<AMDGPU::InfoSectionData> InfoData;
1162 SmallVector<unsigned> OpcodeStream;
1164 OpcodeStreamSymbols;
1165 SmallPtrSet<const MCSymbol *, 8> AMDHSAKernelSymbols;
1168 void checkKernelPrologues();
1171 void createConstantSymbol(StringRef Id, int64_t Val);
1173 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1174 bool OutOfRangeError(SMRange
Range);
1190 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1191 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1192 std::optional<bool> EnableWavefrontSize32,
1193 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1194 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1195 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1196 bool ParseDirectiveAMDGCNTarget();
1197 bool ParseDirectiveAMDHSACodeObjectVersion();
1198 bool ParseDirectiveAMDHSAKernel();
1199 bool ParseAMDKernelCodeTValue(StringRef ID, AMDGPUMCKernelCodeT &Header);
1200 bool ParseDirectiveAMDKernelCodeT();
1202 bool subtargetHasRegister(
const MCRegisterInfo &
MRI, MCRegister
Reg);
1203 bool ParseDirectiveAMDGPUHsaKernel();
1205 bool ParseDirectiveISAVersion();
1206 bool ParseDirectiveHSAMetadata();
1207 bool ParseDirectivePALMetadataBegin();
1208 bool ParseDirectivePALMetadata();
1209 bool ParseDirectiveAMDGPULDS();
1210 bool ParseDirectiveAMDGPUInfo();
1214 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1215 const char *AssemblerDirectiveEnd,
1216 std::string &CollectString);
1218 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1219 RegisterKind RegKind, MCRegister Reg1,
1220 RegisterKind RegKind1, SMLoc Loc);
1221 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1222 unsigned &RegNum,
unsigned &RegWidth,
1223 bool RestoreOnFailure =
false);
1224 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1225 unsigned &RegNum,
unsigned &RegWidth,
1226 SmallVectorImpl<AsmToken> &Tokens);
1227 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1229 SmallVectorImpl<AsmToken> &Tokens);
1230 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1232 SmallVectorImpl<AsmToken> &Tokens);
1233 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1235 SmallVectorImpl<AsmToken> &Tokens);
1236 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &SubReg);
1237 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1238 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1241 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1242 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1243 void initializeGprCountSymbol(RegisterKind RegKind);
1244 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1250 OperandMode_Default,
1254 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1256 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1257 const MCInstrInfo &MII)
1258 : MCTargetAsmParser(STI, MII), Parser(_Parser),
1259 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)),
1264 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1266 if (ISA.Major >= 6 &&
isHsaAbi(getSTI())) {
1267 createConstantSymbol(
".amdgcn.gfx_generation_number", ISA.Major);
1268 createConstantSymbol(
".amdgcn.gfx_generation_minor", ISA.Minor);
1269 createConstantSymbol(
".amdgcn.gfx_generation_stepping", ISA.Stepping);
1271 createConstantSymbol(
".option.machine_version_major", ISA.Major);
1272 createConstantSymbol(
".option.machine_version_minor", ISA.Minor);
1273 createConstantSymbol(
".option.machine_version_stepping", ISA.Stepping);
1275 if (ISA.Major >= 6 &&
isHsaAbi(getSTI())) {
1276 initializeGprCountSymbol(IS_VGPR);
1277 initializeGprCountSymbol(IS_SGPR);
1282 createConstantSymbol(Symbol, Code);
1284 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1285 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1286 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1326 bool hasBVHRayTracingInsts()
const {
1327 return getFeatureBits()[AMDGPU::FeatureBVHRayTracingInsts];
1330 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1332 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1334 bool hasInv2PiInlineImm()
const {
1335 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1338 bool has64BitLiterals()
const {
1339 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1342 bool hasFlatOffsets()
const {
1343 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1346 bool hasTrue16Insts()
const {
1347 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1351 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1354 bool hasSGPR102_SGPR103()
const {
return !
isVI() && !
isGFX9(); }
1356 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1358 bool hasIntClamp()
const {
return getFeatureBits()[AMDGPU::FeatureIntClamp]; }
1360 bool hasPartialNSAEncoding()
const {
1361 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1364 bool hasGloballyAddressableScratch()
const {
1365 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1368 bool hasScaleOffset()
const {
1369 return getFeatureBits()[AMDGPU::FeatureScaleOffset];
1372 bool hasCacheFillSize()
const {
1373 return getFeatureBits()[AMDGPU::FeatureCacheFillSize];
1386 AMDGPUTargetStreamer &getTargetStreamer() {
1387 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1388 return static_cast<AMDGPUTargetStreamer &
>(TS);
1394 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1397 const MCRegisterInfo *getMRI()
const {
1401 const MCInstrInfo *getMII()
const {
return &MII; }
1405 int16_t getTargetRegClass(
unsigned TargetRCIdx)
const {
1411 const FeatureBitset &getFeatureBits()
const {
1412 return getSTI().getFeatureBits();
1415 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1416 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1417 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1419 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1420 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1421 bool isForcedDPP()
const {
return ForcedDPP; }
1422 bool isForcedSDWA()
const {
return ForcedSDWA; }
1423 ArrayRef<unsigned> getMatchedVariants()
const;
1424 StringRef getMatchedVariantName()
const;
1426 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1427 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1428 bool RestoreOnFailure);
1429 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1430 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1431 SMLoc &EndLoc)
override;
1432 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1433 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1434 unsigned Kind)
override;
1435 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1438 bool MatchingInlineAsm)
override;
1439 bool ParseDirective(AsmToken DirectiveID)
override;
1440 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override;
1441 void onEndOfFile()
override;
1443 OperandMode
Mode = OperandMode_Default);
1444 StringRef parseMnemonicSuffix(StringRef Name);
1445 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1451 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1455 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1456 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1458 ParseStatus parseOperandArrayWithPrefix(
1460 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1461 bool (*ConvertResult)(int64_t &) =
nullptr);
1465 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1466 bool IgnoreNegative =
false);
1467 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1472 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1476 ArrayRef<const char *> Ids,
1480 ArrayRef<const char *> Ids,
1481 AMDGPUOperand::ImmTy
Type);
1484 bool isOperandModifier(
const AsmToken &Token,
1485 const AsmToken &NextToken)
const;
1486 bool isRegOrOperandModifier(
const AsmToken &Token,
1487 const AsmToken &NextToken)
const;
1488 bool isNamedOperandModifier(
const AsmToken &Token,
1489 const AsmToken &NextToken)
const;
1490 bool isOpcodeModifierWithVal(
const AsmToken &Token,
1491 const AsmToken &NextToken)
const;
1492 bool parseSP3NegModifier();
1499 bool AllowImm =
true);
1501 bool AllowImm =
true);
1507 AMDGPUOperand::ImmTy ImmTy);
1512 AMDGPUOperand::ImmTy
Type);
1516 AMDGPUOperand::ImmTy
Type);
1520 AMDGPUOperand::ImmTy
Type);
1524 ParseStatus parseDfmtNfmt(int64_t &
Format);
1525 ParseStatus parseUfmt(int64_t &
Format);
1526 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1528 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1531 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1532 ParseStatus parseNumericFormat(int64_t &
Format);
1536 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1537 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr,
1542 bool parseCnt(int64_t &IntVal);
1545 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1546 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1549 bool parseDelay(int64_t &Delay);
1555 struct OperandInfoTy {
1558 bool IsSymbolic =
false;
1559 bool IsDefined =
false;
1561 constexpr OperandInfoTy(int64_t Val) : Val(Val) {}
1564 struct StructuredOpField : OperandInfoTy {
1568 bool IsDefined =
false;
1570 constexpr StructuredOpField(StringLiteral Id, StringLiteral Desc,
1571 unsigned Width, int64_t
Default)
1572 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1573 virtual ~StructuredOpField() =
default;
1575 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1576 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1580 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1582 return Error(Parser,
"not supported on this GPU");
1584 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1592 bool parseSendMsgBody(OperandInfoTy &
Msg, OperandInfoTy &
Op,
1593 OperandInfoTy &Stream);
1594 bool validateSendMsg(
const OperandInfoTy &
Msg,
const OperandInfoTy &
Op,
1595 const OperandInfoTy &Stream);
1597 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1598 OperandInfoTy &Width);
1603 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1610 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand &)>
Test,
1612 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1616 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1622 bool validateBF16InlineConst(
const MCInst &Inst,
1625 bool validateConstantBusLimitations(
const MCInst &Inst,
1627 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1630 bool tryVOPD(
const MCInst &Inst);
1631 bool tryVOPD3(
const MCInst &Inst);
1632 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1634 bool validateIntClampSupported(
const MCInst &Inst);
1635 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1636 bool validateMIMGGatherDMask(
const MCInst &Inst);
1638 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1639 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1640 bool validateMIMGD16(
const MCInst &Inst);
1642 bool validateTensorR128(
const MCInst &Inst);
1643 bool validateMIMGMSAA(
const MCInst &Inst);
1644 bool validateOpSel(
const MCInst &Inst);
1645 bool validateTrue16OpSel(
const MCInst &Inst);
1646 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1648 bool validateVccOperand(MCRegister
Reg)
const;
1653 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1654 bool validateVGPRAlign(
const MCInst &Inst)
const;
1658 bool validateDivScale(
const MCInst &Inst);
1663 const unsigned CPol);
1669 bool validateClusterBarrierIsFirst(
const MCInst &Inst,
1672 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1673 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1674 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1675 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1677 bool isSupportedMnemo(StringRef Mnemo,
const FeatureBitset &FBS);
1678 bool isSupportedMnemo(StringRef Mnemo,
const FeatureBitset &FBS,
1679 ArrayRef<unsigned> Variants);
1680 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1682 bool isId(
const StringRef Id)
const;
1683 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1685 StringRef getId()
const;
1686 bool trySkipId(
const StringRef Id);
1687 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1691 bool parseString(StringRef &Val,
1692 const StringRef ErrMsg =
"expected a string");
1693 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1699 StringRef getTokenStr()
const;
1700 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1702 SMLoc getLoc()
const;
1706 void onBeginOfFile()
override;
1711 void emitTargetDirective();
1712 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1724 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1725 const unsigned MaxVal,
const Twine &ErrMsg,
1727 bool parseSwizzleOperands(
const unsigned OpNum, int64_t *
Op,
1728 const unsigned MinVal,
const unsigned MaxVal,
1729 const StringRef ErrMsg);
1731 bool parseSwizzleOffset(int64_t &
Imm);
1732 bool parseSwizzleMacro(int64_t &
Imm);
1733 bool parseSwizzleQuadPerm(int64_t &
Imm);
1734 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1735 bool parseSwizzleBroadcast(int64_t &
Imm);
1736 bool parseSwizzleSwap(int64_t &
Imm);
1737 bool parseSwizzleReverse(int64_t &
Imm);
1738 bool parseSwizzleFFT(int64_t &
Imm);
1739 bool parseSwizzleRotate(int64_t &
Imm);
1742 int64_t parseGPRIdxMacro();
1745 cvtMubufImpl(Inst,
Operands,
false);
1748 cvtMubufImpl(Inst,
Operands,
true);
1754 OptionalImmIndexMap &OptionalIdx);
1763 OptionalImmIndexMap &OptionalIdx);
1765 OptionalImmIndexMap &OptionalIdx);
1769 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1771 bool parseDimId(
unsigned &Encoding);
1773 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1777 int64_t parseDPPCtrlSel(StringRef Ctrl);
1778 int64_t parseDPPCtrlPerm();
1784 bool IsDPP8 =
false);
1790 AMDGPUOperand::ImmTy
Type);
1798 enum class SDWAInstType :
unsigned {
VOP1 = 0,
VOP2 = 1,
VOPC = 2 };
1801 SDWAInstType BasicInstType,
bool SkipDstVcc =
false,
1802 bool SkipSrcVcc =
false);
1912bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
1922 if (!isImmTy(ImmTyNone)) {
1927 if (getModifiers().
Lit != LitModifier::None)
1937 if (type == MVT::f64 || type == MVT::i64) {
1939 AsmParser->hasInv2PiInlineImm());
1942 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
1961 APFloat::rmNearestTiesToEven, &Lost);
1968 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
1970 AsmParser->hasInv2PiInlineImm());
1975 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
1976 AsmParser->hasInv2PiInlineImm());
1980 if (type == MVT::f64 || type == MVT::i64) {
1982 AsmParser->hasInv2PiInlineImm());
1991 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()), type,
1992 AsmParser->hasInv2PiInlineImm());
1996 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
1997 AsmParser->hasInv2PiInlineImm());
2000bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2002 if (!isImmTy(ImmTyNone)) {
2007 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2012 if (type == MVT::f64 && hasFPModifiers()) {
2032 if (type == MVT::f64) {
2037 if (type == MVT::i64) {
2050 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2051 : (type == MVT::v2i16) ? MVT::f32
2052 : (type == MVT::v2f32) ? MVT::f32
2055 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2059bool AMDGPUOperand::isRegClassTarget(
unsigned TargetRCIdx)
const {
2062 int16_t RCID = AsmParser->getTargetRegClass(TargetRCIdx);
2063 return RCID >= 0 && isRegClass(RCID);
2066bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2067 return isRegKind() &&
2068 AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2071bool AMDGPUOperand::isVRegWithInputMods()
const {
2072 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2074 (AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP] &&
2075 isRegClassTarget(AMDGPU::VReg_64_AlignTarget));
2078template <
bool IsFake16>
2079bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2080 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2081 : AMDGPU::VGPR_16_Lo128RegClassID);
2084template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2085 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2086 : AMDGPU::VGPR_16RegClassID);
2089bool AMDGPUOperand::isT16_LO16VRegWithInputMods()
const {
2090 return isRegClass(AMDGPU::VGPR_16_LO16RegClassID);
2093bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2094 if (AsmParser->isVI())
2096 if (AsmParser->isGFX9Plus())
2097 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2101bool AMDGPUOperand::isSDWAFP16Operand()
const {
2102 return isSDWAOperand(MVT::f16);
2105bool AMDGPUOperand::isSDWAFP32Operand()
const {
2106 return isSDWAOperand(MVT::f32);
2109bool AMDGPUOperand::isSDWAInt16Operand()
const {
2110 return isSDWAOperand(MVT::i16);
2113bool AMDGPUOperand::isSDWAInt32Operand()
const {
2114 return isSDWAOperand(MVT::i32);
2117bool AMDGPUOperand::isBoolReg()
const {
2118 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2119 (AsmParser->isWave32() && isSCSrc_b32()));
2123 unsigned Size)
const {
2124 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2139void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
2140 bool ApplyModifiers)
const {
2150 addLiteralImmOperand(Inst,
Imm.Val,
2151 ApplyModifiers & isImmTy(ImmTyNone) &&
2152 Imm.Mods.hasFPModifiers());
2154 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2159void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
2160 bool ApplyModifiers)
const {
2161 const auto &InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2166 if (ApplyModifiers) {
2168 const unsigned Size =
2170 Val = applyInputFPModifiers(Val,
Size);
2174 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2176 bool CanUse64BitLiterals =
2179 MCContext &Ctx = AsmParser->getContext();
2190 if (
Lit == LitModifier::None &&
2192 AsmParser->hasInv2PiInlineImm())) {
2200 bool HasMandatoryLiteral =
2203 if (
Literal.getLoBits(32) != 0 &&
2204 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2205 !HasMandatoryLiteral) {
2206 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2208 "Can't encode literal as exact 64-bit floating-point operand. "
2209 "Low 32-bits will be set to zero");
2210 Val &= 0xffffffff00000000u;
2216 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2222 Lit = LitModifier::Lit64;
2223 }
else if (
Lit == LitModifier::Lit) {
2237 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2239 Lit = LitModifier::Lit64;
2246 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2247 Literal == 0x3fc45f306725feed) {
2287 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2294 if (
Lit != LitModifier::None) {
2325 if (
Lit == LitModifier::None &&
2335 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2343 if (
Lit == LitModifier::None &&
2351 if (!AsmParser->has64BitLiterals()) {
2352 Val =
static_cast<uint64_t>(Val) << 32;
2359 if (
Lit == LitModifier::Lit ||
2361 Val =
static_cast<uint64_t>(Val) << 32;
2365 if (
Lit == LitModifier::Lit)
2392 if (
Lit != LitModifier::None) {
2400void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2406bool AMDGPUOperand::isInlineValue()
const {
2414void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2425 if (Is == IS_VGPR) {
2430 return AMDGPU::VGPR_32RegClassID;
2432 return AMDGPU::VReg_64RegClassID;
2434 return AMDGPU::VReg_96RegClassID;
2436 return AMDGPU::VReg_128RegClassID;
2438 return AMDGPU::VReg_160RegClassID;
2440 return AMDGPU::VReg_192RegClassID;
2442 return AMDGPU::VReg_224RegClassID;
2444 return AMDGPU::VReg_256RegClassID;
2446 return AMDGPU::VReg_288RegClassID;
2448 return AMDGPU::VReg_320RegClassID;
2450 return AMDGPU::VReg_352RegClassID;
2452 return AMDGPU::VReg_384RegClassID;
2454 return AMDGPU::VReg_512RegClassID;
2456 return AMDGPU::VReg_1024RegClassID;
2458 }
else if (Is == IS_TTMP) {
2463 return AMDGPU::TTMP_32RegClassID;
2465 return AMDGPU::TTMP_64RegClassID;
2467 return AMDGPU::TTMP_128RegClassID;
2469 return AMDGPU::TTMP_256RegClassID;
2471 return AMDGPU::TTMP_512RegClassID;
2473 }
else if (Is == IS_SGPR) {
2478 return AMDGPU::SGPR_32RegClassID;
2480 return AMDGPU::SGPR_64RegClassID;
2482 return AMDGPU::SGPR_96RegClassID;
2484 return AMDGPU::SGPR_128RegClassID;
2486 return AMDGPU::SGPR_160RegClassID;
2488 return AMDGPU::SGPR_192RegClassID;
2490 return AMDGPU::SGPR_224RegClassID;
2492 return AMDGPU::SGPR_256RegClassID;
2494 return AMDGPU::SGPR_288RegClassID;
2496 return AMDGPU::SGPR_320RegClassID;
2498 return AMDGPU::SGPR_352RegClassID;
2500 return AMDGPU::SGPR_384RegClassID;
2502 return AMDGPU::SGPR_512RegClassID;
2504 }
else if (Is == IS_AGPR) {
2509 return AMDGPU::AGPR_32RegClassID;
2511 return AMDGPU::AReg_64RegClassID;
2513 return AMDGPU::AReg_96RegClassID;
2515 return AMDGPU::AReg_128RegClassID;
2517 return AMDGPU::AReg_160RegClassID;
2519 return AMDGPU::AReg_192RegClassID;
2521 return AMDGPU::AReg_224RegClassID;
2523 return AMDGPU::AReg_256RegClassID;
2525 return AMDGPU::AReg_288RegClassID;
2527 return AMDGPU::AReg_320RegClassID;
2529 return AMDGPU::AReg_352RegClassID;
2531 return AMDGPU::AReg_384RegClassID;
2533 return AMDGPU::AReg_512RegClassID;
2535 return AMDGPU::AReg_1024RegClassID;
2543 .
Case(
"exec", AMDGPU::EXEC)
2544 .
Case(
"vcc", AMDGPU::VCC)
2545 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2546 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2547 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2548 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2549 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2550 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2551 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2552 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2553 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2554 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2555 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2556 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2557 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2558 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2559 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2560 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2561 .
Case(
"m0", AMDGPU::M0)
2562 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2563 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2564 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2565 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2566 .
Case(
"scc", AMDGPU::SRC_SCC)
2567 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2568 .
Case(
"tba", AMDGPU::TBA)
2569 .
Case(
"tma", AMDGPU::TMA)
2570 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2571 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2572 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2573 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2574 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2575 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2576 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2577 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2578 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2579 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2580 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2581 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2582 .
Case(
"pc", AMDGPU::PC_REG)
2583 .
Case(
"null", AMDGPU::SGPR_NULL)
2587bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2588 SMLoc &EndLoc,
bool RestoreOnFailure) {
2589 auto R = parseRegister();
2593 RegNo =
R->getReg();
2594 StartLoc =
R->getStartLoc();
2595 EndLoc =
R->getEndLoc();
2599bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2601 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2604ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2606 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2607 bool PendingErrors = getParser().hasPendingError();
2608 getParser().clearPendingErrors();
2616bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2617 RegisterKind RegKind,
2619 RegisterKind RegKind1, SMLoc Loc) {
2621 if (RegKind == IS_SGPR) {
2622 unsigned RegIdx = (
Reg - AMDGPU::SGPR0) + RegWidth / 32;
2623 if ((RegIdx == 106 && Reg1 == AMDGPU::VCC_LO) ||
2624 (RegIdx == 107 && Reg1 == AMDGPU::VCC_HI)) {
2630 if (RegKind != RegKind1) {
2631 Error(Loc,
"registers in a list must be of the same kind");
2637 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2642 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2643 Reg = AMDGPU::FLAT_SCR;
2647 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2648 Reg = AMDGPU::XNACK_MASK;
2652 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2657 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2662 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2667 Error(Loc,
"register does not fit in the list");
2673 if (Reg1 !=
Reg + RegWidth / 32) {
2674 Error(Loc,
"registers in a list must have consecutive indices");
2690 {{
"v"}, IS_VGPR}, {{
"s"}, IS_SGPR}, {{
"ttmp"}, IS_TTMP},
2691 {{
"acc"}, IS_AGPR}, {{
"a"}, IS_AGPR},
2695 return Kind == IS_VGPR || Kind == IS_SGPR || Kind == IS_TTMP ||
2701 if (Str.starts_with(
Reg.Name))
2707 return !Str.getAsInteger(10, Num);
2710bool AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2711 const AsmToken &NextToken)
const {
2726 StringRef RegSuffix = Str.substr(
RegName.size());
2727 if (!RegSuffix.
empty()) {
2744bool AMDGPUAsmParser::isRegister() {
2745 return isRegister(
getToken(), peekToken());
2748MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2749 unsigned SubReg,
unsigned RegWidth,
2753 unsigned AlignSize = 1;
2754 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2760 if (RegNum % AlignSize != 0) {
2761 Error(Loc,
"invalid register alignment");
2762 return MCRegister();
2765 unsigned RegIdx = RegNum / AlignSize;
2768 Error(Loc,
"invalid or unsupported register size");
2769 return MCRegister();
2773 const MCRegisterClass &RC =
TRI->getRegClass(RCID);
2774 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2775 Error(Loc,
"register index is out of range");
2776 return AMDGPU::NoRegister;
2779 if (RegKind == IS_VGPR && !
isGFX1250Plus() && RegIdx + RegWidth / 32 > 256) {
2780 Error(Loc,
"register index is out of range");
2781 return MCRegister();
2790 Error(Loc,
"invalid subregister");
2796bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2798 int64_t RegLo, RegHi;
2802 SMLoc FirstIdxLoc = getLoc();
2809 SecondIdxLoc = getLoc();
2820 Error(FirstIdxLoc,
"invalid register index");
2825 Error(SecondIdxLoc,
"invalid register index");
2829 if (RegLo > RegHi) {
2830 Error(FirstIdxLoc,
"first register index should not exceed second index");
2834 if (RegHi == RegLo) {
2835 StringRef RegSuffix = getTokenStr();
2836 if (RegSuffix ==
".l") {
2837 SubReg = AMDGPU::lo16;
2839 }
else if (RegSuffix ==
".h") {
2840 SubReg = AMDGPU::hi16;
2845 Num =
static_cast<unsigned>(RegLo);
2846 RegWidth = 32 * ((RegHi - RegLo) + 1);
2851MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2854 SmallVectorImpl<AsmToken> &Tokens) {
2860 RegKind = IS_SPECIAL;
2867MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2870 SmallVectorImpl<AsmToken> &Tokens) {
2872 StringRef
RegName = getTokenStr();
2873 auto Loc = getLoc();
2877 Error(Loc,
"invalid register name");
2878 return MCRegister();
2886 unsigned SubReg = NoSubRegister;
2887 bool IsRange =
false;
2888 if (!RegSuffix.
empty()) {
2890 SubReg = AMDGPU::lo16;
2892 SubReg = AMDGPU::hi16;
2896 Error(Loc,
"invalid register index");
2897 return MCRegister();
2903 if (!ParseRegRange(RegNum, RegWidth, SubReg))
2904 return MCRegister();
2908 MCRegister
Reg = getRegularReg(RegKind, RegNum, SubReg, RegWidth, Loc);
2909 const MCRegisterInfo &
TRI = *
getContext().getRegisterInfo();
2910 if (RegKind == IS_SGPR && IsRange
2911 ? (
TRI.isSubRegister(
Reg, VCC_LO) ||
TRI.isSubRegister(
Reg, VCC_HI))
2912 : (
Reg == VCC_LO ||
Reg == VCC_HI)) {
2913 Error(Loc,
"register index is out of range");
2914 return MCRegister();
2920MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
2921 unsigned &RegNum,
unsigned &RegWidth,
2922 SmallVectorImpl<AsmToken> &Tokens) {
2924 auto ListLoc = getLoc();
2927 "expected a register or a list of registers")) {
2928 return MCRegister();
2933 auto Loc = getLoc();
2934 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
2935 return MCRegister();
2936 if (RegWidth != 32) {
2937 Error(Loc,
"expected a single 32-bit register");
2938 return MCRegister();
2942 RegisterKind NextRegKind;
2944 unsigned NextRegNum, NextRegWidth;
2947 if (!ParseAMDGPURegister(NextRegKind, NextReg, NextRegNum, NextRegWidth,
2949 return MCRegister();
2951 if (NextRegWidth != 32) {
2952 Error(Loc,
"expected a single 32-bit register");
2953 return MCRegister();
2955 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, NextRegKind,
2957 return MCRegister();
2961 "expected a comma or a closing square bracket")) {
2962 return MCRegister();
2966 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
2971bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
2972 MCRegister &
Reg,
unsigned &RegNum,
2974 SmallVectorImpl<AsmToken> &Tokens) {
2975 auto Loc = getLoc();
2979 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
2981 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
2983 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
2988 assert(Parser.hasPendingError());
2992 if (!subtargetHasRegister(*
TRI,
Reg)) {
2993 if (
Reg == AMDGPU::SGPR_NULL) {
2994 Error(Loc,
"'null' operand is not supported on this GPU");
2997 " register not available on this GPU");
3005bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3006 MCRegister &
Reg,
unsigned &RegNum,
3008 bool RestoreOnFailure ) {
3012 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3013 if (RestoreOnFailure) {
3014 while (!Tokens.
empty()) {
3023std::optional<StringRef>
3024AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3027 return StringRef(
".amdgcn.next_free_vgpr");
3029 return StringRef(
".amdgcn.next_free_sgpr");
3031 return std::nullopt;
3035void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3036 auto SymbolName = getGprCountSymbolName(RegKind);
3037 assert(SymbolName &&
"initializing invalid register kind");
3043bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3044 unsigned DwordRegIndex,
3045 unsigned RegWidth) {
3050 auto SymbolName = getGprCountSymbolName(RegKind);
3055 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3059 return !
Error(getLoc(),
3060 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3064 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3066 if (OldCount <= NewMax)
3072std::unique_ptr<AMDGPUOperand>
3073AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3075 SMLoc StartLoc = Tok.getLoc();
3076 SMLoc EndLoc = Tok.getEndLoc();
3077 RegisterKind RegKind;
3079 unsigned RegNum, RegWidth;
3081 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3085 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3088 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3089 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3096 if (isRegister() || isModifier())
3099 if (
Lit == LitModifier::None) {
3100 if (trySkipId(
"lit"))
3101 Lit = LitModifier::Lit;
3102 else if (trySkipId(
"lit64"))
3103 Lit = LitModifier::Lit64;
3105 if (
Lit != LitModifier::None) {
3108 ParseStatus S = parseImm(
Operands, HasSP3AbsModifier,
Lit);
3117 const auto &NextTok = peekToken();
3120 bool Negate =
false;
3128 AMDGPUOperand::Modifiers Mods;
3136 StringRef Num = getTokenStr();
3139 APFloat RealVal(APFloat::IEEEdouble());
3140 auto roundMode = APFloat::rmNearestTiesToEven;
3141 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3144 RealVal.changeSign();
3147 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(),
3148 S, AMDGPUOperand::ImmTyNone,
true));
3149 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3150 Op.setModifiers(Mods);
3159 if (HasSP3AbsModifier) {
3168 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3171 if (Parser.parseExpression(Expr))
3175 if (Expr->evaluateAsAbsolute(IntVal)) {
3177 return Error(S,
"literal value out of range");
3178 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3179 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3180 Op.setModifiers(Mods);
3182 if (
Lit != LitModifier::None)
3184 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3197 if (
auto R = parseRegister()) {
3207 ParseStatus Res = parseReg(
Operands);
3215bool AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
3216 const AsmToken &NextToken)
const {
3219 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3224bool AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
3225 const AsmToken &NextToken)
const {
3229bool AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
3230 const AsmToken &NextToken)
const {
3231 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3234bool AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
3235 const AsmToken &NextToken)
const {
3236 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3253bool AMDGPUAsmParser::isModifier() {
3256 AsmToken NextToken[2];
3257 peekTokens(NextToken);
3261 bool IsOpcodeModifier = isOpcodeModifierWithVal(Tok, NextToken[0]) &&
3264 return isOperandModifier(Tok, NextToken[0]) ||
3266 isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3292bool AMDGPUAsmParser::parseSP3NegModifier() {
3294 AsmToken NextToken[2];
3295 peekTokens(NextToken);
3298 (isRegister(NextToken[0], NextToken[1]) ||
3316 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3318 SP3Neg = parseSP3NegModifier();
3321 Neg = trySkipId(
"neg");
3323 return Error(Loc,
"expected register or immediate");
3327 Abs = trySkipId(
"abs");
3332 if (trySkipId(
"lit")) {
3333 Lit = LitModifier::Lit;
3336 }
else if (trySkipId(
"lit64")) {
3337 Lit = LitModifier::Lit64;
3340 if (!has64BitLiterals())
3341 return Error(Loc,
"lit64 is not supported on this GPU");
3347 return Error(Loc,
"expected register or immediate");
3356 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3360 if (
Lit != LitModifier::None && !
Operands.back()->isImm())
3361 Error(Loc,
"expected immediate with lit modifier");
3363 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3369 if (
Lit != LitModifier::None &&
3373 AMDGPUOperand::Modifiers Mods;
3374 Mods.Abs = Abs || SP3Abs;
3375 Mods.Neg = Neg || SP3Neg;
3378 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3379 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3381 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3382 Op.setModifiers(Mods);
3390 bool Sext = trySkipId(
"sext");
3391 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3406 AMDGPUOperand::Modifiers Mods;
3409 if (Mods.hasIntModifiers()) {
3410 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3412 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3413 Op.setModifiers(Mods);
3420 return parseRegOrImmWithFPInputMods(
Operands,
false);
3424 return parseRegOrImmWithIntInputMods(
Operands,
false);
3431 if (!trySkipId(
"rsrcidx"))
3437 SMLoc RegLoc = getLoc();
3438 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3446 if (!
Reg->isRsrcReg32())
3447 return Error(RegLoc,
"rsrcidx operand must be a 32-bit SGPR or VGPR");
3457 auto Loc = getLoc();
3458 if (trySkipId(
"off")) {
3460 AMDGPUOperand::CreateImm(
this, 0, Loc, AMDGPUOperand::ImmTyOff,
false));
3467 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3476unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3481 return Match_InvalidOperand;
3483 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3484 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3487 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3489 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3490 return Match_InvalidOperand;
3498 if (tryAnotherVOPDEncoding(Inst))
3499 return Match_InvalidOperand;
3501 return Match_Success;
3505 static const unsigned Variants[] = {
3514ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3515 if (isForcedDPP() && isForcedVOP3()) {
3519 if (getForcedEncodingSize() == 32) {
3524 if (isForcedVOP3()) {
3529 if (isForcedSDWA()) {
3535 if (isForcedDPP()) {
3543StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3544 if (isForcedDPP() && isForcedVOP3())
3547 if (getForcedEncodingSize() == 32)
3563AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3567 case AMDGPU::FLAT_SCR:
3569 case AMDGPU::VCC_LO:
3570 case AMDGPU::VCC_HI:
3577 return MCRegister();
3584bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3585 unsigned OpIdx)
const {
3593 const MCOperand &MO = Inst.
getOperand(OpIdx);
3643unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3649 case AMDGPU::V_LSHLREV_B64_e64:
3650 case AMDGPU::V_LSHLREV_B64_gfx10:
3651 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3652 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3653 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3654 case AMDGPU::V_LSHRREV_B64_e64:
3655 case AMDGPU::V_LSHRREV_B64_gfx10:
3656 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3657 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3658 case AMDGPU::V_ASHRREV_I64_e64:
3659 case AMDGPU::V_ASHRREV_I64_gfx10:
3660 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3661 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3662 case AMDGPU::V_LSHL_B64_e64:
3663 case AMDGPU::V_LSHR_B64_e64:
3664 case AMDGPU::V_ASHR_I64_e64:
3677 bool AddMandatoryLiterals =
false) {
3680 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3684 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3686 return {getNamedOperandIdx(Opcode, OpName::src0X),
3687 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3688 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3689 getNamedOperandIdx(Opcode, OpName::src0Y),
3690 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3691 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3696 return {getNamedOperandIdx(Opcode, OpName::src0),
3697 getNamedOperandIdx(Opcode, OpName::src1),
3698 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3701bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3702 const MCOperand &MO = Inst.
getOperand(OpIdx);
3704 return !isInlineConstant(Inst, OpIdx);
3711 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3722 const unsigned Opcode = Inst.
getOpcode();
3723 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3726 if (!LaneSelOp.
isReg())
3729 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3732bool AMDGPUAsmParser::validateConstantBusLimitations(
3734 const unsigned Opcode = Inst.
getOpcode();
3735 const MCInstrDesc &
Desc = MII.
get(Opcode);
3736 MCRegister LastSGPR;
3737 unsigned ConstantBusUseCount = 0;
3738 unsigned NumLiterals = 0;
3739 unsigned LiteralSize;
3755 SmallDenseSet<MCRegister> SGPRsUsed;
3756 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3758 SGPRsUsed.
insert(SGPRUsed);
3759 ++ConstantBusUseCount;
3764 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3766 for (
int OpIdx : OpIndices) {
3770 const MCOperand &MO = Inst.
getOperand(OpIdx);
3771 if (usesConstantBus(Inst, OpIdx)) {
3780 if (SGPRsUsed.
insert(LastSGPR).second) {
3781 ++ConstantBusUseCount;
3801 if (NumLiterals == 0) {
3804 }
else if (LiteralSize !=
Size) {
3810 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3812 "invalid operand (violates constant bus restrictions)");
3819std::optional<unsigned>
3820AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3822 const unsigned Opcode = Inst.
getOpcode();
3828 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3829 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3838 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1170 ||
3839 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3840 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3841 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx13 ||
3842 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250 ||
3843 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx13;
3847 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3848 int I = getNamedOperandIdx(Opcode, OpName);
3852 int64_t
Imm =
Op.getImm();
3858 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3859 OpName::vsrc2Y, OpName::imm}) {
3860 int I = getNamedOperandIdx(Opcode, OpName);
3870 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3871 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3873 return InvalidCompOprIdx;
3876bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
3883 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand :
Operands) {
3884 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
3885 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
3887 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
3891 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
3892 if (!InvalidCompOprIdx.has_value())
3895 auto CompOprIdx = *InvalidCompOprIdx;
3898 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3899 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3902 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
3903 if (CompOprIdx == VOPD::Component::DST) {
3905 Error(Loc,
"dst registers must be distinct");
3907 Error(Loc,
"one dst register must be even and the other odd");
3909 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3910 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
3911 " operands must use different VGPR banks");
3919bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
3921 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
3922 if (!InvalidCompOprIdx.has_value())
3926 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
3927 if (InvalidCompOprIdx.has_value()) {
3932 if (*InvalidCompOprIdx == VOPD::Component::DST)
3945bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
3946 const unsigned Opcode = Inst.
getOpcode();
3961 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
3962 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
3963 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
3964 int I = getNamedOperandIdx(Opcode, OpName);
3971 return !tryVOPD3(Inst);
3976bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
3981 return tryVOPD(Inst);
3982 return tryVOPD3(Inst);
3985bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
3990 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
3998bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc) {
4006 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4007 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4008 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4013 if ((DMaskIdx == -1 || TFEIdx == -1) &&
4014 hasBVHRayTracingInsts())
4017 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4018 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4023 bool IsPackedD16 =
false;
4026 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4027 IsPackedD16 = D16Idx >= 0;
4029 DataSize = (DataSize + 1) / 2;
4032 if ((VDataSize / 4) == DataSize + TFESize)
4037 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4039 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4041 Error(IDLoc, Twine(
"image data size does not match ") + Modifiers);
4045bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4054 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4056 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4057 AMDGPU::OpName RSrcOpName =
4059 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4060 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4061 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4065 assert(SrsrcIdx > VAddr0Idx);
4068 if (BaseOpcode->
BVH) {
4069 if (IsA16 == BaseOpcode->
A16)
4071 Error(IDLoc,
"image address size does not match a16");
4077 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4078 unsigned ActualAddrSize =
4079 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4081 unsigned ExpectedAddrSize =
4085 if (hasPartialNSAEncoding() &&
4087 int VAddrLastIdx = SrsrcIdx - 1;
4088 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4090 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4093 if (ExpectedAddrSize > 12)
4094 ExpectedAddrSize = 16;
4099 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4103 if (ActualAddrSize == ExpectedAddrSize)
4106 Error(IDLoc,
"image address size does not match dim and a16");
4110bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4117 if (!
Desc.mayLoad() || !
Desc.mayStore())
4120 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4127 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4130bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4137 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4145 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4148bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4162 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4163 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4170bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4177 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4180 if (!BaseOpcode->
MSAA)
4183 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4189 return DimInfo->
MSAA;
4194 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4195 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4196 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4206bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4214 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4225 Error(getOperandLoc(
Operands, Src0Idx),
"source operand must be a VGPR");
4229bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4234 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4237 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4248 "source operand must be either a VGPR or an inline constant");
4255bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4260 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4263 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4267 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4269 "inline constants are not allowed for this operand");
4276bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4284 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4285 if (BlgpIdx != -1) {
4286 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4287 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4297 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4299 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4304 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4306 "wrong register tuple size for blgp value " + Twine(BLGP));
4314 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4324 if (Src2Reg == DstReg)
4329 .getSizeInBits() <= 128)
4332 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4334 "source 2 operand must not partially overlap with dst");
4341bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4345 case V_DIV_SCALE_F32_gfx6_gfx7:
4346 case V_DIV_SCALE_F32_vi:
4347 case V_DIV_SCALE_F32_gfx10:
4348 case V_DIV_SCALE_F64_gfx6_gfx7:
4349 case V_DIV_SCALE_F64_vi:
4350 case V_DIV_SCALE_F64_gfx10:
4357 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src2_modifiers,
4358 AMDGPU::OpName::src2_modifiers}) {
4369bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4376 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4385bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4391 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4398 case AMDGPU::V_SUBREV_F32_e32:
4399 case AMDGPU::V_SUBREV_F32_e64:
4400 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4401 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4402 case AMDGPU::V_SUBREV_F32_e32_vi:
4403 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4404 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4405 case AMDGPU::V_SUBREV_F32_e64_vi:
4407 case AMDGPU::V_SUBREV_CO_U32_e32:
4408 case AMDGPU::V_SUBREV_CO_U32_e64:
4409 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4410 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4412 case AMDGPU::V_SUBBREV_U32_e32:
4413 case AMDGPU::V_SUBBREV_U32_e64:
4414 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4415 case AMDGPU::V_SUBBREV_U32_e32_vi:
4416 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4417 case AMDGPU::V_SUBBREV_U32_e64_vi:
4419 case AMDGPU::V_SUBREV_U32_e32:
4420 case AMDGPU::V_SUBREV_U32_e64:
4421 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4422 case AMDGPU::V_SUBREV_U32_e32_vi:
4423 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4424 case AMDGPU::V_SUBREV_U32_e64_vi:
4426 case AMDGPU::V_SUBREV_F16_e32:
4427 case AMDGPU::V_SUBREV_F16_e64:
4428 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4429 case AMDGPU::V_SUBREV_F16_e32_vi:
4430 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4431 case AMDGPU::V_SUBREV_F16_e64_vi:
4433 case AMDGPU::V_SUBREV_U16_e32:
4434 case AMDGPU::V_SUBREV_U16_e64:
4435 case AMDGPU::V_SUBREV_U16_e32_vi:
4436 case AMDGPU::V_SUBREV_U16_e64_vi:
4438 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4439 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4440 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4442 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4443 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4445 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4446 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4448 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4449 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4451 case AMDGPU::V_LSHRREV_B32_e32:
4452 case AMDGPU::V_LSHRREV_B32_e64:
4453 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4454 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4455 case AMDGPU::V_LSHRREV_B32_e32_vi:
4456 case AMDGPU::V_LSHRREV_B32_e64_vi:
4457 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4458 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4460 case AMDGPU::V_ASHRREV_I32_e32:
4461 case AMDGPU::V_ASHRREV_I32_e64:
4462 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4463 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4464 case AMDGPU::V_ASHRREV_I32_e32_vi:
4465 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4466 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4467 case AMDGPU::V_ASHRREV_I32_e64_vi:
4469 case AMDGPU::V_LSHLREV_B32_e32:
4470 case AMDGPU::V_LSHLREV_B32_e64:
4471 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4472 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4473 case AMDGPU::V_LSHLREV_B32_e32_vi:
4474 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4475 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4476 case AMDGPU::V_LSHLREV_B32_e64_vi:
4478 case AMDGPU::V_LSHLREV_B16_e32:
4479 case AMDGPU::V_LSHLREV_B16_e64:
4480 case AMDGPU::V_LSHLREV_B16_e32_vi:
4481 case AMDGPU::V_LSHLREV_B16_e64_vi:
4482 case AMDGPU::V_LSHLREV_B16_gfx10:
4484 case AMDGPU::V_LSHRREV_B16_e32:
4485 case AMDGPU::V_LSHRREV_B16_e64:
4486 case AMDGPU::V_LSHRREV_B16_e32_vi:
4487 case AMDGPU::V_LSHRREV_B16_e64_vi:
4488 case AMDGPU::V_LSHRREV_B16_gfx10:
4490 case AMDGPU::V_ASHRREV_I16_e32:
4491 case AMDGPU::V_ASHRREV_I16_e64:
4492 case AMDGPU::V_ASHRREV_I16_e32_vi:
4493 case AMDGPU::V_ASHRREV_I16_e64_vi:
4494 case AMDGPU::V_ASHRREV_I16_gfx10:
4496 case AMDGPU::V_LSHLREV_B64_e64:
4497 case AMDGPU::V_LSHLREV_B64_gfx10:
4498 case AMDGPU::V_LSHLREV_B64_vi:
4500 case AMDGPU::V_LSHRREV_B64_e64:
4501 case AMDGPU::V_LSHRREV_B64_gfx10:
4502 case AMDGPU::V_LSHRREV_B64_vi:
4504 case AMDGPU::V_ASHRREV_I64_e64:
4505 case AMDGPU::V_ASHRREV_I64_gfx10:
4506 case AMDGPU::V_ASHRREV_I64_vi:
4508 case AMDGPU::V_PK_LSHLREV_B16:
4509 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4510 case AMDGPU::V_PK_LSHLREV_B16_vi:
4512 case AMDGPU::V_PK_LSHRREV_B16:
4513 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4514 case AMDGPU::V_PK_LSHRREV_B16_vi:
4515 case AMDGPU::V_PK_ASHRREV_I16:
4516 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4517 case AMDGPU::V_PK_ASHRREV_I16_vi:
4524bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4526 const unsigned Opcode = Inst.
getOpcode();
4535 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4536 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4540 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4544 "lds_direct is not supported on this GPU");
4550 "lds_direct cannot be used with this instruction");
4554 if (SrcName != OpName::src0) {
4556 "lds_direct may be used as src0 only");
4566 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4567 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4568 if (
Op.isFlatOffset())
4569 return Op.getStartLoc();
4574bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4577 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4582 return validateFlatOffset(Inst,
Operands);
4585 return validateSMEMOffset(Inst,
Operands);
4590 const unsigned OffsetSize = 24;
4591 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4593 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4594 "-bit unsigned offset for buffer ops");
4598 const unsigned OffsetSize = 16;
4599 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4601 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4608bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4614 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4618 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4620 "flat offset modifier is not supported on this GPU");
4627 bool AllowNegative =
4629 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4631 Twine(
"expected a ") +
4632 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4633 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4642 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4643 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4644 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4645 return Op.getStartLoc();
4650bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4659 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4675 ?
"expected a 23-bit unsigned offset for buffer ops"
4676 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4677 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4678 :
"expected a 21-bit signed offset");
4684bool AMDGPUAsmParser::validateSMEMSData(
const MCInst &Inst,
4690 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::sdata);
4695 Error(getOperandLoc(
Operands, OpNum),
"expected a 5-bit unsigned immediate");
4704bool AMDGPUAsmParser::validateBF16InlineConst(
const MCInst &Inst,
4706 if (!getFeatureBits()[AMDGPU::FeatureBF16InlineConstFromUpperFP32])
4721 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4725 const MCOperandInfo &Src0Info =
Desc.operands()[Src0Idx];
4730 if (!
Src0.isImm() ||
4732 hasInv2PiInlineImm()))
4737 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
4738 if (ModsIdx != -1 &&
4744 "bf16 inline constant is read from the high half of the fp32 inline "
4745 "constant on this GPU; use the e64 encoding with op_sel:[1,0]");
4749bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4752 const MCInstrDesc &
Desc = MII.
get(Opcode);
4756 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4757 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4759 const int OpIndices[] = {Src0Idx, Src1Idx};
4761 unsigned NumExprs = 0;
4762 unsigned NumLiterals = 0;
4765 for (
int OpIdx : OpIndices) {
4769 const MCOperand &MO = Inst.
getOperand(OpIdx);
4773 std::optional<int64_t>
Imm;
4776 }
else if (MO.
isExpr()) {
4785 if (!
Imm.has_value()) {
4787 }
else if (!isInlineConstant(Inst, OpIdx)) {
4791 if (NumLiterals == 0 || LiteralValue !=
Value) {
4799 if (NumLiterals + NumExprs <= 1)
4803 "only one unique literal operand is allowed");
4807bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4810 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4818 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4819 if (OpSelIdx != -1) {
4823 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4824 if (OpSelHiIdx != -1) {
4833 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4840 if (getFeatureBits()[AMDGPU::FeatureGFX950Insts] &&
4841 (
Opc == AMDGPU::V_PK_ADD_F32_vi ||
Opc == AMDGPU::V_PK_MUL_F32_vi ||
4842 Opc == AMDGPU::V_PK_FMA_F32_vi)) {
4843 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4847 if (
Opc == AMDGPU::V_PK_FMA_F32_vi &&
4848 (((OpSel >> 1) & 1) || ((OpSel >> 2) & 1)))
4851 else if ((OpSel & 3) == 2)
4859 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4860 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4861 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4862 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4871 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4873 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4883 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4884 if (Src2Idx != -1) {
4895bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4896 if (!hasTrue16Insts())
4898 const MCRegisterInfo *
MRI = getMRI();
4900 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4906 if (OpSelOpValue == 0)
4908 unsigned OpCount = 0;
4909 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4910 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4911 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4918 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4919 if (OpSelOpIsHi != VGPRSuffixIsHi)
4928bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4929 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4941 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
4952 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4953 AMDGPU::OpName::src1_modifiers,
4954 AMDGPU::OpName::src2_modifiers};
4956 for (
unsigned i = 0; i < 3; ++i) {
4966bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4969 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
4970 if (DppCtrlIdx >= 0) {
4974 getSTI().
hasFeature(AMDGPU::FeatureDPALU_DPP) &&
4978 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl,
Operands);
4979 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
4980 :
"DP ALU dpp only supports row_newbcast");
4985 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
4986 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4989 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4995 "invalid operand for instruction");
5000 "src1 immediate operand invalid for instruction");
5010bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5011 return (
Reg == AMDGPU::VCC && isWave64()) ||
5012 (
Reg == AMDGPU::VCC_LO && isWave32());
5016bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5019 const MCInstrDesc &
Desc = MII.
get(Opcode);
5020 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5027 std::optional<unsigned> LiteralOpIdx;
5030 for (
int OpIdx : OpIndices) {
5034 const MCOperand &MO = Inst.
getOperand(OpIdx);
5040 std::optional<int64_t>
Imm;
5046 bool IsAnotherLiteral =
false;
5047 bool IsForcedLit = findMCOperand(
Operands, OpIdx).isForcedLit();
5048 bool IsForcedLit64 = findMCOperand(
Operands, OpIdx).isForcedLit64();
5049 if (!
Imm.has_value()) {
5051 IsAnotherLiteral =
true;
5052 }
else if (IsForcedLit || IsForcedLit64 || !isInlineConstant(Inst, OpIdx)) {
5057 HasMandatoryLiteral);
5069 (IsForcedLit64 && !HasMandatoryLiteral)) &&
5070 (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5072 "invalid operand for instruction");
5077 if (!IsForcedFP64 && (IsForcedLit64 || !IsValid32Op) &&
5078 OpIdx != getNamedOperandIdx(Opcode, OpName::src0)) {
5080 "invalid operand for instruction");
5085 if (IsValid32Op && !IsForcedFP64 && !IsForcedLit64) {
5086 Value =
static_cast<uint32_t
>(
5094 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5095 !getFeatureBits()[FeatureVOP3Literal]) {
5097 "literal operands are not supported");
5101 if (LiteralOpIdx && IsAnotherLiteral) {
5103 getOperandLoc(
Operands, *LiteralOpIdx)),
5104 "only one unique literal operand is allowed");
5108 if (IsAnotherLiteral)
5109 LiteralOpIdx = OpIdx;
5118 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), Name);
5132bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5138 ? AMDGPU::OpName::data0
5139 : AMDGPU::OpName::vdata;
5141 const MCRegisterInfo *
MRI = getMRI();
5147 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5151 auto FB = getFeatureBits();
5152 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5153 if (DataAreg < 0 || DstAreg < 0)
5155 return DstAreg == DataAreg;
5158 return DstAreg < 1 && DataAreg < 1;
5161bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5162 auto FB = getFeatureBits();
5163 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5167 const MCRegisterInfo *
MRI = getMRI();
5170 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5173 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5177 case AMDGPU::DS_LOAD_TR6_B96:
5178 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5182 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5183 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5187 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5188 if (VAddrIdx != -1) {
5190 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5191 if ((
Sub - AMDGPU::VGPR0) & 1)
5196 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5197 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5202 const MCRegisterClass &VGPR32 =
MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5203 const MCRegisterClass &AGPR32 =
MRI->
getRegClass(AMDGPU::AGPR_32RegClassID);
5209 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5223 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
5224 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
5226 return Op.getStartLoc();
5231bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5234 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5237 SMLoc BLGPLoc = getBLGPLoc(
Operands);
5240 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5241 auto FB = getFeatureBits();
5242 bool UsesNeg =
false;
5243 if (FB[AMDGPU::FeatureGFX940Insts]) {
5245 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5246 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5247 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5248 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5253 if (IsNeg == UsesNeg)
5256 Error(BLGPLoc, UsesNeg ?
"invalid modifier: blgp is not supported"
5257 :
"invalid modifier: neg is not supported");
5262bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5268 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5269 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5270 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5271 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5274 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5277 if (
Reg == AMDGPU::SGPR_NULL)
5280 Error(getOperandLoc(
Operands, Src0Idx),
"src0 must be null");
5284bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5289 return validateGWS(Inst,
Operands);
5294 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5299 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS,
Operands);
5300 Error(S,
"gds modifier is not supported on this GPU");
5308bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5310 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5314 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5315 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5318 const MCRegisterInfo *
MRI = getMRI();
5319 const MCRegisterClass &VGPR32 =
MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5321 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5324 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5326 Error(getOperandLoc(
Operands, Data0Pos),
"vgpr must be even aligned");
5333bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5337 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::cpol);
5344 if (!hasCacheFillSize()) {
5345 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5348 Error(S,
"Cache fill size is not supported on this GPU");
5349 }
else if (!validateCFSBits(Inst,
Operands)) {
5354 if (!hasScaleOffset() && (CPol &
CPol::SCAL)) {
5355 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5358 Error(S,
"scale_offset is not supported on this GPU");
5362 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5365 Error(S,
"nv is not supported on this GPU");
5369 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5372 Error(S,
"scale_offset is not supported for this instruction");
5376 return validateTHAndScopeBits(Inst,
Operands, CPol);
5380 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5381 Error(S,
"cache policy is not supported for SMRD instructions");
5385 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5392 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5396 "scc modifier is not supported for this instruction on this GPU");
5407 :
"instruction must use glc");
5412 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5415 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5417 :
"instruction must not use glc");
5425bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5427 const unsigned CPol) {
5432 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5439 return PrintError(
"th:TH_ATOMIC_RETURN requires a destination operand");
5444 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5452 return PrintError(
"invalid th value for SMEM instruction");
5459 return PrintError(
"scope and th combination is not valid");
5465 return PrintError(
"invalid th value for atomic instructions");
5468 return PrintError(
"invalid th value for store instructions");
5471 return PrintError(
"invalid th value for load instructions");
5477bool AMDGPUAsmParser::validateCFSBits(
const MCInst &Inst,
5479 const unsigned Opcode = Inst.
getOpcode();
5480 const MCInstrDesc &
Desc = MII.
get(Opcode);
5483 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5491 return PrintError(
"Cache fill size is only supported for VC operations");
5494bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5498 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE,
Operands);
5500 Error(Loc,
"TFE modifier has no meaning for store instructions");
5508bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5514 int AFmtIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
5518 int BFmtIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
5521 auto validateFmt = [&](
unsigned Fmt, AMDGPU::OpName SrcOp) ->
bool {
5522 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5531 "wrong register tuple size for " +
5536 if (!validateFmt(AFmt, AMDGPU::OpName::src0) ||
5537 !validateFmt(BFmt, AMDGPU::OpName::src1))
5541 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
5542 if (AScaleIdx == -1)
5546 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
5550 "invalid matrix and scale format combination");
5557bool AMDGPUAsmParser::validateMonitorSleep(
const MCInst &Inst,
5560 if (
Opc != AMDGPU::S_MONITOR_SLEEP_gfx12 ||
5561 !getSTI().
hasFeature(AMDGPU::FeatureNoSleepForever))
5564 int ImmIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::simm16);
5567 "sleep forever is unsuported on the target");
5574bool AMDGPUAsmParser::validateClusterBarrierIsFirst(
5577 if (
Opc != AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM_gfx12 &&
5578 Opc != AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM_gfx13)
5581 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
5588 "s_barrier_signal_isfirst does not support user_cluster_barrier_id (-3)");
5592bool AMDGPUAsmParser::validateScaleSel(
const MCInst &Inst,
5595 int ScaleSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::scale_sel);
5596 if (ScaleSelIdx == -1)
5600 case AMDGPU::V_CVT_SCALE_PK16_F16_FP6_e64_gfx1250:
5601 case AMDGPU::V_CVT_SCALE_PK16_BF16_FP6_e64_gfx1250:
5602 case AMDGPU::V_CVT_SCALE_PK16_F16_BF6_e64_gfx1250:
5603 case AMDGPU::V_CVT_SCALE_PK16_BF16_BF6_e64_gfx1250:
5604 case AMDGPU::V_CVT_SCALE_PK16_F32_FP6_e64_gfx1250:
5605 case AMDGPU::V_CVT_SCALE_PK16_F32_BF6_e64_gfx1250:
5606 case AMDGPU::V_CVT_SCALE_PK8_F16_FP4_e64_gfx1250:
5607 case AMDGPU::V_CVT_SCALE_PK8_BF16_FP4_e64_gfx1250:
5608 case AMDGPU::V_CVT_SCALE_PK8_F32_FP4_e64_gfx1250:
5611 case AMDGPU::V_CVT_SCALE_PK8_F16_FP8_e64_gfx1250:
5612 case AMDGPU::V_CVT_SCALE_PK8_BF16_FP8_e64_gfx1250:
5613 case AMDGPU::V_CVT_SCALE_PK8_F16_BF8_e64_gfx1250:
5614 case AMDGPU::V_CVT_SCALE_PK8_BF16_BF8_e64_gfx1250:
5615 case AMDGPU::V_CVT_SCALE_PK8_F32_FP8_e64_gfx1250:
5616 case AMDGPU::V_CVT_SCALE_PK8_F32_BF8_e64_gfx1250:
5623 if (getSTI().
hasFeature(AMDGPU::FeatureBlock16ConversionScaleInsts))
5627 if (ScaleSel < MaxSel)
5631 "scale_sel maximum supported value is " + Twine(MaxSel - 1));
5635bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5637 if (!validateLdsDirect(Inst,
Operands))
5639 if (!validateTrue16OpSel(Inst)) {
5641 "op_sel operand conflicts with 16-bit operand suffix");
5644 if (!validateSOPLiteral(Inst,
Operands))
5646 if (!validateVOPLiteral(Inst,
Operands)) {
5649 if (!validateConstantBusLimitations(Inst,
Operands)) {
5652 if (!validateVOPD(Inst,
Operands)) {
5655 if (!validateIntClampSupported(Inst)) {
5657 "integer clamping is not supported on this GPU");
5660 if (!validateOpSel(Inst)) {
5662 "invalid op_sel operand");
5665 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5667 "invalid neg_lo operand");
5670 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5672 "invalid neg_hi operand");
5675 if (!validateDPP(Inst,
Operands)) {
5679 if (!validateMIMGD16(Inst)) {
5681 "d16 modifier is not supported on this GPU");
5684 if (!validateMIMGDim(Inst,
Operands)) {
5685 Error(IDLoc,
"missing dim operand");
5688 if (!validateTensorR128(Inst)) {
5690 "instruction must set modifier r128=0");
5693 if (!validateMIMGMSAA(Inst)) {
5695 "invalid dim; must be MSAA type");
5698 if (!validateMIMGDataSize(Inst, IDLoc)) {
5701 if (!validateMIMGAddrSize(Inst, IDLoc))
5703 if (!validateMIMGAtomicDMask(Inst)) {
5705 "invalid atomic image dmask");
5708 if (!validateMIMGGatherDMask(Inst)) {
5710 "invalid image_gather dmask: only one bit must be set");
5713 if (!validateMovrels(Inst,
Operands)) {
5716 if (!validateOffset(Inst,
Operands)) {
5719 if (!validateSMEMSData(Inst,
Operands))
5721 if (!validateBF16InlineConst(Inst,
Operands)) {
5724 if (!validateMAIAccWrite(Inst,
Operands)) {
5727 if (!validateMAISrc2(Inst,
Operands)) {
5730 if (!validateMFMA(Inst,
Operands)) {
5733 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5737 if (!validateAGPRLdSt(Inst)) {
5740 getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5741 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5742 :
"invalid register class: agpr loads and stores not supported on "
5746 if (!validateVGPRAlign(Inst)) {
5747 Error(IDLoc,
"invalid register class: vgpr tuples must be 64 bit aligned");
5754 if (!validateBLGP(Inst,
Operands)) {
5758 if (!validateDivScale(Inst)) {
5759 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5762 if (!validateWaitCnt(Inst,
Operands)) {
5765 if (!validateTFE(Inst,
Operands)) {
5768 if (!validateWMMA(Inst,
Operands)) {
5771 if (!validateMonitorSleep(Inst,
Operands)) {
5774 if (!validateClusterBarrierIsFirst(Inst,
Operands)) {
5777 if (!validateScaleSel(Inst,
Operands)) {
5786 unsigned VariantID = 0);
5790 unsigned VariantID);
5792bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5797bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5798 const FeatureBitset &FBS,
5799 ArrayRef<unsigned> Variants) {
5800 for (
auto Variant : Variants) {
5808bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5810 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5813 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5818 getParser().clearPendingErrors();
5822 StringRef VariantName = getMatchedVariantName();
5823 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5824 return Error(IDLoc, Twine(VariantName,
5825 " variant of this instruction is not supported"));
5829 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5830 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5832 FeatureBitset FeaturesWS32 = getFeatureBits();
5833 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5834 .
flip(AMDGPU::FeatureWavefrontSize32);
5835 FeatureBitset AvailableFeaturesWS32 =
5836 ComputeAvailableFeatures(FeaturesWS32);
5838 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5839 return Error(IDLoc,
"instruction requires wavesize=32");
5843 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5844 return Error(IDLoc,
"instruction not supported on this GPU (" +
5845 getSTI().
getCPU() +
")" +
": " + Mnemo);
5850 return Error(IDLoc,
"invalid instruction" + Suggestion);
5856 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5857 if (
Op.isToken() && InvalidOprIdx > 1) {
5858 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5859 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5864bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5868 bool MatchingInlineAsm) {
5871 unsigned Result = Match_Success;
5876 auto atLeastAsSpecific = [](
unsigned New,
unsigned Cur) {
5877 auto rank = [](
unsigned M) {
5878 return M == Match_MnemonicFail ? 1
5879 :
M == Match_InvalidOperand ? 2
5880 :
M == Match_MissingFeature ? 3
5883 return rank(New) >= rank(Cur);
5886 for (
auto Variant : getMatchedVariants()) {
5889 MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm, Variant);
5890 if (R == Match_Success || atLeastAsSpecific(R, Result)) {
5894 if (R == Match_Success)
5898 if (Result == Match_Success) {
5899 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5902 emitTargetDirective();
5903 Out.emitInstruction(Inst, getSTI());
5910 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5917 case Match_MissingFeature:
5921 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5923 case Match_InvalidOperand: {
5924 SMLoc ErrorLoc = IDLoc;
5925 if (ErrorInfo != ~0ULL) {
5926 if (ErrorInfo >=
Operands.size()) {
5927 return Error(IDLoc,
"too few operands for instruction");
5929 AMDGPUOperand &ErrorOp = (AMDGPUOperand &)*
Operands[ErrorInfo];
5930 ErrorLoc = ErrorOp.getStartLoc();
5931 if (ErrorLoc == SMLoc())
5935 return Error(ErrorLoc,
"invalid VOPDY instruction");
5937 return Error(ErrorLoc,
"invalid operand for instruction");
5940 case Match_MnemonicFail:
5946bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5951 if (getParser().parseAbsoluteExpression(Tmp)) {
5954 Ret =
static_cast<uint32_t
>(Tmp);
5958bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5959 if (!getSTI().getTargetTriple().isAMDGCN())
5960 return TokError(
"directive only supported for amdgcn architecture");
5962 std::string TargetIDDirective;
5963 SMLoc TargetStart = getTok().getLoc();
5964 if (getParser().parseEscapedString(TargetIDDirective))
5967 std::optional<AMDGPU::TargetID> MaybeParsed =
5970 return getParser().Error(TargetStart,
5971 "malformed target id '" + TargetIDDirective +
"'");
5974 const Triple &
TT = getSTI().getTargetTriple();
5980 return getParser().Error(
5981 TargetStart,
"target id '" + TargetIDDirective +
5982 "' specifies a processor that is not valid for "
5984 TT.getArchName() +
"'");
5987 const std::optional<AMDGPU::TargetID> &CurrentTargetID =
5988 getTargetStreamer().getTargetID();
5991 const Triple &STITriple = getSTI().getTargetTriple();
5992 if (!DirectiveTriple.isCompatibleWith(STITriple)) {
5993 return getParser().Error(
5994 TargetStart,
".amdgcn_target " + Twine(ParsedTargetID.
toString()) +
5995 " is incompatible with " +
5996 Twine(CurrentTargetID->toString()));
6000 StringRef DirectiveProcessor =
6003 if (DirectiveISA != ISA) {
6004 return getParser().Error(TargetStart,
6005 ".amdgcn_target directive processor " +
6006 Twine(DirectiveProcessor) +
6007 " does not match the specified processor " +
6008 Twine(getSTI().
getCPU()));
6014 CurrentTargetID->getXnackSetting())) {
6016 ".amdgcn_target directive has conflicting xnack settings");
6020 CurrentTargetID->getSramEccSetting())) {
6022 ".amdgcn_target directive has conflicting sramecc settings");
6028 getTargetStreamer().getTargetID()->setXnackSetting(
6030 getTargetStreamer().getTargetID()->setSramEccSetting(
6036bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
6040bool AMDGPUAsmParser::calculateGPRBlocks(
6041 const FeatureBitset &Features,
const MCExpr *VCCUsed,
6042 const MCExpr *FlatScrUsed,
bool XNACKUsed,
6043 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
6044 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
6045 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
6050 const MCExpr *
NumSGPRs = NextFreeSGPR;
6051 int64_t EvaluatedSGPRs;
6053 if (
ISA.Major >= 10)
6058 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
ISA.Major >= 8 &&
6059 !Features.
test(FeatureSGPRInitBug) &&
6060 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
6061 return OutOfRangeError(SGPRRange);
6063 const MCExpr *ExtraSGPRs =
6067 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
6068 (
ISA.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
6069 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
6070 return OutOfRangeError(SGPRRange);
6072 if (Features.
test(FeatureSGPRInitBug))
6079 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
6080 unsigned Granule) ->
const MCExpr * {
6084 const MCExpr *AlignToGPR =
6086 const MCExpr *DivGPR =
6092 VGPRBlocks = GetNumGPRBlocks(
6101bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
6102 if (!getSTI().getTargetTriple().isAMDGCN())
6103 return TokError(
"directive only supported for amdgcn architecture");
6106 return TokError(
"directive only supported for amdhsa OS");
6108 StringRef KernelName;
6109 if (getParser().parseIdentifier(KernelName))
6116 AMDGPU::MCKernelDescriptor KD =
6126 const MCExpr *NextFreeVGPR = ZeroExpr;
6128 const MCExpr *NamedBarCnt = ZeroExpr;
6133 const MCExpr *NextFreeSGPR = ZeroExpr;
6136 unsigned ImpliedUserSGPRCount = 0;
6140 std::optional<unsigned> ExplicitUserSGPRCount;
6141 const MCExpr *ReserveVCC = OneExpr;
6142 const MCExpr *ReserveFlatScr = OneExpr;
6143 std::optional<bool> EnableWavefrontSize32;
6150 SMRange IDRange = getTok().getLocRange();
6151 if (!parseId(ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6154 if (ID ==
".end_amdhsa_kernel")
6157 if (!Seen.
insert(ID).second)
6158 return TokError(
".amdhsa_ directives cannot be repeated");
6160 SMLoc ValStart = getLoc();
6161 const MCExpr *ExprVal;
6162 if (getParser().parseExpression(ExprVal))
6164 SMLoc ValEnd = getLoc();
6165 SMRange ValRange = SMRange(ValStart, ValEnd);
6169 bool EvaluatableExpr;
6170 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6172 return OutOfRangeError(ValRange);
6176#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6177 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6178 return OutOfRangeError(RANGE); \
6179 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6184#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6186 return Error(IDRange.Start, "directive should have resolvable expression", \
6189 if (ID ==
".amdhsa_group_segment_fixed_size") {
6192 return OutOfRangeError(ValRange);
6194 }
else if (ID ==
".amdhsa_private_segment_fixed_size") {
6197 return OutOfRangeError(ValRange);
6199 }
else if (ID ==
".amdhsa_kernarg_size") {
6201 return OutOfRangeError(ValRange);
6203 }
else if (ID ==
".amdhsa_user_sgpr_count") {
6205 ExplicitUserSGPRCount = Val;
6206 }
else if (ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6210 "directive is not supported with architected flat scratch",
6213 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6216 ImpliedUserSGPRCount += 4;
6217 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6220 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6223 return OutOfRangeError(ValRange);
6227 ImpliedUserSGPRCount += Val;
6228 PreloadLength = Val;
6230 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6233 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6236 return OutOfRangeError(ValRange);
6240 PreloadOffset = Val;
6241 }
else if (ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6244 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6247 ImpliedUserSGPRCount += 2;
6248 }
else if (ID ==
".amdhsa_user_sgpr_queue_ptr") {
6251 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6254 ImpliedUserSGPRCount += 2;
6255 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6258 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6261 ImpliedUserSGPRCount += 2;
6262 }
else if (ID ==
".amdhsa_user_sgpr_dispatch_id") {
6265 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6268 ImpliedUserSGPRCount += 2;
6269 }
else if (ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6272 "directive is not supported with architected flat scratch",
6276 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6279 ImpliedUserSGPRCount += 2;
6280 }
else if (ID ==
".amdhsa_user_sgpr_private_segment_size") {
6283 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6286 ImpliedUserSGPRCount += 1;
6287 }
else if (ID ==
".amdhsa_wavefront_size32") {
6290 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6291 EnableWavefrontSize32 = Val;
6293 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6295 }
else if (ID ==
".amdhsa_uses_dynamic_stack") {
6297 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6299 }
else if (ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6302 "directive is not supported with architected flat scratch",
6305 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6307 }
else if (ID ==
".amdhsa_enable_private_segment") {
6311 "directive is not supported without architected flat scratch",
6314 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6316 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6318 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6320 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6322 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6324 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6326 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6328 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_info") {
6330 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6332 }
else if (ID ==
".amdhsa_system_vgpr_workitem_id") {
6334 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6336 }
else if (ID ==
".amdhsa_next_free_vgpr") {
6337 VGPRRange = ValRange;
6338 NextFreeVGPR = ExprVal;
6339 }
else if (ID ==
".amdhsa_next_free_sgpr") {
6340 SGPRRange = ValRange;
6341 NextFreeSGPR = ExprVal;
6342 }
else if (ID ==
".amdhsa_accum_offset") {
6344 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6345 AccumOffset = ExprVal;
6346 }
else if (ID ==
".amdhsa_named_barrier_count") {
6348 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6349 NamedBarCnt = ExprVal;
6350 }
else if (ID ==
".amdhsa_reserve_vcc") {
6352 return OutOfRangeError(ValRange);
6353 ReserveVCC = ExprVal;
6354 }
else if (ID ==
".amdhsa_reserve_flat_scratch") {
6356 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6359 "directive is not supported with architected flat scratch",
6362 return OutOfRangeError(ValRange);
6363 ReserveFlatScr = ExprVal;
6364 }
else if (ID ==
".amdhsa_reserve_xnack_mask") {
6366 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6368 return OutOfRangeError(ValRange);
6369 bool XnackOn = getTargetStreamer().getTargetID()->isXnackOnOrAny();
6370 if (Val != XnackOn) {
6371 return getParser().Error(
6373 ".amdhsa_reserve_xnack_mask does not match target id", IDRange);
6375 }
else if (ID ==
".amdhsa_float_round_mode_32") {
6377 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6379 }
else if (ID ==
".amdhsa_float_round_mode_16_64") {
6381 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6383 }
else if (ID ==
".amdhsa_float_denorm_mode_32") {
6385 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6387 }
else if (ID ==
".amdhsa_float_denorm_mode_16_64") {
6389 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6391 }
else if (ID ==
".amdhsa_dx10_clamp") {
6392 if (!getSTI().
hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6393 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6396 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6398 }
else if (ID ==
".amdhsa_ieee_mode") {
6399 if (!getSTI().
hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6400 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6403 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6405 }
else if (ID ==
".amdhsa_fp16_overflow") {
6407 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6409 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6411 }
else if (ID ==
".amdhsa_tg_split") {
6413 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6416 }
else if (ID ==
".amdhsa_workgroup_processor_mode") {
6419 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6421 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6423 }
else if (ID ==
".amdhsa_memory_ordered") {
6425 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6427 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6429 }
else if (ID ==
".amdhsa_forward_progress") {
6431 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6433 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6435 }
else if (ID ==
".amdhsa_shared_vgpr_count") {
6437 if (
ISA.Major < 10 ||
ISA.Major >= 12)
6438 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6440 SharedVGPRCount = Val;
6442 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6444 }
else if (ID ==
".amdhsa_inst_pref_size") {
6446 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6447 if (
ISA.Major == 11) {
6449 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6453 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6456 }
else if (ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6459 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6461 }
else if (ID ==
".amdhsa_exception_fp_denorm_src") {
6463 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6465 }
else if (ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6468 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6470 }
else if (ID ==
".amdhsa_exception_fp_ieee_overflow") {
6472 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6474 }
else if (ID ==
".amdhsa_exception_fp_ieee_underflow") {
6476 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6478 }
else if (ID ==
".amdhsa_exception_fp_ieee_inexact") {
6480 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6482 }
else if (ID ==
".amdhsa_exception_int_div_zero") {
6484 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6486 }
else if (ID ==
".amdhsa_round_robin_scheduling") {
6488 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6490 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6493 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6496#undef PARSE_BITS_ENTRY
6499 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6500 return TokError(
".amdhsa_next_free_vgpr directive is required");
6502 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6503 return TokError(
".amdhsa_next_free_sgpr directive is required");
6505 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6507 return TokError(
"too many user SGPRs enabled, found " +
6508 Twine(UserSGPRCount) +
", but only " +
6514 if (PreloadLength) {
6520 const MCExpr *VGPRBlocks;
6521 const MCExpr *SGPRBlocks;
6522 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6523 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6524 EnableWavefrontSize32, NextFreeVGPR, VGPRRange,
6525 NextFreeSGPR, SGPRRange, VGPRBlocks, SGPRBlocks))
6528 int64_t EvaluatedVGPRBlocks;
6529 bool VGPRBlocksEvaluatable =
6530 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6531 if (VGPRBlocksEvaluatable &&
6533 static_cast<uint64_t>(EvaluatedVGPRBlocks))) {
6534 return OutOfRangeError(VGPRRange);
6538 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6539 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6541 int64_t EvaluatedSGPRBlocks;
6542 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6544 static_cast<uint64_t>(EvaluatedSGPRBlocks)))
6545 return OutOfRangeError(SGPRRange);
6548 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6549 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6551 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6552 return TokError(
"amdgpu_user_sgpr_count smaller than implied by "
6553 "enabled user SGPRs");
6559 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6560 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6565 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6566 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6571 return TokError(
"Kernarg size should be resolvable");
6573 if (PreloadLength && kernarg_size &&
6574 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6575 return TokError(
"Kernarg preload length + offset is larger than the "
6576 "kernarg segment size");
6579 if (!Seen.
contains(
".amdhsa_accum_offset"))
6580 return TokError(
".amdhsa_accum_offset directive is required");
6581 int64_t EvaluatedAccum;
6582 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6583 uint64_t UEvaluatedAccum = EvaluatedAccum;
6584 if (AccumEvaluatable &&
6585 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6586 return TokError(
"accum_offset should be in range [4..256] in "
6589 int64_t EvaluatedNumVGPR;
6590 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6594 return TokError(
"accum_offset exceeds total VGPR allocation");
6600 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6601 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6607 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6608 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6611 if (
ISA.Major >= 10 &&
ISA.Major < 12) {
6613 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6614 return TokError(
"shared_vgpr_count directive not valid on "
6615 "wavefront size 32");
6618 if (VGPRBlocksEvaluatable &&
6619 (SharedVGPRCount * 2 +
static_cast<uint64_t>(EvaluatedVGPRBlocks) >
6621 return TokError(
"shared_vgpr_count*2 + "
6622 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6627 emitTargetDirective();
6628 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6629 NextFreeVGPR, NextFreeSGPR,
6630 ReserveVCC, ReserveFlatScr);
6634bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6636 if (ParseAsAbsoluteExpression(
Version))
6639 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6640 emitTargetDirective();
6644bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
6645 AMDGPUMCKernelCodeT &
C) {
6648 if (ID ==
"max_scratch_backing_memory_byte_size") {
6649 Parser.eatToEndOfStatement();
6653 SmallString<40> ErrStr;
6654 raw_svector_ostream Err(ErrStr);
6655 if (!
C.ParseKernelCodeT(ID, getParser(), Err)) {
6656 return TokError(Err.
str());
6660 if (ID ==
"enable_wavefront_size32") {
6663 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6665 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6668 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6672 if (ID ==
"wavefront_size") {
6673 if (
C.wavefront_size == 5) {
6675 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6677 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6678 }
else if (
C.wavefront_size == 6) {
6680 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6687bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6688 AMDGPUMCKernelCodeT KernelCode;
6698 if (!parseId(ID,
"expected value identifier or .end_amd_kernel_code_t"))
6701 if (ID ==
".end_amd_kernel_code_t")
6704 if (ParseAMDKernelCodeTValue(ID, KernelCode))
6709 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6714bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6715 StringRef KernelName;
6716 if (!parseId(KernelName,
"expected symbol name"))
6719 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6726bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6727 if (!getSTI().getTargetTriple().isAMDGCN()) {
6728 return Error(getLoc(),
6729 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6733 StringRef TargetIDDirective = getLexer().getTok().getStringContents();
6735 std::optional<AMDGPU::TargetID> MaybeParsed =
6738 return Error(getParser().getTok().getLoc(),
6739 "malformed target id '" + TargetIDDirective +
"'");
6742 const Triple &
TT = getSTI().getTargetTriple();
6748 return Error(getParser().getTok().getLoc(),
6749 "target id '" + TargetIDDirective +
6750 "' specifies a processor that is not valid for subarch '" +
6751 TT.getArchName() +
"'");
6754 const std::optional<AMDGPU::TargetID> &CurrentTargetID =
6755 getTargetStreamer().getTargetID();
6758 const Triple &STITriple = getSTI().getTargetTriple();
6759 if (!DirectiveTriple.isCompatibleWith(STITriple)) {
6760 return Error(getParser().getTok().getLoc(),
6761 ".amd_amdgpu_isa " + Twine(ParsedTargetID.
toString()) +
6762 " is incompatible with " +
6763 Twine(CurrentTargetID->toString()));
6767 StringRef DirectiveProcessor =
6770 if (DirectiveISA != ISA) {
6771 return Error(getParser().getTok().getLoc(),
6772 ".amd_amdgpu_isa directive processor " +
6773 Twine(DirectiveProcessor) +
6774 " does not match the specified processor " +
6775 Twine(getSTI().
getCPU()));
6778 getTargetStreamer().EmitISAVersion();
6784bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6787 std::string HSAMetadataString;
6792 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6793 return Error(getLoc(),
"invalid HSA metadata");
6800bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6801 const char *AssemblerDirectiveEnd,
6802 std::string &CollectString) {
6804 raw_string_ostream CollectStream(CollectString);
6806 getLexer().setSkipSpace(
false);
6808 bool FoundEnd =
false;
6811 CollectStream << getTokenStr();
6815 if (trySkipId(AssemblerDirectiveEnd)) {
6820 CollectStream << Parser.parseStringToEndOfStatement()
6821 <<
getContext().getAsmInfo().getSeparatorString();
6823 Parser.eatToEndOfStatement();
6826 getLexer().setSkipSpace(
true);
6829 return TokError(Twine(
"expected directive ") +
6830 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6837bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6843 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6844 if (!PALMetadata->setFromString(
String))
6845 return Error(getLoc(),
"invalid PAL metadata");
6850bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6853 Twine(
" directive is "
6854 "not available on non-amdpal OSes"))
6858 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6859 PALMetadata->setLegacy();
6862 if (ParseAsAbsoluteExpression(
Key)) {
6863 return TokError(Twine(
"invalid value in ") +
6867 return TokError(Twine(
"expected an even number of values in ") +
6870 if (ParseAsAbsoluteExpression(
Value)) {
6871 return TokError(Twine(
"invalid value in ") +
6874 PALMetadata->setRegister(
Key,
Value);
6883bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6884 if (getParser().checkForValidSection())
6888 SMLoc NameLoc = getLoc();
6889 if (getParser().parseIdentifier(Name))
6890 return TokError(
"expected identifier in directive");
6893 if (getParser().parseComma())
6899 SMLoc SizeLoc = getLoc();
6900 if (getParser().parseAbsoluteExpression(
Size))
6903 return Error(SizeLoc,
"size must be non-negative");
6904 if (
Size > LocalMemorySize)
6905 return Error(SizeLoc,
"size is too large");
6909 SMLoc AlignLoc = getLoc();
6910 if (getParser().parseAbsoluteExpression(Alignment))
6913 return Error(AlignLoc,
"alignment must be a power of two");
6918 if (Alignment >= 1u << 31)
6919 return Error(AlignLoc,
"alignment is too large");
6925 Symbol->redefineIfPossible();
6926 if (!
Symbol->isUndefined())
6927 return Error(NameLoc,
"invalid symbol redefinition");
6929 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6933bool AMDGPUAsmParser::ParseDirectiveAMDGPUInfo() {
6934 if (getParser().checkForValidSection())
6938 if (getParser().parseIdentifier(FuncName))
6939 return TokError(
"expected symbol name after .amdgpu_info");
6942 AMDGPU::InfoSectionData ParsedInfoData;
6943 AMDGPU::FuncInfo FI;
6945 bool HasScalarAttrs =
false;
6952 SMLoc IDLoc = getLoc();
6953 if (!parseId(ID,
"expected directive or .end_amdgpu_info"))
6956 if (ID ==
".end_amdgpu_info")
6964 return Error(IDLoc,
"unknown .amdgpu_info directive '" + ID +
"'");
6966 if (Dir ==
"flags") {
6968 if (getParser().parseAbsoluteExpression(Val))
6971 FI.
UsesVCC = !!(
Flags & AMDGPU::FuncInfoFlags::FUNC_USES_VCC);
6973 !!(
Flags & AMDGPU::FuncInfoFlags::FUNC_USES_FLAT_SCRATCH);
6975 HasScalarAttrs =
true;
6976 }
else if (Dir ==
"num_sgpr") {
6978 if (getParser().parseAbsoluteExpression(Val))
6980 FI.
NumSGPR =
static_cast<uint32_t
>(Val);
6981 HasScalarAttrs =
true;
6982 }
else if (Dir ==
"num_vgpr") {
6984 if (getParser().parseAbsoluteExpression(Val))
6987 HasScalarAttrs =
true;
6988 }
else if (Dir ==
"num_agpr") {
6990 if (getParser().parseAbsoluteExpression(Val))
6993 HasScalarAttrs =
true;
6994 }
else if (Dir ==
"private_segment_size") {
6996 if (getParser().parseAbsoluteExpression(Val))
6999 HasScalarAttrs =
true;
7000 }
else if (Dir ==
"use") {
7002 if (getParser().parseIdentifier(ResName))
7003 return TokError(
"expected resource symbol for .amdgpu_use");
7004 ParsedInfoData.
Uses.push_back(
7005 {FuncSym,
getContext().getOrCreateSymbol(ResName)});
7006 }
else if (Dir ==
"call") {
7008 if (getParser().parseIdentifier(DstName))
7009 return TokError(
"expected callee symbol for .amdgpu_call");
7010 ParsedInfoData.
Calls.push_back(
7011 {FuncSym,
getContext().getOrCreateSymbol(DstName)});
7012 }
else if (Dir ==
"indirect_call") {
7014 if (getParser().parseEscapedString(TypeId))
7015 return TokError(
"expected type ID string for .amdgpu_indirect_call");
7016 ParsedInfoData.
IndirectCalls.push_back({FuncSym, std::move(TypeId)});
7017 }
else if (Dir ==
"typeid") {
7019 if (getParser().parseEscapedString(TypeId))
7020 return TokError(
"expected type ID string for .amdgpu_typeid");
7021 ParsedInfoData.
TypeIds.push_back({FuncSym, std::move(TypeId)});
7023 return Error(IDLoc,
"unknown .amdgpu_info directive '" + ID +
"'");
7028 ParsedInfoData.
Funcs.push_back(std::move(FI));
7030 AMDGPU::InfoSectionData &
Data = InfoData ? *InfoData : InfoData.emplace();
7031 for (AMDGPU::FuncInfo &Func : ParsedInfoData.
Funcs)
7032 Data.Funcs.push_back(std::move(Func));
7033 for (std::pair<MCSymbol *, MCSymbol *> &Use : ParsedInfoData.
Uses)
7034 Data.Uses.push_back(Use);
7035 for (std::pair<MCSymbol *, MCSymbol *> &
Call : ParsedInfoData.
Calls)
7037 for (std::pair<MCSymbol *, std::string> &
IndirectCall :
7040 for (std::pair<MCSymbol *, std::string> &TypeId : ParsedInfoData.
TypeIds)
7041 Data.TypeIds.push_back(std::move(TypeId));
7046void AMDGPUAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
7053void AMDGPUAsmParser::checkKernelPrologues() {
7054 if (getFeatureBits()[AMDGPU::FeatureRequiresInitialUnclausedVmem]) {
7055 static const unsigned Required[] = {S_MOV_B64_gfx12, V_NOP_e32_gfx12,
7056 GLOBAL_PREFETCH_B8_SADDR_gfx1250};
7057 for (
auto [Sym, Loc,
Offset] : OpcodeStreamSymbols) {
7058 if (!AMDHSAKernelSymbols.
contains(Sym))
7060 ArrayRef<unsigned> Prologue =
ArrayRef(OpcodeStream).drop_front(
Offset);
7061 if (!Prologue.
empty() && Prologue.
front() == S_SETREG_IMM32_B32_gfx12)
7065 "' does not begin with the required prologue "
7066 "sequence: s_mov_b64 followed by v_nop and "
7067 "global_prefetch_b8");
7071 OpcodeStream.
clear();
7072 OpcodeStreamSymbols.clear();
7073 AMDHSAKernelSymbols.
clear();
7076void AMDGPUAsmParser::onEndOfFile() {
7077 emitTargetDirective();
7078 checkKernelPrologues();
7080 getTargetStreamer().emitAMDGPUInfo(*InfoData);
7083bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
7084 StringRef IDVal = DirectiveID.
getString();
7087 if (IDVal ==
".amdhsa_kernel")
7088 return ParseDirectiveAMDHSAKernel();
7090 if (IDVal ==
".amdhsa_code_object_version")
7091 return ParseDirectiveAMDHSACodeObjectVersion();
7095 return ParseDirectiveHSAMetadata();
7097 if (IDVal ==
".amd_kernel_code_t")
7098 return ParseDirectiveAMDKernelCodeT();
7100 if (IDVal ==
".amdgpu_hsa_kernel")
7101 return ParseDirectiveAMDGPUHsaKernel();
7103 if (IDVal ==
".amd_amdgpu_isa")
7104 return ParseDirectiveISAVersion();
7108 Twine(
" directive is "
7109 "not available on non-amdhsa OSes"))
7114 if (IDVal ==
".amdgcn_target")
7115 return ParseDirectiveAMDGCNTarget();
7117 if (IDVal ==
".amdgpu_lds")
7118 return ParseDirectiveAMDGPULDS();
7120 if (IDVal ==
".amdgpu_info")
7121 return ParseDirectiveAMDGPUInfo();
7124 return ParseDirectivePALMetadataBegin();
7127 return ParseDirectivePALMetadata();
7132bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
7134 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
7138 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
7139 return hasSGPR104_SGPR105();
7142 case SRC_SHARED_BASE_LO:
7143 case SRC_SHARED_BASE:
7144 case SRC_SHARED_LIMIT_LO:
7145 case SRC_SHARED_LIMIT:
7147 case SRC_PRIVATE_BASE_LO:
7148 case SRC_PRIVATE_BASE:
7149 case SRC_PRIVATE_LIMIT_LO:
7150 case SRC_PRIVATE_LIMIT:
7152 case SRC_FLAT_SCRATCH_BASE_LO:
7153 case SRC_FLAT_SCRATCH_BASE_HI:
7154 return hasGloballyAddressableScratch();
7155 case SRC_POPS_EXITING_WAVE_ID:
7168 getTargetStreamer().getTargetID()->isXnackSupported();
7197 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
7198 return hasSGPR102_SGPR103();
7206 ParseStatus Res = parseVOPD(
Operands);
7211 Res = MatchOperandParserImpl(
Operands, Mnemonic);
7223 SMLoc LBraceLoc = getLoc();
7228 auto Loc = getLoc();
7231 Error(Loc,
"expected a register");
7235 RBraceLoc = getLoc();
7240 "expected a comma or a closing square bracket"))
7244 if (
Operands.size() - Prefix > 1) {
7246 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
7247 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
7256StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
7258 setForcedEncodingSize(0);
7259 setForcedDPP(
false);
7260 setForcedSDWA(
false);
7262 if (
Name.consume_back(
"_e64_dpp")) {
7264 setForcedEncodingSize(64);
7267 if (
Name.consume_back(
"_e64")) {
7268 setForcedEncodingSize(64);
7271 if (
Name.consume_back(
"_e32")) {
7272 setForcedEncodingSize(32);
7275 if (
Name.consume_back(
"_dpp")) {
7279 if (
Name.consume_back(
"_sdwa")) {
7280 setForcedSDWA(
true);
7288 unsigned VariantID);
7294 Name = parseMnemonicSuffix(Name);
7300 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
7302 bool IsMIMG = Name.starts_with(
"image_");
7305 OperandMode
Mode = OperandMode_Default;
7307 Mode = OperandMode_NSA;
7311 checkUnsupportedInstruction(Name, NameLoc);
7312 if (!Parser.hasPendingError()) {
7315 :
"not a valid operand.";
7335ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
7338 if (!trySkipId(Name))
7341 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, S));
7345ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7354ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7356 std::function<
bool(int64_t &)> ConvertResult) {
7360 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7364 if (ConvertResult && !ConvertResult(
Value)) {
7365 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7368 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7372ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7374 bool (*ConvertResult)(int64_t &)) {
7383 const unsigned MaxSize = 4;
7387 for (
int I = 0;; ++
I) {
7389 SMLoc Loc = getLoc();
7393 if (
Op != 0 &&
Op != 1)
7394 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7401 if (
I + 1 == MaxSize)
7402 return Error(getLoc(),
"expected a closing square bracket");
7408 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7412ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7414 AMDGPUOperand::ImmTy ImmTy,
7415 bool IgnoreNegative) {
7419 if (trySkipId(Name)) {
7421 }
else if (trySkipId(
"no", Name)) {
7430 return Error(S,
"r128 modifier is not supported on this GPU");
7431 if (Name ==
"a16" && !
hasA16())
7432 return Error(S,
"a16 modifier is not supported on this GPU");
7434 if (Bit == 0 && Name ==
"gds") {
7437 return Error(S,
"nogds is not allowed");
7440 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7441 ImmTy = AMDGPUOperand::ImmTyR128A16;
7443 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7447unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7448 bool &Disabling)
const {
7449 Disabling =
Id.consume_front(
"no");
7452 return StringSwitch<unsigned>(Id)
7459 return StringSwitch<unsigned>(Id)
7469 SMLoc StringLoc = getLoc();
7471 int64_t CPolVal = 0;
7492 ResScope = parseScope(
Operands, Scope);
7505 if (trySkipId(
"nv")) {
7509 }
else if (trySkipId(
"no",
"nv")) {
7516 if (trySkipId(
"scale_offset")) {
7520 }
else if (trySkipId(
"no",
"scale_offset")) {
7544 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7545 AMDGPUOperand::ImmTyCPol));
7550 SMLoc OpLoc = getLoc();
7551 unsigned Enabled = 0, Seen = 0;
7555 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7562 return Error(S,
"dlc modifier is not supported on this GPU");
7565 return Error(S,
"scc modifier is not supported on this GPU");
7568 return Error(S,
"duplicate cache policy modifier");
7580 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7589 ParseStatus Res = parseStringOrIntWithPrefix(
7590 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7604 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7608 if (
Value ==
"TH_DEFAULT")
7610 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7611 Value ==
"TH_LOAD_NT_WB") {
7612 return Error(StringLoc,
"invalid th value");
7613 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7615 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7617 }
else if (
Value.consume_front(
"TH_STORE_")) {
7620 return Error(StringLoc,
"invalid th value");
7623 if (
Value ==
"BYPASS")
7628 TH |= StringSwitch<int64_t>(
Value)
7638 .Default(0xffffffff);
7640 TH |= StringSwitch<int64_t>(
Value)
7651 .Default(0xffffffff);
7654 if (TH == 0xffffffff)
7655 return Error(StringLoc,
"invalid th value");
7664 ParseStatus Res = parseStringOrIntWithPrefix(
7665 Operands,
"cfs", {
"CFS_256B",
"CFS_128B",
"CFS_64B",
"CFS_32B"},
CFS);
7675 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7676 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7677 std::optional<unsigned> InsertAt = std::nullopt) {
7678 auto i = OptionalIdx.find(ImmT);
7679 if (i != OptionalIdx.end()) {
7680 unsigned Idx = i->second;
7681 const AMDGPUOperand &
Op =
7682 static_cast<const AMDGPUOperand &
>(*
Operands[
Idx]);
7686 Op.addImmOperands(Inst, 1);
7688 if (InsertAt.has_value())
7695ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7701 StringLoc = getLoc();
7706ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7712 SMLoc StringLoc = getLoc();
7716 Value = getTokenStr();
7720 if (
Value == Ids[IntVal])
7725 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7726 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7731ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7733 AMDGPUOperand::ImmTy
Type) {
7737 ParseStatus Res = parseStringOrIntWithPrefix(
Operands, Name, Ids, IntVal);
7739 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7748bool AMDGPUAsmParser::tryParseFmt(
const char *Pref, int64_t MaxVal,
7751 SMLoc Loc = getLoc();
7753 auto Res = parseIntWithPrefix(Pref, Val);
7759 if (Val < 0 || Val > MaxVal) {
7760 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7769 AMDGPUOperand::ImmTy ImmTy) {
7770 const char *Pref =
"index_key";
7772 SMLoc Loc = getLoc();
7773 auto Res = parseIntWithPrefix(Pref, ImmVal);
7777 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7778 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7779 (ImmVal < 0 || ImmVal > 1))
7780 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7782 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7783 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7785 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7790 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7794 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7798 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7803 AMDGPUOperand::ImmTy
Type) {
7809 return tryParseMatrixFMT(
Operands,
"matrix_a_fmt",
7810 AMDGPUOperand::ImmTyMatrixAFMT);
7814 return tryParseMatrixFMT(
Operands,
"matrix_b_fmt",
7815 AMDGPUOperand::ImmTyMatrixBFMT);
7820 AMDGPUOperand::ImmTy
Type) {
7826 return tryParseMatrixScale(
Operands,
"matrix_a_scale",
7827 AMDGPUOperand::ImmTyMatrixAScale);
7831 return tryParseMatrixScale(
Operands,
"matrix_b_scale",
7832 AMDGPUOperand::ImmTyMatrixBScale);
7837 AMDGPUOperand::ImmTy
Type) {
7843 return tryParseMatrixScaleFmt(
Operands,
"matrix_a_scale_fmt",
7844 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7848 return tryParseMatrixScaleFmt(
Operands,
"matrix_b_scale_fmt",
7849 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7854ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7855 using namespace llvm::AMDGPU::MTBUFFormat;
7861 for (
int I = 0;
I < 2; ++
I) {
7862 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7865 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7870 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7876 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7879 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7880 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7886ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7887 using namespace llvm::AMDGPU::MTBUFFormat;
7891 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7894 if (Fmt == UFMT_UNDEF)
7901bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt,
7902 StringRef FormatStr, SMLoc Loc) {
7903 using namespace llvm::AMDGPU::MTBUFFormat;
7907 if (
Format != DFMT_UNDEF) {
7913 if (
Format != NFMT_UNDEF) {
7918 Error(Loc,
"unsupported format");
7922ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7925 using namespace llvm::AMDGPU::MTBUFFormat;
7929 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7934 SMLoc Loc = getLoc();
7935 if (!parseId(Str,
"expected a format string") ||
7936 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7938 if (Dfmt == DFMT_UNDEF)
7939 return Error(Loc,
"duplicate numeric format");
7940 if (Nfmt == NFMT_UNDEF)
7941 return Error(Loc,
"duplicate data format");
7944 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7945 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7949 if (Ufmt == UFMT_UNDEF)
7950 return Error(FormatLoc,
"unsupported format");
7959ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7962 using namespace llvm::AMDGPU::MTBUFFormat;
7965 if (Id == UFMT_UNDEF)
7969 return Error(Loc,
"unified format is not supported on this GPU");
7975ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7976 using namespace llvm::AMDGPU::MTBUFFormat;
7977 SMLoc Loc = getLoc();
7982 return Error(Loc,
"out of range format");
7987ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7988 using namespace llvm::AMDGPU::MTBUFFormat;
7994 StringRef FormatStr;
7995 SMLoc Loc = getLoc();
7996 if (!parseId(FormatStr,
"expected a format string"))
7999 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
8001 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
8011 return parseNumericFormat(
Format);
8015 using namespace llvm::AMDGPU::MTBUFFormat;
8019 SMLoc Loc = getLoc();
8029 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
8048 Res = parseSymbolicOrNumericFormat(
Format);
8053 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
8054 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
8061 return Error(getLoc(),
"duplicate format");
8067 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
8069 Res = parseIntWithPrefix(
"inst_offset",
Operands,
8070 AMDGPUOperand::ImmTyInstOffset);
8077 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
8079 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
8085 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
8088 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
8098 OptionalImmIndexMap OptionalIdx;
8100 unsigned OperandIdx[4];
8101 unsigned EnMask = 0;
8104 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
8105 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8110 OperandIdx[SrcIdx] = Inst.
size();
8111 Op.addRegOperands(Inst, 1);
8118 OperandIdx[SrcIdx] = Inst.
size();
8124 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
8125 Op.addImmOperands(Inst, 1);
8129 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
8133 OptionalIdx[
Op.getImmTy()] = i;
8139 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
8146 for (
auto i = 0; i < SrcIdx; ++i) {
8148 EnMask |= Compr ? (0x3 << i * 2) : (0x1 << i);
8154 AMDGPUOperand::ImmTyExpCompr);
8164 int64_t CntVal,
bool Saturate,
8170 IntVal =
encode(ISA, IntVal, CntVal);
8171 if (CntVal !=
decode(ISA, IntVal)) {
8173 IntVal =
encode(ISA, IntVal, -1);
8181bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
8183 SMLoc CntLoc = getLoc();
8184 StringRef CntName = getTokenStr();
8191 SMLoc ValLoc = getLoc();
8198 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
8200 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
8202 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
8205 Error(CntLoc,
"invalid counter name " + CntName);
8210 Error(ValLoc,
"too large value for " + CntName);
8219 Error(getLoc(),
"expected a counter name");
8233 if (!parseCnt(Waitcnt))
8241 Operands.push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
8245bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
8246 SMLoc FieldLoc = getLoc();
8247 StringRef FieldName = getTokenStr();
8252 SMLoc ValueLoc = getLoc();
8259 if (FieldName ==
"instid0") {
8261 }
else if (FieldName ==
"instskip") {
8263 }
else if (FieldName ==
"instid1") {
8266 Error(FieldLoc,
"invalid field name " + FieldName);
8285 .Case(
"VALU_DEP_1", 1)
8286 .Case(
"VALU_DEP_2", 2)
8287 .Case(
"VALU_DEP_3", 3)
8288 .Case(
"VALU_DEP_4", 4)
8289 .Case(
"TRANS32_DEP_1", 5)
8290 .Case(
"TRANS32_DEP_2", 6)
8291 .Case(
"TRANS32_DEP_3", 7)
8292 .Case(
"FMA_ACCUM_CYCLE_1", 8)
8293 .Case(
"SALU_CYCLE_1", 9)
8294 .Case(
"SALU_CYCLE_2", 10)
8295 .Case(
"SALU_CYCLE_3", 11)
8303 Delay |=
Value << Shift;
8313 if (!parseDelay(Delay))
8321 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
8325bool AMDGPUOperand::isSWaitCnt()
const {
return isImm(); }
8327bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
8333void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
8334 StringRef DepCtrName) {
8337 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
8340 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
8343 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
8346 Error(Loc, Twine(
"invalid value for ", DepCtrName));
8353bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
8355 using namespace llvm::AMDGPU::DepCtr;
8357 SMLoc DepCtrLoc = getLoc();
8358 StringRef DepCtrName = getTokenStr();
8368 unsigned PrevOprMask = UsedOprMask;
8369 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8372 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8381 Error(getLoc(),
"expected a counter name");
8386 int64_t CntValMask = PrevOprMask ^ UsedOprMask;
8387 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8392 using namespace llvm::AMDGPU::DepCtr;
8395 SMLoc Loc = getLoc();
8398 unsigned UsedOprMask = 0;
8400 if (!parseDepCtr(DepCtr, UsedOprMask))
8408 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8412bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8418ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8420 OperandInfoTy &Width) {
8421 using namespace llvm::AMDGPU::Hwreg;
8427 HwReg.Loc = getLoc();
8430 HwReg.IsSymbolic =
true;
8432 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8440 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8450 Width.Loc = getLoc();
8459 using namespace llvm::AMDGPU::Hwreg;
8462 SMLoc Loc = getLoc();
8464 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8466 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8467 HwregOffset::Default);
8468 struct : StructuredOpField {
8469 using StructuredOpField::StructuredOpField;
8470 bool validate(AMDGPUAsmParser &Parser)
const override {
8472 return Error(Parser,
"only values from 1 to 32 are legal");
8475 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8476 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8479 Res = parseHwregFunc(HwReg,
Offset, Width);
8482 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8484 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8488 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8495 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8497 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8501bool AMDGPUOperand::isHwreg()
const {
return isImmTy(ImmTyHwreg); }
8507bool AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &
Msg, OperandInfoTy &
Op,
8508 OperandInfoTy &Stream) {
8509 using namespace llvm::AMDGPU::SendMsg;
8514 Msg.IsSymbolic =
true;
8521 Op.IsDefined =
true;
8527 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8532 Stream.IsDefined =
true;
8533 Stream.Loc = getLoc();
8542bool AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &
Msg,
8543 const OperandInfoTy &
Op,
8544 const OperandInfoTy &Stream) {
8545 using namespace llvm::AMDGPU::SendMsg;
8554 Error(
Msg.Loc,
"specified message id is not supported on this GPU");
8559 Error(
Msg.Loc,
"invalid message id");
8565 Error(
Op.Loc,
"message does not support operations");
8567 Error(
Msg.Loc,
"missing message operation");
8573 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8575 Error(
Op.Loc,
"invalid operation id");
8580 Error(Stream.Loc,
"message operation does not support streams");
8584 Error(Stream.Loc,
"invalid message stream id");
8591 using namespace llvm::AMDGPU::SendMsg;
8594 SMLoc Loc = getLoc();
8598 OperandInfoTy
Op(OP_NONE_);
8599 OperandInfoTy Stream(STREAM_ID_NONE_);
8600 if (parseSendMsgBody(
Msg,
Op, Stream) && validateSendMsg(
Msg,
Op, Stream)) {
8605 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8607 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8613 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8617bool AMDGPUOperand::isSendMsg()
const {
return isImmTy(ImmTySendMsg); }
8620 using namespace llvm::AMDGPU::WaitEvent;
8622 SMLoc Loc = getLoc();
8625 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8627 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8629 StructuredOpField *TargetBitfield =
8630 isGFX11() ? &DontWaitExportReady : &ExportReady;
8632 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8636 if (!validateStructuredOpFields({TargetBitfield}))
8638 ImmVal = TargetBitfield->Val;
8645 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8647 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8648 AMDGPUOperand::ImmTyWaitEvent));
8652bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8665 int Slot = StringSwitch<int>(Str)
8672 return Error(S,
"invalid interpolation slot");
8675 AMDGPUOperand::CreateImm(
this, Slot, S, AMDGPUOperand::ImmTyInterpSlot));
8686 if (!Str.starts_with(
"attr"))
8687 return Error(S,
"invalid interpolation attribute");
8689 StringRef Chan = Str.take_back(2);
8690 int AttrChan = StringSwitch<int>(Chan)
8697 return Error(S,
"invalid or missing interpolation attribute channel");
8699 Str = Str.drop_back(2).drop_front(4);
8702 if (Str.getAsInteger(10, Attr))
8703 return Error(S,
"invalid or missing interpolation attribute number");
8706 return Error(S,
"out of bounds interpolation attribute number");
8711 AMDGPUOperand::CreateImm(
this, Attr, S, AMDGPUOperand::ImmTyInterpAttr));
8712 Operands.push_back(AMDGPUOperand::CreateImm(
8713 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8722 using namespace llvm::AMDGPU::Exp;
8732 return Error(S, (Id == ET_INVALID)
8733 ?
"invalid exp target"
8734 :
"exp target is not supported on this GPU");
8737 AMDGPUOperand::CreateImm(
this, Id, S, AMDGPUOperand::ImmTyExpTgt));
8745bool AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8749bool AMDGPUAsmParser::isId(
const StringRef Id)
const {
8754 return getTokenKind() ==
Kind;
8757StringRef AMDGPUAsmParser::getId()
const {
8761bool AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8769bool AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8771 StringRef Tok = getTokenStr();
8780bool AMDGPUAsmParser::trySkipId(
const StringRef Id,
8782 if (isId(Id) && peekToken().is(Kind)) {
8791 if (isToken(Kind)) {
8799 const StringRef ErrMsg) {
8800 if (!trySkipToken(Kind)) {
8801 Error(getLoc(), ErrMsg);
8807bool AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8811 if (Parser.parseExpression(Expr))
8814 if (Expr->evaluateAsAbsolute(
Imm))
8817 if (Expected.empty()) {
8818 Error(S,
"expected absolute expression");
8821 Twine(
"expected ", Expected) + Twine(
" or an absolute expression"));
8830 if (Parser.parseExpression(Expr))
8834 if (Expr->evaluateAsAbsolute(IntVal)) {
8835 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8837 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8842bool AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8844 Val =
getToken().getStringContents();
8848 Error(getLoc(), ErrMsg);
8852bool AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8854 Val = getTokenStr();
8858 if (!ErrMsg.
empty())
8859 Error(getLoc(), ErrMsg);
8863AsmToken AMDGPUAsmParser::getToken()
const {
return Parser.getTok(); }
8865AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8868 : getLexer().peekTok(ShouldSkipSpace);
8872 auto TokCount = getLexer().peekTokens(Tokens);
8879 return getLexer().getKind();
8882SMLoc AMDGPUAsmParser::getLoc()
const {
return getToken().getLoc(); }
8884StringRef AMDGPUAsmParser::getTokenStr()
const {
8888void AMDGPUAsmParser::lex() { Parser.Lex(); }
8890const AMDGPUOperand &
8892 int MCOpIdx)
const {
8894 const AMDGPUOperand &TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8895 if (TargetOp.getMCOpIdx() == MCOpIdx)
8902 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
8906SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8911 int MCOpIdx)
const {
8912 return findMCOperand(
Operands, MCOpIdx).getStartLoc();
8915SMLoc AMDGPUAsmParser::getOperandLoc(
8916 std::function<
bool(
const AMDGPUOperand &)>
Test,
8918 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
8919 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8921 return Op.getStartLoc();
8926SMLoc AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8928 auto Test = [=](
const AMDGPUOperand &
Op) {
return Op.isImmTy(
Type); };
8943 StringRef
Id = getTokenStr();
8944 SMLoc IdLoc = getLoc();
8950 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8951 if (
I == Fields.
end())
8952 return Error(IdLoc,
"unknown field");
8953 if ((*I)->IsDefined)
8954 return Error(IdLoc,
"duplicate field");
8957 (*I)->Loc = getLoc();
8960 (*I)->IsDefined =
true;
8967bool AMDGPUAsmParser::validateStructuredOpFields(
8969 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8970 return F->validate(*
this);
8980 const unsigned XorMask) {
8987bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8988 const unsigned MaxVal,
8989 const Twine &ErrMsg, SMLoc &Loc) {
9005bool AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t *
Op,
9006 const unsigned MinVal,
9007 const unsigned MaxVal,
9008 const StringRef ErrMsg) {
9010 for (
unsigned i = 0; i < OpNum; ++i) {
9011 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
9018bool AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
9019 using namespace llvm::AMDGPU::Swizzle;
9022 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
9023 "expected a 2-bit lane id")) {
9033bool AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
9034 using namespace llvm::AMDGPU::Swizzle;
9040 if (!parseSwizzleOperand(GroupSize, 2, 32,
9041 "group size must be in the interval [2,32]", Loc)) {
9045 Error(Loc,
"group size must be a power of two");
9048 if (parseSwizzleOperand(LaneIdx, 0, GroupSize - 1,
9049 "lane id must be in the interval [0,group size - 1]",
9057bool AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
9058 using namespace llvm::AMDGPU::Swizzle;
9063 if (!parseSwizzleOperand(GroupSize, 2, 32,
9064 "group size must be in the interval [2,32]", Loc)) {
9068 Error(Loc,
"group size must be a power of two");
9076bool AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
9077 using namespace llvm::AMDGPU::Swizzle;
9082 if (!parseSwizzleOperand(GroupSize, 1, 16,
9083 "group size must be in the interval [1,16]", Loc)) {
9087 Error(Loc,
"group size must be a power of two");
9095bool AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
9096 using namespace llvm::AMDGPU::Swizzle;
9103 SMLoc StrLoc = getLoc();
9104 if (!parseString(Ctl)) {
9107 if (Ctl.
size() != BITMASK_WIDTH) {
9108 Error(StrLoc,
"expected a 5-character mask");
9112 unsigned AndMask = 0;
9113 unsigned OrMask = 0;
9114 unsigned XorMask = 0;
9116 for (
size_t i = 0; i < Ctl.
size(); ++i) {
9120 Error(StrLoc,
"invalid mask");
9141bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
9142 using namespace llvm::AMDGPU::Swizzle;
9145 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
9151 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
9152 "FFT swizzle must be in the interval [0," +
9153 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
9161bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
9162 using namespace llvm::AMDGPU::Swizzle;
9165 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
9172 if (!parseSwizzleOperand(
Direction, 0, 1,
9173 "direction must be 0 (left) or 1 (right)", Loc))
9177 if (!parseSwizzleOperand(
9178 RotateSize, 0, ROTATE_MAX_SIZE,
9179 "number of threads to rotate must be in the interval [0," +
9180 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
9185 (RotateSize << ROTATE_SIZE_SHIFT);
9189bool AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
9191 SMLoc OffsetLoc = getLoc();
9197 Error(OffsetLoc,
"expected a 16-bit offset");
9203bool AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
9204 using namespace llvm::AMDGPU::Swizzle;
9208 SMLoc ModeLoc = getLoc();
9211 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
9212 Ok = parseSwizzleQuadPerm(
Imm);
9213 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
9214 Ok = parseSwizzleBitmaskPerm(
Imm);
9215 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
9216 Ok = parseSwizzleBroadcast(
Imm);
9217 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
9218 Ok = parseSwizzleSwap(
Imm);
9219 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
9220 Ok = parseSwizzleReverse(
Imm);
9221 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
9222 Ok = parseSwizzleFFT(
Imm);
9223 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
9224 Ok = parseSwizzleRotate(
Imm);
9226 Error(ModeLoc,
"expected a swizzle mode");
9229 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
9239 if (trySkipId(
"offset")) {
9243 if (trySkipId(
"swizzle")) {
9244 Ok = parseSwizzleMacro(
Imm);
9246 Ok = parseSwizzleOffset(
Imm);
9251 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
9258bool AMDGPUOperand::isSwizzle()
const {
return isImmTy(ImmTySwizzle); }
9264int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
9266 using namespace llvm::AMDGPU::VGPRIndexMode;
9278 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
9279 if (trySkipId(IdSymbolic[ModeId])) {
9287 ?
"expected a VGPR index mode or a closing parenthesis"
9288 :
"expected a VGPR index mode");
9293 Error(S,
"duplicate VGPR index mode");
9301 "expected a comma or a closing parenthesis"))
9310 using namespace llvm::AMDGPU::VGPRIndexMode;
9316 Imm = parseGPRIdxMacro();
9320 if (getParser().parseAbsoluteExpression(
Imm))
9323 return Error(S,
"invalid immediate: only 4-bit values are legal");
9327 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9331bool AMDGPUOperand::isGPRIdxMode()
const {
return isImmTy(ImmTyGprIdxMode); }
9342 if (isRegister() || isModifier())
9349 assert(Opr.isImm() || Opr.isExpr());
9350 SMLoc Loc = Opr.getStartLoc();
9354 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9355 Error(Loc,
"expected an absolute expression or a label");
9356 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9357 Error(Loc,
"expected a 16-bit signed jump offset");
9377 OptionalImmIndexMap OptionalIdx;
9378 unsigned FirstOperandIdx = 1;
9379 bool IsAtomicReturn =
false;
9385 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
9386 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
9390 Op.addRegOperands(Inst, 1);
9394 if (IsAtomicReturn && i == FirstOperandIdx)
9395 Op.addRegOperands(Inst, 1);
9400 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9401 Op.addImmOperands(Inst, 1);
9413 OptionalIdx[
Op.getImmTy()] = i;
9417 AMDGPUOperand::ImmTyOffset);
9433bool AMDGPUOperand::isSMRDOffset8()
const {
9437bool AMDGPUOperand::isSMEMOffset()
const {
9439 return isImmLiteral();
9442bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9477bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9478 if (BoundCtrl == 0 || BoundCtrl == 1) {
9486void AMDGPUAsmParser::onBeginOfFile() {
9487 if (!getParser().getStreamer().getTargetStreamer())
9490 if (!getTargetStreamer().getTargetID())
9491 getTargetStreamer().initializeTargetID(getSTI(),
9495void AMDGPUAsmParser::emitTargetDirective() {
9496 if (!getParser().getStreamer().getTargetStreamer() ||
9501 getTargetStreamer().emitDirectiveAMDGCNTargetOnce();
9510bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9514 StringRef TokenId = getTokenStr();
9515 AGVK VK = StringSwitch<AGVK>(TokenId)
9516 .Case(
"max", AGVK::AGVK_Max)
9517 .Case(
"min", AGVK::AGVK_Min)
9518 .Case(
"or", AGVK::AGVK_Or)
9519 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9520 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9521 .Case(
"alignto", AGVK::AGVK_AlignTo)
9522 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9523 .Case(
"instprefsize", AGVK::AGVK_InstPrefSize)
9524 .Default(AGVK::AGVK_None);
9533 if (Exprs.
empty()) {
9535 "empty " + Twine(TokenId) +
" expression");
9538 if (CommaCount + 1 != Exprs.
size()) {
9540 "mismatch of commas in " + Twine(TokenId) +
" expression");
9544 Expected && Exprs.
size() != Expected) {
9545 Error(
getToken().getLoc(), Twine(TokenId) +
" expression expects " +
9546 Twine(Expected) +
" operands");
9553 if (getParser().parseExpression(Expr, EndLoc))
9557 if (LastTokenWasComma)
9561 "unexpected token in " + Twine(TokenId) +
" expression");
9567 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9571 StringRef
Name = getTokenStr();
9572 if (Name ==
"mul") {
9573 return parseIntWithPrefix(
"mul",
Operands, AMDGPUOperand::ImmTyOModSI,
9577 if (Name ==
"div") {
9578 return parseIntWithPrefix(
"div",
Operands, AMDGPUOperand::ImmTyOModSI,
9589 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9594 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9595 AMDGPU::OpName::src2};
9603 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9608 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9610 if (
DstOp.isReg() &&
9611 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9615 if ((OpSel & (1 << SrcNum)) != 0)
9621void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9628 OptionalImmIndexMap &OptionalIdx) {
9629 cvtVOP3P(Inst,
Operands, OptionalIdx);
9638 &&
Desc.NumOperands > (OpNum + 1)
9640 &&
Desc.operands()[OpNum + 1].RegClass != -1
9642 &&
Desc.getOperandConstraint(OpNum + 1,
9646void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9648 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9649 AMDGPU::OpName::src2};
9650 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9651 AMDGPU::OpName::src1_modifiers,
9652 AMDGPU::OpName::src2_modifiers};
9653 for (
int J = 0; J < 3; ++J) {
9654 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9660 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9663 if ((OpSel & (1 << J)) != 0)
9666 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9673void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
9675 OptionalImmIndexMap OptionalIdx;
9680 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9681 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9685 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9687 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9688 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9689 Op.isInterpAttrChan()) {
9691 }
else if (
Op.isImmModifier()) {
9692 OptionalIdx[
Op.getImmTy()] =
I;
9700 AMDGPUOperand::ImmTyHigh);
9704 AMDGPUOperand::ImmTyClamp);
9708 AMDGPUOperand::ImmTyOModSI);
9713 AMDGPUOperand::ImmTyOpSel);
9714 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9717 cvtOpSelHelper(Inst, OpSel);
9722 OptionalImmIndexMap OptionalIdx;
9727 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9728 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9732 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9734 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9735 }
else if (
Op.isImmModifier()) {
9736 OptionalIdx[
Op.getImmTy()] =
I;
9744 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9747 AMDGPUOperand::ImmTyOpSel);
9750 AMDGPUOperand::ImmTyWaitEXP);
9756 cvtOpSelHelper(Inst, OpSel);
9759void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9761 OptionalImmIndexMap OptionalIdx;
9764 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9768 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9769 static_cast<AMDGPUOperand &
>(*
Operands[
I++]).addRegOperands(Inst, 1);
9772 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
I]);
9777 if (NumOperands == CbszOpIdx) {
9782 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9783 }
else if (
Op.isImmModifier()) {
9784 OptionalIdx[
Op.getImmTy()] =
I;
9786 Op.addRegOrImmOperands(Inst, 1);
9791 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9792 if (CbszIdx != OptionalIdx.end()) {
9793 int CbszVal = ((AMDGPUOperand &)*
Operands[CbszIdx->second]).
getImm();
9797 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9798 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9799 if (BlgpIdx != OptionalIdx.end()) {
9800 int BlgpVal = ((AMDGPUOperand &)*
Operands[BlgpIdx->second]).
getImm();
9811 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9812 if (OpselIdx != OptionalIdx.end()) {
9813 OpSel =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselIdx->second])
9817 unsigned OpSelHi = 0;
9818 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9819 if (OpselHiIdx != OptionalIdx.end()) {
9820 OpSelHi =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselHiIdx->second])
9823 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9824 AMDGPU::OpName::src1_modifiers};
9826 for (
unsigned J = 0; J < 2; ++J) {
9827 unsigned ModVal = 0;
9828 if (OpSel & (1 << J))
9830 if (OpSelHi & (1 << J))
9833 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9839 OptionalImmIndexMap &OptionalIdx) {
9844 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9845 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9849 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9851 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9852 }
else if (
Op.isImmModifier()) {
9853 OptionalIdx[
Op.getImmTy()] =
I;
9855 Op.addRegOrImmOperands(Inst, 1);
9861 AMDGPUOperand::ImmTyScaleSel);
9865 AMDGPUOperand::ImmTyClamp);
9871 AMDGPUOperand::ImmTyByteSel);
9876 AMDGPUOperand::ImmTyOModSI);
9883 auto *it = Inst.
begin();
9885 it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9894 OptionalImmIndexMap OptionalIdx;
9895 cvtVOP3(Inst,
Operands, OptionalIdx);
9899 OptionalImmIndexMap &OptIdx) {
9904 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9905 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9906 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9907 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9908 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9909 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9910 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9911 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12 ||
9912 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx13 ||
9913 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx13) {
9922 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
9923 if (VdstInIdx != -1 && VdstInIdx ==
static_cast<int>(Inst.
getNumOperands()))
9926 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9927 if (BitOp3Idx != -1) {
9934 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9935 if (OpSelIdx != -1) {
9939 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9940 if (OpSelHiIdx != -1) {
9941 int DefaultVal =
IsPacked ? -1 : 0;
9947 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9948 if (MatrixAFMTIdx != -1) {
9950 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9954 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9955 if (MatrixBFMTIdx != -1) {
9957 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9960 int MatrixAScaleIdx =
9961 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9962 if (MatrixAScaleIdx != -1) {
9964 AMDGPUOperand::ImmTyMatrixAScale, 0);
9967 int MatrixBScaleIdx =
9968 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9969 if (MatrixBScaleIdx != -1) {
9971 AMDGPUOperand::ImmTyMatrixBScale, 0);
9974 int MatrixAScaleFmtIdx =
9975 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9976 if (MatrixAScaleFmtIdx != -1) {
9978 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9981 int MatrixBScaleFmtIdx =
9982 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9983 if (MatrixBScaleFmtIdx != -1) {
9985 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9990 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9994 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9996 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
10000 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
10001 if (NegHiIdx != -1)
10004 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
10005 AMDGPU::OpName::src2};
10006 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
10007 AMDGPU::OpName::src1_modifiers,
10008 AMDGPU::OpName::src2_modifiers};
10010 unsigned OpSel = 0;
10011 unsigned OpSelHi = 0;
10012 unsigned NegLo = 0;
10013 unsigned NegHi = 0;
10015 if (OpSelIdx != -1)
10018 if (OpSelHiIdx != -1)
10021 if (NegLoIdx != -1)
10024 if (NegHiIdx != -1)
10027 for (
int J = 0; J < 3; ++J) {
10028 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
10032 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
10042 uint32_t ModVal = 0;
10044 const MCOperand &SrcOp = Inst.
getOperand(OpIdx);
10045 if (SrcOp.
isReg() && getMRI()
10049 if (VGPRSuffixIsHi)
10052 if ((OpSel & (1 << J)) != 0)
10056 if ((OpSelHi & (1 << J)) != 0)
10059 if ((NegLo & (1 << J)) != 0)
10062 if ((NegHi & (1 << J)) != 0)
10070 OptionalImmIndexMap OptIdx;
10076 unsigned i,
unsigned Opc,
10077 AMDGPU::OpName
OpName) {
10078 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
10079 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
10081 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
10087 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
10090 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
10091 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
10093 OptionalImmIndexMap OptIdx;
10094 for (
unsigned i = 5; i <
Operands.size(); ++i) {
10095 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
10096 OptIdx[
Op.getImmTy()] = i;
10101 AMDGPUOperand::ImmTyIndexKey8bit);
10105 AMDGPUOperand::ImmTyIndexKey16bit);
10109 AMDGPUOperand::ImmTyIndexKey32bit);
10126 SMLoc S = getLoc();
10129 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
10130 SMLoc OpYLoc = getLoc();
10133 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
10136 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
10145 auto addOp = [&](uint16_t ParsedOprIdx) {
10146 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
10148 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10152 Op.addRegOperands(Inst, 1);
10155 if (
Op.isImm() ||
Op.isExpr()) {
10156 Op.addImmOperands(Inst, 1);
10168 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
10172 const auto &CInfo = InstInfo[CompIdx];
10173 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
10174 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
10175 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
10176 if (CInfo.hasSrc2Acc())
10177 addOp(CInfo.getIndexOfDstInParsedOperands());
10181 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
10182 if (BitOp3Idx != -1) {
10183 OptionalImmIndexMap OptIdx;
10184 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands.back());
10186 OptIdx[
Op.getImmTy()] =
Operands.size() - 1;
10196bool AMDGPUOperand::isDPP8()
const {
return isImmTy(ImmTyDPP8); }
10198bool AMDGPUOperand::isDPPCtrl()
const {
10199 using namespace AMDGPU::DPP;
10201 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
10204 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
10205 Imm <= DppCtrl::QUAD_PERM_LAST) ||
10206 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
10207 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
10208 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
10209 (
Imm == DppCtrl::WAVE_SHL1) || (
Imm == DppCtrl::WAVE_ROL1) ||
10210 (
Imm == DppCtrl::WAVE_SHR1) || (
Imm == DppCtrl::WAVE_ROR1) ||
10211 (
Imm == DppCtrl::ROW_MIRROR) || (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
10212 (
Imm == DppCtrl::BCAST15) || (
Imm == DppCtrl::BCAST31) ||
10213 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
10214 Imm <= DppCtrl::ROW_SHARE_LAST) ||
10215 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
10224bool AMDGPUOperand::isBLGP()
const {
10228bool AMDGPUOperand::isS16Imm()
const {
10232bool AMDGPUOperand::isU16Imm()
const {
10240bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
10245 SMLoc Loc =
getToken().getEndLoc();
10246 Token = std::string(getTokenStr());
10248 if (getLoc() != Loc)
10253 if (!parseId(Suffix))
10257 StringRef DimId = Token;
10272 SMLoc S = getLoc();
10278 SMLoc Loc = getLoc();
10279 if (!parseDimId(Encoding))
10280 return Error(Loc,
"invalid dim value");
10283 AMDGPUOperand::CreateImm(
this, Encoding, S, AMDGPUOperand::ImmTyDim));
10292 SMLoc S = getLoc();
10301 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10304 for (
size_t i = 0; i < 8; ++i) {
10308 SMLoc Loc = getLoc();
10309 if (getParser().parseAbsoluteExpression(Sels[i]))
10311 if (0 > Sels[i] || 7 < Sels[i])
10312 return Error(Loc,
"expected a 3-bit value");
10315 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10319 for (
size_t i = 0; i < 8; ++i)
10320 DPP8 |= (Sels[i] << (i * 3));
10323 AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10327bool AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10329 if (Ctrl ==
"row_newbcast")
10332 if (Ctrl ==
"row_share" || Ctrl ==
"row_xmask")
10335 if (Ctrl ==
"wave_shl" || Ctrl ==
"wave_shr" || Ctrl ==
"wave_rol" ||
10336 Ctrl ==
"wave_ror" || Ctrl ==
"row_bcast")
10339 return Ctrl ==
"row_mirror" ||
Ctrl ==
"row_half_mirror" ||
10340 Ctrl ==
"quad_perm" ||
Ctrl ==
"row_shl" ||
Ctrl ==
"row_shr" ||
10344int64_t AMDGPUAsmParser::parseDPPCtrlPerm() {
10347 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10351 for (
int i = 0; i < 4; ++i) {
10356 SMLoc Loc = getLoc();
10357 if (getParser().parseAbsoluteExpression(Temp))
10359 if (Temp < 0 || Temp > 3) {
10360 Error(Loc,
"expected a 2-bit value");
10364 Val += (Temp << i * 2);
10367 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10373int64_t AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10374 using namespace AMDGPU::DPP;
10379 SMLoc Loc = getLoc();
10381 if (getParser().parseAbsoluteExpression(Val))
10384 struct DppCtrlCheck {
10390 DppCtrlCheck
Check =
10391 StringSwitch<DppCtrlCheck>(Ctrl)
10392 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10393 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10394 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10395 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10396 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10397 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10398 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10399 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10400 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10401 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10405 if (
Check.Ctrl == -1) {
10406 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10414 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10422 using namespace AMDGPU::DPP;
10425 !isSupportedDPPCtrl(getTokenStr(),
Operands))
10428 SMLoc S = getLoc();
10434 if (Ctrl ==
"row_mirror") {
10435 Val = DppCtrl::ROW_MIRROR;
10436 }
else if (Ctrl ==
"row_half_mirror") {
10437 Val = DppCtrl::ROW_HALF_MIRROR;
10440 if (Ctrl ==
"quad_perm") {
10441 Val = parseDPPCtrlPerm();
10443 Val = parseDPPCtrlSel(Ctrl);
10452 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10458 OptionalImmIndexMap OptionalIdx;
10465 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10467 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10468 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10472 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10473 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10477 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10478 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10479 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx13 ||
10480 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10481 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx13 ||
10482 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10483 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx13 ||
10484 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
10485 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx13;
10491 if (OldIdx == NumOperands) {
10493 constexpr int DST_IDX = 0;
10495 }
else if (Src2ModIdx == NumOperands) {
10505 if (IsVOP3CvtSrDpp) {
10514 if (TiedTo != -1) {
10519 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10521 if (IsDPP8 &&
Op.isDppFI()) {
10524 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10525 }
else if (
Op.isReg()) {
10526 Op.addRegOperands(Inst, 1);
10527 }
else if (
Op.isImm() &&
10529 Op.addImmOperands(Inst, 1);
10530 }
else if (
Op.isImm()) {
10531 OptionalIdx[
Op.getImmTy()] =
I;
10539 AMDGPUOperand::ImmTyClamp);
10545 AMDGPUOperand::ImmTyByteSel);
10550 AMDGPUOperand::ImmTyOModSI);
10553 cvtVOP3P(Inst,
Operands, OptionalIdx);
10555 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
10558 AMDGPUOperand::ImmTyOpSel);
10563 AMDGPUOperand::ImmTyDPP8);
10564 using namespace llvm::AMDGPU::DPP;
10568 AMDGPUOperand::ImmTyDppCtrl, 0xe4);
10570 AMDGPUOperand::ImmTyDppRowMask, 0xf);
10572 AMDGPUOperand::ImmTyDppBankMask, 0xf);
10574 AMDGPUOperand::ImmTyDppBoundCtrl);
10578 AMDGPUOperand::ImmTyDppFI);
10584 OptionalImmIndexMap OptionalIdx;
10588 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10589 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10596 if (TiedTo != -1) {
10601 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10603 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10611 Op.addImmOperands(Inst, 1);
10613 Op.addRegWithFPInputModsOperands(Inst, 2);
10614 }
else if (
Op.isDppFI()) {
10616 }
else if (
Op.isReg()) {
10617 Op.addRegOperands(Inst, 1);
10623 Op.addRegWithFPInputModsOperands(Inst, 2);
10624 }
else if (
Op.isReg()) {
10625 Op.addRegOperands(Inst, 1);
10626 }
else if (
Op.isDPPCtrl()) {
10627 Op.addImmOperands(Inst, 1);
10628 }
else if (
Op.isImm()) {
10630 OptionalIdx[
Op.getImmTy()] =
I;
10638 using namespace llvm::AMDGPU::DPP;
10642 AMDGPUOperand::ImmTyDppRowMask, 0xf);
10644 AMDGPUOperand::ImmTyDppBankMask, 0xf);
10646 AMDGPUOperand::ImmTyDppBoundCtrl);
10649 AMDGPUOperand::ImmTyDppFI);
10660 AMDGPUOperand::ImmTy
Type) {
10661 return parseStringOrIntWithPrefix(
10663 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10668 return parseStringOrIntWithPrefix(
10669 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10670 AMDGPUOperand::ImmTySDWADstUnused);
10674 cvtSDWA(Inst,
Operands, SDWAInstType::VOP1);
10678 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2);
10681void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
10683 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2,
true,
true);
10686void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
10688 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2,
false,
true);
10696 SDWAInstType BasicInstType,
bool SkipDstVcc,
10698 using namespace llvm::AMDGPU::SDWA;
10700 OptionalImmIndexMap OptionalIdx;
10701 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10702 bool SkippedVcc =
false;
10706 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10707 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10711 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10712 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10713 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10719 if (BasicInstType == SDWAInstType::VOP2 &&
10725 if (BasicInstType == SDWAInstType::VOPC && Inst.
getNumOperands() == 0) {
10731 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10732 }
else if (
Op.isImm()) {
10734 OptionalIdx[
Op.getImmTy()] =
I;
10738 SkippedVcc =
false;
10742 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10743 Opc != AMDGPU::V_NOP_sdwa_vi) {
10745 switch (BasicInstType) {
10746 case SDWAInstType::VOP1:
10749 AMDGPUOperand::ImmTyClamp, 0);
10753 AMDGPUOperand::ImmTyOModSI, 0);
10757 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10761 AMDGPUOperand::ImmTySDWADstUnused,
10762 DstUnused::UNUSED_PRESERVE);
10765 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10768 case SDWAInstType::VOP2:
10770 AMDGPUOperand::ImmTyClamp, 0);
10774 AMDGPUOperand::ImmTyOModSI, 0);
10777 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10779 AMDGPUOperand::ImmTySDWADstUnused,
10780 DstUnused::UNUSED_PRESERVE);
10782 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10784 AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10787 case SDWAInstType::VOPC:
10790 AMDGPUOperand::ImmTyClamp, 0);
10792 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10794 AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10801 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10802 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10803 auto *it = Inst.
begin();
10805 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10818#define GET_MATCHER_IMPLEMENTATION
10819#define GET_MNEMONIC_SPELL_CHECKER
10820#define GET_MNEMONIC_CHECKER
10821#include "AMDGPUGenAsmMatcher.inc"
10827 return parseTokenOp(
"addr64",
Operands);
10829 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10831 return parseTokenOp(
"idxen",
Operands);
10833 return parseNamedBit(
"lds",
Operands, AMDGPUOperand::ImmTyLDS,
10836 return parseTokenOp(
"offen",
Operands);
10838 return parseTokenOp(
"off",
Operands);
10839 case MCK_row_95_en:
10840 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10842 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10844 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10846 return tryCustomParseOperand(
Operands, MCK);
10851unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10857 AMDGPUOperand &Operand = (AMDGPUOperand &)
Op;
10860 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10862 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10864 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10866 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10868 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10870 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10872 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10873 case MCK_row_95_en:
10874 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10882 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10884 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10885 case MCK_SOPPBrTarget:
10886 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10887 case MCK_VReg32OrOff:
10888 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10889 case MCK_InterpSlot:
10890 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10891 case MCK_InterpAttr:
10892 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10893 case MCK_InterpAttrChan:
10894 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10896 case MCK_SReg_64_XEXEC:
10906 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10908 return Match_InvalidOperand;
10917 SMLoc S = getLoc();
10926 return Error(S,
"expected a 16-bit value");
10929 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10933bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10939bool AMDGPUOperand::isSplitBarrier()
const {
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)
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.
Enums shared between the AMDGPU backend (LLVM) and the ELF linker (LLD) for the .amdgpu....
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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(GsymDataExtractor &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
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
MachineRegisterInfo & MRI
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.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static unsigned getNumExpectedArgs(VariantKind Kind)
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 std::optional< TargetID > parseTargetIDString(StringRef TargetIDDirective)
Parse and validate a TargetID from a full "<triple>-<processor>:<features>" directive string.
TargetIDSetting getXnackSetting() const
GPUKind getGPUKind() const
StringRef getTargetTripleString() const
std::string toString() const
TargetIDSetting getSramEccSetting() const
static constexpr roundingMode rmNearestTiesToEven
static constexpr const fltSemantics & IEEEhalf()
static constexpr const fltSemantics & IEEEsingle()
static constexpr const fltSemantics & BFloat()
static constexpr const fltSemantics & IEEEdouble()
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
const T & front() const
Get the first element.
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
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.
const int16_t * getRegClassByHwModeTable(unsigned ModeId) const
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
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
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.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
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
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
reference emplace_back(ArgTypes &&... Args)
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...
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
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
Get the string size.
constexpr const char * data() const
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)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getVGPREncodingGranule(const MCSubtargetInfo &STI, std::optional< bool > EnableWavefrontSize32)
unsigned getSGPREncodingGranule(const MCSubtargetInfo &STI)
bool targetIDSettingsConflict(TargetIDSetting Lhs, TargetIDSetting Rhs)
Returns true if Lhs and Rhs are incompatible (both specific but different).
unsigned getLocalMemorySize(const MCSubtargetInfo &STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
constexpr const char *const ModMatrixFmt[]
constexpr const char *const ModMatrixScaleFmt[]
constexpr const char *const ModMatrixScale[]
bool 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.
FuncInfoFlags
Per-function flags packed into INFO_FLAGS entries.
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)
LLVM_READONLY bool isLitExpr(const MCExpr *Expr)
bool isInlinableLiteralV2BF16(uint32_t Literal)
LLVM_ABI bool isCPUValidForSubArch(Triple::SubArchType SubArch, GPUKind AK)
Return true if the GPU AK is usable with the triple subarch SubArch.
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 isPackedSingleSGPRFP32Inst(unsigned Opc)
The opcode is a packed fp32 instruction which only reads low 32 bits of a scalar operand and propagat...
LLVM_ABI unsigned getAddressableNumSGPRs(GPUKind AK)
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
LLVM_ABI unsigned getTotalNumVGPRs(GPUKind AK, bool IsWave32)
CanBeVOPD getCanBeVOPD(unsigned Opc, unsigned EncodingFamily, bool VOPD3)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
bool isSI(const MCSubtargetInfo &STI)
bool hasPrivateApertureRegs(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
bool isGFX9(const MCSubtargetInfo &STI)
unsigned getVOPDEncodingFamily(const MCSubtargetInfo &ST)
LLVM_READONLY bool hasNamedOperand(uint32_t Opcode, OpName NamedIdx)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
GPUKind
GPU kinds supported by the AMDGPU target.
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?
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi, bool *IsBF16)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
LLVM_ABI GPUKind parseArchAMDGCN(StringRef CPU)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
AMDGPU::TargetID TargetID
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
bool isValidWMMAScaleFmtCombination(unsigned AFmt, unsigned AScale, unsigned BFmt, unsigned BScale)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_IMM_NOINLINE_FP16
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT64
@ 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
constexpr bool isBF16SrcOperand(const MCOperandInfo &OpInfo)
Is this a scalar (i.e. not packed) bf16 source operand?
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
LLVM_ABI StringRef getArchNameAMDGCN(GPUKind AK)
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)
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)
bool hasPopsExitingWaveID(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.
@ 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)
constexpr bool isAtomicRet(const T &...O)
constexpr bool isVOPC(const T &...O)
constexpr bool isVOP3(const T &...O)
constexpr bool isVOP1(const T &...O)
constexpr bool usesTENSOR_CNT(const T &...O)
constexpr bool isMAI(const T &...O)
constexpr bool isVOP2(const T &...O)
constexpr bool isSWMMAC(const T &...O)
constexpr bool isSOP2(const T &...O)
constexpr bool isFLAT(const T &...O)
constexpr bool isVOP3P(const T &...O)
constexpr bool isBuffer(const T &...O)
constexpr bool hasIntClamp(const T &...O)
constexpr bool isAtomicNoRet(const T &...O)
constexpr bool isSMRD(const T &...O)
constexpr bool isVOP3Like(const T &...O)
constexpr bool isMIMG(const T &...O)
constexpr bool isVMEM(const T &...O)
constexpr bool isImage(const T &...O)
constexpr bool isWMMA(const T &...O)
constexpr bool isVOPD3(const T &...O)
constexpr bool isGWS(const T &...O)
constexpr bool isMUBUF(const T &...O)
constexpr bool isSDWA(const T &...O)
constexpr bool isSOPC(const T &...O)
constexpr bool isDOT(const T &...O)
constexpr bool isVSAMPLE(const T &...O)
constexpr bool isDS(const T &...O)
constexpr bool isAtomic(const T &...O)
constexpr bool isGather4(const T &...O)
constexpr bool isPacked(const T &...O)
constexpr bool isDPP(const T &...O)
constexpr bool isSegmentSpecificFLAT(const T &...O)
@ Valid
The data is already valid.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
EnumSet< Modifier > Modifiers
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
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()
LLVM_ABI 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.
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
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.
Target & getTheGCNLegacyTarget()
The target for GCN GPUs, registered under the legacy "amdgcn" architecture name for use with -march.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
void initDefault(const MCSubtargetInfo &STI, MCContext &Ctx, bool InitMCExpr=true)
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
uint32_t PrivateSegmentSize
SmallVector< std::pair< MCSymbol *, std::string >, 4 > IndirectCalls
SmallVector< std::pair< MCSymbol *, MCSymbol * >, 8 > Calls
SmallVector< FuncInfo, 8 > Funcs
SmallVector< std::pair< MCSymbol *, std::string >, 4 > TypeIds
SmallVector< std::pair< MCSymbol *, MCSymbol * >, 4 > Uses
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