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 hasCacheFillSize()
const {
1369 return getFeatureBits()[AMDGPU::FeatureCacheFillSize];
1382 AMDGPUTargetStreamer &getTargetStreamer() {
1383 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1384 return static_cast<AMDGPUTargetStreamer &
>(TS);
1390 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1393 const MCRegisterInfo *getMRI()
const {
1397 const MCInstrInfo *getMII()
const {
return &MII; }
1401 int16_t getTargetRegClass(
unsigned TargetRCIdx)
const {
1407 const FeatureBitset &getFeatureBits()
const {
1408 return getSTI().getFeatureBits();
1411 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1412 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1413 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1415 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1416 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1417 bool isForcedDPP()
const {
return ForcedDPP; }
1418 bool isForcedSDWA()
const {
return ForcedSDWA; }
1419 ArrayRef<unsigned> getMatchedVariants()
const;
1420 StringRef getMatchedVariantName()
const;
1422 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1423 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1424 bool RestoreOnFailure);
1425 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1426 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1427 SMLoc &EndLoc)
override;
1428 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1429 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1430 unsigned Kind)
override;
1431 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1434 bool MatchingInlineAsm)
override;
1435 bool ParseDirective(AsmToken DirectiveID)
override;
1436 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override;
1437 void onEndOfFile()
override;
1439 OperandMode
Mode = OperandMode_Default);
1440 StringRef parseMnemonicSuffix(StringRef Name);
1441 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1447 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1451 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1452 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1454 ParseStatus parseOperandArrayWithPrefix(
1456 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1457 bool (*ConvertResult)(int64_t &) =
nullptr);
1461 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1462 bool IgnoreNegative =
false);
1463 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1468 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1472 ArrayRef<const char *> Ids,
1476 ArrayRef<const char *> Ids,
1477 AMDGPUOperand::ImmTy
Type);
1480 bool isOperandModifier(
const AsmToken &Token,
1481 const AsmToken &NextToken)
const;
1482 bool isRegOrOperandModifier(
const AsmToken &Token,
1483 const AsmToken &NextToken)
const;
1484 bool isNamedOperandModifier(
const AsmToken &Token,
1485 const AsmToken &NextToken)
const;
1486 bool isOpcodeModifierWithVal(
const AsmToken &Token,
1487 const AsmToken &NextToken)
const;
1488 bool parseSP3NegModifier();
1495 bool AllowImm =
true);
1497 bool AllowImm =
true);
1503 AMDGPUOperand::ImmTy ImmTy);
1508 AMDGPUOperand::ImmTy
Type);
1512 AMDGPUOperand::ImmTy
Type);
1516 AMDGPUOperand::ImmTy
Type);
1520 ParseStatus parseDfmtNfmt(int64_t &
Format);
1521 ParseStatus parseUfmt(int64_t &
Format);
1522 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1524 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1527 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1528 ParseStatus parseNumericFormat(int64_t &
Format);
1532 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1533 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr,
1538 bool parseCnt(int64_t &IntVal);
1541 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1542 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1545 bool parseDelay(int64_t &Delay);
1551 struct OperandInfoTy {
1554 bool IsSymbolic =
false;
1555 bool IsDefined =
false;
1557 constexpr OperandInfoTy(int64_t Val) : Val(Val) {}
1560 struct StructuredOpField : OperandInfoTy {
1564 bool IsDefined =
false;
1566 constexpr StructuredOpField(StringLiteral Id, StringLiteral Desc,
1567 unsigned Width, int64_t
Default)
1568 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1569 virtual ~StructuredOpField() =
default;
1571 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1572 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1576 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1578 return Error(Parser,
"not supported on this GPU");
1580 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1588 bool parseSendMsgBody(OperandInfoTy &
Msg, OperandInfoTy &
Op,
1589 OperandInfoTy &Stream);
1590 bool validateSendMsg(
const OperandInfoTy &
Msg,
const OperandInfoTy &
Op,
1591 const OperandInfoTy &Stream);
1593 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1594 OperandInfoTy &Width);
1599 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1606 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand &)>
Test,
1608 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1612 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1618 bool validateBF16InlineConst(
const MCInst &Inst,
1621 bool validateConstantBusLimitations(
const MCInst &Inst,
1623 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1626 bool tryVOPD(
const MCInst &Inst);
1627 bool tryVOPD3(
const MCInst &Inst);
1628 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1630 bool validateIntClampSupported(
const MCInst &Inst);
1631 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1632 bool validateMIMGGatherDMask(
const MCInst &Inst);
1634 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1635 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1636 bool validateMIMGD16(
const MCInst &Inst);
1638 bool validateTensorR128(
const MCInst &Inst);
1639 bool validateMIMGMSAA(
const MCInst &Inst);
1640 bool validateOpSel(
const MCInst &Inst);
1641 bool validateTrue16OpSel(
const MCInst &Inst);
1642 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1644 bool validateVccOperand(MCRegister
Reg)
const;
1649 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1650 bool validateVGPRAlign(
const MCInst &Inst)
const;
1654 bool validateDivScale(
const MCInst &Inst);
1659 const unsigned CPol);
1665 bool validateClusterBarrierIsFirst(
const MCInst &Inst,
1668 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1669 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1670 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1671 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1673 bool isSupportedMnemo(StringRef Mnemo,
const FeatureBitset &FBS);
1674 bool isSupportedMnemo(StringRef Mnemo,
const FeatureBitset &FBS,
1675 ArrayRef<unsigned> Variants);
1676 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1678 bool isId(
const StringRef Id)
const;
1679 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1681 StringRef getId()
const;
1682 bool trySkipId(
const StringRef Id);
1683 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1687 bool parseString(StringRef &Val,
1688 const StringRef ErrMsg =
"expected a string");
1689 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1695 StringRef getTokenStr()
const;
1696 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1698 SMLoc getLoc()
const;
1702 void onBeginOfFile()
override;
1707 void emitTargetDirective();
1708 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1720 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1721 const unsigned MaxVal,
const Twine &ErrMsg,
1723 bool parseSwizzleOperands(
const unsigned OpNum, int64_t *
Op,
1724 const unsigned MinVal,
const unsigned MaxVal,
1725 const StringRef ErrMsg);
1727 bool parseSwizzleOffset(int64_t &
Imm);
1728 bool parseSwizzleMacro(int64_t &
Imm);
1729 bool parseSwizzleQuadPerm(int64_t &
Imm);
1730 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1731 bool parseSwizzleBroadcast(int64_t &
Imm);
1732 bool parseSwizzleSwap(int64_t &
Imm);
1733 bool parseSwizzleReverse(int64_t &
Imm);
1734 bool parseSwizzleFFT(int64_t &
Imm);
1735 bool parseSwizzleRotate(int64_t &
Imm);
1738 int64_t parseGPRIdxMacro();
1741 cvtMubufImpl(Inst,
Operands,
false);
1744 cvtMubufImpl(Inst,
Operands,
true);
1750 OptionalImmIndexMap &OptionalIdx);
1759 OptionalImmIndexMap &OptionalIdx);
1761 OptionalImmIndexMap &OptionalIdx);
1765 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1767 bool parseDimId(
unsigned &Encoding);
1769 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1773 int64_t parseDPPCtrlSel(StringRef Ctrl);
1774 int64_t parseDPPCtrlPerm();
1780 bool IsDPP8 =
false);
1786 AMDGPUOperand::ImmTy
Type);
1794 enum class SDWAInstType :
unsigned {
VOP1 = 0,
VOP2 = 1,
VOPC = 2 };
1797 SDWAInstType BasicInstType,
bool SkipDstVcc =
false,
1798 bool SkipSrcVcc =
false);
1908bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
1918 if (!isImmTy(ImmTyNone)) {
1923 if (getModifiers().
Lit != LitModifier::None)
1933 if (type == MVT::f64 || type == MVT::i64) {
1935 AsmParser->hasInv2PiInlineImm());
1938 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
1957 APFloat::rmNearestTiesToEven, &Lost);
1964 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
1966 AsmParser->hasInv2PiInlineImm());
1971 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
1972 AsmParser->hasInv2PiInlineImm());
1976 if (type == MVT::f64 || type == MVT::i64) {
1978 AsmParser->hasInv2PiInlineImm());
1987 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()), type,
1988 AsmParser->hasInv2PiInlineImm());
1992 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
1993 AsmParser->hasInv2PiInlineImm());
1996bool AMDGPUOperand::isLiteralImm(MVT type)
const {
1998 if (!isImmTy(ImmTyNone)) {
2003 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2008 if (type == MVT::f64 && hasFPModifiers()) {
2028 if (type == MVT::f64) {
2033 if (type == MVT::i64) {
2046 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2047 : (type == MVT::v2i16) ? MVT::f32
2048 : (type == MVT::v2f32) ? MVT::f32
2051 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2055bool AMDGPUOperand::isRegClassTarget(
unsigned TargetRCIdx)
const {
2058 int16_t RCID = AsmParser->getTargetRegClass(TargetRCIdx);
2059 return RCID >= 0 && isRegClass(RCID);
2062bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2063 return isRegKind() &&
2064 AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2067bool AMDGPUOperand::isVRegWithInputMods()
const {
2068 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2070 (AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP] &&
2071 isRegClassTarget(AMDGPU::VReg_64_AlignTarget));
2074template <
bool IsFake16>
2075bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2076 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2077 : AMDGPU::VGPR_16_Lo128RegClassID);
2080template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2081 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2082 : AMDGPU::VGPR_16RegClassID);
2085bool AMDGPUOperand::isT16_LO16VRegWithInputMods()
const {
2086 return isRegClass(AMDGPU::VGPR_16_LO16RegClassID);
2089bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2090 if (AsmParser->isVI())
2092 if (AsmParser->isGFX9Plus())
2093 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2097bool AMDGPUOperand::isSDWAFP16Operand()
const {
2098 return isSDWAOperand(MVT::f16);
2101bool AMDGPUOperand::isSDWAFP32Operand()
const {
2102 return isSDWAOperand(MVT::f32);
2105bool AMDGPUOperand::isSDWAInt16Operand()
const {
2106 return isSDWAOperand(MVT::i16);
2109bool AMDGPUOperand::isSDWAInt32Operand()
const {
2110 return isSDWAOperand(MVT::i32);
2113bool AMDGPUOperand::isBoolReg()
const {
2114 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2115 (AsmParser->isWave32() && isSCSrc_b32()));
2119 unsigned Size)
const {
2120 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2135void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
2136 bool ApplyModifiers)
const {
2146 addLiteralImmOperand(Inst,
Imm.Val,
2147 ApplyModifiers & isImmTy(ImmTyNone) &&
2148 Imm.Mods.hasFPModifiers());
2150 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2155void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
2156 bool ApplyModifiers)
const {
2157 const auto &InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2162 if (ApplyModifiers) {
2164 const unsigned Size =
2166 Val = applyInputFPModifiers(Val,
Size);
2170 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2172 bool CanUse64BitLiterals =
2175 MCContext &Ctx = AsmParser->getContext();
2186 if (
Lit == LitModifier::None &&
2188 AsmParser->hasInv2PiInlineImm())) {
2196 bool HasMandatoryLiteral =
2199 if (
Literal.getLoBits(32) != 0 &&
2200 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2201 !HasMandatoryLiteral) {
2202 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2204 "Can't encode literal as exact 64-bit floating-point operand. "
2205 "Low 32-bits will be set to zero");
2206 Val &= 0xffffffff00000000u;
2212 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2218 Lit = LitModifier::Lit64;
2219 }
else if (
Lit == LitModifier::Lit) {
2233 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2235 Lit = LitModifier::Lit64;
2242 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2243 Literal == 0x3fc45f306725feed) {
2283 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2290 if (
Lit != LitModifier::None) {
2321 if (
Lit == LitModifier::None &&
2331 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2339 if (
Lit == LitModifier::None &&
2347 if (!AsmParser->has64BitLiterals()) {
2348 Val =
static_cast<uint64_t>(Val) << 32;
2355 if (
Lit == LitModifier::Lit ||
2357 Val =
static_cast<uint64_t>(Val) << 32;
2361 if (
Lit == LitModifier::Lit)
2388 if (
Lit != LitModifier::None) {
2396void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2402bool AMDGPUOperand::isInlineValue()
const {
2410void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2421 if (Is == IS_VGPR) {
2426 return AMDGPU::VGPR_32RegClassID;
2428 return AMDGPU::VReg_64RegClassID;
2430 return AMDGPU::VReg_96RegClassID;
2432 return AMDGPU::VReg_128RegClassID;
2434 return AMDGPU::VReg_160RegClassID;
2436 return AMDGPU::VReg_192RegClassID;
2438 return AMDGPU::VReg_224RegClassID;
2440 return AMDGPU::VReg_256RegClassID;
2442 return AMDGPU::VReg_288RegClassID;
2444 return AMDGPU::VReg_320RegClassID;
2446 return AMDGPU::VReg_352RegClassID;
2448 return AMDGPU::VReg_384RegClassID;
2450 return AMDGPU::VReg_512RegClassID;
2452 return AMDGPU::VReg_1024RegClassID;
2454 }
else if (Is == IS_TTMP) {
2459 return AMDGPU::TTMP_32RegClassID;
2461 return AMDGPU::TTMP_64RegClassID;
2463 return AMDGPU::TTMP_128RegClassID;
2465 return AMDGPU::TTMP_256RegClassID;
2467 return AMDGPU::TTMP_512RegClassID;
2469 }
else if (Is == IS_SGPR) {
2474 return AMDGPU::SGPR_32RegClassID;
2476 return AMDGPU::SGPR_64RegClassID;
2478 return AMDGPU::SGPR_96RegClassID;
2480 return AMDGPU::SGPR_128RegClassID;
2482 return AMDGPU::SGPR_160RegClassID;
2484 return AMDGPU::SGPR_192RegClassID;
2486 return AMDGPU::SGPR_224RegClassID;
2488 return AMDGPU::SGPR_256RegClassID;
2490 return AMDGPU::SGPR_288RegClassID;
2492 return AMDGPU::SGPR_320RegClassID;
2494 return AMDGPU::SGPR_352RegClassID;
2496 return AMDGPU::SGPR_384RegClassID;
2498 return AMDGPU::SGPR_512RegClassID;
2500 }
else if (Is == IS_AGPR) {
2505 return AMDGPU::AGPR_32RegClassID;
2507 return AMDGPU::AReg_64RegClassID;
2509 return AMDGPU::AReg_96RegClassID;
2511 return AMDGPU::AReg_128RegClassID;
2513 return AMDGPU::AReg_160RegClassID;
2515 return AMDGPU::AReg_192RegClassID;
2517 return AMDGPU::AReg_224RegClassID;
2519 return AMDGPU::AReg_256RegClassID;
2521 return AMDGPU::AReg_288RegClassID;
2523 return AMDGPU::AReg_320RegClassID;
2525 return AMDGPU::AReg_352RegClassID;
2527 return AMDGPU::AReg_384RegClassID;
2529 return AMDGPU::AReg_512RegClassID;
2531 return AMDGPU::AReg_1024RegClassID;
2539 .
Case(
"exec", AMDGPU::EXEC)
2540 .
Case(
"vcc", AMDGPU::VCC)
2541 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2542 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2543 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2544 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2545 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2546 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2547 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2548 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2549 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2550 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2551 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2552 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2553 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2554 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2555 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2556 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2557 .
Case(
"m0", AMDGPU::M0)
2558 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2559 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2560 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2561 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2562 .
Case(
"scc", AMDGPU::SRC_SCC)
2563 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2564 .
Case(
"tba", AMDGPU::TBA)
2565 .
Case(
"tma", AMDGPU::TMA)
2566 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2567 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2568 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2569 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2570 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2571 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2572 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2573 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2574 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2575 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2576 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2577 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2578 .
Case(
"pc", AMDGPU::PC_REG)
2579 .
Case(
"null", AMDGPU::SGPR_NULL)
2583bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2584 SMLoc &EndLoc,
bool RestoreOnFailure) {
2585 auto R = parseRegister();
2589 RegNo =
R->getReg();
2590 StartLoc =
R->getStartLoc();
2591 EndLoc =
R->getEndLoc();
2595bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2597 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2600ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2602 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2603 bool PendingErrors = getParser().hasPendingError();
2604 getParser().clearPendingErrors();
2612bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2613 RegisterKind RegKind,
2615 RegisterKind RegKind1, SMLoc Loc) {
2617 if (RegKind == IS_SGPR) {
2618 unsigned RegIdx = (
Reg - AMDGPU::SGPR0) + RegWidth / 32;
2619 if ((RegIdx == 106 && Reg1 == AMDGPU::VCC_LO) ||
2620 (RegIdx == 107 && Reg1 == AMDGPU::VCC_HI)) {
2626 if (RegKind != RegKind1) {
2627 Error(Loc,
"registers in a list must be of the same kind");
2633 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2638 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2639 Reg = AMDGPU::FLAT_SCR;
2643 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2644 Reg = AMDGPU::XNACK_MASK;
2648 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2653 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2658 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2663 Error(Loc,
"register does not fit in the list");
2669 if (Reg1 !=
Reg + RegWidth / 32) {
2670 Error(Loc,
"registers in a list must have consecutive indices");
2686 {{
"v"}, IS_VGPR}, {{
"s"}, IS_SGPR}, {{
"ttmp"}, IS_TTMP},
2687 {{
"acc"}, IS_AGPR}, {{
"a"}, IS_AGPR},
2691 return Kind == IS_VGPR || Kind == IS_SGPR || Kind == IS_TTMP ||
2697 if (Str.starts_with(
Reg.Name))
2703 return !Str.getAsInteger(10, Num);
2706bool AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2707 const AsmToken &NextToken)
const {
2722 StringRef RegSuffix = Str.substr(
RegName.size());
2723 if (!RegSuffix.
empty()) {
2740bool AMDGPUAsmParser::isRegister() {
2741 return isRegister(
getToken(), peekToken());
2744MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2745 unsigned SubReg,
unsigned RegWidth,
2749 unsigned AlignSize = 1;
2750 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2756 if (RegNum % AlignSize != 0) {
2757 Error(Loc,
"invalid register alignment");
2758 return MCRegister();
2761 unsigned RegIdx = RegNum / AlignSize;
2764 Error(Loc,
"invalid or unsupported register size");
2765 return MCRegister();
2769 const MCRegisterClass &RC =
TRI->getRegClass(RCID);
2770 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2771 Error(Loc,
"register index is out of range");
2772 return AMDGPU::NoRegister;
2775 if (RegKind == IS_VGPR && !
isGFX1250Plus() && RegIdx + RegWidth / 32 > 256) {
2776 Error(Loc,
"register index is out of range");
2777 return MCRegister();
2786 Error(Loc,
"invalid subregister");
2792bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2794 int64_t RegLo, RegHi;
2798 SMLoc FirstIdxLoc = getLoc();
2805 SecondIdxLoc = getLoc();
2816 Error(FirstIdxLoc,
"invalid register index");
2821 Error(SecondIdxLoc,
"invalid register index");
2825 if (RegLo > RegHi) {
2826 Error(FirstIdxLoc,
"first register index should not exceed second index");
2830 if (RegHi == RegLo) {
2831 StringRef RegSuffix = getTokenStr();
2832 if (RegSuffix ==
".l") {
2833 SubReg = AMDGPU::lo16;
2835 }
else if (RegSuffix ==
".h") {
2836 SubReg = AMDGPU::hi16;
2841 Num =
static_cast<unsigned>(RegLo);
2842 RegWidth = 32 * ((RegHi - RegLo) + 1);
2847MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2850 SmallVectorImpl<AsmToken> &Tokens) {
2856 RegKind = IS_SPECIAL;
2863MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2866 SmallVectorImpl<AsmToken> &Tokens) {
2868 StringRef
RegName = getTokenStr();
2869 auto Loc = getLoc();
2873 Error(Loc,
"invalid register name");
2874 return MCRegister();
2882 unsigned SubReg = NoSubRegister;
2883 bool IsRange =
false;
2884 if (!RegSuffix.
empty()) {
2886 SubReg = AMDGPU::lo16;
2888 SubReg = AMDGPU::hi16;
2892 Error(Loc,
"invalid register index");
2893 return MCRegister();
2899 if (!ParseRegRange(RegNum, RegWidth, SubReg))
2900 return MCRegister();
2904 MCRegister
Reg = getRegularReg(RegKind, RegNum, SubReg, RegWidth, Loc);
2905 const MCRegisterInfo &
TRI = *
getContext().getRegisterInfo();
2906 if (RegKind == IS_SGPR && IsRange
2907 ? (
TRI.isSubRegister(
Reg, VCC_LO) ||
TRI.isSubRegister(
Reg, VCC_HI))
2908 : (
Reg == VCC_LO ||
Reg == VCC_HI)) {
2909 Error(Loc,
"register index is out of range");
2910 return MCRegister();
2916MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
2917 unsigned &RegNum,
unsigned &RegWidth,
2918 SmallVectorImpl<AsmToken> &Tokens) {
2920 auto ListLoc = getLoc();
2923 "expected a register or a list of registers")) {
2924 return MCRegister();
2929 auto Loc = getLoc();
2930 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
2931 return MCRegister();
2932 if (RegWidth != 32) {
2933 Error(Loc,
"expected a single 32-bit register");
2934 return MCRegister();
2938 RegisterKind NextRegKind;
2940 unsigned NextRegNum, NextRegWidth;
2943 if (!ParseAMDGPURegister(NextRegKind, NextReg, NextRegNum, NextRegWidth,
2945 return MCRegister();
2947 if (NextRegWidth != 32) {
2948 Error(Loc,
"expected a single 32-bit register");
2949 return MCRegister();
2951 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, NextRegKind,
2953 return MCRegister();
2957 "expected a comma or a closing square bracket")) {
2958 return MCRegister();
2962 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
2967bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
2968 MCRegister &
Reg,
unsigned &RegNum,
2970 SmallVectorImpl<AsmToken> &Tokens) {
2971 auto Loc = getLoc();
2975 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
2977 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
2979 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
2984 assert(Parser.hasPendingError());
2988 if (!subtargetHasRegister(*
TRI,
Reg)) {
2989 if (
Reg == AMDGPU::SGPR_NULL) {
2990 Error(Loc,
"'null' operand is not supported on this GPU");
2993 " register not available on this GPU");
3001bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3002 MCRegister &
Reg,
unsigned &RegNum,
3004 bool RestoreOnFailure ) {
3008 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3009 if (RestoreOnFailure) {
3010 while (!Tokens.
empty()) {
3019std::optional<StringRef>
3020AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3023 return StringRef(
".amdgcn.next_free_vgpr");
3025 return StringRef(
".amdgcn.next_free_sgpr");
3027 return std::nullopt;
3031void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3032 auto SymbolName = getGprCountSymbolName(RegKind);
3033 assert(SymbolName &&
"initializing invalid register kind");
3039bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3040 unsigned DwordRegIndex,
3041 unsigned RegWidth) {
3046 auto SymbolName = getGprCountSymbolName(RegKind);
3051 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3055 return !
Error(getLoc(),
3056 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3060 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3062 if (OldCount <= NewMax)
3068std::unique_ptr<AMDGPUOperand>
3069AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3071 SMLoc StartLoc = Tok.getLoc();
3072 SMLoc EndLoc = Tok.getEndLoc();
3073 RegisterKind RegKind;
3075 unsigned RegNum, RegWidth;
3077 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3081 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3084 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3085 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3092 if (isRegister() || isModifier())
3095 if (
Lit == LitModifier::None) {
3096 if (trySkipId(
"lit"))
3097 Lit = LitModifier::Lit;
3098 else if (trySkipId(
"lit64"))
3099 Lit = LitModifier::Lit64;
3101 if (
Lit != LitModifier::None) {
3104 ParseStatus S = parseImm(
Operands, HasSP3AbsModifier,
Lit);
3113 const auto &NextTok = peekToken();
3116 bool Negate =
false;
3124 AMDGPUOperand::Modifiers Mods;
3132 StringRef Num = getTokenStr();
3135 APFloat RealVal(APFloat::IEEEdouble());
3136 auto roundMode = APFloat::rmNearestTiesToEven;
3137 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3140 RealVal.changeSign();
3143 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(),
3144 S, AMDGPUOperand::ImmTyNone,
true));
3145 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3146 Op.setModifiers(Mods);
3155 if (HasSP3AbsModifier) {
3164 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3167 if (Parser.parseExpression(Expr))
3171 if (Expr->evaluateAsAbsolute(IntVal)) {
3173 return Error(S,
"literal value out of range");
3174 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3175 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3176 Op.setModifiers(Mods);
3178 if (
Lit != LitModifier::None)
3180 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3193 if (
auto R = parseRegister()) {
3203 ParseStatus Res = parseReg(
Operands);
3211bool AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
3212 const AsmToken &NextToken)
const {
3215 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3220bool AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
3221 const AsmToken &NextToken)
const {
3225bool AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
3226 const AsmToken &NextToken)
const {
3227 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3230bool AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
3231 const AsmToken &NextToken)
const {
3232 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3249bool AMDGPUAsmParser::isModifier() {
3252 AsmToken NextToken[2];
3253 peekTokens(NextToken);
3257 bool IsOpcodeModifier = isOpcodeModifierWithVal(Tok, NextToken[0]) &&
3260 return isOperandModifier(Tok, NextToken[0]) ||
3262 isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3288bool AMDGPUAsmParser::parseSP3NegModifier() {
3290 AsmToken NextToken[2];
3291 peekTokens(NextToken);
3294 (isRegister(NextToken[0], NextToken[1]) ||
3312 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3314 SP3Neg = parseSP3NegModifier();
3317 Neg = trySkipId(
"neg");
3319 return Error(Loc,
"expected register or immediate");
3323 Abs = trySkipId(
"abs");
3328 if (trySkipId(
"lit")) {
3329 Lit = LitModifier::Lit;
3332 }
else if (trySkipId(
"lit64")) {
3333 Lit = LitModifier::Lit64;
3336 if (!has64BitLiterals())
3337 return Error(Loc,
"lit64 is not supported on this GPU");
3343 return Error(Loc,
"expected register or immediate");
3352 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3356 if (
Lit != LitModifier::None && !
Operands.back()->isImm())
3357 Error(Loc,
"expected immediate with lit modifier");
3359 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3365 if (
Lit != LitModifier::None &&
3369 AMDGPUOperand::Modifiers Mods;
3370 Mods.Abs = Abs || SP3Abs;
3371 Mods.Neg = Neg || SP3Neg;
3374 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3375 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3377 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3378 Op.setModifiers(Mods);
3386 bool Sext = trySkipId(
"sext");
3387 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3402 AMDGPUOperand::Modifiers Mods;
3405 if (Mods.hasIntModifiers()) {
3406 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3408 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3409 Op.setModifiers(Mods);
3416 return parseRegOrImmWithFPInputMods(
Operands,
false);
3420 return parseRegOrImmWithIntInputMods(
Operands,
false);
3427 if (!trySkipId(
"rsrcidx"))
3433 SMLoc RegLoc = getLoc();
3434 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3442 if (!
Reg->isRsrcReg32())
3443 return Error(RegLoc,
"rsrcidx operand must be a 32-bit SGPR or VGPR");
3453 auto Loc = getLoc();
3454 if (trySkipId(
"off")) {
3456 AMDGPUOperand::CreateImm(
this, 0, Loc, AMDGPUOperand::ImmTyOff,
false));
3463 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3472unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3477 return Match_InvalidOperand;
3479 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3480 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3483 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3485 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3486 return Match_InvalidOperand;
3494 if (tryAnotherVOPDEncoding(Inst))
3495 return Match_InvalidOperand;
3497 return Match_Success;
3501 static const unsigned Variants[] = {
3510ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3511 if (isForcedDPP() && isForcedVOP3()) {
3515 if (getForcedEncodingSize() == 32) {
3520 if (isForcedVOP3()) {
3525 if (isForcedSDWA()) {
3531 if (isForcedDPP()) {
3539StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3540 if (isForcedDPP() && isForcedVOP3())
3543 if (getForcedEncodingSize() == 32)
3559AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3563 case AMDGPU::FLAT_SCR:
3565 case AMDGPU::VCC_LO:
3566 case AMDGPU::VCC_HI:
3573 return MCRegister();
3580bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3581 unsigned OpIdx)
const {
3589 const MCOperand &MO = Inst.
getOperand(OpIdx);
3639unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3645 case AMDGPU::V_LSHLREV_B64_e64:
3646 case AMDGPU::V_LSHLREV_B64_gfx10:
3647 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3648 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3649 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3650 case AMDGPU::V_LSHRREV_B64_e64:
3651 case AMDGPU::V_LSHRREV_B64_gfx10:
3652 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3653 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3654 case AMDGPU::V_ASHRREV_I64_e64:
3655 case AMDGPU::V_ASHRREV_I64_gfx10:
3656 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3657 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3658 case AMDGPU::V_LSHL_B64_e64:
3659 case AMDGPU::V_LSHR_B64_e64:
3660 case AMDGPU::V_ASHR_I64_e64:
3673 bool AddMandatoryLiterals =
false) {
3676 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3680 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3682 return {getNamedOperandIdx(Opcode, OpName::src0X),
3683 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3684 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3685 getNamedOperandIdx(Opcode, OpName::src0Y),
3686 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3687 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3692 return {getNamedOperandIdx(Opcode, OpName::src0),
3693 getNamedOperandIdx(Opcode, OpName::src1),
3694 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3697bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3698 const MCOperand &MO = Inst.
getOperand(OpIdx);
3700 return !isInlineConstant(Inst, OpIdx);
3707 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3718 const unsigned Opcode = Inst.
getOpcode();
3719 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3722 if (!LaneSelOp.
isReg())
3725 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3728bool AMDGPUAsmParser::validateConstantBusLimitations(
3730 const unsigned Opcode = Inst.
getOpcode();
3731 const MCInstrDesc &
Desc = MII.
get(Opcode);
3732 MCRegister LastSGPR;
3733 unsigned ConstantBusUseCount = 0;
3734 unsigned NumLiterals = 0;
3735 unsigned LiteralSize;
3751 SmallDenseSet<MCRegister> SGPRsUsed;
3752 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3754 SGPRsUsed.
insert(SGPRUsed);
3755 ++ConstantBusUseCount;
3760 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3762 for (
int OpIdx : OpIndices) {
3766 const MCOperand &MO = Inst.
getOperand(OpIdx);
3767 if (usesConstantBus(Inst, OpIdx)) {
3776 if (SGPRsUsed.
insert(LastSGPR).second) {
3777 ++ConstantBusUseCount;
3797 if (NumLiterals == 0) {
3800 }
else if (LiteralSize !=
Size) {
3806 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3808 "invalid operand (violates constant bus restrictions)");
3815std::optional<unsigned>
3816AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3818 const unsigned Opcode = Inst.
getOpcode();
3824 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3825 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3834 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1170 ||
3835 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3836 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3837 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx13 ||
3838 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250 ||
3839 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx13;
3843 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3844 int I = getNamedOperandIdx(Opcode, OpName);
3848 int64_t
Imm =
Op.getImm();
3854 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3855 OpName::vsrc2Y, OpName::imm}) {
3856 int I = getNamedOperandIdx(Opcode, OpName);
3866 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3867 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3869 return InvalidCompOprIdx;
3872bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
3879 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand :
Operands) {
3880 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
3881 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
3883 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
3887 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
3888 if (!InvalidCompOprIdx.has_value())
3891 auto CompOprIdx = *InvalidCompOprIdx;
3894 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3895 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3898 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
3899 if (CompOprIdx == VOPD::Component::DST) {
3901 Error(Loc,
"dst registers must be distinct");
3903 Error(Loc,
"one dst register must be even and the other odd");
3905 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3906 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
3907 " operands must use different VGPR banks");
3915bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
3917 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
3918 if (!InvalidCompOprIdx.has_value())
3922 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
3923 if (InvalidCompOprIdx.has_value()) {
3928 if (*InvalidCompOprIdx == VOPD::Component::DST)
3941bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
3942 const unsigned Opcode = Inst.
getOpcode();
3957 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
3958 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
3959 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
3960 int I = getNamedOperandIdx(Opcode, OpName);
3967 return !tryVOPD3(Inst);
3972bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
3977 return tryVOPD(Inst);
3978 return tryVOPD3(Inst);
3981bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
3986 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
3994bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc) {
4002 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4003 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4004 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4009 if ((DMaskIdx == -1 || TFEIdx == -1) &&
4010 hasBVHRayTracingInsts())
4013 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4014 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4019 bool IsPackedD16 =
false;
4022 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4023 IsPackedD16 = D16Idx >= 0;
4025 DataSize = (DataSize + 1) / 2;
4028 if ((VDataSize / 4) == DataSize + TFESize)
4033 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4035 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4037 Error(IDLoc, Twine(
"image data size does not match ") + Modifiers);
4041bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4050 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4052 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4053 AMDGPU::OpName RSrcOpName =
4055 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4056 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4057 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4061 assert(SrsrcIdx > VAddr0Idx);
4064 if (BaseOpcode->
BVH) {
4065 if (IsA16 == BaseOpcode->
A16)
4067 Error(IDLoc,
"image address size does not match a16");
4073 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4074 unsigned ActualAddrSize =
4075 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4077 unsigned ExpectedAddrSize =
4081 if (hasPartialNSAEncoding() &&
4083 int VAddrLastIdx = SrsrcIdx - 1;
4084 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4086 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4089 if (ExpectedAddrSize > 12)
4090 ExpectedAddrSize = 16;
4095 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4099 if (ActualAddrSize == ExpectedAddrSize)
4102 Error(IDLoc,
"image address size does not match dim and a16");
4106bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4113 if (!
Desc.mayLoad() || !
Desc.mayStore())
4116 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4123 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4126bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4133 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4141 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4144bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4158 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4159 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4166bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4173 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4176 if (!BaseOpcode->
MSAA)
4179 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4185 return DimInfo->
MSAA;
4190 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4191 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4192 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4202bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4210 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4221 Error(getOperandLoc(
Operands, Src0Idx),
"source operand must be a VGPR");
4225bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4230 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4233 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4244 "source operand must be either a VGPR or an inline constant");
4251bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4256 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4259 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4263 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4265 "inline constants are not allowed for this operand");
4272bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4280 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4281 if (BlgpIdx != -1) {
4282 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4283 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4293 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4295 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4300 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4302 "wrong register tuple size for blgp value " + Twine(BLGP));
4310 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4320 if (Src2Reg == DstReg)
4325 .getSizeInBits() <= 128)
4328 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4330 "source 2 operand must not partially overlap with dst");
4337bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4341 case V_DIV_SCALE_F32_gfx6_gfx7:
4342 case V_DIV_SCALE_F32_vi:
4343 case V_DIV_SCALE_F32_gfx10:
4344 case V_DIV_SCALE_F64_gfx6_gfx7:
4345 case V_DIV_SCALE_F64_vi:
4346 case V_DIV_SCALE_F64_gfx10:
4353 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src2_modifiers,
4354 AMDGPU::OpName::src2_modifiers}) {
4365bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4372 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4381bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4387 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4394 case AMDGPU::V_SUBREV_F32_e32:
4395 case AMDGPU::V_SUBREV_F32_e64:
4396 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4397 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4398 case AMDGPU::V_SUBREV_F32_e32_vi:
4399 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4400 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4401 case AMDGPU::V_SUBREV_F32_e64_vi:
4403 case AMDGPU::V_SUBREV_CO_U32_e32:
4404 case AMDGPU::V_SUBREV_CO_U32_e64:
4405 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4406 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4408 case AMDGPU::V_SUBBREV_U32_e32:
4409 case AMDGPU::V_SUBBREV_U32_e64:
4410 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4411 case AMDGPU::V_SUBBREV_U32_e32_vi:
4412 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4413 case AMDGPU::V_SUBBREV_U32_e64_vi:
4415 case AMDGPU::V_SUBREV_U32_e32:
4416 case AMDGPU::V_SUBREV_U32_e64:
4417 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4418 case AMDGPU::V_SUBREV_U32_e32_vi:
4419 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4420 case AMDGPU::V_SUBREV_U32_e64_vi:
4422 case AMDGPU::V_SUBREV_F16_e32:
4423 case AMDGPU::V_SUBREV_F16_e64:
4424 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4425 case AMDGPU::V_SUBREV_F16_e32_vi:
4426 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4427 case AMDGPU::V_SUBREV_F16_e64_vi:
4429 case AMDGPU::V_SUBREV_U16_e32:
4430 case AMDGPU::V_SUBREV_U16_e64:
4431 case AMDGPU::V_SUBREV_U16_e32_vi:
4432 case AMDGPU::V_SUBREV_U16_e64_vi:
4434 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4435 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4436 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4438 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4439 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4441 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4442 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4444 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4445 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4447 case AMDGPU::V_LSHRREV_B32_e32:
4448 case AMDGPU::V_LSHRREV_B32_e64:
4449 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4450 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4451 case AMDGPU::V_LSHRREV_B32_e32_vi:
4452 case AMDGPU::V_LSHRREV_B32_e64_vi:
4453 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4454 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4456 case AMDGPU::V_ASHRREV_I32_e32:
4457 case AMDGPU::V_ASHRREV_I32_e64:
4458 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4459 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4460 case AMDGPU::V_ASHRREV_I32_e32_vi:
4461 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4462 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4463 case AMDGPU::V_ASHRREV_I32_e64_vi:
4465 case AMDGPU::V_LSHLREV_B32_e32:
4466 case AMDGPU::V_LSHLREV_B32_e64:
4467 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4468 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4469 case AMDGPU::V_LSHLREV_B32_e32_vi:
4470 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4471 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4472 case AMDGPU::V_LSHLREV_B32_e64_vi:
4474 case AMDGPU::V_LSHLREV_B16_e32:
4475 case AMDGPU::V_LSHLREV_B16_e64:
4476 case AMDGPU::V_LSHLREV_B16_e32_vi:
4477 case AMDGPU::V_LSHLREV_B16_e64_vi:
4478 case AMDGPU::V_LSHLREV_B16_gfx10:
4480 case AMDGPU::V_LSHRREV_B16_e32:
4481 case AMDGPU::V_LSHRREV_B16_e64:
4482 case AMDGPU::V_LSHRREV_B16_e32_vi:
4483 case AMDGPU::V_LSHRREV_B16_e64_vi:
4484 case AMDGPU::V_LSHRREV_B16_gfx10:
4486 case AMDGPU::V_ASHRREV_I16_e32:
4487 case AMDGPU::V_ASHRREV_I16_e64:
4488 case AMDGPU::V_ASHRREV_I16_e32_vi:
4489 case AMDGPU::V_ASHRREV_I16_e64_vi:
4490 case AMDGPU::V_ASHRREV_I16_gfx10:
4492 case AMDGPU::V_LSHLREV_B64_e64:
4493 case AMDGPU::V_LSHLREV_B64_gfx10:
4494 case AMDGPU::V_LSHLREV_B64_vi:
4496 case AMDGPU::V_LSHRREV_B64_e64:
4497 case AMDGPU::V_LSHRREV_B64_gfx10:
4498 case AMDGPU::V_LSHRREV_B64_vi:
4500 case AMDGPU::V_ASHRREV_I64_e64:
4501 case AMDGPU::V_ASHRREV_I64_gfx10:
4502 case AMDGPU::V_ASHRREV_I64_vi:
4504 case AMDGPU::V_PK_LSHLREV_B16:
4505 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4506 case AMDGPU::V_PK_LSHLREV_B16_vi:
4508 case AMDGPU::V_PK_LSHRREV_B16:
4509 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4510 case AMDGPU::V_PK_LSHRREV_B16_vi:
4511 case AMDGPU::V_PK_ASHRREV_I16:
4512 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4513 case AMDGPU::V_PK_ASHRREV_I16_vi:
4520bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4522 const unsigned Opcode = Inst.
getOpcode();
4531 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4532 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4536 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4540 "lds_direct is not supported on this GPU");
4546 "lds_direct cannot be used with this instruction");
4550 if (SrcName != OpName::src0) {
4552 "lds_direct may be used as src0 only");
4562 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4563 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4564 if (
Op.isFlatOffset())
4565 return Op.getStartLoc();
4570bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4573 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4578 return validateFlatOffset(Inst,
Operands);
4581 return validateSMEMOffset(Inst,
Operands);
4586 const unsigned OffsetSize = 24;
4587 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4589 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4590 "-bit unsigned offset for buffer ops");
4594 const unsigned OffsetSize = 16;
4595 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4597 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4604bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4610 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4614 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4616 "flat offset modifier is not supported on this GPU");
4623 bool AllowNegative =
4625 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4627 Twine(
"expected a ") +
4628 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4629 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4638 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4639 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4640 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4641 return Op.getStartLoc();
4646bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4655 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4671 ?
"expected a 23-bit unsigned offset for buffer ops"
4672 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4673 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4674 :
"expected a 21-bit signed offset");
4680bool AMDGPUAsmParser::validateSMEMSData(
const MCInst &Inst,
4686 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::sdata);
4691 Error(getOperandLoc(
Operands, OpNum),
"expected a 5-bit unsigned immediate");
4700bool AMDGPUAsmParser::validateBF16InlineConst(
const MCInst &Inst,
4702 if (!getFeatureBits()[AMDGPU::FeatureBF16InlineConstFromUpperFP32])
4717 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4721 const MCOperandInfo &Src0Info =
Desc.operands()[Src0Idx];
4726 if (!
Src0.isImm() ||
4728 hasInv2PiInlineImm()))
4733 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
4734 if (ModsIdx != -1 &&
4740 "bf16 inline constant is read from the high half of the fp32 inline "
4741 "constant on this GPU; use the e64 encoding with op_sel:[1,0]");
4745bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4748 const MCInstrDesc &
Desc = MII.
get(Opcode);
4752 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4753 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4755 const int OpIndices[] = {Src0Idx, Src1Idx};
4757 unsigned NumExprs = 0;
4758 unsigned NumLiterals = 0;
4761 for (
int OpIdx : OpIndices) {
4765 const MCOperand &MO = Inst.
getOperand(OpIdx);
4769 std::optional<int64_t>
Imm;
4772 }
else if (MO.
isExpr()) {
4781 if (!
Imm.has_value()) {
4783 }
else if (!isInlineConstant(Inst, OpIdx)) {
4787 if (NumLiterals == 0 || LiteralValue !=
Value) {
4795 if (NumLiterals + NumExprs <= 1)
4799 "only one unique literal operand is allowed");
4803bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4806 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4814 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4815 if (OpSelIdx != -1) {
4819 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4820 if (OpSelHiIdx != -1) {
4829 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4836 if (getFeatureBits()[AMDGPU::FeatureGFX950Insts] &&
4837 (
Opc == AMDGPU::V_PK_ADD_F32_vi ||
Opc == AMDGPU::V_PK_MUL_F32_vi ||
4838 Opc == AMDGPU::V_PK_FMA_F32_vi)) {
4839 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4843 if (
Opc == AMDGPU::V_PK_FMA_F32_vi &&
4844 (((OpSel >> 1) & 1) || ((OpSel >> 2) & 1)))
4847 else if ((OpSel & 3) == 2)
4855 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4856 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4857 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4858 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4867 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4869 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4879 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4880 if (Src2Idx != -1) {
4891bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4892 if (!hasTrue16Insts())
4894 const MCRegisterInfo *
MRI = getMRI();
4896 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4902 if (OpSelOpValue == 0)
4904 unsigned OpCount = 0;
4905 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4906 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4907 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4914 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4915 if (OpSelOpIsHi != VGPRSuffixIsHi)
4924bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4925 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4937 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
4948 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4949 AMDGPU::OpName::src1_modifiers,
4950 AMDGPU::OpName::src2_modifiers};
4952 for (
unsigned i = 0; i < 3; ++i) {
4962bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4965 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
4966 if (DppCtrlIdx >= 0) {
4970 getSTI().
hasFeature(AMDGPU::FeatureDPALU_DPP) &&
4974 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl,
Operands);
4975 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
4976 :
"DP ALU dpp only supports row_newbcast");
4981 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
4982 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4985 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4991 "invalid operand for instruction");
4996 "src1 immediate operand invalid for instruction");
5006bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5007 return (
Reg == AMDGPU::VCC && isWave64()) ||
5008 (
Reg == AMDGPU::VCC_LO && isWave32());
5012bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5015 const MCInstrDesc &
Desc = MII.
get(Opcode);
5016 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5023 std::optional<unsigned> LiteralOpIdx;
5026 for (
int OpIdx : OpIndices) {
5030 const MCOperand &MO = Inst.
getOperand(OpIdx);
5036 std::optional<int64_t>
Imm;
5042 bool IsAnotherLiteral =
false;
5043 bool IsForcedLit = findMCOperand(
Operands, OpIdx).isForcedLit();
5044 bool IsForcedLit64 = findMCOperand(
Operands, OpIdx).isForcedLit64();
5045 if (!
Imm.has_value()) {
5047 IsAnotherLiteral =
true;
5048 }
else if (IsForcedLit || IsForcedLit64 || !isInlineConstant(Inst, OpIdx)) {
5053 HasMandatoryLiteral);
5065 (IsForcedLit64 && !HasMandatoryLiteral)) &&
5066 (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5068 "invalid operand for instruction");
5073 if (!IsForcedFP64 && (IsForcedLit64 || !IsValid32Op) &&
5074 OpIdx != getNamedOperandIdx(Opcode, OpName::src0)) {
5076 "invalid operand for instruction");
5081 if (IsValid32Op && !IsForcedFP64 && !IsForcedLit64) {
5082 Value =
static_cast<uint32_t
>(
5090 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5091 !getFeatureBits()[FeatureVOP3Literal]) {
5093 "literal operands are not supported");
5097 if (LiteralOpIdx && IsAnotherLiteral) {
5099 getOperandLoc(
Operands, *LiteralOpIdx)),
5100 "only one unique literal operand is allowed");
5104 if (IsAnotherLiteral)
5105 LiteralOpIdx = OpIdx;
5114 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), Name);
5128bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5134 ? AMDGPU::OpName::data0
5135 : AMDGPU::OpName::vdata;
5137 const MCRegisterInfo *
MRI = getMRI();
5143 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5147 auto FB = getFeatureBits();
5148 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5149 if (DataAreg < 0 || DstAreg < 0)
5151 return DstAreg == DataAreg;
5154 return DstAreg < 1 && DataAreg < 1;
5157bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5158 auto FB = getFeatureBits();
5159 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5163 const MCRegisterInfo *
MRI = getMRI();
5166 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5169 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5173 case AMDGPU::DS_LOAD_TR6_B96:
5174 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5178 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5179 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5183 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5184 if (VAddrIdx != -1) {
5186 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5187 if ((
Sub - AMDGPU::VGPR0) & 1)
5192 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5193 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5198 const MCRegisterClass &VGPR32 =
MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5199 const MCRegisterClass &AGPR32 =
MRI->
getRegClass(AMDGPU::AGPR_32RegClassID);
5205 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5219 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
5220 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
5222 return Op.getStartLoc();
5227bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5230 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5233 SMLoc BLGPLoc = getBLGPLoc(
Operands);
5236 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5237 auto FB = getFeatureBits();
5238 bool UsesNeg =
false;
5239 if (FB[AMDGPU::FeatureGFX940Insts]) {
5241 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5242 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5243 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5244 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5249 if (IsNeg == UsesNeg)
5252 Error(BLGPLoc, UsesNeg ?
"invalid modifier: blgp is not supported"
5253 :
"invalid modifier: neg is not supported");
5258bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5264 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5265 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5266 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5267 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5270 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5273 if (
Reg == AMDGPU::SGPR_NULL)
5276 Error(getOperandLoc(
Operands, Src0Idx),
"src0 must be null");
5280bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5285 return validateGWS(Inst,
Operands);
5290 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5295 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS,
Operands);
5296 Error(S,
"gds modifier is not supported on this GPU");
5304bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5306 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5310 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5311 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5314 const MCRegisterInfo *
MRI = getMRI();
5315 const MCRegisterClass &VGPR32 =
MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5317 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5320 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5322 Error(getOperandLoc(
Operands, Data0Pos),
"vgpr must be even aligned");
5329bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5333 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::cpol);
5340 if (!hasCacheFillSize()) {
5341 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5344 Error(S,
"Cache fill size is not supported on this GPU");
5345 }
else if (!validateCFSBits(Inst,
Operands)) {
5352 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5355 Error(S,
"scale_offset is not supported on this GPU");
5358 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5361 Error(S,
"nv is not supported on this GPU");
5366 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5369 Error(S,
"scale_offset is not supported for this instruction");
5373 return validateTHAndScopeBits(Inst,
Operands, CPol);
5377 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5378 Error(S,
"cache policy is not supported for SMRD instructions");
5382 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5389 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5393 "scc modifier is not supported for this instruction on this GPU");
5404 :
"instruction must use glc");
5409 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5412 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5414 :
"instruction must not use glc");
5422bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5424 const unsigned CPol) {
5429 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5436 return PrintError(
"th:TH_ATOMIC_RETURN requires a destination operand");
5441 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5449 return PrintError(
"invalid th value for SMEM instruction");
5456 return PrintError(
"scope and th combination is not valid");
5462 return PrintError(
"invalid th value for atomic instructions");
5465 return PrintError(
"invalid th value for store instructions");
5468 return PrintError(
"invalid th value for load instructions");
5474bool AMDGPUAsmParser::validateCFSBits(
const MCInst &Inst,
5476 const unsigned Opcode = Inst.
getOpcode();
5477 const MCInstrDesc &
Desc = MII.
get(Opcode);
5480 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5488 return PrintError(
"Cache fill size is only supported for VC operations");
5491bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5495 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE,
Operands);
5497 Error(Loc,
"TFE modifier has no meaning for store instructions");
5505bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5511 int AFmtIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
5515 int BFmtIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
5518 auto validateFmt = [&](
unsigned Fmt, AMDGPU::OpName SrcOp) ->
bool {
5519 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5528 "wrong register tuple size for " +
5533 if (!validateFmt(AFmt, AMDGPU::OpName::src0) ||
5534 !validateFmt(BFmt, AMDGPU::OpName::src1))
5538 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
5539 if (AScaleIdx == -1)
5543 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
5547 "invalid matrix and scale format combination");
5554bool AMDGPUAsmParser::validateMonitorSleep(
const MCInst &Inst,
5557 if (
Opc != AMDGPU::S_MONITOR_SLEEP_gfx12 ||
5558 !getSTI().
hasFeature(AMDGPU::FeatureNoSleepForever))
5561 int ImmIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::simm16);
5564 "sleep forever is unsuported on the target");
5571bool AMDGPUAsmParser::validateClusterBarrierIsFirst(
5574 if (
Opc != AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM_gfx12 &&
5575 Opc != AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM_gfx13)
5578 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
5585 "s_barrier_signal_isfirst does not support user_cluster_barrier_id (-3)");
5589bool AMDGPUAsmParser::validateScaleSel(
const MCInst &Inst,
5592 int ScaleSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::scale_sel);
5593 if (ScaleSelIdx == -1)
5597 case AMDGPU::V_CVT_SCALE_PK16_F16_FP6_e64_gfx1250:
5598 case AMDGPU::V_CVT_SCALE_PK16_BF16_FP6_e64_gfx1250:
5599 case AMDGPU::V_CVT_SCALE_PK16_F16_BF6_e64_gfx1250:
5600 case AMDGPU::V_CVT_SCALE_PK16_BF16_BF6_e64_gfx1250:
5601 case AMDGPU::V_CVT_SCALE_PK16_F32_FP6_e64_gfx1250:
5602 case AMDGPU::V_CVT_SCALE_PK16_F32_BF6_e64_gfx1250:
5603 case AMDGPU::V_CVT_SCALE_PK8_F16_FP4_e64_gfx1250:
5604 case AMDGPU::V_CVT_SCALE_PK8_BF16_FP4_e64_gfx1250:
5605 case AMDGPU::V_CVT_SCALE_PK8_F32_FP4_e64_gfx1250:
5608 case AMDGPU::V_CVT_SCALE_PK8_F16_FP8_e64_gfx1250:
5609 case AMDGPU::V_CVT_SCALE_PK8_BF16_FP8_e64_gfx1250:
5610 case AMDGPU::V_CVT_SCALE_PK8_F16_BF8_e64_gfx1250:
5611 case AMDGPU::V_CVT_SCALE_PK8_BF16_BF8_e64_gfx1250:
5612 case AMDGPU::V_CVT_SCALE_PK8_F32_FP8_e64_gfx1250:
5613 case AMDGPU::V_CVT_SCALE_PK8_F32_BF8_e64_gfx1250:
5620 if (getSTI().
hasFeature(AMDGPU::FeatureBlock16ConversionScaleInsts))
5624 if (ScaleSel < MaxSel)
5628 "scale_sel maximum supported value is " + Twine(MaxSel - 1));
5632bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5634 if (!validateLdsDirect(Inst,
Operands))
5636 if (!validateTrue16OpSel(Inst)) {
5638 "op_sel operand conflicts with 16-bit operand suffix");
5641 if (!validateSOPLiteral(Inst,
Operands))
5643 if (!validateVOPLiteral(Inst,
Operands)) {
5646 if (!validateConstantBusLimitations(Inst,
Operands)) {
5649 if (!validateVOPD(Inst,
Operands)) {
5652 if (!validateIntClampSupported(Inst)) {
5654 "integer clamping is not supported on this GPU");
5657 if (!validateOpSel(Inst)) {
5659 "invalid op_sel operand");
5662 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5664 "invalid neg_lo operand");
5667 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5669 "invalid neg_hi operand");
5672 if (!validateDPP(Inst,
Operands)) {
5676 if (!validateMIMGD16(Inst)) {
5678 "d16 modifier is not supported on this GPU");
5681 if (!validateMIMGDim(Inst,
Operands)) {
5682 Error(IDLoc,
"missing dim operand");
5685 if (!validateTensorR128(Inst)) {
5687 "instruction must set modifier r128=0");
5690 if (!validateMIMGMSAA(Inst)) {
5692 "invalid dim; must be MSAA type");
5695 if (!validateMIMGDataSize(Inst, IDLoc)) {
5698 if (!validateMIMGAddrSize(Inst, IDLoc))
5700 if (!validateMIMGAtomicDMask(Inst)) {
5702 "invalid atomic image dmask");
5705 if (!validateMIMGGatherDMask(Inst)) {
5707 "invalid image_gather dmask: only one bit must be set");
5710 if (!validateMovrels(Inst,
Operands)) {
5713 if (!validateOffset(Inst,
Operands)) {
5716 if (!validateSMEMSData(Inst,
Operands))
5718 if (!validateBF16InlineConst(Inst,
Operands)) {
5721 if (!validateMAIAccWrite(Inst,
Operands)) {
5724 if (!validateMAISrc2(Inst,
Operands)) {
5727 if (!validateMFMA(Inst,
Operands)) {
5730 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5734 if (!validateAGPRLdSt(Inst)) {
5737 getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5738 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5739 :
"invalid register class: agpr loads and stores not supported on "
5743 if (!validateVGPRAlign(Inst)) {
5744 Error(IDLoc,
"invalid register class: vgpr tuples must be 64 bit aligned");
5751 if (!validateBLGP(Inst,
Operands)) {
5755 if (!validateDivScale(Inst)) {
5756 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5759 if (!validateWaitCnt(Inst,
Operands)) {
5762 if (!validateTFE(Inst,
Operands)) {
5765 if (!validateWMMA(Inst,
Operands)) {
5768 if (!validateMonitorSleep(Inst,
Operands)) {
5771 if (!validateClusterBarrierIsFirst(Inst,
Operands)) {
5774 if (!validateScaleSel(Inst,
Operands)) {
5783 unsigned VariantID = 0);
5787 unsigned VariantID);
5789bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5794bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5795 const FeatureBitset &FBS,
5796 ArrayRef<unsigned> Variants) {
5797 for (
auto Variant : Variants) {
5805bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5807 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5810 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5815 getParser().clearPendingErrors();
5819 StringRef VariantName = getMatchedVariantName();
5820 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5821 return Error(IDLoc, Twine(VariantName,
5822 " variant of this instruction is not supported"));
5826 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5827 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5829 FeatureBitset FeaturesWS32 = getFeatureBits();
5830 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5831 .
flip(AMDGPU::FeatureWavefrontSize32);
5832 FeatureBitset AvailableFeaturesWS32 =
5833 ComputeAvailableFeatures(FeaturesWS32);
5835 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5836 return Error(IDLoc,
"instruction requires wavesize=32");
5840 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5841 return Error(IDLoc,
"instruction not supported on this GPU (" +
5842 getSTI().
getCPU() +
")" +
": " + Mnemo);
5847 return Error(IDLoc,
"invalid instruction" + Suggestion);
5853 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5854 if (
Op.isToken() && InvalidOprIdx > 1) {
5855 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5856 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5861bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5865 bool MatchingInlineAsm) {
5868 unsigned Result = Match_Success;
5873 auto atLeastAsSpecific = [](
unsigned New,
unsigned Cur) {
5874 auto rank = [](
unsigned M) {
5875 return M == Match_MnemonicFail ? 1
5876 :
M == Match_InvalidOperand ? 2
5877 :
M == Match_MissingFeature ? 3
5880 return rank(New) >= rank(Cur);
5883 for (
auto Variant : getMatchedVariants()) {
5886 MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm, Variant);
5887 if (R == Match_Success || atLeastAsSpecific(R, Result)) {
5891 if (R == Match_Success)
5895 if (Result == Match_Success) {
5896 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5899 emitTargetDirective();
5900 Out.emitInstruction(Inst, getSTI());
5907 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5914 case Match_MissingFeature:
5918 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5920 case Match_InvalidOperand: {
5921 SMLoc ErrorLoc = IDLoc;
5922 if (ErrorInfo != ~0ULL) {
5923 if (ErrorInfo >=
Operands.size()) {
5924 return Error(IDLoc,
"too few operands for instruction");
5926 AMDGPUOperand &ErrorOp = (AMDGPUOperand &)*
Operands[ErrorInfo];
5927 ErrorLoc = ErrorOp.getStartLoc();
5928 if (ErrorLoc == SMLoc())
5932 return Error(ErrorLoc,
"invalid VOPDY instruction");
5934 return Error(ErrorLoc,
"invalid operand for instruction");
5937 case Match_MnemonicFail:
5943bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5948 if (getParser().parseAbsoluteExpression(Tmp)) {
5951 Ret =
static_cast<uint32_t
>(Tmp);
5955bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5956 if (!getSTI().getTargetTriple().isAMDGCN())
5957 return TokError(
"directive only supported for amdgcn architecture");
5959 std::string TargetIDDirective;
5960 SMLoc TargetStart = getTok().getLoc();
5961 if (getParser().parseEscapedString(TargetIDDirective))
5964 std::optional<AMDGPU::TargetID> MaybeParsed =
5967 return getParser().Error(TargetStart,
5968 "malformed target id '" + TargetIDDirective +
"'");
5971 const Triple &
TT = getSTI().getTargetTriple();
5977 return getParser().Error(
5978 TargetStart,
"target id '" + TargetIDDirective +
5979 "' specifies a processor that is not valid for "
5981 TT.getArchName() +
"'");
5984 const std::optional<AMDGPU::TargetID> &CurrentTargetID =
5985 getTargetStreamer().getTargetID();
5988 const Triple &STITriple = getSTI().getTargetTriple();
5989 if (!DirectiveTriple.isCompatibleWith(STITriple)) {
5990 return getParser().Error(
5991 TargetStart,
".amdgcn_target " + Twine(ParsedTargetID.
toString()) +
5992 " is incompatible with " +
5993 Twine(CurrentTargetID->toString()));
5997 StringRef DirectiveProcessor =
6000 if (DirectiveISA != ISA) {
6001 return getParser().Error(TargetStart,
6002 ".amdgcn_target directive processor " +
6003 Twine(DirectiveProcessor) +
6004 " does not match the specified processor " +
6005 Twine(getSTI().
getCPU()));
6011 CurrentTargetID->getXnackSetting())) {
6013 ".amdgcn_target directive has conflicting xnack settings");
6017 CurrentTargetID->getSramEccSetting())) {
6019 ".amdgcn_target directive has conflicting sramecc settings");
6025 getTargetStreamer().getTargetID()->setXnackSetting(
6027 getTargetStreamer().getTargetID()->setSramEccSetting(
6033bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
6037bool AMDGPUAsmParser::calculateGPRBlocks(
6038 const FeatureBitset &Features,
const MCExpr *VCCUsed,
6039 const MCExpr *FlatScrUsed,
bool XNACKUsed,
6040 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
6041 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
6042 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
6047 const MCExpr *
NumSGPRs = NextFreeSGPR;
6048 int64_t EvaluatedSGPRs;
6050 if (
ISA.Major >= 10)
6055 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
ISA.Major >= 8 &&
6056 !Features.
test(FeatureSGPRInitBug) &&
6057 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
6058 return OutOfRangeError(SGPRRange);
6060 const MCExpr *ExtraSGPRs =
6064 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
6065 (
ISA.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
6066 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
6067 return OutOfRangeError(SGPRRange);
6069 if (Features.
test(FeatureSGPRInitBug))
6076 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
6077 unsigned Granule) ->
const MCExpr * {
6081 const MCExpr *AlignToGPR =
6083 const MCExpr *DivGPR =
6089 VGPRBlocks = GetNumGPRBlocks(
6098bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
6099 if (!getSTI().getTargetTriple().isAMDGCN())
6100 return TokError(
"directive only supported for amdgcn architecture");
6103 return TokError(
"directive only supported for amdhsa OS");
6105 StringRef KernelName;
6106 if (getParser().parseIdentifier(KernelName))
6113 AMDGPU::MCKernelDescriptor KD =
6123 const MCExpr *NextFreeVGPR = ZeroExpr;
6125 const MCExpr *NamedBarCnt = ZeroExpr;
6130 const MCExpr *NextFreeSGPR = ZeroExpr;
6133 unsigned ImpliedUserSGPRCount = 0;
6137 std::optional<unsigned> ExplicitUserSGPRCount;
6138 const MCExpr *ReserveVCC = OneExpr;
6139 const MCExpr *ReserveFlatScr = OneExpr;
6140 std::optional<bool> EnableWavefrontSize32;
6147 SMRange IDRange = getTok().getLocRange();
6148 if (!parseId(ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6151 if (ID ==
".end_amdhsa_kernel")
6154 if (!Seen.
insert(ID).second)
6155 return TokError(
".amdhsa_ directives cannot be repeated");
6157 SMLoc ValStart = getLoc();
6158 const MCExpr *ExprVal;
6159 if (getParser().parseExpression(ExprVal))
6161 SMLoc ValEnd = getLoc();
6162 SMRange ValRange = SMRange(ValStart, ValEnd);
6166 bool EvaluatableExpr;
6167 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6169 return OutOfRangeError(ValRange);
6173#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6174 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6175 return OutOfRangeError(RANGE); \
6176 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6181#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6183 return Error(IDRange.Start, "directive should have resolvable expression", \
6186 if (ID ==
".amdhsa_group_segment_fixed_size") {
6189 return OutOfRangeError(ValRange);
6191 }
else if (ID ==
".amdhsa_private_segment_fixed_size") {
6194 return OutOfRangeError(ValRange);
6196 }
else if (ID ==
".amdhsa_kernarg_size") {
6198 return OutOfRangeError(ValRange);
6200 }
else if (ID ==
".amdhsa_user_sgpr_count") {
6202 ExplicitUserSGPRCount = Val;
6203 }
else if (ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6207 "directive is not supported with architected flat scratch",
6210 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6213 ImpliedUserSGPRCount += 4;
6214 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6217 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6220 return OutOfRangeError(ValRange);
6224 ImpliedUserSGPRCount += Val;
6225 PreloadLength = Val;
6227 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6230 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6233 return OutOfRangeError(ValRange);
6237 PreloadOffset = Val;
6238 }
else if (ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6241 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6244 ImpliedUserSGPRCount += 2;
6245 }
else if (ID ==
".amdhsa_user_sgpr_queue_ptr") {
6248 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6251 ImpliedUserSGPRCount += 2;
6252 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6255 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6258 ImpliedUserSGPRCount += 2;
6259 }
else if (ID ==
".amdhsa_user_sgpr_dispatch_id") {
6262 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6265 ImpliedUserSGPRCount += 2;
6266 }
else if (ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6269 "directive is not supported with architected flat scratch",
6273 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6276 ImpliedUserSGPRCount += 2;
6277 }
else if (ID ==
".amdhsa_user_sgpr_private_segment_size") {
6280 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6283 ImpliedUserSGPRCount += 1;
6284 }
else if (ID ==
".amdhsa_wavefront_size32") {
6287 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6288 EnableWavefrontSize32 = Val;
6290 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6292 }
else if (ID ==
".amdhsa_uses_dynamic_stack") {
6294 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6296 }
else if (ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6299 "directive is not supported with architected flat scratch",
6302 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6304 }
else if (ID ==
".amdhsa_enable_private_segment") {
6308 "directive is not supported without architected flat scratch",
6311 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6313 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6315 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6317 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6319 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6321 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6323 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6325 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_info") {
6327 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6329 }
else if (ID ==
".amdhsa_system_vgpr_workitem_id") {
6331 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6333 }
else if (ID ==
".amdhsa_next_free_vgpr") {
6334 VGPRRange = ValRange;
6335 NextFreeVGPR = ExprVal;
6336 }
else if (ID ==
".amdhsa_next_free_sgpr") {
6337 SGPRRange = ValRange;
6338 NextFreeSGPR = ExprVal;
6339 }
else if (ID ==
".amdhsa_accum_offset") {
6341 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6342 AccumOffset = ExprVal;
6343 }
else if (ID ==
".amdhsa_named_barrier_count") {
6345 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6346 NamedBarCnt = ExprVal;
6347 }
else if (ID ==
".amdhsa_reserve_vcc") {
6349 return OutOfRangeError(ValRange);
6350 ReserveVCC = ExprVal;
6351 }
else if (ID ==
".amdhsa_reserve_flat_scratch") {
6353 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6356 "directive is not supported with architected flat scratch",
6359 return OutOfRangeError(ValRange);
6360 ReserveFlatScr = ExprVal;
6361 }
else if (ID ==
".amdhsa_reserve_xnack_mask") {
6363 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6365 return OutOfRangeError(ValRange);
6366 bool XnackOn = getTargetStreamer().getTargetID()->isXnackOnOrAny();
6367 if (Val != XnackOn) {
6368 return getParser().Error(
6370 ".amdhsa_reserve_xnack_mask does not match target id", IDRange);
6372 }
else if (ID ==
".amdhsa_float_round_mode_32") {
6374 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6376 }
else if (ID ==
".amdhsa_float_round_mode_16_64") {
6378 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6380 }
else if (ID ==
".amdhsa_float_denorm_mode_32") {
6382 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6384 }
else if (ID ==
".amdhsa_float_denorm_mode_16_64") {
6386 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6388 }
else if (ID ==
".amdhsa_dx10_clamp") {
6389 if (!getSTI().
hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6390 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6393 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6395 }
else if (ID ==
".amdhsa_ieee_mode") {
6396 if (!getSTI().
hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6397 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6400 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6402 }
else if (ID ==
".amdhsa_fp16_overflow") {
6404 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6406 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6408 }
else if (ID ==
".amdhsa_tg_split") {
6410 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6413 }
else if (ID ==
".amdhsa_workgroup_processor_mode") {
6416 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6418 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6420 }
else if (ID ==
".amdhsa_memory_ordered") {
6422 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6424 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6426 }
else if (ID ==
".amdhsa_forward_progress") {
6428 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6430 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6432 }
else if (ID ==
".amdhsa_shared_vgpr_count") {
6434 if (
ISA.Major < 10 ||
ISA.Major >= 12)
6435 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6437 SharedVGPRCount = Val;
6439 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6441 }
else if (ID ==
".amdhsa_inst_pref_size") {
6443 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6444 if (
ISA.Major == 11) {
6446 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6450 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6453 }
else if (ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6456 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6458 }
else if (ID ==
".amdhsa_exception_fp_denorm_src") {
6460 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6462 }
else if (ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6465 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6467 }
else if (ID ==
".amdhsa_exception_fp_ieee_overflow") {
6469 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6471 }
else if (ID ==
".amdhsa_exception_fp_ieee_underflow") {
6473 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6475 }
else if (ID ==
".amdhsa_exception_fp_ieee_inexact") {
6477 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6479 }
else if (ID ==
".amdhsa_exception_int_div_zero") {
6481 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6483 }
else if (ID ==
".amdhsa_round_robin_scheduling") {
6485 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6487 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6490 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6493#undef PARSE_BITS_ENTRY
6496 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6497 return TokError(
".amdhsa_next_free_vgpr directive is required");
6499 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6500 return TokError(
".amdhsa_next_free_sgpr directive is required");
6502 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6504 return TokError(
"too many user SGPRs enabled, found " +
6505 Twine(UserSGPRCount) +
", but only " +
6511 if (PreloadLength) {
6517 const MCExpr *VGPRBlocks;
6518 const MCExpr *SGPRBlocks;
6519 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6520 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6521 EnableWavefrontSize32, NextFreeVGPR, VGPRRange,
6522 NextFreeSGPR, SGPRRange, VGPRBlocks, SGPRBlocks))
6525 int64_t EvaluatedVGPRBlocks;
6526 bool VGPRBlocksEvaluatable =
6527 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6528 if (VGPRBlocksEvaluatable &&
6530 static_cast<uint64_t>(EvaluatedVGPRBlocks))) {
6531 return OutOfRangeError(VGPRRange);
6535 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6536 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6538 int64_t EvaluatedSGPRBlocks;
6539 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6541 static_cast<uint64_t>(EvaluatedSGPRBlocks)))
6542 return OutOfRangeError(SGPRRange);
6545 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6546 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6548 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6549 return TokError(
"amdgpu_user_sgpr_count smaller than implied by "
6550 "enabled user SGPRs");
6556 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6557 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6562 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6563 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6568 return TokError(
"Kernarg size should be resolvable");
6570 if (PreloadLength && kernarg_size &&
6571 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6572 return TokError(
"Kernarg preload length + offset is larger than the "
6573 "kernarg segment size");
6576 if (!Seen.
contains(
".amdhsa_accum_offset"))
6577 return TokError(
".amdhsa_accum_offset directive is required");
6578 int64_t EvaluatedAccum;
6579 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6580 uint64_t UEvaluatedAccum = EvaluatedAccum;
6581 if (AccumEvaluatable &&
6582 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6583 return TokError(
"accum_offset should be in range [4..256] in "
6586 int64_t EvaluatedNumVGPR;
6587 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6591 return TokError(
"accum_offset exceeds total VGPR allocation");
6597 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6598 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6604 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6605 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6608 if (
ISA.Major >= 10 &&
ISA.Major < 12) {
6610 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6611 return TokError(
"shared_vgpr_count directive not valid on "
6612 "wavefront size 32");
6615 if (VGPRBlocksEvaluatable &&
6616 (SharedVGPRCount * 2 +
static_cast<uint64_t>(EvaluatedVGPRBlocks) >
6618 return TokError(
"shared_vgpr_count*2 + "
6619 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6624 emitTargetDirective();
6625 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6626 NextFreeVGPR, NextFreeSGPR,
6627 ReserveVCC, ReserveFlatScr);
6631bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6633 if (ParseAsAbsoluteExpression(
Version))
6636 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6637 emitTargetDirective();
6641bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
6642 AMDGPUMCKernelCodeT &
C) {
6645 if (ID ==
"max_scratch_backing_memory_byte_size") {
6646 Parser.eatToEndOfStatement();
6650 SmallString<40> ErrStr;
6651 raw_svector_ostream Err(ErrStr);
6652 if (!
C.ParseKernelCodeT(ID, getParser(), Err)) {
6653 return TokError(Err.
str());
6657 if (ID ==
"enable_wavefront_size32") {
6660 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6662 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6665 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6669 if (ID ==
"wavefront_size") {
6670 if (
C.wavefront_size == 5) {
6672 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6674 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6675 }
else if (
C.wavefront_size == 6) {
6677 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6684bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6685 AMDGPUMCKernelCodeT KernelCode;
6695 if (!parseId(ID,
"expected value identifier or .end_amd_kernel_code_t"))
6698 if (ID ==
".end_amd_kernel_code_t")
6701 if (ParseAMDKernelCodeTValue(ID, KernelCode))
6706 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6711bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6712 StringRef KernelName;
6713 if (!parseId(KernelName,
"expected symbol name"))
6716 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6723bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6724 if (!getSTI().getTargetTriple().isAMDGCN()) {
6725 return Error(getLoc(),
6726 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6730 StringRef TargetIDDirective = getLexer().getTok().getStringContents();
6732 std::optional<AMDGPU::TargetID> MaybeParsed =
6735 return Error(getParser().getTok().getLoc(),
6736 "malformed target id '" + TargetIDDirective +
"'");
6739 const Triple &
TT = getSTI().getTargetTriple();
6745 return Error(getParser().getTok().getLoc(),
6746 "target id '" + TargetIDDirective +
6747 "' specifies a processor that is not valid for subarch '" +
6748 TT.getArchName() +
"'");
6751 const std::optional<AMDGPU::TargetID> &CurrentTargetID =
6752 getTargetStreamer().getTargetID();
6755 const Triple &STITriple = getSTI().getTargetTriple();
6756 if (!DirectiveTriple.isCompatibleWith(STITriple)) {
6757 return Error(getParser().getTok().getLoc(),
6758 ".amd_amdgpu_isa " + Twine(ParsedTargetID.
toString()) +
6759 " is incompatible with " +
6760 Twine(CurrentTargetID->toString()));
6764 StringRef DirectiveProcessor =
6767 if (DirectiveISA != ISA) {
6768 return Error(getParser().getTok().getLoc(),
6769 ".amd_amdgpu_isa directive processor " +
6770 Twine(DirectiveProcessor) +
6771 " does not match the specified processor " +
6772 Twine(getSTI().
getCPU()));
6775 getTargetStreamer().EmitISAVersion();
6781bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6784 std::string HSAMetadataString;
6789 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6790 return Error(getLoc(),
"invalid HSA metadata");
6797bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6798 const char *AssemblerDirectiveEnd,
6799 std::string &CollectString) {
6801 raw_string_ostream CollectStream(CollectString);
6803 getLexer().setSkipSpace(
false);
6805 bool FoundEnd =
false;
6808 CollectStream << getTokenStr();
6812 if (trySkipId(AssemblerDirectiveEnd)) {
6817 CollectStream << Parser.parseStringToEndOfStatement()
6818 <<
getContext().getAsmInfo().getSeparatorString();
6820 Parser.eatToEndOfStatement();
6823 getLexer().setSkipSpace(
true);
6826 return TokError(Twine(
"expected directive ") +
6827 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6834bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6840 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6841 if (!PALMetadata->setFromString(
String))
6842 return Error(getLoc(),
"invalid PAL metadata");
6847bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6850 Twine(
" directive is "
6851 "not available on non-amdpal OSes"))
6855 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6856 PALMetadata->setLegacy();
6859 if (ParseAsAbsoluteExpression(
Key)) {
6860 return TokError(Twine(
"invalid value in ") +
6864 return TokError(Twine(
"expected an even number of values in ") +
6867 if (ParseAsAbsoluteExpression(
Value)) {
6868 return TokError(Twine(
"invalid value in ") +
6871 PALMetadata->setRegister(
Key,
Value);
6880bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6881 if (getParser().checkForValidSection())
6885 SMLoc NameLoc = getLoc();
6886 if (getParser().parseIdentifier(Name))
6887 return TokError(
"expected identifier in directive");
6890 if (getParser().parseComma())
6896 SMLoc SizeLoc = getLoc();
6897 if (getParser().parseAbsoluteExpression(
Size))
6900 return Error(SizeLoc,
"size must be non-negative");
6901 if (
Size > LocalMemorySize)
6902 return Error(SizeLoc,
"size is too large");
6906 SMLoc AlignLoc = getLoc();
6907 if (getParser().parseAbsoluteExpression(Alignment))
6910 return Error(AlignLoc,
"alignment must be a power of two");
6915 if (Alignment >= 1u << 31)
6916 return Error(AlignLoc,
"alignment is too large");
6922 Symbol->redefineIfPossible();
6923 if (!
Symbol->isUndefined())
6924 return Error(NameLoc,
"invalid symbol redefinition");
6926 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6930bool AMDGPUAsmParser::ParseDirectiveAMDGPUInfo() {
6931 if (getParser().checkForValidSection())
6935 if (getParser().parseIdentifier(FuncName))
6936 return TokError(
"expected symbol name after .amdgpu_info");
6939 AMDGPU::InfoSectionData ParsedInfoData;
6940 AMDGPU::FuncInfo FI;
6942 bool HasScalarAttrs =
false;
6949 SMLoc IDLoc = getLoc();
6950 if (!parseId(ID,
"expected directive or .end_amdgpu_info"))
6953 if (ID ==
".end_amdgpu_info")
6961 return Error(IDLoc,
"unknown .amdgpu_info directive '" + ID +
"'");
6963 if (Dir ==
"flags") {
6965 if (getParser().parseAbsoluteExpression(Val))
6968 FI.
UsesVCC = !!(
Flags & AMDGPU::FuncInfoFlags::FUNC_USES_VCC);
6970 !!(
Flags & AMDGPU::FuncInfoFlags::FUNC_USES_FLAT_SCRATCH);
6972 HasScalarAttrs =
true;
6973 }
else if (Dir ==
"num_sgpr") {
6975 if (getParser().parseAbsoluteExpression(Val))
6977 FI.
NumSGPR =
static_cast<uint32_t
>(Val);
6978 HasScalarAttrs =
true;
6979 }
else if (Dir ==
"num_vgpr") {
6981 if (getParser().parseAbsoluteExpression(Val))
6984 HasScalarAttrs =
true;
6985 }
else if (Dir ==
"num_agpr") {
6987 if (getParser().parseAbsoluteExpression(Val))
6990 HasScalarAttrs =
true;
6991 }
else if (Dir ==
"private_segment_size") {
6993 if (getParser().parseAbsoluteExpression(Val))
6996 HasScalarAttrs =
true;
6997 }
else if (Dir ==
"use") {
6999 if (getParser().parseIdentifier(ResName))
7000 return TokError(
"expected resource symbol for .amdgpu_use");
7001 ParsedInfoData.
Uses.push_back(
7002 {FuncSym,
getContext().getOrCreateSymbol(ResName)});
7003 }
else if (Dir ==
"call") {
7005 if (getParser().parseIdentifier(DstName))
7006 return TokError(
"expected callee symbol for .amdgpu_call");
7007 ParsedInfoData.
Calls.push_back(
7008 {FuncSym,
getContext().getOrCreateSymbol(DstName)});
7009 }
else if (Dir ==
"indirect_call") {
7011 if (getParser().parseEscapedString(TypeId))
7012 return TokError(
"expected type ID string for .amdgpu_indirect_call");
7013 ParsedInfoData.
IndirectCalls.push_back({FuncSym, std::move(TypeId)});
7014 }
else if (Dir ==
"typeid") {
7016 if (getParser().parseEscapedString(TypeId))
7017 return TokError(
"expected type ID string for .amdgpu_typeid");
7018 ParsedInfoData.
TypeIds.push_back({FuncSym, std::move(TypeId)});
7020 return Error(IDLoc,
"unknown .amdgpu_info directive '" + ID +
"'");
7025 ParsedInfoData.
Funcs.push_back(std::move(FI));
7027 AMDGPU::InfoSectionData &
Data = InfoData ? *InfoData : InfoData.emplace();
7028 for (AMDGPU::FuncInfo &Func : ParsedInfoData.
Funcs)
7029 Data.Funcs.push_back(std::move(Func));
7030 for (std::pair<MCSymbol *, MCSymbol *> &Use : ParsedInfoData.
Uses)
7031 Data.Uses.push_back(Use);
7032 for (std::pair<MCSymbol *, MCSymbol *> &
Call : ParsedInfoData.
Calls)
7034 for (std::pair<MCSymbol *, std::string> &
IndirectCall :
7037 for (std::pair<MCSymbol *, std::string> &TypeId : ParsedInfoData.
TypeIds)
7038 Data.TypeIds.push_back(std::move(TypeId));
7043void AMDGPUAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
7050void AMDGPUAsmParser::checkKernelPrologues() {
7051 if (getFeatureBits()[AMDGPU::FeatureRequiresInitialUnclausedVmem]) {
7052 static const unsigned Required[] = {S_MOV_B64_gfx12, V_NOP_e32_gfx12,
7053 GLOBAL_PREFETCH_B8_SADDR_gfx1250};
7054 for (
auto [Sym, Loc,
Offset] : OpcodeStreamSymbols) {
7055 if (!AMDHSAKernelSymbols.
contains(Sym))
7057 ArrayRef<unsigned> Prologue =
ArrayRef(OpcodeStream).drop_front(
Offset);
7058 if (!Prologue.
empty() && Prologue.
front() == S_SETREG_IMM32_B32_gfx12)
7062 "' does not begin with the required prologue "
7063 "sequence: s_mov_b64 followed by v_nop and "
7064 "global_prefetch_b8");
7068 OpcodeStream.
clear();
7069 OpcodeStreamSymbols.clear();
7070 AMDHSAKernelSymbols.
clear();
7073void AMDGPUAsmParser::onEndOfFile() {
7074 emitTargetDirective();
7075 checkKernelPrologues();
7077 getTargetStreamer().emitAMDGPUInfo(*InfoData);
7080bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
7081 StringRef IDVal = DirectiveID.
getString();
7084 if (IDVal ==
".amdhsa_kernel")
7085 return ParseDirectiveAMDHSAKernel();
7087 if (IDVal ==
".amdhsa_code_object_version")
7088 return ParseDirectiveAMDHSACodeObjectVersion();
7092 return ParseDirectiveHSAMetadata();
7094 if (IDVal ==
".amd_kernel_code_t")
7095 return ParseDirectiveAMDKernelCodeT();
7097 if (IDVal ==
".amdgpu_hsa_kernel")
7098 return ParseDirectiveAMDGPUHsaKernel();
7100 if (IDVal ==
".amd_amdgpu_isa")
7101 return ParseDirectiveISAVersion();
7105 Twine(
" directive is "
7106 "not available on non-amdhsa OSes"))
7111 if (IDVal ==
".amdgcn_target")
7112 return ParseDirectiveAMDGCNTarget();
7114 if (IDVal ==
".amdgpu_lds")
7115 return ParseDirectiveAMDGPULDS();
7117 if (IDVal ==
".amdgpu_info")
7118 return ParseDirectiveAMDGPUInfo();
7121 return ParseDirectivePALMetadataBegin();
7124 return ParseDirectivePALMetadata();
7129bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
7131 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
7135 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
7136 return hasSGPR104_SGPR105();
7139 case SRC_SHARED_BASE_LO:
7140 case SRC_SHARED_BASE:
7141 case SRC_SHARED_LIMIT_LO:
7142 case SRC_SHARED_LIMIT:
7144 case SRC_PRIVATE_BASE_LO:
7145 case SRC_PRIVATE_BASE:
7146 case SRC_PRIVATE_LIMIT_LO:
7147 case SRC_PRIVATE_LIMIT:
7149 case SRC_FLAT_SCRATCH_BASE_LO:
7150 case SRC_FLAT_SCRATCH_BASE_HI:
7151 return hasGloballyAddressableScratch();
7152 case SRC_POPS_EXITING_WAVE_ID:
7165 getTargetStreamer().getTargetID()->isXnackSupported();
7194 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
7195 return hasSGPR102_SGPR103();
7203 ParseStatus Res = parseVOPD(
Operands);
7208 Res = MatchOperandParserImpl(
Operands, Mnemonic);
7220 SMLoc LBraceLoc = getLoc();
7225 auto Loc = getLoc();
7228 Error(Loc,
"expected a register");
7232 RBraceLoc = getLoc();
7237 "expected a comma or a closing square bracket"))
7241 if (
Operands.size() - Prefix > 1) {
7243 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
7244 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
7253StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
7255 setForcedEncodingSize(0);
7256 setForcedDPP(
false);
7257 setForcedSDWA(
false);
7259 if (
Name.consume_back(
"_e64_dpp")) {
7261 setForcedEncodingSize(64);
7264 if (
Name.consume_back(
"_e64")) {
7265 setForcedEncodingSize(64);
7268 if (
Name.consume_back(
"_e32")) {
7269 setForcedEncodingSize(32);
7272 if (
Name.consume_back(
"_dpp")) {
7276 if (
Name.consume_back(
"_sdwa")) {
7277 setForcedSDWA(
true);
7285 unsigned VariantID);
7291 Name = parseMnemonicSuffix(Name);
7297 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
7299 bool IsMIMG = Name.starts_with(
"image_");
7302 OperandMode
Mode = OperandMode_Default;
7304 Mode = OperandMode_NSA;
7308 checkUnsupportedInstruction(Name, NameLoc);
7309 if (!Parser.hasPendingError()) {
7312 :
"not a valid operand.";
7332ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
7335 if (!trySkipId(Name))
7338 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, S));
7342ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7351ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7353 std::function<
bool(int64_t &)> ConvertResult) {
7357 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7361 if (ConvertResult && !ConvertResult(
Value)) {
7362 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7365 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7369ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7371 bool (*ConvertResult)(int64_t &)) {
7380 const unsigned MaxSize = 4;
7384 for (
int I = 0;; ++
I) {
7386 SMLoc Loc = getLoc();
7390 if (
Op != 0 &&
Op != 1)
7391 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7398 if (
I + 1 == MaxSize)
7399 return Error(getLoc(),
"expected a closing square bracket");
7405 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7409ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7411 AMDGPUOperand::ImmTy ImmTy,
7412 bool IgnoreNegative) {
7416 if (trySkipId(Name)) {
7418 }
else if (trySkipId(
"no", Name)) {
7427 return Error(S,
"r128 modifier is not supported on this GPU");
7428 if (Name ==
"a16" && !
hasA16())
7429 return Error(S,
"a16 modifier is not supported on this GPU");
7431 if (Bit == 0 && Name ==
"gds") {
7434 return Error(S,
"nogds is not allowed");
7437 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7438 ImmTy = AMDGPUOperand::ImmTyR128A16;
7440 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7444unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7445 bool &Disabling)
const {
7446 Disabling =
Id.consume_front(
"no");
7449 return StringSwitch<unsigned>(Id)
7456 return StringSwitch<unsigned>(Id)
7466 SMLoc StringLoc = getLoc();
7468 int64_t CPolVal = 0;
7489 ResScope = parseScope(
Operands, Scope);
7502 if (trySkipId(
"nv")) {
7506 }
else if (trySkipId(
"no",
"nv")) {
7513 if (trySkipId(
"scale_offset")) {
7517 }
else if (trySkipId(
"no",
"scale_offset")) {
7541 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7542 AMDGPUOperand::ImmTyCPol));
7547 SMLoc OpLoc = getLoc();
7548 unsigned Enabled = 0, Seen = 0;
7552 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7559 return Error(S,
"dlc modifier is not supported on this GPU");
7562 return Error(S,
"scc modifier is not supported on this GPU");
7565 return Error(S,
"duplicate cache policy modifier");
7577 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7586 ParseStatus Res = parseStringOrIntWithPrefix(
7587 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7601 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7605 if (
Value ==
"TH_DEFAULT")
7607 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7608 Value ==
"TH_LOAD_NT_WB") {
7609 return Error(StringLoc,
"invalid th value");
7610 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7612 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7614 }
else if (
Value.consume_front(
"TH_STORE_")) {
7617 return Error(StringLoc,
"invalid th value");
7620 if (
Value ==
"BYPASS")
7625 TH |= StringSwitch<int64_t>(
Value)
7635 .Default(0xffffffff);
7637 TH |= StringSwitch<int64_t>(
Value)
7648 .Default(0xffffffff);
7651 if (TH == 0xffffffff)
7652 return Error(StringLoc,
"invalid th value");
7661 ParseStatus Res = parseStringOrIntWithPrefix(
7662 Operands,
"cfs", {
"CFS_256B",
"CFS_128B",
"CFS_64B",
"CFS_32B"},
CFS);
7672 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7673 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7674 std::optional<unsigned> InsertAt = std::nullopt) {
7675 auto i = OptionalIdx.find(ImmT);
7676 if (i != OptionalIdx.end()) {
7677 unsigned Idx = i->second;
7678 const AMDGPUOperand &
Op =
7679 static_cast<const AMDGPUOperand &
>(*
Operands[
Idx]);
7683 Op.addImmOperands(Inst, 1);
7685 if (InsertAt.has_value())
7692ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7698 StringLoc = getLoc();
7703ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7709 SMLoc StringLoc = getLoc();
7713 Value = getTokenStr();
7717 if (
Value == Ids[IntVal])
7722 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7723 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7728ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7730 AMDGPUOperand::ImmTy
Type) {
7734 ParseStatus Res = parseStringOrIntWithPrefix(
Operands, Name, Ids, IntVal);
7736 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7745bool AMDGPUAsmParser::tryParseFmt(
const char *Pref, int64_t MaxVal,
7748 SMLoc Loc = getLoc();
7750 auto Res = parseIntWithPrefix(Pref, Val);
7756 if (Val < 0 || Val > MaxVal) {
7757 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7766 AMDGPUOperand::ImmTy ImmTy) {
7767 const char *Pref =
"index_key";
7769 SMLoc Loc = getLoc();
7770 auto Res = parseIntWithPrefix(Pref, ImmVal);
7774 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7775 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7776 (ImmVal < 0 || ImmVal > 1))
7777 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7779 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7780 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7782 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7787 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7791 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7795 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7800 AMDGPUOperand::ImmTy
Type) {
7806 return tryParseMatrixFMT(
Operands,
"matrix_a_fmt",
7807 AMDGPUOperand::ImmTyMatrixAFMT);
7811 return tryParseMatrixFMT(
Operands,
"matrix_b_fmt",
7812 AMDGPUOperand::ImmTyMatrixBFMT);
7817 AMDGPUOperand::ImmTy
Type) {
7823 return tryParseMatrixScale(
Operands,
"matrix_a_scale",
7824 AMDGPUOperand::ImmTyMatrixAScale);
7828 return tryParseMatrixScale(
Operands,
"matrix_b_scale",
7829 AMDGPUOperand::ImmTyMatrixBScale);
7834 AMDGPUOperand::ImmTy
Type) {
7840 return tryParseMatrixScaleFmt(
Operands,
"matrix_a_scale_fmt",
7841 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7845 return tryParseMatrixScaleFmt(
Operands,
"matrix_b_scale_fmt",
7846 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7851ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7852 using namespace llvm::AMDGPU::MTBUFFormat;
7858 for (
int I = 0;
I < 2; ++
I) {
7859 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7862 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7867 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7873 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7876 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7877 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7883ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7884 using namespace llvm::AMDGPU::MTBUFFormat;
7888 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7891 if (Fmt == UFMT_UNDEF)
7898bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt,
7899 StringRef FormatStr, SMLoc Loc) {
7900 using namespace llvm::AMDGPU::MTBUFFormat;
7904 if (
Format != DFMT_UNDEF) {
7910 if (
Format != NFMT_UNDEF) {
7915 Error(Loc,
"unsupported format");
7919ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7922 using namespace llvm::AMDGPU::MTBUFFormat;
7926 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7931 SMLoc Loc = getLoc();
7932 if (!parseId(Str,
"expected a format string") ||
7933 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7935 if (Dfmt == DFMT_UNDEF)
7936 return Error(Loc,
"duplicate numeric format");
7937 if (Nfmt == NFMT_UNDEF)
7938 return Error(Loc,
"duplicate data format");
7941 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7942 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7946 if (Ufmt == UFMT_UNDEF)
7947 return Error(FormatLoc,
"unsupported format");
7956ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7959 using namespace llvm::AMDGPU::MTBUFFormat;
7962 if (Id == UFMT_UNDEF)
7966 return Error(Loc,
"unified format is not supported on this GPU");
7972ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7973 using namespace llvm::AMDGPU::MTBUFFormat;
7974 SMLoc Loc = getLoc();
7979 return Error(Loc,
"out of range format");
7984ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7985 using namespace llvm::AMDGPU::MTBUFFormat;
7991 StringRef FormatStr;
7992 SMLoc Loc = getLoc();
7993 if (!parseId(FormatStr,
"expected a format string"))
7996 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7998 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
8008 return parseNumericFormat(
Format);
8012 using namespace llvm::AMDGPU::MTBUFFormat;
8016 SMLoc Loc = getLoc();
8026 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
8045 Res = parseSymbolicOrNumericFormat(
Format);
8050 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
8051 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
8058 return Error(getLoc(),
"duplicate format");
8064 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
8066 Res = parseIntWithPrefix(
"inst_offset",
Operands,
8067 AMDGPUOperand::ImmTyInstOffset);
8074 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
8076 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
8082 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
8085 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
8095 OptionalImmIndexMap OptionalIdx;
8097 unsigned OperandIdx[4];
8098 unsigned EnMask = 0;
8101 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
8102 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8107 OperandIdx[SrcIdx] = Inst.
size();
8108 Op.addRegOperands(Inst, 1);
8115 OperandIdx[SrcIdx] = Inst.
size();
8121 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
8122 Op.addImmOperands(Inst, 1);
8126 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
8130 OptionalIdx[
Op.getImmTy()] = i;
8136 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
8143 for (
auto i = 0; i < SrcIdx; ++i) {
8145 EnMask |= Compr ? (0x3 << i * 2) : (0x1 << i);
8151 AMDGPUOperand::ImmTyExpCompr);
8161 int64_t CntVal,
bool Saturate,
8167 IntVal =
encode(ISA, IntVal, CntVal);
8168 if (CntVal !=
decode(ISA, IntVal)) {
8170 IntVal =
encode(ISA, IntVal, -1);
8178bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
8180 SMLoc CntLoc = getLoc();
8181 StringRef CntName = getTokenStr();
8188 SMLoc ValLoc = getLoc();
8195 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
8197 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
8199 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
8202 Error(CntLoc,
"invalid counter name " + CntName);
8207 Error(ValLoc,
"too large value for " + CntName);
8216 Error(getLoc(),
"expected a counter name");
8230 if (!parseCnt(Waitcnt))
8238 Operands.push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
8242bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
8243 SMLoc FieldLoc = getLoc();
8244 StringRef FieldName = getTokenStr();
8249 SMLoc ValueLoc = getLoc();
8256 if (FieldName ==
"instid0") {
8258 }
else if (FieldName ==
"instskip") {
8260 }
else if (FieldName ==
"instid1") {
8263 Error(FieldLoc,
"invalid field name " + FieldName);
8282 .Case(
"VALU_DEP_1", 1)
8283 .Case(
"VALU_DEP_2", 2)
8284 .Case(
"VALU_DEP_3", 3)
8285 .Case(
"VALU_DEP_4", 4)
8286 .Case(
"TRANS32_DEP_1", 5)
8287 .Case(
"TRANS32_DEP_2", 6)
8288 .Case(
"TRANS32_DEP_3", 7)
8289 .Case(
"FMA_ACCUM_CYCLE_1", 8)
8290 .Case(
"SALU_CYCLE_1", 9)
8291 .Case(
"SALU_CYCLE_2", 10)
8292 .Case(
"SALU_CYCLE_3", 11)
8300 Delay |=
Value << Shift;
8310 if (!parseDelay(Delay))
8318 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
8322bool AMDGPUOperand::isSWaitCnt()
const {
return isImm(); }
8324bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
8330void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
8331 StringRef DepCtrName) {
8334 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
8337 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
8340 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
8343 Error(Loc, Twine(
"invalid value for ", DepCtrName));
8350bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
8352 using namespace llvm::AMDGPU::DepCtr;
8354 SMLoc DepCtrLoc = getLoc();
8355 StringRef DepCtrName = getTokenStr();
8365 unsigned PrevOprMask = UsedOprMask;
8366 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8369 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8378 Error(getLoc(),
"expected a counter name");
8383 int64_t CntValMask = PrevOprMask ^ UsedOprMask;
8384 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8389 using namespace llvm::AMDGPU::DepCtr;
8392 SMLoc Loc = getLoc();
8395 unsigned UsedOprMask = 0;
8397 if (!parseDepCtr(DepCtr, UsedOprMask))
8405 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8409bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8415ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8417 OperandInfoTy &Width) {
8418 using namespace llvm::AMDGPU::Hwreg;
8424 HwReg.Loc = getLoc();
8427 HwReg.IsSymbolic =
true;
8429 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8437 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8447 Width.Loc = getLoc();
8456 using namespace llvm::AMDGPU::Hwreg;
8459 SMLoc Loc = getLoc();
8461 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8463 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8464 HwregOffset::Default);
8465 struct : StructuredOpField {
8466 using StructuredOpField::StructuredOpField;
8467 bool validate(AMDGPUAsmParser &Parser)
const override {
8469 return Error(Parser,
"only values from 1 to 32 are legal");
8472 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8473 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8476 Res = parseHwregFunc(HwReg,
Offset, Width);
8479 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8481 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8485 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8492 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8494 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8498bool AMDGPUOperand::isHwreg()
const {
return isImmTy(ImmTyHwreg); }
8504bool AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &
Msg, OperandInfoTy &
Op,
8505 OperandInfoTy &Stream) {
8506 using namespace llvm::AMDGPU::SendMsg;
8511 Msg.IsSymbolic =
true;
8518 Op.IsDefined =
true;
8524 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8529 Stream.IsDefined =
true;
8530 Stream.Loc = getLoc();
8539bool AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &
Msg,
8540 const OperandInfoTy &
Op,
8541 const OperandInfoTy &Stream) {
8542 using namespace llvm::AMDGPU::SendMsg;
8551 Error(
Msg.Loc,
"specified message id is not supported on this GPU");
8556 Error(
Msg.Loc,
"invalid message id");
8562 Error(
Op.Loc,
"message does not support operations");
8564 Error(
Msg.Loc,
"missing message operation");
8570 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8572 Error(
Op.Loc,
"invalid operation id");
8577 Error(Stream.Loc,
"message operation does not support streams");
8581 Error(Stream.Loc,
"invalid message stream id");
8588 using namespace llvm::AMDGPU::SendMsg;
8591 SMLoc Loc = getLoc();
8595 OperandInfoTy
Op(OP_NONE_);
8596 OperandInfoTy Stream(STREAM_ID_NONE_);
8597 if (parseSendMsgBody(
Msg,
Op, Stream) && validateSendMsg(
Msg,
Op, Stream)) {
8602 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8604 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8610 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8614bool AMDGPUOperand::isSendMsg()
const {
return isImmTy(ImmTySendMsg); }
8617 using namespace llvm::AMDGPU::WaitEvent;
8619 SMLoc Loc = getLoc();
8622 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8624 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8626 StructuredOpField *TargetBitfield =
8627 isGFX11() ? &DontWaitExportReady : &ExportReady;
8629 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8633 if (!validateStructuredOpFields({TargetBitfield}))
8635 ImmVal = TargetBitfield->Val;
8642 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8644 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8645 AMDGPUOperand::ImmTyWaitEvent));
8649bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8662 int Slot = StringSwitch<int>(Str)
8669 return Error(S,
"invalid interpolation slot");
8672 AMDGPUOperand::CreateImm(
this, Slot, S, AMDGPUOperand::ImmTyInterpSlot));
8683 if (!Str.starts_with(
"attr"))
8684 return Error(S,
"invalid interpolation attribute");
8686 StringRef Chan = Str.take_back(2);
8687 int AttrChan = StringSwitch<int>(Chan)
8694 return Error(S,
"invalid or missing interpolation attribute channel");
8696 Str = Str.drop_back(2).drop_front(4);
8699 if (Str.getAsInteger(10, Attr))
8700 return Error(S,
"invalid or missing interpolation attribute number");
8703 return Error(S,
"out of bounds interpolation attribute number");
8708 AMDGPUOperand::CreateImm(
this, Attr, S, AMDGPUOperand::ImmTyInterpAttr));
8709 Operands.push_back(AMDGPUOperand::CreateImm(
8710 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8719 using namespace llvm::AMDGPU::Exp;
8729 return Error(S, (Id == ET_INVALID)
8730 ?
"invalid exp target"
8731 :
"exp target is not supported on this GPU");
8734 AMDGPUOperand::CreateImm(
this, Id, S, AMDGPUOperand::ImmTyExpTgt));
8742bool AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8746bool AMDGPUAsmParser::isId(
const StringRef Id)
const {
8751 return getTokenKind() ==
Kind;
8754StringRef AMDGPUAsmParser::getId()
const {
8758bool AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8766bool AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8768 StringRef Tok = getTokenStr();
8777bool AMDGPUAsmParser::trySkipId(
const StringRef Id,
8779 if (isId(Id) && peekToken().is(Kind)) {
8788 if (isToken(Kind)) {
8796 const StringRef ErrMsg) {
8797 if (!trySkipToken(Kind)) {
8798 Error(getLoc(), ErrMsg);
8804bool AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8808 if (Parser.parseExpression(Expr))
8811 if (Expr->evaluateAsAbsolute(
Imm))
8814 if (Expected.empty()) {
8815 Error(S,
"expected absolute expression");
8818 Twine(
"expected ", Expected) + Twine(
" or an absolute expression"));
8827 if (Parser.parseExpression(Expr))
8831 if (Expr->evaluateAsAbsolute(IntVal)) {
8832 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8834 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8839bool AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8841 Val =
getToken().getStringContents();
8845 Error(getLoc(), ErrMsg);
8849bool AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8851 Val = getTokenStr();
8855 if (!ErrMsg.
empty())
8856 Error(getLoc(), ErrMsg);
8860AsmToken AMDGPUAsmParser::getToken()
const {
return Parser.getTok(); }
8862AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8865 : getLexer().peekTok(ShouldSkipSpace);
8869 auto TokCount = getLexer().peekTokens(Tokens);
8876 return getLexer().getKind();
8879SMLoc AMDGPUAsmParser::getLoc()
const {
return getToken().getLoc(); }
8881StringRef AMDGPUAsmParser::getTokenStr()
const {
8885void AMDGPUAsmParser::lex() { Parser.Lex(); }
8887const AMDGPUOperand &
8889 int MCOpIdx)
const {
8891 const AMDGPUOperand &TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8892 if (TargetOp.getMCOpIdx() == MCOpIdx)
8899 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
8903SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8908 int MCOpIdx)
const {
8909 return findMCOperand(
Operands, MCOpIdx).getStartLoc();
8912SMLoc AMDGPUAsmParser::getOperandLoc(
8913 std::function<
bool(
const AMDGPUOperand &)>
Test,
8915 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
8916 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8918 return Op.getStartLoc();
8923SMLoc AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8925 auto Test = [=](
const AMDGPUOperand &
Op) {
return Op.isImmTy(
Type); };
8940 StringRef
Id = getTokenStr();
8941 SMLoc IdLoc = getLoc();
8947 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8948 if (
I == Fields.
end())
8949 return Error(IdLoc,
"unknown field");
8950 if ((*I)->IsDefined)
8951 return Error(IdLoc,
"duplicate field");
8954 (*I)->Loc = getLoc();
8957 (*I)->IsDefined =
true;
8964bool AMDGPUAsmParser::validateStructuredOpFields(
8966 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8967 return F->validate(*
this);
8977 const unsigned XorMask) {
8984bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8985 const unsigned MaxVal,
8986 const Twine &ErrMsg, SMLoc &Loc) {
9002bool AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t *
Op,
9003 const unsigned MinVal,
9004 const unsigned MaxVal,
9005 const StringRef ErrMsg) {
9007 for (
unsigned i = 0; i < OpNum; ++i) {
9008 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
9015bool AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
9016 using namespace llvm::AMDGPU::Swizzle;
9019 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
9020 "expected a 2-bit lane id")) {
9030bool AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
9031 using namespace llvm::AMDGPU::Swizzle;
9037 if (!parseSwizzleOperand(GroupSize, 2, 32,
9038 "group size must be in the interval [2,32]", Loc)) {
9042 Error(Loc,
"group size must be a power of two");
9045 if (parseSwizzleOperand(LaneIdx, 0, GroupSize - 1,
9046 "lane id must be in the interval [0,group size - 1]",
9054bool AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
9055 using namespace llvm::AMDGPU::Swizzle;
9060 if (!parseSwizzleOperand(GroupSize, 2, 32,
9061 "group size must be in the interval [2,32]", Loc)) {
9065 Error(Loc,
"group size must be a power of two");
9073bool AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
9074 using namespace llvm::AMDGPU::Swizzle;
9079 if (!parseSwizzleOperand(GroupSize, 1, 16,
9080 "group size must be in the interval [1,16]", Loc)) {
9084 Error(Loc,
"group size must be a power of two");
9092bool AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
9093 using namespace llvm::AMDGPU::Swizzle;
9100 SMLoc StrLoc = getLoc();
9101 if (!parseString(Ctl)) {
9104 if (Ctl.
size() != BITMASK_WIDTH) {
9105 Error(StrLoc,
"expected a 5-character mask");
9109 unsigned AndMask = 0;
9110 unsigned OrMask = 0;
9111 unsigned XorMask = 0;
9113 for (
size_t i = 0; i < Ctl.
size(); ++i) {
9117 Error(StrLoc,
"invalid mask");
9138bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
9139 using namespace llvm::AMDGPU::Swizzle;
9142 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
9148 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
9149 "FFT swizzle must be in the interval [0," +
9150 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
9158bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
9159 using namespace llvm::AMDGPU::Swizzle;
9162 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
9169 if (!parseSwizzleOperand(
Direction, 0, 1,
9170 "direction must be 0 (left) or 1 (right)", Loc))
9174 if (!parseSwizzleOperand(
9175 RotateSize, 0, ROTATE_MAX_SIZE,
9176 "number of threads to rotate must be in the interval [0," +
9177 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
9182 (RotateSize << ROTATE_SIZE_SHIFT);
9186bool AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
9188 SMLoc OffsetLoc = getLoc();
9194 Error(OffsetLoc,
"expected a 16-bit offset");
9200bool AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
9201 using namespace llvm::AMDGPU::Swizzle;
9205 SMLoc ModeLoc = getLoc();
9208 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
9209 Ok = parseSwizzleQuadPerm(
Imm);
9210 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
9211 Ok = parseSwizzleBitmaskPerm(
Imm);
9212 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
9213 Ok = parseSwizzleBroadcast(
Imm);
9214 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
9215 Ok = parseSwizzleSwap(
Imm);
9216 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
9217 Ok = parseSwizzleReverse(
Imm);
9218 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
9219 Ok = parseSwizzleFFT(
Imm);
9220 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
9221 Ok = parseSwizzleRotate(
Imm);
9223 Error(ModeLoc,
"expected a swizzle mode");
9226 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
9236 if (trySkipId(
"offset")) {
9240 if (trySkipId(
"swizzle")) {
9241 Ok = parseSwizzleMacro(
Imm);
9243 Ok = parseSwizzleOffset(
Imm);
9248 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
9255bool AMDGPUOperand::isSwizzle()
const {
return isImmTy(ImmTySwizzle); }
9261int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
9263 using namespace llvm::AMDGPU::VGPRIndexMode;
9275 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
9276 if (trySkipId(IdSymbolic[ModeId])) {
9284 ?
"expected a VGPR index mode or a closing parenthesis"
9285 :
"expected a VGPR index mode");
9290 Error(S,
"duplicate VGPR index mode");
9298 "expected a comma or a closing parenthesis"))
9307 using namespace llvm::AMDGPU::VGPRIndexMode;
9313 Imm = parseGPRIdxMacro();
9317 if (getParser().parseAbsoluteExpression(
Imm))
9320 return Error(S,
"invalid immediate: only 4-bit values are legal");
9324 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9328bool AMDGPUOperand::isGPRIdxMode()
const {
return isImmTy(ImmTyGprIdxMode); }
9339 if (isRegister() || isModifier())
9346 assert(Opr.isImm() || Opr.isExpr());
9347 SMLoc Loc = Opr.getStartLoc();
9351 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9352 Error(Loc,
"expected an absolute expression or a label");
9353 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9354 Error(Loc,
"expected a 16-bit signed jump offset");
9374 OptionalImmIndexMap OptionalIdx;
9375 unsigned FirstOperandIdx = 1;
9376 bool IsAtomicReturn =
false;
9382 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
9383 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
9387 Op.addRegOperands(Inst, 1);
9391 if (IsAtomicReturn && i == FirstOperandIdx)
9392 Op.addRegOperands(Inst, 1);
9397 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9398 Op.addImmOperands(Inst, 1);
9410 OptionalIdx[
Op.getImmTy()] = i;
9414 AMDGPUOperand::ImmTyOffset);
9430bool AMDGPUOperand::isSMRDOffset8()
const {
9434bool AMDGPUOperand::isSMEMOffset()
const {
9436 return isImmLiteral();
9439bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9474bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9475 if (BoundCtrl == 0 || BoundCtrl == 1) {
9483void AMDGPUAsmParser::onBeginOfFile() {
9484 if (!getParser().getStreamer().getTargetStreamer())
9487 if (!getTargetStreamer().getTargetID())
9488 getTargetStreamer().initializeTargetID(getSTI(),
9492void AMDGPUAsmParser::emitTargetDirective() {
9493 if (!getParser().getStreamer().getTargetStreamer() ||
9498 getTargetStreamer().emitDirectiveAMDGCNTargetOnce();
9507bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9511 StringRef TokenId = getTokenStr();
9512 AGVK VK = StringSwitch<AGVK>(TokenId)
9513 .Case(
"max", AGVK::AGVK_Max)
9514 .Case(
"min", AGVK::AGVK_Min)
9515 .Case(
"or", AGVK::AGVK_Or)
9516 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9517 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9518 .Case(
"alignto", AGVK::AGVK_AlignTo)
9519 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9520 .Case(
"instprefsize", AGVK::AGVK_InstPrefSize)
9521 .Default(AGVK::AGVK_None);
9530 if (Exprs.
empty()) {
9532 "empty " + Twine(TokenId) +
" expression");
9535 if (CommaCount + 1 != Exprs.
size()) {
9537 "mismatch of commas in " + Twine(TokenId) +
" expression");
9541 Expected && Exprs.
size() != Expected) {
9542 Error(
getToken().getLoc(), Twine(TokenId) +
" expression expects " +
9543 Twine(Expected) +
" operands");
9550 if (getParser().parseExpression(Expr, EndLoc))
9554 if (LastTokenWasComma)
9558 "unexpected token in " + Twine(TokenId) +
" expression");
9564 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9568 StringRef
Name = getTokenStr();
9569 if (Name ==
"mul") {
9570 return parseIntWithPrefix(
"mul",
Operands, AMDGPUOperand::ImmTyOModSI,
9574 if (Name ==
"div") {
9575 return parseIntWithPrefix(
"div",
Operands, AMDGPUOperand::ImmTyOModSI,
9586 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9591 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9592 AMDGPU::OpName::src2};
9600 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9605 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9607 if (
DstOp.isReg() &&
9608 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9612 if ((OpSel & (1 << SrcNum)) != 0)
9618void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9625 OptionalImmIndexMap &OptionalIdx) {
9626 cvtVOP3P(Inst,
Operands, OptionalIdx);
9635 &&
Desc.NumOperands > (OpNum + 1)
9637 &&
Desc.operands()[OpNum + 1].RegClass != -1
9639 &&
Desc.getOperandConstraint(OpNum + 1,
9643void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9645 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9646 AMDGPU::OpName::src2};
9647 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9648 AMDGPU::OpName::src1_modifiers,
9649 AMDGPU::OpName::src2_modifiers};
9650 for (
int J = 0; J < 3; ++J) {
9651 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9657 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9660 if ((OpSel & (1 << J)) != 0)
9663 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9670void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
9672 OptionalImmIndexMap OptionalIdx;
9677 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9678 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9682 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9684 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9685 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9686 Op.isInterpAttrChan()) {
9688 }
else if (
Op.isImmModifier()) {
9689 OptionalIdx[
Op.getImmTy()] =
I;
9697 AMDGPUOperand::ImmTyHigh);
9701 AMDGPUOperand::ImmTyClamp);
9705 AMDGPUOperand::ImmTyOModSI);
9710 AMDGPUOperand::ImmTyOpSel);
9711 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9714 cvtOpSelHelper(Inst, OpSel);
9719 OptionalImmIndexMap OptionalIdx;
9724 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9725 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9729 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9731 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9732 }
else if (
Op.isImmModifier()) {
9733 OptionalIdx[
Op.getImmTy()] =
I;
9741 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9744 AMDGPUOperand::ImmTyOpSel);
9747 AMDGPUOperand::ImmTyWaitEXP);
9753 cvtOpSelHelper(Inst, OpSel);
9756void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9758 OptionalImmIndexMap OptionalIdx;
9761 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9765 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9766 static_cast<AMDGPUOperand &
>(*
Operands[
I++]).addRegOperands(Inst, 1);
9769 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
I]);
9774 if (NumOperands == CbszOpIdx) {
9779 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9780 }
else if (
Op.isImmModifier()) {
9781 OptionalIdx[
Op.getImmTy()] =
I;
9783 Op.addRegOrImmOperands(Inst, 1);
9788 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9789 if (CbszIdx != OptionalIdx.end()) {
9790 int CbszVal = ((AMDGPUOperand &)*
Operands[CbszIdx->second]).
getImm();
9794 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9795 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9796 if (BlgpIdx != OptionalIdx.end()) {
9797 int BlgpVal = ((AMDGPUOperand &)*
Operands[BlgpIdx->second]).
getImm();
9808 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9809 if (OpselIdx != OptionalIdx.end()) {
9810 OpSel =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselIdx->second])
9814 unsigned OpSelHi = 0;
9815 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9816 if (OpselHiIdx != OptionalIdx.end()) {
9817 OpSelHi =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselHiIdx->second])
9820 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9821 AMDGPU::OpName::src1_modifiers};
9823 for (
unsigned J = 0; J < 2; ++J) {
9824 unsigned ModVal = 0;
9825 if (OpSel & (1 << J))
9827 if (OpSelHi & (1 << J))
9830 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9836 OptionalImmIndexMap &OptionalIdx) {
9841 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9842 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9846 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9848 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9849 }
else if (
Op.isImmModifier()) {
9850 OptionalIdx[
Op.getImmTy()] =
I;
9852 Op.addRegOrImmOperands(Inst, 1);
9858 AMDGPUOperand::ImmTyScaleSel);
9862 AMDGPUOperand::ImmTyClamp);
9868 AMDGPUOperand::ImmTyByteSel);
9873 AMDGPUOperand::ImmTyOModSI);
9880 auto *it = Inst.
begin();
9882 it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9891 OptionalImmIndexMap OptionalIdx;
9892 cvtVOP3(Inst,
Operands, OptionalIdx);
9896 OptionalImmIndexMap &OptIdx) {
9901 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9902 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9903 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9904 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9905 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9906 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9907 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9908 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12 ||
9909 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx13 ||
9910 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx13) {
9919 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
9920 if (VdstInIdx != -1 && VdstInIdx ==
static_cast<int>(Inst.
getNumOperands()))
9923 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9924 if (BitOp3Idx != -1) {
9931 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9932 if (OpSelIdx != -1) {
9936 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9937 if (OpSelHiIdx != -1) {
9938 int DefaultVal =
IsPacked ? -1 : 0;
9944 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9945 if (MatrixAFMTIdx != -1) {
9947 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9951 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9952 if (MatrixBFMTIdx != -1) {
9954 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9957 int MatrixAScaleIdx =
9958 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9959 if (MatrixAScaleIdx != -1) {
9961 AMDGPUOperand::ImmTyMatrixAScale, 0);
9964 int MatrixBScaleIdx =
9965 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9966 if (MatrixBScaleIdx != -1) {
9968 AMDGPUOperand::ImmTyMatrixBScale, 0);
9971 int MatrixAScaleFmtIdx =
9972 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9973 if (MatrixAScaleFmtIdx != -1) {
9975 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9978 int MatrixBScaleFmtIdx =
9979 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9980 if (MatrixBScaleFmtIdx != -1) {
9982 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9987 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9991 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9993 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9997 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
10001 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
10002 AMDGPU::OpName::src2};
10003 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
10004 AMDGPU::OpName::src1_modifiers,
10005 AMDGPU::OpName::src2_modifiers};
10007 unsigned OpSel = 0;
10008 unsigned OpSelHi = 0;
10009 unsigned NegLo = 0;
10010 unsigned NegHi = 0;
10012 if (OpSelIdx != -1)
10015 if (OpSelHiIdx != -1)
10018 if (NegLoIdx != -1)
10021 if (NegHiIdx != -1)
10024 for (
int J = 0; J < 3; ++J) {
10025 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
10029 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
10039 uint32_t ModVal = 0;
10041 const MCOperand &SrcOp = Inst.
getOperand(OpIdx);
10042 if (SrcOp.
isReg() && getMRI()
10046 if (VGPRSuffixIsHi)
10049 if ((OpSel & (1 << J)) != 0)
10053 if ((OpSelHi & (1 << J)) != 0)
10056 if ((NegLo & (1 << J)) != 0)
10059 if ((NegHi & (1 << J)) != 0)
10067 OptionalImmIndexMap OptIdx;
10073 unsigned i,
unsigned Opc,
10074 AMDGPU::OpName
OpName) {
10075 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
10076 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
10078 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
10084 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
10087 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
10088 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
10090 OptionalImmIndexMap OptIdx;
10091 for (
unsigned i = 5; i <
Operands.size(); ++i) {
10092 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
10093 OptIdx[
Op.getImmTy()] = i;
10098 AMDGPUOperand::ImmTyIndexKey8bit);
10102 AMDGPUOperand::ImmTyIndexKey16bit);
10106 AMDGPUOperand::ImmTyIndexKey32bit);
10123 SMLoc S = getLoc();
10126 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
10127 SMLoc OpYLoc = getLoc();
10130 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
10133 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
10142 auto addOp = [&](uint16_t ParsedOprIdx) {
10143 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
10145 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10149 Op.addRegOperands(Inst, 1);
10152 if (
Op.isImm() ||
Op.isExpr()) {
10153 Op.addImmOperands(Inst, 1);
10165 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
10169 const auto &CInfo = InstInfo[CompIdx];
10170 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
10171 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
10172 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
10173 if (CInfo.hasSrc2Acc())
10174 addOp(CInfo.getIndexOfDstInParsedOperands());
10178 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
10179 if (BitOp3Idx != -1) {
10180 OptionalImmIndexMap OptIdx;
10181 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands.back());
10183 OptIdx[
Op.getImmTy()] =
Operands.size() - 1;
10193bool AMDGPUOperand::isDPP8()
const {
return isImmTy(ImmTyDPP8); }
10195bool AMDGPUOperand::isDPPCtrl()
const {
10196 using namespace AMDGPU::DPP;
10198 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
10201 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
10202 Imm <= DppCtrl::QUAD_PERM_LAST) ||
10203 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
10204 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
10205 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
10206 (
Imm == DppCtrl::WAVE_SHL1) || (
Imm == DppCtrl::WAVE_ROL1) ||
10207 (
Imm == DppCtrl::WAVE_SHR1) || (
Imm == DppCtrl::WAVE_ROR1) ||
10208 (
Imm == DppCtrl::ROW_MIRROR) || (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
10209 (
Imm == DppCtrl::BCAST15) || (
Imm == DppCtrl::BCAST31) ||
10210 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
10211 Imm <= DppCtrl::ROW_SHARE_LAST) ||
10212 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
10221bool AMDGPUOperand::isBLGP()
const {
10225bool AMDGPUOperand::isS16Imm()
const {
10229bool AMDGPUOperand::isU16Imm()
const {
10237bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
10242 SMLoc Loc =
getToken().getEndLoc();
10243 Token = std::string(getTokenStr());
10245 if (getLoc() != Loc)
10250 if (!parseId(Suffix))
10254 StringRef DimId = Token;
10269 SMLoc S = getLoc();
10275 SMLoc Loc = getLoc();
10276 if (!parseDimId(Encoding))
10277 return Error(Loc,
"invalid dim value");
10280 AMDGPUOperand::CreateImm(
this, Encoding, S, AMDGPUOperand::ImmTyDim));
10289 SMLoc S = getLoc();
10298 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10301 for (
size_t i = 0; i < 8; ++i) {
10305 SMLoc Loc = getLoc();
10306 if (getParser().parseAbsoluteExpression(Sels[i]))
10308 if (0 > Sels[i] || 7 < Sels[i])
10309 return Error(Loc,
"expected a 3-bit value");
10312 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10316 for (
size_t i = 0; i < 8; ++i)
10317 DPP8 |= (Sels[i] << (i * 3));
10320 AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10324bool AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10326 if (Ctrl ==
"row_newbcast")
10329 if (Ctrl ==
"row_share" || Ctrl ==
"row_xmask")
10332 if (Ctrl ==
"wave_shl" || Ctrl ==
"wave_shr" || Ctrl ==
"wave_rol" ||
10333 Ctrl ==
"wave_ror" || Ctrl ==
"row_bcast")
10336 return Ctrl ==
"row_mirror" ||
Ctrl ==
"row_half_mirror" ||
10337 Ctrl ==
"quad_perm" ||
Ctrl ==
"row_shl" ||
Ctrl ==
"row_shr" ||
10341int64_t AMDGPUAsmParser::parseDPPCtrlPerm() {
10344 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10348 for (
int i = 0; i < 4; ++i) {
10353 SMLoc Loc = getLoc();
10354 if (getParser().parseAbsoluteExpression(Temp))
10356 if (Temp < 0 || Temp > 3) {
10357 Error(Loc,
"expected a 2-bit value");
10361 Val += (Temp << i * 2);
10364 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10370int64_t AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10371 using namespace AMDGPU::DPP;
10376 SMLoc Loc = getLoc();
10378 if (getParser().parseAbsoluteExpression(Val))
10381 struct DppCtrlCheck {
10387 DppCtrlCheck
Check =
10388 StringSwitch<DppCtrlCheck>(Ctrl)
10389 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10390 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10391 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10392 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10393 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10394 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10395 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10396 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10397 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10398 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10402 if (
Check.Ctrl == -1) {
10403 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10411 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10419 using namespace AMDGPU::DPP;
10422 !isSupportedDPPCtrl(getTokenStr(),
Operands))
10425 SMLoc S = getLoc();
10431 if (Ctrl ==
"row_mirror") {
10432 Val = DppCtrl::ROW_MIRROR;
10433 }
else if (Ctrl ==
"row_half_mirror") {
10434 Val = DppCtrl::ROW_HALF_MIRROR;
10437 if (Ctrl ==
"quad_perm") {
10438 Val = parseDPPCtrlPerm();
10440 Val = parseDPPCtrlSel(Ctrl);
10449 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10455 OptionalImmIndexMap OptionalIdx;
10462 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10464 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10465 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10469 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10470 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10474 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10475 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10476 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx13 ||
10477 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10478 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx13 ||
10479 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10480 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx13 ||
10481 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
10482 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx13;
10488 if (OldIdx == NumOperands) {
10490 constexpr int DST_IDX = 0;
10492 }
else if (Src2ModIdx == NumOperands) {
10502 if (IsVOP3CvtSrDpp) {
10511 if (TiedTo != -1) {
10516 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10518 if (IsDPP8 &&
Op.isDppFI()) {
10521 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10522 }
else if (
Op.isReg()) {
10523 Op.addRegOperands(Inst, 1);
10524 }
else if (
Op.isImm() &&
10526 Op.addImmOperands(Inst, 1);
10527 }
else if (
Op.isImm()) {
10528 OptionalIdx[
Op.getImmTy()] =
I;
10536 AMDGPUOperand::ImmTyClamp);
10542 AMDGPUOperand::ImmTyByteSel);
10547 AMDGPUOperand::ImmTyOModSI);
10550 cvtVOP3P(Inst,
Operands, OptionalIdx);
10552 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
10555 AMDGPUOperand::ImmTyOpSel);
10560 AMDGPUOperand::ImmTyDPP8);
10561 using namespace llvm::AMDGPU::DPP;
10565 AMDGPUOperand::ImmTyDppCtrl, 0xe4);
10567 AMDGPUOperand::ImmTyDppRowMask, 0xf);
10569 AMDGPUOperand::ImmTyDppBankMask, 0xf);
10571 AMDGPUOperand::ImmTyDppBoundCtrl);
10575 AMDGPUOperand::ImmTyDppFI);
10581 OptionalImmIndexMap OptionalIdx;
10585 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10586 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10593 if (TiedTo != -1) {
10598 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10600 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10608 Op.addImmOperands(Inst, 1);
10610 Op.addRegWithFPInputModsOperands(Inst, 2);
10611 }
else if (
Op.isDppFI()) {
10613 }
else if (
Op.isReg()) {
10614 Op.addRegOperands(Inst, 1);
10620 Op.addRegWithFPInputModsOperands(Inst, 2);
10621 }
else if (
Op.isReg()) {
10622 Op.addRegOperands(Inst, 1);
10623 }
else if (
Op.isDPPCtrl()) {
10624 Op.addImmOperands(Inst, 1);
10625 }
else if (
Op.isImm()) {
10627 OptionalIdx[
Op.getImmTy()] =
I;
10635 using namespace llvm::AMDGPU::DPP;
10639 AMDGPUOperand::ImmTyDppRowMask, 0xf);
10641 AMDGPUOperand::ImmTyDppBankMask, 0xf);
10643 AMDGPUOperand::ImmTyDppBoundCtrl);
10646 AMDGPUOperand::ImmTyDppFI);
10657 AMDGPUOperand::ImmTy
Type) {
10658 return parseStringOrIntWithPrefix(
10660 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10665 return parseStringOrIntWithPrefix(
10666 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10667 AMDGPUOperand::ImmTySDWADstUnused);
10671 cvtSDWA(Inst,
Operands, SDWAInstType::VOP1);
10675 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2);
10678void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
10680 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2,
true,
true);
10683void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
10685 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2,
false,
true);
10693 SDWAInstType BasicInstType,
bool SkipDstVcc,
10695 using namespace llvm::AMDGPU::SDWA;
10697 OptionalImmIndexMap OptionalIdx;
10698 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10699 bool SkippedVcc =
false;
10703 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10704 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10708 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10709 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10710 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10716 if (BasicInstType == SDWAInstType::VOP2 &&
10722 if (BasicInstType == SDWAInstType::VOPC && Inst.
getNumOperands() == 0) {
10728 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10729 }
else if (
Op.isImm()) {
10731 OptionalIdx[
Op.getImmTy()] =
I;
10735 SkippedVcc =
false;
10739 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10740 Opc != AMDGPU::V_NOP_sdwa_vi) {
10742 switch (BasicInstType) {
10743 case SDWAInstType::VOP1:
10746 AMDGPUOperand::ImmTyClamp, 0);
10750 AMDGPUOperand::ImmTyOModSI, 0);
10754 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10758 AMDGPUOperand::ImmTySDWADstUnused,
10759 DstUnused::UNUSED_PRESERVE);
10762 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10765 case SDWAInstType::VOP2:
10767 AMDGPUOperand::ImmTyClamp, 0);
10771 AMDGPUOperand::ImmTyOModSI, 0);
10774 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10776 AMDGPUOperand::ImmTySDWADstUnused,
10777 DstUnused::UNUSED_PRESERVE);
10779 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10781 AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10784 case SDWAInstType::VOPC:
10787 AMDGPUOperand::ImmTyClamp, 0);
10789 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10791 AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10798 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10799 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10800 auto *it = Inst.
begin();
10802 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10815#define GET_MATCHER_IMPLEMENTATION
10816#define GET_MNEMONIC_SPELL_CHECKER
10817#define GET_MNEMONIC_CHECKER
10818#include "AMDGPUGenAsmMatcher.inc"
10824 return parseTokenOp(
"addr64",
Operands);
10826 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10828 return parseTokenOp(
"idxen",
Operands);
10830 return parseNamedBit(
"lds",
Operands, AMDGPUOperand::ImmTyLDS,
10833 return parseTokenOp(
"offen",
Operands);
10835 return parseTokenOp(
"off",
Operands);
10836 case MCK_row_95_en:
10837 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10839 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10841 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10843 return tryCustomParseOperand(
Operands, MCK);
10848unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10854 AMDGPUOperand &Operand = (AMDGPUOperand &)
Op;
10857 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10859 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10861 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10863 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10865 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10867 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10869 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10870 case MCK_row_95_en:
10871 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10879 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10881 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10882 case MCK_SOPPBrTarget:
10883 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10884 case MCK_VReg32OrOff:
10885 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10886 case MCK_InterpSlot:
10887 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10888 case MCK_InterpAttr:
10889 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10890 case MCK_InterpAttrChan:
10891 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10893 case MCK_SReg_64_XEXEC:
10903 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10905 return Match_InvalidOperand;
10914 SMLoc S = getLoc();
10923 return Error(S,
"expected a 16-bit value");
10926 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10930bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10936bool 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 const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
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