56enum RegisterKind { IS_UNKNOWN,
IS_VGPR, IS_SGPR,
IS_AGPR, IS_TTMP, IS_SPECIAL };
70 SMLoc StartLoc, EndLoc;
71 const AMDGPUAsmParser *AsmParser;
74 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
75 : Kind(Kind_), AsmParser(AsmParser_) {}
77 using Ptr = std::unique_ptr<AMDGPUOperand>;
85 bool hasFPModifiers()
const {
return Abs || Neg; }
86 bool hasIntModifiers()
const {
return Sext; }
87 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
89 int64_t getFPModifiersOperand()
const {
96 int64_t getIntModifiersOperand()
const {
102 int64_t getModifiersOperand()
const {
103 assert(!(hasFPModifiers() && hasIntModifiers())
104 &&
"fp and int modifiers should not be used simultaneously");
105 if (hasFPModifiers())
106 return getFPModifiersOperand();
107 if (hasIntModifiers())
108 return getIntModifiersOperand();
112 friend raw_ostream &
operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
182 ImmTyMatrixAScaleFmt,
183 ImmTyMatrixBScaleFmt,
216 mutable int MCOpIdx = -1;
219 bool isToken()
const override {
return Kind == Token; }
221 bool isSymbolRefExpr()
const {
225 bool isImm()
const override {
226 return Kind == Immediate;
229 bool isInlinableImm(MVT type)
const;
230 bool isLiteralImm(MVT type)
const;
232 bool isRegKind()
const {
233 return Kind == Register;
236 bool isReg()
const override {
237 return isRegKind() && !hasModifiers();
240 bool isRegOrInline(
unsigned RCID, MVT type)
const {
241 return isRegClass(RCID) || isInlinableImm(type);
245 return isRegOrInline(RCID, type) || isLiteralImm(type);
248 bool isRegOrImmWithInt16InputMods()
const {
252 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
254 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
257 bool isRegOrImmWithInt32InputMods()
const {
261 bool isRegOrInlineImmWithInt16InputMods()
const {
262 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
265 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
266 return isRegOrInline(
267 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
270 bool isRegOrInlineImmWithInt32InputMods()
const {
271 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
274 bool isRegOrImmWithInt64InputMods()
const {
278 bool isRegOrImmWithFP16InputMods()
const {
282 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
284 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
287 bool isRegOrImmWithFP32InputMods()
const {
291 bool isRegOrImmWithFP64InputMods()
const {
295 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
296 return isRegOrInline(
297 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
300 bool isRegOrInlineImmWithFP32InputMods()
const {
301 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
304 bool isRegOrInlineImmWithFP64InputMods()
const {
305 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
308 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
310 bool isVRegWithFP32InputMods()
const {
311 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
314 bool isVRegWithFP64InputMods()
const {
315 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
318 bool isPackedFP16InputMods()
const {
322 bool isPackedVGPRFP32InputMods()
const {
326 bool isVReg()
const {
327 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
328 isRegClass(AMDGPU::VReg_64RegClassID) ||
329 isRegClass(AMDGPU::VReg_96RegClassID) ||
330 isRegClass(AMDGPU::VReg_128RegClassID) ||
331 isRegClass(AMDGPU::VReg_160RegClassID) ||
332 isRegClass(AMDGPU::VReg_192RegClassID) ||
333 isRegClass(AMDGPU::VReg_256RegClassID) ||
334 isRegClass(AMDGPU::VReg_512RegClassID) ||
335 isRegClass(AMDGPU::VReg_1024RegClassID);
338 bool isVReg32()
const {
339 return isRegClass(AMDGPU::VGPR_32RegClassID);
342 bool isVReg32OrOff()
const {
343 return isOff() || isVReg32();
347 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
350 bool isAV_LdSt_32_Align2_RegOp()
const {
351 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
352 isRegClass(AMDGPU::AGPR_32RegClassID);
355 bool isVRegWithInputMods()
const;
356 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
357 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
359 bool isSDWAOperand(MVT type)
const;
360 bool isSDWAFP16Operand()
const;
361 bool isSDWAFP32Operand()
const;
362 bool isSDWAInt16Operand()
const;
363 bool isSDWAInt32Operand()
const;
365 bool isImmTy(ImmTy ImmT)
const {
366 return isImm() &&
Imm.Type == ImmT;
369 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
371 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
373 bool isImmModifier()
const {
374 return isImm() &&
Imm.Type != ImmTyNone;
377 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
378 bool isDim()
const {
return isImmTy(ImmTyDim); }
379 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
380 bool isOff()
const {
return isImmTy(ImmTyOff); }
381 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
382 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
383 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
384 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
385 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
386 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
387 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
388 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
389 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
390 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
391 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
392 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
393 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
394 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
395 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
396 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
397 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
398 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
399 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
400 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
401 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
402 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
403 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
404 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
405 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
406 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
407 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
408 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
409 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
410 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
411 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
412 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
413 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
414 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
415 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
417 bool isRegOrImm()
const {
418 return isReg() || isImm();
421 bool isRegClass(
unsigned RCID)
const;
425 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
426 return isRegOrInline(RCID, type) && !hasModifiers();
429 bool isSCSrcB16()
const {
430 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
433 bool isSCSrcV2B16()
const {
437 bool isSCSrc_b32()
const {
438 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
441 bool isSCSrc_b64()
const {
442 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
445 bool isBoolReg()
const;
447 bool isSCSrcF16()
const {
448 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
451 bool isSCSrcV2F16()
const {
455 bool isSCSrcF32()
const {
456 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
459 bool isSCSrcF64()
const {
460 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
463 bool isSSrc_b32()
const {
464 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
467 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
469 bool isSSrcV2B16()
const {
474 bool isSSrc_b64()
const {
477 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
478 (((
const MCTargetAsmParser *)AsmParser)
479 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
483 bool isSSrc_f32()
const {
484 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
487 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
489 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
491 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
493 bool isSSrcV2F16()
const {
498 bool isSSrcV2FP32()
const {
503 bool isSCSrcV2FP32()
const {
508 bool isSSrcV2INT32()
const {
513 bool isSCSrcV2INT32()
const {
515 return isSCSrc_b32();
518 bool isSSrcOrLds_b32()
const {
519 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
520 isLiteralImm(MVT::i32) || isExpr();
523 bool isVCSrc_b32()
const {
524 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
527 bool isVCSrc_b32_Lo256()
const {
528 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
531 bool isVCSrc_b64_Lo256()
const {
532 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
535 bool isVCSrc_b64()
const {
536 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
539 bool isVCSrcT_b16()
const {
540 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
543 bool isVCSrcTB16_Lo128()
const {
544 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
547 bool isVCSrcFake16B16_Lo128()
const {
548 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
551 bool isVCSrc_b16()
const {
552 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
555 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
557 bool isVCSrc_f32()
const {
558 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
561 bool isVCSrc_f64()
const {
562 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
565 bool isVCSrcTBF16()
const {
566 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
569 bool isVCSrcT_f16()
const {
570 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
573 bool isVCSrcT_bf16()
const {
574 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
577 bool isVCSrcTBF16_Lo128()
const {
578 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
581 bool isVCSrcTF16_Lo128()
const {
582 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
585 bool isVCSrcFake16BF16_Lo128()
const {
586 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
589 bool isVCSrcFake16F16_Lo128()
const {
590 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
593 bool isVCSrc_bf16()
const {
594 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
597 bool isVCSrc_f16()
const {
598 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
601 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
603 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
605 bool isVSrc_b32()
const {
606 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
609 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
611 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
613 bool isVSrcT_b16_Lo128()
const {
614 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
617 bool isVSrcFake16_b16_Lo128()
const {
618 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
621 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
623 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
625 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
627 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
629 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
631 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
633 bool isVSrc_f32()
const {
634 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
637 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
639 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
641 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
643 bool isVSrcT_bf16_Lo128()
const {
644 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
647 bool isVSrcT_f16_Lo128()
const {
648 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
651 bool isVSrcFake16_bf16_Lo128()
const {
652 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
655 bool isVSrcFake16_f16_Lo128()
const {
656 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
659 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
661 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
663 bool isVSrc_v2bf16()
const {
664 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
667 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
669 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
671 bool isVISrcB32()
const {
672 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
675 bool isVISrcB16()
const {
676 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
679 bool isVISrcV2B16()
const {
683 bool isVISrcF32()
const {
684 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
687 bool isVISrcF16()
const {
688 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
691 bool isVISrcV2F16()
const {
692 return isVISrcF16() || isVISrcB32();
695 bool isVISrc_64_bf16()
const {
696 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
699 bool isVISrc_64_f16()
const {
700 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
703 bool isVISrc_64_b32()
const {
704 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
707 bool isVISrc_64B64()
const {
708 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
711 bool isVISrc_64_f64()
const {
712 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
715 bool isVISrc_64V2FP32()
const {
716 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
719 bool isVISrc_64V2INT32()
const {
720 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
723 bool isVISrc_256_b32()
const {
724 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
727 bool isVISrc_256_f32()
const {
728 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
731 bool isVISrc_256B64()
const {
732 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
735 bool isVISrc_256_f64()
const {
736 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
739 bool isVISrc_512_f64()
const {
740 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
743 bool isVISrc_128B16()
const {
744 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
747 bool isVISrc_128V2B16()
const {
748 return isVISrc_128B16();
751 bool isVISrc_128_b32()
const {
752 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
755 bool isVISrc_128_f32()
const {
756 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
759 bool isVISrc_256V2FP32()
const {
760 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
763 bool isVISrc_256V2INT32()
const {
764 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
767 bool isVISrc_512_b32()
const {
768 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
771 bool isVISrc_512B16()
const {
772 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
775 bool isVISrc_512V2B16()
const {
776 return isVISrc_512B16();
779 bool isVISrc_512_f32()
const {
780 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
783 bool isVISrc_512F16()
const {
784 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
787 bool isVISrc_512V2F16()
const {
788 return isVISrc_512F16() || isVISrc_512_b32();
791 bool isVISrc_1024_b32()
const {
792 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
795 bool isVISrc_1024B16()
const {
796 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
799 bool isVISrc_1024V2B16()
const {
800 return isVISrc_1024B16();
803 bool isVISrc_1024_f32()
const {
804 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
807 bool isVISrc_1024F16()
const {
808 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
811 bool isVISrc_1024V2F16()
const {
812 return isVISrc_1024F16() || isVISrc_1024_b32();
815 bool isAISrcB32()
const {
816 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
819 bool isAISrcB16()
const {
820 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
823 bool isAISrcV2B16()
const {
827 bool isAISrcF32()
const {
828 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
831 bool isAISrcF16()
const {
832 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
835 bool isAISrcV2F16()
const {
836 return isAISrcF16() || isAISrcB32();
839 bool isAISrc_64B64()
const {
840 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
843 bool isAISrc_64_f64()
const {
844 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
847 bool isAISrc_128_b32()
const {
848 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
851 bool isAISrc_128B16()
const {
852 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
855 bool isAISrc_128V2B16()
const {
856 return isAISrc_128B16();
859 bool isAISrc_128_f32()
const {
860 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
863 bool isAISrc_128F16()
const {
864 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
867 bool isAISrc_128V2F16()
const {
868 return isAISrc_128F16() || isAISrc_128_b32();
871 bool isVISrc_128_bf16()
const {
872 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
875 bool isVISrc_128_f16()
const {
876 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
879 bool isVISrc_128V2F16()
const {
880 return isVISrc_128_f16() || isVISrc_128_b32();
883 bool isAISrc_256B64()
const {
884 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
887 bool isAISrc_256_f64()
const {
888 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
891 bool isAISrc_512_b32()
const {
892 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
895 bool isAISrc_512B16()
const {
896 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
899 bool isAISrc_512V2B16()
const {
900 return isAISrc_512B16();
903 bool isAISrc_512_f32()
const {
904 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
907 bool isAISrc_512F16()
const {
908 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
911 bool isAISrc_512V2F16()
const {
912 return isAISrc_512F16() || isAISrc_512_b32();
915 bool isAISrc_1024_b32()
const {
916 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
919 bool isAISrc_1024B16()
const {
920 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
923 bool isAISrc_1024V2B16()
const {
924 return isAISrc_1024B16();
927 bool isAISrc_1024_f32()
const {
928 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
931 bool isAISrc_1024F16()
const {
932 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
935 bool isAISrc_1024V2F16()
const {
936 return isAISrc_1024F16() || isAISrc_1024_b32();
939 bool isKImmFP32()
const {
940 return isLiteralImm(MVT::f32);
943 bool isKImmFP16()
const {
944 return isLiteralImm(MVT::f16);
947 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
949 bool isMem()
const override {
953 bool isExpr()
const {
954 return Kind == Expression;
957 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
959 bool isSWaitCnt()
const;
960 bool isDepCtr()
const;
961 bool isSDelayALU()
const;
962 bool isHwreg()
const;
963 bool isSendMsg()
const;
964 bool isSplitBarrier()
const;
965 bool isSwizzle()
const;
966 bool isSMRDOffset8()
const;
967 bool isSMEMOffset()
const;
968 bool isSMRDLiteralOffset()
const;
970 bool isDPPCtrl()
const;
972 bool isGPRIdxMode()
const;
973 bool isS16Imm()
const;
974 bool isU16Imm()
const;
975 bool isEndpgm()
const;
977 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
978 return [
this,
P]() {
return P(*
this); };
983 return StringRef(Tok.Data, Tok.Length);
991 void setImm(int64_t Val) {
996 ImmTy getImmTy()
const {
1001 MCRegister
getReg()
const override {
1006 SMLoc getStartLoc()
const override {
1010 SMLoc getEndLoc()
const override {
1014 SMRange getLocRange()
const {
1015 return SMRange(StartLoc, EndLoc);
1018 int getMCOpIdx()
const {
return MCOpIdx; }
1020 Modifiers getModifiers()
const {
1021 assert(isRegKind() || isImmTy(ImmTyNone));
1022 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1025 void setModifiers(Modifiers Mods) {
1026 assert(isRegKind() || isImmTy(ImmTyNone));
1033 bool hasModifiers()
const {
1034 return getModifiers().hasModifiers();
1037 bool hasFPModifiers()
const {
1038 return getModifiers().hasFPModifiers();
1041 bool hasIntModifiers()
const {
1042 return getModifiers().hasIntModifiers();
1045 uint64_t applyInputFPModifiers(uint64_t Val,
unsigned Size)
const;
1047 void addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1049 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1051 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1053 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1055 addRegOperands(Inst,
N);
1057 addImmOperands(Inst,
N);
1060 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1061 Modifiers Mods = getModifiers();
1064 addRegOperands(Inst,
N);
1066 addImmOperands(Inst,
N,
false);
1070 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1071 assert(!hasIntModifiers());
1072 addRegOrImmWithInputModsOperands(Inst,
N);
1075 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1076 assert(!hasFPModifiers());
1077 addRegOrImmWithInputModsOperands(Inst,
N);
1080 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1081 Modifiers Mods = getModifiers();
1084 addRegOperands(Inst,
N);
1087 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1088 assert(!hasIntModifiers());
1089 addRegWithInputModsOperands(Inst,
N);
1092 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1093 assert(!hasFPModifiers());
1094 addRegWithInputModsOperands(Inst,
N);
1097 static void printImmTy(raw_ostream& OS, ImmTy
Type) {
1100 case ImmTyNone: OS <<
"None";
break;
1101 case ImmTyGDS: OS <<
"GDS";
break;
1102 case ImmTyLDS: OS <<
"LDS";
break;
1103 case ImmTyOffen: OS <<
"Offen";
break;
1104 case ImmTyIdxen: OS <<
"Idxen";
break;
1105 case ImmTyAddr64: OS <<
"Addr64";
break;
1106 case ImmTyOffset: OS <<
"Offset";
break;
1107 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1108 case ImmTyOffset0: OS <<
"Offset0";
break;
1109 case ImmTyOffset1: OS <<
"Offset1";
break;
1110 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1111 case ImmTyCPol: OS <<
"CPol";
break;
1112 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1113 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1114 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1115 case ImmTyTFE: OS <<
"TFE";
break;
1116 case ImmTyD16: OS <<
"D16";
break;
1117 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1118 case ImmTyClamp: OS <<
"Clamp";
break;
1119 case ImmTyOModSI: OS <<
"OModSI";
break;
1120 case ImmTyDPP8: OS <<
"DPP8";
break;
1121 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1122 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1123 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1124 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1125 case ImmTyDppFI: OS <<
"DppFI";
break;
1126 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1127 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1128 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1129 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1130 case ImmTyDMask: OS <<
"DMask";
break;
1131 case ImmTyDim: OS <<
"Dim";
break;
1132 case ImmTyUNorm: OS <<
"UNorm";
break;
1133 case ImmTyDA: OS <<
"DA";
break;
1134 case ImmTyR128A16: OS <<
"R128A16";
break;
1135 case ImmTyA16: OS <<
"A16";
break;
1136 case ImmTyLWE: OS <<
"LWE";
break;
1137 case ImmTyOff: OS <<
"Off";
break;
1138 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1139 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1140 case ImmTyExpVM: OS <<
"ExpVM";
break;
1141 case ImmTyHwreg: OS <<
"Hwreg";
break;
1142 case ImmTySendMsg: OS <<
"SendMsg";
break;
1143 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1144 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1145 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1146 case ImmTyOpSel: OS <<
"OpSel";
break;
1147 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1148 case ImmTyNegLo: OS <<
"NegLo";
break;
1149 case ImmTyNegHi: OS <<
"NegHi";
break;
1150 case ImmTySwizzle: OS <<
"Swizzle";
break;
1151 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1152 case ImmTyHigh: OS <<
"High";
break;
1153 case ImmTyBLGP: OS <<
"BLGP";
break;
1154 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1155 case ImmTyABID: OS <<
"ABID";
break;
1156 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1157 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1158 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1159 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1160 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1161 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1162 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1163 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1164 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1165 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1166 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1167 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1168 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1169 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1170 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1171 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1176 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1180 <<
" mods: " <<
Reg.Mods <<
'>';
1184 if (getImmTy() != ImmTyNone) {
1185 OS <<
" type: "; printImmTy(OS, getImmTy());
1187 OS <<
" mods: " <<
Imm.Mods <<
'>';
1200 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1201 int64_t Val, SMLoc Loc,
1202 ImmTy
Type = ImmTyNone,
1203 bool IsFPImm =
false) {
1204 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1206 Op->Imm.IsFPImm = IsFPImm;
1208 Op->Imm.Mods = Modifiers();
1214 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1215 StringRef Str, SMLoc Loc,
1216 bool HasExplicitEncodingSize =
true) {
1217 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1218 Res->Tok.Data = Str.data();
1219 Res->Tok.Length = Str.size();
1220 Res->StartLoc = Loc;
1225 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1226 MCRegister
Reg, SMLoc S, SMLoc
E) {
1227 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1228 Op->Reg.RegNo =
Reg;
1229 Op->Reg.Mods = Modifiers();
1235 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1236 const class MCExpr *Expr, SMLoc S) {
1237 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1246 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1255#define GET_REGISTER_MATCHER
1256#include "AMDGPUGenAsmMatcher.inc"
1257#undef GET_REGISTER_MATCHER
1258#undef GET_SUBTARGET_FEATURE_NAME
1263class KernelScopeInfo {
1264 int SgprIndexUnusedMin = -1;
1265 int VgprIndexUnusedMin = -1;
1266 int AgprIndexUnusedMin = -1;
1270 void usesSgprAt(
int i) {
1271 if (i >= SgprIndexUnusedMin) {
1272 SgprIndexUnusedMin = ++i;
1275 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1281 void usesVgprAt(
int i) {
1282 if (i >= VgprIndexUnusedMin) {
1283 VgprIndexUnusedMin = ++i;
1286 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1288 VgprIndexUnusedMin);
1294 void usesAgprAt(
int i) {
1299 if (i >= AgprIndexUnusedMin) {
1300 AgprIndexUnusedMin = ++i;
1303 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1308 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1310 VgprIndexUnusedMin);
1317 KernelScopeInfo() =
default;
1321 MSTI = Ctx->getSubtargetInfo();
1323 usesSgprAt(SgprIndexUnusedMin = -1);
1324 usesVgprAt(VgprIndexUnusedMin = -1);
1326 usesAgprAt(AgprIndexUnusedMin = -1);
1330 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1331 unsigned RegWidth) {
1334 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1337 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1340 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1349 MCAsmParser &Parser;
1351 unsigned ForcedEncodingSize = 0;
1352 bool ForcedDPP =
false;
1353 bool ForcedSDWA =
false;
1354 KernelScopeInfo KernelScope;
1355 const unsigned HwMode;
1360#define GET_ASSEMBLER_HEADER
1361#include "AMDGPUGenAsmMatcher.inc"
1366 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1368 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1373 void createConstantSymbol(StringRef Id, int64_t Val);
1375 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1376 bool OutOfRangeError(SMRange
Range);
1392 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1393 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1394 std::optional<bool> EnableWavefrontSize32,
1395 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1396 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1397 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1398 bool ParseDirectiveAMDGCNTarget();
1399 bool ParseDirectiveAMDHSACodeObjectVersion();
1400 bool ParseDirectiveAMDHSAKernel();
1401 bool ParseAMDKernelCodeTValue(StringRef
ID, AMDGPUMCKernelCodeT &Header);
1402 bool ParseDirectiveAMDKernelCodeT();
1404 bool subtargetHasRegister(
const MCRegisterInfo &
MRI, MCRegister
Reg);
1405 bool ParseDirectiveAMDGPUHsaKernel();
1407 bool ParseDirectiveISAVersion();
1408 bool ParseDirectiveHSAMetadata();
1409 bool ParseDirectivePALMetadataBegin();
1410 bool ParseDirectivePALMetadata();
1411 bool ParseDirectiveAMDGPULDS();
1415 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1416 const char *AssemblerDirectiveEnd,
1417 std::string &CollectString);
1419 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1420 RegisterKind RegKind, MCRegister Reg1, SMLoc Loc);
1421 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1422 unsigned &RegNum,
unsigned &RegWidth,
1423 bool RestoreOnFailure =
false);
1424 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1425 unsigned &RegNum,
unsigned &RegWidth,
1426 SmallVectorImpl<AsmToken> &Tokens);
1427 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1429 SmallVectorImpl<AsmToken> &Tokens);
1430 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1432 SmallVectorImpl<AsmToken> &Tokens);
1433 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1435 SmallVectorImpl<AsmToken> &Tokens);
1436 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &
SubReg);
1437 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1438 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1441 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1442 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1443 void initializeGprCountSymbol(RegisterKind RegKind);
1444 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1446 void cvtMubufImpl(MCInst &Inst,
const OperandVector &Operands,
1451 OperandMode_Default,
1455 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1457 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1458 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
1459 : MCTargetAsmParser(
Options, STI, MII), Parser(_Parser),
1460 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)) {
1463 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1467 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1468 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1469 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1471 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1472 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1473 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1476 initializeGprCountSymbol(IS_VGPR);
1477 initializeGprCountSymbol(IS_SGPR);
1482 createConstantSymbol(Symbol, Code);
1484 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1485 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1486 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1558 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1560 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1562 bool hasInv2PiInlineImm()
const {
1563 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1566 bool has64BitLiterals()
const {
1567 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1570 bool hasFlatOffsets()
const {
1571 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1574 bool hasTrue16Insts()
const {
1575 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1579 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1582 bool hasSGPR102_SGPR103()
const {
1586 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1588 bool hasIntClamp()
const {
1589 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1592 bool hasPartialNSAEncoding()
const {
1593 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1596 bool hasGloballyAddressableScratch()
const {
1597 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1610 AMDGPUTargetStreamer &getTargetStreamer() {
1611 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1612 return static_cast<AMDGPUTargetStreamer &
>(TS);
1618 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1621 const MCRegisterInfo *getMRI()
const {
1625 const MCInstrInfo *getMII()
const {
1631 const FeatureBitset &getFeatureBits()
const {
1632 return getSTI().getFeatureBits();
1635 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1636 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1637 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1639 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1640 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1641 bool isForcedDPP()
const {
return ForcedDPP; }
1642 bool isForcedSDWA()
const {
return ForcedSDWA; }
1643 ArrayRef<unsigned> getMatchedVariants()
const;
1644 StringRef getMatchedVariantName()
const;
1646 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1647 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1648 bool RestoreOnFailure);
1649 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1650 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1651 SMLoc &EndLoc)
override;
1652 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1653 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1654 unsigned Kind)
override;
1655 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1657 uint64_t &ErrorInfo,
1658 bool MatchingInlineAsm)
override;
1659 bool ParseDirective(AsmToken DirectiveID)
override;
1660 ParseStatus parseOperand(
OperandVector &Operands, StringRef Mnemonic,
1661 OperandMode
Mode = OperandMode_Default);
1662 StringRef parseMnemonicSuffix(StringRef Name);
1663 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
1667 ParseStatus parseTokenOp(StringRef Name,
OperandVector &Operands);
1669 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1672 parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1673 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1674 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1676 ParseStatus parseOperandArrayWithPrefix(
1678 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1679 bool (*ConvertResult)(int64_t &) =
nullptr);
1683 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1684 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1686 ParseStatus parseScope(
OperandVector &Operands, int64_t &Scope);
1688 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1690 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1692 ArrayRef<const char *> Ids,
1694 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1696 ArrayRef<const char *> Ids,
1697 AMDGPUOperand::ImmTy
Type);
1700 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1701 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1702 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1703 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1704 bool parseSP3NegModifier();
1705 ParseStatus parseImm(
OperandVector &Operands,
bool HasSP3AbsModifier =
false,
1708 ParseStatus parseRegOrImm(
OperandVector &Operands,
bool HasSP3AbsMod =
false,
1710 ParseStatus parseRegOrImmWithFPInputMods(
OperandVector &Operands,
1711 bool AllowImm =
true);
1712 ParseStatus parseRegOrImmWithIntInputMods(
OperandVector &Operands,
1713 bool AllowImm =
true);
1714 ParseStatus parseRegWithFPInputMods(
OperandVector &Operands);
1715 ParseStatus parseRegWithIntInputMods(
OperandVector &Operands);
1718 AMDGPUOperand::ImmTy ImmTy);
1722 ParseStatus tryParseMatrixFMT(
OperandVector &Operands, StringRef Name,
1723 AMDGPUOperand::ImmTy
Type);
1726 ParseStatus tryParseMatrixScale(
OperandVector &Operands, StringRef Name,
1727 AMDGPUOperand::ImmTy
Type);
1730 ParseStatus tryParseMatrixScaleFmt(
OperandVector &Operands, StringRef Name,
1731 AMDGPUOperand::ImmTy
Type);
1735 ParseStatus parseDfmtNfmt(int64_t &
Format);
1736 ParseStatus parseUfmt(int64_t &
Format);
1737 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1739 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1742 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1743 ParseStatus parseNumericFormat(int64_t &
Format);
1747 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1748 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1752 bool parseCnt(int64_t &IntVal);
1755 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1756 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1759 bool parseDelay(int64_t &Delay);
1765 struct OperandInfoTy {
1768 bool IsSymbolic =
false;
1769 bool IsDefined =
false;
1771 OperandInfoTy(int64_t Val) : Val(Val) {}
1774 struct StructuredOpField : OperandInfoTy {
1778 bool IsDefined =
false;
1780 StructuredOpField(StringLiteral Id, StringLiteral Desc,
unsigned Width,
1782 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1783 virtual ~StructuredOpField() =
default;
1785 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1786 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1790 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1792 return Error(Parser,
"not supported on this GPU");
1794 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1802 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1803 bool validateSendMsg(
const OperandInfoTy &Msg,
1804 const OperandInfoTy &
Op,
1805 const OperandInfoTy &Stream);
1807 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1808 OperandInfoTy &Width);
1810 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1812 SMLoc getFlatOffsetLoc(
const OperandVector &Operands)
const;
1813 SMLoc getSMEMOffsetLoc(
const OperandVector &Operands)
const;
1816 SMLoc getOperandLoc(
const OperandVector &Operands,
int MCOpIdx)
const;
1817 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1819 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1823 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1825 bool validateOffset(
const MCInst &Inst,
const OperandVector &Operands);
1826 bool validateFlatOffset(
const MCInst &Inst,
const OperandVector &Operands);
1827 bool validateSMEMOffset(
const MCInst &Inst,
const OperandVector &Operands);
1828 bool validateSOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1829 bool validateConstantBusLimitations(
const MCInst &Inst,
const OperandVector &Operands);
1830 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1832 bool validateVOPD(
const MCInst &Inst,
const OperandVector &Operands);
1833 bool tryVOPD(
const MCInst &Inst);
1834 bool tryVOPD3(
const MCInst &Inst);
1835 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1837 bool validateIntClampSupported(
const MCInst &Inst);
1838 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1839 bool validateMIMGGatherDMask(
const MCInst &Inst);
1840 bool validateMovrels(
const MCInst &Inst,
const OperandVector &Operands);
1841 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1842 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1843 bool validateMIMGD16(
const MCInst &Inst);
1844 bool validateMIMGDim(
const MCInst &Inst,
const OperandVector &Operands);
1845 bool validateTensorR128(
const MCInst &Inst);
1846 bool validateMIMGMSAA(
const MCInst &Inst);
1847 bool validateOpSel(
const MCInst &Inst);
1848 bool validateTrue16OpSel(
const MCInst &Inst);
1849 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1850 bool validateDPP(
const MCInst &Inst,
const OperandVector &Operands);
1851 bool validateVccOperand(MCRegister
Reg)
const;
1852 bool validateVOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1853 bool validateMAIAccWrite(
const MCInst &Inst,
const OperandVector &Operands);
1854 bool validateMAISrc2(
const MCInst &Inst,
const OperandVector &Operands);
1855 bool validateMFMA(
const MCInst &Inst,
const OperandVector &Operands);
1856 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1857 bool validateVGPRAlign(
const MCInst &Inst)
const;
1858 bool validateBLGP(
const MCInst &Inst,
const OperandVector &Operands);
1859 bool validateDS(
const MCInst &Inst,
const OperandVector &Operands);
1860 bool validateGWS(
const MCInst &Inst,
const OperandVector &Operands);
1861 bool validateDivScale(
const MCInst &Inst);
1862 bool validateWaitCnt(
const MCInst &Inst,
const OperandVector &Operands);
1863 bool validateCoherencyBits(
const MCInst &Inst,
const OperandVector &Operands,
1865 bool validateTHAndScopeBits(
const MCInst &Inst,
const OperandVector &Operands,
1866 const unsigned CPol);
1867 bool validateTFE(
const MCInst &Inst,
const OperandVector &Operands);
1868 bool validateLdsDirect(
const MCInst &Inst,
const OperandVector &Operands);
1869 bool validateWMMA(
const MCInst &Inst,
const OperandVector &Operands);
1870 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1871 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1872 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1873 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1875 bool isSupportedMnemo(StringRef Mnemo,
1876 const FeatureBitset &FBS);
1877 bool isSupportedMnemo(StringRef Mnemo,
1878 const FeatureBitset &FBS,
1879 ArrayRef<unsigned> Variants);
1880 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1882 bool isId(
const StringRef Id)
const;
1883 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1885 StringRef getId()
const;
1886 bool trySkipId(
const StringRef Id);
1887 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1891 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1892 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1898 StringRef getTokenStr()
const;
1899 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1901 SMLoc getLoc()
const;
1905 void onBeginOfFile()
override;
1906 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1908 ParseStatus parseCustomOperand(
OperandVector &Operands,
unsigned MCK);
1917 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1918 const unsigned MaxVal,
const Twine &ErrMsg,
1920 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1921 const unsigned MinVal,
1922 const unsigned MaxVal,
1923 const StringRef ErrMsg);
1925 bool parseSwizzleOffset(int64_t &
Imm);
1926 bool parseSwizzleMacro(int64_t &
Imm);
1927 bool parseSwizzleQuadPerm(int64_t &
Imm);
1928 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1929 bool parseSwizzleBroadcast(int64_t &
Imm);
1930 bool parseSwizzleSwap(int64_t &
Imm);
1931 bool parseSwizzleReverse(int64_t &
Imm);
1932 bool parseSwizzleFFT(int64_t &
Imm);
1933 bool parseSwizzleRotate(int64_t &
Imm);
1936 int64_t parseGPRIdxMacro();
1938 void cvtMubuf(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
false); }
1939 void cvtMubufAtomic(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
true); }
1944 OptionalImmIndexMap &OptionalIdx);
1945 void cvtScaledMFMA(MCInst &Inst,
const OperandVector &Operands);
1946 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands);
1949 void cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands);
1952 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
1953 OptionalImmIndexMap &OptionalIdx);
1955 OptionalImmIndexMap &OptionalIdx);
1957 void cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands);
1958 void cvtVINTERP(MCInst &Inst,
const OperandVector &Operands);
1959 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1961 bool parseDimId(
unsigned &Encoding);
1963 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1966 bool isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands);
1967 int64_t parseDPPCtrlSel(StringRef Ctrl);
1968 int64_t parseDPPCtrlPerm();
1969 void cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8 =
false);
1971 cvtDPP(Inst, Operands,
true);
1973 void cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
1974 bool IsDPP8 =
false);
1975 void cvtVOP3DPP8(MCInst &Inst,
const OperandVector &Operands) {
1976 cvtVOP3DPP(Inst, Operands,
true);
1979 ParseStatus parseSDWASel(
OperandVector &Operands, StringRef Prefix,
1980 AMDGPUOperand::ImmTy
Type);
1982 void cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands);
1983 void cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands);
1984 void cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands);
1985 void cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands);
1986 void cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands);
1988 uint64_t BasicInstType,
1989 bool SkipDstVcc =
false,
1990 bool SkipSrcVcc =
false);
2098bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2108 if (!isImmTy(ImmTyNone)) {
2113 if (getModifiers().
Lit != LitModifier::None)
2123 if (type == MVT::f64 || type == MVT::i64) {
2125 AsmParser->hasInv2PiInlineImm());
2128 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2147 APFloat::rmNearestTiesToEven, &Lost);
2154 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2156 AsmParser->hasInv2PiInlineImm());
2161 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2162 AsmParser->hasInv2PiInlineImm());
2166 if (type == MVT::f64 || type == MVT::i64) {
2168 AsmParser->hasInv2PiInlineImm());
2177 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2178 type, AsmParser->hasInv2PiInlineImm());
2182 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2183 AsmParser->hasInv2PiInlineImm());
2186bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2188 if (!isImmTy(ImmTyNone)) {
2193 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2198 if (type == MVT::f64 && hasFPModifiers()) {
2218 if (type == MVT::f64) {
2223 if (type == MVT::i64) {
2236 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2237 : (type == MVT::v2i16) ? MVT::f32
2238 : (type == MVT::v2f32) ? MVT::f32
2241 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2245bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2246 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2249bool AMDGPUOperand::isVRegWithInputMods()
const {
2250 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2252 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2253 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2256template <
bool IsFake16>
2257bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2258 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2259 : AMDGPU::VGPR_16_Lo128RegClassID);
2262template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2263 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2264 : AMDGPU::VGPR_16RegClassID);
2267bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2268 if (AsmParser->isVI())
2270 if (AsmParser->isGFX9Plus())
2271 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2275bool AMDGPUOperand::isSDWAFP16Operand()
const {
2276 return isSDWAOperand(MVT::f16);
2279bool AMDGPUOperand::isSDWAFP32Operand()
const {
2280 return isSDWAOperand(MVT::f32);
2283bool AMDGPUOperand::isSDWAInt16Operand()
const {
2284 return isSDWAOperand(MVT::i16);
2287bool AMDGPUOperand::isSDWAInt32Operand()
const {
2288 return isSDWAOperand(MVT::i32);
2291bool AMDGPUOperand::isBoolReg()
const {
2292 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2293 (AsmParser->isWave32() && isSCSrc_b32()));
2296uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2298 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2301 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2313void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2323 addLiteralImmOperand(Inst,
Imm.Val,
2325 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2327 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2332void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2333 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2338 if (ApplyModifiers) {
2341 Val = applyInputFPModifiers(Val,
Size);
2345 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2347 bool CanUse64BitLiterals =
2348 AsmParser->has64BitLiterals() &&
2351 MCContext &Ctx = AsmParser->getContext();
2360 if (
Lit == LitModifier::None &&
2362 AsmParser->hasInv2PiInlineImm())) {
2370 bool HasMandatoryLiteral =
2373 if (
Literal.getLoBits(32) != 0 &&
2374 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2375 !HasMandatoryLiteral) {
2376 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2378 "Can't encode literal as exact 64-bit floating-point operand. "
2379 "Low 32-bits will be set to zero");
2380 Val &= 0xffffffff00000000u;
2386 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2392 Lit = LitModifier::Lit64;
2393 }
else if (
Lit == LitModifier::Lit) {
2407 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2409 Lit = LitModifier::Lit64;
2416 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2417 Literal == 0x3fc45f306725feed) {
2451 APFloat::rmNearestTiesToEven, &lost);
2455 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2462 if (
Lit != LitModifier::None) {
2491 if (
Lit == LitModifier::None &&
2501 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2508 if (
Lit == LitModifier::None &&
2516 if (!AsmParser->has64BitLiterals()) {
2517 Val =
static_cast<uint64_t
>(Val) << 32;
2524 if (
Lit == LitModifier::Lit ||
2526 Val =
static_cast<uint64_t
>(Val) << 32;
2530 if (
Lit == LitModifier::Lit)
2556 if (
Lit != LitModifier::None) {
2564void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2569bool AMDGPUOperand::isInlineValue()
const {
2577void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2588 if (Is == IS_VGPR) {
2592 return AMDGPU::VGPR_32RegClassID;
2594 return AMDGPU::VReg_64RegClassID;
2596 return AMDGPU::VReg_96RegClassID;
2598 return AMDGPU::VReg_128RegClassID;
2600 return AMDGPU::VReg_160RegClassID;
2602 return AMDGPU::VReg_192RegClassID;
2604 return AMDGPU::VReg_224RegClassID;
2606 return AMDGPU::VReg_256RegClassID;
2608 return AMDGPU::VReg_288RegClassID;
2610 return AMDGPU::VReg_320RegClassID;
2612 return AMDGPU::VReg_352RegClassID;
2614 return AMDGPU::VReg_384RegClassID;
2616 return AMDGPU::VReg_512RegClassID;
2618 return AMDGPU::VReg_1024RegClassID;
2620 }
else if (Is == IS_TTMP) {
2624 return AMDGPU::TTMP_32RegClassID;
2626 return AMDGPU::TTMP_64RegClassID;
2628 return AMDGPU::TTMP_128RegClassID;
2630 return AMDGPU::TTMP_256RegClassID;
2632 return AMDGPU::TTMP_512RegClassID;
2634 }
else if (Is == IS_SGPR) {
2638 return AMDGPU::SGPR_32RegClassID;
2640 return AMDGPU::SGPR_64RegClassID;
2642 return AMDGPU::SGPR_96RegClassID;
2644 return AMDGPU::SGPR_128RegClassID;
2646 return AMDGPU::SGPR_160RegClassID;
2648 return AMDGPU::SGPR_192RegClassID;
2650 return AMDGPU::SGPR_224RegClassID;
2652 return AMDGPU::SGPR_256RegClassID;
2654 return AMDGPU::SGPR_288RegClassID;
2656 return AMDGPU::SGPR_320RegClassID;
2658 return AMDGPU::SGPR_352RegClassID;
2660 return AMDGPU::SGPR_384RegClassID;
2662 return AMDGPU::SGPR_512RegClassID;
2664 }
else if (Is == IS_AGPR) {
2668 return AMDGPU::AGPR_32RegClassID;
2670 return AMDGPU::AReg_64RegClassID;
2672 return AMDGPU::AReg_96RegClassID;
2674 return AMDGPU::AReg_128RegClassID;
2676 return AMDGPU::AReg_160RegClassID;
2678 return AMDGPU::AReg_192RegClassID;
2680 return AMDGPU::AReg_224RegClassID;
2682 return AMDGPU::AReg_256RegClassID;
2684 return AMDGPU::AReg_288RegClassID;
2686 return AMDGPU::AReg_320RegClassID;
2688 return AMDGPU::AReg_352RegClassID;
2690 return AMDGPU::AReg_384RegClassID;
2692 return AMDGPU::AReg_512RegClassID;
2694 return AMDGPU::AReg_1024RegClassID;
2702 .
Case(
"exec", AMDGPU::EXEC)
2703 .
Case(
"vcc", AMDGPU::VCC)
2704 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2705 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2706 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2707 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2708 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2709 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2710 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2711 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2712 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2713 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2714 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2715 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2716 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2717 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2718 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2719 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2720 .
Case(
"m0", AMDGPU::M0)
2721 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2722 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2723 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2724 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2725 .
Case(
"scc", AMDGPU::SRC_SCC)
2726 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2727 .
Case(
"tba", AMDGPU::TBA)
2728 .
Case(
"tma", AMDGPU::TMA)
2729 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2730 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2731 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2732 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2733 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2734 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2735 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2736 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2737 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2738 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2739 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2740 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2741 .
Case(
"pc", AMDGPU::PC_REG)
2742 .
Case(
"null", AMDGPU::SGPR_NULL)
2746bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2747 SMLoc &EndLoc,
bool RestoreOnFailure) {
2748 auto R = parseRegister();
2749 if (!R)
return true;
2751 RegNo =
R->getReg();
2752 StartLoc =
R->getStartLoc();
2753 EndLoc =
R->getEndLoc();
2757bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2759 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2762ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2764 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2765 bool PendingErrors = getParser().hasPendingError();
2766 getParser().clearPendingErrors();
2774bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2775 RegisterKind RegKind,
2776 MCRegister Reg1, SMLoc Loc) {
2779 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2784 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2785 Reg = AMDGPU::FLAT_SCR;
2789 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2790 Reg = AMDGPU::XNACK_MASK;
2794 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2799 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2804 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2809 Error(Loc,
"register does not fit in the list");
2815 if (Reg1 !=
Reg + RegWidth / 32) {
2816 Error(Loc,
"registers in a list must have consecutive indices");
2834 {{
"ttmp"}, IS_TTMP},
2840 return Kind == IS_VGPR ||
2848 if (Str.starts_with(
Reg.Name))
2854 return !Str.getAsInteger(10, Num);
2858AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2859 const AsmToken &NextToken)
const {
2874 StringRef RegSuffix = Str.substr(
RegName.size());
2875 if (!RegSuffix.
empty()) {
2893AMDGPUAsmParser::isRegister()
2895 return isRegister(
getToken(), peekToken());
2898MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2899 unsigned SubReg,
unsigned RegWidth,
2903 unsigned AlignSize = 1;
2904 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2910 if (RegNum % AlignSize != 0) {
2911 Error(Loc,
"invalid register alignment");
2912 return MCRegister();
2915 unsigned RegIdx = RegNum / AlignSize;
2918 Error(Loc,
"invalid or unsupported register size");
2919 return MCRegister();
2923 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2924 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2925 Error(Loc,
"register index is out of range");
2926 return AMDGPU::NoRegister;
2929 if (RegKind == IS_VGPR && !
isGFX1250() && RegIdx + RegWidth / 32 > 256) {
2930 Error(Loc,
"register index is out of range");
2931 return MCRegister();
2947bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2949 int64_t RegLo, RegHi;
2953 SMLoc FirstIdxLoc = getLoc();
2960 SecondIdxLoc = getLoc();
2971 Error(FirstIdxLoc,
"invalid register index");
2976 Error(SecondIdxLoc,
"invalid register index");
2980 if (RegLo > RegHi) {
2981 Error(FirstIdxLoc,
"first register index should not exceed second index");
2985 if (RegHi == RegLo) {
2986 StringRef RegSuffix = getTokenStr();
2987 if (RegSuffix ==
".l") {
2990 }
else if (RegSuffix ==
".h") {
2996 Num =
static_cast<unsigned>(RegLo);
2997 RegWidth = 32 * ((RegHi - RegLo) + 1);
3002MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3005 SmallVectorImpl<AsmToken> &Tokens) {
3011 RegKind = IS_SPECIAL;
3018MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3021 SmallVectorImpl<AsmToken> &Tokens) {
3023 StringRef
RegName = getTokenStr();
3024 auto Loc = getLoc();
3028 Error(Loc,
"invalid register name");
3029 return MCRegister();
3037 unsigned SubReg = NoSubRegister;
3038 if (!RegSuffix.
empty()) {
3046 Error(Loc,
"invalid register index");
3047 return MCRegister();
3052 if (!ParseRegRange(RegNum, RegWidth,
SubReg))
3053 return MCRegister();
3056 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
3059MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3060 unsigned &RegNum,
unsigned &RegWidth,
3061 SmallVectorImpl<AsmToken> &Tokens) {
3063 auto ListLoc = getLoc();
3066 "expected a register or a list of registers")) {
3067 return MCRegister();
3072 auto Loc = getLoc();
3073 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3074 return MCRegister();
3075 if (RegWidth != 32) {
3076 Error(Loc,
"expected a single 32-bit register");
3077 return MCRegister();
3081 RegisterKind NextRegKind;
3083 unsigned NextRegNum, NextRegWidth;
3086 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3087 NextRegNum, NextRegWidth,
3089 return MCRegister();
3091 if (NextRegWidth != 32) {
3092 Error(Loc,
"expected a single 32-bit register");
3093 return MCRegister();
3095 if (NextRegKind != RegKind) {
3096 Error(Loc,
"registers in a list must be of the same kind");
3097 return MCRegister();
3099 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3100 return MCRegister();
3104 "expected a comma or a closing square bracket")) {
3105 return MCRegister();
3109 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3114bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3115 MCRegister &
Reg,
unsigned &RegNum,
3117 SmallVectorImpl<AsmToken> &Tokens) {
3118 auto Loc = getLoc();
3122 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3124 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3126 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3131 assert(Parser.hasPendingError());
3135 if (!subtargetHasRegister(*
TRI,
Reg)) {
3136 if (
Reg == AMDGPU::SGPR_NULL) {
3137 Error(Loc,
"'null' operand is not supported on this GPU");
3140 " register not available on this GPU");
3148bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3149 MCRegister &
Reg,
unsigned &RegNum,
3151 bool RestoreOnFailure ) {
3155 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3156 if (RestoreOnFailure) {
3157 while (!Tokens.
empty()) {
3166std::optional<StringRef>
3167AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3170 return StringRef(
".amdgcn.next_free_vgpr");
3172 return StringRef(
".amdgcn.next_free_sgpr");
3174 return std::nullopt;
3178void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3179 auto SymbolName = getGprCountSymbolName(RegKind);
3180 assert(SymbolName &&
"initializing invalid register kind");
3186bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3187 unsigned DwordRegIndex,
3188 unsigned RegWidth) {
3193 auto SymbolName = getGprCountSymbolName(RegKind);
3198 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3202 return !
Error(getLoc(),
3203 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3207 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3209 if (OldCount <= NewMax)
3215std::unique_ptr<AMDGPUOperand>
3216AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3218 SMLoc StartLoc = Tok.getLoc();
3219 SMLoc EndLoc = Tok.getEndLoc();
3220 RegisterKind RegKind;
3222 unsigned RegNum, RegWidth;
3224 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3228 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3231 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3232 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3235ParseStatus AMDGPUAsmParser::parseImm(
OperandVector &Operands,
3239 if (isRegister() || isModifier())
3242 if (
Lit == LitModifier::None) {
3243 if (trySkipId(
"lit"))
3244 Lit = LitModifier::Lit;
3245 else if (trySkipId(
"lit64"))
3246 Lit = LitModifier::Lit64;
3248 if (
Lit != LitModifier::None) {
3251 ParseStatus S = parseImm(Operands, HasSP3AbsModifier,
Lit);
3260 const auto& NextTok = peekToken();
3263 bool Negate =
false;
3271 AMDGPUOperand::Modifiers Mods;
3279 StringRef Num = getTokenStr();
3282 APFloat RealVal(APFloat::IEEEdouble());
3283 auto roundMode = APFloat::rmNearestTiesToEven;
3284 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3287 RealVal.changeSign();
3290 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3291 AMDGPUOperand::ImmTyNone,
true));
3292 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3293 Op.setModifiers(Mods);
3302 if (HasSP3AbsModifier) {
3311 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3314 if (Parser.parseExpression(Expr))
3318 if (Expr->evaluateAsAbsolute(IntVal)) {
3319 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3320 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3321 Op.setModifiers(Mods);
3323 if (
Lit != LitModifier::None)
3325 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3334ParseStatus AMDGPUAsmParser::parseReg(
OperandVector &Operands) {
3338 if (
auto R = parseRegister()) {
3346ParseStatus AMDGPUAsmParser::parseRegOrImm(
OperandVector &Operands,
3348 ParseStatus Res = parseReg(Operands);
3353 return parseImm(Operands, HasSP3AbsMod,
Lit);
3357AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3360 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3366AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3371AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3372 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3376AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3377 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3394AMDGPUAsmParser::isModifier() {
3397 AsmToken NextToken[2];
3398 peekTokens(NextToken);
3400 return isOperandModifier(Tok, NextToken[0]) ||
3401 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3402 isOpcodeModifierWithVal(Tok, NextToken[0]);
3428AMDGPUAsmParser::parseSP3NegModifier() {
3430 AsmToken NextToken[2];
3431 peekTokens(NextToken);
3434 (isRegister(NextToken[0], NextToken[1]) ||
3436 isId(NextToken[0],
"abs"))) {
3445AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
3453 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3455 SP3Neg = parseSP3NegModifier();
3458 Neg = trySkipId(
"neg");
3460 return Error(Loc,
"expected register or immediate");
3464 Abs = trySkipId(
"abs");
3469 if (trySkipId(
"lit")) {
3470 Lit = LitModifier::Lit;
3473 }
else if (trySkipId(
"lit64")) {
3474 Lit = LitModifier::Lit64;
3477 if (!has64BitLiterals())
3478 return Error(Loc,
"lit64 is not supported on this GPU");
3484 return Error(Loc,
"expected register or immediate");
3488 Res = parseRegOrImm(Operands, SP3Abs,
Lit);
3490 Res = parseReg(Operands);
3493 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3497 if (
Lit != LitModifier::None && !Operands.
back()->isImm())
3498 Error(Loc,
"expected immediate with lit modifier");
3500 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3506 if (
Lit != LitModifier::None &&
3510 AMDGPUOperand::Modifiers Mods;
3511 Mods.Abs = Abs || SP3Abs;
3512 Mods.Neg = Neg || SP3Neg;
3515 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3516 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3518 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3519 Op.setModifiers(Mods);
3525AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
3527 bool Sext = trySkipId(
"sext");
3528 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3533 Res = parseRegOrImm(Operands);
3535 Res = parseReg(Operands);
3543 AMDGPUOperand::Modifiers Mods;
3546 if (Mods.hasIntModifiers()) {
3547 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3549 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3550 Op.setModifiers(Mods);
3556ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
3557 return parseRegOrImmWithFPInputMods(Operands,
false);
3560ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
3561 return parseRegOrImmWithIntInputMods(Operands,
false);
3564ParseStatus AMDGPUAsmParser::parseVReg32OrOff(
OperandVector &Operands) {
3565 auto Loc = getLoc();
3566 if (trySkipId(
"off")) {
3567 Operands.
push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3568 AMDGPUOperand::ImmTyOff,
false));
3575 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3584unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3591 return Match_InvalidOperand;
3593 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3594 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3597 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3599 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3600 return Match_InvalidOperand;
3608 if (tryAnotherVOPDEncoding(Inst))
3609 return Match_InvalidOperand;
3611 return Match_Success;
3615 static const unsigned Variants[] = {
3625ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3626 if (isForcedDPP() && isForcedVOP3()) {
3630 if (getForcedEncodingSize() == 32) {
3635 if (isForcedVOP3()) {
3640 if (isForcedSDWA()) {
3646 if (isForcedDPP()) {
3654StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3655 if (isForcedDPP() && isForcedVOP3())
3658 if (getForcedEncodingSize() == 32)
3674AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3678 case AMDGPU::FLAT_SCR:
3680 case AMDGPU::VCC_LO:
3681 case AMDGPU::VCC_HI:
3688 return MCRegister();
3695bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3696 unsigned OpIdx)
const {
3750unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3756 case AMDGPU::V_LSHLREV_B64_e64:
3757 case AMDGPU::V_LSHLREV_B64_gfx10:
3758 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3759 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3760 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3761 case AMDGPU::V_LSHRREV_B64_e64:
3762 case AMDGPU::V_LSHRREV_B64_gfx10:
3763 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3764 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3765 case AMDGPU::V_ASHRREV_I64_e64:
3766 case AMDGPU::V_ASHRREV_I64_gfx10:
3767 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3768 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3769 case AMDGPU::V_LSHL_B64_e64:
3770 case AMDGPU::V_LSHR_B64_e64:
3771 case AMDGPU::V_ASHR_I64_e64:
3784 bool AddMandatoryLiterals =
false) {
3787 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3791 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3793 return {getNamedOperandIdx(Opcode, OpName::src0X),
3794 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3795 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3796 getNamedOperandIdx(Opcode, OpName::src0Y),
3797 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3798 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3803 return {getNamedOperandIdx(Opcode, OpName::src0),
3804 getNamedOperandIdx(Opcode, OpName::src1),
3805 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3808bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3811 return !isInlineConstant(Inst,
OpIdx);
3818 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3829 const unsigned Opcode = Inst.
getOpcode();
3830 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3833 if (!LaneSelOp.
isReg())
3836 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3839bool AMDGPUAsmParser::validateConstantBusLimitations(
3841 const unsigned Opcode = Inst.
getOpcode();
3842 const MCInstrDesc &
Desc = MII.
get(Opcode);
3843 MCRegister LastSGPR;
3844 unsigned ConstantBusUseCount = 0;
3845 unsigned NumLiterals = 0;
3846 unsigned LiteralSize;
3848 if (!(
Desc.TSFlags &
3863 SmallDenseSet<MCRegister> SGPRsUsed;
3864 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3866 SGPRsUsed.
insert(SGPRUsed);
3867 ++ConstantBusUseCount;
3872 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3874 for (
int OpIdx : OpIndices) {
3879 if (usesConstantBus(Inst,
OpIdx)) {
3888 if (SGPRsUsed.
insert(LastSGPR).second) {
3889 ++ConstantBusUseCount;
3909 if (NumLiterals == 0) {
3912 }
else if (LiteralSize !=
Size) {
3918 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3920 "invalid operand (violates constant bus restrictions)");
3927std::optional<unsigned>
3928AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3930 const unsigned Opcode = Inst.
getOpcode();
3936 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3937 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3945 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3946 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3947 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250;
3951 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3952 int I = getNamedOperandIdx(Opcode, OpName);
3956 int64_t
Imm =
Op.getImm();
3962 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3963 OpName::vsrc2Y, OpName::imm}) {
3964 int I = getNamedOperandIdx(Opcode, OpName);
3974 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3975 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3977 return InvalidCompOprIdx;
3980bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
3987 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
3988 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
3989 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
3991 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
3995 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
3996 if (!InvalidCompOprIdx.has_value())
3999 auto CompOprIdx = *InvalidCompOprIdx;
4002 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4003 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4004 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4006 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4007 if (CompOprIdx == VOPD::Component::DST) {
4009 Error(Loc,
"dst registers must be distinct");
4011 Error(Loc,
"one dst register must be even and the other odd");
4013 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4014 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4015 " operands must use different VGPR banks");
4023bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4025 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4026 if (!InvalidCompOprIdx.has_value())
4030 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4031 if (InvalidCompOprIdx.has_value()) {
4036 if (*InvalidCompOprIdx == VOPD::Component::DST)
4049bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4050 const unsigned Opcode = Inst.
getOpcode();
4065 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4066 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4067 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4068 int I = getNamedOperandIdx(Opcode, OpName);
4075 return !tryVOPD3(Inst);
4080bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4081 const unsigned Opcode = Inst.
getOpcode();
4086 return tryVOPD(Inst);
4087 return tryVOPD3(Inst);
4090bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4096 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4107bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4115 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4116 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4117 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4125 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4126 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4131 bool IsPackedD16 =
false;
4135 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4136 IsPackedD16 = D16Idx >= 0;
4141 if ((VDataSize / 4) ==
DataSize + TFESize)
4146 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4148 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4150 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4154bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4163 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4165 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4167 ? AMDGPU::OpName::srsrc
4168 : AMDGPU::OpName::rsrc;
4169 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4170 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4171 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4175 assert(SrsrcIdx > VAddr0Idx);
4178 if (BaseOpcode->
BVH) {
4179 if (IsA16 == BaseOpcode->
A16)
4181 Error(IDLoc,
"image address size does not match a16");
4187 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4188 unsigned ActualAddrSize =
4189 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4191 unsigned ExpectedAddrSize =
4195 if (hasPartialNSAEncoding() &&
4198 int VAddrLastIdx = SrsrcIdx - 1;
4199 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4201 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4204 if (ExpectedAddrSize > 12)
4205 ExpectedAddrSize = 16;
4210 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4214 if (ActualAddrSize == ExpectedAddrSize)
4217 Error(IDLoc,
"image address size does not match dim and a16");
4221bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4228 if (!
Desc.mayLoad() || !
Desc.mayStore())
4231 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4238 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4241bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4249 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4257 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4260bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4275 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4276 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4283bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4291 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4294 if (!BaseOpcode->
MSAA)
4297 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4303 return DimInfo->
MSAA;
4309 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4310 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4311 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4321bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4330 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4333 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4341 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4345bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4350 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4353 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4356 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4363 Error(getOperandLoc(Operands, Src0Idx),
4364 "source operand must be either a VGPR or an inline constant");
4371bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4374 const MCInstrDesc &
Desc = MII.
get(Opcode);
4377 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4380 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4384 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4385 Error(getOperandLoc(Operands, Src2Idx),
4386 "inline constants are not allowed for this operand");
4393bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4401 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4402 if (BlgpIdx != -1) {
4403 if (
const MFMA_F8F6F4_Info *
Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4404 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4414 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4415 Error(getOperandLoc(Operands, Src0Idx),
4416 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4421 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4422 Error(getOperandLoc(Operands, Src1Idx),
4423 "wrong register tuple size for blgp value " + Twine(BLGP));
4431 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4435 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4439 MCRegister Src2Reg = Src2.
getReg();
4441 if (Src2Reg == DstReg)
4446 .getSizeInBits() <= 128)
4449 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4450 Error(getOperandLoc(Operands, Src2Idx),
4451 "source 2 operand must not partially overlap with dst");
4458bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4462 case V_DIV_SCALE_F32_gfx6_gfx7:
4463 case V_DIV_SCALE_F32_vi:
4464 case V_DIV_SCALE_F32_gfx10:
4465 case V_DIV_SCALE_F64_gfx6_gfx7:
4466 case V_DIV_SCALE_F64_vi:
4467 case V_DIV_SCALE_F64_gfx10:
4473 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4474 AMDGPU::OpName::src2_modifiers,
4475 AMDGPU::OpName::src2_modifiers}) {
4486bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4494 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4503bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4510 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4518 case AMDGPU::V_SUBREV_F32_e32:
4519 case AMDGPU::V_SUBREV_F32_e64:
4520 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4521 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4522 case AMDGPU::V_SUBREV_F32_e32_vi:
4523 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4524 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4525 case AMDGPU::V_SUBREV_F32_e64_vi:
4527 case AMDGPU::V_SUBREV_CO_U32_e32:
4528 case AMDGPU::V_SUBREV_CO_U32_e64:
4529 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4530 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4532 case AMDGPU::V_SUBBREV_U32_e32:
4533 case AMDGPU::V_SUBBREV_U32_e64:
4534 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4535 case AMDGPU::V_SUBBREV_U32_e32_vi:
4536 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4537 case AMDGPU::V_SUBBREV_U32_e64_vi:
4539 case AMDGPU::V_SUBREV_U32_e32:
4540 case AMDGPU::V_SUBREV_U32_e64:
4541 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4542 case AMDGPU::V_SUBREV_U32_e32_vi:
4543 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4544 case AMDGPU::V_SUBREV_U32_e64_vi:
4546 case AMDGPU::V_SUBREV_F16_e32:
4547 case AMDGPU::V_SUBREV_F16_e64:
4548 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4549 case AMDGPU::V_SUBREV_F16_e32_vi:
4550 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4551 case AMDGPU::V_SUBREV_F16_e64_vi:
4553 case AMDGPU::V_SUBREV_U16_e32:
4554 case AMDGPU::V_SUBREV_U16_e64:
4555 case AMDGPU::V_SUBREV_U16_e32_vi:
4556 case AMDGPU::V_SUBREV_U16_e64_vi:
4558 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4559 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4560 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4562 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4563 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4565 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4566 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4568 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4569 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4571 case AMDGPU::V_LSHRREV_B32_e32:
4572 case AMDGPU::V_LSHRREV_B32_e64:
4573 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4574 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4575 case AMDGPU::V_LSHRREV_B32_e32_vi:
4576 case AMDGPU::V_LSHRREV_B32_e64_vi:
4577 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4578 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4580 case AMDGPU::V_ASHRREV_I32_e32:
4581 case AMDGPU::V_ASHRREV_I32_e64:
4582 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4583 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4584 case AMDGPU::V_ASHRREV_I32_e32_vi:
4585 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4586 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4587 case AMDGPU::V_ASHRREV_I32_e64_vi:
4589 case AMDGPU::V_LSHLREV_B32_e32:
4590 case AMDGPU::V_LSHLREV_B32_e64:
4591 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4592 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4593 case AMDGPU::V_LSHLREV_B32_e32_vi:
4594 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4595 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4596 case AMDGPU::V_LSHLREV_B32_e64_vi:
4598 case AMDGPU::V_LSHLREV_B16_e32:
4599 case AMDGPU::V_LSHLREV_B16_e64:
4600 case AMDGPU::V_LSHLREV_B16_e32_vi:
4601 case AMDGPU::V_LSHLREV_B16_e64_vi:
4602 case AMDGPU::V_LSHLREV_B16_gfx10:
4604 case AMDGPU::V_LSHRREV_B16_e32:
4605 case AMDGPU::V_LSHRREV_B16_e64:
4606 case AMDGPU::V_LSHRREV_B16_e32_vi:
4607 case AMDGPU::V_LSHRREV_B16_e64_vi:
4608 case AMDGPU::V_LSHRREV_B16_gfx10:
4610 case AMDGPU::V_ASHRREV_I16_e32:
4611 case AMDGPU::V_ASHRREV_I16_e64:
4612 case AMDGPU::V_ASHRREV_I16_e32_vi:
4613 case AMDGPU::V_ASHRREV_I16_e64_vi:
4614 case AMDGPU::V_ASHRREV_I16_gfx10:
4616 case AMDGPU::V_LSHLREV_B64_e64:
4617 case AMDGPU::V_LSHLREV_B64_gfx10:
4618 case AMDGPU::V_LSHLREV_B64_vi:
4620 case AMDGPU::V_LSHRREV_B64_e64:
4621 case AMDGPU::V_LSHRREV_B64_gfx10:
4622 case AMDGPU::V_LSHRREV_B64_vi:
4624 case AMDGPU::V_ASHRREV_I64_e64:
4625 case AMDGPU::V_ASHRREV_I64_gfx10:
4626 case AMDGPU::V_ASHRREV_I64_vi:
4628 case AMDGPU::V_PK_LSHLREV_B16:
4629 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4630 case AMDGPU::V_PK_LSHLREV_B16_vi:
4632 case AMDGPU::V_PK_LSHRREV_B16:
4633 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4634 case AMDGPU::V_PK_LSHRREV_B16_vi:
4635 case AMDGPU::V_PK_ASHRREV_I16:
4636 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4637 case AMDGPU::V_PK_ASHRREV_I16_vi:
4644bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4646 using namespace SIInstrFlags;
4647 const unsigned Opcode = Inst.
getOpcode();
4648 const MCInstrDesc &
Desc = MII.
get(Opcode);
4653 if ((
Desc.TSFlags & Enc) == 0)
4656 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4657 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4661 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4664 Error(getOperandLoc(Operands, SrcIdx),
4665 "lds_direct is not supported on this GPU");
4670 Error(getOperandLoc(Operands, SrcIdx),
4671 "lds_direct cannot be used with this instruction");
4675 if (SrcName != OpName::src0) {
4676 Error(getOperandLoc(Operands, SrcIdx),
4677 "lds_direct may be used as src0 only");
4686SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4687 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4688 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4689 if (
Op.isFlatOffset())
4690 return Op.getStartLoc();
4695bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4698 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4704 return validateFlatOffset(Inst, Operands);
4707 return validateSMEMOffset(Inst, Operands);
4713 const unsigned OffsetSize = 24;
4714 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4715 Error(getFlatOffsetLoc(Operands),
4716 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4717 "-bit unsigned offset for buffer ops");
4721 const unsigned OffsetSize = 16;
4722 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4723 Error(getFlatOffsetLoc(Operands),
4724 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4731bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4738 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4742 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4743 Error(getFlatOffsetLoc(Operands),
4744 "flat offset modifier is not supported on this GPU");
4751 bool AllowNegative =
4754 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4755 Error(getFlatOffsetLoc(Operands),
4756 Twine(
"expected a ") +
4757 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4758 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4765SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4767 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4768 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4769 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4770 return Op.getStartLoc();
4775bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4785 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4799 Error(getSMEMOffsetLoc(Operands),
4801 ?
"expected a 23-bit unsigned offset for buffer ops"
4802 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4803 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4804 :
"expected a 21-bit signed offset");
4809bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4812 const MCInstrDesc &
Desc = MII.
get(Opcode);
4816 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4817 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4819 const int OpIndices[] = { Src0Idx, Src1Idx };
4821 unsigned NumExprs = 0;
4822 unsigned NumLiterals = 0;
4825 for (
int OpIdx : OpIndices) {
4826 if (
OpIdx == -1)
break;
4832 std::optional<int64_t>
Imm;
4835 }
else if (MO.
isExpr()) {
4844 if (!
Imm.has_value()) {
4846 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4850 if (NumLiterals == 0 || LiteralValue !=
Value) {
4858 if (NumLiterals + NumExprs <= 1)
4861 Error(getOperandLoc(Operands, Src1Idx),
4862 "only one unique literal operand is allowed");
4866bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4869 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4879 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4880 if (OpSelIdx != -1) {
4884 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4885 if (OpSelHiIdx != -1) {
4894 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4904 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4905 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4906 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4907 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4909 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4910 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4916 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4918 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4928 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4929 if (Src2Idx != -1) {
4930 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4940bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4941 if (!hasTrue16Insts())
4943 const MCRegisterInfo *
MRI = getMRI();
4945 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4951 if (OpSelOpValue == 0)
4953 unsigned OpCount = 0;
4954 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4955 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4956 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4961 MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(
Op.getReg())) {
4963 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4964 if (OpSelOpIsHi != VGPRSuffixIsHi)
4973bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4974 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4987 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
4998 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4999 AMDGPU::OpName::src1_modifiers,
5000 AMDGPU::OpName::src2_modifiers};
5002 for (
unsigned i = 0; i < 3; ++i) {
5012bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5015 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5016 if (DppCtrlIdx >= 0) {
5023 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5024 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5025 :
"DP ALU dpp only supports row_newbcast");
5030 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5031 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5034 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5036 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5039 Error(getOperandLoc(Operands, Src1Idx),
5040 "invalid operand for instruction");
5044 Error(getInstLoc(Operands),
5045 "src1 immediate operand invalid for instruction");
5055bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5056 return (
Reg == AMDGPU::VCC && isWave64()) ||
5057 (
Reg == AMDGPU::VCC_LO && isWave32());
5061bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5064 const MCInstrDesc &
Desc = MII.
get(Opcode);
5065 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5067 !HasMandatoryLiteral && !
isVOPD(Opcode))
5072 std::optional<unsigned> LiteralOpIdx;
5075 for (
int OpIdx : OpIndices) {
5085 std::optional<int64_t>
Imm;
5091 bool IsAnotherLiteral =
false;
5092 if (!
Imm.has_value()) {
5094 IsAnotherLiteral =
true;
5095 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5100 HasMandatoryLiteral);
5106 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5108 "invalid operand for instruction");
5112 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5119 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5120 !getFeatureBits()[FeatureVOP3Literal]) {
5122 "literal operands are not supported");
5126 if (LiteralOpIdx && IsAnotherLiteral) {
5127 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5128 getOperandLoc(Operands, *LiteralOpIdx)),
5129 "only one unique literal operand is allowed");
5133 if (IsAnotherLiteral)
5134 LiteralOpIdx =
OpIdx;
5157bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5165 ? AMDGPU::OpName::data0
5166 : AMDGPU::OpName::vdata;
5168 const MCRegisterInfo *
MRI = getMRI();
5174 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5178 auto FB = getFeatureBits();
5179 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5180 if (DataAreg < 0 || DstAreg < 0)
5182 return DstAreg == DataAreg;
5185 return DstAreg < 1 && DataAreg < 1;
5188bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5189 auto FB = getFeatureBits();
5190 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5194 const MCRegisterInfo *
MRI = getMRI();
5197 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5200 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5204 case AMDGPU::DS_LOAD_TR6_B96:
5205 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5209 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5210 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5214 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5215 if (VAddrIdx != -1) {
5217 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5218 if ((
Sub - AMDGPU::VGPR0) & 1)
5223 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5224 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5229 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5230 const MCRegisterClass &AGPR32 =
MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
5236 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5249SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5250 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5251 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5253 return Op.getStartLoc();
5258bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5261 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5264 SMLoc BLGPLoc = getBLGPLoc(Operands);
5267 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5268 auto FB = getFeatureBits();
5269 bool UsesNeg =
false;
5270 if (FB[AMDGPU::FeatureGFX940Insts]) {
5272 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5273 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5274 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5275 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5280 if (IsNeg == UsesNeg)
5284 UsesNeg ?
"invalid modifier: blgp is not supported"
5285 :
"invalid modifier: neg is not supported");
5290bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5296 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5297 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5298 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5299 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5302 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5305 if (
Reg == AMDGPU::SGPR_NULL)
5308 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5312bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5318 return validateGWS(Inst, Operands);
5323 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5328 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5329 Error(S,
"gds modifier is not supported on this GPU");
5337bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5339 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5343 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5344 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5347 const MCRegisterInfo *
MRI = getMRI();
5348 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5350 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5353 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5355 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5362bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5365 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5366 AMDGPU::OpName::cpol);
5374 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5377 Error(S,
"scale_offset is not supported on this GPU");
5380 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5383 Error(S,
"nv is not supported on this GPU");
5388 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5391 Error(S,
"scale_offset is not supported for this instruction");
5395 return validateTHAndScopeBits(Inst, Operands, CPol);
5400 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5401 Error(S,
"cache policy is not supported for SMRD instructions");
5405 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5414 if (!(TSFlags & AllowSCCModifier)) {
5415 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5419 "scc modifier is not supported for this instruction on this GPU");
5430 :
"instruction must use glc");
5435 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5438 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5440 :
"instruction must not use glc");
5448bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5450 const unsigned CPol) {
5454 const unsigned Opcode = Inst.
getOpcode();
5455 const MCInstrDesc &TID = MII.
get(Opcode);
5458 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5466 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5474 return PrintError(
"invalid th value for SMEM instruction");
5481 return PrintError(
"scope and th combination is not valid");
5487 return PrintError(
"invalid th value for atomic instructions");
5490 return PrintError(
"invalid th value for store instructions");
5493 return PrintError(
"invalid th value for load instructions");
5499bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5502 if (
Desc.mayStore() &&
5504 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5505 if (Loc != getInstLoc(Operands)) {
5506 Error(Loc,
"TFE modifier has no meaning for store instructions");
5514bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5520 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5521 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5525 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5533 static const char *FmtNames[] = {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
5534 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
5537 Error(getOperandLoc(Operands, SrcIdx),
5538 "wrong register tuple size for " + Twine(FmtNames[Fmt]));
5542 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5543 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5546bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5548 if (!validateLdsDirect(Inst, Operands))
5550 if (!validateTrue16OpSel(Inst)) {
5551 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5552 "op_sel operand conflicts with 16-bit operand suffix");
5555 if (!validateSOPLiteral(Inst, Operands))
5557 if (!validateVOPLiteral(Inst, Operands)) {
5560 if (!validateConstantBusLimitations(Inst, Operands)) {
5563 if (!validateVOPD(Inst, Operands)) {
5566 if (!validateIntClampSupported(Inst)) {
5567 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5568 "integer clamping is not supported on this GPU");
5571 if (!validateOpSel(Inst)) {
5572 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5573 "invalid op_sel operand");
5576 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5577 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5578 "invalid neg_lo operand");
5581 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5582 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5583 "invalid neg_hi operand");
5586 if (!validateDPP(Inst, Operands)) {
5590 if (!validateMIMGD16(Inst)) {
5591 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5592 "d16 modifier is not supported on this GPU");
5595 if (!validateMIMGDim(Inst, Operands)) {
5596 Error(IDLoc,
"missing dim operand");
5599 if (!validateTensorR128(Inst)) {
5600 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5601 "instruction must set modifier r128=0");
5604 if (!validateMIMGMSAA(Inst)) {
5605 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5606 "invalid dim; must be MSAA type");
5609 if (!validateMIMGDataSize(Inst, IDLoc)) {
5612 if (!validateMIMGAddrSize(Inst, IDLoc))
5614 if (!validateMIMGAtomicDMask(Inst)) {
5615 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5616 "invalid atomic image dmask");
5619 if (!validateMIMGGatherDMask(Inst)) {
5620 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5621 "invalid image_gather dmask: only one bit must be set");
5624 if (!validateMovrels(Inst, Operands)) {
5627 if (!validateOffset(Inst, Operands)) {
5630 if (!validateMAIAccWrite(Inst, Operands)) {
5633 if (!validateMAISrc2(Inst, Operands)) {
5636 if (!validateMFMA(Inst, Operands)) {
5639 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5643 if (!validateAGPRLdSt(Inst)) {
5644 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5645 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5646 :
"invalid register class: agpr loads and stores not supported on this GPU"
5650 if (!validateVGPRAlign(Inst)) {
5652 "invalid register class: vgpr tuples must be 64 bit aligned");
5655 if (!validateDS(Inst, Operands)) {
5659 if (!validateBLGP(Inst, Operands)) {
5663 if (!validateDivScale(Inst)) {
5664 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5667 if (!validateWaitCnt(Inst, Operands)) {
5670 if (!validateTFE(Inst, Operands)) {
5673 if (!validateWMMA(Inst, Operands)) {
5682 unsigned VariantID = 0);
5686 unsigned VariantID);
5688bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5693bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5694 const FeatureBitset &FBS,
5695 ArrayRef<unsigned> Variants) {
5696 for (
auto Variant : Variants) {
5704bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5706 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5709 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5714 getParser().clearPendingErrors();
5718 StringRef VariantName = getMatchedVariantName();
5719 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5722 " variant of this instruction is not supported"));
5726 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5727 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5729 FeatureBitset FeaturesWS32 = getFeatureBits();
5730 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5731 .
flip(AMDGPU::FeatureWavefrontSize32);
5732 FeatureBitset AvailableFeaturesWS32 =
5733 ComputeAvailableFeatures(FeaturesWS32);
5735 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5736 return Error(IDLoc,
"instruction requires wavesize=32");
5740 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5741 return Error(IDLoc,
"instruction not supported on this GPU");
5746 return Error(IDLoc,
"invalid instruction" + Suggestion);
5752 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5753 if (
Op.isToken() && InvalidOprIdx > 1) {
5754 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5755 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5760bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5763 uint64_t &ErrorInfo,
5764 bool MatchingInlineAsm) {
5767 unsigned Result = Match_Success;
5768 for (
auto Variant : getMatchedVariants()) {
5770 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5775 if (R == Match_Success || R == Match_MissingFeature ||
5776 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5777 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5778 Result != Match_MissingFeature)) {
5782 if (R == Match_Success)
5786 if (Result == Match_Success) {
5787 if (!validateInstruction(Inst, IDLoc, Operands)) {
5794 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5795 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5801 case Match_MissingFeature:
5805 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5807 case Match_InvalidOperand: {
5808 SMLoc ErrorLoc = IDLoc;
5809 if (ErrorInfo != ~0ULL) {
5810 if (ErrorInfo >= Operands.
size()) {
5811 return Error(IDLoc,
"too few operands for instruction");
5813 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5814 if (ErrorLoc == SMLoc())
5818 return Error(ErrorLoc,
"invalid VOPDY instruction");
5820 return Error(ErrorLoc,
"invalid operand for instruction");
5823 case Match_MnemonicFail:
5829bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5834 if (getParser().parseAbsoluteExpression(Tmp)) {
5837 Ret =
static_cast<uint32_t
>(Tmp);
5841bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5842 if (!getSTI().getTargetTriple().isAMDGCN())
5843 return TokError(
"directive only supported for amdgcn architecture");
5845 std::string TargetIDDirective;
5846 SMLoc TargetStart = getTok().getLoc();
5847 if (getParser().parseEscapedString(TargetIDDirective))
5850 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5851 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5852 return getParser().Error(TargetRange.
Start,
5853 (Twine(
".amdgcn_target directive's target id ") +
5854 Twine(TargetIDDirective) +
5855 Twine(
" does not match the specified target id ") +
5856 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5861bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5865bool AMDGPUAsmParser::calculateGPRBlocks(
5866 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5867 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5868 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5869 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5870 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5876 const MCExpr *
NumSGPRs = NextFreeSGPR;
5877 int64_t EvaluatedSGPRs;
5882 unsigned MaxAddressableNumSGPRs =
5885 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5886 !Features.
test(FeatureSGPRInitBug) &&
5887 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5888 return OutOfRangeError(SGPRRange);
5890 const MCExpr *ExtraSGPRs =
5894 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5895 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5896 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5897 return OutOfRangeError(SGPRRange);
5899 if (Features.
test(FeatureSGPRInitBug))
5906 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5907 unsigned Granule) ->
const MCExpr * {
5911 const MCExpr *AlignToGPR =
5913 const MCExpr *DivGPR =
5919 VGPRBlocks = GetNumGPRBlocks(
5928bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5929 if (!getSTI().getTargetTriple().isAMDGCN())
5930 return TokError(
"directive only supported for amdgcn architecture");
5933 return TokError(
"directive only supported for amdhsa OS");
5935 StringRef KernelName;
5936 if (getParser().parseIdentifier(KernelName))
5939 AMDGPU::MCKernelDescriptor KD =
5951 const MCExpr *NextFreeVGPR = ZeroExpr;
5953 const MCExpr *NamedBarCnt = ZeroExpr;
5954 uint64_t SharedVGPRCount = 0;
5955 uint64_t PreloadLength = 0;
5956 uint64_t PreloadOffset = 0;
5958 const MCExpr *NextFreeSGPR = ZeroExpr;
5961 unsigned ImpliedUserSGPRCount = 0;
5965 std::optional<unsigned> ExplicitUserSGPRCount;
5966 const MCExpr *ReserveVCC = OneExpr;
5967 const MCExpr *ReserveFlatScr = OneExpr;
5968 std::optional<bool> EnableWavefrontSize32;
5974 SMRange IDRange = getTok().getLocRange();
5975 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5978 if (
ID ==
".end_amdhsa_kernel")
5982 return TokError(
".amdhsa_ directives cannot be repeated");
5984 SMLoc ValStart = getLoc();
5985 const MCExpr *ExprVal;
5986 if (getParser().parseExpression(ExprVal))
5988 SMLoc ValEnd = getLoc();
5989 SMRange ValRange = SMRange(ValStart, ValEnd);
5992 uint64_t Val = IVal;
5993 bool EvaluatableExpr;
5994 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5996 return OutOfRangeError(ValRange);
6000#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6001 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6002 return OutOfRangeError(RANGE); \
6003 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6008#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6010 return Error(IDRange.Start, "directive should have resolvable expression", \
6013 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6016 return OutOfRangeError(ValRange);
6018 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6021 return OutOfRangeError(ValRange);
6023 }
else if (
ID ==
".amdhsa_kernarg_size") {
6025 return OutOfRangeError(ValRange);
6027 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6029 ExplicitUserSGPRCount = Val;
6030 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6034 "directive is not supported with architected flat scratch",
6037 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6040 ImpliedUserSGPRCount += 4;
6041 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6044 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6047 return OutOfRangeError(ValRange);
6051 ImpliedUserSGPRCount += Val;
6052 PreloadLength = Val;
6054 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6057 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6060 return OutOfRangeError(ValRange);
6064 PreloadOffset = Val;
6065 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6068 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6071 ImpliedUserSGPRCount += 2;
6072 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6075 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6078 ImpliedUserSGPRCount += 2;
6079 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6082 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6085 ImpliedUserSGPRCount += 2;
6086 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6089 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6092 ImpliedUserSGPRCount += 2;
6093 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6096 "directive is not supported with architected flat scratch",
6100 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6103 ImpliedUserSGPRCount += 2;
6104 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6107 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6110 ImpliedUserSGPRCount += 1;
6111 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6113 if (IVersion.
Major < 10)
6114 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6115 EnableWavefrontSize32 = Val;
6117 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6119 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6121 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6123 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6126 "directive is not supported with architected flat scratch",
6129 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6131 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6135 "directive is not supported without architected flat scratch",
6138 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6140 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6142 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6144 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6146 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6148 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6150 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6152 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6154 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6156 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6158 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6160 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6161 VGPRRange = ValRange;
6162 NextFreeVGPR = ExprVal;
6163 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6164 SGPRRange = ValRange;
6165 NextFreeSGPR = ExprVal;
6166 }
else if (
ID ==
".amdhsa_accum_offset") {
6168 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6169 AccumOffset = ExprVal;
6170 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6172 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6173 NamedBarCnt = ExprVal;
6174 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6176 return OutOfRangeError(ValRange);
6177 ReserveVCC = ExprVal;
6178 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6179 if (IVersion.
Major < 7)
6180 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6183 "directive is not supported with architected flat scratch",
6186 return OutOfRangeError(ValRange);
6187 ReserveFlatScr = ExprVal;
6188 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6189 if (IVersion.
Major < 8)
6190 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6192 return OutOfRangeError(ValRange);
6193 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6194 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6196 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6198 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6200 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6202 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6204 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6206 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6208 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6210 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6212 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6213 if (IVersion.
Major >= 12)
6214 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6216 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6218 }
else if (
ID ==
".amdhsa_ieee_mode") {
6219 if (IVersion.
Major >= 12)
6220 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6222 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6224 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6225 if (IVersion.
Major < 9)
6226 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6228 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6230 }
else if (
ID ==
".amdhsa_tg_split") {
6232 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6235 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6238 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6240 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6242 }
else if (
ID ==
".amdhsa_memory_ordered") {
6243 if (IVersion.
Major < 10)
6244 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6246 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6248 }
else if (
ID ==
".amdhsa_forward_progress") {
6249 if (IVersion.
Major < 10)
6250 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6252 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6254 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6256 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6257 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6259 SharedVGPRCount = Val;
6261 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6263 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6264 if (IVersion.
Major < 11)
6265 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6266 if (IVersion.
Major == 11) {
6268 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6272 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6275 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6278 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6280 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6282 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6284 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6287 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6289 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6291 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6293 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6295 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6297 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6299 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6301 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6303 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6305 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6306 if (IVersion.
Major < 12)
6307 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6309 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6312 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6315#undef PARSE_BITS_ENTRY
6318 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6319 return TokError(
".amdhsa_next_free_vgpr directive is required");
6321 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6322 return TokError(
".amdhsa_next_free_sgpr directive is required");
6324 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6329 if (PreloadLength) {
6335 const MCExpr *VGPRBlocks;
6336 const MCExpr *SGPRBlocks;
6337 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6338 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6339 EnableWavefrontSize32, NextFreeVGPR,
6340 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6344 int64_t EvaluatedVGPRBlocks;
6345 bool VGPRBlocksEvaluatable =
6346 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6347 if (VGPRBlocksEvaluatable &&
6349 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6350 return OutOfRangeError(VGPRRange);
6354 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6355 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6357 int64_t EvaluatedSGPRBlocks;
6358 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6360 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6361 return OutOfRangeError(SGPRRange);
6364 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6365 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6367 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6368 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6369 "enabled user SGPRs");
6373 return TokError(
"too many user SGPRs enabled");
6377 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6378 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6382 return TokError(
"too many user SGPRs enabled");
6386 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6387 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6392 return TokError(
"Kernarg size should be resolvable");
6393 uint64_t kernarg_size = IVal;
6394 if (PreloadLength && kernarg_size &&
6395 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6396 return TokError(
"Kernarg preload length + offset is larger than the "
6397 "kernarg segment size");
6400 if (!Seen.
contains(
".amdhsa_accum_offset"))
6401 return TokError(
".amdhsa_accum_offset directive is required");
6402 int64_t EvaluatedAccum;
6403 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6404 uint64_t UEvaluatedAccum = EvaluatedAccum;
6405 if (AccumEvaluatable &&
6406 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6407 return TokError(
"accum_offset should be in range [4..256] in "
6410 int64_t EvaluatedNumVGPR;
6411 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6414 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6415 return TokError(
"accum_offset exceeds total VGPR allocation");
6421 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6422 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6428 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6429 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6432 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6434 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6435 return TokError(
"shared_vgpr_count directive not valid on "
6436 "wavefront size 32");
6439 if (VGPRBlocksEvaluatable &&
6440 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6442 return TokError(
"shared_vgpr_count*2 + "
6443 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6448 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6449 NextFreeVGPR, NextFreeSGPR,
6450 ReserveVCC, ReserveFlatScr);
6454bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6456 if (ParseAsAbsoluteExpression(
Version))
6459 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6463bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6464 AMDGPUMCKernelCodeT &
C) {
6467 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6468 Parser.eatToEndOfStatement();
6472 SmallString<40> ErrStr;
6473 raw_svector_ostream Err(ErrStr);
6474 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6475 return TokError(Err.
str());
6479 if (
ID ==
"enable_wavefront_size32") {
6482 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6484 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6487 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6491 if (
ID ==
"wavefront_size") {
6492 if (
C.wavefront_size == 5) {
6494 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6496 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6497 }
else if (
C.wavefront_size == 6) {
6499 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6506bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6507 AMDGPUMCKernelCodeT KernelCode;
6516 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6519 if (
ID ==
".end_amd_kernel_code_t")
6522 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6527 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6532bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6533 StringRef KernelName;
6534 if (!parseId(KernelName,
"expected symbol name"))
6537 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6544bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6545 if (!getSTI().getTargetTriple().isAMDGCN()) {
6546 return Error(getLoc(),
6547 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6551 auto TargetIDDirective = getLexer().getTok().getStringContents();
6552 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6553 return Error(getParser().getTok().getLoc(),
"target id must match options");
6555 getTargetStreamer().EmitISAVersion();
6561bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6564 std::string HSAMetadataString;
6569 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6570 return Error(getLoc(),
"invalid HSA metadata");
6577bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6578 const char *AssemblerDirectiveEnd,
6579 std::string &CollectString) {
6581 raw_string_ostream CollectStream(CollectString);
6583 getLexer().setSkipSpace(
false);
6585 bool FoundEnd =
false;
6588 CollectStream << getTokenStr();
6592 if (trySkipId(AssemblerDirectiveEnd)) {
6597 CollectStream << Parser.parseStringToEndOfStatement()
6598 <<
getContext().getAsmInfo()->getSeparatorString();
6600 Parser.eatToEndOfStatement();
6603 getLexer().setSkipSpace(
true);
6606 return TokError(Twine(
"expected directive ") +
6607 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6614bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6620 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6621 if (!PALMetadata->setFromString(
String))
6622 return Error(getLoc(),
"invalid PAL metadata");
6627bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6629 return Error(getLoc(),
6631 "not available on non-amdpal OSes")).str());
6634 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6635 PALMetadata->setLegacy();
6638 if (ParseAsAbsoluteExpression(
Key)) {
6639 return TokError(Twine(
"invalid value in ") +
6643 return TokError(Twine(
"expected an even number of values in ") +
6646 if (ParseAsAbsoluteExpression(
Value)) {
6647 return TokError(Twine(
"invalid value in ") +
6650 PALMetadata->setRegister(
Key,
Value);
6659bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6660 if (getParser().checkForValidSection())
6664 SMLoc NameLoc = getLoc();
6665 if (getParser().parseIdentifier(Name))
6666 return TokError(
"expected identifier in directive");
6669 if (getParser().parseComma())
6675 SMLoc SizeLoc = getLoc();
6676 if (getParser().parseAbsoluteExpression(
Size))
6679 return Error(SizeLoc,
"size must be non-negative");
6680 if (
Size > LocalMemorySize)
6681 return Error(SizeLoc,
"size is too large");
6683 int64_t Alignment = 4;
6685 SMLoc AlignLoc = getLoc();
6686 if (getParser().parseAbsoluteExpression(Alignment))
6689 return Error(AlignLoc,
"alignment must be a power of two");
6694 if (Alignment >= 1u << 31)
6695 return Error(AlignLoc,
"alignment is too large");
6701 Symbol->redefineIfPossible();
6702 if (!
Symbol->isUndefined())
6703 return Error(NameLoc,
"invalid symbol redefinition");
6705 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6709bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6710 StringRef IDVal = DirectiveID.
getString();
6713 if (IDVal ==
".amdhsa_kernel")
6714 return ParseDirectiveAMDHSAKernel();
6716 if (IDVal ==
".amdhsa_code_object_version")
6717 return ParseDirectiveAMDHSACodeObjectVersion();
6721 return ParseDirectiveHSAMetadata();
6723 if (IDVal ==
".amd_kernel_code_t")
6724 return ParseDirectiveAMDKernelCodeT();
6726 if (IDVal ==
".amdgpu_hsa_kernel")
6727 return ParseDirectiveAMDGPUHsaKernel();
6729 if (IDVal ==
".amd_amdgpu_isa")
6730 return ParseDirectiveISAVersion();
6734 Twine(
" directive is "
6735 "not available on non-amdhsa OSes"))
6740 if (IDVal ==
".amdgcn_target")
6741 return ParseDirectiveAMDGCNTarget();
6743 if (IDVal ==
".amdgpu_lds")
6744 return ParseDirectiveAMDGPULDS();
6747 return ParseDirectivePALMetadataBegin();
6750 return ParseDirectivePALMetadata();
6755bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
6757 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
6761 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
6762 return hasSGPR104_SGPR105();
6765 case SRC_SHARED_BASE_LO:
6766 case SRC_SHARED_BASE:
6767 case SRC_SHARED_LIMIT_LO:
6768 case SRC_SHARED_LIMIT:
6769 case SRC_PRIVATE_BASE_LO:
6770 case SRC_PRIVATE_BASE:
6771 case SRC_PRIVATE_LIMIT_LO:
6772 case SRC_PRIVATE_LIMIT:
6774 case SRC_FLAT_SCRATCH_BASE_LO:
6775 case SRC_FLAT_SCRATCH_BASE_HI:
6776 return hasGloballyAddressableScratch();
6777 case SRC_POPS_EXITING_WAVE_ID:
6789 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6818 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
6819 return hasSGPR102_SGPR103();
6824ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6827 ParseStatus Res = parseVOPD(Operands);
6832 Res = MatchOperandParserImpl(Operands, Mnemonic);
6844 SMLoc LBraceLoc = getLoc();
6849 auto Loc = getLoc();
6850 Res = parseReg(Operands);
6852 Error(Loc,
"expected a register");
6856 RBraceLoc = getLoc();
6861 "expected a comma or a closing square bracket"))
6865 if (Operands.
size() - Prefix > 1) {
6867 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6868 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6874 return parseRegOrImm(Operands);
6877StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6879 setForcedEncodingSize(0);
6880 setForcedDPP(
false);
6881 setForcedSDWA(
false);
6883 if (
Name.consume_back(
"_e64_dpp")) {
6885 setForcedEncodingSize(64);
6888 if (
Name.consume_back(
"_e64")) {
6889 setForcedEncodingSize(64);
6892 if (
Name.consume_back(
"_e32")) {
6893 setForcedEncodingSize(32);
6896 if (
Name.consume_back(
"_dpp")) {
6900 if (
Name.consume_back(
"_sdwa")) {
6901 setForcedSDWA(
true);
6909 unsigned VariantID);
6915 Name = parseMnemonicSuffix(Name);
6921 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6923 bool IsMIMG = Name.starts_with(
"image_");
6926 OperandMode
Mode = OperandMode_Default;
6928 Mode = OperandMode_NSA;
6932 checkUnsupportedInstruction(Name, NameLoc);
6933 if (!Parser.hasPendingError()) {
6936 :
"not a valid operand.";
6937 Error(getLoc(), Msg);
6956ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6959 if (!trySkipId(Name))
6962 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6966ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6975ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6976 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6977 std::function<
bool(int64_t &)> ConvertResult) {
6981 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
6985 if (ConvertResult && !ConvertResult(
Value)) {
6986 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
6989 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6993ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6994 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6995 bool (*ConvertResult)(int64_t &)) {
7004 const unsigned MaxSize = 4;
7008 for (
int I = 0; ; ++
I) {
7010 SMLoc Loc = getLoc();
7014 if (
Op != 0 &&
Op != 1)
7015 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7022 if (
I + 1 == MaxSize)
7023 return Error(getLoc(),
"expected a closing square bracket");
7029 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7033ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7035 AMDGPUOperand::ImmTy ImmTy) {
7039 if (trySkipId(Name)) {
7041 }
else if (trySkipId(
"no", Name)) {
7048 return Error(S,
"r128 modifier is not supported on this GPU");
7049 if (Name ==
"a16" && !
hasA16())
7050 return Error(S,
"a16 modifier is not supported on this GPU");
7052 if (Bit == 0 && Name ==
"gds") {
7053 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7055 return Error(S,
"nogds is not allowed");
7058 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7059 ImmTy = AMDGPUOperand::ImmTyR128A16;
7061 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7065unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7066 bool &Disabling)
const {
7067 Disabling =
Id.consume_front(
"no");
7070 return StringSwitch<unsigned>(Id)
7077 return StringSwitch<unsigned>(Id)
7085ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7087 SMLoc StringLoc = getLoc();
7089 int64_t CPolVal = 0;
7098 ResTH = parseTH(Operands, TH);
7109 ResScope = parseScope(Operands, Scope);
7122 if (trySkipId(
"nv")) {
7126 }
else if (trySkipId(
"no",
"nv")) {
7133 if (trySkipId(
"scale_offset")) {
7137 }
else if (trySkipId(
"no",
"scale_offset")) {
7150 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7151 AMDGPUOperand::ImmTyCPol));
7155 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7156 SMLoc OpLoc = getLoc();
7157 unsigned Enabled = 0, Seen = 0;
7161 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7168 return Error(S,
"dlc modifier is not supported on this GPU");
7171 return Error(S,
"scc modifier is not supported on this GPU");
7174 return Error(S,
"duplicate cache policy modifier");
7186 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7190ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7195 ParseStatus Res = parseStringOrIntWithPrefix(
7196 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7205ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7210 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7214 if (
Value ==
"TH_DEFAULT")
7216 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7217 Value ==
"TH_LOAD_NT_WB") {
7218 return Error(StringLoc,
"invalid th value");
7219 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7221 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7223 }
else if (
Value.consume_front(
"TH_STORE_")) {
7226 return Error(StringLoc,
"invalid th value");
7229 if (
Value ==
"BYPASS")
7234 TH |= StringSwitch<int64_t>(
Value)
7244 .Default(0xffffffff);
7246 TH |= StringSwitch<int64_t>(
Value)
7257 .Default(0xffffffff);
7260 if (TH == 0xffffffff)
7261 return Error(StringLoc,
"invalid th value");
7268 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7269 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7270 std::optional<unsigned> InsertAt = std::nullopt) {
7271 auto i = OptionalIdx.find(ImmT);
7272 if (i != OptionalIdx.end()) {
7273 unsigned Idx = i->second;
7274 const AMDGPUOperand &
Op =
7275 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7279 Op.addImmOperands(Inst, 1);
7281 if (InsertAt.has_value())
7288ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7294 StringLoc = getLoc();
7299ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7300 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7305 SMLoc StringLoc = getLoc();
7309 Value = getTokenStr();
7313 if (
Value == Ids[IntVal])
7318 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7319 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7324ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7325 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7326 AMDGPUOperand::ImmTy
Type) {
7330 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7332 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7341bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7345 SMLoc Loc = getLoc();
7347 auto Res = parseIntWithPrefix(Pref, Val);
7353 if (Val < 0 || Val > MaxVal) {
7354 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7362ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7363 AMDGPUOperand::ImmTy ImmTy) {
7364 const char *Pref =
"index_key";
7366 SMLoc Loc = getLoc();
7367 auto Res = parseIntWithPrefix(Pref, ImmVal);
7371 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7372 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7373 (ImmVal < 0 || ImmVal > 1))
7374 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7376 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7377 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7379 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7383ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7384 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7387ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7388 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7391ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7392 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7395ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7397 AMDGPUOperand::ImmTy
Type) {
7398 return parseStringOrIntWithPrefix(Operands, Name,
7399 {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
7400 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
7405ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7406 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7407 AMDGPUOperand::ImmTyMatrixAFMT);
7410ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7411 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7412 AMDGPUOperand::ImmTyMatrixBFMT);
7415ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7417 AMDGPUOperand::ImmTy
Type) {
7418 return parseStringOrIntWithPrefix(
7419 Operands, Name, {
"MATRIX_SCALE_ROW0",
"MATRIX_SCALE_ROW1"},
Type);
7422ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7423 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7424 AMDGPUOperand::ImmTyMatrixAScale);
7427ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7428 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7429 AMDGPUOperand::ImmTyMatrixBScale);
7432ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7434 AMDGPUOperand::ImmTy
Type) {
7435 return parseStringOrIntWithPrefix(
7437 {
"MATRIX_SCALE_FMT_E8",
"MATRIX_SCALE_FMT_E5M3",
"MATRIX_SCALE_FMT_E4M3"},
7441ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7442 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7443 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7446ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7447 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7448 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7453ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7454 using namespace llvm::AMDGPU::MTBUFFormat;
7460 for (
int I = 0;
I < 2; ++
I) {
7461 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7464 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7469 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7475 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7478 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7479 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7485ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7486 using namespace llvm::AMDGPU::MTBUFFormat;
7490 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7493 if (Fmt == UFMT_UNDEF)
7500bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7502 StringRef FormatStr,
7504 using namespace llvm::AMDGPU::MTBUFFormat;
7508 if (
Format != DFMT_UNDEF) {
7514 if (
Format != NFMT_UNDEF) {
7519 Error(Loc,
"unsupported format");
7523ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7526 using namespace llvm::AMDGPU::MTBUFFormat;
7530 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7535 SMLoc Loc = getLoc();
7536 if (!parseId(Str,
"expected a format string") ||
7537 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7539 if (Dfmt == DFMT_UNDEF)
7540 return Error(Loc,
"duplicate numeric format");
7541 if (Nfmt == NFMT_UNDEF)
7542 return Error(Loc,
"duplicate data format");
7545 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7546 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7550 if (Ufmt == UFMT_UNDEF)
7551 return Error(FormatLoc,
"unsupported format");
7560ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7563 using namespace llvm::AMDGPU::MTBUFFormat;
7566 if (Id == UFMT_UNDEF)
7570 return Error(Loc,
"unified format is not supported on this GPU");
7576ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7577 using namespace llvm::AMDGPU::MTBUFFormat;
7578 SMLoc Loc = getLoc();
7583 return Error(Loc,
"out of range format");
7588ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7589 using namespace llvm::AMDGPU::MTBUFFormat;
7595 StringRef FormatStr;
7596 SMLoc Loc = getLoc();
7597 if (!parseId(FormatStr,
"expected a format string"))
7600 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7602 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7612 return parseNumericFormat(
Format);
7615ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7616 using namespace llvm::AMDGPU::MTBUFFormat;
7620 SMLoc Loc = getLoc();
7630 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7642 Res = parseRegOrImm(Operands);
7649 Res = parseSymbolicOrNumericFormat(
Format);
7654 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7655 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7662 return Error(getLoc(),
"duplicate format");
7666ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7668 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7670 Res = parseIntWithPrefix(
"inst_offset", Operands,
7671 AMDGPUOperand::ImmTyInstOffset);
7676ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7678 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7680 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7684ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7686 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7689 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7698void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7699 OptionalImmIndexMap OptionalIdx;
7701 unsigned OperandIdx[4];
7702 unsigned EnMask = 0;
7705 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7706 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7711 OperandIdx[SrcIdx] = Inst.
size();
7712 Op.addRegOperands(Inst, 1);
7719 OperandIdx[SrcIdx] = Inst.
size();
7725 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7726 Op.addImmOperands(Inst, 1);
7730 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7734 OptionalIdx[
Op.getImmTy()] = i;
7740 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7747 for (
auto i = 0; i < SrcIdx; ++i) {
7749 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7774 IntVal =
encode(ISA, IntVal, CntVal);
7775 if (CntVal !=
decode(ISA, IntVal)) {
7777 IntVal =
encode(ISA, IntVal, -1);
7785bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7787 SMLoc CntLoc = getLoc();
7788 StringRef CntName = getTokenStr();
7795 SMLoc ValLoc = getLoc();
7804 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7806 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7808 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7811 Error(CntLoc,
"invalid counter name " + CntName);
7816 Error(ValLoc,
"too large value for " + CntName);
7825 Error(getLoc(),
"expected a counter name");
7833ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7840 if (!parseCnt(Waitcnt))
7848 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7852bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7853 SMLoc FieldLoc = getLoc();
7854 StringRef FieldName = getTokenStr();
7859 SMLoc ValueLoc = getLoc();
7866 if (FieldName ==
"instid0") {
7868 }
else if (FieldName ==
"instskip") {
7870 }
else if (FieldName ==
"instid1") {
7873 Error(FieldLoc,
"invalid field name " + FieldName);
7892 .Case(
"VALU_DEP_1", 1)
7893 .Case(
"VALU_DEP_2", 2)
7894 .Case(
"VALU_DEP_3", 3)
7895 .Case(
"VALU_DEP_4", 4)
7896 .Case(
"TRANS32_DEP_1", 5)
7897 .Case(
"TRANS32_DEP_2", 6)
7898 .Case(
"TRANS32_DEP_3", 7)
7899 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7900 .Case(
"SALU_CYCLE_1", 9)
7901 .Case(
"SALU_CYCLE_2", 10)
7902 .Case(
"SALU_CYCLE_3", 11)
7910 Delay |=
Value << Shift;
7914ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7920 if (!parseDelay(Delay))
7928 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7933AMDGPUOperand::isSWaitCnt()
const {
7937bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7943void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7944 StringRef DepCtrName) {
7947 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7950 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7953 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7956 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7963bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7965 using namespace llvm::AMDGPU::DepCtr;
7967 SMLoc DepCtrLoc = getLoc();
7968 StringRef DepCtrName = getTokenStr();
7978 unsigned PrevOprMask = UsedOprMask;
7979 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7982 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7991 Error(getLoc(),
"expected a counter name");
7996 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7997 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8001ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
8002 using namespace llvm::AMDGPU::DepCtr;
8005 SMLoc Loc = getLoc();
8008 unsigned UsedOprMask = 0;
8010 if (!parseDepCtr(DepCtr, UsedOprMask))
8018 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8022bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8028ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8030 OperandInfoTy &Width) {
8031 using namespace llvm::AMDGPU::Hwreg;
8037 HwReg.Loc = getLoc();
8040 HwReg.IsSymbolic =
true;
8042 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8050 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8060 Width.Loc = getLoc();
8068ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8069 using namespace llvm::AMDGPU::Hwreg;
8072 SMLoc Loc = getLoc();
8074 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8076 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8077 HwregOffset::Default);
8078 struct : StructuredOpField {
8079 using StructuredOpField::StructuredOpField;
8080 bool validate(AMDGPUAsmParser &Parser)
const override {
8082 return Error(Parser,
"only values from 1 to 32 are legal");
8085 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8086 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8089 Res = parseHwregFunc(HwReg,
Offset, Width);
8092 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8094 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8098 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8105 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8107 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8111bool AMDGPUOperand::isHwreg()
const {
8112 return isImmTy(ImmTyHwreg);
8120AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8122 OperandInfoTy &Stream) {
8123 using namespace llvm::AMDGPU::SendMsg;
8128 Msg.IsSymbolic =
true;
8130 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8135 Op.IsDefined =
true;
8138 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8141 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8146 Stream.IsDefined =
true;
8147 Stream.Loc = getLoc();
8157AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8158 const OperandInfoTy &
Op,
8159 const OperandInfoTy &Stream) {
8160 using namespace llvm::AMDGPU::SendMsg;
8165 bool Strict = Msg.IsSymbolic;
8169 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8174 Error(Msg.Loc,
"invalid message id");
8180 Error(
Op.Loc,
"message does not support operations");
8182 Error(Msg.Loc,
"missing message operation");
8188 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8190 Error(
Op.Loc,
"invalid operation id");
8195 Error(Stream.Loc,
"message operation does not support streams");
8199 Error(Stream.Loc,
"invalid message stream id");
8205ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8206 using namespace llvm::AMDGPU::SendMsg;
8209 SMLoc Loc = getLoc();
8213 OperandInfoTy
Op(OP_NONE_);
8214 OperandInfoTy Stream(STREAM_ID_NONE_);
8215 if (parseSendMsgBody(Msg,
Op, Stream) &&
8216 validateSendMsg(Msg,
Op, Stream)) {
8221 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8223 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8228 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8232bool AMDGPUOperand::isSendMsg()
const {
8233 return isImmTy(ImmTySendMsg);
8240ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8247 int Slot = StringSwitch<int>(Str)
8254 return Error(S,
"invalid interpolation slot");
8256 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8257 AMDGPUOperand::ImmTyInterpSlot));
8261ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8268 if (!Str.starts_with(
"attr"))
8269 return Error(S,
"invalid interpolation attribute");
8271 StringRef Chan = Str.take_back(2);
8272 int AttrChan = StringSwitch<int>(Chan)
8279 return Error(S,
"invalid or missing interpolation attribute channel");
8281 Str = Str.drop_back(2).drop_front(4);
8284 if (Str.getAsInteger(10, Attr))
8285 return Error(S,
"invalid or missing interpolation attribute number");
8288 return Error(S,
"out of bounds interpolation attribute number");
8292 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8293 AMDGPUOperand::ImmTyInterpAttr));
8294 Operands.
push_back(AMDGPUOperand::CreateImm(
8295 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8303ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8304 using namespace llvm::AMDGPU::Exp;
8314 return Error(S, (Id == ET_INVALID)
8315 ?
"invalid exp target"
8316 :
"exp target is not supported on this GPU");
8318 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8319 AMDGPUOperand::ImmTyExpTgt));
8328AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8333AMDGPUAsmParser::isId(
const StringRef Id)
const {
8339 return getTokenKind() ==
Kind;
8342StringRef AMDGPUAsmParser::getId()
const {
8347AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8356AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8358 StringRef Tok = getTokenStr();
8369 if (isId(Id) && peekToken().is(Kind)) {
8379 if (isToken(Kind)) {
8388 const StringRef ErrMsg) {
8389 if (!trySkipToken(Kind)) {
8390 Error(getLoc(), ErrMsg);
8397AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8401 if (Parser.parseExpression(Expr))
8404 if (Expr->evaluateAsAbsolute(
Imm))
8407 if (Expected.empty()) {
8408 Error(S,
"expected absolute expression");
8410 Error(S, Twine(
"expected ", Expected) +
8411 Twine(
" or an absolute expression"));
8421 if (Parser.parseExpression(Expr))
8425 if (Expr->evaluateAsAbsolute(IntVal)) {
8426 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8428 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8434AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8436 Val =
getToken().getStringContents();
8440 Error(getLoc(), ErrMsg);
8445AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8447 Val = getTokenStr();
8451 if (!ErrMsg.
empty())
8452 Error(getLoc(), ErrMsg);
8457AMDGPUAsmParser::getToken()
const {
8458 return Parser.getTok();
8461AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8464 : getLexer().peekTok(ShouldSkipSpace);
8469 auto TokCount = getLexer().peekTokens(Tokens);
8471 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8476AMDGPUAsmParser::getTokenKind()
const {
8477 return getLexer().getKind();
8481AMDGPUAsmParser::getLoc()
const {
8486AMDGPUAsmParser::getTokenStr()
const {
8491AMDGPUAsmParser::lex() {
8495SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8496 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8500SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8504SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8505 int MCOpIdx)
const {
8506 for (
const auto &
Op : Operands) {
8507 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8508 if (TargetOp.getMCOpIdx() == MCOpIdx)
8509 return TargetOp.getStartLoc();
8515AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8517 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8518 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8520 return Op.getStartLoc();
8522 return getInstLoc(Operands);
8526AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8528 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8529 return getOperandLoc(
Test, Operands);
8543 StringRef
Id = getTokenStr();
8544 SMLoc IdLoc = getLoc();
8550 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8551 if (
I == Fields.
end())
8552 return Error(IdLoc,
"unknown field");
8553 if ((*I)->IsDefined)
8554 return Error(IdLoc,
"duplicate field");
8557 (*I)->Loc = getLoc();
8560 (*I)->IsDefined =
true;
8567bool AMDGPUAsmParser::validateStructuredOpFields(
8569 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8570 return F->validate(*
this);
8581 const unsigned OrMask,
8582 const unsigned XorMask) {
8591bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8592 const unsigned MaxVal,
8593 const Twine &ErrMsg, SMLoc &Loc) {
8610AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8611 const unsigned MinVal,
8612 const unsigned MaxVal,
8613 const StringRef ErrMsg) {
8615 for (
unsigned i = 0; i < OpNum; ++i) {
8616 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8624AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8625 using namespace llvm::AMDGPU::Swizzle;
8628 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8629 "expected a 2-bit lane id")) {
8640AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8641 using namespace llvm::AMDGPU::Swizzle;
8647 if (!parseSwizzleOperand(GroupSize,
8649 "group size must be in the interval [2,32]",
8654 Error(Loc,
"group size must be a power of two");
8657 if (parseSwizzleOperand(LaneIdx,
8659 "lane id must be in the interval [0,group size - 1]",
8668AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8669 using namespace llvm::AMDGPU::Swizzle;
8674 if (!parseSwizzleOperand(GroupSize,
8676 "group size must be in the interval [2,32]",
8681 Error(Loc,
"group size must be a power of two");
8690AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8691 using namespace llvm::AMDGPU::Swizzle;
8696 if (!parseSwizzleOperand(GroupSize,
8698 "group size must be in the interval [1,16]",
8703 Error(Loc,
"group size must be a power of two");
8712AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8713 using namespace llvm::AMDGPU::Swizzle;
8720 SMLoc StrLoc = getLoc();
8721 if (!parseString(Ctl)) {
8724 if (Ctl.
size() != BITMASK_WIDTH) {
8725 Error(StrLoc,
"expected a 5-character mask");
8729 unsigned AndMask = 0;
8730 unsigned OrMask = 0;
8731 unsigned XorMask = 0;
8733 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8737 Error(StrLoc,
"invalid mask");
8758bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8759 using namespace llvm::AMDGPU::Swizzle;
8762 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8768 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8769 "FFT swizzle must be in the interval [0," +
8770 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8778bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8779 using namespace llvm::AMDGPU::Swizzle;
8782 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8789 if (!parseSwizzleOperand(
Direction, 0, 1,
8790 "direction must be 0 (left) or 1 (right)", Loc))
8794 if (!parseSwizzleOperand(
8795 RotateSize, 0, ROTATE_MAX_SIZE,
8796 "number of threads to rotate must be in the interval [0," +
8797 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8802 (RotateSize << ROTATE_SIZE_SHIFT);
8807AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8809 SMLoc OffsetLoc = getLoc();
8815 Error(OffsetLoc,
"expected a 16-bit offset");
8822AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8823 using namespace llvm::AMDGPU::Swizzle;
8827 SMLoc ModeLoc = getLoc();
8830 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8831 Ok = parseSwizzleQuadPerm(
Imm);
8832 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8833 Ok = parseSwizzleBitmaskPerm(
Imm);
8834 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8835 Ok = parseSwizzleBroadcast(
Imm);
8836 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8837 Ok = parseSwizzleSwap(
Imm);
8838 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8839 Ok = parseSwizzleReverse(
Imm);
8840 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8841 Ok = parseSwizzleFFT(
Imm);
8842 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8843 Ok = parseSwizzleRotate(
Imm);
8845 Error(ModeLoc,
"expected a swizzle mode");
8848 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8854ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8858 if (trySkipId(
"offset")) {
8862 if (trySkipId(
"swizzle")) {
8863 Ok = parseSwizzleMacro(
Imm);
8865 Ok = parseSwizzleOffset(
Imm);
8869 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8877AMDGPUOperand::isSwizzle()
const {
8878 return isImmTy(ImmTySwizzle);
8885int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8887 using namespace llvm::AMDGPU::VGPRIndexMode;
8899 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8900 if (trySkipId(IdSymbolic[ModeId])) {
8908 "expected a VGPR index mode or a closing parenthesis" :
8909 "expected a VGPR index mode");
8914 Error(S,
"duplicate VGPR index mode");
8922 "expected a comma or a closing parenthesis"))
8929ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8931 using namespace llvm::AMDGPU::VGPRIndexMode;
8937 Imm = parseGPRIdxMacro();
8941 if (getParser().parseAbsoluteExpression(
Imm))
8944 return Error(S,
"invalid immediate: only 4-bit values are legal");
8948 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8952bool AMDGPUOperand::isGPRIdxMode()
const {
8953 return isImmTy(ImmTyGprIdxMode);
8960ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
8965 if (isRegister() || isModifier())
8971 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
8972 assert(Opr.isImm() || Opr.isExpr());
8973 SMLoc Loc = Opr.getStartLoc();
8977 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8978 Error(Loc,
"expected an absolute expression or a label");
8979 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8980 Error(Loc,
"expected a 16-bit signed jump offset");
8990ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
8991 return parseReg(Operands);
8998void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
9001 OptionalImmIndexMap OptionalIdx;
9002 unsigned FirstOperandIdx = 1;
9003 bool IsAtomicReturn =
false;
9010 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9011 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9015 Op.addRegOperands(Inst, 1);
9019 if (IsAtomicReturn && i == FirstOperandIdx)
9020 Op.addRegOperands(Inst, 1);
9025 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9026 Op.addImmOperands(Inst, 1);
9038 OptionalIdx[
Op.getImmTy()] = i;
9052bool AMDGPUOperand::isSMRDOffset8()
const {
9056bool AMDGPUOperand::isSMEMOffset()
const {
9058 return isImmLiteral();
9061bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9096bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9097 if (BoundCtrl == 0 || BoundCtrl == 1) {
9105void AMDGPUAsmParser::onBeginOfFile() {
9106 if (!getParser().getStreamer().getTargetStreamer() ||
9110 if (!getTargetStreamer().getTargetID())
9111 getTargetStreamer().initializeTargetID(getSTI(),
9112 getSTI().getFeatureString());
9115 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9123bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9127 StringRef TokenId = getTokenStr();
9128 AGVK VK = StringSwitch<AGVK>(TokenId)
9129 .Case(
"max", AGVK::AGVK_Max)
9130 .Case(
"or", AGVK::AGVK_Or)
9131 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9132 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9133 .Case(
"alignto", AGVK::AGVK_AlignTo)
9134 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9135 .Default(AGVK::AGVK_None);
9139 uint64_t CommaCount = 0;
9144 if (Exprs.
empty()) {
9146 "empty " + Twine(TokenId) +
" expression");
9149 if (CommaCount + 1 != Exprs.
size()) {
9151 "mismatch of commas in " + Twine(TokenId) +
" expression");
9158 if (getParser().parseExpression(Expr, EndLoc))
9162 if (LastTokenWasComma)
9166 "unexpected token in " + Twine(TokenId) +
" expression");
9172 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9175ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9176 StringRef
Name = getTokenStr();
9177 if (Name ==
"mul") {
9178 return parseIntWithPrefix(
"mul", Operands,
9182 if (Name ==
"div") {
9183 return parseIntWithPrefix(
"div", Operands,
9194 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9199 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9200 AMDGPU::OpName::src2};
9208 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9213 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9215 if (
DstOp.isReg() &&
9216 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9220 if ((OpSel & (1 << SrcNum)) != 0)
9226void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9228 cvtVOP3P(Inst, Operands);
9232void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9233 OptionalImmIndexMap &OptionalIdx) {
9234 cvtVOP3P(Inst, Operands, OptionalIdx);
9243 &&
Desc.NumOperands > (OpNum + 1)
9245 &&
Desc.operands()[OpNum + 1].RegClass != -1
9247 &&
Desc.getOperandConstraint(OpNum + 1,
9251void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9253 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9254 AMDGPU::OpName::src2};
9255 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9256 AMDGPU::OpName::src1_modifiers,
9257 AMDGPU::OpName::src2_modifiers};
9258 for (
int J = 0; J < 3; ++J) {
9259 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9265 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9268 if ((OpSel & (1 << J)) != 0)
9271 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9278void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9280 OptionalImmIndexMap OptionalIdx;
9285 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9286 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9289 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9290 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9292 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9293 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9294 Op.isInterpAttrChan()) {
9296 }
else if (
Op.isImmModifier()) {
9297 OptionalIdx[
Op.getImmTy()] =
I;
9305 AMDGPUOperand::ImmTyHigh);
9309 AMDGPUOperand::ImmTyClamp);
9313 AMDGPUOperand::ImmTyOModSI);
9318 AMDGPUOperand::ImmTyOpSel);
9319 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9322 cvtOpSelHelper(Inst, OpSel);
9326void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9328 OptionalImmIndexMap OptionalIdx;
9333 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9334 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9337 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9338 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9340 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9341 }
else if (
Op.isImmModifier()) {
9342 OptionalIdx[
Op.getImmTy()] =
I;
9350 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9360 cvtOpSelHelper(Inst, OpSel);
9363void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9365 OptionalImmIndexMap OptionalIdx;
9368 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9372 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9373 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9375 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9376 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9381 if (NumOperands == CbszOpIdx) {
9386 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9387 }
else if (
Op.isImmModifier()) {
9388 OptionalIdx[
Op.getImmTy()] =
I;
9390 Op.addRegOrImmOperands(Inst, 1);
9395 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9396 if (CbszIdx != OptionalIdx.end()) {
9397 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9401 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9402 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9403 if (BlgpIdx != OptionalIdx.end()) {
9404 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9415 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9416 if (OpselIdx != OptionalIdx.end()) {
9417 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9421 unsigned OpSelHi = 0;
9422 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9423 if (OpselHiIdx != OptionalIdx.end()) {
9424 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9427 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9428 AMDGPU::OpName::src1_modifiers};
9430 for (
unsigned J = 0; J < 2; ++J) {
9431 unsigned ModVal = 0;
9432 if (OpSel & (1 << J))
9434 if (OpSelHi & (1 << J))
9437 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9442void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9443 OptionalImmIndexMap &OptionalIdx) {
9448 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9449 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9452 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9453 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9455 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9456 }
else if (
Op.isImmModifier()) {
9457 OptionalIdx[
Op.getImmTy()] =
I;
9459 Op.addRegOrImmOperands(Inst, 1);
9465 AMDGPUOperand::ImmTyScaleSel);
9469 AMDGPUOperand::ImmTyClamp);
9475 AMDGPUOperand::ImmTyByteSel);
9480 AMDGPUOperand::ImmTyOModSI);
9487 auto *it = Inst.
begin();
9488 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9496void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9497 OptionalImmIndexMap OptionalIdx;
9498 cvtVOP3(Inst, Operands, OptionalIdx);
9501void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9502 OptionalImmIndexMap &OptIdx) {
9508 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9509 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9510 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9511 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9512 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9513 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9521 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9522 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9523 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9524 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9525 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9526 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9527 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9528 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9529 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9530 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9531 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9532 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9533 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9534 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9535 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9536 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9537 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9538 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9539 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9540 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9541 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9542 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9543 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9544 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9545 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9546 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9550 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9551 if (BitOp3Idx != -1) {
9558 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9559 if (OpSelIdx != -1) {
9563 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9564 if (OpSelHiIdx != -1) {
9571 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9572 if (MatrixAFMTIdx != -1) {
9574 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9578 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9579 if (MatrixBFMTIdx != -1) {
9581 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9584 int MatrixAScaleIdx =
9585 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9586 if (MatrixAScaleIdx != -1) {
9588 AMDGPUOperand::ImmTyMatrixAScale, 0);
9591 int MatrixBScaleIdx =
9592 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9593 if (MatrixBScaleIdx != -1) {
9595 AMDGPUOperand::ImmTyMatrixBScale, 0);
9598 int MatrixAScaleFmtIdx =
9599 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9600 if (MatrixAScaleFmtIdx != -1) {
9602 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9605 int MatrixBScaleFmtIdx =
9606 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9607 if (MatrixBScaleFmtIdx != -1) {
9609 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9614 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9618 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9620 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9624 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9628 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9629 AMDGPU::OpName::src2};
9630 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9631 AMDGPU::OpName::src1_modifiers,
9632 AMDGPU::OpName::src2_modifiers};
9635 unsigned OpSelHi = 0;
9642 if (OpSelHiIdx != -1)
9651 for (
int J = 0; J < 3; ++J) {
9652 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9656 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9661 uint32_t ModVal = 0;
9664 if (SrcOp.
isReg() && getMRI()
9671 if ((OpSel & (1 << J)) != 0)
9675 if ((OpSelHi & (1 << J)) != 0)
9678 if ((NegLo & (1 << J)) != 0)
9681 if ((NegHi & (1 << J)) != 0)
9688void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9689 OptionalImmIndexMap OptIdx;
9690 cvtVOP3(Inst, Operands, OptIdx);
9691 cvtVOP3P(Inst, Operands, OptIdx);
9695 unsigned i,
unsigned Opc,
9697 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9698 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9700 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9703void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9706 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9709 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9710 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9712 OptionalImmIndexMap OptIdx;
9713 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9714 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9715 OptIdx[
Op.getImmTy()] = i;
9720 AMDGPUOperand::ImmTyIndexKey8bit);
9724 AMDGPUOperand::ImmTyIndexKey16bit);
9728 AMDGPUOperand::ImmTyIndexKey32bit);
9733 cvtVOP3P(Inst, Operands, OptIdx);
9740ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9748 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9749 SMLoc OpYLoc = getLoc();
9752 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9755 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9761void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9764 auto addOp = [&](uint16_t ParsedOprIdx) {
9765 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9767 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9771 Op.addRegOperands(Inst, 1);
9775 Op.addImmOperands(Inst, 1);
9787 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9791 const auto &CInfo = InstInfo[CompIdx];
9792 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9793 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9794 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9795 if (CInfo.hasSrc2Acc())
9796 addOp(CInfo.getIndexOfDstInParsedOperands());
9800 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9801 if (BitOp3Idx != -1) {
9802 OptionalImmIndexMap OptIdx;
9803 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9805 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9815bool AMDGPUOperand::isDPP8()
const {
9816 return isImmTy(ImmTyDPP8);
9819bool AMDGPUOperand::isDPPCtrl()
const {
9820 using namespace AMDGPU::DPP;
9822 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9825 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9826 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9827 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9828 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9829 (
Imm == DppCtrl::WAVE_SHL1) ||
9830 (
Imm == DppCtrl::WAVE_ROL1) ||
9831 (
Imm == DppCtrl::WAVE_SHR1) ||
9832 (
Imm == DppCtrl::WAVE_ROR1) ||
9833 (
Imm == DppCtrl::ROW_MIRROR) ||
9834 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9835 (
Imm == DppCtrl::BCAST15) ||
9836 (
Imm == DppCtrl::BCAST31) ||
9837 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9838 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9847bool AMDGPUOperand::isBLGP()
const {
9851bool AMDGPUOperand::isS16Imm()
const {
9855bool AMDGPUOperand::isU16Imm()
const {
9863bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9868 SMLoc Loc =
getToken().getEndLoc();
9869 Token = std::string(getTokenStr());
9871 if (getLoc() != Loc)
9876 if (!parseId(Suffix))
9880 StringRef DimId = Token;
9891ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9901 SMLoc Loc = getLoc();
9902 if (!parseDimId(Encoding))
9903 return Error(Loc,
"invalid dim value");
9905 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9906 AMDGPUOperand::ImmTyDim));
9914ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
9924 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9927 for (
size_t i = 0; i < 8; ++i) {
9931 SMLoc Loc = getLoc();
9932 if (getParser().parseAbsoluteExpression(Sels[i]))
9934 if (0 > Sels[i] || 7 < Sels[i])
9935 return Error(Loc,
"expected a 3-bit value");
9942 for (
size_t i = 0; i < 8; ++i)
9943 DPP8 |= (Sels[i] << (i * 3));
9945 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9950AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
9952 if (Ctrl ==
"row_newbcast")
9955 if (Ctrl ==
"row_share" ||
9956 Ctrl ==
"row_xmask")
9959 if (Ctrl ==
"wave_shl" ||
9960 Ctrl ==
"wave_shr" ||
9961 Ctrl ==
"wave_rol" ||
9962 Ctrl ==
"wave_ror" ||
9963 Ctrl ==
"row_bcast")
9966 return Ctrl ==
"row_mirror" ||
9967 Ctrl ==
"row_half_mirror" ||
9968 Ctrl ==
"quad_perm" ||
9969 Ctrl ==
"row_shl" ||
9970 Ctrl ==
"row_shr" ||
9975AMDGPUAsmParser::parseDPPCtrlPerm() {
9978 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9982 for (
int i = 0; i < 4; ++i) {
9987 SMLoc Loc = getLoc();
9988 if (getParser().parseAbsoluteExpression(Temp))
9990 if (Temp < 0 || Temp > 3) {
9991 Error(Loc,
"expected a 2-bit value");
9995 Val += (Temp << i * 2);
10005AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10006 using namespace AMDGPU::DPP;
10011 SMLoc Loc = getLoc();
10013 if (getParser().parseAbsoluteExpression(Val))
10016 struct DppCtrlCheck {
10022 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10023 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10024 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10025 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10026 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10027 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10028 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10029 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10030 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10031 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10032 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10036 if (
Check.Ctrl == -1) {
10037 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10045 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10052ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10053 using namespace AMDGPU::DPP;
10056 !isSupportedDPPCtrl(getTokenStr(), Operands))
10059 SMLoc S = getLoc();
10065 if (Ctrl ==
"row_mirror") {
10066 Val = DppCtrl::ROW_MIRROR;
10067 }
else if (Ctrl ==
"row_half_mirror") {
10068 Val = DppCtrl::ROW_HALF_MIRROR;
10071 if (Ctrl ==
"quad_perm") {
10072 Val = parseDPPCtrlPerm();
10074 Val = parseDPPCtrlSel(Ctrl);
10083 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10087void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10089 OptionalImmIndexMap OptionalIdx;
10096 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10098 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10099 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10103 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10104 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10108 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10109 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10110 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10111 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10112 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10114 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10118 if (OldIdx == NumOperands) {
10120 constexpr int DST_IDX = 0;
10122 }
else if (Src2ModIdx == NumOperands) {
10132 if (IsVOP3CvtSrDpp) {
10141 if (TiedTo != -1) {
10146 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10148 if (IsDPP8 &&
Op.isDppFI()) {
10151 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10152 }
else if (
Op.isReg()) {
10153 Op.addRegOperands(Inst, 1);
10154 }
else if (
Op.isImm() &&
10156 Op.addImmOperands(Inst, 1);
10157 }
else if (
Op.isImm()) {
10158 OptionalIdx[
Op.getImmTy()] =
I;
10166 AMDGPUOperand::ImmTyClamp);
10172 AMDGPUOperand::ImmTyByteSel);
10179 cvtVOP3P(Inst, Operands, OptionalIdx);
10181 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10188 using namespace llvm::AMDGPU::DPP;
10198 AMDGPUOperand::ImmTyDppFI);
10202void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10203 OptionalImmIndexMap OptionalIdx;
10207 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10208 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10212 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10215 if (TiedTo != -1) {
10220 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10222 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10230 Op.addImmOperands(Inst, 1);
10232 Op.addRegWithFPInputModsOperands(Inst, 2);
10233 }
else if (
Op.isDppFI()) {
10235 }
else if (
Op.isReg()) {
10236 Op.addRegOperands(Inst, 1);
10242 Op.addRegWithFPInputModsOperands(Inst, 2);
10243 }
else if (
Op.isReg()) {
10244 Op.addRegOperands(Inst, 1);
10245 }
else if (
Op.isDPPCtrl()) {
10246 Op.addImmOperands(Inst, 1);
10247 }
else if (
Op.isImm()) {
10249 OptionalIdx[
Op.getImmTy()] =
I;
10257 using namespace llvm::AMDGPU::DPP;
10265 AMDGPUOperand::ImmTyDppFI);
10274ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10276 AMDGPUOperand::ImmTy
Type) {
10277 return parseStringOrIntWithPrefix(
10279 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10283ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10284 return parseStringOrIntWithPrefix(
10285 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10286 AMDGPUOperand::ImmTySDWADstUnused);
10289void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10293void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10297void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10301void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10305void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10309void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10310 uint64_t BasicInstType,
10313 using namespace llvm::AMDGPU::SDWA;
10315 OptionalImmIndexMap OptionalIdx;
10316 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10317 bool SkippedVcc =
false;
10321 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10322 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10325 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10326 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10327 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10328 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10346 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10347 }
else if (
Op.isImm()) {
10349 OptionalIdx[
Op.getImmTy()] =
I;
10353 SkippedVcc =
false;
10357 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10358 Opc != AMDGPU::V_NOP_sdwa_vi) {
10360 switch (BasicInstType) {
10364 AMDGPUOperand::ImmTyClamp, 0);
10368 AMDGPUOperand::ImmTyOModSI, 0);
10372 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10376 AMDGPUOperand::ImmTySDWADstUnused,
10377 DstUnused::UNUSED_PRESERVE);
10379 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10384 AMDGPUOperand::ImmTyClamp, 0);
10389 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10390 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10391 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10392 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10398 AMDGPUOperand::ImmTyClamp, 0);
10399 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10400 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10404 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10410 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10411 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10412 auto *it = Inst.
begin();
10414 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10426#define GET_MATCHER_IMPLEMENTATION
10427#define GET_MNEMONIC_SPELL_CHECKER
10428#define GET_MNEMONIC_CHECKER
10429#include "AMDGPUGenAsmMatcher.inc"
10435 return parseTokenOp(
"addr64",
Operands);
10437 return parseTokenOp(
"done",
Operands);
10439 return parseTokenOp(
"idxen",
Operands);
10441 return parseTokenOp(
"lds",
Operands);
10443 return parseTokenOp(
"offen",
Operands);
10445 return parseTokenOp(
"off",
Operands);
10446 case MCK_row_95_en:
10447 return parseTokenOp(
"row_en",
Operands);
10449 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10451 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10453 return tryCustomParseOperand(
Operands, MCK);
10458unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10464 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10467 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10469 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10471 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10473 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10475 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10477 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10485 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10487 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10488 case MCK_SOPPBrTarget:
10489 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10490 case MCK_VReg32OrOff:
10491 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10492 case MCK_InterpSlot:
10493 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10494 case MCK_InterpAttr:
10495 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10496 case MCK_InterpAttrChan:
10497 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10499 case MCK_SReg_64_XEXEC:
10509 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10511 return Match_InvalidOperand;
10519ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10520 SMLoc S = getLoc();
10529 return Error(S,
"expected a 16-bit value");
10532 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10536bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10542bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, AMDGPU::OpName OpName)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static int IsAGPROperand(const MCInst &Inst, AMDGPU::OpName Name, const MCRegisterInfo *MRI)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
constexpr uint64_t MIMGFlags
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static bool IsRevOpcode(const unsigned Opcode)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static MCRegister getSpecialRegForName(StringRef RegName)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0, std::optional< unsigned > InsertAt=std::nullopt)
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Loop::LoopBounds::Direction Direction
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
MachineInstr unsigned OpIdx
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
unsigned unsigned DefaultVal
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
static const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
int16_t getOpRegClassID(const MCOperandInfo &OpInfo, unsigned HwModeId) const
Return the ID of the register class to use for OpInfo, for the active HwMode HwModeId.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
void setReg(MCRegister Reg)
Set the register number.
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterClass - Base class of TargetRegisterClass.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isVariable() const
isVariable - Check if this is a variable symbol.
LLVM_ABI void setVariableValue(const MCExpr *Value)
void setRedefinable(bool Value)
Mark this symbol as redefinable.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
uint64_t getScalarSizeInBits() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
unsigned getTgtId(const StringRef Name)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI)
static constexpr CustomOperand Operands[]
unsigned getVGPREncodingGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI)
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
bool isPackedFP32Inst(unsigned Opc)
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
bool isInlineValue(MCRegister Reg)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
bool isSGPR(MCRegister Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
uint8_t wmmaScaleF8F6F4FormatToNumRegs(unsigned Fmt)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
unsigned getTemporalHintType(const MCInstrDesc TID)
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
bool isGFX10(const MCSubtargetInfo &STI)
LLVM_READONLY bool isLitExpr(const MCExpr *Expr)
bool isInlinableLiteralV2BF16(uint32_t Literal)
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
bool hasA16(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset, bool IsBuffer)
bool isGFX12Plus(const MCSubtargetInfo &STI)
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool isHsaAbi(const MCSubtargetInfo &STI)
bool isGFX11(const MCSubtargetInfo &STI)
const int OPR_VAL_INVALID
bool getSMEMIsBuffer(unsigned Opc)
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
CanBeVOPD getCanBeVOPD(unsigned Opc, unsigned EncodingFamily, bool VOPD3)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
bool isSI(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isGFX9(const MCSubtargetInfo &STI)
unsigned getVOPDEncodingFamily(const MCSubtargetInfo &ST)
bool isGFX10_AEncoding(const MCSubtargetInfo &STI)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool hasMAIInsts(const MCSubtargetInfo &STI)
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
@ Valid
The data is already valid.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
FunctionAddr VTableAddr uintptr_t uintptr_t Version
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ Default
The result values are uniform if and only if all operands are uniform.
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
Instruction set architecture version.
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
const MCExpr * compute_pgm_rsrc1
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * group_segment_fixed_size
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * kernel_code_properties
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size