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>;
86 bool hasFPModifiers()
const {
return Abs || Neg; }
87 bool hasIntModifiers()
const {
return Sext; }
88 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
90 int64_t getFPModifiersOperand()
const {
97 int64_t getIntModifiersOperand()
const {
103 int64_t getModifiersOperand()
const {
104 assert(!(hasFPModifiers() && hasIntModifiers())
105 &&
"fp and int modifiers should not be used simultaneously");
106 if (hasFPModifiers())
107 return getFPModifiersOperand();
108 if (hasIntModifiers())
109 return getIntModifiersOperand();
113 friend raw_ostream &
operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
183 ImmTyMatrixAScaleFmt,
184 ImmTyMatrixBScaleFmt,
217 mutable int MCOpIdx = -1;
220 bool isToken()
const override {
return Kind == Token; }
222 bool isSymbolRefExpr()
const {
226 bool isImm()
const override {
227 return Kind == Immediate;
230 bool isInlinableImm(MVT type)
const;
231 bool isLiteralImm(MVT type)
const;
233 bool isRegKind()
const {
234 return Kind == Register;
237 bool isReg()
const override {
238 return isRegKind() && !hasModifiers();
241 bool isRegOrInline(
unsigned RCID, MVT type)
const {
242 return isRegClass(RCID) || isInlinableImm(type);
246 return isRegOrInline(RCID, type) || isLiteralImm(type);
249 bool isRegOrImmWithInt16InputMods()
const {
253 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
255 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
258 bool isRegOrImmWithInt32InputMods()
const {
262 bool isRegOrInlineImmWithInt16InputMods()
const {
263 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
266 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
267 return isRegOrInline(
268 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
271 bool isRegOrInlineImmWithInt32InputMods()
const {
272 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
275 bool isRegOrImmWithInt64InputMods()
const {
279 bool isRegOrImmWithFP16InputMods()
const {
283 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
285 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
288 bool isRegOrImmWithFP32InputMods()
const {
292 bool isRegOrImmWithFP64InputMods()
const {
296 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
297 return isRegOrInline(
298 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
301 bool isRegOrInlineImmWithFP32InputMods()
const {
302 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
305 bool isRegOrInlineImmWithFP64InputMods()
const {
306 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
309 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
311 bool isVRegWithFP32InputMods()
const {
312 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
315 bool isVRegWithFP64InputMods()
const {
316 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
319 bool isPackedFP16InputMods()
const {
323 bool isPackedVGPRFP32InputMods()
const {
327 bool isVReg()
const {
328 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
329 isRegClass(AMDGPU::VReg_64RegClassID) ||
330 isRegClass(AMDGPU::VReg_96RegClassID) ||
331 isRegClass(AMDGPU::VReg_128RegClassID) ||
332 isRegClass(AMDGPU::VReg_160RegClassID) ||
333 isRegClass(AMDGPU::VReg_192RegClassID) ||
334 isRegClass(AMDGPU::VReg_256RegClassID) ||
335 isRegClass(AMDGPU::VReg_512RegClassID) ||
336 isRegClass(AMDGPU::VReg_1024RegClassID);
339 bool isVReg32()
const {
340 return isRegClass(AMDGPU::VGPR_32RegClassID);
343 bool isVReg32OrOff()
const {
344 return isOff() || isVReg32();
348 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
351 bool isVRegWithInputMods()
const;
352 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
353 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
355 bool isSDWAOperand(MVT type)
const;
356 bool isSDWAFP16Operand()
const;
357 bool isSDWAFP32Operand()
const;
358 bool isSDWAInt16Operand()
const;
359 bool isSDWAInt32Operand()
const;
361 bool isImmTy(ImmTy ImmT)
const {
362 return isImm() &&
Imm.Type == ImmT;
365 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
367 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
369 bool isImmModifier()
const {
370 return isImm() &&
Imm.Type != ImmTyNone;
373 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
374 bool isDim()
const {
return isImmTy(ImmTyDim); }
375 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
376 bool isOff()
const {
return isImmTy(ImmTyOff); }
377 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
378 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
379 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
380 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
381 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
382 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
383 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
384 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
385 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
386 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
387 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
388 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
389 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
390 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
391 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
392 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
393 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
394 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
395 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
396 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
397 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
398 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
399 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
400 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
401 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
402 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
403 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
404 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
405 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
406 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
407 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
408 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
409 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
410 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
411 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
413 bool isRegOrImm()
const {
414 return isReg() || isImm();
417 bool isRegClass(
unsigned RCID)
const;
421 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
422 return isRegOrInline(RCID, type) && !hasModifiers();
425 bool isSCSrcB16()
const {
426 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
429 bool isSCSrcV2B16()
const {
433 bool isSCSrc_b32()
const {
434 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
437 bool isSCSrc_b64()
const {
438 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
441 bool isBoolReg()
const;
443 bool isSCSrcF16()
const {
444 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
447 bool isSCSrcV2F16()
const {
451 bool isSCSrcF32()
const {
452 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
455 bool isSCSrcF64()
const {
456 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
459 bool isSSrc_b32()
const {
460 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
463 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
465 bool isSSrcV2B16()
const {
470 bool isSSrc_b64()
const {
473 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
474 (((
const MCTargetAsmParser *)AsmParser)
475 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
479 bool isSSrc_f32()
const {
480 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
483 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
485 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
487 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
489 bool isSSrcV2F16()
const {
494 bool isSSrcV2FP32()
const {
499 bool isSCSrcV2FP32()
const {
504 bool isSSrcV2INT32()
const {
509 bool isSCSrcV2INT32()
const {
511 return isSCSrc_b32();
514 bool isSSrcOrLds_b32()
const {
515 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
516 isLiteralImm(MVT::i32) || isExpr();
519 bool isVCSrc_b32()
const {
520 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
523 bool isVCSrc_b32_Lo256()
const {
524 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
527 bool isVCSrc_b64_Lo256()
const {
528 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
531 bool isVCSrc_b64()
const {
532 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
535 bool isVCSrcT_b16()
const {
536 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
539 bool isVCSrcTB16_Lo128()
const {
540 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
543 bool isVCSrcFake16B16_Lo128()
const {
544 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
547 bool isVCSrc_b16()
const {
548 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
551 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
553 bool isVCSrc_f32()
const {
554 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
557 bool isVCSrc_f64()
const {
558 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
561 bool isVCSrcTBF16()
const {
562 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
565 bool isVCSrcT_f16()
const {
566 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
569 bool isVCSrcT_bf16()
const {
570 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
573 bool isVCSrcTBF16_Lo128()
const {
574 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
577 bool isVCSrcTF16_Lo128()
const {
578 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
581 bool isVCSrcFake16BF16_Lo128()
const {
582 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
585 bool isVCSrcFake16F16_Lo128()
const {
586 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
589 bool isVCSrc_bf16()
const {
590 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
593 bool isVCSrc_f16()
const {
594 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
597 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
599 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
601 bool isVSrc_b32()
const {
602 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
605 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
607 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
609 bool isVSrcT_b16_Lo128()
const {
610 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
613 bool isVSrcFake16_b16_Lo128()
const {
614 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
617 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
619 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
621 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
623 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
625 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
627 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
629 bool isVSrc_f32()
const {
630 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
633 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
635 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
637 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
639 bool isVSrcT_bf16_Lo128()
const {
640 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
643 bool isVSrcT_f16_Lo128()
const {
644 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
647 bool isVSrcFake16_bf16_Lo128()
const {
648 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
651 bool isVSrcFake16_f16_Lo128()
const {
652 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
655 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
657 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
659 bool isVSrc_v2bf16()
const {
660 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
663 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
665 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
667 bool isVISrcB32()
const {
668 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
671 bool isVISrcB16()
const {
672 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
675 bool isVISrcV2B16()
const {
679 bool isVISrcF32()
const {
680 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
683 bool isVISrcF16()
const {
684 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
687 bool isVISrcV2F16()
const {
688 return isVISrcF16() || isVISrcB32();
691 bool isVISrc_64_bf16()
const {
692 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
695 bool isVISrc_64_f16()
const {
696 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
699 bool isVISrc_64_b32()
const {
700 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
703 bool isVISrc_64B64()
const {
704 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
707 bool isVISrc_64_f64()
const {
708 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
711 bool isVISrc_64V2FP32()
const {
712 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
715 bool isVISrc_64V2INT32()
const {
716 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
719 bool isVISrc_256_b32()
const {
720 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
723 bool isVISrc_256_f32()
const {
724 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
727 bool isVISrc_256B64()
const {
728 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
731 bool isVISrc_256_f64()
const {
732 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
735 bool isVISrc_512_f64()
const {
736 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
739 bool isVISrc_128B16()
const {
740 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
743 bool isVISrc_128V2B16()
const {
744 return isVISrc_128B16();
747 bool isVISrc_128_b32()
const {
748 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
751 bool isVISrc_128_f32()
const {
752 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
755 bool isVISrc_256V2FP32()
const {
756 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
759 bool isVISrc_256V2INT32()
const {
760 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
763 bool isVISrc_512_b32()
const {
764 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
767 bool isVISrc_512B16()
const {
768 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
771 bool isVISrc_512V2B16()
const {
772 return isVISrc_512B16();
775 bool isVISrc_512_f32()
const {
776 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
779 bool isVISrc_512F16()
const {
780 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
783 bool isVISrc_512V2F16()
const {
784 return isVISrc_512F16() || isVISrc_512_b32();
787 bool isVISrc_1024_b32()
const {
788 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
791 bool isVISrc_1024B16()
const {
792 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
795 bool isVISrc_1024V2B16()
const {
796 return isVISrc_1024B16();
799 bool isVISrc_1024_f32()
const {
800 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
803 bool isVISrc_1024F16()
const {
804 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
807 bool isVISrc_1024V2F16()
const {
808 return isVISrc_1024F16() || isVISrc_1024_b32();
811 bool isAISrcB32()
const {
812 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
815 bool isAISrcB16()
const {
816 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
819 bool isAISrcV2B16()
const {
823 bool isAISrcF32()
const {
824 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
827 bool isAISrcF16()
const {
828 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
831 bool isAISrcV2F16()
const {
832 return isAISrcF16() || isAISrcB32();
835 bool isAISrc_64B64()
const {
836 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
839 bool isAISrc_64_f64()
const {
840 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
843 bool isAISrc_128_b32()
const {
844 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
847 bool isAISrc_128B16()
const {
848 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
851 bool isAISrc_128V2B16()
const {
852 return isAISrc_128B16();
855 bool isAISrc_128_f32()
const {
856 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
859 bool isAISrc_128F16()
const {
860 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
863 bool isAISrc_128V2F16()
const {
864 return isAISrc_128F16() || isAISrc_128_b32();
867 bool isVISrc_128_bf16()
const {
868 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
871 bool isVISrc_128_f16()
const {
872 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
875 bool isVISrc_128V2F16()
const {
876 return isVISrc_128_f16() || isVISrc_128_b32();
879 bool isAISrc_256B64()
const {
880 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
883 bool isAISrc_256_f64()
const {
884 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
887 bool isAISrc_512_b32()
const {
888 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
891 bool isAISrc_512B16()
const {
892 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
895 bool isAISrc_512V2B16()
const {
896 return isAISrc_512B16();
899 bool isAISrc_512_f32()
const {
900 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
903 bool isAISrc_512F16()
const {
904 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
907 bool isAISrc_512V2F16()
const {
908 return isAISrc_512F16() || isAISrc_512_b32();
911 bool isAISrc_1024_b32()
const {
912 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
915 bool isAISrc_1024B16()
const {
916 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
919 bool isAISrc_1024V2B16()
const {
920 return isAISrc_1024B16();
923 bool isAISrc_1024_f32()
const {
924 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
927 bool isAISrc_1024F16()
const {
928 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
931 bool isAISrc_1024V2F16()
const {
932 return isAISrc_1024F16() || isAISrc_1024_b32();
935 bool isKImmFP32()
const {
936 return isLiteralImm(MVT::f32);
939 bool isKImmFP16()
const {
940 return isLiteralImm(MVT::f16);
943 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
945 bool isMem()
const override {
949 bool isExpr()
const {
950 return Kind == Expression;
953 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
955 bool isSWaitCnt()
const;
956 bool isDepCtr()
const;
957 bool isSDelayALU()
const;
958 bool isHwreg()
const;
959 bool isSendMsg()
const;
960 bool isSplitBarrier()
const;
961 bool isSwizzle()
const;
962 bool isSMRDOffset8()
const;
963 bool isSMEMOffset()
const;
964 bool isSMRDLiteralOffset()
const;
966 bool isDPPCtrl()
const;
968 bool isGPRIdxMode()
const;
969 bool isS16Imm()
const;
970 bool isU16Imm()
const;
971 bool isEndpgm()
const;
973 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
974 return [
this,
P]() {
return P(*
this); };
979 return StringRef(Tok.Data, Tok.Length);
987 void setImm(int64_t Val) {
992 ImmTy getImmTy()
const {
997 MCRegister
getReg()
const override {
1002 SMLoc getStartLoc()
const override {
1006 SMLoc getEndLoc()
const override {
1010 SMRange getLocRange()
const {
1011 return SMRange(StartLoc, EndLoc);
1014 int getMCOpIdx()
const {
return MCOpIdx; }
1016 Modifiers getModifiers()
const {
1017 assert(isRegKind() || isImmTy(ImmTyNone));
1018 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1021 void setModifiers(Modifiers Mods) {
1022 assert(isRegKind() || isImmTy(ImmTyNone));
1029 bool hasModifiers()
const {
1030 return getModifiers().hasModifiers();
1033 bool hasFPModifiers()
const {
1034 return getModifiers().hasFPModifiers();
1037 bool hasIntModifiers()
const {
1038 return getModifiers().hasIntModifiers();
1041 uint64_t applyInputFPModifiers(uint64_t Val,
unsigned Size)
const;
1043 void addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1045 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1047 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1049 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1051 addRegOperands(Inst,
N);
1053 addImmOperands(Inst,
N);
1056 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1057 Modifiers Mods = getModifiers();
1060 addRegOperands(Inst,
N);
1062 addImmOperands(Inst,
N,
false);
1066 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1067 assert(!hasIntModifiers());
1068 addRegOrImmWithInputModsOperands(Inst,
N);
1071 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1072 assert(!hasFPModifiers());
1073 addRegOrImmWithInputModsOperands(Inst,
N);
1076 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1077 Modifiers Mods = getModifiers();
1080 addRegOperands(Inst,
N);
1083 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1084 assert(!hasIntModifiers());
1085 addRegWithInputModsOperands(Inst,
N);
1088 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1089 assert(!hasFPModifiers());
1090 addRegWithInputModsOperands(Inst,
N);
1093 static void printImmTy(raw_ostream& OS, ImmTy
Type) {
1096 case ImmTyNone: OS <<
"None";
break;
1097 case ImmTyGDS: OS <<
"GDS";
break;
1098 case ImmTyLDS: OS <<
"LDS";
break;
1099 case ImmTyOffen: OS <<
"Offen";
break;
1100 case ImmTyIdxen: OS <<
"Idxen";
break;
1101 case ImmTyAddr64: OS <<
"Addr64";
break;
1102 case ImmTyOffset: OS <<
"Offset";
break;
1103 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1104 case ImmTyOffset0: OS <<
"Offset0";
break;
1105 case ImmTyOffset1: OS <<
"Offset1";
break;
1106 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1107 case ImmTyCPol: OS <<
"CPol";
break;
1108 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1109 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1110 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1111 case ImmTyTFE: OS <<
"TFE";
break;
1112 case ImmTyD16: OS <<
"D16";
break;
1113 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1114 case ImmTyClamp: OS <<
"Clamp";
break;
1115 case ImmTyOModSI: OS <<
"OModSI";
break;
1116 case ImmTyDPP8: OS <<
"DPP8";
break;
1117 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1118 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1119 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1120 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1121 case ImmTyDppFI: OS <<
"DppFI";
break;
1122 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1123 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1124 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1125 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1126 case ImmTyDMask: OS <<
"DMask";
break;
1127 case ImmTyDim: OS <<
"Dim";
break;
1128 case ImmTyUNorm: OS <<
"UNorm";
break;
1129 case ImmTyDA: OS <<
"DA";
break;
1130 case ImmTyR128A16: OS <<
"R128A16";
break;
1131 case ImmTyA16: OS <<
"A16";
break;
1132 case ImmTyLWE: OS <<
"LWE";
break;
1133 case ImmTyOff: OS <<
"Off";
break;
1134 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1135 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1136 case ImmTyExpVM: OS <<
"ExpVM";
break;
1137 case ImmTyHwreg: OS <<
"Hwreg";
break;
1138 case ImmTySendMsg: OS <<
"SendMsg";
break;
1139 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1140 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1141 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1142 case ImmTyOpSel: OS <<
"OpSel";
break;
1143 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1144 case ImmTyNegLo: OS <<
"NegLo";
break;
1145 case ImmTyNegHi: OS <<
"NegHi";
break;
1146 case ImmTySwizzle: OS <<
"Swizzle";
break;
1147 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1148 case ImmTyHigh: OS <<
"High";
break;
1149 case ImmTyBLGP: OS <<
"BLGP";
break;
1150 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1151 case ImmTyABID: OS <<
"ABID";
break;
1152 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1153 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1154 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1155 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1156 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1157 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1158 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1159 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1160 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1161 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1162 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1163 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1164 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1165 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1166 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1167 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1172 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1176 <<
" mods: " <<
Reg.Mods <<
'>';
1180 if (getImmTy() != ImmTyNone) {
1181 OS <<
" type: "; printImmTy(OS, getImmTy());
1183 OS <<
" mods: " <<
Imm.Mods <<
'>';
1196 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1197 int64_t Val, SMLoc Loc,
1198 ImmTy
Type = ImmTyNone,
1199 bool IsFPImm =
false) {
1200 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1202 Op->Imm.IsFPImm = IsFPImm;
1204 Op->Imm.Mods = Modifiers();
1210 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1211 StringRef Str, SMLoc Loc,
1212 bool HasExplicitEncodingSize =
true) {
1213 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1214 Res->Tok.Data = Str.data();
1215 Res->Tok.Length = Str.size();
1216 Res->StartLoc = Loc;
1221 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1222 MCRegister
Reg, SMLoc S, SMLoc
E) {
1223 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1224 Op->Reg.RegNo =
Reg;
1225 Op->Reg.Mods = Modifiers();
1231 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1232 const class MCExpr *Expr, SMLoc S) {
1233 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1242 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1253class KernelScopeInfo {
1254 int SgprIndexUnusedMin = -1;
1255 int VgprIndexUnusedMin = -1;
1256 int AgprIndexUnusedMin = -1;
1257 MCContext *Ctx =
nullptr;
1258 MCSubtargetInfo
const *MSTI =
nullptr;
1260 void usesSgprAt(
int i) {
1261 if (i >= SgprIndexUnusedMin) {
1262 SgprIndexUnusedMin = ++i;
1265 Ctx->getOrCreateSymbol(Twine(
".kernel.sgpr_count"));
1271 void usesVgprAt(
int i) {
1272 if (i >= VgprIndexUnusedMin) {
1273 VgprIndexUnusedMin = ++i;
1276 Ctx->getOrCreateSymbol(Twine(
".kernel.vgpr_count"));
1278 VgprIndexUnusedMin);
1284 void usesAgprAt(
int i) {
1289 if (i >= AgprIndexUnusedMin) {
1290 AgprIndexUnusedMin = ++i;
1293 Ctx->getOrCreateSymbol(Twine(
".kernel.agpr_count"));
1298 Ctx->getOrCreateSymbol(Twine(
".kernel.vgpr_count"));
1300 VgprIndexUnusedMin);
1307 KernelScopeInfo() =
default;
1311 MSTI = Ctx->getSubtargetInfo();
1313 usesSgprAt(SgprIndexUnusedMin = -1);
1314 usesVgprAt(VgprIndexUnusedMin = -1);
1316 usesAgprAt(AgprIndexUnusedMin = -1);
1320 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1321 unsigned RegWidth) {
1324 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1327 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1330 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1339 MCAsmParser &Parser;
1341 unsigned ForcedEncodingSize = 0;
1342 bool ForcedDPP =
false;
1343 bool ForcedSDWA =
false;
1344 KernelScopeInfo KernelScope;
1349#define GET_ASSEMBLER_HEADER
1350#include "AMDGPUGenAsmMatcher.inc"
1355 void createConstantSymbol(
StringRef Id, int64_t Val);
1357 bool ParseAsAbsoluteExpression(
uint32_t &Ret);
1375 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1376 std::optional<bool> EnableWavefrontSize32,
1380 bool ParseDirectiveAMDGCNTarget();
1381 bool ParseDirectiveAMDHSACodeObjectVersion();
1382 bool ParseDirectiveAMDHSAKernel();
1384 bool ParseDirectiveAMDKernelCodeT();
1387 bool ParseDirectiveAMDGPUHsaKernel();
1389 bool ParseDirectiveISAVersion();
1390 bool ParseDirectiveHSAMetadata();
1391 bool ParseDirectivePALMetadataBegin();
1392 bool ParseDirectivePALMetadata();
1393 bool ParseDirectiveAMDGPULDS();
1397 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1398 const char *AssemblerDirectiveEnd,
1399 std::string &CollectString);
1401 bool AddNextRegisterToList(
MCRegister &
Reg,
unsigned &RegWidth,
1403 bool ParseAMDGPURegister(RegisterKind &RegKind,
MCRegister &
Reg,
1404 unsigned &RegNum,
unsigned &RegWidth,
1405 bool RestoreOnFailure =
false);
1406 bool ParseAMDGPURegister(RegisterKind &RegKind,
MCRegister &
Reg,
1407 unsigned &RegNum,
unsigned &RegWidth,
1409 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1412 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1415 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1418 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &
SubReg);
1419 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1424 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1425 void initializeGprCountSymbol(RegisterKind RegKind);
1426 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1433 OperandMode_Default,
1437 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1439 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1440 const MCInstrInfo &MII,
1441 const MCTargetOptions &
Options)
1442 : MCTargetAsmParser(
Options, STI, MII), Parser(_Parser) {
1445 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1449 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1450 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1451 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1453 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1454 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1455 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1458 initializeGprCountSymbol(IS_VGPR);
1459 initializeGprCountSymbol(IS_SGPR);
1464 createConstantSymbol(Symbol, Code);
1466 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1467 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1468 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1540 bool hasInv2PiInlineImm()
const {
1541 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1544 bool has64BitLiterals()
const {
1545 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1548 bool hasFlatOffsets()
const {
1549 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1552 bool hasTrue16Insts()
const {
1553 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1557 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1560 bool hasSGPR102_SGPR103()
const {
1564 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1566 bool hasIntClamp()
const {
1567 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1570 bool hasPartialNSAEncoding()
const {
1571 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1574 bool hasGloballyAddressableScratch()
const {
1575 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1588 AMDGPUTargetStreamer &getTargetStreamer() {
1589 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1590 return static_cast<AMDGPUTargetStreamer &
>(TS);
1593 const MCRegisterInfo *getMRI()
const {
1596 return const_cast<AMDGPUAsmParser*
>(
this)->
getContext().getRegisterInfo();
1599 const MCInstrInfo *getMII()
const {
1603 const FeatureBitset &getFeatureBits()
const {
1604 return getSTI().getFeatureBits();
1607 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1608 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1609 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1611 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1612 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1613 bool isForcedDPP()
const {
return ForcedDPP; }
1614 bool isForcedSDWA()
const {
return ForcedSDWA; }
1615 ArrayRef<unsigned> getMatchedVariants()
const;
1616 StringRef getMatchedVariantName()
const;
1618 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1619 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1620 bool RestoreOnFailure);
1621 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1622 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1623 SMLoc &EndLoc)
override;
1624 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1625 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1626 unsigned Kind)
override;
1627 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1629 uint64_t &ErrorInfo,
1630 bool MatchingInlineAsm)
override;
1631 bool ParseDirective(AsmToken DirectiveID)
override;
1633 OperandMode
Mode = OperandMode_Default);
1634 StringRef parseMnemonicSuffix(StringRef Name);
1635 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
1641 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1645 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1646 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1648 ParseStatus parseOperandArrayWithPrefix(
1650 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1651 bool (*ConvertResult)(int64_t &) =
nullptr);
1655 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1656 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1660 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1664 ArrayRef<const char *> Ids,
1668 ArrayRef<const char *> Ids,
1669 AMDGPUOperand::ImmTy
Type);
1672 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1673 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1674 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1675 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1676 bool parseSP3NegModifier();
1678 bool HasLit =
false,
bool HasLit64 =
false);
1681 bool HasLit =
false,
bool HasLit64 =
false);
1683 bool AllowImm =
true);
1685 bool AllowImm =
true);
1690 AMDGPUOperand::ImmTy ImmTy);
1695 AMDGPUOperand::ImmTy
Type);
1699 AMDGPUOperand::ImmTy
Type);
1703 AMDGPUOperand::ImmTy
Type);
1707 ParseStatus parseDfmtNfmt(int64_t &
Format);
1708 ParseStatus parseUfmt(int64_t &
Format);
1709 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1711 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1714 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1715 ParseStatus parseNumericFormat(int64_t &
Format);
1719 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1720 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1724 bool parseCnt(int64_t &IntVal);
1727 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1728 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1731 bool parseDelay(int64_t &Delay);
1737 struct OperandInfoTy {
1740 bool IsSymbolic =
false;
1741 bool IsDefined =
false;
1743 OperandInfoTy(int64_t Val) : Val(Val) {}
1746 struct StructuredOpField : OperandInfoTy {
1750 bool IsDefined =
false;
1752 StructuredOpField(StringLiteral Id, StringLiteral Desc,
unsigned Width,
1754 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1755 virtual ~StructuredOpField() =
default;
1757 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1758 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1762 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1764 return Error(Parser,
"not supported on this GPU");
1766 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1774 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1775 bool validateSendMsg(
const OperandInfoTy &Msg,
1776 const OperandInfoTy &
Op,
1777 const OperandInfoTy &Stream);
1779 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1780 OperandInfoTy &Width);
1782 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1789 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1791 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1801 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1804 bool tryVOPD(
const MCInst &Inst);
1805 bool tryVOPD3(
const MCInst &Inst);
1806 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1808 bool validateIntClampSupported(
const MCInst &Inst);
1809 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1810 bool validateMIMGGatherDMask(
const MCInst &Inst);
1812 bool validateMIMGDataSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1813 bool validateMIMGAddrSize(
const MCInst &Inst,
const SMLoc &IDLoc);
1814 bool validateMIMGD16(
const MCInst &Inst);
1816 bool validateTensorR128(
const MCInst &Inst);
1817 bool validateMIMGMSAA(
const MCInst &Inst);
1818 bool validateOpSel(
const MCInst &Inst);
1819 bool validateTrue16OpSel(
const MCInst &Inst);
1820 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1822 bool validateVccOperand(MCRegister
Reg)
const;
1827 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1828 bool validateVGPRAlign(
const MCInst &Inst)
const;
1832 bool validateDivScale(
const MCInst &Inst);
1835 const SMLoc &IDLoc);
1837 const unsigned CPol);
1842 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1843 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1844 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1845 unsigned findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1847 bool isSupportedMnemo(StringRef Mnemo,
1848 const FeatureBitset &FBS);
1849 bool isSupportedMnemo(StringRef Mnemo,
1850 const FeatureBitset &FBS,
1851 ArrayRef<unsigned> Variants);
1852 bool checkUnsupportedInstruction(StringRef Name,
const SMLoc &IDLoc);
1854 bool isId(
const StringRef Id)
const;
1855 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1857 StringRef getId()
const;
1858 bool trySkipId(
const StringRef Id);
1859 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1863 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1864 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1870 StringRef getTokenStr()
const;
1871 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1873 SMLoc getLoc()
const;
1877 void onBeginOfFile()
override;
1878 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1889 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1890 const unsigned MaxVal,
const Twine &ErrMsg,
1892 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1893 const unsigned MinVal,
1894 const unsigned MaxVal,
1895 const StringRef ErrMsg);
1897 bool parseSwizzleOffset(int64_t &
Imm);
1898 bool parseSwizzleMacro(int64_t &
Imm);
1899 bool parseSwizzleQuadPerm(int64_t &
Imm);
1900 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1901 bool parseSwizzleBroadcast(int64_t &
Imm);
1902 bool parseSwizzleSwap(int64_t &
Imm);
1903 bool parseSwizzleReverse(int64_t &
Imm);
1904 bool parseSwizzleFFT(int64_t &
Imm);
1905 bool parseSwizzleRotate(int64_t &
Imm);
1908 int64_t parseGPRIdxMacro();
1916 OptionalImmIndexMap &OptionalIdx);
1925 OptionalImmIndexMap &OptionalIdx);
1927 OptionalImmIndexMap &OptionalIdx);
1932 bool parseDimId(
unsigned &Encoding);
1934 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1938 int64_t parseDPPCtrlSel(StringRef Ctrl);
1939 int64_t parseDPPCtrlPerm();
1945 bool IsDPP8 =
false);
1951 AMDGPUOperand::ImmTy
Type);
1959 uint64_t BasicInstType,
1960 bool SkipDstVcc =
false,
1961 bool SkipSrcVcc =
false);
2069bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2079 if (!isImmTy(ImmTyNone)) {
2090 if (type == MVT::f64 || type == MVT::i64) {
2092 AsmParser->hasInv2PiInlineImm());
2095 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2114 APFloat::rmNearestTiesToEven, &Lost);
2121 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2123 AsmParser->hasInv2PiInlineImm());
2128 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2129 AsmParser->hasInv2PiInlineImm());
2133 if (type == MVT::f64 || type == MVT::i64) {
2135 AsmParser->hasInv2PiInlineImm());
2144 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2145 type, AsmParser->hasInv2PiInlineImm());
2149 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2150 AsmParser->hasInv2PiInlineImm());
2153bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2155 if (!isImmTy(ImmTyNone)) {
2160 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2165 if (type == MVT::f64 && hasFPModifiers()) {
2185 if (type == MVT::f64) {
2190 if (type == MVT::i64) {
2203 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2204 : (type == MVT::v2i16) ? MVT::f32
2205 : (type == MVT::v2f32) ? MVT::f32
2208 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2212bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2213 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2216bool AMDGPUOperand::isVRegWithInputMods()
const {
2217 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2219 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2220 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2223template <
bool IsFake16>
2224bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2225 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2226 : AMDGPU::VGPR_16_Lo128RegClassID);
2229template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2230 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2231 : AMDGPU::VGPR_16RegClassID);
2234bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2235 if (AsmParser->isVI())
2237 if (AsmParser->isGFX9Plus())
2238 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2242bool AMDGPUOperand::isSDWAFP16Operand()
const {
2243 return isSDWAOperand(MVT::f16);
2246bool AMDGPUOperand::isSDWAFP32Operand()
const {
2247 return isSDWAOperand(MVT::f32);
2250bool AMDGPUOperand::isSDWAInt16Operand()
const {
2251 return isSDWAOperand(MVT::i16);
2254bool AMDGPUOperand::isSDWAInt32Operand()
const {
2255 return isSDWAOperand(MVT::i32);
2258bool AMDGPUOperand::isBoolReg()
const {
2259 auto FB = AsmParser->getFeatureBits();
2260 return isReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrc_b64()) ||
2261 (FB[AMDGPU::FeatureWavefrontSize32] && isSCSrc_b32()));
2264uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2266 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2269 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2281void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2291 addLiteralImmOperand(Inst,
Imm.Val,
2293 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2295 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2300void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2301 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2306 if (ApplyModifiers) {
2309 Val = applyInputFPModifiers(Val,
Size);
2313 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2323 AsmParser->hasInv2PiInlineImm())) {
2331 bool HasMandatoryLiteral =
2334 if (
Literal.getLoBits(32) != 0 &&
2335 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2336 !HasMandatoryLiteral) {
2337 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2339 "Can't encode literal as exact 64-bit floating-point operand. "
2340 "Low 32-bits will be set to zero");
2341 Val &= 0xffffffff00000000u;
2361 if (AsmParser->hasInv2PiInlineImm() &&
Literal == 0x3fc45f306725feed) {
2395 APFloat::rmNearestTiesToEven, &lost);
2399 uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2440 if (!AsmParser->has64BitLiterals() || getModifiers().Lit)
2456 if (!AsmParser->has64BitLiterals()) {
2457 Val =
static_cast<uint64_t
>(Val) << 32;
2464 if (getModifiers().Lit ||
2466 Val =
static_cast<uint64_t
>(Val) << 32;
2498void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2503bool AMDGPUOperand::isInlineValue()
const {
2511void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2522 if (Is == IS_VGPR) {
2526 return AMDGPU::VGPR_32RegClassID;
2528 return AMDGPU::VReg_64RegClassID;
2530 return AMDGPU::VReg_96RegClassID;
2532 return AMDGPU::VReg_128RegClassID;
2534 return AMDGPU::VReg_160RegClassID;
2536 return AMDGPU::VReg_192RegClassID;
2538 return AMDGPU::VReg_224RegClassID;
2540 return AMDGPU::VReg_256RegClassID;
2542 return AMDGPU::VReg_288RegClassID;
2544 return AMDGPU::VReg_320RegClassID;
2546 return AMDGPU::VReg_352RegClassID;
2548 return AMDGPU::VReg_384RegClassID;
2550 return AMDGPU::VReg_512RegClassID;
2552 return AMDGPU::VReg_1024RegClassID;
2554 }
else if (Is == IS_TTMP) {
2558 return AMDGPU::TTMP_32RegClassID;
2560 return AMDGPU::TTMP_64RegClassID;
2562 return AMDGPU::TTMP_128RegClassID;
2564 return AMDGPU::TTMP_256RegClassID;
2566 return AMDGPU::TTMP_512RegClassID;
2568 }
else if (Is == IS_SGPR) {
2572 return AMDGPU::SGPR_32RegClassID;
2574 return AMDGPU::SGPR_64RegClassID;
2576 return AMDGPU::SGPR_96RegClassID;
2578 return AMDGPU::SGPR_128RegClassID;
2580 return AMDGPU::SGPR_160RegClassID;
2582 return AMDGPU::SGPR_192RegClassID;
2584 return AMDGPU::SGPR_224RegClassID;
2586 return AMDGPU::SGPR_256RegClassID;
2588 return AMDGPU::SGPR_288RegClassID;
2590 return AMDGPU::SGPR_320RegClassID;
2592 return AMDGPU::SGPR_352RegClassID;
2594 return AMDGPU::SGPR_384RegClassID;
2596 return AMDGPU::SGPR_512RegClassID;
2598 }
else if (Is == IS_AGPR) {
2602 return AMDGPU::AGPR_32RegClassID;
2604 return AMDGPU::AReg_64RegClassID;
2606 return AMDGPU::AReg_96RegClassID;
2608 return AMDGPU::AReg_128RegClassID;
2610 return AMDGPU::AReg_160RegClassID;
2612 return AMDGPU::AReg_192RegClassID;
2614 return AMDGPU::AReg_224RegClassID;
2616 return AMDGPU::AReg_256RegClassID;
2618 return AMDGPU::AReg_288RegClassID;
2620 return AMDGPU::AReg_320RegClassID;
2622 return AMDGPU::AReg_352RegClassID;
2624 return AMDGPU::AReg_384RegClassID;
2626 return AMDGPU::AReg_512RegClassID;
2628 return AMDGPU::AReg_1024RegClassID;
2636 .
Case(
"exec", AMDGPU::EXEC)
2637 .
Case(
"vcc", AMDGPU::VCC)
2638 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2639 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2640 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2641 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2642 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2643 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2644 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2645 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2646 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2647 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2648 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2649 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2650 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2651 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2652 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2653 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2654 .
Case(
"m0", AMDGPU::M0)
2655 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2656 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2657 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2658 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2659 .
Case(
"scc", AMDGPU::SRC_SCC)
2660 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2661 .
Case(
"tba", AMDGPU::TBA)
2662 .
Case(
"tma", AMDGPU::TMA)
2663 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2664 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2665 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2666 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2667 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2668 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2669 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2670 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2671 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2672 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2673 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2674 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2675 .
Case(
"pc", AMDGPU::PC_REG)
2676 .
Case(
"null", AMDGPU::SGPR_NULL)
2680bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2681 SMLoc &EndLoc,
bool RestoreOnFailure) {
2682 auto R = parseRegister();
2683 if (!R)
return true;
2685 RegNo =
R->getReg();
2686 StartLoc =
R->getStartLoc();
2687 EndLoc =
R->getEndLoc();
2691bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2693 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2696ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2698 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2699 bool PendingErrors = getParser().hasPendingError();
2700 getParser().clearPendingErrors();
2708bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2709 RegisterKind RegKind,
2710 MCRegister Reg1, SMLoc Loc) {
2713 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2718 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2719 Reg = AMDGPU::FLAT_SCR;
2723 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2724 Reg = AMDGPU::XNACK_MASK;
2728 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2733 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2738 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2743 Error(Loc,
"register does not fit in the list");
2749 if (Reg1 !=
Reg + RegWidth / 32) {
2750 Error(Loc,
"registers in a list must have consecutive indices");
2768 {{
"ttmp"}, IS_TTMP},
2774 return Kind == IS_VGPR ||
2782 if (Str.starts_with(
Reg.Name))
2788 return !Str.getAsInteger(10, Num);
2792AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2793 const AsmToken &NextToken)
const {
2808 StringRef RegSuffix = Str.substr(
RegName.size());
2809 if (!RegSuffix.
empty()) {
2827AMDGPUAsmParser::isRegister()
2829 return isRegister(
getToken(), peekToken());
2832MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2833 unsigned SubReg,
unsigned RegWidth,
2837 unsigned AlignSize = 1;
2838 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2844 if (RegNum % AlignSize != 0) {
2845 Error(Loc,
"invalid register alignment");
2846 return MCRegister();
2849 unsigned RegIdx = RegNum / AlignSize;
2852 Error(Loc,
"invalid or unsupported register size");
2853 return MCRegister();
2857 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2858 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2859 Error(Loc,
"register index is out of range");
2860 return AMDGPU::NoRegister;
2863 if (RegKind == IS_VGPR && !
isGFX1250() && RegIdx + RegWidth / 32 > 256) {
2864 Error(Loc,
"register index is out of range");
2865 return MCRegister();
2881bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2883 int64_t RegLo, RegHi;
2887 SMLoc FirstIdxLoc = getLoc();
2894 SecondIdxLoc = getLoc();
2905 Error(FirstIdxLoc,
"invalid register index");
2910 Error(SecondIdxLoc,
"invalid register index");
2914 if (RegLo > RegHi) {
2915 Error(FirstIdxLoc,
"first register index should not exceed second index");
2919 if (RegHi == RegLo) {
2920 StringRef RegSuffix = getTokenStr();
2921 if (RegSuffix ==
".l") {
2924 }
else if (RegSuffix ==
".h") {
2930 Num =
static_cast<unsigned>(RegLo);
2931 RegWidth = 32 * ((RegHi - RegLo) + 1);
2936MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2939 SmallVectorImpl<AsmToken> &Tokens) {
2945 RegKind = IS_SPECIAL;
2952MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2955 SmallVectorImpl<AsmToken> &Tokens) {
2957 StringRef
RegName = getTokenStr();
2958 auto Loc = getLoc();
2962 Error(Loc,
"invalid register name");
2963 return MCRegister();
2971 unsigned SubReg = NoSubRegister;
2972 if (!RegSuffix.
empty()) {
2980 Error(Loc,
"invalid register index");
2981 return MCRegister();
2986 if (!ParseRegRange(RegNum, RegWidth,
SubReg))
2987 return MCRegister();
2990 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
2993MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
2994 unsigned &RegNum,
unsigned &RegWidth,
2995 SmallVectorImpl<AsmToken> &Tokens) {
2997 auto ListLoc = getLoc();
3000 "expected a register or a list of registers")) {
3001 return MCRegister();
3006 auto Loc = getLoc();
3007 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3008 return MCRegister();
3009 if (RegWidth != 32) {
3010 Error(Loc,
"expected a single 32-bit register");
3011 return MCRegister();
3015 RegisterKind NextRegKind;
3017 unsigned NextRegNum, NextRegWidth;
3020 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3021 NextRegNum, NextRegWidth,
3023 return MCRegister();
3025 if (NextRegWidth != 32) {
3026 Error(Loc,
"expected a single 32-bit register");
3027 return MCRegister();
3029 if (NextRegKind != RegKind) {
3030 Error(Loc,
"registers in a list must be of the same kind");
3031 return MCRegister();
3033 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3034 return MCRegister();
3038 "expected a comma or a closing square bracket")) {
3039 return MCRegister();
3043 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3048bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3049 MCRegister &
Reg,
unsigned &RegNum,
3051 SmallVectorImpl<AsmToken> &Tokens) {
3052 auto Loc = getLoc();
3056 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3058 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3060 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3065 assert(Parser.hasPendingError());
3069 if (!subtargetHasRegister(*
TRI,
Reg)) {
3070 if (
Reg == AMDGPU::SGPR_NULL) {
3071 Error(Loc,
"'null' operand is not supported on this GPU");
3074 " register not available on this GPU");
3082bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3083 MCRegister &
Reg,
unsigned &RegNum,
3085 bool RestoreOnFailure ) {
3089 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3090 if (RestoreOnFailure) {
3091 while (!Tokens.
empty()) {
3100std::optional<StringRef>
3101AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3104 return StringRef(
".amdgcn.next_free_vgpr");
3106 return StringRef(
".amdgcn.next_free_sgpr");
3108 return std::nullopt;
3112void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3113 auto SymbolName = getGprCountSymbolName(RegKind);
3114 assert(SymbolName &&
"initializing invalid register kind");
3120bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3121 unsigned DwordRegIndex,
3122 unsigned RegWidth) {
3127 auto SymbolName = getGprCountSymbolName(RegKind);
3132 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3136 return !
Error(getLoc(),
3137 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3141 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3143 if (OldCount <= NewMax)
3149std::unique_ptr<AMDGPUOperand>
3150AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3152 SMLoc StartLoc = Tok.getLoc();
3153 SMLoc EndLoc = Tok.getEndLoc();
3154 RegisterKind RegKind;
3156 unsigned RegNum, RegWidth;
3158 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3162 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3165 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3166 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3170 bool HasSP3AbsModifier,
bool HasLit,
3174 if (isRegister() || isModifier())
3177 if (!HasLit && !HasLit64) {
3178 HasLit64 = trySkipId(
"lit64");
3179 HasLit = !HasLit64 && trySkipId(
"lit");
3180 if (HasLit || HasLit64) {
3183 ParseStatus S = parseImm(
Operands, HasSP3AbsModifier, HasLit, HasLit64);
3192 const auto& NextTok = peekToken();
3195 bool Negate =
false;
3203 AMDGPUOperand::Modifiers Mods;
3205 Mods.Lit64 = HasLit64;
3212 StringRef Num = getTokenStr();
3215 APFloat RealVal(APFloat::IEEEdouble());
3216 auto roundMode = APFloat::rmNearestTiesToEven;
3217 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3220 RealVal.changeSign();
3223 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3224 AMDGPUOperand::ImmTyNone,
true));
3225 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3226 Op.setModifiers(Mods);
3235 if (HasSP3AbsModifier) {
3244 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3247 if (Parser.parseExpression(Expr))
3251 if (Expr->evaluateAsAbsolute(IntVal)) {
3252 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3253 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3254 Op.setModifiers(Mods);
3256 if (HasLit || HasLit64)
3258 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3271 if (
auto R = parseRegister()) {
3280 bool HasSP3AbsMod,
bool HasLit,
3282 ParseStatus Res = parseReg(
Operands);
3287 return parseImm(
Operands, HasSP3AbsMod, HasLit, HasLit64);
3291AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3294 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3300AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3305AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3306 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3310AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3311 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3328AMDGPUAsmParser::isModifier() {
3331 AsmToken NextToken[2];
3332 peekTokens(NextToken);
3334 return isOperandModifier(Tok, NextToken[0]) ||
3335 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3336 isOpcodeModifierWithVal(Tok, NextToken[0]);
3362AMDGPUAsmParser::parseSP3NegModifier() {
3364 AsmToken NextToken[2];
3365 peekTokens(NextToken);
3368 (isRegister(NextToken[0], NextToken[1]) ||
3370 isId(NextToken[0],
"abs"))) {
3388 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3390 SP3Neg = parseSP3NegModifier();
3393 Neg = trySkipId(
"neg");
3395 return Error(Loc,
"expected register or immediate");
3399 Abs = trySkipId(
"abs");
3403 Lit64 = trySkipId(
"lit64");
3407 if (!has64BitLiterals())
3408 return Error(Loc,
"lit64 is not supported on this GPU");
3411 Lit = !Lit64 && trySkipId(
"lit");
3418 return Error(Loc,
"expected register or immediate");
3422 Res = parseRegOrImm(
Operands, SP3Abs, Lit, Lit64);
3427 return (SP3Neg || Neg || SP3Abs || Abs || Lit || Lit64)
3431 if ((Lit || Lit64) && !
Operands.back()->isImm())
3432 Error(Loc,
"expected immediate with lit modifier");
3434 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3440 if ((Lit || Lit64) &&
3444 AMDGPUOperand::Modifiers Mods;
3445 Mods.Abs = Abs || SP3Abs;
3446 Mods.Neg = Neg || SP3Neg;
3450 if (Mods.hasFPModifiers() || Lit || Lit64) {
3451 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3453 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3454 Op.setModifiers(Mods);
3462 bool Sext = trySkipId(
"sext");
3463 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3478 AMDGPUOperand::Modifiers Mods;
3481 if (Mods.hasIntModifiers()) {
3482 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3484 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3485 Op.setModifiers(Mods);
3492 return parseRegOrImmWithFPInputMods(
Operands,
false);
3496 return parseRegOrImmWithIntInputMods(
Operands,
false);
3500 auto Loc = getLoc();
3501 if (trySkipId(
"off")) {
3502 Operands.push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3503 AMDGPUOperand::ImmTyOff,
false));
3510 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3519unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3526 return Match_InvalidOperand;
3528 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3529 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3532 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3534 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3535 return Match_InvalidOperand;
3543 if (tryAnotherVOPDEncoding(Inst))
3544 return Match_InvalidOperand;
3546 return Match_Success;
3550 static const unsigned Variants[] = {
3560ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3561 if (isForcedDPP() && isForcedVOP3()) {
3565 if (getForcedEncodingSize() == 32) {
3570 if (isForcedVOP3()) {
3575 if (isForcedSDWA()) {
3581 if (isForcedDPP()) {
3589StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3590 if (isForcedDPP() && isForcedVOP3())
3593 if (getForcedEncodingSize() == 32)
3608unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3612 case AMDGPU::FLAT_SCR:
3614 case AMDGPU::VCC_LO:
3615 case AMDGPU::VCC_HI:
3622 return AMDGPU::NoRegister;
3629bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3630 unsigned OpIdx)
const {
3640 int64_t Val = MO.
getImm();
3684unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3690 case AMDGPU::V_LSHLREV_B64_e64:
3691 case AMDGPU::V_LSHLREV_B64_gfx10:
3692 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3693 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3694 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3695 case AMDGPU::V_LSHRREV_B64_e64:
3696 case AMDGPU::V_LSHRREV_B64_gfx10:
3697 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3698 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3699 case AMDGPU::V_ASHRREV_I64_e64:
3700 case AMDGPU::V_ASHRREV_I64_gfx10:
3701 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3702 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3703 case AMDGPU::V_LSHL_B64_e64:
3704 case AMDGPU::V_LSHR_B64_e64:
3705 case AMDGPU::V_ASHR_I64_e64:
3718 bool AddMandatoryLiterals =
false) {
3721 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3725 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3727 return {getNamedOperandIdx(Opcode, OpName::src0X),
3728 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3729 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3730 getNamedOperandIdx(Opcode, OpName::src0Y),
3731 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3732 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3737 return {getNamedOperandIdx(Opcode, OpName::src0),
3738 getNamedOperandIdx(Opcode, OpName::src1),
3739 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3742bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3745 return !isInlineConstant(Inst,
OpIdx);
3752 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3763 const unsigned Opcode = Inst.
getOpcode();
3764 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3767 if (!LaneSelOp.
isReg())
3770 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3773bool AMDGPUAsmParser::validateConstantBusLimitations(
3775 const unsigned Opcode = Inst.
getOpcode();
3776 const MCInstrDesc &
Desc = MII.
get(Opcode);
3777 MCRegister LastSGPR;
3778 unsigned ConstantBusUseCount = 0;
3779 unsigned NumLiterals = 0;
3780 unsigned LiteralSize;
3782 if (!(
Desc.TSFlags &
3797 SmallDenseSet<unsigned> SGPRsUsed;
3798 unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3799 if (SGPRUsed != AMDGPU::NoRegister) {
3800 SGPRsUsed.
insert(SGPRUsed);
3801 ++ConstantBusUseCount;
3806 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3808 for (
int OpIdx : OpIndices) {
3813 if (usesConstantBus(Inst,
OpIdx)) {
3822 if (SGPRsUsed.
insert(LastSGPR).second) {
3823 ++ConstantBusUseCount;
3843 if (NumLiterals == 0) {
3846 }
else if (LiteralSize !=
Size) {
3852 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3854 "invalid operand (violates constant bus restrictions)");
3861std::optional<unsigned>
3862AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3864 const unsigned Opcode = Inst.
getOpcode();
3870 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3871 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3879 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3880 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3881 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250;
3885 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3886 int I = getNamedOperandIdx(Opcode, OpName);
3890 int64_t
Imm =
Op.getImm();
3896 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3897 OpName::vsrc2Y, OpName::imm}) {
3898 int I = getNamedOperandIdx(Opcode, OpName);
3908 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3909 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3911 return InvalidCompOprIdx;
3914bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
3921 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand :
Operands) {
3922 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
3923 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
3925 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
3929 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
3930 if (!InvalidCompOprIdx.has_value())
3933 auto CompOprIdx = *InvalidCompOprIdx;
3936 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3937 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3940 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
3941 if (CompOprIdx == VOPD::Component::DST) {
3943 Error(Loc,
"dst registers must be distinct");
3945 Error(Loc,
"one dst register must be even and the other odd");
3947 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3948 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
3949 " operands must use different VGPR banks");
3957bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
3959 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
3960 if (!InvalidCompOprIdx.has_value())
3964 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
3965 if (InvalidCompOprIdx.has_value()) {
3970 if (*InvalidCompOprIdx == VOPD::Component::DST)
3983bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
3984 const unsigned Opcode = Inst.
getOpcode();
3999 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4000 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4001 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4002 int I = getNamedOperandIdx(Opcode, OpName);
4009 return !tryVOPD3(Inst);
4014bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4015 const unsigned Opcode = Inst.
getOpcode();
4020 return tryVOPD(Inst);
4021 return tryVOPD3(Inst);
4024bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4030 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4041bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
4042 const SMLoc &IDLoc) {
4050 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4051 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4052 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4061 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4066 bool IsPackedD16 =
false;
4070 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4071 IsPackedD16 = D16Idx >= 0;
4076 if ((VDataSize / 4) ==
DataSize + TFESize)
4081 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4083 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4085 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4089bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst,
4090 const SMLoc &IDLoc) {
4099 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4101 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4103 ? AMDGPU::OpName::srsrc
4104 : AMDGPU::OpName::rsrc;
4105 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4106 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4107 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4111 assert(SrsrcIdx > VAddr0Idx);
4114 if (BaseOpcode->
BVH) {
4115 if (IsA16 == BaseOpcode->
A16)
4117 Error(IDLoc,
"image address size does not match a16");
4123 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4124 unsigned ActualAddrSize =
4125 IsNSA ? SrsrcIdx - VAddr0Idx
4128 unsigned ExpectedAddrSize =
4132 if (hasPartialNSAEncoding() &&
4135 int VAddrLastIdx = SrsrcIdx - 1;
4136 unsigned VAddrLastSize =
4139 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4142 if (ExpectedAddrSize > 12)
4143 ExpectedAddrSize = 16;
4148 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4152 if (ActualAddrSize == ExpectedAddrSize)
4155 Error(IDLoc,
"image address size does not match dim and a16");
4159bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4166 if (!
Desc.mayLoad() || !
Desc.mayStore())
4169 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4176 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4179bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4187 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4195 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4198bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4213 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4214 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4221bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4229 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4232 if (!BaseOpcode->
MSAA)
4235 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4241 return DimInfo->
MSAA;
4247 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4248 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4249 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4259bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4268 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4271 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4279 Error(getOperandLoc(
Operands, Src0Idx),
"source operand must be a VGPR");
4283bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4288 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4291 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4294 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4302 "source operand must be either a VGPR or an inline constant");
4309bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4312 const MCInstrDesc &
Desc = MII.
get(Opcode);
4315 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4318 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4322 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4324 "inline constants are not allowed for this operand");
4331bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4339 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4340 if (BlgpIdx != -1) {
4341 if (
const MFMA_F8F6F4_Info *
Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4342 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4352 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4354 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4359 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4361 "wrong register tuple size for blgp value " + Twine(BLGP));
4369 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4373 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4377 MCRegister Src2Reg = Src2.
getReg();
4379 if (Src2Reg == DstReg)
4383 if (
TRI->getRegClass(
Desc.operands()[0].RegClass).getSizeInBits() <= 128)
4386 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4388 "source 2 operand must not partially overlap with dst");
4395bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4399 case V_DIV_SCALE_F32_gfx6_gfx7:
4400 case V_DIV_SCALE_F32_vi:
4401 case V_DIV_SCALE_F32_gfx10:
4402 case V_DIV_SCALE_F64_gfx6_gfx7:
4403 case V_DIV_SCALE_F64_vi:
4404 case V_DIV_SCALE_F64_gfx10:
4410 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4411 AMDGPU::OpName::src2_modifiers,
4412 AMDGPU::OpName::src2_modifiers}) {
4423bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4431 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4440bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4447 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4455 case AMDGPU::V_SUBREV_F32_e32:
4456 case AMDGPU::V_SUBREV_F32_e64:
4457 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4458 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4459 case AMDGPU::V_SUBREV_F32_e32_vi:
4460 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4461 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4462 case AMDGPU::V_SUBREV_F32_e64_vi:
4464 case AMDGPU::V_SUBREV_CO_U32_e32:
4465 case AMDGPU::V_SUBREV_CO_U32_e64:
4466 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4467 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4469 case AMDGPU::V_SUBBREV_U32_e32:
4470 case AMDGPU::V_SUBBREV_U32_e64:
4471 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4472 case AMDGPU::V_SUBBREV_U32_e32_vi:
4473 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4474 case AMDGPU::V_SUBBREV_U32_e64_vi:
4476 case AMDGPU::V_SUBREV_U32_e32:
4477 case AMDGPU::V_SUBREV_U32_e64:
4478 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4479 case AMDGPU::V_SUBREV_U32_e32_vi:
4480 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4481 case AMDGPU::V_SUBREV_U32_e64_vi:
4483 case AMDGPU::V_SUBREV_F16_e32:
4484 case AMDGPU::V_SUBREV_F16_e64:
4485 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4486 case AMDGPU::V_SUBREV_F16_e32_vi:
4487 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4488 case AMDGPU::V_SUBREV_F16_e64_vi:
4490 case AMDGPU::V_SUBREV_U16_e32:
4491 case AMDGPU::V_SUBREV_U16_e64:
4492 case AMDGPU::V_SUBREV_U16_e32_vi:
4493 case AMDGPU::V_SUBREV_U16_e64_vi:
4495 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4496 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4497 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4499 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4500 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4502 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4503 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4505 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4506 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4508 case AMDGPU::V_LSHRREV_B32_e32:
4509 case AMDGPU::V_LSHRREV_B32_e64:
4510 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4511 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4512 case AMDGPU::V_LSHRREV_B32_e32_vi:
4513 case AMDGPU::V_LSHRREV_B32_e64_vi:
4514 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4515 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4517 case AMDGPU::V_ASHRREV_I32_e32:
4518 case AMDGPU::V_ASHRREV_I32_e64:
4519 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4520 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4521 case AMDGPU::V_ASHRREV_I32_e32_vi:
4522 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4523 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4524 case AMDGPU::V_ASHRREV_I32_e64_vi:
4526 case AMDGPU::V_LSHLREV_B32_e32:
4527 case AMDGPU::V_LSHLREV_B32_e64:
4528 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4529 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4530 case AMDGPU::V_LSHLREV_B32_e32_vi:
4531 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4532 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4533 case AMDGPU::V_LSHLREV_B32_e64_vi:
4535 case AMDGPU::V_LSHLREV_B16_e32:
4536 case AMDGPU::V_LSHLREV_B16_e64:
4537 case AMDGPU::V_LSHLREV_B16_e32_vi:
4538 case AMDGPU::V_LSHLREV_B16_e64_vi:
4539 case AMDGPU::V_LSHLREV_B16_gfx10:
4541 case AMDGPU::V_LSHRREV_B16_e32:
4542 case AMDGPU::V_LSHRREV_B16_e64:
4543 case AMDGPU::V_LSHRREV_B16_e32_vi:
4544 case AMDGPU::V_LSHRREV_B16_e64_vi:
4545 case AMDGPU::V_LSHRREV_B16_gfx10:
4547 case AMDGPU::V_ASHRREV_I16_e32:
4548 case AMDGPU::V_ASHRREV_I16_e64:
4549 case AMDGPU::V_ASHRREV_I16_e32_vi:
4550 case AMDGPU::V_ASHRREV_I16_e64_vi:
4551 case AMDGPU::V_ASHRREV_I16_gfx10:
4553 case AMDGPU::V_LSHLREV_B64_e64:
4554 case AMDGPU::V_LSHLREV_B64_gfx10:
4555 case AMDGPU::V_LSHLREV_B64_vi:
4557 case AMDGPU::V_LSHRREV_B64_e64:
4558 case AMDGPU::V_LSHRREV_B64_gfx10:
4559 case AMDGPU::V_LSHRREV_B64_vi:
4561 case AMDGPU::V_ASHRREV_I64_e64:
4562 case AMDGPU::V_ASHRREV_I64_gfx10:
4563 case AMDGPU::V_ASHRREV_I64_vi:
4565 case AMDGPU::V_PK_LSHLREV_B16:
4566 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4567 case AMDGPU::V_PK_LSHLREV_B16_vi:
4569 case AMDGPU::V_PK_LSHRREV_B16:
4570 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4571 case AMDGPU::V_PK_LSHRREV_B16_vi:
4572 case AMDGPU::V_PK_ASHRREV_I16:
4573 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4574 case AMDGPU::V_PK_ASHRREV_I16_vi:
4581bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4583 using namespace SIInstrFlags;
4584 const unsigned Opcode = Inst.
getOpcode();
4585 const MCInstrDesc &
Desc = MII.
get(Opcode);
4590 if ((
Desc.TSFlags & Enc) == 0)
4593 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4594 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4598 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4602 "lds_direct is not supported on this GPU");
4608 "lds_direct cannot be used with this instruction");
4612 if (SrcName != OpName::src0) {
4614 "lds_direct may be used as src0 only");
4624 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4625 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4626 if (
Op.isFlatOffset())
4627 return Op.getStartLoc();
4632bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4635 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4641 return validateFlatOffset(Inst,
Operands);
4644 return validateSMEMOffset(Inst,
Operands);
4650 const unsigned OffsetSize = 24;
4651 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4653 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4654 "-bit unsigned offset for buffer ops");
4658 const unsigned OffsetSize = 16;
4659 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4661 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4668bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4675 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4679 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4681 "flat offset modifier is not supported on this GPU");
4688 bool AllowNegative =
4691 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4693 Twine(
"expected a ") +
4694 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4695 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4704 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4705 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4706 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4707 return Op.getStartLoc();
4712bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4722 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4738 ?
"expected a 23-bit unsigned offset for buffer ops"
4739 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4740 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4741 :
"expected a 21-bit signed offset");
4746bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4749 const MCInstrDesc &
Desc = MII.
get(Opcode);
4753 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4754 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4756 const int OpIndices[] = { Src0Idx, Src1Idx };
4758 unsigned NumExprs = 0;
4759 unsigned NumLiterals = 0;
4762 for (
int OpIdx : OpIndices) {
4763 if (
OpIdx == -1)
break;
4768 if (MO.
isImm() && !isInlineConstant(Inst,
OpIdx)) {
4772 if (NumLiterals == 0 || LiteralValue !=
Value) {
4776 }
else if (MO.
isExpr()) {
4782 if (NumLiterals + NumExprs <= 1)
4786 "only one unique literal operand is allowed");
4790bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4793 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4803 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4804 if (OpSelIdx != -1) {
4808 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4809 if (OpSelHiIdx != -1) {
4818 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4828 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4829 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4830 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4831 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4833 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4834 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4840 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4842 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4852 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4853 if (Src2Idx != -1) {
4854 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4864bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4865 if (!hasTrue16Insts())
4867 const MCRegisterInfo *
MRI = getMRI();
4869 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4875 if (OpSelOpValue == 0)
4877 unsigned OpCount = 0;
4878 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4879 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4880 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4885 MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(
Op.getReg())) {
4887 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4888 if (OpSelOpIsHi != VGPRSuffixIsHi)
4897bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4898 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4911 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
4922 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4923 AMDGPU::OpName::src1_modifiers,
4924 AMDGPU::OpName::src2_modifiers};
4926 for (
unsigned i = 0; i < 3; ++i) {
4936bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4939 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
4940 if (DppCtrlIdx >= 0) {
4947 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl,
Operands);
4948 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
4949 :
"DP ALU dpp only supports row_newbcast");
4954 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
4955 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4958 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4960 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4964 "invalid operand for instruction");
4969 "src1 immediate operand invalid for instruction");
4979bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
4980 auto FB = getFeatureBits();
4981 return (FB[AMDGPU::FeatureWavefrontSize64] &&
Reg == AMDGPU::VCC) ||
4982 (FB[AMDGPU::FeatureWavefrontSize32] &&
Reg == AMDGPU::VCC_LO);
4986bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
4989 const MCInstrDesc &
Desc = MII.
get(Opcode);
4990 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
4992 !HasMandatoryLiteral && !
isVOPD(Opcode))
4997 std::optional<unsigned> LiteralOpIdx;
5000 for (
int OpIdx : OpIndices) {
5010 bool IsAnotherLiteral =
false;
5011 if (MO.
isImm() && !isInlineConstant(Inst,
OpIdx)) {
5012 uint64_t
Value =
static_cast<uint64_t
>(MO.
getImm());
5016 HasMandatoryLiteral);
5022 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5024 "invalid operand for instruction");
5028 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5033 }
else if (MO.
isExpr()) {
5035 IsAnotherLiteral =
true;
5038 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5039 !getFeatureBits()[FeatureVOP3Literal]) {
5041 "literal operands are not supported");
5045 if (LiteralOpIdx && IsAnotherLiteral) {
5047 getOperandLoc(
Operands, *LiteralOpIdx)),
5048 "only one unique literal operand is allowed");
5052 if (IsAnotherLiteral)
5053 LiteralOpIdx =
OpIdx;
5076bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5084 ? AMDGPU::OpName::data0
5085 : AMDGPU::OpName::vdata;
5087 const MCRegisterInfo *
MRI = getMRI();
5093 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5097 auto FB = getFeatureBits();
5098 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5099 if (DataAreg < 0 || DstAreg < 0)
5101 return DstAreg == DataAreg;
5104 return DstAreg < 1 && DataAreg < 1;
5107bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5108 auto FB = getFeatureBits();
5109 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5113 const MCRegisterInfo *
MRI = getMRI();
5116 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5119 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5123 case AMDGPU::DS_LOAD_TR6_B96:
5124 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5128 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5129 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5133 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5134 if (VAddrIdx != -1) {
5136 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5137 if ((
Sub - AMDGPU::VGPR0) & 1)
5142 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5143 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5148 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5149 const MCRegisterClass &AGPR32 =
MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
5155 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5169 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
5170 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
5172 return Op.getStartLoc();
5177bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5180 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5183 SMLoc BLGPLoc = getBLGPLoc(
Operands);
5186 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5187 auto FB = getFeatureBits();
5188 bool UsesNeg =
false;
5189 if (FB[AMDGPU::FeatureGFX940Insts]) {
5191 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5192 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5193 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5194 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5199 if (IsNeg == UsesNeg)
5203 UsesNeg ?
"invalid modifier: blgp is not supported"
5204 :
"invalid modifier: neg is not supported");
5209bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5215 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5216 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5217 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5218 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5221 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5224 if (
Reg == AMDGPU::SGPR_NULL)
5227 Error(getOperandLoc(
Operands, Src0Idx),
"src0 must be null");
5231bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5237 return validateGWS(Inst,
Operands);
5242 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5247 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS,
Operands);
5248 Error(S,
"gds modifier is not supported on this GPU");
5256bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5258 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5262 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5263 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5266 const MCRegisterInfo *
MRI = getMRI();
5267 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5269 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5272 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5274 Error(getOperandLoc(
Operands, Data0Pos),
"vgpr must be even aligned");
5281bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5283 const SMLoc &IDLoc) {
5284 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5285 AMDGPU::OpName::cpol);
5293 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5296 Error(S,
"scale_offset is not supported on this GPU");
5299 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5302 Error(S,
"nv is not supported on this GPU");
5307 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5310 Error(S,
"scale_offset is not supported for this instruction");
5314 return validateTHAndScopeBits(Inst,
Operands, CPol);
5319 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5320 Error(S,
"cache policy is not supported for SMRD instructions");
5324 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5333 if (!(TSFlags & AllowSCCModifier)) {
5334 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5338 "scc modifier is not supported for this instruction on this GPU");
5349 :
"instruction must use glc");
5354 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5357 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5359 :
"instruction must not use glc");
5367bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5369 const unsigned CPol) {
5373 const unsigned Opcode = Inst.
getOpcode();
5374 const MCInstrDesc &TID = MII.
get(Opcode);
5377 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5385 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5393 return PrintError(
"invalid th value for SMEM instruction");
5400 return PrintError(
"scope and th combination is not valid");
5406 return PrintError(
"invalid th value for atomic instructions");
5409 return PrintError(
"invalid th value for store instructions");
5412 return PrintError(
"invalid th value for load instructions");
5418bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5421 if (
Desc.mayStore() &&
5423 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE,
Operands);
5425 Error(Loc,
"TFE modifier has no meaning for store instructions");
5433bool AMDGPUAsmParser::validateSetVgprMSB(
const MCInst &Inst,
5435 if (Inst.
getOpcode() != AMDGPU::S_SET_VGPR_MSB_gfx12)
5439 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::simm16);
5441 SMLoc Loc =
Operands[1]->getStartLoc();
5442 Error(Loc,
"s_set_vgpr_msb accepts values in range [0..255]");
5449bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5455 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5456 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5460 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5462 TRI->getRegClass(
Desc.operands()[SrcIdx].RegClass).getSizeInBits();
5467 static const char *FmtNames[] = {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
5468 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
5472 "wrong register tuple size for " + Twine(FmtNames[Fmt]));
5476 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5477 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5480bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst,
5483 if (!validateLdsDirect(Inst,
Operands))
5485 if (!validateTrue16OpSel(Inst)) {
5487 "op_sel operand conflicts with 16-bit operand suffix");
5490 if (!validateSOPLiteral(Inst,
Operands))
5492 if (!validateVOPLiteral(Inst,
Operands)) {
5495 if (!validateConstantBusLimitations(Inst,
Operands)) {
5498 if (!validateVOPD(Inst,
Operands)) {
5501 if (!validateIntClampSupported(Inst)) {
5503 "integer clamping is not supported on this GPU");
5506 if (!validateOpSel(Inst)) {
5508 "invalid op_sel operand");
5511 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5513 "invalid neg_lo operand");
5516 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5518 "invalid neg_hi operand");
5521 if (!validateDPP(Inst,
Operands)) {
5525 if (!validateMIMGD16(Inst)) {
5527 "d16 modifier is not supported on this GPU");
5530 if (!validateMIMGDim(Inst,
Operands)) {
5531 Error(IDLoc,
"missing dim operand");
5534 if (!validateTensorR128(Inst)) {
5536 "instruction must set modifier r128=0");
5539 if (!validateMIMGMSAA(Inst)) {
5541 "invalid dim; must be MSAA type");
5544 if (!validateMIMGDataSize(Inst, IDLoc)) {
5547 if (!validateMIMGAddrSize(Inst, IDLoc))
5549 if (!validateMIMGAtomicDMask(Inst)) {
5551 "invalid atomic image dmask");
5554 if (!validateMIMGGatherDMask(Inst)) {
5556 "invalid image_gather dmask: only one bit must be set");
5559 if (!validateMovrels(Inst,
Operands)) {
5562 if (!validateOffset(Inst,
Operands)) {
5565 if (!validateMAIAccWrite(Inst,
Operands)) {
5568 if (!validateMAISrc2(Inst,
Operands)) {
5571 if (!validateMFMA(Inst,
Operands)) {
5574 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5578 if (!validateAGPRLdSt(Inst)) {
5579 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5580 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5581 :
"invalid register class: agpr loads and stores not supported on this GPU"
5585 if (!validateVGPRAlign(Inst)) {
5587 "invalid register class: vgpr tuples must be 64 bit aligned");
5594 if (!validateBLGP(Inst,
Operands)) {
5598 if (!validateDivScale(Inst)) {
5599 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5602 if (!validateWaitCnt(Inst,
Operands)) {
5605 if (!validateTFE(Inst,
Operands)) {
5608 if (!validateSetVgprMSB(Inst,
Operands)) {
5611 if (!validateWMMA(Inst,
Operands)) {
5620 unsigned VariantID = 0);
5624 unsigned VariantID);
5626bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5631bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5632 const FeatureBitset &FBS,
5633 ArrayRef<unsigned> Variants) {
5634 for (
auto Variant : Variants) {
5642bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5643 const SMLoc &IDLoc) {
5644 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5647 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5652 getParser().clearPendingErrors();
5656 StringRef VariantName = getMatchedVariantName();
5657 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5660 " variant of this instruction is not supported"));
5664 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5665 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5667 FeatureBitset FeaturesWS32 = getFeatureBits();
5668 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5669 .
flip(AMDGPU::FeatureWavefrontSize32);
5670 FeatureBitset AvailableFeaturesWS32 =
5671 ComputeAvailableFeatures(FeaturesWS32);
5673 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5674 return Error(IDLoc,
"instruction requires wavesize=32");
5678 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5679 return Error(IDLoc,
"instruction not supported on this GPU");
5684 return Error(IDLoc,
"invalid instruction" + Suggestion);
5690 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5691 if (
Op.isToken() && InvalidOprIdx > 1) {
5692 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5693 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5698bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5701 uint64_t &ErrorInfo,
5702 bool MatchingInlineAsm) {
5705 unsigned Result = Match_Success;
5706 for (
auto Variant : getMatchedVariants()) {
5708 auto R = MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm,
5713 if (R == Match_Success || R == Match_MissingFeature ||
5714 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5715 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5716 Result != Match_MissingFeature)) {
5720 if (R == Match_Success)
5724 if (Result == Match_Success) {
5725 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5733 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5739 case Match_MissingFeature:
5743 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5745 case Match_InvalidOperand: {
5746 SMLoc ErrorLoc = IDLoc;
5747 if (ErrorInfo != ~0ULL) {
5748 if (ErrorInfo >=
Operands.size()) {
5749 return Error(IDLoc,
"too few operands for instruction");
5751 ErrorLoc = ((AMDGPUOperand &)*
Operands[ErrorInfo]).getStartLoc();
5752 if (ErrorLoc == SMLoc())
5756 return Error(ErrorLoc,
"invalid VOPDY instruction");
5758 return Error(ErrorLoc,
"invalid operand for instruction");
5761 case Match_MnemonicFail:
5767bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5772 if (getParser().parseAbsoluteExpression(Tmp)) {
5775 Ret =
static_cast<uint32_t
>(Tmp);
5779bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5780 if (!getSTI().getTargetTriple().isAMDGCN())
5781 return TokError(
"directive only supported for amdgcn architecture");
5783 std::string TargetIDDirective;
5784 SMLoc TargetStart = getTok().getLoc();
5785 if (getParser().parseEscapedString(TargetIDDirective))
5788 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5789 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5790 return getParser().Error(TargetRange.
Start,
5791 (Twine(
".amdgcn_target directive's target id ") +
5792 Twine(TargetIDDirective) +
5793 Twine(
" does not match the specified target id ") +
5794 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5799bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5803bool AMDGPUAsmParser::calculateGPRBlocks(
5804 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5805 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5806 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5807 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5808 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5814 const MCExpr *
NumSGPRs = NextFreeSGPR;
5815 int64_t EvaluatedSGPRs;
5820 unsigned MaxAddressableNumSGPRs =
5823 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5824 !Features.
test(FeatureSGPRInitBug) &&
5825 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5826 return OutOfRangeError(SGPRRange);
5828 const MCExpr *ExtraSGPRs =
5832 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5833 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5834 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5835 return OutOfRangeError(SGPRRange);
5837 if (Features.
test(FeatureSGPRInitBug))
5844 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5845 unsigned Granule) ->
const MCExpr * {
5849 const MCExpr *AlignToGPR =
5851 const MCExpr *DivGPR =
5857 VGPRBlocks = GetNumGPRBlocks(
5866bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5867 if (!getSTI().getTargetTriple().isAMDGCN())
5868 return TokError(
"directive only supported for amdgcn architecture");
5871 return TokError(
"directive only supported for amdhsa OS");
5873 StringRef KernelName;
5874 if (getParser().parseIdentifier(KernelName))
5877 AMDGPU::MCKernelDescriptor KD =
5889 const MCExpr *NextFreeVGPR = ZeroExpr;
5891 const MCExpr *NamedBarCnt = ZeroExpr;
5892 uint64_t SharedVGPRCount = 0;
5893 uint64_t PreloadLength = 0;
5894 uint64_t PreloadOffset = 0;
5896 const MCExpr *NextFreeSGPR = ZeroExpr;
5899 unsigned ImpliedUserSGPRCount = 0;
5903 std::optional<unsigned> ExplicitUserSGPRCount;
5904 const MCExpr *ReserveVCC = OneExpr;
5905 const MCExpr *ReserveFlatScr = OneExpr;
5906 std::optional<bool> EnableWavefrontSize32;
5912 SMRange IDRange = getTok().getLocRange();
5913 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5916 if (
ID ==
".end_amdhsa_kernel")
5920 return TokError(
".amdhsa_ directives cannot be repeated");
5922 SMLoc ValStart = getLoc();
5923 const MCExpr *ExprVal;
5924 if (getParser().parseExpression(ExprVal))
5926 SMLoc ValEnd = getLoc();
5927 SMRange ValRange = SMRange(ValStart, ValEnd);
5930 uint64_t Val = IVal;
5931 bool EvaluatableExpr;
5932 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5934 return OutOfRangeError(ValRange);
5938#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5939 if (!isUInt<ENTRY##_WIDTH>(Val)) \
5940 return OutOfRangeError(RANGE); \
5941 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
5946#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
5948 return Error(IDRange.Start, "directive should have resolvable expression", \
5951 if (
ID ==
".amdhsa_group_segment_fixed_size") {
5954 return OutOfRangeError(ValRange);
5956 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
5959 return OutOfRangeError(ValRange);
5961 }
else if (
ID ==
".amdhsa_kernarg_size") {
5963 return OutOfRangeError(ValRange);
5965 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
5967 ExplicitUserSGPRCount = Val;
5968 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
5972 "directive is not supported with architected flat scratch",
5975 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
5978 ImpliedUserSGPRCount += 4;
5979 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
5982 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5985 return OutOfRangeError(ValRange);
5989 ImpliedUserSGPRCount += Val;
5990 PreloadLength = Val;
5992 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
5995 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5998 return OutOfRangeError(ValRange);
6002 PreloadOffset = Val;
6003 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6006 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6009 ImpliedUserSGPRCount += 2;
6010 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6013 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6016 ImpliedUserSGPRCount += 2;
6017 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6020 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6023 ImpliedUserSGPRCount += 2;
6024 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6027 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6030 ImpliedUserSGPRCount += 2;
6031 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6034 "directive is not supported with architected flat scratch",
6038 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6041 ImpliedUserSGPRCount += 2;
6042 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6045 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6048 ImpliedUserSGPRCount += 1;
6049 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6051 if (IVersion.
Major < 10)
6052 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6053 EnableWavefrontSize32 = Val;
6055 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6057 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6059 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6061 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6064 "directive is not supported with architected flat scratch",
6067 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6069 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6073 "directive is not supported without architected flat scratch",
6076 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6078 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6080 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6082 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6084 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6086 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6088 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6090 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6092 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6094 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6096 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6098 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6099 VGPRRange = ValRange;
6100 NextFreeVGPR = ExprVal;
6101 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6102 SGPRRange = ValRange;
6103 NextFreeSGPR = ExprVal;
6104 }
else if (
ID ==
".amdhsa_accum_offset") {
6106 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6107 AccumOffset = ExprVal;
6108 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6110 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6111 NamedBarCnt = ExprVal;
6112 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6114 return OutOfRangeError(ValRange);
6115 ReserveVCC = ExprVal;
6116 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6117 if (IVersion.
Major < 7)
6118 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6121 "directive is not supported with architected flat scratch",
6124 return OutOfRangeError(ValRange);
6125 ReserveFlatScr = ExprVal;
6126 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6127 if (IVersion.
Major < 8)
6128 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6130 return OutOfRangeError(ValRange);
6131 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6132 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6134 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6136 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6138 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6140 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6142 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6144 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6146 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6148 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6150 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6151 if (IVersion.
Major >= 12)
6152 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6154 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6156 }
else if (
ID ==
".amdhsa_ieee_mode") {
6157 if (IVersion.
Major >= 12)
6158 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6160 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6162 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6163 if (IVersion.
Major < 9)
6164 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6166 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6168 }
else if (
ID ==
".amdhsa_tg_split") {
6170 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6173 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6176 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6178 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6180 }
else if (
ID ==
".amdhsa_memory_ordered") {
6181 if (IVersion.
Major < 10)
6182 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6184 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6186 }
else if (
ID ==
".amdhsa_forward_progress") {
6187 if (IVersion.
Major < 10)
6188 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6190 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6192 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6194 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6195 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6197 SharedVGPRCount = Val;
6199 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6201 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6202 if (IVersion.
Major < 11)
6203 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6204 if (IVersion.
Major == 11) {
6206 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6210 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6213 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6216 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6218 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6220 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6222 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6225 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6227 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6229 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6231 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6233 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6235 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6237 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6239 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6241 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6243 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6244 if (IVersion.
Major < 12)
6245 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6247 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6250 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6253#undef PARSE_BITS_ENTRY
6256 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6257 return TokError(
".amdhsa_next_free_vgpr directive is required");
6259 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6260 return TokError(
".amdhsa_next_free_sgpr directive is required");
6262 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6267 if (PreloadLength) {
6273 const MCExpr *VGPRBlocks;
6274 const MCExpr *SGPRBlocks;
6275 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6276 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6277 EnableWavefrontSize32, NextFreeVGPR,
6278 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6282 int64_t EvaluatedVGPRBlocks;
6283 bool VGPRBlocksEvaluatable =
6284 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6285 if (VGPRBlocksEvaluatable &&
6287 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6288 return OutOfRangeError(VGPRRange);
6292 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6293 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6295 int64_t EvaluatedSGPRBlocks;
6296 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6298 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6299 return OutOfRangeError(SGPRRange);
6302 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6303 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6305 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6306 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6307 "enabled user SGPRs");
6311 return TokError(
"too many user SGPRs enabled");
6315 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6316 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6320 return TokError(
"too many user SGPRs enabled");
6324 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6325 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6330 return TokError(
"Kernarg size should be resolvable");
6331 uint64_t kernarg_size = IVal;
6332 if (PreloadLength && kernarg_size &&
6333 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6334 return TokError(
"Kernarg preload length + offset is larger than the "
6335 "kernarg segment size");
6338 if (!Seen.
contains(
".amdhsa_accum_offset"))
6339 return TokError(
".amdhsa_accum_offset directive is required");
6340 int64_t EvaluatedAccum;
6341 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6342 uint64_t UEvaluatedAccum = EvaluatedAccum;
6343 if (AccumEvaluatable &&
6344 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6345 return TokError(
"accum_offset should be in range [4..256] in "
6348 int64_t EvaluatedNumVGPR;
6349 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6352 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6353 return TokError(
"accum_offset exceeds total VGPR allocation");
6359 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6360 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6366 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6367 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6370 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6372 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6373 return TokError(
"shared_vgpr_count directive not valid on "
6374 "wavefront size 32");
6377 if (VGPRBlocksEvaluatable &&
6378 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6380 return TokError(
"shared_vgpr_count*2 + "
6381 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6386 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6387 NextFreeVGPR, NextFreeSGPR,
6388 ReserveVCC, ReserveFlatScr);
6392bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6394 if (ParseAsAbsoluteExpression(
Version))
6397 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6401bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6402 AMDGPUMCKernelCodeT &
C) {
6405 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6406 Parser.eatToEndOfStatement();
6410 SmallString<40> ErrStr;
6411 raw_svector_ostream Err(ErrStr);
6412 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6413 return TokError(Err.
str());
6417 if (
ID ==
"enable_wavefront_size32") {
6420 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6421 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
6422 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6424 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
6425 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6429 if (
ID ==
"wavefront_size") {
6430 if (
C.wavefront_size == 5) {
6432 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6433 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
6434 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6435 }
else if (
C.wavefront_size == 6) {
6436 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
6437 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6444bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6445 AMDGPUMCKernelCodeT KernelCode;
6454 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6457 if (
ID ==
".end_amd_kernel_code_t")
6460 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6465 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6470bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6471 StringRef KernelName;
6472 if (!parseId(KernelName,
"expected symbol name"))
6475 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6482bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6483 if (!getSTI().getTargetTriple().isAMDGCN()) {
6484 return Error(getLoc(),
6485 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6489 auto TargetIDDirective = getLexer().getTok().getStringContents();
6490 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6491 return Error(getParser().getTok().getLoc(),
"target id must match options");
6493 getTargetStreamer().EmitISAVersion();
6499bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6502 std::string HSAMetadataString;
6507 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6508 return Error(getLoc(),
"invalid HSA metadata");
6515bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6516 const char *AssemblerDirectiveEnd,
6517 std::string &CollectString) {
6519 raw_string_ostream CollectStream(CollectString);
6521 getLexer().setSkipSpace(
false);
6523 bool FoundEnd =
false;
6526 CollectStream << getTokenStr();
6530 if (trySkipId(AssemblerDirectiveEnd)) {
6535 CollectStream << Parser.parseStringToEndOfStatement()
6536 <<
getContext().getAsmInfo()->getSeparatorString();
6538 Parser.eatToEndOfStatement();
6541 getLexer().setSkipSpace(
true);
6544 return TokError(Twine(
"expected directive ") +
6545 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6552bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6558 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6559 if (!PALMetadata->setFromString(
String))
6560 return Error(getLoc(),
"invalid PAL metadata");
6565bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6567 return Error(getLoc(),
6569 "not available on non-amdpal OSes")).str());
6572 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6573 PALMetadata->setLegacy();
6576 if (ParseAsAbsoluteExpression(
Key)) {
6577 return TokError(Twine(
"invalid value in ") +
6581 return TokError(Twine(
"expected an even number of values in ") +
6584 if (ParseAsAbsoluteExpression(
Value)) {
6585 return TokError(Twine(
"invalid value in ") +
6588 PALMetadata->setRegister(
Key,
Value);
6597bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6598 if (getParser().checkForValidSection())
6602 SMLoc NameLoc = getLoc();
6603 if (getParser().parseIdentifier(Name))
6604 return TokError(
"expected identifier in directive");
6607 if (getParser().parseComma())
6613 SMLoc SizeLoc = getLoc();
6614 if (getParser().parseAbsoluteExpression(
Size))
6617 return Error(SizeLoc,
"size must be non-negative");
6618 if (
Size > LocalMemorySize)
6619 return Error(SizeLoc,
"size is too large");
6621 int64_t Alignment = 4;
6623 SMLoc AlignLoc = getLoc();
6624 if (getParser().parseAbsoluteExpression(Alignment))
6627 return Error(AlignLoc,
"alignment must be a power of two");
6632 if (Alignment >= 1u << 31)
6633 return Error(AlignLoc,
"alignment is too large");
6639 Symbol->redefineIfPossible();
6640 if (!
Symbol->isUndefined())
6641 return Error(NameLoc,
"invalid symbol redefinition");
6643 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6647bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6648 StringRef IDVal = DirectiveID.
getString();
6651 if (IDVal ==
".amdhsa_kernel")
6652 return ParseDirectiveAMDHSAKernel();
6654 if (IDVal ==
".amdhsa_code_object_version")
6655 return ParseDirectiveAMDHSACodeObjectVersion();
6659 return ParseDirectiveHSAMetadata();
6661 if (IDVal ==
".amd_kernel_code_t")
6662 return ParseDirectiveAMDKernelCodeT();
6664 if (IDVal ==
".amdgpu_hsa_kernel")
6665 return ParseDirectiveAMDGPUHsaKernel();
6667 if (IDVal ==
".amd_amdgpu_isa")
6668 return ParseDirectiveISAVersion();
6672 Twine(
" directive is "
6673 "not available on non-amdhsa OSes"))
6678 if (IDVal ==
".amdgcn_target")
6679 return ParseDirectiveAMDGCNTarget();
6681 if (IDVal ==
".amdgpu_lds")
6682 return ParseDirectiveAMDGPULDS();
6685 return ParseDirectivePALMetadataBegin();
6688 return ParseDirectivePALMetadata();
6693bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
6695 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
6699 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
6700 return hasSGPR104_SGPR105();
6703 case SRC_SHARED_BASE_LO:
6704 case SRC_SHARED_BASE:
6705 case SRC_SHARED_LIMIT_LO:
6706 case SRC_SHARED_LIMIT:
6707 case SRC_PRIVATE_BASE_LO:
6708 case SRC_PRIVATE_BASE:
6709 case SRC_PRIVATE_LIMIT_LO:
6710 case SRC_PRIVATE_LIMIT:
6712 case SRC_FLAT_SCRATCH_BASE_LO:
6713 case SRC_FLAT_SCRATCH_BASE_HI:
6714 return hasGloballyAddressableScratch();
6715 case SRC_POPS_EXITING_WAVE_ID:
6727 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6756 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
6757 return hasSGPR102_SGPR103();
6765 ParseStatus Res = parseVOPD(
Operands);
6770 Res = MatchOperandParserImpl(
Operands, Mnemonic);
6782 SMLoc LBraceLoc = getLoc();
6787 auto Loc = getLoc();
6790 Error(Loc,
"expected a register");
6794 RBraceLoc = getLoc();
6799 "expected a comma or a closing square bracket"))
6803 if (
Operands.size() - Prefix > 1) {
6805 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6806 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6815StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6817 setForcedEncodingSize(0);
6818 setForcedDPP(
false);
6819 setForcedSDWA(
false);
6821 if (
Name.consume_back(
"_e64_dpp")) {
6823 setForcedEncodingSize(64);
6826 if (
Name.consume_back(
"_e64")) {
6827 setForcedEncodingSize(64);
6830 if (
Name.consume_back(
"_e32")) {
6831 setForcedEncodingSize(32);
6834 if (
Name.consume_back(
"_dpp")) {
6838 if (
Name.consume_back(
"_sdwa")) {
6839 setForcedSDWA(
true);
6847 unsigned VariantID);
6853 Name = parseMnemonicSuffix(Name);
6859 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6861 bool IsMIMG = Name.starts_with(
"image_");
6864 OperandMode
Mode = OperandMode_Default;
6866 Mode = OperandMode_NSA;
6870 checkUnsupportedInstruction(Name, NameLoc);
6871 if (!Parser.hasPendingError()) {
6874 :
"not a valid operand.";
6875 Error(getLoc(), Msg);
6894ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6897 if (!trySkipId(Name))
6900 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6904ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6913ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6915 std::function<
bool(int64_t &)> ConvertResult) {
6919 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
6923 if (ConvertResult && !ConvertResult(
Value)) {
6924 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
6927 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6931ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6933 bool (*ConvertResult)(int64_t &)) {
6942 const unsigned MaxSize = 4;
6946 for (
int I = 0; ; ++
I) {
6948 SMLoc Loc = getLoc();
6952 if (
Op != 0 &&
Op != 1)
6953 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
6960 if (
I + 1 == MaxSize)
6961 return Error(getLoc(),
"expected a closing square bracket");
6967 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
6971ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
6973 AMDGPUOperand::ImmTy ImmTy) {
6977 if (trySkipId(Name)) {
6979 }
else if (trySkipId(
"no", Name)) {
6986 return Error(S,
"r128 modifier is not supported on this GPU");
6987 if (Name ==
"a16" && !
hasA16())
6988 return Error(S,
"a16 modifier is not supported on this GPU");
6990 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
6991 ImmTy = AMDGPUOperand::ImmTyR128A16;
6993 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
6997unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
6998 bool &Disabling)
const {
6999 Disabling =
Id.consume_front(
"no");
7002 return StringSwitch<unsigned>(Id)
7009 return StringSwitch<unsigned>(Id)
7019 SMLoc StringLoc = getLoc();
7021 int64_t CPolVal = 0;
7041 ResScope = parseScope(
Operands, Scope);
7054 if (trySkipId(
"nv")) {
7058 }
else if (trySkipId(
"no",
"nv")) {
7065 if (trySkipId(
"scale_offset")) {
7069 }
else if (trySkipId(
"no",
"scale_offset")) {
7082 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7083 AMDGPUOperand::ImmTyCPol));
7088 SMLoc OpLoc = getLoc();
7089 unsigned Enabled = 0, Seen = 0;
7093 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7100 return Error(S,
"dlc modifier is not supported on this GPU");
7103 return Error(S,
"scc modifier is not supported on this GPU");
7106 return Error(S,
"duplicate cache policy modifier");
7118 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7127 ParseStatus Res = parseStringOrIntWithPrefix(
7128 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7142 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7146 if (
Value ==
"TH_DEFAULT")
7148 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7149 Value ==
"TH_LOAD_NT_WB") {
7150 return Error(StringLoc,
"invalid th value");
7151 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7153 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7155 }
else if (
Value.consume_front(
"TH_STORE_")) {
7158 return Error(StringLoc,
"invalid th value");
7161 if (
Value ==
"BYPASS")
7166 TH |= StringSwitch<int64_t>(
Value)
7176 .Default(0xffffffff);
7178 TH |= StringSwitch<int64_t>(
Value)
7189 .Default(0xffffffff);
7192 if (TH == 0xffffffff)
7193 return Error(StringLoc,
"invalid th value");
7200 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7201 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7202 std::optional<unsigned> InsertAt = std::nullopt) {
7203 auto i = OptionalIdx.find(ImmT);
7204 if (i != OptionalIdx.end()) {
7205 unsigned Idx = i->second;
7206 const AMDGPUOperand &
Op =
7207 static_cast<const AMDGPUOperand &
>(*
Operands[Idx]);
7211 Op.addImmOperands(Inst, 1);
7213 if (InsertAt.has_value())
7220ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7226 StringLoc = getLoc();
7231ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7237 SMLoc StringLoc = getLoc();
7241 Value = getTokenStr();
7245 if (
Value == Ids[IntVal])
7250 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7251 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7256ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7258 AMDGPUOperand::ImmTy
Type) {
7262 ParseStatus Res = parseStringOrIntWithPrefix(
Operands, Name, Ids, IntVal);
7264 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7273bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7277 SMLoc Loc = getLoc();
7279 auto Res = parseIntWithPrefix(Pref, Val);
7285 if (Val < 0 || Val > MaxVal) {
7286 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7295 AMDGPUOperand::ImmTy ImmTy) {
7296 const char *Pref =
"index_key";
7298 SMLoc Loc = getLoc();
7299 auto Res = parseIntWithPrefix(Pref, ImmVal);
7303 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7304 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7305 (ImmVal < 0 || ImmVal > 1))
7306 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7308 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7309 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7311 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7316 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7320 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7324 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7329 AMDGPUOperand::ImmTy
Type) {
7330 return parseStringOrIntWithPrefix(
Operands, Name,
7331 {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
7332 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
7338 return tryParseMatrixFMT(
Operands,
"matrix_a_fmt",
7339 AMDGPUOperand::ImmTyMatrixAFMT);
7343 return tryParseMatrixFMT(
Operands,
"matrix_b_fmt",
7344 AMDGPUOperand::ImmTyMatrixBFMT);
7349 AMDGPUOperand::ImmTy
Type) {
7350 return parseStringOrIntWithPrefix(
7351 Operands, Name, {
"MATRIX_SCALE_ROW0",
"MATRIX_SCALE_ROW1"},
Type);
7355 return tryParseMatrixScale(
Operands,
"matrix_a_scale",
7356 AMDGPUOperand::ImmTyMatrixAScale);
7360 return tryParseMatrixScale(
Operands,
"matrix_b_scale",
7361 AMDGPUOperand::ImmTyMatrixBScale);
7366 AMDGPUOperand::ImmTy
Type) {
7367 return parseStringOrIntWithPrefix(
7369 {
"MATRIX_SCALE_FMT_E8",
"MATRIX_SCALE_FMT_E5M3",
"MATRIX_SCALE_FMT_E4M3"},
7374 return tryParseMatrixScaleFmt(
Operands,
"matrix_a_scale_fmt",
7375 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7379 return tryParseMatrixScaleFmt(
Operands,
"matrix_b_scale_fmt",
7380 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7385ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7386 using namespace llvm::AMDGPU::MTBUFFormat;
7392 for (
int I = 0;
I < 2; ++
I) {
7393 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7396 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7401 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7407 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7410 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7411 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7417ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7418 using namespace llvm::AMDGPU::MTBUFFormat;
7422 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7425 if (Fmt == UFMT_UNDEF)
7432bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7434 StringRef FormatStr,
7436 using namespace llvm::AMDGPU::MTBUFFormat;
7440 if (
Format != DFMT_UNDEF) {
7446 if (
Format != NFMT_UNDEF) {
7451 Error(Loc,
"unsupported format");
7455ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7458 using namespace llvm::AMDGPU::MTBUFFormat;
7462 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7467 SMLoc Loc = getLoc();
7468 if (!parseId(Str,
"expected a format string") ||
7469 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7471 if (Dfmt == DFMT_UNDEF)
7472 return Error(Loc,
"duplicate numeric format");
7473 if (Nfmt == NFMT_UNDEF)
7474 return Error(Loc,
"duplicate data format");
7477 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7478 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7482 if (Ufmt == UFMT_UNDEF)
7483 return Error(FormatLoc,
"unsupported format");
7492ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7495 using namespace llvm::AMDGPU::MTBUFFormat;
7498 if (Id == UFMT_UNDEF)
7502 return Error(Loc,
"unified format is not supported on this GPU");
7508ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7509 using namespace llvm::AMDGPU::MTBUFFormat;
7510 SMLoc Loc = getLoc();
7515 return Error(Loc,
"out of range format");
7520ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7521 using namespace llvm::AMDGPU::MTBUFFormat;
7527 StringRef FormatStr;
7528 SMLoc Loc = getLoc();
7529 if (!parseId(FormatStr,
"expected a format string"))
7532 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7534 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7544 return parseNumericFormat(
Format);
7548 using namespace llvm::AMDGPU::MTBUFFormat;
7552 SMLoc Loc = getLoc();
7562 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7581 Res = parseSymbolicOrNumericFormat(
Format);
7586 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
7587 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7594 return Error(getLoc(),
"duplicate format");
7600 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
7602 Res = parseIntWithPrefix(
"inst_offset",
Operands,
7603 AMDGPUOperand::ImmTyInstOffset);
7610 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
7612 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
7618 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
7621 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
7631 OptionalImmIndexMap OptionalIdx;
7633 unsigned OperandIdx[4];
7634 unsigned EnMask = 0;
7637 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
7638 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7643 OperandIdx[SrcIdx] = Inst.
size();
7644 Op.addRegOperands(Inst, 1);
7651 OperandIdx[SrcIdx] = Inst.
size();
7657 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7658 Op.addImmOperands(Inst, 1);
7662 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7666 OptionalIdx[
Op.getImmTy()] = i;
7672 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7679 for (
auto i = 0; i < SrcIdx; ++i) {
7681 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7706 IntVal =
encode(ISA, IntVal, CntVal);
7707 if (CntVal !=
decode(ISA, IntVal)) {
7709 IntVal =
encode(ISA, IntVal, -1);
7717bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7719 SMLoc CntLoc = getLoc();
7720 StringRef CntName = getTokenStr();
7727 SMLoc ValLoc = getLoc();
7736 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7738 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7740 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7743 Error(CntLoc,
"invalid counter name " + CntName);
7748 Error(ValLoc,
"too large value for " + CntName);
7757 Error(getLoc(),
"expected a counter name");
7772 if (!parseCnt(Waitcnt))
7780 Operands.push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7784bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7785 SMLoc FieldLoc = getLoc();
7786 StringRef FieldName = getTokenStr();
7791 SMLoc ValueLoc = getLoc();
7798 if (FieldName ==
"instid0") {
7800 }
else if (FieldName ==
"instskip") {
7802 }
else if (FieldName ==
"instid1") {
7805 Error(FieldLoc,
"invalid field name " + FieldName);
7824 .Case(
"VALU_DEP_1", 1)
7825 .Case(
"VALU_DEP_2", 2)
7826 .Case(
"VALU_DEP_3", 3)
7827 .Case(
"VALU_DEP_4", 4)
7828 .Case(
"TRANS32_DEP_1", 5)
7829 .Case(
"TRANS32_DEP_2", 6)
7830 .Case(
"TRANS32_DEP_3", 7)
7831 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7832 .Case(
"SALU_CYCLE_1", 9)
7833 .Case(
"SALU_CYCLE_2", 10)
7834 .Case(
"SALU_CYCLE_3", 11)
7842 Delay |=
Value << Shift;
7852 if (!parseDelay(Delay))
7860 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7865AMDGPUOperand::isSWaitCnt()
const {
7869bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7875void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7876 StringRef DepCtrName) {
7879 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7882 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7885 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7888 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7895bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7897 using namespace llvm::AMDGPU::DepCtr;
7899 SMLoc DepCtrLoc = getLoc();
7900 StringRef DepCtrName = getTokenStr();
7910 unsigned PrevOprMask = UsedOprMask;
7911 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7914 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7923 Error(getLoc(),
"expected a counter name");
7928 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7929 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7934 using namespace llvm::AMDGPU::DepCtr;
7937 SMLoc Loc = getLoc();
7940 unsigned UsedOprMask = 0;
7942 if (!parseDepCtr(DepCtr, UsedOprMask))
7950 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
7954bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
7960ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
7962 OperandInfoTy &Width) {
7963 using namespace llvm::AMDGPU::Hwreg;
7969 HwReg.Loc = getLoc();
7972 HwReg.IsSymbolic =
true;
7974 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
7982 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
7992 Width.Loc = getLoc();
8001 using namespace llvm::AMDGPU::Hwreg;
8004 SMLoc Loc = getLoc();
8006 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8008 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8009 HwregOffset::Default);
8010 struct : StructuredOpField {
8011 using StructuredOpField::StructuredOpField;
8012 bool validate(AMDGPUAsmParser &Parser)
const override {
8014 return Error(Parser,
"only values from 1 to 32 are legal");
8017 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8018 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8021 Res = parseHwregFunc(HwReg,
Offset, Width);
8024 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8026 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8030 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8037 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8039 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8043bool AMDGPUOperand::isHwreg()
const {
8044 return isImmTy(ImmTyHwreg);
8052AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8054 OperandInfoTy &Stream) {
8055 using namespace llvm::AMDGPU::SendMsg;
8060 Msg.IsSymbolic =
true;
8062 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8067 Op.IsDefined =
true;
8070 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8073 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8078 Stream.IsDefined =
true;
8079 Stream.Loc = getLoc();
8089AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8090 const OperandInfoTy &
Op,
8091 const OperandInfoTy &Stream) {
8092 using namespace llvm::AMDGPU::SendMsg;
8097 bool Strict = Msg.IsSymbolic;
8101 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8106 Error(Msg.Loc,
"invalid message id");
8112 Error(
Op.Loc,
"message does not support operations");
8114 Error(Msg.Loc,
"missing message operation");
8120 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8122 Error(
Op.Loc,
"invalid operation id");
8127 Error(Stream.Loc,
"message operation does not support streams");
8131 Error(Stream.Loc,
"invalid message stream id");
8138 using namespace llvm::AMDGPU::SendMsg;
8141 SMLoc Loc = getLoc();
8145 OperandInfoTy
Op(OP_NONE_);
8146 OperandInfoTy Stream(STREAM_ID_NONE_);
8147 if (parseSendMsgBody(Msg,
Op, Stream) &&
8148 validateSendMsg(Msg,
Op, Stream)) {
8153 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8155 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8160 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8164bool AMDGPUOperand::isSendMsg()
const {
8165 return isImmTy(ImmTySendMsg);
8179 int Slot = StringSwitch<int>(Str)
8186 return Error(S,
"invalid interpolation slot");
8188 Operands.push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8189 AMDGPUOperand::ImmTyInterpSlot));
8200 if (!Str.starts_with(
"attr"))
8201 return Error(S,
"invalid interpolation attribute");
8203 StringRef Chan = Str.take_back(2);
8204 int AttrChan = StringSwitch<int>(Chan)
8211 return Error(S,
"invalid or missing interpolation attribute channel");
8213 Str = Str.drop_back(2).drop_front(4);
8216 if (Str.getAsInteger(10, Attr))
8217 return Error(S,
"invalid or missing interpolation attribute number");
8220 return Error(S,
"out of bounds interpolation attribute number");
8224 Operands.push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8225 AMDGPUOperand::ImmTyInterpAttr));
8226 Operands.push_back(AMDGPUOperand::CreateImm(
8227 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8236 using namespace llvm::AMDGPU::Exp;
8246 return Error(S, (Id == ET_INVALID)
8247 ?
"invalid exp target"
8248 :
"exp target is not supported on this GPU");
8250 Operands.push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8251 AMDGPUOperand::ImmTyExpTgt));
8260AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8265AMDGPUAsmParser::isId(
const StringRef Id)
const {
8271 return getTokenKind() ==
Kind;
8274StringRef AMDGPUAsmParser::getId()
const {
8279AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8288AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8290 StringRef Tok = getTokenStr();
8301 if (isId(Id) && peekToken().is(Kind)) {
8311 if (isToken(Kind)) {
8320 const StringRef ErrMsg) {
8321 if (!trySkipToken(Kind)) {
8322 Error(getLoc(), ErrMsg);
8329AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8333 if (Parser.parseExpression(Expr))
8336 if (Expr->evaluateAsAbsolute(
Imm))
8339 if (Expected.empty()) {
8340 Error(S,
"expected absolute expression");
8342 Error(S, Twine(
"expected ", Expected) +
8343 Twine(
" or an absolute expression"));
8353 if (Parser.parseExpression(Expr))
8357 if (Expr->evaluateAsAbsolute(IntVal)) {
8358 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8360 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8366AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8368 Val =
getToken().getStringContents();
8372 Error(getLoc(), ErrMsg);
8377AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8379 Val = getTokenStr();
8383 if (!ErrMsg.
empty())
8384 Error(getLoc(), ErrMsg);
8389AMDGPUAsmParser::getToken()
const {
8390 return Parser.getTok();
8393AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8396 : getLexer().peekTok(ShouldSkipSpace);
8401 auto TokCount = getLexer().peekTokens(Tokens);
8403 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8408AMDGPUAsmParser::getTokenKind()
const {
8409 return getLexer().getKind();
8413AMDGPUAsmParser::getLoc()
const {
8418AMDGPUAsmParser::getTokenStr()
const {
8423AMDGPUAsmParser::lex() {
8428 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
8432SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8437 int MCOpIdx)
const {
8439 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8440 if (TargetOp.getMCOpIdx() == MCOpIdx)
8441 return TargetOp.getStartLoc();
8447AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8449 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
8450 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8452 return Op.getStartLoc();
8458AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8460 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8475 StringRef
Id = getTokenStr();
8476 SMLoc IdLoc = getLoc();
8482 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8483 if (
I == Fields.
end())
8484 return Error(IdLoc,
"unknown field");
8485 if ((*I)->IsDefined)
8486 return Error(IdLoc,
"duplicate field");
8489 (*I)->Loc = getLoc();
8492 (*I)->IsDefined =
true;
8499bool AMDGPUAsmParser::validateStructuredOpFields(
8501 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8502 return F->validate(*
this);
8513 const unsigned OrMask,
8514 const unsigned XorMask) {
8523bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8524 const unsigned MaxVal,
8525 const Twine &ErrMsg, SMLoc &Loc) {
8542AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8543 const unsigned MinVal,
8544 const unsigned MaxVal,
8545 const StringRef ErrMsg) {
8547 for (
unsigned i = 0; i < OpNum; ++i) {
8548 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8556AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8557 using namespace llvm::AMDGPU::Swizzle;
8560 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8561 "expected a 2-bit lane id")) {
8572AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8573 using namespace llvm::AMDGPU::Swizzle;
8579 if (!parseSwizzleOperand(GroupSize,
8581 "group size must be in the interval [2,32]",
8586 Error(Loc,
"group size must be a power of two");
8589 if (parseSwizzleOperand(LaneIdx,
8591 "lane id must be in the interval [0,group size - 1]",
8600AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8601 using namespace llvm::AMDGPU::Swizzle;
8606 if (!parseSwizzleOperand(GroupSize,
8608 "group size must be in the interval [2,32]",
8613 Error(Loc,
"group size must be a power of two");
8622AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8623 using namespace llvm::AMDGPU::Swizzle;
8628 if (!parseSwizzleOperand(GroupSize,
8630 "group size must be in the interval [1,16]",
8635 Error(Loc,
"group size must be a power of two");
8644AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8645 using namespace llvm::AMDGPU::Swizzle;
8652 SMLoc StrLoc = getLoc();
8653 if (!parseString(Ctl)) {
8656 if (Ctl.
size() != BITMASK_WIDTH) {
8657 Error(StrLoc,
"expected a 5-character mask");
8661 unsigned AndMask = 0;
8662 unsigned OrMask = 0;
8663 unsigned XorMask = 0;
8665 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8669 Error(StrLoc,
"invalid mask");
8690bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8691 using namespace llvm::AMDGPU::Swizzle;
8694 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8700 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8701 "FFT swizzle must be in the interval [0," +
8702 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8710bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8711 using namespace llvm::AMDGPU::Swizzle;
8714 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8721 if (!parseSwizzleOperand(
Direction, 0, 1,
8722 "direction must be 0 (left) or 1 (right)", Loc))
8726 if (!parseSwizzleOperand(
8727 RotateSize, 0, ROTATE_MAX_SIZE,
8728 "number of threads to rotate must be in the interval [0," +
8729 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8734 (RotateSize << ROTATE_SIZE_SHIFT);
8739AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8741 SMLoc OffsetLoc = getLoc();
8747 Error(OffsetLoc,
"expected a 16-bit offset");
8754AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8755 using namespace llvm::AMDGPU::Swizzle;
8759 SMLoc ModeLoc = getLoc();
8762 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8763 Ok = parseSwizzleQuadPerm(
Imm);
8764 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8765 Ok = parseSwizzleBitmaskPerm(
Imm);
8766 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8767 Ok = parseSwizzleBroadcast(
Imm);
8768 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8769 Ok = parseSwizzleSwap(
Imm);
8770 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8771 Ok = parseSwizzleReverse(
Imm);
8772 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8773 Ok = parseSwizzleFFT(
Imm);
8774 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8775 Ok = parseSwizzleRotate(
Imm);
8777 Error(ModeLoc,
"expected a swizzle mode");
8780 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8790 if (trySkipId(
"offset")) {
8794 if (trySkipId(
"swizzle")) {
8795 Ok = parseSwizzleMacro(
Imm);
8797 Ok = parseSwizzleOffset(
Imm);
8801 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8809AMDGPUOperand::isSwizzle()
const {
8810 return isImmTy(ImmTySwizzle);
8817int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8819 using namespace llvm::AMDGPU::VGPRIndexMode;
8831 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8832 if (trySkipId(IdSymbolic[ModeId])) {
8840 "expected a VGPR index mode or a closing parenthesis" :
8841 "expected a VGPR index mode");
8846 Error(S,
"duplicate VGPR index mode");
8854 "expected a comma or a closing parenthesis"))
8863 using namespace llvm::AMDGPU::VGPRIndexMode;
8869 Imm = parseGPRIdxMacro();
8873 if (getParser().parseAbsoluteExpression(
Imm))
8876 return Error(S,
"invalid immediate: only 4-bit values are legal");
8880 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8884bool AMDGPUOperand::isGPRIdxMode()
const {
8885 return isImmTy(ImmTyGprIdxMode);
8897 if (isRegister() || isModifier())
8904 assert(Opr.isImm() || Opr.isExpr());
8905 SMLoc Loc = Opr.getStartLoc();
8909 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8910 Error(Loc,
"expected an absolute expression or a label");
8911 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8912 Error(Loc,
"expected a 16-bit signed jump offset");
8930void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
8933 OptionalImmIndexMap OptionalIdx;
8934 unsigned FirstOperandIdx = 1;
8935 bool IsAtomicReturn =
false;
8942 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
8943 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8947 Op.addRegOperands(Inst, 1);
8951 if (IsAtomicReturn && i == FirstOperandIdx)
8952 Op.addRegOperands(Inst, 1);
8957 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
8958 Op.addImmOperands(Inst, 1);
8970 OptionalIdx[
Op.getImmTy()] = i;
8981bool AMDGPUOperand::isSMRDOffset8()
const {
8985bool AMDGPUOperand::isSMEMOffset()
const {
8987 return isImmLiteral();
8990bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9025bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9026 if (BoundCtrl == 0 || BoundCtrl == 1) {
9034void AMDGPUAsmParser::onBeginOfFile() {
9035 if (!getParser().getStreamer().getTargetStreamer() ||
9039 if (!getTargetStreamer().getTargetID())
9040 getTargetStreamer().initializeTargetID(getSTI(),
9041 getSTI().getFeatureString());
9044 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9052bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9056 StringRef TokenId = getTokenStr();
9057 AGVK VK = StringSwitch<AGVK>(TokenId)
9058 .Case(
"max", AGVK::AGVK_Max)
9059 .Case(
"or", AGVK::AGVK_Or)
9060 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9061 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9062 .Case(
"alignto", AGVK::AGVK_AlignTo)
9063 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9064 .Default(AGVK::AGVK_None);
9068 uint64_t CommaCount = 0;
9073 if (Exprs.
empty()) {
9075 "empty " + Twine(TokenId) +
" expression");
9078 if (CommaCount + 1 != Exprs.
size()) {
9080 "mismatch of commas in " + Twine(TokenId) +
" expression");
9087 if (getParser().parseExpression(Expr, EndLoc))
9091 if (LastTokenWasComma)
9095 "unexpected token in " + Twine(TokenId) +
" expression");
9101 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9105 StringRef
Name = getTokenStr();
9106 if (Name ==
"mul") {
9107 return parseIntWithPrefix(
"mul",
Operands,
9111 if (Name ==
"div") {
9112 return parseIntWithPrefix(
"div",
Operands,
9123 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9128 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9129 AMDGPU::OpName::src2};
9137 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9142 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9144 if (
DstOp.isReg() &&
9145 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9149 if ((OpSel & (1 << SrcNum)) != 0)
9155void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9162 OptionalImmIndexMap &OptionalIdx) {
9163 cvtVOP3P(Inst,
Operands, OptionalIdx);
9172 &&
Desc.NumOperands > (OpNum + 1)
9174 &&
Desc.operands()[OpNum + 1].RegClass != -1
9176 &&
Desc.getOperandConstraint(OpNum + 1,
9182 OptionalImmIndexMap OptionalIdx;
9187 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9188 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9192 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9194 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9195 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9196 Op.isInterpAttrChan()) {
9198 }
else if (
Op.isImmModifier()) {
9199 OptionalIdx[
Op.getImmTy()] =
I;
9207 AMDGPUOperand::ImmTyHigh);
9211 AMDGPUOperand::ImmTyClamp);
9215 AMDGPUOperand::ImmTyOModSI);
9220 OptionalImmIndexMap OptionalIdx;
9225 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9226 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9230 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9232 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9233 }
else if (
Op.isImmModifier()) {
9234 OptionalIdx[
Op.getImmTy()] =
I;
9242 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9251 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9252 AMDGPU::OpName::src2};
9253 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9254 AMDGPU::OpName::src1_modifiers,
9255 AMDGPU::OpName::src2_modifiers};
9259 for (
int J = 0; J < 3; ++J) {
9260 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9264 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9267 if ((OpSel & (1 << J)) != 0)
9269 if (ModOps[J] == AMDGPU::OpName::src0_modifiers &&
9270 (OpSel & (1 << 3)) != 0)
9276void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9278 OptionalImmIndexMap OptionalIdx;
9281 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9285 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9286 static_cast<AMDGPUOperand &
>(*
Operands[
I++]).addRegOperands(Inst, 1);
9289 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
I]);
9294 if (NumOperands == CbszOpIdx) {
9299 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9300 }
else if (
Op.isImmModifier()) {
9301 OptionalIdx[
Op.getImmTy()] =
I;
9303 Op.addRegOrImmOperands(Inst, 1);
9308 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9309 if (CbszIdx != OptionalIdx.end()) {
9310 int CbszVal = ((AMDGPUOperand &)*
Operands[CbszIdx->second]).
getImm();
9314 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9315 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9316 if (BlgpIdx != OptionalIdx.end()) {
9317 int BlgpVal = ((AMDGPUOperand &)*
Operands[BlgpIdx->second]).
getImm();
9328 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9329 if (OpselIdx != OptionalIdx.end()) {
9330 OpSel =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselIdx->second])
9334 unsigned OpSelHi = 0;
9335 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9336 if (OpselHiIdx != OptionalIdx.end()) {
9337 OpSelHi =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselHiIdx->second])
9340 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9341 AMDGPU::OpName::src1_modifiers};
9343 for (
unsigned J = 0; J < 2; ++J) {
9344 unsigned ModVal = 0;
9345 if (OpSel & (1 << J))
9347 if (OpSelHi & (1 << J))
9350 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9356 OptionalImmIndexMap &OptionalIdx) {
9361 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9362 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9366 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9368 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9369 }
else if (
Op.isImmModifier()) {
9370 OptionalIdx[
Op.getImmTy()] =
I;
9372 Op.addRegOrImmOperands(Inst, 1);
9378 AMDGPUOperand::ImmTyScaleSel);
9382 AMDGPUOperand::ImmTyClamp);
9388 AMDGPUOperand::ImmTyByteSel);
9393 AMDGPUOperand::ImmTyOModSI);
9400 auto *it = Inst.
begin();
9401 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9410 OptionalImmIndexMap OptionalIdx;
9411 cvtVOP3(Inst,
Operands, OptionalIdx);
9415 OptionalImmIndexMap &OptIdx) {
9421 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9422 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9423 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9424 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9425 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9426 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9434 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9435 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9436 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9437 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9438 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9439 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9440 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9441 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9442 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9443 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9444 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9445 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9446 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9447 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9448 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9449 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9450 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9451 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9452 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9453 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9454 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9455 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9456 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9457 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9458 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9459 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9463 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9464 if (BitOp3Idx != -1) {
9471 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9472 if (OpSelIdx != -1) {
9476 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9477 if (OpSelHiIdx != -1) {
9484 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9485 if (MatrixAFMTIdx != -1) {
9487 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9491 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9492 if (MatrixBFMTIdx != -1) {
9494 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9497 int MatrixAScaleIdx =
9498 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9499 if (MatrixAScaleIdx != -1) {
9501 AMDGPUOperand::ImmTyMatrixAScale, 0);
9504 int MatrixBScaleIdx =
9505 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9506 if (MatrixBScaleIdx != -1) {
9508 AMDGPUOperand::ImmTyMatrixBScale, 0);
9511 int MatrixAScaleFmtIdx =
9512 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9513 if (MatrixAScaleFmtIdx != -1) {
9515 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9518 int MatrixBScaleFmtIdx =
9519 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9520 if (MatrixBScaleFmtIdx != -1) {
9522 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9527 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9531 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9533 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9537 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9541 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9542 AMDGPU::OpName::src2};
9543 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9544 AMDGPU::OpName::src1_modifiers,
9545 AMDGPU::OpName::src2_modifiers};
9548 unsigned OpSelHi = 0;
9555 if (OpSelHiIdx != -1)
9564 for (
int J = 0; J < 3; ++J) {
9565 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9569 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9574 uint32_t ModVal = 0;
9577 if (SrcOp.
isReg() && getMRI()
9584 if ((OpSel & (1 << J)) != 0)
9588 if ((OpSelHi & (1 << J)) != 0)
9591 if ((NegLo & (1 << J)) != 0)
9594 if ((NegHi & (1 << J)) != 0)
9602 OptionalImmIndexMap OptIdx;
9608 unsigned i,
unsigned Opc,
9610 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9611 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9613 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9619 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
9622 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
9623 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
9625 OptionalImmIndexMap OptIdx;
9626 for (
unsigned i = 5; i <
Operands.size(); ++i) {
9627 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
9628 OptIdx[
Op.getImmTy()] = i;
9633 AMDGPUOperand::ImmTyIndexKey8bit);
9637 AMDGPUOperand::ImmTyIndexKey16bit);
9641 AMDGPUOperand::ImmTyIndexKey32bit);
9661 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9662 SMLoc OpYLoc = getLoc();
9665 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9668 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9677 auto addOp = [&](uint16_t ParsedOprIdx) {
9678 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
9680 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9684 Op.addRegOperands(Inst, 1);
9688 Op.addImmOperands(Inst, 1);
9700 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9704 const auto &CInfo = InstInfo[CompIdx];
9705 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9706 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9707 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9708 if (CInfo.hasSrc2Acc())
9709 addOp(CInfo.getIndexOfDstInParsedOperands());
9713 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9714 if (BitOp3Idx != -1) {
9715 OptionalImmIndexMap OptIdx;
9716 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands.back());
9728bool AMDGPUOperand::isDPP8()
const {
9729 return isImmTy(ImmTyDPP8);
9732bool AMDGPUOperand::isDPPCtrl()
const {
9733 using namespace AMDGPU::DPP;
9735 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9738 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9739 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9740 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9741 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9742 (
Imm == DppCtrl::WAVE_SHL1) ||
9743 (
Imm == DppCtrl::WAVE_ROL1) ||
9744 (
Imm == DppCtrl::WAVE_SHR1) ||
9745 (
Imm == DppCtrl::WAVE_ROR1) ||
9746 (
Imm == DppCtrl::ROW_MIRROR) ||
9747 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9748 (
Imm == DppCtrl::BCAST15) ||
9749 (
Imm == DppCtrl::BCAST31) ||
9750 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9751 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9760bool AMDGPUOperand::isBLGP()
const {
9764bool AMDGPUOperand::isS16Imm()
const {
9768bool AMDGPUOperand::isU16Imm()
const {
9776bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9781 SMLoc Loc =
getToken().getEndLoc();
9782 Token = std::string(getTokenStr());
9784 if (getLoc() != Loc)
9789 if (!parseId(Suffix))
9793 StringRef DimId = Token;
9814 SMLoc Loc = getLoc();
9815 if (!parseDimId(Encoding))
9816 return Error(Loc,
"invalid dim value");
9818 Operands.push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9819 AMDGPUOperand::ImmTyDim));
9837 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9840 for (
size_t i = 0; i < 8; ++i) {
9844 SMLoc Loc = getLoc();
9845 if (getParser().parseAbsoluteExpression(Sels[i]))
9847 if (0 > Sels[i] || 7 < Sels[i])
9848 return Error(Loc,
"expected a 3-bit value");
9855 for (
size_t i = 0; i < 8; ++i)
9856 DPP8 |= (Sels[i] << (i * 3));
9858 Operands.push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9863AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
9865 if (Ctrl ==
"row_newbcast")
9868 if (Ctrl ==
"row_share" ||
9869 Ctrl ==
"row_xmask")
9872 if (Ctrl ==
"wave_shl" ||
9873 Ctrl ==
"wave_shr" ||
9874 Ctrl ==
"wave_rol" ||
9875 Ctrl ==
"wave_ror" ||
9876 Ctrl ==
"row_bcast")
9879 return Ctrl ==
"row_mirror" ||
9880 Ctrl ==
"row_half_mirror" ||
9881 Ctrl ==
"quad_perm" ||
9882 Ctrl ==
"row_shl" ||
9883 Ctrl ==
"row_shr" ||
9888AMDGPUAsmParser::parseDPPCtrlPerm() {
9891 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9895 for (
int i = 0; i < 4; ++i) {
9900 SMLoc Loc = getLoc();
9901 if (getParser().parseAbsoluteExpression(Temp))
9903 if (Temp < 0 || Temp > 3) {
9904 Error(Loc,
"expected a 2-bit value");
9908 Val += (Temp << i * 2);
9918AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
9919 using namespace AMDGPU::DPP;
9924 SMLoc Loc = getLoc();
9926 if (getParser().parseAbsoluteExpression(Val))
9929 struct DppCtrlCheck {
9935 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
9936 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
9937 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
9938 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
9939 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
9940 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
9941 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
9942 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
9943 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
9944 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
9945 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
9949 if (
Check.Ctrl == -1) {
9950 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
9958 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
9966 using namespace AMDGPU::DPP;
9969 !isSupportedDPPCtrl(getTokenStr(),
Operands))
9978 if (Ctrl ==
"row_mirror") {
9979 Val = DppCtrl::ROW_MIRROR;
9980 }
else if (Ctrl ==
"row_half_mirror") {
9981 Val = DppCtrl::ROW_HALF_MIRROR;
9984 if (Ctrl ==
"quad_perm") {
9985 Val = parseDPPCtrlPerm();
9987 Val = parseDPPCtrlSel(Ctrl);
9996 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10002 OptionalImmIndexMap OptionalIdx;
10009 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10011 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10012 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10016 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10017 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10021 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10022 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10023 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10024 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10025 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10031 if (OldIdx == NumOperands) {
10033 constexpr int DST_IDX = 0;
10035 }
else if (Src2ModIdx == NumOperands) {
10045 if (IsVOP3CvtSrDpp) {
10054 if (TiedTo != -1) {
10059 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10061 if (IsDPP8 &&
Op.isDppFI()) {
10064 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10065 }
else if (
Op.isReg()) {
10066 Op.addRegOperands(Inst, 1);
10067 }
else if (
Op.isImm() &&
10069 Op.addImmOperands(Inst, 1);
10070 }
else if (
Op.isImm()) {
10071 OptionalIdx[
Op.getImmTy()] =
I;
10079 AMDGPUOperand::ImmTyClamp);
10085 AMDGPUOperand::ImmTyByteSel);
10092 cvtVOP3P(Inst,
Operands, OptionalIdx);
10094 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
10101 using namespace llvm::AMDGPU::DPP;
10111 AMDGPUOperand::ImmTyDppFI);
10116 OptionalImmIndexMap OptionalIdx;
10120 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10121 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10128 if (TiedTo != -1) {
10133 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10135 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10143 Op.addImmOperands(Inst, 1);
10145 Op.addRegWithFPInputModsOperands(Inst, 2);
10146 }
else if (
Op.isDppFI()) {
10148 }
else if (
Op.isReg()) {
10149 Op.addRegOperands(Inst, 1);
10155 Op.addRegWithFPInputModsOperands(Inst, 2);
10156 }
else if (
Op.isReg()) {
10157 Op.addRegOperands(Inst, 1);
10158 }
else if (
Op.isDPPCtrl()) {
10159 Op.addImmOperands(Inst, 1);
10160 }
else if (
Op.isImm()) {
10162 OptionalIdx[
Op.getImmTy()] =
I;
10170 using namespace llvm::AMDGPU::DPP;
10178 AMDGPUOperand::ImmTyDppFI);
10189 AMDGPUOperand::ImmTy
Type) {
10190 return parseStringOrIntWithPrefix(
10192 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10197 return parseStringOrIntWithPrefix(
10198 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10199 AMDGPUOperand::ImmTySDWADstUnused);
10223 uint64_t BasicInstType,
10226 using namespace llvm::AMDGPU::SDWA;
10228 OptionalImmIndexMap OptionalIdx;
10229 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10230 bool SkippedVcc =
false;
10234 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10235 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10239 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10240 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10241 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10259 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10260 }
else if (
Op.isImm()) {
10262 OptionalIdx[
Op.getImmTy()] =
I;
10266 SkippedVcc =
false;
10270 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10271 Opc != AMDGPU::V_NOP_sdwa_vi) {
10273 switch (BasicInstType) {
10277 AMDGPUOperand::ImmTyClamp, 0);
10281 AMDGPUOperand::ImmTyOModSI, 0);
10285 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10289 AMDGPUOperand::ImmTySDWADstUnused,
10290 DstUnused::UNUSED_PRESERVE);
10297 AMDGPUOperand::ImmTyClamp, 0);
10311 AMDGPUOperand::ImmTyClamp, 0);
10317 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10323 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10324 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10325 auto *it = Inst.
begin();
10327 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10339#define GET_REGISTER_MATCHER
10340#define GET_MATCHER_IMPLEMENTATION
10341#define GET_MNEMONIC_SPELL_CHECKER
10342#define GET_MNEMONIC_CHECKER
10343#include "AMDGPUGenAsmMatcher.inc"
10349 return parseTokenOp(
"addr64",
Operands);
10351 return parseTokenOp(
"done",
Operands);
10353 return parseTokenOp(
"idxen",
Operands);
10355 return parseTokenOp(
"lds",
Operands);
10357 return parseTokenOp(
"offen",
Operands);
10359 return parseTokenOp(
"off",
Operands);
10360 case MCK_row_95_en:
10361 return parseTokenOp(
"row_en",
Operands);
10363 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10365 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10367 return tryCustomParseOperand(
Operands, MCK);
10372unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10378 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10381 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10383 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10385 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10387 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10389 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10391 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10399 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10401 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10402 case MCK_SOPPBrTarget:
10403 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10404 case MCK_VReg32OrOff:
10405 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10406 case MCK_InterpSlot:
10407 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10408 case MCK_InterpAttr:
10409 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10410 case MCK_InterpAttrChan:
10411 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10413 case MCK_SReg_64_XEXEC:
10423 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10425 return Match_InvalidOperand;
10434 SMLoc S = getLoc();
10443 return Error(S,
"expected a 16-bit value");
10446 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10450bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10456bool 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
mir Rename Register Operands
Register const TargetRegisterInfo * TRI
static unsigned 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, ArrayRef< StringLiteral > StandardNames)
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 * 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)
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.
Target independent representation for an assembler token.
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)
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
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.
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.
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.
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
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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)
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)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc, unsigned OpNo)
Get size of register operand.
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)
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?
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCSubtargetInfo &ST)
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)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isInlineValue(unsigned Reg)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
@ 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 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)
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type)
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)
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.
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.
@ Default
The result values are uniform if and only if all operands are uniform.
int popcount(T Value) noexcept
Count the number of set bits in a value.
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
static LLVM_ABI const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI const fltSemantics & IEEEdouble() LLVM_READNONE
static LLVM_ABI const fltSemantics & IEEEhalf() LLVM_READNONE
static LLVM_ABI const fltSemantics & BFloat() LLVM_READNONE
opStatus
IEEE-754R 7: Default exception handling.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size