57enum RegisterKind { IS_UNKNOWN,
IS_VGPR, IS_SGPR,
IS_AGPR, IS_TTMP, IS_SPECIAL };
71 SMLoc StartLoc, EndLoc;
72 const AMDGPUAsmParser *AsmParser;
75 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
76 : Kind(Kind_), AsmParser(AsmParser_) {}
78 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(); }
89 bool isForcedLit()
const {
return Lit == LitModifier::Lit; }
90 bool isForcedLit64()
const {
return Lit == LitModifier::Lit64; }
92 int64_t getFPModifiersOperand()
const {
99 int64_t getIntModifiersOperand()
const {
105 int64_t getModifiersOperand()
const {
106 assert(!(hasFPModifiers() && hasIntModifiers())
107 &&
"fp and int modifiers should not be used simultaneously");
108 if (hasFPModifiers())
109 return getFPModifiersOperand();
110 if (hasIntModifiers())
111 return getIntModifiersOperand();
115 friend raw_ostream &
operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
189 ImmTyMatrixAScaleFmt,
190 ImmTyMatrixBScaleFmt,
223 mutable int MCOpIdx = -1;
226 bool isToken()
const override {
return Kind == Token; }
228 bool isSymbolRefExpr()
const {
232 bool isImm()
const override {
233 return Kind == Immediate;
236 bool isInlinableImm(MVT type)
const;
237 bool isLiteralImm(MVT type)
const;
239 bool isRegKind()
const {
240 return Kind == Register;
243 bool isReg()
const override {
244 return isRegKind() && !hasModifiers();
247 bool isRegOrInline(
unsigned RCID, MVT type)
const {
248 return isRegClass(RCID) || isInlinableImm(type);
252 return isRegOrInline(RCID, type) || isLiteralImm(type);
255 bool isRegOrImmWithInt16InputMods()
const {
259 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
261 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
264 bool isRegOrImmWithInt32InputMods()
const {
268 bool isRegOrInlineImmWithInt16InputMods()
const {
269 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
272 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
273 return isRegOrInline(
274 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
277 bool isRegOrInlineImmWithInt32InputMods()
const {
278 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
281 bool isRegOrImmWithInt64InputMods()
const {
285 bool isRegOrImmWithFP16InputMods()
const {
289 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
291 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
294 bool isRegOrImmWithFP32InputMods()
const {
298 bool isRegOrImmWithFP64InputMods()
const {
302 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
303 return isRegOrInline(
304 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
307 bool isRegOrInlineImmWithFP32InputMods()
const {
308 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
311 bool isRegOrInlineImmWithFP64InputMods()
const {
312 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
315 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
317 bool isVRegWithFP32InputMods()
const {
318 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
321 bool isVRegWithFP64InputMods()
const {
322 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
325 bool isPackedFP16InputMods()
const {
329 bool isPackedVGPRFP32InputMods()
const {
333 bool isVReg()
const {
334 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
335 isRegClass(AMDGPU::VReg_64RegClassID) ||
336 isRegClass(AMDGPU::VReg_96RegClassID) ||
337 isRegClass(AMDGPU::VReg_128RegClassID) ||
338 isRegClass(AMDGPU::VReg_160RegClassID) ||
339 isRegClass(AMDGPU::VReg_192RegClassID) ||
340 isRegClass(AMDGPU::VReg_256RegClassID) ||
341 isRegClass(AMDGPU::VReg_512RegClassID) ||
342 isRegClass(AMDGPU::VReg_1024RegClassID);
345 bool isVReg32()
const {
346 return isRegClass(AMDGPU::VGPR_32RegClassID);
349 bool isVReg32OrOff()
const {
350 return isOff() || isVReg32();
354 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
357 bool isAV_LdSt_32_Align2_RegOp()
const {
358 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
359 isRegClass(AMDGPU::AGPR_32RegClassID);
362 bool isVRegWithInputMods()
const;
363 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
364 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
366 bool isSDWAOperand(MVT type)
const;
367 bool isSDWAFP16Operand()
const;
368 bool isSDWAFP32Operand()
const;
369 bool isSDWAInt16Operand()
const;
370 bool isSDWAInt32Operand()
const;
372 bool isImmTy(ImmTy ImmT)
const {
373 return isImm() &&
Imm.Type == ImmT;
376 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
378 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
380 bool isImmModifier()
const {
381 return isImm() &&
Imm.Type != ImmTyNone;
384 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
385 bool isDim()
const {
return isImmTy(ImmTyDim); }
386 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
387 bool isOff()
const {
return isImmTy(ImmTyOff); }
388 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
389 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
390 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
391 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
392 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
393 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
394 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
395 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
396 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
397 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
398 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
399 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
400 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
401 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
402 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
403 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
404 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
405 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
406 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
407 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
408 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
409 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
410 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
411 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
412 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
413 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
414 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
415 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
416 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
417 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
418 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
419 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
420 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
421 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
422 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
423 bool isDone()
const {
return isImmTy(ImmTyDone); }
424 bool isRowEn()
const {
return isImmTy(ImmTyRowEn); }
426 bool isRegOrImm()
const {
427 return isReg() || isImm();
430 bool isRegClass(
unsigned RCID)
const;
434 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
435 return isRegOrInline(RCID, type) && !hasModifiers();
438 bool isSCSrcB16()
const {
439 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
442 bool isSCSrcV2B16()
const {
446 bool isSCSrc_b32()
const {
447 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
450 bool isSCSrc_b64()
const {
451 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
454 bool isBoolReg()
const;
456 bool isSCSrcF16()
const {
457 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
460 bool isSCSrcV2F16()
const {
464 bool isSCSrcF32()
const {
465 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
468 bool isSCSrcF64()
const {
469 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
472 bool isSSrc_b32()
const {
473 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
476 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
478 bool isSSrcV2B16()
const {
483 bool isSSrc_b64()
const {
486 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
487 (((
const MCTargetAsmParser *)AsmParser)
488 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
492 bool isSSrc_f32()
const {
493 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
496 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
498 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
500 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
502 bool isSSrcV2F16()
const {
507 bool isSSrcV2FP32()
const {
512 bool isSCSrcV2FP32()
const {
517 bool isSSrcV2INT32()
const {
522 bool isSCSrcV2INT32()
const {
524 return isSCSrc_b32();
527 bool isSSrcOrLds_b32()
const {
528 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
529 isLiteralImm(MVT::i32) || isExpr();
532 bool isVCSrc_b32()
const {
533 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
536 bool isVCSrc_b32_Lo256()
const {
537 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
540 bool isVCSrc_b64_Lo256()
const {
541 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
544 bool isVCSrc_b64()
const {
545 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
548 bool isVCSrcT_b16()
const {
549 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
552 bool isVCSrcTB16_Lo128()
const {
553 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
556 bool isVCSrcFake16B16_Lo128()
const {
557 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
560 bool isVCSrc_b16()
const {
561 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
564 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
566 bool isVCSrc_f32()
const {
567 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
570 bool isVCSrc_f64()
const {
571 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
574 bool isVCSrcTBF16()
const {
575 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
578 bool isVCSrcT_f16()
const {
579 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
582 bool isVCSrcT_bf16()
const {
583 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
586 bool isVCSrcTBF16_Lo128()
const {
587 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
590 bool isVCSrcTF16_Lo128()
const {
591 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
594 bool isVCSrcFake16BF16_Lo128()
const {
595 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
598 bool isVCSrcFake16F16_Lo128()
const {
599 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
602 bool isVCSrc_bf16()
const {
603 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
606 bool isVCSrc_f16()
const {
607 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
610 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
612 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
614 bool isVSrc_b32()
const {
615 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
618 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
620 bool isVSrc_v2b64()
const {
621 return isRegOrInlineNoMods(AMDGPU::VS_128RegClassID, MVT::i64) ||
622 isLiteralImm(MVT::i64);
625 bool isVSrc_v2f64()
const {
626 return isRegOrInlineNoMods(AMDGPU::VS_128RegClassID, MVT::f64) ||
627 isLiteralImm(MVT::f64);
630 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
632 bool isVSrcT_b16_Lo128()
const {
633 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
636 bool isVSrcFake16_b16_Lo128()
const {
637 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
640 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
642 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
644 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
646 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
648 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
650 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
652 bool isVSrc_f32()
const {
653 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
656 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
658 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
660 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
662 bool isVSrcT_bf16_Lo128()
const {
663 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
666 bool isVSrcT_f16_Lo128()
const {
667 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
670 bool isVSrcFake16_bf16_Lo128()
const {
671 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
674 bool isVSrcFake16_f16_Lo128()
const {
675 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
678 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
680 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
682 bool isVSrc_v2bf16()
const {
683 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
686 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
688 bool isVSrc_v2f16_splat()
const {
return isVSrc_v2f16(); }
690 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
692 bool isVISrcB32()
const {
693 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
696 bool isVISrcB16()
const {
697 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
700 bool isVISrcV2B16()
const {
704 bool isVISrcF32()
const {
705 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
708 bool isVISrcF16()
const {
709 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
712 bool isVISrcV2F16()
const {
713 return isVISrcF16() || isVISrcB32();
716 bool isVISrc_64_bf16()
const {
717 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
720 bool isVISrc_64_f16()
const {
721 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
724 bool isVISrc_64_b32()
const {
725 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
728 bool isVISrc_64B64()
const {
729 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
732 bool isVISrc_64_f64()
const {
733 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
736 bool isVISrc_64V2FP32()
const {
737 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
740 bool isVISrc_64V2INT32()
const {
741 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
744 bool isVISrc_256_b32()
const {
745 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
748 bool isVISrc_256_f32()
const {
749 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
752 bool isVISrc_256B64()
const {
753 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
756 bool isVISrc_256_f64()
const {
757 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
760 bool isVISrc_512_f64()
const {
761 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
764 bool isVISrc_128B16()
const {
765 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
768 bool isVISrc_128V2B16()
const {
769 return isVISrc_128B16();
772 bool isVISrc_128_b32()
const {
773 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
776 bool isVISrc_128_f32()
const {
777 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
780 bool isVISrc_256V2FP32()
const {
781 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
784 bool isVISrc_256V2INT32()
const {
785 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
788 bool isVISrc_512_b32()
const {
789 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
792 bool isVISrc_512B16()
const {
793 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
796 bool isVISrc_512V2B16()
const {
797 return isVISrc_512B16();
800 bool isVISrc_512_f32()
const {
801 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
804 bool isVISrc_512F16()
const {
805 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
808 bool isVISrc_512V2F16()
const {
809 return isVISrc_512F16() || isVISrc_512_b32();
812 bool isVISrc_1024_b32()
const {
813 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
816 bool isVISrc_1024B16()
const {
817 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
820 bool isVISrc_1024V2B16()
const {
821 return isVISrc_1024B16();
824 bool isVISrc_1024_f32()
const {
825 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
828 bool isVISrc_1024F16()
const {
829 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
832 bool isVISrc_1024V2F16()
const {
833 return isVISrc_1024F16() || isVISrc_1024_b32();
836 bool isAISrcB32()
const {
837 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
840 bool isAISrcB16()
const {
841 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
844 bool isAISrcV2B16()
const {
848 bool isAISrcF32()
const {
849 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
852 bool isAISrcF16()
const {
853 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
856 bool isAISrcV2F16()
const {
857 return isAISrcF16() || isAISrcB32();
860 bool isAISrc_64B64()
const {
861 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
864 bool isAISrc_64_f64()
const {
865 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
868 bool isAISrc_128_b32()
const {
869 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
872 bool isAISrc_128B16()
const {
873 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
876 bool isAISrc_128V2B16()
const {
877 return isAISrc_128B16();
880 bool isAISrc_128_f32()
const {
881 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
884 bool isAISrc_128F16()
const {
885 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
888 bool isAISrc_128V2F16()
const {
889 return isAISrc_128F16() || isAISrc_128_b32();
892 bool isVISrc_128_bf16()
const {
893 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
896 bool isVISrc_128_f16()
const {
897 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
900 bool isVISrc_128V2F16()
const {
901 return isVISrc_128_f16() || isVISrc_128_b32();
904 bool isAISrc_256B64()
const {
905 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
908 bool isAISrc_256_f64()
const {
909 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
912 bool isAISrc_512_b32()
const {
913 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
916 bool isAISrc_512B16()
const {
917 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
920 bool isAISrc_512V2B16()
const {
921 return isAISrc_512B16();
924 bool isAISrc_512_f32()
const {
925 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
928 bool isAISrc_512F16()
const {
929 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
932 bool isAISrc_512V2F16()
const {
933 return isAISrc_512F16() || isAISrc_512_b32();
936 bool isAISrc_1024_b32()
const {
937 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
940 bool isAISrc_1024B16()
const {
941 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
944 bool isAISrc_1024V2B16()
const {
945 return isAISrc_1024B16();
948 bool isAISrc_1024_f32()
const {
949 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
952 bool isAISrc_1024F16()
const {
953 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
956 bool isAISrc_1024V2F16()
const {
957 return isAISrc_1024F16() || isAISrc_1024_b32();
960 bool isKImmFP32()
const {
961 return isLiteralImm(MVT::f32);
964 bool isKImmFP16()
const {
965 return isLiteralImm(MVT::f16);
968 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
970 bool isMem()
const override {
974 bool isExpr()
const {
975 return Kind == Expression;
978 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
980 bool isSWaitCnt()
const;
981 bool isDepCtr()
const;
982 bool isSDelayALU()
const;
983 bool isHwreg()
const;
984 bool isSendMsg()
const;
985 bool isWaitEvent()
const;
986 bool isSplitBarrier()
const;
987 bool isSwizzle()
const;
988 bool isSMRDOffset8()
const;
989 bool isSMEMOffset()
const;
990 bool isSMRDLiteralOffset()
const;
992 bool isDPPCtrl()
const;
994 bool isGPRIdxMode()
const;
995 bool isS16Imm()
const;
996 bool isU16Imm()
const;
997 bool isEndpgm()
const;
999 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
1000 return [
this,
P]() {
return P(*
this); };
1005 return StringRef(Tok.Data, Tok.Length);
1013 void setImm(int64_t Val) {
1018 ImmTy getImmTy()
const {
1023 MCRegister
getReg()
const override {
1028 SMLoc getStartLoc()
const override {
1032 SMLoc getEndLoc()
const override {
1036 SMRange getLocRange()
const {
1037 return SMRange(StartLoc, EndLoc);
1040 int getMCOpIdx()
const {
return MCOpIdx; }
1042 Modifiers getModifiers()
const {
1043 assert(isRegKind() || isImmTy(ImmTyNone));
1044 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1047 void setModifiers(Modifiers Mods) {
1048 assert(isRegKind() || isImmTy(ImmTyNone));
1055 bool hasModifiers()
const {
1056 return getModifiers().hasModifiers();
1059 bool hasFPModifiers()
const {
1060 return getModifiers().hasFPModifiers();
1063 bool hasIntModifiers()
const {
1064 return getModifiers().hasIntModifiers();
1067 bool isForcedLit()
const {
1068 return isImmLiteral() && getModifiers().isForcedLit();
1071 bool isForcedLit64()
const {
1072 return isImmLiteral() && getModifiers().isForcedLit64();
1075 uint64_t applyInputFPModifiers(uint64_t Val,
unsigned Size)
const;
1077 void addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1079 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1081 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1083 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1085 addRegOperands(Inst,
N);
1087 addImmOperands(Inst,
N);
1090 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1091 Modifiers Mods = getModifiers();
1094 addRegOperands(Inst,
N);
1096 addImmOperands(Inst,
N,
false);
1100 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1101 assert(!hasIntModifiers());
1102 addRegOrImmWithInputModsOperands(Inst,
N);
1105 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1106 assert(!hasFPModifiers());
1107 addRegOrImmWithInputModsOperands(Inst,
N);
1110 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1111 Modifiers Mods = getModifiers();
1114 addRegOperands(Inst,
N);
1117 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1118 assert(!hasIntModifiers());
1119 addRegWithInputModsOperands(Inst,
N);
1122 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1123 assert(!hasFPModifiers());
1124 addRegWithInputModsOperands(Inst,
N);
1127 static void printImmTy(raw_ostream& OS, ImmTy
Type) {
1130 case ImmTyNone: OS <<
"None";
break;
1131 case ImmTyGDS: OS <<
"GDS";
break;
1132 case ImmTyLDS: OS <<
"LDS";
break;
1133 case ImmTyOffen: OS <<
"Offen";
break;
1134 case ImmTyIdxen: OS <<
"Idxen";
break;
1135 case ImmTyAddr64: OS <<
"Addr64";
break;
1136 case ImmTyOffset: OS <<
"Offset";
break;
1137 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1138 case ImmTyOffset0: OS <<
"Offset0";
break;
1139 case ImmTyOffset1: OS <<
"Offset1";
break;
1140 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1141 case ImmTyCPol: OS <<
"CPol";
break;
1142 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1143 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1144 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1145 case ImmTyTFE: OS <<
"TFE";
break;
1146 case ImmTyIsAsync: OS <<
"IsAsync";
break;
1147 case ImmTyD16: OS <<
"D16";
break;
1148 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1149 case ImmTyClamp: OS <<
"Clamp";
break;
1150 case ImmTyOModSI: OS <<
"OModSI";
break;
1151 case ImmTyDPP8: OS <<
"DPP8";
break;
1152 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1153 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1154 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1155 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1156 case ImmTyDppFI: OS <<
"DppFI";
break;
1157 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1158 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1159 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1160 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1161 case ImmTyDMask: OS <<
"DMask";
break;
1162 case ImmTyDim: OS <<
"Dim";
break;
1163 case ImmTyUNorm: OS <<
"UNorm";
break;
1164 case ImmTyDA: OS <<
"DA";
break;
1165 case ImmTyR128A16: OS <<
"R128A16";
break;
1166 case ImmTyA16: OS <<
"A16";
break;
1167 case ImmTyLWE: OS <<
"LWE";
break;
1168 case ImmTyOff: OS <<
"Off";
break;
1169 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1170 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1171 case ImmTyExpVM: OS <<
"ExpVM";
break;
1172 case ImmTyDone: OS <<
"Done";
break;
1173 case ImmTyRowEn: OS <<
"RowEn";
break;
1174 case ImmTyHwreg: OS <<
"Hwreg";
break;
1175 case ImmTySendMsg: OS <<
"SendMsg";
break;
1176 case ImmTyWaitEvent: OS <<
"WaitEvent";
break;
1177 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1178 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1179 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1180 case ImmTyOpSel: OS <<
"OpSel";
break;
1181 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1182 case ImmTyNegLo: OS <<
"NegLo";
break;
1183 case ImmTyNegHi: OS <<
"NegHi";
break;
1184 case ImmTySwizzle: OS <<
"Swizzle";
break;
1185 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1186 case ImmTyHigh: OS <<
"High";
break;
1187 case ImmTyBLGP: OS <<
"BLGP";
break;
1188 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1189 case ImmTyABID: OS <<
"ABID";
break;
1190 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1191 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1192 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1193 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1194 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1195 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1196 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1197 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1198 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1199 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1200 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1201 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1202 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1203 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1204 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1205 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1210 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1214 <<
" mods: " <<
Reg.Mods <<
'>';
1218 if (getImmTy() != ImmTyNone) {
1219 OS <<
" type: "; printImmTy(OS, getImmTy());
1221 OS <<
" mods: " <<
Imm.Mods <<
'>';
1234 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1235 int64_t Val, SMLoc Loc,
1236 ImmTy
Type = ImmTyNone,
1237 bool IsFPImm =
false) {
1238 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1240 Op->Imm.IsFPImm = IsFPImm;
1242 Op->Imm.Mods = Modifiers();
1248 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1249 StringRef Str, SMLoc Loc,
1250 bool HasExplicitEncodingSize =
true) {
1251 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1252 Res->Tok.Data = Str.data();
1253 Res->Tok.Length = Str.size();
1254 Res->StartLoc = Loc;
1259 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1260 MCRegister
Reg, SMLoc S, SMLoc
E) {
1261 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1262 Op->Reg.RegNo =
Reg;
1263 Op->Reg.Mods = Modifiers();
1269 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1270 const class MCExpr *Expr, SMLoc S) {
1271 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1280 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1289#define GET_REGISTER_MATCHER
1290#include "AMDGPUGenAsmMatcher.inc"
1291#undef GET_REGISTER_MATCHER
1292#undef GET_SUBTARGET_FEATURE_NAME
1297class KernelScopeInfo {
1298 int SgprIndexUnusedMin = -1;
1299 int VgprIndexUnusedMin = -1;
1300 int AgprIndexUnusedMin = -1;
1304 void usesSgprAt(
int i) {
1305 if (i >= SgprIndexUnusedMin) {
1306 SgprIndexUnusedMin = ++i;
1309 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1315 void usesVgprAt(
int i) {
1316 if (i >= VgprIndexUnusedMin) {
1317 VgprIndexUnusedMin = ++i;
1320 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1322 VgprIndexUnusedMin);
1328 void usesAgprAt(
int i) {
1333 if (i >= AgprIndexUnusedMin) {
1334 AgprIndexUnusedMin = ++i;
1337 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1342 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1344 VgprIndexUnusedMin);
1351 KernelScopeInfo() =
default;
1355 MSTI = Ctx->getSubtargetInfo();
1357 usesSgprAt(SgprIndexUnusedMin = -1);
1358 usesVgprAt(VgprIndexUnusedMin = -1);
1360 usesAgprAt(AgprIndexUnusedMin = -1);
1364 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1365 unsigned RegWidth) {
1368 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1371 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1374 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1383 MCAsmParser &Parser;
1385 unsigned ForcedEncodingSize = 0;
1386 bool ForcedDPP =
false;
1387 bool ForcedSDWA =
false;
1388 KernelScopeInfo KernelScope;
1389 const unsigned HwMode;
1394#define GET_ASSEMBLER_HEADER
1395#include "AMDGPUGenAsmMatcher.inc"
1400 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1402 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1406 std::optional<AMDGPU::InfoSectionData> InfoData;
1413 bool TargetDirectiveEmitted =
false;
1422 SmallVector<unsigned> OpcodeStream;
1424 OpcodeStreamSymbols;
1425 SmallPtrSet<const MCSymbol *, 8> AMDHSAKernelSymbols;
1428 void checkKernelPrologues();
1431 void createConstantSymbol(StringRef Id, int64_t Val);
1433 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1434 bool OutOfRangeError(SMRange
Range);
1450 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1451 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1452 std::optional<bool> EnableWavefrontSize32,
1453 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1454 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1455 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1456 bool ParseDirectiveAMDGCNTarget();
1457 bool ParseDirectiveAMDHSACodeObjectVersion();
1458 bool ParseDirectiveAMDHSAKernel();
1459 bool ParseAMDKernelCodeTValue(StringRef
ID, AMDGPUMCKernelCodeT &Header);
1460 bool ParseDirectiveAMDKernelCodeT();
1462 bool subtargetHasRegister(
const MCRegisterInfo &MRI, MCRegister
Reg);
1463 bool ParseDirectiveAMDGPUHsaKernel();
1465 bool ParseDirectiveISAVersion();
1466 bool ParseDirectiveHSAMetadata();
1467 bool ParseDirectivePALMetadataBegin();
1468 bool ParseDirectivePALMetadata();
1469 bool ParseDirectiveAMDGPULDS();
1470 bool ParseDirectiveAMDGPUInfo();
1474 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1475 const char *AssemblerDirectiveEnd,
1476 std::string &CollectString);
1478 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1479 RegisterKind RegKind, MCRegister Reg1,
1480 RegisterKind RegKind1, SMLoc Loc);
1481 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1482 unsigned &RegNum,
unsigned &RegWidth,
1483 bool RestoreOnFailure =
false);
1484 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1485 unsigned &RegNum,
unsigned &RegWidth,
1486 SmallVectorImpl<AsmToken> &Tokens);
1487 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1489 SmallVectorImpl<AsmToken> &Tokens);
1490 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1492 SmallVectorImpl<AsmToken> &Tokens);
1493 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1495 SmallVectorImpl<AsmToken> &Tokens);
1496 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &SubReg);
1497 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1498 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1501 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1502 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1503 void initializeGprCountSymbol(RegisterKind RegKind);
1504 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1506 void cvtMubufImpl(MCInst &Inst,
const OperandVector &Operands,
1511 OperandMode_Default,
1515 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1517 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1518 const MCInstrInfo &MII)
1519 : MCTargetAsmParser(STI, MII), Parser(_Parser),
1520 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)) {
1523 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1527 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1528 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1529 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1531 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1532 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1533 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1536 initializeGprCountSymbol(IS_VGPR);
1537 initializeGprCountSymbol(IS_SGPR);
1542 createConstantSymbol(Symbol, Code);
1544 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1545 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1546 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1618 bool hasBVHRayTracingInsts()
const {
1619 return getFeatureBits()[AMDGPU::FeatureBVHRayTracingInsts];
1626 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1628 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1630 bool hasInv2PiInlineImm()
const {
1631 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1634 bool has64BitLiterals()
const {
1635 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1638 bool hasFlatOffsets()
const {
1639 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1642 bool hasTrue16Insts()
const {
1643 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1647 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1650 bool hasSGPR102_SGPR103()
const {
1654 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1657 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1660 bool hasPartialNSAEncoding()
const {
1661 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1664 bool hasGloballyAddressableScratch()
const {
1665 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1678 AMDGPUTargetStreamer &getTargetStreamer() {
1679 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1680 return static_cast<AMDGPUTargetStreamer &
>(TS);
1686 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1689 const MCRegisterInfo *getMRI()
const {
1693 const MCInstrInfo *getMII()
const {
1699 const FeatureBitset &getFeatureBits()
const {
1700 return getSTI().getFeatureBits();
1703 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1704 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1705 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1707 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1708 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1709 bool isForcedDPP()
const {
return ForcedDPP; }
1710 bool isForcedSDWA()
const {
return ForcedSDWA; }
1711 ArrayRef<unsigned> getMatchedVariants()
const;
1712 StringRef getMatchedVariantName()
const;
1714 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1715 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1716 bool RestoreOnFailure);
1717 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1718 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1719 SMLoc &EndLoc)
override;
1720 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1721 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1722 unsigned Kind)
override;
1723 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1725 uint64_t &ErrorInfo,
1726 bool MatchingInlineAsm)
override;
1727 bool ParseDirective(AsmToken DirectiveID)
override;
1728 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override;
1729 void onEndOfFile()
override;
1730 ParseStatus parseOperand(
OperandVector &Operands, StringRef Mnemonic,
1731 OperandMode
Mode = OperandMode_Default);
1732 StringRef parseMnemonicSuffix(StringRef Name);
1733 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1737 ParseStatus parseTokenOp(StringRef Name,
OperandVector &Operands);
1739 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1742 parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1743 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1744 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1746 ParseStatus parseOperandArrayWithPrefix(
1748 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1749 bool (*ConvertResult)(int64_t &) =
nullptr);
1753 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1754 bool IgnoreNegative =
false);
1755 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1757 ParseStatus parseScope(
OperandVector &Operands, int64_t &Scope);
1759 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1761 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1763 ArrayRef<const char *> Ids,
1765 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1767 ArrayRef<const char *> Ids,
1768 AMDGPUOperand::ImmTy
Type);
1771 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1772 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1773 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1774 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1775 bool parseSP3NegModifier();
1776 ParseStatus parseImm(
OperandVector &Operands,
bool HasSP3AbsModifier =
false,
1779 ParseStatus parseRegOrImm(
OperandVector &Operands,
bool HasSP3AbsMod =
false,
1781 ParseStatus parseRegOrImmWithFPInputMods(
OperandVector &Operands,
1782 bool AllowImm =
true);
1783 ParseStatus parseRegOrImmWithIntInputMods(
OperandVector &Operands,
1784 bool AllowImm =
true);
1785 ParseStatus parseRegWithFPInputMods(
OperandVector &Operands);
1786 ParseStatus parseRegWithIntInputMods(
OperandVector &Operands);
1789 AMDGPUOperand::ImmTy ImmTy);
1793 ParseStatus tryParseMatrixFMT(
OperandVector &Operands, StringRef Name,
1794 AMDGPUOperand::ImmTy
Type);
1797 ParseStatus tryParseMatrixScale(
OperandVector &Operands, StringRef Name,
1798 AMDGPUOperand::ImmTy
Type);
1801 ParseStatus tryParseMatrixScaleFmt(
OperandVector &Operands, StringRef Name,
1802 AMDGPUOperand::ImmTy
Type);
1806 ParseStatus parseDfmtNfmt(int64_t &
Format);
1807 ParseStatus parseUfmt(int64_t &
Format);
1808 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1810 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1813 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1814 ParseStatus parseNumericFormat(int64_t &
Format);
1818 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1819 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1823 bool parseCnt(int64_t &IntVal);
1826 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1827 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1830 bool parseDelay(int64_t &Delay);
1836 struct OperandInfoTy {
1839 bool IsSymbolic =
false;
1840 bool IsDefined =
false;
1842 constexpr OperandInfoTy(int64_t Val) : Val(Val) {}
1845 struct StructuredOpField : OperandInfoTy {
1849 bool IsDefined =
false;
1851 constexpr StructuredOpField(StringLiteral Id, StringLiteral Desc,
1852 unsigned Width, int64_t
Default)
1853 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1854 virtual ~StructuredOpField() =
default;
1856 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1857 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1861 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1863 return Error(Parser,
"not supported on this GPU");
1865 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1873 bool parseSendMsgBody(OperandInfoTy &
Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1874 bool validateSendMsg(
const OperandInfoTy &
Msg,
1875 const OperandInfoTy &
Op,
1876 const OperandInfoTy &Stream);
1878 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1879 OperandInfoTy &Width);
1881 const AMDGPUOperand &findMCOperand(
const OperandVector &Operands,
1884 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1886 SMLoc getFlatOffsetLoc(
const OperandVector &Operands)
const;
1887 SMLoc getSMEMOffsetLoc(
const OperandVector &Operands)
const;
1890 SMLoc getOperandLoc(
const OperandVector &Operands,
int MCOpIdx)
const;
1891 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1893 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1897 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1899 bool validateOffset(
const MCInst &Inst,
const OperandVector &Operands);
1900 bool validateFlatOffset(
const MCInst &Inst,
const OperandVector &Operands);
1901 bool validateSMEMOffset(
const MCInst &Inst,
const OperandVector &Operands);
1902 bool validateSOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1903 bool validateConstantBusLimitations(
const MCInst &Inst,
const OperandVector &Operands);
1904 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1906 bool validateVOPD(
const MCInst &Inst,
const OperandVector &Operands);
1907 bool tryVOPD(
const MCInst &Inst);
1908 bool tryVOPD3(
const MCInst &Inst);
1909 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1911 bool validateIntClampSupported(
const MCInst &Inst);
1912 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1913 bool validateMIMGGatherDMask(
const MCInst &Inst);
1914 bool validateMovrels(
const MCInst &Inst,
const OperandVector &Operands);
1915 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1916 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1917 bool validateMIMGD16(
const MCInst &Inst);
1918 bool validateMIMGDim(
const MCInst &Inst,
const OperandVector &Operands);
1919 bool validateTensorR128(
const MCInst &Inst);
1920 bool validateMIMGMSAA(
const MCInst &Inst);
1921 bool validateOpSel(
const MCInst &Inst);
1922 bool validateTrue16OpSel(
const MCInst &Inst);
1923 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1924 bool validateDPP(
const MCInst &Inst,
const OperandVector &Operands);
1925 bool validateVccOperand(MCRegister
Reg)
const;
1926 bool validateVOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1927 bool validateMAIAccWrite(
const MCInst &Inst,
const OperandVector &Operands);
1928 bool validateMAISrc2(
const MCInst &Inst,
const OperandVector &Operands);
1929 bool validateMFMA(
const MCInst &Inst,
const OperandVector &Operands);
1930 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1931 bool validateVGPRAlign(
const MCInst &Inst)
const;
1932 bool validateBLGP(
const MCInst &Inst,
const OperandVector &Operands);
1933 bool validateDS(
const MCInst &Inst,
const OperandVector &Operands);
1934 bool validateGWS(
const MCInst &Inst,
const OperandVector &Operands);
1935 bool validateDivScale(
const MCInst &Inst);
1936 bool validateWaitCnt(
const MCInst &Inst,
const OperandVector &Operands);
1937 bool validateCoherencyBits(
const MCInst &Inst,
const OperandVector &Operands,
1939 bool validateTHAndScopeBits(
const MCInst &Inst,
const OperandVector &Operands,
1940 const unsigned CPol);
1941 bool validateTFE(
const MCInst &Inst,
const OperandVector &Operands);
1942 bool validateLdsDirect(
const MCInst &Inst,
const OperandVector &Operands);
1943 bool validateWMMA(
const MCInst &Inst,
const OperandVector &Operands);
1944 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1945 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1946 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1947 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1949 bool isSupportedMnemo(StringRef Mnemo,
1950 const FeatureBitset &FBS);
1951 bool isSupportedMnemo(StringRef Mnemo,
1952 const FeatureBitset &FBS,
1953 ArrayRef<unsigned> Variants);
1954 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1956 bool isId(
const StringRef Id)
const;
1957 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1959 StringRef getId()
const;
1960 bool trySkipId(
const StringRef Id);
1961 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1965 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1966 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1972 StringRef getTokenStr()
const;
1973 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1975 SMLoc getLoc()
const;
1979 void onBeginOfFile()
override;
1983 void emitTargetDirective();
1984 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1986 ParseStatus parseCustomOperand(
OperandVector &Operands,
unsigned MCK);
1996 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1997 const unsigned MaxVal,
const Twine &ErrMsg,
1999 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
2000 const unsigned MinVal,
2001 const unsigned MaxVal,
2002 const StringRef ErrMsg);
2004 bool parseSwizzleOffset(int64_t &
Imm);
2005 bool parseSwizzleMacro(int64_t &
Imm);
2006 bool parseSwizzleQuadPerm(int64_t &
Imm);
2007 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
2008 bool parseSwizzleBroadcast(int64_t &
Imm);
2009 bool parseSwizzleSwap(int64_t &
Imm);
2010 bool parseSwizzleReverse(int64_t &
Imm);
2011 bool parseSwizzleFFT(int64_t &
Imm);
2012 bool parseSwizzleRotate(int64_t &
Imm);
2015 int64_t parseGPRIdxMacro();
2017 void cvtMubuf(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
false); }
2018 void cvtMubufAtomic(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
true); }
2023 OptionalImmIndexMap &OptionalIdx);
2024 void cvtScaledMFMA(MCInst &Inst,
const OperandVector &Operands);
2025 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands);
2028 void cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands);
2031 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
2032 OptionalImmIndexMap &OptionalIdx);
2034 OptionalImmIndexMap &OptionalIdx);
2036 void cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands);
2037 void cvtVINTERP(MCInst &Inst,
const OperandVector &Operands);
2038 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
2040 bool parseDimId(
unsigned &Encoding);
2042 bool convertDppBoundCtrl(int64_t &BoundCtrl);
2045 bool isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands);
2046 int64_t parseDPPCtrlSel(StringRef Ctrl);
2047 int64_t parseDPPCtrlPerm();
2048 void cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8 =
false);
2050 cvtDPP(Inst, Operands,
true);
2052 void cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
2053 bool IsDPP8 =
false);
2054 void cvtVOP3DPP8(MCInst &Inst,
const OperandVector &Operands) {
2055 cvtVOP3DPP(Inst, Operands,
true);
2058 ParseStatus parseSDWASel(
OperandVector &Operands, StringRef Prefix,
2059 AMDGPUOperand::ImmTy
Type);
2061 void cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands);
2062 void cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands);
2063 void cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands);
2064 void cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands);
2065 void cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands);
2067 enum class SDWAInstType :
unsigned {
VOP1 = 0,
VOP2 = 1,
VOPC = 2 };
2070 SDWAInstType BasicInstType,
bool SkipDstVcc =
false,
2071 bool SkipSrcVcc =
false);
2182bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2192 if (!isImmTy(ImmTyNone)) {
2197 if (getModifiers().
Lit != LitModifier::None)
2207 if (type == MVT::f64 || type == MVT::i64) {
2209 AsmParser->hasInv2PiInlineImm());
2212 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2231 APFloat::rmNearestTiesToEven, &Lost);
2238 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2240 AsmParser->hasInv2PiInlineImm());
2245 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2246 AsmParser->hasInv2PiInlineImm());
2250 if (type == MVT::f64 || type == MVT::i64) {
2252 AsmParser->hasInv2PiInlineImm());
2261 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2262 type, AsmParser->hasInv2PiInlineImm());
2266 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2267 AsmParser->hasInv2PiInlineImm());
2270bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2272 if (!isImmTy(ImmTyNone)) {
2277 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2282 if (type == MVT::f64 && hasFPModifiers()) {
2302 if (type == MVT::f64) {
2307 if (type == MVT::i64) {
2320 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2321 : (type == MVT::v2i16) ? MVT::f32
2322 : (type == MVT::v2f32) ? MVT::f32
2325 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2329bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2330 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2333bool AMDGPUOperand::isVRegWithInputMods()
const {
2334 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2336 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2337 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2340template <
bool IsFake16>
2341bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2342 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2343 : AMDGPU::VGPR_16_Lo128RegClassID);
2346template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2347 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2348 : AMDGPU::VGPR_16RegClassID);
2351bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2352 if (AsmParser->isVI())
2354 if (AsmParser->isGFX9Plus())
2355 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2359bool AMDGPUOperand::isSDWAFP16Operand()
const {
2360 return isSDWAOperand(MVT::f16);
2363bool AMDGPUOperand::isSDWAFP32Operand()
const {
2364 return isSDWAOperand(MVT::f32);
2367bool AMDGPUOperand::isSDWAInt16Operand()
const {
2368 return isSDWAOperand(MVT::i16);
2371bool AMDGPUOperand::isSDWAInt32Operand()
const {
2372 return isSDWAOperand(MVT::i32);
2375bool AMDGPUOperand::isBoolReg()
const {
2376 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2377 (AsmParser->isWave32() && isSCSrc_b32()));
2380uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2382 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2385 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2397void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2407 addLiteralImmOperand(Inst,
Imm.Val,
2409 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2411 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2416void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2417 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2422 if (ApplyModifiers) {
2425 Val = applyInputFPModifiers(Val,
Size);
2429 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2431 bool CanUse64BitLiterals =
2432 AsmParser->has64BitLiterals() &&
2435 MCContext &Ctx = AsmParser->getContext();
2446 if (
Lit == LitModifier::None &&
2448 AsmParser->hasInv2PiInlineImm())) {
2456 bool HasMandatoryLiteral =
2459 if (
Literal.getLoBits(32) != 0 &&
2460 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2461 !HasMandatoryLiteral) {
2462 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2464 "Can't encode literal as exact 64-bit floating-point operand. "
2465 "Low 32-bits will be set to zero");
2466 Val &= 0xffffffff00000000u;
2472 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2478 Lit = LitModifier::Lit64;
2479 }
else if (
Lit == LitModifier::Lit) {
2493 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2495 Lit = LitModifier::Lit64;
2502 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2503 Literal == 0x3fc45f306725feed) {
2538 APFloat::rmNearestTiesToEven, &lost);
2542 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2549 if (
Lit != LitModifier::None) {
2580 if (
Lit == LitModifier::None &&
2590 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2598 if (
Lit == LitModifier::None &&
2606 if (!AsmParser->has64BitLiterals()) {
2607 Val =
static_cast<uint64_t
>(Val) << 32;
2614 if (
Lit == LitModifier::Lit ||
2616 Val =
static_cast<uint64_t
>(Val) << 32;
2620 if (
Lit == LitModifier::Lit)
2646 if (
Lit != LitModifier::None) {
2654void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2659bool AMDGPUOperand::isInlineValue()
const {
2667void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2678 if (Is == IS_VGPR) {
2682 return AMDGPU::VGPR_32RegClassID;
2684 return AMDGPU::VReg_64RegClassID;
2686 return AMDGPU::VReg_96RegClassID;
2688 return AMDGPU::VReg_128RegClassID;
2690 return AMDGPU::VReg_160RegClassID;
2692 return AMDGPU::VReg_192RegClassID;
2694 return AMDGPU::VReg_224RegClassID;
2696 return AMDGPU::VReg_256RegClassID;
2698 return AMDGPU::VReg_288RegClassID;
2700 return AMDGPU::VReg_320RegClassID;
2702 return AMDGPU::VReg_352RegClassID;
2704 return AMDGPU::VReg_384RegClassID;
2706 return AMDGPU::VReg_512RegClassID;
2708 return AMDGPU::VReg_1024RegClassID;
2710 }
else if (Is == IS_TTMP) {
2714 return AMDGPU::TTMP_32RegClassID;
2716 return AMDGPU::TTMP_64RegClassID;
2718 return AMDGPU::TTMP_128RegClassID;
2720 return AMDGPU::TTMP_256RegClassID;
2722 return AMDGPU::TTMP_512RegClassID;
2724 }
else if (Is == IS_SGPR) {
2728 return AMDGPU::SGPR_32RegClassID;
2730 return AMDGPU::SGPR_64RegClassID;
2732 return AMDGPU::SGPR_96RegClassID;
2734 return AMDGPU::SGPR_128RegClassID;
2736 return AMDGPU::SGPR_160RegClassID;
2738 return AMDGPU::SGPR_192RegClassID;
2740 return AMDGPU::SGPR_224RegClassID;
2742 return AMDGPU::SGPR_256RegClassID;
2744 return AMDGPU::SGPR_288RegClassID;
2746 return AMDGPU::SGPR_320RegClassID;
2748 return AMDGPU::SGPR_352RegClassID;
2750 return AMDGPU::SGPR_384RegClassID;
2752 return AMDGPU::SGPR_512RegClassID;
2754 }
else if (Is == IS_AGPR) {
2758 return AMDGPU::AGPR_32RegClassID;
2760 return AMDGPU::AReg_64RegClassID;
2762 return AMDGPU::AReg_96RegClassID;
2764 return AMDGPU::AReg_128RegClassID;
2766 return AMDGPU::AReg_160RegClassID;
2768 return AMDGPU::AReg_192RegClassID;
2770 return AMDGPU::AReg_224RegClassID;
2772 return AMDGPU::AReg_256RegClassID;
2774 return AMDGPU::AReg_288RegClassID;
2776 return AMDGPU::AReg_320RegClassID;
2778 return AMDGPU::AReg_352RegClassID;
2780 return AMDGPU::AReg_384RegClassID;
2782 return AMDGPU::AReg_512RegClassID;
2784 return AMDGPU::AReg_1024RegClassID;
2792 .
Case(
"exec", AMDGPU::EXEC)
2793 .
Case(
"vcc", AMDGPU::VCC)
2794 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2795 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2796 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2797 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2798 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2799 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2800 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2801 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2802 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2803 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2804 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2805 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2806 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2807 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2808 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2809 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2810 .
Case(
"m0", AMDGPU::M0)
2811 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2812 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2813 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2814 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2815 .
Case(
"scc", AMDGPU::SRC_SCC)
2816 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2817 .
Case(
"tba", AMDGPU::TBA)
2818 .
Case(
"tma", AMDGPU::TMA)
2819 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2820 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2821 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2822 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2823 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2824 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2825 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2826 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2827 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2828 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2829 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2830 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2831 .
Case(
"pc", AMDGPU::PC_REG)
2832 .
Case(
"null", AMDGPU::SGPR_NULL)
2836bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2837 SMLoc &EndLoc,
bool RestoreOnFailure) {
2838 auto R = parseRegister();
2839 if (!R)
return true;
2841 RegNo =
R->getReg();
2842 StartLoc =
R->getStartLoc();
2843 EndLoc =
R->getEndLoc();
2847bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2849 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2852ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2854 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2855 bool PendingErrors = getParser().hasPendingError();
2856 getParser().clearPendingErrors();
2864bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2865 RegisterKind RegKind,
2867 RegisterKind RegKind1, SMLoc Loc) {
2869 if (RegKind == IS_SGPR) {
2870 unsigned RegIdx = (
Reg - AMDGPU::SGPR0) + RegWidth / 32;
2871 if ((RegIdx == 106 && Reg1 == AMDGPU::VCC_LO) ||
2872 (RegIdx == 107 && Reg1 == AMDGPU::VCC_HI)) {
2878 if (RegKind != RegKind1) {
2879 Error(Loc,
"registers in a list must be of the same kind");
2880 return MCRegister();
2885 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2890 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2891 Reg = AMDGPU::FLAT_SCR;
2895 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2896 Reg = AMDGPU::XNACK_MASK;
2900 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2905 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2910 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2915 Error(Loc,
"register does not fit in the list");
2921 if (Reg1 !=
Reg + RegWidth / 32) {
2922 Error(Loc,
"registers in a list must have consecutive indices");
2940 {{
"ttmp"}, IS_TTMP},
2946 return Kind == IS_VGPR ||
2954 if (Str.starts_with(
Reg.Name))
2960 return !Str.getAsInteger(10, Num);
2964AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2965 const AsmToken &NextToken)
const {
2980 StringRef RegSuffix = Str.substr(
RegName.size());
2981 if (!RegSuffix.
empty()) {
2999AMDGPUAsmParser::isRegister()
3001 return isRegister(
getToken(), peekToken());
3004MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
3005 unsigned SubReg,
unsigned RegWidth,
3009 unsigned AlignSize = 1;
3010 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
3016 if (RegNum % AlignSize != 0) {
3017 Error(Loc,
"invalid register alignment");
3018 return MCRegister();
3021 unsigned RegIdx = RegNum / AlignSize;
3024 Error(Loc,
"invalid or unsupported register size");
3025 return MCRegister();
3029 const MCRegisterClass &RC =
TRI->getRegClass(RCID);
3030 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
3031 Error(Loc,
"register index is out of range");
3032 return AMDGPU::NoRegister;
3035 if (RegKind == IS_VGPR && !
isGFX1250Plus() && RegIdx + RegWidth / 32 > 256) {
3036 Error(Loc,
"register index is out of range");
3037 return MCRegister();
3053bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
3055 int64_t RegLo, RegHi;
3059 SMLoc FirstIdxLoc = getLoc();
3066 SecondIdxLoc = getLoc();
3077 Error(FirstIdxLoc,
"invalid register index");
3082 Error(SecondIdxLoc,
"invalid register index");
3086 if (RegLo > RegHi) {
3087 Error(FirstIdxLoc,
"first register index should not exceed second index");
3091 if (RegHi == RegLo) {
3092 StringRef RegSuffix = getTokenStr();
3093 if (RegSuffix ==
".l") {
3094 SubReg = AMDGPU::lo16;
3096 }
else if (RegSuffix ==
".h") {
3097 SubReg = AMDGPU::hi16;
3102 Num =
static_cast<unsigned>(RegLo);
3103 RegWidth = 32 * ((RegHi - RegLo) + 1);
3108MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3111 SmallVectorImpl<AsmToken> &Tokens) {
3117 RegKind = IS_SPECIAL;
3124MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3127 SmallVectorImpl<AsmToken> &Tokens) {
3129 StringRef
RegName = getTokenStr();
3130 auto Loc = getLoc();
3134 Error(Loc,
"invalid register name");
3135 return MCRegister();
3143 unsigned SubReg = NoSubRegister;
3144 bool IsRange =
false;
3145 if (!RegSuffix.
empty()) {
3147 SubReg = AMDGPU::lo16;
3149 SubReg = AMDGPU::hi16;
3153 Error(Loc,
"invalid register index");
3154 return MCRegister();
3160 if (!ParseRegRange(RegNum, RegWidth, SubReg))
3161 return MCRegister();
3165 MCRegister
Reg = getRegularReg(RegKind, RegNum, SubReg, RegWidth, Loc);
3166 const MCRegisterInfo &
TRI = *
getContext().getRegisterInfo();
3167 if (RegKind == IS_SGPR && IsRange
3168 ? (
TRI.isSubRegister(
Reg, VCC_LO) ||
TRI.isSubRegister(
Reg, VCC_HI))
3169 : (
Reg == VCC_LO ||
Reg == VCC_HI)) {
3170 Error(Loc,
"register index is out of range");
3171 return MCRegister();
3177MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3178 unsigned &RegNum,
unsigned &RegWidth,
3179 SmallVectorImpl<AsmToken> &Tokens) {
3181 auto ListLoc = getLoc();
3184 "expected a register or a list of registers")) {
3185 return MCRegister();
3190 auto Loc = getLoc();
3191 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3192 return MCRegister();
3193 if (RegWidth != 32) {
3194 Error(Loc,
"expected a single 32-bit register");
3195 return MCRegister();
3199 RegisterKind NextRegKind;
3201 unsigned NextRegNum, NextRegWidth;
3204 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3205 NextRegNum, NextRegWidth,
3207 return MCRegister();
3209 if (NextRegWidth != 32) {
3210 Error(Loc,
"expected a single 32-bit register");
3211 return MCRegister();
3213 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, NextRegKind,
3215 return MCRegister();
3219 "expected a comma or a closing square bracket")) {
3220 return MCRegister();
3224 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3229bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3230 MCRegister &
Reg,
unsigned &RegNum,
3232 SmallVectorImpl<AsmToken> &Tokens) {
3233 auto Loc = getLoc();
3237 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3239 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3241 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3246 assert(Parser.hasPendingError());
3250 if (!subtargetHasRegister(*
TRI,
Reg)) {
3251 if (
Reg == AMDGPU::SGPR_NULL) {
3252 Error(Loc,
"'null' operand is not supported on this GPU");
3255 " register not available on this GPU");
3263bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3264 MCRegister &
Reg,
unsigned &RegNum,
3266 bool RestoreOnFailure ) {
3270 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3271 if (RestoreOnFailure) {
3272 while (!Tokens.
empty()) {
3281std::optional<StringRef>
3282AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3285 return StringRef(
".amdgcn.next_free_vgpr");
3287 return StringRef(
".amdgcn.next_free_sgpr");
3289 return std::nullopt;
3293void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3294 auto SymbolName = getGprCountSymbolName(RegKind);
3295 assert(SymbolName &&
"initializing invalid register kind");
3301bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3302 unsigned DwordRegIndex,
3303 unsigned RegWidth) {
3308 auto SymbolName = getGprCountSymbolName(RegKind);
3313 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3317 return !
Error(getLoc(),
3318 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3322 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3324 if (OldCount <= NewMax)
3330std::unique_ptr<AMDGPUOperand>
3331AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3333 SMLoc StartLoc = Tok.getLoc();
3334 SMLoc EndLoc = Tok.getEndLoc();
3335 RegisterKind RegKind;
3337 unsigned RegNum, RegWidth;
3339 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3343 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3346 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3347 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3350ParseStatus AMDGPUAsmParser::parseImm(
OperandVector &Operands,
3354 if (isRegister() || isModifier())
3357 if (
Lit == LitModifier::None) {
3358 if (trySkipId(
"lit"))
3359 Lit = LitModifier::Lit;
3360 else if (trySkipId(
"lit64"))
3361 Lit = LitModifier::Lit64;
3363 if (
Lit != LitModifier::None) {
3366 ParseStatus S = parseImm(Operands, HasSP3AbsModifier,
Lit);
3375 const auto& NextTok = peekToken();
3378 bool Negate =
false;
3386 AMDGPUOperand::Modifiers Mods;
3394 StringRef Num = getTokenStr();
3397 APFloat RealVal(APFloat::IEEEdouble());
3398 auto roundMode = APFloat::rmNearestTiesToEven;
3399 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3402 RealVal.changeSign();
3405 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3406 AMDGPUOperand::ImmTyNone,
true));
3407 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3408 Op.setModifiers(Mods);
3417 if (HasSP3AbsModifier) {
3426 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3429 if (Parser.parseExpression(Expr))
3433 if (Expr->evaluateAsAbsolute(IntVal)) {
3435 return Error(S,
"literal value out of range");
3436 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3437 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3438 Op.setModifiers(Mods);
3440 if (
Lit != LitModifier::None)
3442 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3451ParseStatus AMDGPUAsmParser::parseReg(
OperandVector &Operands) {
3455 if (
auto R = parseRegister()) {
3463ParseStatus AMDGPUAsmParser::parseRegOrImm(
OperandVector &Operands,
3465 ParseStatus Res = parseReg(Operands);
3470 return parseImm(Operands, HasSP3AbsMod,
Lit);
3474AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3477 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3483AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3488AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3489 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3493AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3494 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3511AMDGPUAsmParser::isModifier() {
3514 AsmToken NextToken[2];
3515 peekTokens(NextToken);
3517 return isOperandModifier(Tok, NextToken[0]) ||
3518 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3519 isOpcodeModifierWithVal(Tok, NextToken[0]);
3545AMDGPUAsmParser::parseSP3NegModifier() {
3547 AsmToken NextToken[2];
3548 peekTokens(NextToken);
3551 (isRegister(NextToken[0], NextToken[1]) ||
3553 isId(NextToken[0],
"abs"))) {
3562AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
3570 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3572 SP3Neg = parseSP3NegModifier();
3575 Neg = trySkipId(
"neg");
3577 return Error(Loc,
"expected register or immediate");
3581 Abs = trySkipId(
"abs");
3586 if (trySkipId(
"lit")) {
3587 Lit = LitModifier::Lit;
3590 }
else if (trySkipId(
"lit64")) {
3591 Lit = LitModifier::Lit64;
3594 if (!has64BitLiterals())
3595 return Error(Loc,
"lit64 is not supported on this GPU");
3601 return Error(Loc,
"expected register or immediate");
3605 Res = parseRegOrImm(Operands, SP3Abs,
Lit);
3607 Res = parseReg(Operands);
3610 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3614 if (
Lit != LitModifier::None && !Operands.
back()->isImm())
3615 Error(Loc,
"expected immediate with lit modifier");
3617 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3623 if (
Lit != LitModifier::None &&
3627 AMDGPUOperand::Modifiers Mods;
3628 Mods.Abs = Abs || SP3Abs;
3629 Mods.Neg = Neg || SP3Neg;
3632 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3633 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3635 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3636 Op.setModifiers(Mods);
3642AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
3644 bool Sext = trySkipId(
"sext");
3645 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3650 Res = parseRegOrImm(Operands);
3652 Res = parseReg(Operands);
3660 AMDGPUOperand::Modifiers Mods;
3663 if (Mods.hasIntModifiers()) {
3664 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3666 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3667 Op.setModifiers(Mods);
3673ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
3674 return parseRegOrImmWithFPInputMods(Operands,
false);
3677ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
3678 return parseRegOrImmWithIntInputMods(Operands,
false);
3681ParseStatus AMDGPUAsmParser::parseVReg32OrOff(
OperandVector &Operands) {
3682 auto Loc = getLoc();
3683 if (trySkipId(
"off")) {
3684 Operands.
push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3685 AMDGPUOperand::ImmTyOff,
false));
3692 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3701unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3708 return Match_InvalidOperand;
3710 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3711 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3714 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3716 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3717 return Match_InvalidOperand;
3725 if (tryAnotherVOPDEncoding(Inst))
3726 return Match_InvalidOperand;
3728 return Match_Success;
3732 static const unsigned Variants[] = {
3742ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3743 if (isForcedDPP() && isForcedVOP3()) {
3747 if (getForcedEncodingSize() == 32) {
3752 if (isForcedVOP3()) {
3757 if (isForcedSDWA()) {
3763 if (isForcedDPP()) {
3771StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3772 if (isForcedDPP() && isForcedVOP3())
3775 if (getForcedEncodingSize() == 32)
3791AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3795 case AMDGPU::FLAT_SCR:
3797 case AMDGPU::VCC_LO:
3798 case AMDGPU::VCC_HI:
3805 return MCRegister();
3812bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3813 unsigned OpIdx)
const {
3870unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3876 case AMDGPU::V_LSHLREV_B64_e64:
3877 case AMDGPU::V_LSHLREV_B64_gfx10:
3878 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3879 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3880 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3881 case AMDGPU::V_LSHRREV_B64_e64:
3882 case AMDGPU::V_LSHRREV_B64_gfx10:
3883 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3884 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3885 case AMDGPU::V_ASHRREV_I64_e64:
3886 case AMDGPU::V_ASHRREV_I64_gfx10:
3887 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3888 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3889 case AMDGPU::V_LSHL_B64_e64:
3890 case AMDGPU::V_LSHR_B64_e64:
3891 case AMDGPU::V_ASHR_I64_e64:
3904 bool AddMandatoryLiterals =
false) {
3907 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3911 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3913 return {getNamedOperandIdx(Opcode, OpName::src0X),
3914 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3915 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3916 getNamedOperandIdx(Opcode, OpName::src0Y),
3917 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3918 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3923 return {getNamedOperandIdx(Opcode, OpName::src0),
3924 getNamedOperandIdx(Opcode, OpName::src1),
3925 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3928bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3931 return !isInlineConstant(Inst,
OpIdx);
3938 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3949 const unsigned Opcode = Inst.
getOpcode();
3950 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3953 if (!LaneSelOp.
isReg())
3956 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3959bool AMDGPUAsmParser::validateConstantBusLimitations(
3961 const unsigned Opcode = Inst.
getOpcode();
3962 const MCInstrDesc &
Desc = MII.
get(Opcode);
3963 MCRegister LastSGPR;
3964 unsigned ConstantBusUseCount = 0;
3965 unsigned NumLiterals = 0;
3966 unsigned LiteralSize;
3968 if (!(
Desc.TSFlags &
3983 SmallDenseSet<MCRegister> SGPRsUsed;
3984 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3986 SGPRsUsed.
insert(SGPRUsed);
3987 ++ConstantBusUseCount;
3992 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3994 for (
int OpIdx : OpIndices) {
3999 if (usesConstantBus(Inst,
OpIdx)) {
4008 if (SGPRsUsed.
insert(LastSGPR).second) {
4009 ++ConstantBusUseCount;
4029 if (NumLiterals == 0) {
4032 }
else if (LiteralSize !=
Size) {
4038 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
4040 "invalid operand (violates constant bus restrictions)");
4047std::optional<unsigned>
4048AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
4050 const unsigned Opcode = Inst.
getOpcode();
4056 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
4057 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
4066 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1170 ||
4067 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
4068 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
4069 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx13 ||
4070 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250 ||
4071 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx13;
4075 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
4076 int I = getNamedOperandIdx(Opcode, OpName);
4080 int64_t
Imm =
Op.getImm();
4086 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
4087 OpName::vsrc2Y, OpName::imm}) {
4088 int I = getNamedOperandIdx(Opcode, OpName);
4098 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
4099 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
4101 return InvalidCompOprIdx;
4104bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
4111 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
4112 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
4113 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
4115 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
4119 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
4120 if (!InvalidCompOprIdx.has_value())
4123 auto CompOprIdx = *InvalidCompOprIdx;
4126 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4127 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4128 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4130 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4131 if (CompOprIdx == VOPD::Component::DST) {
4133 Error(Loc,
"dst registers must be distinct");
4135 Error(Loc,
"one dst register must be even and the other odd");
4137 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4138 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4139 " operands must use different VGPR banks");
4147bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4149 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4150 if (!InvalidCompOprIdx.has_value())
4154 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4155 if (InvalidCompOprIdx.has_value()) {
4160 if (*InvalidCompOprIdx == VOPD::Component::DST)
4173bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4174 const unsigned Opcode = Inst.
getOpcode();
4189 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4190 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4191 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4192 int I = getNamedOperandIdx(Opcode, OpName);
4199 return !tryVOPD3(Inst);
4204bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4205 const unsigned Opcode = Inst.
getOpcode();
4210 return tryVOPD(Inst);
4211 return tryVOPD3(Inst);
4214bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4220 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4231bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4239 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4240 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4241 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4246 if ((DMaskIdx == -1 || TFEIdx == -1) &&
4247 hasBVHRayTracingInsts())
4250 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4251 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4256 bool IsPackedD16 =
false;
4260 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4261 IsPackedD16 = D16Idx >= 0;
4263 DataSize = (DataSize + 1) / 2;
4266 if ((VDataSize / 4) == DataSize + TFESize)
4271 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4273 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4275 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4279bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4288 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4290 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4292 ? AMDGPU::OpName::srsrc
4293 : AMDGPU::OpName::rsrc;
4294 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4295 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4296 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4300 assert(SrsrcIdx > VAddr0Idx);
4303 if (BaseOpcode->
BVH) {
4304 if (IsA16 == BaseOpcode->
A16)
4306 Error(IDLoc,
"image address size does not match a16");
4312 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4313 unsigned ActualAddrSize =
4314 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4316 unsigned ExpectedAddrSize =
4320 if (hasPartialNSAEncoding() &&
4323 int VAddrLastIdx = SrsrcIdx - 1;
4324 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4326 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4329 if (ExpectedAddrSize > 12)
4330 ExpectedAddrSize = 16;
4335 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4339 if (ActualAddrSize == ExpectedAddrSize)
4342 Error(IDLoc,
"image address size does not match dim and a16");
4346bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4353 if (!
Desc.mayLoad() || !
Desc.mayStore())
4356 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4363 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4366bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4374 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4382 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4385bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4400 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4401 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4408bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4416 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4419 if (!BaseOpcode->
MSAA)
4422 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4428 return DimInfo->
MSAA;
4434 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4435 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4436 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4446bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4455 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4458 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4466 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4470bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4475 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4478 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4481 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4488 Error(getOperandLoc(Operands, Src0Idx),
4489 "source operand must be either a VGPR or an inline constant");
4496bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4499 const MCInstrDesc &
Desc = MII.
get(Opcode);
4502 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4505 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4509 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4510 Error(getOperandLoc(Operands, Src2Idx),
4511 "inline constants are not allowed for this operand");
4518bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4526 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4527 if (BlgpIdx != -1) {
4528 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4529 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4539 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4540 Error(getOperandLoc(Operands, Src0Idx),
4541 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4546 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4547 Error(getOperandLoc(Operands, Src1Idx),
4548 "wrong register tuple size for blgp value " + Twine(BLGP));
4556 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4560 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4564 MCRegister Src2Reg = Src2.
getReg();
4566 if (Src2Reg == DstReg)
4571 .getSizeInBits() <= 128)
4574 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4575 Error(getOperandLoc(Operands, Src2Idx),
4576 "source 2 operand must not partially overlap with dst");
4583bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4587 case V_DIV_SCALE_F32_gfx6_gfx7:
4588 case V_DIV_SCALE_F32_vi:
4589 case V_DIV_SCALE_F32_gfx10:
4590 case V_DIV_SCALE_F64_gfx6_gfx7:
4591 case V_DIV_SCALE_F64_vi:
4592 case V_DIV_SCALE_F64_gfx10:
4598 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4599 AMDGPU::OpName::src2_modifiers,
4600 AMDGPU::OpName::src2_modifiers}) {
4611bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4619 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4628bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4635 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4643 case AMDGPU::V_SUBREV_F32_e32:
4644 case AMDGPU::V_SUBREV_F32_e64:
4645 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4646 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4647 case AMDGPU::V_SUBREV_F32_e32_vi:
4648 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4649 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4650 case AMDGPU::V_SUBREV_F32_e64_vi:
4652 case AMDGPU::V_SUBREV_CO_U32_e32:
4653 case AMDGPU::V_SUBREV_CO_U32_e64:
4654 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4655 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4657 case AMDGPU::V_SUBBREV_U32_e32:
4658 case AMDGPU::V_SUBBREV_U32_e64:
4659 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4660 case AMDGPU::V_SUBBREV_U32_e32_vi:
4661 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4662 case AMDGPU::V_SUBBREV_U32_e64_vi:
4664 case AMDGPU::V_SUBREV_U32_e32:
4665 case AMDGPU::V_SUBREV_U32_e64:
4666 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4667 case AMDGPU::V_SUBREV_U32_e32_vi:
4668 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4669 case AMDGPU::V_SUBREV_U32_e64_vi:
4671 case AMDGPU::V_SUBREV_F16_e32:
4672 case AMDGPU::V_SUBREV_F16_e64:
4673 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4674 case AMDGPU::V_SUBREV_F16_e32_vi:
4675 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4676 case AMDGPU::V_SUBREV_F16_e64_vi:
4678 case AMDGPU::V_SUBREV_U16_e32:
4679 case AMDGPU::V_SUBREV_U16_e64:
4680 case AMDGPU::V_SUBREV_U16_e32_vi:
4681 case AMDGPU::V_SUBREV_U16_e64_vi:
4683 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4684 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4685 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4687 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4688 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4690 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4691 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4693 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4694 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4696 case AMDGPU::V_LSHRREV_B32_e32:
4697 case AMDGPU::V_LSHRREV_B32_e64:
4698 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4699 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4700 case AMDGPU::V_LSHRREV_B32_e32_vi:
4701 case AMDGPU::V_LSHRREV_B32_e64_vi:
4702 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4703 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4705 case AMDGPU::V_ASHRREV_I32_e32:
4706 case AMDGPU::V_ASHRREV_I32_e64:
4707 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4708 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4709 case AMDGPU::V_ASHRREV_I32_e32_vi:
4710 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4711 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4712 case AMDGPU::V_ASHRREV_I32_e64_vi:
4714 case AMDGPU::V_LSHLREV_B32_e32:
4715 case AMDGPU::V_LSHLREV_B32_e64:
4716 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4717 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4718 case AMDGPU::V_LSHLREV_B32_e32_vi:
4719 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4720 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4721 case AMDGPU::V_LSHLREV_B32_e64_vi:
4723 case AMDGPU::V_LSHLREV_B16_e32:
4724 case AMDGPU::V_LSHLREV_B16_e64:
4725 case AMDGPU::V_LSHLREV_B16_e32_vi:
4726 case AMDGPU::V_LSHLREV_B16_e64_vi:
4727 case AMDGPU::V_LSHLREV_B16_gfx10:
4729 case AMDGPU::V_LSHRREV_B16_e32:
4730 case AMDGPU::V_LSHRREV_B16_e64:
4731 case AMDGPU::V_LSHRREV_B16_e32_vi:
4732 case AMDGPU::V_LSHRREV_B16_e64_vi:
4733 case AMDGPU::V_LSHRREV_B16_gfx10:
4735 case AMDGPU::V_ASHRREV_I16_e32:
4736 case AMDGPU::V_ASHRREV_I16_e64:
4737 case AMDGPU::V_ASHRREV_I16_e32_vi:
4738 case AMDGPU::V_ASHRREV_I16_e64_vi:
4739 case AMDGPU::V_ASHRREV_I16_gfx10:
4741 case AMDGPU::V_LSHLREV_B64_e64:
4742 case AMDGPU::V_LSHLREV_B64_gfx10:
4743 case AMDGPU::V_LSHLREV_B64_vi:
4745 case AMDGPU::V_LSHRREV_B64_e64:
4746 case AMDGPU::V_LSHRREV_B64_gfx10:
4747 case AMDGPU::V_LSHRREV_B64_vi:
4749 case AMDGPU::V_ASHRREV_I64_e64:
4750 case AMDGPU::V_ASHRREV_I64_gfx10:
4751 case AMDGPU::V_ASHRREV_I64_vi:
4753 case AMDGPU::V_PK_LSHLREV_B16:
4754 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4755 case AMDGPU::V_PK_LSHLREV_B16_vi:
4757 case AMDGPU::V_PK_LSHRREV_B16:
4758 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4759 case AMDGPU::V_PK_LSHRREV_B16_vi:
4760 case AMDGPU::V_PK_ASHRREV_I16:
4761 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4762 case AMDGPU::V_PK_ASHRREV_I16_vi:
4769bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4771 using namespace SIInstrFlags;
4772 const unsigned Opcode = Inst.
getOpcode();
4773 const MCInstrDesc &
Desc = MII.
get(Opcode);
4778 if ((
Desc.TSFlags & Enc) == 0)
4781 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4782 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4786 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4789 Error(getOperandLoc(Operands, SrcIdx),
4790 "lds_direct is not supported on this GPU");
4795 Error(getOperandLoc(Operands, SrcIdx),
4796 "lds_direct cannot be used with this instruction");
4800 if (SrcName != OpName::src0) {
4801 Error(getOperandLoc(Operands, SrcIdx),
4802 "lds_direct may be used as src0 only");
4811SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4812 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4813 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4814 if (
Op.isFlatOffset())
4815 return Op.getStartLoc();
4820bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4823 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4829 return validateFlatOffset(Inst, Operands);
4832 return validateSMEMOffset(Inst, Operands);
4838 const unsigned OffsetSize = 24;
4839 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4840 Error(getFlatOffsetLoc(Operands),
4841 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4842 "-bit unsigned offset for buffer ops");
4846 const unsigned OffsetSize = 16;
4847 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4848 Error(getFlatOffsetLoc(Operands),
4849 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4856bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4863 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4867 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4868 Error(getFlatOffsetLoc(Operands),
4869 "flat offset modifier is not supported on this GPU");
4876 bool AllowNegative =
4879 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4880 Error(getFlatOffsetLoc(Operands),
4881 Twine(
"expected a ") +
4882 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4883 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4890SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4892 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4893 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4894 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4895 return Op.getStartLoc();
4900bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4910 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4924 Error(getSMEMOffsetLoc(Operands),
4926 ?
"expected a 23-bit unsigned offset for buffer ops"
4927 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4928 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4929 :
"expected a 21-bit signed offset");
4934bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4937 const MCInstrDesc &
Desc = MII.
get(Opcode);
4941 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4942 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4944 const int OpIndices[] = { Src0Idx, Src1Idx };
4946 unsigned NumExprs = 0;
4947 unsigned NumLiterals = 0;
4950 for (
int OpIdx : OpIndices) {
4951 if (
OpIdx == -1)
break;
4957 std::optional<int64_t>
Imm;
4960 }
else if (MO.
isExpr()) {
4969 if (!
Imm.has_value()) {
4971 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4975 if (NumLiterals == 0 || LiteralValue !=
Value) {
4983 if (NumLiterals + NumExprs <= 1)
4986 Error(getOperandLoc(Operands, Src1Idx),
4987 "only one unique literal operand is allowed");
4991bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4994 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5004 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5005 if (OpSelIdx != -1) {
5009 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
5010 if (OpSelHiIdx != -1) {
5019 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5029 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
5030 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5031 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5032 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
5034 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
5035 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5041 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
5043 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
5053 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
5054 if (Src2Idx != -1) {
5055 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
5065bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
5066 if (!hasTrue16Insts())
5068 const MCRegisterInfo *MRI = getMRI();
5070 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5076 if (OpSelOpValue == 0)
5078 unsigned OpCount = 0;
5079 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
5080 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
5081 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
5088 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
5089 if (OpSelOpIsHi != VGPRSuffixIsHi)
5098bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
5099 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
5112 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
5123 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
5124 AMDGPU::OpName::src1_modifiers,
5125 AMDGPU::OpName::src2_modifiers};
5127 for (
unsigned i = 0; i < 3; ++i) {
5137bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5140 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5141 if (DppCtrlIdx >= 0) {
5148 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5149 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5150 :
"DP ALU dpp only supports row_newbcast");
5155 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5156 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5159 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5161 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5164 Error(getOperandLoc(Operands, Src1Idx),
5165 "invalid operand for instruction");
5169 Error(getInstLoc(Operands),
5170 "src1 immediate operand invalid for instruction");
5180bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5181 return (
Reg == AMDGPU::VCC && isWave64()) ||
5182 (
Reg == AMDGPU::VCC_LO && isWave32());
5186bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5189 const MCInstrDesc &
Desc = MII.
get(Opcode);
5190 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5192 !HasMandatoryLiteral && !
isVOPD(Opcode))
5197 std::optional<unsigned> LiteralOpIdx;
5200 for (
int OpIdx : OpIndices) {
5210 std::optional<int64_t>
Imm;
5216 bool IsAnotherLiteral =
false;
5217 bool IsForcedLit = findMCOperand(Operands,
OpIdx).isForcedLit();
5218 bool IsForcedLit64 = findMCOperand(Operands,
OpIdx).isForcedLit64();
5219 if (!
Imm.has_value()) {
5221 IsAnotherLiteral =
true;
5222 }
else if (IsForcedLit || IsForcedLit64 || !isInlineConstant(Inst,
OpIdx)) {
5227 HasMandatoryLiteral);
5228 unsigned OpTy =
Desc.operands()[
OpIdx].OperandType;
5238 (IsForcedLit64 && !HasMandatoryLiteral)) &&
5239 (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5241 "invalid operand for instruction");
5246 if (!IsForcedFP64 && (IsForcedLit64 || !IsValid32Op) &&
5247 OpIdx != getNamedOperandIdx(Opcode, OpName::src0)) {
5249 "invalid operand for instruction");
5253 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5260 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5261 !getFeatureBits()[FeatureVOP3Literal]) {
5263 "literal operands are not supported");
5267 if (LiteralOpIdx && IsAnotherLiteral) {
5268 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5269 getOperandLoc(Operands, *LiteralOpIdx)),
5270 "only one unique literal operand is allowed");
5274 if (IsAnotherLiteral)
5275 LiteralOpIdx =
OpIdx;
5298bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5306 ? AMDGPU::OpName::data0
5307 : AMDGPU::OpName::vdata;
5309 const MCRegisterInfo *MRI = getMRI();
5310 int DstAreg =
IsAGPROperand(Inst, AMDGPU::OpName::vdst, MRI);
5314 int Data2Areg =
IsAGPROperand(Inst, AMDGPU::OpName::data1, MRI);
5315 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5319 auto FB = getFeatureBits();
5320 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5321 if (DataAreg < 0 || DstAreg < 0)
5323 return DstAreg == DataAreg;
5326 return DstAreg < 1 && DataAreg < 1;
5329bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5330 auto FB = getFeatureBits();
5331 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5335 const MCRegisterInfo *MRI = getMRI();
5338 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5341 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5345 case AMDGPU::DS_LOAD_TR6_B96:
5346 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5350 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5351 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5355 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5356 if (VAddrIdx != -1) {
5359 if ((
Sub - AMDGPU::VGPR0) & 1)
5364 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5365 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5370 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5371 const MCRegisterClass &AGPR32 = MRI->
getRegClass(AMDGPU::AGPR_32RegClassID);
5390SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5391 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5392 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5394 return Op.getStartLoc();
5399bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5402 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5405 SMLoc BLGPLoc = getBLGPLoc(Operands);
5408 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5409 auto FB = getFeatureBits();
5410 bool UsesNeg =
false;
5411 if (FB[AMDGPU::FeatureGFX940Insts]) {
5413 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5414 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5415 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5416 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5421 if (IsNeg == UsesNeg)
5425 UsesNeg ?
"invalid modifier: blgp is not supported"
5426 :
"invalid modifier: neg is not supported");
5431bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5437 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5438 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5439 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5440 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5443 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5446 if (
Reg == AMDGPU::SGPR_NULL)
5449 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5453bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5459 return validateGWS(Inst, Operands);
5464 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5469 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5470 Error(S,
"gds modifier is not supported on this GPU");
5478bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5480 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5484 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5485 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5488 const MCRegisterInfo *MRI = getMRI();
5489 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5491 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5494 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5496 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5503bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5506 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5507 AMDGPU::OpName::cpol);
5515 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5518 Error(S,
"scale_offset is not supported on this GPU");
5521 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5524 Error(S,
"nv is not supported on this GPU");
5529 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5532 Error(S,
"scale_offset is not supported for this instruction");
5536 return validateTHAndScopeBits(Inst, Operands, CPol);
5541 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5542 Error(S,
"cache policy is not supported for SMRD instructions");
5546 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5555 if (!(TSFlags & AllowSCCModifier)) {
5556 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5560 "scc modifier is not supported for this instruction on this GPU");
5571 :
"instruction must use glc");
5576 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5579 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5581 :
"instruction must not use glc");
5589bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5591 const unsigned CPol) {
5595 const unsigned Opcode = Inst.
getOpcode();
5596 const MCInstrDesc &TID = MII.
get(Opcode);
5599 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5606 return PrintError(
"th:TH_ATOMIC_RETURN requires a destination operand");
5611 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5619 return PrintError(
"invalid th value for SMEM instruction");
5626 return PrintError(
"scope and th combination is not valid");
5632 return PrintError(
"invalid th value for atomic instructions");
5635 return PrintError(
"invalid th value for store instructions");
5638 return PrintError(
"invalid th value for load instructions");
5644bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5647 if (
Desc.mayStore() &&
5649 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5650 if (Loc != getInstLoc(Operands)) {
5651 Error(Loc,
"TFE modifier has no meaning for store instructions");
5659bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5665 int AFmtIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
5669 int BFmtIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
5672 auto validateFmt = [&](
unsigned Fmt, AMDGPU::OpName SrcOp) ->
bool {
5673 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5681 Error(getOperandLoc(Operands, SrcIdx),
5682 "wrong register tuple size for " +
5687 if (!validateFmt(AFmt, AMDGPU::OpName::src0) ||
5688 !validateFmt(BFmt, AMDGPU::OpName::src1))
5692 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
5693 if (AScaleIdx == -1)
5697 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
5700 Error(getImmLoc(AMDGPUOperand::ImmTyMatrixAFMT, Operands),
5701 "invalid matrix and scale format combination");
5708bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5710 if (!validateLdsDirect(Inst, Operands))
5712 if (!validateTrue16OpSel(Inst)) {
5713 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5714 "op_sel operand conflicts with 16-bit operand suffix");
5717 if (!validateSOPLiteral(Inst, Operands))
5719 if (!validateVOPLiteral(Inst, Operands)) {
5722 if (!validateConstantBusLimitations(Inst, Operands)) {
5725 if (!validateVOPD(Inst, Operands)) {
5728 if (!validateIntClampSupported(Inst)) {
5729 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5730 "integer clamping is not supported on this GPU");
5733 if (!validateOpSel(Inst)) {
5734 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5735 "invalid op_sel operand");
5738 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5739 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5740 "invalid neg_lo operand");
5743 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5744 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5745 "invalid neg_hi operand");
5748 if (!validateDPP(Inst, Operands)) {
5752 if (!validateMIMGD16(Inst)) {
5753 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5754 "d16 modifier is not supported on this GPU");
5757 if (!validateMIMGDim(Inst, Operands)) {
5758 Error(IDLoc,
"missing dim operand");
5761 if (!validateTensorR128(Inst)) {
5762 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5763 "instruction must set modifier r128=0");
5766 if (!validateMIMGMSAA(Inst)) {
5767 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5768 "invalid dim; must be MSAA type");
5771 if (!validateMIMGDataSize(Inst, IDLoc)) {
5774 if (!validateMIMGAddrSize(Inst, IDLoc))
5776 if (!validateMIMGAtomicDMask(Inst)) {
5777 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5778 "invalid atomic image dmask");
5781 if (!validateMIMGGatherDMask(Inst)) {
5782 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5783 "invalid image_gather dmask: only one bit must be set");
5786 if (!validateMovrels(Inst, Operands)) {
5789 if (!validateOffset(Inst, Operands)) {
5792 if (!validateMAIAccWrite(Inst, Operands)) {
5795 if (!validateMAISrc2(Inst, Operands)) {
5798 if (!validateMFMA(Inst, Operands)) {
5801 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5805 if (!validateAGPRLdSt(Inst)) {
5806 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5807 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5808 :
"invalid register class: agpr loads and stores not supported on this GPU"
5812 if (!validateVGPRAlign(Inst)) {
5814 "invalid register class: vgpr tuples must be 64 bit aligned");
5817 if (!validateDS(Inst, Operands)) {
5821 if (!validateBLGP(Inst, Operands)) {
5825 if (!validateDivScale(Inst)) {
5826 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5829 if (!validateWaitCnt(Inst, Operands)) {
5832 if (!validateTFE(Inst, Operands)) {
5835 if (!validateWMMA(Inst, Operands)) {
5844 unsigned VariantID = 0);
5848 unsigned VariantID);
5850bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5855bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5856 const FeatureBitset &FBS,
5857 ArrayRef<unsigned> Variants) {
5858 for (
auto Variant : Variants) {
5866bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5868 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5871 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5876 getParser().clearPendingErrors();
5880 StringRef VariantName = getMatchedVariantName();
5881 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5884 " variant of this instruction is not supported"));
5888 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5889 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5891 FeatureBitset FeaturesWS32 = getFeatureBits();
5892 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5893 .
flip(AMDGPU::FeatureWavefrontSize32);
5894 FeatureBitset AvailableFeaturesWS32 =
5895 ComputeAvailableFeatures(FeaturesWS32);
5897 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5898 return Error(IDLoc,
"instruction requires wavesize=32");
5902 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5903 return Error(IDLoc,
"instruction not supported on this GPU (" +
5904 getSTI().
getCPU() +
")" +
": " + Mnemo);
5909 return Error(IDLoc,
"invalid instruction" + Suggestion);
5915 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5916 if (
Op.isToken() && InvalidOprIdx > 1) {
5917 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5918 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5923bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5926 uint64_t &ErrorInfo,
5927 bool MatchingInlineAsm) {
5930 unsigned Result = Match_Success;
5931 for (
auto Variant : getMatchedVariants()) {
5933 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5938 if (R == Match_Success || R == Match_MissingFeature ||
5939 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5940 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5941 Result != Match_MissingFeature)) {
5945 if (R == Match_Success)
5949 if (Result == Match_Success) {
5950 if (!validateInstruction(Inst, IDLoc, Operands)) {
5953 emitTargetDirective();
5960 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5961 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5967 case Match_MissingFeature:
5971 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5973 case Match_InvalidOperand: {
5974 SMLoc ErrorLoc = IDLoc;
5975 if (ErrorInfo != ~0ULL) {
5976 if (ErrorInfo >= Operands.
size()) {
5977 return Error(IDLoc,
"too few operands for instruction");
5979 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5980 if (ErrorLoc == SMLoc())
5984 return Error(ErrorLoc,
"invalid VOPDY instruction");
5986 return Error(ErrorLoc,
"invalid operand for instruction");
5989 case Match_MnemonicFail:
5995bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
6000 if (getParser().parseAbsoluteExpression(Tmp)) {
6003 Ret =
static_cast<uint32_t
>(Tmp);
6007bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
6008 if (!getSTI().getTargetTriple().isAMDGCN())
6009 return TokError(
"directive only supported for amdgcn architecture");
6011 std::string TargetIDDirective;
6012 SMLoc TargetStart = getTok().getLoc();
6013 if (getParser().parseEscapedString(TargetIDDirective))
6016 std::optional<AMDGPU::TargetID> MaybeParsed =
6019 return getParser().Error(TargetStart,
6020 "malformed target id '" + TargetIDDirective +
"'");
6023 const Triple &
TT = getSTI().getTargetTriple();
6029 return getParser().Error(
6030 TargetStart,
"target id '" + TargetIDDirective +
6031 "' specifies a processor that is not valid for "
6033 TT.getArchName() +
"'");
6036 const std::optional<AMDGPU::TargetID> &CurrentTargetID =
6037 getTargetStreamer().getTargetID();
6040 const Triple &STITriple = getSTI().getTargetTriple();
6041 if (!DirectiveTriple.isCompatibleWith(STITriple)) {
6042 return getParser().Error(
6043 TargetStart,
".amdgcn_target " + Twine(ParsedTargetID.
toString()) +
6044 " is incompatible with " +
6045 Twine(CurrentTargetID->toString()));
6049 StringRef DirectiveProcessor =
6053 if (DirectiveISA != CurrentISA) {
6054 return getParser().Error(TargetStart,
6055 ".amdgcn_target directive processor " +
6056 Twine(DirectiveProcessor) +
6057 " does not match the specified processor " +
6058 Twine(getSTI().
getCPU()));
6064 CurrentTargetID->getXnackSetting())) {
6066 ".amdgcn_target directive has conflicting xnack settings");
6070 CurrentTargetID->getSramEccSetting())) {
6072 ".amdgcn_target directive has conflicting sramecc settings");
6078 getTargetStreamer().getTargetID()->setXnackSetting(
6080 getTargetStreamer().getTargetID()->setSramEccSetting(
6086bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
6090bool AMDGPUAsmParser::calculateGPRBlocks(
6091 const FeatureBitset &Features,
const MCExpr *VCCUsed,
6092 const MCExpr *FlatScrUsed,
bool XNACKUsed,
6093 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
6094 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
6095 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
6101 const MCExpr *
NumSGPRs = NextFreeSGPR;
6102 int64_t EvaluatedSGPRs;
6109 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
6110 !Features.
test(FeatureSGPRInitBug) &&
6111 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
6112 return OutOfRangeError(SGPRRange);
6114 const MCExpr *ExtraSGPRs =
6118 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
6119 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
6120 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
6121 return OutOfRangeError(SGPRRange);
6123 if (Features.
test(FeatureSGPRInitBug))
6130 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
6131 unsigned Granule) ->
const MCExpr * {
6135 const MCExpr *AlignToGPR =
6137 const MCExpr *DivGPR =
6143 VGPRBlocks = GetNumGPRBlocks(
6152bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
6153 if (!getSTI().getTargetTriple().isAMDGCN())
6154 return TokError(
"directive only supported for amdgcn architecture");
6157 return TokError(
"directive only supported for amdhsa OS");
6159 StringRef KernelName;
6160 if (getParser().parseIdentifier(KernelName))
6167 AMDGPU::MCKernelDescriptor KD =
6179 const MCExpr *NextFreeVGPR = ZeroExpr;
6181 const MCExpr *NamedBarCnt = ZeroExpr;
6182 uint64_t SharedVGPRCount = 0;
6183 uint64_t PreloadLength = 0;
6184 uint64_t PreloadOffset = 0;
6186 const MCExpr *NextFreeSGPR = ZeroExpr;
6189 unsigned ImpliedUserSGPRCount = 0;
6193 std::optional<unsigned> ExplicitUserSGPRCount;
6194 const MCExpr *ReserveVCC = OneExpr;
6195 const MCExpr *ReserveFlatScr = OneExpr;
6196 std::optional<bool> EnableWavefrontSize32;
6202 SMRange IDRange = getTok().getLocRange();
6203 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6206 if (
ID ==
".end_amdhsa_kernel")
6210 return TokError(
".amdhsa_ directives cannot be repeated");
6212 SMLoc ValStart = getLoc();
6213 const MCExpr *ExprVal;
6214 if (getParser().parseExpression(ExprVal))
6216 SMLoc ValEnd = getLoc();
6217 SMRange ValRange = SMRange(ValStart, ValEnd);
6220 uint64_t Val = IVal;
6221 bool EvaluatableExpr;
6222 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6224 return OutOfRangeError(ValRange);
6228#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6229 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6230 return OutOfRangeError(RANGE); \
6231 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6236#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6238 return Error(IDRange.Start, "directive should have resolvable expression", \
6241 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6244 return OutOfRangeError(ValRange);
6246 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6249 return OutOfRangeError(ValRange);
6251 }
else if (
ID ==
".amdhsa_kernarg_size") {
6253 return OutOfRangeError(ValRange);
6255 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6257 ExplicitUserSGPRCount = Val;
6258 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6262 "directive is not supported with architected flat scratch",
6265 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6268 ImpliedUserSGPRCount += 4;
6269 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6272 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6275 return OutOfRangeError(ValRange);
6279 ImpliedUserSGPRCount += Val;
6280 PreloadLength = Val;
6282 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6285 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6288 return OutOfRangeError(ValRange);
6292 PreloadOffset = Val;
6293 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6296 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6299 ImpliedUserSGPRCount += 2;
6300 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6303 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6306 ImpliedUserSGPRCount += 2;
6307 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6310 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6313 ImpliedUserSGPRCount += 2;
6314 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6317 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6320 ImpliedUserSGPRCount += 2;
6321 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6324 "directive is not supported with architected flat scratch",
6328 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6331 ImpliedUserSGPRCount += 2;
6332 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6335 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6338 ImpliedUserSGPRCount += 1;
6339 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6341 if (IVersion.
Major < 10)
6342 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6343 EnableWavefrontSize32 = Val;
6345 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6347 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6349 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6351 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6354 "directive is not supported with architected flat scratch",
6357 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6359 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6363 "directive is not supported without architected flat scratch",
6366 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6368 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6370 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6372 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6374 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6376 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6378 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6380 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6382 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6384 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6386 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6388 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6389 VGPRRange = ValRange;
6390 NextFreeVGPR = ExprVal;
6391 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6392 SGPRRange = ValRange;
6393 NextFreeSGPR = ExprVal;
6394 }
else if (
ID ==
".amdhsa_accum_offset") {
6396 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6397 AccumOffset = ExprVal;
6398 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6400 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6401 NamedBarCnt = ExprVal;
6402 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6404 return OutOfRangeError(ValRange);
6405 ReserveVCC = ExprVal;
6406 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6407 if (IVersion.
Major < 7)
6408 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6411 "directive is not supported with architected flat scratch",
6414 return OutOfRangeError(ValRange);
6415 ReserveFlatScr = ExprVal;
6416 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6417 if (IVersion.
Major < 8)
6418 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6420 return OutOfRangeError(ValRange);
6421 bool XnackOn = getTargetStreamer().getTargetID()->isXnackOnOrAny() ||
6422 getSTI().hasFeature(AMDGPU::FeatureXNACK);
6423 if (Val != XnackOn) {
6424 return getParser().Error(
6426 ".amdhsa_reserve_xnack_mask does not match target id", IDRange);
6428 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6430 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6432 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6434 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6436 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6438 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6440 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6442 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6444 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6445 if (!getSTI().
hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6446 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6449 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6451 }
else if (
ID ==
".amdhsa_ieee_mode") {
6452 if (!getSTI().
hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6453 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6456 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6458 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6459 if (IVersion.
Major < 9)
6460 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6462 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6464 }
else if (
ID ==
".amdhsa_tg_split") {
6466 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6469 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6472 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6474 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6476 }
else if (
ID ==
".amdhsa_memory_ordered") {
6477 if (IVersion.
Major < 10)
6478 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6480 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6482 }
else if (
ID ==
".amdhsa_forward_progress") {
6483 if (IVersion.
Major < 10)
6484 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6486 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6488 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6490 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6491 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6493 SharedVGPRCount = Val;
6495 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6497 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6498 if (IVersion.
Major < 11)
6499 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6500 if (IVersion.
Major == 11) {
6502 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6506 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6509 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6512 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6514 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6516 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6518 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6521 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6523 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6525 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6527 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6529 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6531 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6533 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6535 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6537 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6539 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6540 if (IVersion.
Major < 12)
6541 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6543 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6546 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6549#undef PARSE_BITS_ENTRY
6552 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6553 return TokError(
".amdhsa_next_free_vgpr directive is required");
6555 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6556 return TokError(
".amdhsa_next_free_sgpr directive is required");
6558 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6560 return TokError(
"too many user SGPRs enabled, found " +
6561 Twine(UserSGPRCount) +
", but only " +
6567 if (PreloadLength) {
6573 const MCExpr *VGPRBlocks;
6574 const MCExpr *SGPRBlocks;
6575 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6576 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6577 EnableWavefrontSize32, NextFreeVGPR,
6578 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6582 int64_t EvaluatedVGPRBlocks;
6583 bool VGPRBlocksEvaluatable =
6584 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6585 if (VGPRBlocksEvaluatable &&
6587 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6588 return OutOfRangeError(VGPRRange);
6592 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6593 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6595 int64_t EvaluatedSGPRBlocks;
6596 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6598 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6599 return OutOfRangeError(SGPRRange);
6602 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6603 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6605 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6606 return TokError(
"amdgpu_user_sgpr_count smaller than implied by "
6607 "enabled user SGPRs");
6613 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6614 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6619 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6620 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6625 return TokError(
"Kernarg size should be resolvable");
6626 uint64_t kernarg_size = IVal;
6627 if (PreloadLength && kernarg_size &&
6628 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6629 return TokError(
"Kernarg preload length + offset is larger than the "
6630 "kernarg segment size");
6633 if (!Seen.
contains(
".amdhsa_accum_offset"))
6634 return TokError(
".amdhsa_accum_offset directive is required");
6635 int64_t EvaluatedAccum;
6636 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6637 uint64_t UEvaluatedAccum = EvaluatedAccum;
6638 if (AccumEvaluatable &&
6639 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6640 return TokError(
"accum_offset should be in range [4..256] in "
6643 int64_t EvaluatedNumVGPR;
6644 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6647 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6648 return TokError(
"accum_offset exceeds total VGPR allocation");
6654 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6655 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6661 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6662 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6665 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6667 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6668 return TokError(
"shared_vgpr_count directive not valid on "
6669 "wavefront size 32");
6672 if (VGPRBlocksEvaluatable &&
6673 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6675 return TokError(
"shared_vgpr_count*2 + "
6676 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6681 emitTargetDirective();
6682 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6683 NextFreeVGPR, NextFreeSGPR,
6684 ReserveVCC, ReserveFlatScr);
6688bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6690 if (ParseAsAbsoluteExpression(
Version))
6693 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6694 emitTargetDirective();
6698bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6699 AMDGPUMCKernelCodeT &
C) {
6702 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6703 Parser.eatToEndOfStatement();
6707 SmallString<40> ErrStr;
6708 raw_svector_ostream Err(ErrStr);
6709 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6710 return TokError(Err.
str());
6714 if (
ID ==
"enable_wavefront_size32") {
6717 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6719 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6722 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6726 if (
ID ==
"wavefront_size") {
6727 if (
C.wavefront_size == 5) {
6729 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6731 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6732 }
else if (
C.wavefront_size == 6) {
6734 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6741bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6742 AMDGPUMCKernelCodeT KernelCode;
6751 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6754 if (
ID ==
".end_amd_kernel_code_t")
6757 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6762 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6767bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6768 StringRef KernelName;
6769 if (!parseId(KernelName,
"expected symbol name"))
6772 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6779bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6780 if (!getSTI().getTargetTriple().isAMDGCN()) {
6781 return Error(getLoc(),
6782 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6786 StringRef TargetIDDirective = getLexer().getTok().getStringContents();
6788 std::optional<AMDGPU::TargetID> MaybeParsed =
6791 return Error(getParser().getTok().getLoc(),
6792 "malformed target id '" + TargetIDDirective +
"'");
6795 const Triple &
TT = getSTI().getTargetTriple();
6801 return Error(getParser().getTok().getLoc(),
6802 "target id '" + TargetIDDirective +
6803 "' specifies a processor that is not valid for subarch '" +
6804 TT.getArchName() +
"'");
6807 const std::optional<AMDGPU::TargetID> &CurrentTargetID =
6808 getTargetStreamer().getTargetID();
6811 const Triple &STITriple = getSTI().getTargetTriple();
6812 if (!DirectiveTriple.isCompatibleWith(STITriple)) {
6813 return Error(getParser().getTok().getLoc(),
6814 ".amd_amdgpu_isa " + Twine(ParsedTargetID.
toString()) +
6815 " is incompatible with " +
6816 Twine(CurrentTargetID->toString()));
6820 StringRef DirectiveProcessor =
6824 if (DirectiveISA != CurrentISA) {
6825 return Error(getParser().getTok().getLoc(),
6826 ".amd_amdgpu_isa directive processor " +
6827 Twine(DirectiveProcessor) +
6828 " does not match the specified processor " +
6829 Twine(getSTI().
getCPU()));
6832 getTargetStreamer().EmitISAVersion();
6838bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6841 std::string HSAMetadataString;
6846 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6847 return Error(getLoc(),
"invalid HSA metadata");
6854bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6855 const char *AssemblerDirectiveEnd,
6856 std::string &CollectString) {
6858 raw_string_ostream CollectStream(CollectString);
6860 getLexer().setSkipSpace(
false);
6862 bool FoundEnd =
false;
6865 CollectStream << getTokenStr();
6869 if (trySkipId(AssemblerDirectiveEnd)) {
6874 CollectStream << Parser.parseStringToEndOfStatement()
6875 <<
getContext().getAsmInfo().getSeparatorString();
6877 Parser.eatToEndOfStatement();
6880 getLexer().setSkipSpace(
true);
6883 return TokError(Twine(
"expected directive ") +
6884 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6891bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6897 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6898 if (!PALMetadata->setFromString(
String))
6899 return Error(getLoc(),
"invalid PAL metadata");
6904bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6906 return Error(getLoc(),
6908 "not available on non-amdpal OSes")).str());
6911 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6912 PALMetadata->setLegacy();
6915 if (ParseAsAbsoluteExpression(
Key)) {
6916 return TokError(Twine(
"invalid value in ") +
6920 return TokError(Twine(
"expected an even number of values in ") +
6923 if (ParseAsAbsoluteExpression(
Value)) {
6924 return TokError(Twine(
"invalid value in ") +
6927 PALMetadata->setRegister(
Key,
Value);
6936bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6937 if (getParser().checkForValidSection())
6941 SMLoc NameLoc = getLoc();
6942 if (getParser().parseIdentifier(Name))
6943 return TokError(
"expected identifier in directive");
6946 if (getParser().parseComma())
6952 SMLoc SizeLoc = getLoc();
6953 if (getParser().parseAbsoluteExpression(
Size))
6956 return Error(SizeLoc,
"size must be non-negative");
6957 if (
Size > LocalMemorySize)
6958 return Error(SizeLoc,
"size is too large");
6960 int64_t Alignment = 4;
6962 SMLoc AlignLoc = getLoc();
6963 if (getParser().parseAbsoluteExpression(Alignment))
6966 return Error(AlignLoc,
"alignment must be a power of two");
6971 if (Alignment >= 1u << 31)
6972 return Error(AlignLoc,
"alignment is too large");
6978 Symbol->redefineIfPossible();
6979 if (!
Symbol->isUndefined())
6980 return Error(NameLoc,
"invalid symbol redefinition");
6982 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6986bool AMDGPUAsmParser::ParseDirectiveAMDGPUInfo() {
6987 if (getParser().checkForValidSection())
6991 if (getParser().parseIdentifier(FuncName))
6992 return TokError(
"expected symbol name after .amdgpu_info");
6995 AMDGPU::InfoSectionData ParsedInfoData;
6996 AMDGPU::FuncInfo FI;
6998 bool HasScalarAttrs =
false;
7005 SMLoc IDLoc = getLoc();
7006 if (!parseId(
ID,
"expected directive or .end_amdgpu_info"))
7009 if (
ID ==
".end_amdgpu_info")
7017 return Error(IDLoc,
"unknown .amdgpu_info directive '" +
ID +
"'");
7019 if (Dir ==
"flags") {
7021 if (getParser().parseAbsoluteExpression(Val))
7024 FI.
UsesVCC = !!(
Flags & AMDGPU::FuncInfoFlags::FUNC_USES_VCC);
7026 !!(
Flags & AMDGPU::FuncInfoFlags::FUNC_USES_FLAT_SCRATCH);
7028 HasScalarAttrs =
true;
7029 }
else if (Dir ==
"num_sgpr") {
7031 if (getParser().parseAbsoluteExpression(Val))
7033 FI.
NumSGPR =
static_cast<uint32_t
>(Val);
7034 HasScalarAttrs =
true;
7035 }
else if (Dir ==
"num_vgpr") {
7037 if (getParser().parseAbsoluteExpression(Val))
7040 HasScalarAttrs =
true;
7041 }
else if (Dir ==
"num_agpr") {
7043 if (getParser().parseAbsoluteExpression(Val))
7046 HasScalarAttrs =
true;
7047 }
else if (Dir ==
"private_segment_size") {
7049 if (getParser().parseAbsoluteExpression(Val))
7052 HasScalarAttrs =
true;
7053 }
else if (Dir ==
"use") {
7055 if (getParser().parseIdentifier(ResName))
7056 return TokError(
"expected resource symbol for .amdgpu_use");
7057 ParsedInfoData.
Uses.push_back(
7058 {FuncSym,
getContext().getOrCreateSymbol(ResName)});
7059 }
else if (Dir ==
"call") {
7061 if (getParser().parseIdentifier(DstName))
7062 return TokError(
"expected callee symbol for .amdgpu_call");
7063 ParsedInfoData.
Calls.push_back(
7064 {FuncSym,
getContext().getOrCreateSymbol(DstName)});
7065 }
else if (Dir ==
"indirect_call") {
7067 if (getParser().parseEscapedString(TypeId))
7068 return TokError(
"expected type ID string for .amdgpu_indirect_call");
7069 ParsedInfoData.
IndirectCalls.push_back({FuncSym, std::move(TypeId)});
7070 }
else if (Dir ==
"typeid") {
7072 if (getParser().parseEscapedString(TypeId))
7073 return TokError(
"expected type ID string for .amdgpu_typeid");
7074 ParsedInfoData.
TypeIds.push_back({FuncSym, std::move(TypeId)});
7076 return Error(IDLoc,
"unknown .amdgpu_info directive '" +
ID +
"'");
7081 ParsedInfoData.
Funcs.push_back(std::move(FI));
7083 AMDGPU::InfoSectionData &
Data = InfoData ? *InfoData : InfoData.emplace();
7084 for (AMDGPU::FuncInfo &Func : ParsedInfoData.
Funcs)
7085 Data.Funcs.push_back(std::move(Func));
7086 for (std::pair<MCSymbol *, MCSymbol *> &Use : ParsedInfoData.
Uses)
7087 Data.Uses.push_back(Use);
7088 for (std::pair<MCSymbol *, MCSymbol *> &
Call : ParsedInfoData.
Calls)
7090 for (std::pair<MCSymbol *, std::string> &
IndirectCall :
7093 for (std::pair<MCSymbol *, std::string> &TypeId : ParsedInfoData.
TypeIds)
7094 Data.TypeIds.push_back(std::move(TypeId));
7099void AMDGPUAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
7106void AMDGPUAsmParser::checkKernelPrologues() {
7107 if (getFeatureBits()[AMDGPU::FeatureRequiresInitialUnclausedVmem]) {
7108 static const unsigned Required[] = {GLOBAL_WB_gfx12, V_NOP_e32_gfx12};
7109 for (
auto [Sym, Loc,
Offset] : OpcodeStreamSymbols) {
7110 if (!AMDHSAKernelSymbols.
contains(Sym))
7112 ArrayRef<unsigned> Prologue =
ArrayRef(OpcodeStream).drop_front(
Offset);
7115 "' does not begin with the required prologue "
7116 "sequence: GLOBAL_WB followed by V_NOP");
7120 OpcodeStream.
clear();
7121 OpcodeStreamSymbols.clear();
7122 AMDHSAKernelSymbols.
clear();
7125void AMDGPUAsmParser::onEndOfFile() {
7126 emitTargetDirective();
7127 checkKernelPrologues();
7129 getTargetStreamer().emitAMDGPUInfo(*InfoData);
7132bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
7133 StringRef IDVal = DirectiveID.
getString();
7136 if (IDVal ==
".amdhsa_kernel")
7137 return ParseDirectiveAMDHSAKernel();
7139 if (IDVal ==
".amdhsa_code_object_version")
7140 return ParseDirectiveAMDHSACodeObjectVersion();
7144 return ParseDirectiveHSAMetadata();
7146 if (IDVal ==
".amd_kernel_code_t")
7147 return ParseDirectiveAMDKernelCodeT();
7149 if (IDVal ==
".amdgpu_hsa_kernel")
7150 return ParseDirectiveAMDGPUHsaKernel();
7152 if (IDVal ==
".amd_amdgpu_isa")
7153 return ParseDirectiveISAVersion();
7157 Twine(
" directive is "
7158 "not available on non-amdhsa OSes"))
7163 if (IDVal ==
".amdgcn_target")
7164 return ParseDirectiveAMDGCNTarget();
7166 if (IDVal ==
".amdgpu_lds")
7167 return ParseDirectiveAMDGPULDS();
7169 if (IDVal ==
".amdgpu_info")
7170 return ParseDirectiveAMDGPUInfo();
7173 return ParseDirectivePALMetadataBegin();
7176 return ParseDirectivePALMetadata();
7181bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &MRI,
7188 return hasSGPR104_SGPR105();
7191 case SRC_SHARED_BASE_LO:
7192 case SRC_SHARED_BASE:
7193 case SRC_SHARED_LIMIT_LO:
7194 case SRC_SHARED_LIMIT:
7195 case SRC_PRIVATE_BASE_LO:
7196 case SRC_PRIVATE_BASE:
7197 case SRC_PRIVATE_LIMIT_LO:
7198 case SRC_PRIVATE_LIMIT:
7200 case SRC_FLAT_SCRATCH_BASE_LO:
7201 case SRC_FLAT_SCRATCH_BASE_HI:
7202 return hasGloballyAddressableScratch();
7203 case SRC_POPS_EXITING_WAVE_ID:
7215 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
7245 return hasSGPR102_SGPR103();
7250ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
7253 ParseStatus Res = parseVOPD(Operands);
7258 Res = MatchOperandParserImpl(Operands, Mnemonic);
7270 SMLoc LBraceLoc = getLoc();
7275 auto Loc = getLoc();
7276 Res = parseReg(Operands);
7278 Error(Loc,
"expected a register");
7282 RBraceLoc = getLoc();
7287 "expected a comma or a closing square bracket"))
7291 if (Operands.
size() - Prefix > 1) {
7293 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
7294 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
7300 return parseRegOrImm(Operands);
7303StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
7305 setForcedEncodingSize(0);
7306 setForcedDPP(
false);
7307 setForcedSDWA(
false);
7309 if (
Name.consume_back(
"_e64_dpp")) {
7311 setForcedEncodingSize(64);
7314 if (
Name.consume_back(
"_e64")) {
7315 setForcedEncodingSize(64);
7318 if (
Name.consume_back(
"_e32")) {
7319 setForcedEncodingSize(32);
7322 if (
Name.consume_back(
"_dpp")) {
7326 if (
Name.consume_back(
"_sdwa")) {
7327 setForcedSDWA(
true);
7335 unsigned VariantID);
7341 Name = parseMnemonicSuffix(Name);
7347 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
7349 bool IsMIMG = Name.starts_with(
"image_");
7352 OperandMode
Mode = OperandMode_Default;
7354 Mode = OperandMode_NSA;
7358 checkUnsupportedInstruction(Name, NameLoc);
7359 if (!Parser.hasPendingError()) {
7362 :
"not a valid operand.";
7382ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
7385 if (!trySkipId(Name))
7388 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
7392ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7401ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7402 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7403 std::function<
bool(int64_t &)> ConvertResult) {
7407 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7411 if (ConvertResult && !ConvertResult(
Value)) {
7412 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7415 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7419ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7420 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
7421 bool (*ConvertResult)(int64_t &)) {
7430 const unsigned MaxSize = 4;
7434 for (
int I = 0; ; ++
I) {
7436 SMLoc Loc = getLoc();
7440 if (
Op != 0 &&
Op != 1)
7441 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7448 if (
I + 1 == MaxSize)
7449 return Error(getLoc(),
"expected a closing square bracket");
7455 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7459ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7461 AMDGPUOperand::ImmTy ImmTy,
7462 bool IgnoreNegative) {
7466 if (trySkipId(Name)) {
7468 }
else if (trySkipId(
"no", Name)) {
7477 return Error(S,
"r128 modifier is not supported on this GPU");
7478 if (Name ==
"a16" && !
hasA16())
7479 return Error(S,
"a16 modifier is not supported on this GPU");
7481 if (Bit == 0 && Name ==
"gds") {
7482 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7484 return Error(S,
"nogds is not allowed");
7487 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7488 ImmTy = AMDGPUOperand::ImmTyR128A16;
7490 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7494unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7495 bool &Disabling)
const {
7496 Disabling =
Id.consume_front(
"no");
7499 return StringSwitch<unsigned>(Id)
7506 return StringSwitch<unsigned>(Id)
7514ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7516 SMLoc StringLoc = getLoc();
7518 int64_t CPolVal = 0;
7527 ResTH = parseTH(Operands, TH);
7538 ResScope = parseScope(Operands, Scope);
7551 if (trySkipId(
"nv")) {
7555 }
else if (trySkipId(
"no",
"nv")) {
7562 if (trySkipId(
"scale_offset")) {
7566 }
else if (trySkipId(
"no",
"scale_offset")) {
7579 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7580 AMDGPUOperand::ImmTyCPol));
7584 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7585 SMLoc OpLoc = getLoc();
7586 unsigned Enabled = 0, Seen = 0;
7590 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7597 return Error(S,
"dlc modifier is not supported on this GPU");
7600 return Error(S,
"scc modifier is not supported on this GPU");
7603 return Error(S,
"duplicate cache policy modifier");
7615 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7619ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7624 ParseStatus Res = parseStringOrIntWithPrefix(
7625 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7634ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7639 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7643 if (
Value ==
"TH_DEFAULT")
7645 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7646 Value ==
"TH_LOAD_NT_WB") {
7647 return Error(StringLoc,
"invalid th value");
7648 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7650 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7652 }
else if (
Value.consume_front(
"TH_STORE_")) {
7655 return Error(StringLoc,
"invalid th value");
7658 if (
Value ==
"BYPASS")
7663 TH |= StringSwitch<int64_t>(
Value)
7673 .Default(0xffffffff);
7675 TH |= StringSwitch<int64_t>(
Value)
7686 .Default(0xffffffff);
7689 if (TH == 0xffffffff)
7690 return Error(StringLoc,
"invalid th value");
7697 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7698 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7699 std::optional<unsigned> InsertAt = std::nullopt) {
7700 auto i = OptionalIdx.find(ImmT);
7701 if (i != OptionalIdx.end()) {
7702 unsigned Idx = i->second;
7703 const AMDGPUOperand &
Op =
7704 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7708 Op.addImmOperands(Inst, 1);
7710 if (InsertAt.has_value())
7717ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7723 StringLoc = getLoc();
7728ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7729 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7734 SMLoc StringLoc = getLoc();
7738 Value = getTokenStr();
7742 if (
Value == Ids[IntVal])
7747 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7748 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7753ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7754 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7755 AMDGPUOperand::ImmTy
Type) {
7759 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7761 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7770bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7774 SMLoc Loc = getLoc();
7776 auto Res = parseIntWithPrefix(Pref, Val);
7782 if (Val < 0 || Val > MaxVal) {
7783 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7791ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7792 AMDGPUOperand::ImmTy ImmTy) {
7793 const char *Pref =
"index_key";
7795 SMLoc Loc = getLoc();
7796 auto Res = parseIntWithPrefix(Pref, ImmVal);
7800 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7801 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7802 (ImmVal < 0 || ImmVal > 1))
7803 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7805 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7806 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7808 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7812ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7813 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7816ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7817 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7820ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7821 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7824ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7826 AMDGPUOperand::ImmTy
Type) {
7831ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7832 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7833 AMDGPUOperand::ImmTyMatrixAFMT);
7836ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7837 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7838 AMDGPUOperand::ImmTyMatrixBFMT);
7841ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7843 AMDGPUOperand::ImmTy
Type) {
7848ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7849 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7850 AMDGPUOperand::ImmTyMatrixAScale);
7853ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7854 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7855 AMDGPUOperand::ImmTyMatrixBScale);
7858ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7860 AMDGPUOperand::ImmTy
Type) {
7865ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7866 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7867 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7870ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7871 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7872 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7877ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7878 using namespace llvm::AMDGPU::MTBUFFormat;
7884 for (
int I = 0;
I < 2; ++
I) {
7885 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7888 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7893 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7899 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7902 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7903 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7909ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7910 using namespace llvm::AMDGPU::MTBUFFormat;
7914 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7917 if (Fmt == UFMT_UNDEF)
7924bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7926 StringRef FormatStr,
7928 using namespace llvm::AMDGPU::MTBUFFormat;
7932 if (
Format != DFMT_UNDEF) {
7938 if (
Format != NFMT_UNDEF) {
7943 Error(Loc,
"unsupported format");
7947ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7950 using namespace llvm::AMDGPU::MTBUFFormat;
7954 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7959 SMLoc Loc = getLoc();
7960 if (!parseId(Str,
"expected a format string") ||
7961 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7963 if (Dfmt == DFMT_UNDEF)
7964 return Error(Loc,
"duplicate numeric format");
7965 if (Nfmt == NFMT_UNDEF)
7966 return Error(Loc,
"duplicate data format");
7969 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7970 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7974 if (Ufmt == UFMT_UNDEF)
7975 return Error(FormatLoc,
"unsupported format");
7984ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7987 using namespace llvm::AMDGPU::MTBUFFormat;
7990 if (Id == UFMT_UNDEF)
7994 return Error(Loc,
"unified format is not supported on this GPU");
8000ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
8001 using namespace llvm::AMDGPU::MTBUFFormat;
8002 SMLoc Loc = getLoc();
8007 return Error(Loc,
"out of range format");
8012ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
8013 using namespace llvm::AMDGPU::MTBUFFormat;
8019 StringRef FormatStr;
8020 SMLoc Loc = getLoc();
8021 if (!parseId(FormatStr,
"expected a format string"))
8024 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
8026 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
8036 return parseNumericFormat(
Format);
8039ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
8040 using namespace llvm::AMDGPU::MTBUFFormat;
8044 SMLoc Loc = getLoc();
8054 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
8066 Res = parseRegOrImm(Operands);
8073 Res = parseSymbolicOrNumericFormat(
Format);
8078 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
8079 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
8086 return Error(getLoc(),
"duplicate format");
8090ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
8092 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
8094 Res = parseIntWithPrefix(
"inst_offset", Operands,
8095 AMDGPUOperand::ImmTyInstOffset);
8100ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
8102 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
8104 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
8108ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
8110 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
8113 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
8122void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
8123 OptionalImmIndexMap OptionalIdx;
8125 unsigned OperandIdx[4];
8126 unsigned EnMask = 0;
8129 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
8130 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8135 OperandIdx[SrcIdx] = Inst.
size();
8136 Op.addRegOperands(Inst, 1);
8143 OperandIdx[SrcIdx] = Inst.
size();
8149 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
8150 Op.addImmOperands(Inst, 1);
8154 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
8158 OptionalIdx[
Op.getImmTy()] = i;
8164 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
8171 for (
auto i = 0; i < SrcIdx; ++i) {
8173 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
8198 IntVal =
encode(ISA, IntVal, CntVal);
8199 if (CntVal !=
decode(ISA, IntVal)) {
8201 IntVal =
encode(ISA, IntVal, -1);
8209bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
8211 SMLoc CntLoc = getLoc();
8212 StringRef CntName = getTokenStr();
8219 SMLoc ValLoc = getLoc();
8228 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
8230 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
8232 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
8235 Error(CntLoc,
"invalid counter name " + CntName);
8240 Error(ValLoc,
"too large value for " + CntName);
8249 Error(getLoc(),
"expected a counter name");
8257ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
8264 if (!parseCnt(Waitcnt))
8272 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
8276bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
8277 SMLoc FieldLoc = getLoc();
8278 StringRef FieldName = getTokenStr();
8283 SMLoc ValueLoc = getLoc();
8290 if (FieldName ==
"instid0") {
8292 }
else if (FieldName ==
"instskip") {
8294 }
else if (FieldName ==
"instid1") {
8297 Error(FieldLoc,
"invalid field name " + FieldName);
8316 .Case(
"VALU_DEP_1", 1)
8317 .Case(
"VALU_DEP_2", 2)
8318 .Case(
"VALU_DEP_3", 3)
8319 .Case(
"VALU_DEP_4", 4)
8320 .Case(
"TRANS32_DEP_1", 5)
8321 .Case(
"TRANS32_DEP_2", 6)
8322 .Case(
"TRANS32_DEP_3", 7)
8323 .Case(
"FMA_ACCUM_CYCLE_1", 8)
8324 .Case(
"SALU_CYCLE_1", 9)
8325 .Case(
"SALU_CYCLE_2", 10)
8326 .Case(
"SALU_CYCLE_3", 11)
8334 Delay |=
Value << Shift;
8338ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
8344 if (!parseDelay(Delay))
8352 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
8357AMDGPUOperand::isSWaitCnt()
const {
8361bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
8367void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
8368 StringRef DepCtrName) {
8371 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
8374 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
8377 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
8380 Error(Loc, Twine(
"invalid value for ", DepCtrName));
8387bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
8389 using namespace llvm::AMDGPU::DepCtr;
8391 SMLoc DepCtrLoc = getLoc();
8392 StringRef DepCtrName = getTokenStr();
8402 unsigned PrevOprMask = UsedOprMask;
8403 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8406 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8415 Error(getLoc(),
"expected a counter name");
8420 int64_t CntValMask = PrevOprMask ^ UsedOprMask;
8421 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8425ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
8426 using namespace llvm::AMDGPU::DepCtr;
8429 SMLoc Loc = getLoc();
8432 unsigned UsedOprMask = 0;
8434 if (!parseDepCtr(DepCtr, UsedOprMask))
8442 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8446bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8452ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8454 OperandInfoTy &Width) {
8455 using namespace llvm::AMDGPU::Hwreg;
8461 HwReg.Loc = getLoc();
8464 HwReg.IsSymbolic =
true;
8466 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8474 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8484 Width.Loc = getLoc();
8492ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8493 using namespace llvm::AMDGPU::Hwreg;
8496 SMLoc Loc = getLoc();
8498 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8500 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8501 HwregOffset::Default);
8502 struct : StructuredOpField {
8503 using StructuredOpField::StructuredOpField;
8504 bool validate(AMDGPUAsmParser &Parser)
const override {
8506 return Error(Parser,
"only values from 1 to 32 are legal");
8509 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8510 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8513 Res = parseHwregFunc(HwReg,
Offset, Width);
8516 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8518 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8522 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8529 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8531 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8535bool AMDGPUOperand::isHwreg()
const {
8536 return isImmTy(ImmTyHwreg);
8544AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &
Msg,
8546 OperandInfoTy &Stream) {
8547 using namespace llvm::AMDGPU::SendMsg;
8552 Msg.IsSymbolic =
true;
8559 Op.IsDefined =
true;
8565 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8570 Stream.IsDefined =
true;
8571 Stream.Loc = getLoc();
8581AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &
Msg,
8582 const OperandInfoTy &
Op,
8583 const OperandInfoTy &Stream) {
8584 using namespace llvm::AMDGPU::SendMsg;
8593 Error(
Msg.Loc,
"specified message id is not supported on this GPU");
8598 Error(
Msg.Loc,
"invalid message id");
8604 Error(
Op.Loc,
"message does not support operations");
8606 Error(
Msg.Loc,
"missing message operation");
8612 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8614 Error(
Op.Loc,
"invalid operation id");
8619 Error(Stream.Loc,
"message operation does not support streams");
8623 Error(Stream.Loc,
"invalid message stream id");
8629ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8630 using namespace llvm::AMDGPU::SendMsg;
8633 SMLoc Loc = getLoc();
8637 OperandInfoTy
Op(OP_NONE_);
8638 OperandInfoTy Stream(STREAM_ID_NONE_);
8639 if (parseSendMsgBody(
Msg,
Op, Stream) &&
8640 validateSendMsg(
Msg,
Op, Stream)) {
8645 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8647 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8652 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8656bool AMDGPUOperand::isSendMsg()
const {
8657 return isImmTy(ImmTySendMsg);
8660ParseStatus AMDGPUAsmParser::parseWaitEvent(
OperandVector &Operands) {
8661 using namespace llvm::AMDGPU::WaitEvent;
8663 SMLoc Loc = getLoc();
8666 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8668 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8670 StructuredOpField *TargetBitfield =
8671 isGFX11() ? &DontWaitExportReady : &ExportReady;
8673 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8677 if (!validateStructuredOpFields({TargetBitfield}))
8679 ImmVal = TargetBitfield->Val;
8686 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8688 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8689 AMDGPUOperand::ImmTyWaitEvent));
8693bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8699ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8706 int Slot = StringSwitch<int>(Str)
8713 return Error(S,
"invalid interpolation slot");
8715 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8716 AMDGPUOperand::ImmTyInterpSlot));
8720ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8727 if (!Str.starts_with(
"attr"))
8728 return Error(S,
"invalid interpolation attribute");
8730 StringRef Chan = Str.take_back(2);
8731 int AttrChan = StringSwitch<int>(Chan)
8738 return Error(S,
"invalid or missing interpolation attribute channel");
8740 Str = Str.drop_back(2).drop_front(4);
8743 if (Str.getAsInteger(10, Attr))
8744 return Error(S,
"invalid or missing interpolation attribute number");
8747 return Error(S,
"out of bounds interpolation attribute number");
8751 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8752 AMDGPUOperand::ImmTyInterpAttr));
8753 Operands.
push_back(AMDGPUOperand::CreateImm(
8754 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8762ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8763 using namespace llvm::AMDGPU::Exp;
8773 return Error(S, (Id == ET_INVALID)
8774 ?
"invalid exp target"
8775 :
"exp target is not supported on this GPU");
8777 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8778 AMDGPUOperand::ImmTyExpTgt));
8787AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8792AMDGPUAsmParser::isId(
const StringRef Id)
const {
8798 return getTokenKind() ==
Kind;
8801StringRef AMDGPUAsmParser::getId()
const {
8806AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8815AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8817 StringRef Tok = getTokenStr();
8828 if (isId(Id) && peekToken().is(Kind)) {
8838 if (isToken(Kind)) {
8847 const StringRef ErrMsg) {
8848 if (!trySkipToken(Kind)) {
8849 Error(getLoc(), ErrMsg);
8856AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8860 if (Parser.parseExpression(Expr))
8863 if (Expr->evaluateAsAbsolute(
Imm))
8866 if (Expected.empty()) {
8867 Error(S,
"expected absolute expression");
8869 Error(S, Twine(
"expected ", Expected) +
8870 Twine(
" or an absolute expression"));
8880 if (Parser.parseExpression(Expr))
8884 if (Expr->evaluateAsAbsolute(IntVal)) {
8885 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8887 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8893AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8895 Val =
getToken().getStringContents();
8899 Error(getLoc(), ErrMsg);
8904AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8906 Val = getTokenStr();
8910 if (!ErrMsg.
empty())
8911 Error(getLoc(), ErrMsg);
8916AMDGPUAsmParser::getToken()
const {
8917 return Parser.getTok();
8920AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8923 : getLexer().peekTok(ShouldSkipSpace);
8928 auto TokCount = getLexer().peekTokens(Tokens);
8930 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8935AMDGPUAsmParser::getTokenKind()
const {
8936 return getLexer().getKind();
8940AMDGPUAsmParser::getLoc()
const {
8945AMDGPUAsmParser::getTokenStr()
const {
8950AMDGPUAsmParser::lex() {
8954const AMDGPUOperand &
8955AMDGPUAsmParser::findMCOperand(
const OperandVector &Operands,
8956 int MCOpIdx)
const {
8957 for (
const auto &
Op : Operands) {
8958 const AMDGPUOperand &TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8959 if (TargetOp.getMCOpIdx() == MCOpIdx)
8965SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8966 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8970SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8974SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8975 int MCOpIdx)
const {
8976 return findMCOperand(Operands, MCOpIdx).getStartLoc();
8980AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8982 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8983 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8985 return Op.getStartLoc();
8987 return getInstLoc(Operands);
8991AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8993 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8994 return getOperandLoc(
Test, Operands);
9008 StringRef
Id = getTokenStr();
9009 SMLoc IdLoc = getLoc();
9015 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
9016 if (
I == Fields.
end())
9017 return Error(IdLoc,
"unknown field");
9018 if ((*I)->IsDefined)
9019 return Error(IdLoc,
"duplicate field");
9022 (*I)->Loc = getLoc();
9025 (*I)->IsDefined =
true;
9032bool AMDGPUAsmParser::validateStructuredOpFields(
9034 return all_of(Fields, [
this](
const StructuredOpField *
F) {
9035 return F->validate(*
this);
9046 const unsigned OrMask,
9047 const unsigned XorMask) {
9056bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
9057 const unsigned MaxVal,
9058 const Twine &ErrMsg, SMLoc &Loc) {
9075AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
9076 const unsigned MinVal,
9077 const unsigned MaxVal,
9078 const StringRef ErrMsg) {
9080 for (
unsigned i = 0; i < OpNum; ++i) {
9081 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
9089AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
9090 using namespace llvm::AMDGPU::Swizzle;
9093 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
9094 "expected a 2-bit lane id")) {
9105AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
9106 using namespace llvm::AMDGPU::Swizzle;
9112 if (!parseSwizzleOperand(GroupSize,
9114 "group size must be in the interval [2,32]",
9119 Error(Loc,
"group size must be a power of two");
9122 if (parseSwizzleOperand(LaneIdx,
9124 "lane id must be in the interval [0,group size - 1]",
9133AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
9134 using namespace llvm::AMDGPU::Swizzle;
9139 if (!parseSwizzleOperand(GroupSize,
9141 "group size must be in the interval [2,32]",
9146 Error(Loc,
"group size must be a power of two");
9155AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
9156 using namespace llvm::AMDGPU::Swizzle;
9161 if (!parseSwizzleOperand(GroupSize,
9163 "group size must be in the interval [1,16]",
9168 Error(Loc,
"group size must be a power of two");
9177AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
9178 using namespace llvm::AMDGPU::Swizzle;
9185 SMLoc StrLoc = getLoc();
9186 if (!parseString(Ctl)) {
9189 if (Ctl.
size() != BITMASK_WIDTH) {
9190 Error(StrLoc,
"expected a 5-character mask");
9194 unsigned AndMask = 0;
9195 unsigned OrMask = 0;
9196 unsigned XorMask = 0;
9198 for (
size_t i = 0; i < Ctl.
size(); ++i) {
9202 Error(StrLoc,
"invalid mask");
9223bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
9224 using namespace llvm::AMDGPU::Swizzle;
9227 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
9233 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
9234 "FFT swizzle must be in the interval [0," +
9235 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
9243bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
9244 using namespace llvm::AMDGPU::Swizzle;
9247 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
9254 if (!parseSwizzleOperand(
Direction, 0, 1,
9255 "direction must be 0 (left) or 1 (right)", Loc))
9259 if (!parseSwizzleOperand(
9260 RotateSize, 0, ROTATE_MAX_SIZE,
9261 "number of threads to rotate must be in the interval [0," +
9262 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
9267 (RotateSize << ROTATE_SIZE_SHIFT);
9272AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
9274 SMLoc OffsetLoc = getLoc();
9280 Error(OffsetLoc,
"expected a 16-bit offset");
9287AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
9288 using namespace llvm::AMDGPU::Swizzle;
9292 SMLoc ModeLoc = getLoc();
9295 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
9296 Ok = parseSwizzleQuadPerm(
Imm);
9297 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
9298 Ok = parseSwizzleBitmaskPerm(
Imm);
9299 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
9300 Ok = parseSwizzleBroadcast(
Imm);
9301 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
9302 Ok = parseSwizzleSwap(
Imm);
9303 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
9304 Ok = parseSwizzleReverse(
Imm);
9305 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
9306 Ok = parseSwizzleFFT(
Imm);
9307 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
9308 Ok = parseSwizzleRotate(
Imm);
9310 Error(ModeLoc,
"expected a swizzle mode");
9313 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
9319ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
9323 if (trySkipId(
"offset")) {
9327 if (trySkipId(
"swizzle")) {
9328 Ok = parseSwizzleMacro(
Imm);
9330 Ok = parseSwizzleOffset(
Imm);
9334 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
9342AMDGPUOperand::isSwizzle()
const {
9343 return isImmTy(ImmTySwizzle);
9350int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
9352 using namespace llvm::AMDGPU::VGPRIndexMode;
9364 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
9365 if (trySkipId(IdSymbolic[ModeId])) {
9373 "expected a VGPR index mode or a closing parenthesis" :
9374 "expected a VGPR index mode");
9379 Error(S,
"duplicate VGPR index mode");
9387 "expected a comma or a closing parenthesis"))
9394ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
9396 using namespace llvm::AMDGPU::VGPRIndexMode;
9402 Imm = parseGPRIdxMacro();
9406 if (getParser().parseAbsoluteExpression(
Imm))
9409 return Error(S,
"invalid immediate: only 4-bit values are legal");
9413 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9417bool AMDGPUOperand::isGPRIdxMode()
const {
9418 return isImmTy(ImmTyGprIdxMode);
9425ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
9430 if (isRegister() || isModifier())
9436 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
9437 assert(Opr.isImm() || Opr.isExpr());
9438 SMLoc Loc = Opr.getStartLoc();
9442 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9443 Error(Loc,
"expected an absolute expression or a label");
9444 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9445 Error(Loc,
"expected a 16-bit signed jump offset");
9455ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
9456 return parseReg(Operands);
9463void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
9466 OptionalImmIndexMap OptionalIdx;
9467 unsigned FirstOperandIdx = 1;
9468 bool IsAtomicReturn =
false;
9475 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9476 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9480 Op.addRegOperands(Inst, 1);
9484 if (IsAtomicReturn && i == FirstOperandIdx)
9485 Op.addRegOperands(Inst, 1);
9490 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9491 Op.addImmOperands(Inst, 1);
9503 OptionalIdx[
Op.getImmTy()] = i;
9517bool AMDGPUOperand::isSMRDOffset8()
const {
9521bool AMDGPUOperand::isSMEMOffset()
const {
9523 return isImmLiteral();
9526bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9561bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9562 if (BoundCtrl == 0 || BoundCtrl == 1) {
9570void AMDGPUAsmParser::onBeginOfFile() {
9571 if (!getParser().getStreamer().getTargetStreamer())
9574 if (!getTargetStreamer().getTargetID())
9575 getTargetStreamer().initializeTargetID(getSTI(),
9579void AMDGPUAsmParser::emitTargetDirective() {
9580 if (TargetDirectiveEmitted)
9582 TargetDirectiveEmitted =
true;
9584 if (!getParser().getStreamer().getTargetStreamer() ||
9589 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9598bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9602 StringRef TokenId = getTokenStr();
9603 AGVK VK = StringSwitch<AGVK>(TokenId)
9604 .Case(
"max", AGVK::AGVK_Max)
9605 .Case(
"min", AGVK::AGVK_Min)
9606 .Case(
"or", AGVK::AGVK_Or)
9607 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9608 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9609 .Case(
"alignto", AGVK::AGVK_AlignTo)
9610 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9611 .Case(
"instprefsize", AGVK::AGVK_InstPrefSize)
9612 .Default(AGVK::AGVK_None);
9616 uint64_t CommaCount = 0;
9621 if (Exprs.
empty()) {
9623 "empty " + Twine(TokenId) +
" expression");
9626 if (CommaCount + 1 != Exprs.
size()) {
9628 "mismatch of commas in " + Twine(TokenId) +
" expression");
9632 Expected && Exprs.
size() != Expected) {
9633 Error(
getToken().getLoc(), Twine(TokenId) +
" expression expects " +
9634 Twine(Expected) +
" operands");
9641 if (getParser().parseExpression(Expr, EndLoc))
9645 if (LastTokenWasComma)
9649 "unexpected token in " + Twine(TokenId) +
" expression");
9655 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9658ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9659 StringRef
Name = getTokenStr();
9660 if (Name ==
"mul") {
9661 return parseIntWithPrefix(
"mul", Operands,
9665 if (Name ==
"div") {
9666 return parseIntWithPrefix(
"div", Operands,
9677 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9682 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9683 AMDGPU::OpName::src2};
9691 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9696 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9698 if (
DstOp.isReg() &&
9703 if ((OpSel & (1 << SrcNum)) != 0)
9709void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9711 cvtVOP3P(Inst, Operands);
9715void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9716 OptionalImmIndexMap &OptionalIdx) {
9717 cvtVOP3P(Inst, Operands, OptionalIdx);
9726 &&
Desc.NumOperands > (OpNum + 1)
9728 &&
Desc.operands()[OpNum + 1].RegClass != -1
9730 &&
Desc.getOperandConstraint(OpNum + 1,
9734void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9736 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9737 AMDGPU::OpName::src2};
9738 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9739 AMDGPU::OpName::src1_modifiers,
9740 AMDGPU::OpName::src2_modifiers};
9741 for (
int J = 0; J < 3; ++J) {
9742 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9748 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9751 if ((OpSel & (1 << J)) != 0)
9754 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9761void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9763 OptionalImmIndexMap OptionalIdx;
9768 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9769 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9772 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9773 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9775 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9776 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9777 Op.isInterpAttrChan()) {
9779 }
else if (
Op.isImmModifier()) {
9780 OptionalIdx[
Op.getImmTy()] =
I;
9788 AMDGPUOperand::ImmTyHigh);
9792 AMDGPUOperand::ImmTyClamp);
9796 AMDGPUOperand::ImmTyOModSI);
9801 AMDGPUOperand::ImmTyOpSel);
9802 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9805 cvtOpSelHelper(Inst, OpSel);
9809void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9811 OptionalImmIndexMap OptionalIdx;
9816 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9817 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9820 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9821 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9823 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9824 }
else if (
Op.isImmModifier()) {
9825 OptionalIdx[
Op.getImmTy()] =
I;
9833 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9843 cvtOpSelHelper(Inst, OpSel);
9846void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9848 OptionalImmIndexMap OptionalIdx;
9851 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9855 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9856 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9858 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9859 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9864 if (NumOperands == CbszOpIdx) {
9869 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9870 }
else if (
Op.isImmModifier()) {
9871 OptionalIdx[
Op.getImmTy()] =
I;
9873 Op.addRegOrImmOperands(Inst, 1);
9878 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9879 if (CbszIdx != OptionalIdx.end()) {
9880 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9884 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9885 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9886 if (BlgpIdx != OptionalIdx.end()) {
9887 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9898 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9899 if (OpselIdx != OptionalIdx.end()) {
9900 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9904 unsigned OpSelHi = 0;
9905 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9906 if (OpselHiIdx != OptionalIdx.end()) {
9907 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9910 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9911 AMDGPU::OpName::src1_modifiers};
9913 for (
unsigned J = 0; J < 2; ++J) {
9914 unsigned ModVal = 0;
9915 if (OpSel & (1 << J))
9917 if (OpSelHi & (1 << J))
9920 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9925void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9926 OptionalImmIndexMap &OptionalIdx) {
9931 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9932 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9935 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9936 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9938 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9939 }
else if (
Op.isImmModifier()) {
9940 OptionalIdx[
Op.getImmTy()] =
I;
9942 Op.addRegOrImmOperands(Inst, 1);
9948 AMDGPUOperand::ImmTyScaleSel);
9952 AMDGPUOperand::ImmTyClamp);
9958 AMDGPUOperand::ImmTyByteSel);
9963 AMDGPUOperand::ImmTyOModSI);
9970 auto *it = Inst.
begin();
9971 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9979void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9980 OptionalImmIndexMap OptionalIdx;
9981 cvtVOP3(Inst, Operands, OptionalIdx);
9984void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9985 OptionalImmIndexMap &OptIdx) {
9991 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9992 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9993 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9994 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9995 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9996 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9997 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9998 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12 ||
9999 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx13 ||
10000 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx13) {
10009 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10010 if (VdstInIdx != -1 && VdstInIdx ==
static_cast<int>(Inst.
getNumOperands()))
10013 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
10014 if (BitOp3Idx != -1) {
10021 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
10022 if (OpSelIdx != -1) {
10026 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
10027 if (OpSelHiIdx != -1) {
10028 int DefaultVal =
IsPacked ? -1 : 0;
10033 int MatrixAFMTIdx =
10034 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
10035 if (MatrixAFMTIdx != -1) {
10037 AMDGPUOperand::ImmTyMatrixAFMT, 0);
10040 int MatrixBFMTIdx =
10041 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
10042 if (MatrixBFMTIdx != -1) {
10044 AMDGPUOperand::ImmTyMatrixBFMT, 0);
10047 int MatrixAScaleIdx =
10048 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
10049 if (MatrixAScaleIdx != -1) {
10051 AMDGPUOperand::ImmTyMatrixAScale, 0);
10054 int MatrixBScaleIdx =
10055 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
10056 if (MatrixBScaleIdx != -1) {
10058 AMDGPUOperand::ImmTyMatrixBScale, 0);
10061 int MatrixAScaleFmtIdx =
10062 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
10063 if (MatrixAScaleFmtIdx != -1) {
10065 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
10068 int MatrixBScaleFmtIdx =
10069 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
10070 if (MatrixBScaleFmtIdx != -1) {
10072 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
10077 AMDGPUOperand::ImmTyMatrixAReuse, 0);
10081 AMDGPUOperand::ImmTyMatrixBReuse, 0);
10083 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
10084 if (NegLoIdx != -1)
10087 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
10088 if (NegHiIdx != -1)
10091 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
10092 AMDGPU::OpName::src2};
10093 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
10094 AMDGPU::OpName::src1_modifiers,
10095 AMDGPU::OpName::src2_modifiers};
10097 unsigned OpSel = 0;
10098 unsigned OpSelHi = 0;
10099 unsigned NegLo = 0;
10100 unsigned NegHi = 0;
10102 if (OpSelIdx != -1)
10105 if (OpSelHiIdx != -1)
10108 if (NegLoIdx != -1)
10111 if (NegHiIdx != -1)
10114 for (
int J = 0; J < 3; ++J) {
10115 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
10119 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
10129 uint32_t ModVal = 0;
10132 if (SrcOp.
isReg() && getMRI()
10136 if (VGPRSuffixIsHi)
10139 if ((OpSel & (1 << J)) != 0)
10143 if ((OpSelHi & (1 << J)) != 0)
10146 if ((NegLo & (1 << J)) != 0)
10149 if ((NegHi & (1 << J)) != 0)
10156void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
10157 OptionalImmIndexMap OptIdx;
10158 cvtVOP3(Inst, Operands, OptIdx);
10159 cvtVOP3P(Inst, Operands, OptIdx);
10163 unsigned i,
unsigned Opc,
10164 AMDGPU::OpName
OpName) {
10165 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
10166 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
10168 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
10171void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
10174 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
10177 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
10178 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
10180 OptionalImmIndexMap OptIdx;
10181 for (
unsigned i = 5; i < Operands.
size(); ++i) {
10182 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
10183 OptIdx[
Op.getImmTy()] = i;
10188 AMDGPUOperand::ImmTyIndexKey8bit);
10192 AMDGPUOperand::ImmTyIndexKey16bit);
10196 AMDGPUOperand::ImmTyIndexKey32bit);
10201 cvtVOP3P(Inst, Operands, OptIdx);
10208ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
10213 SMLoc S = getLoc();
10216 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
10217 SMLoc OpYLoc = getLoc();
10220 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
10223 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
10229void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
10232 auto addOp = [&](uint16_t ParsedOprIdx) {
10233 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
10235 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10239 Op.addRegOperands(Inst, 1);
10243 Op.addImmOperands(Inst, 1);
10255 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
10259 const auto &CInfo = InstInfo[CompIdx];
10260 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
10261 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
10262 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
10263 if (CInfo.hasSrc2Acc())
10264 addOp(CInfo.getIndexOfDstInParsedOperands());
10268 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
10269 if (BitOp3Idx != -1) {
10270 OptionalImmIndexMap OptIdx;
10271 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
10273 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
10283bool AMDGPUOperand::isDPP8()
const {
10284 return isImmTy(ImmTyDPP8);
10287bool AMDGPUOperand::isDPPCtrl()
const {
10288 using namespace AMDGPU::DPP;
10290 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
10293 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
10294 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
10295 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
10296 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
10297 (
Imm == DppCtrl::WAVE_SHL1) ||
10298 (
Imm == DppCtrl::WAVE_ROL1) ||
10299 (
Imm == DppCtrl::WAVE_SHR1) ||
10300 (
Imm == DppCtrl::WAVE_ROR1) ||
10301 (
Imm == DppCtrl::ROW_MIRROR) ||
10302 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
10303 (
Imm == DppCtrl::BCAST15) ||
10304 (
Imm == DppCtrl::BCAST31) ||
10305 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
10306 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
10315bool AMDGPUOperand::isBLGP()
const {
10319bool AMDGPUOperand::isS16Imm()
const {
10323bool AMDGPUOperand::isU16Imm()
const {
10331bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
10336 SMLoc Loc =
getToken().getEndLoc();
10337 Token = std::string(getTokenStr());
10339 if (getLoc() != Loc)
10344 if (!parseId(Suffix))
10348 StringRef DimId = Token;
10359ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
10363 SMLoc S = getLoc();
10369 SMLoc Loc = getLoc();
10370 if (!parseDimId(Encoding))
10371 return Error(Loc,
"invalid dim value");
10373 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
10374 AMDGPUOperand::ImmTyDim));
10382ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
10383 SMLoc S = getLoc();
10392 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10395 for (
size_t i = 0; i < 8; ++i) {
10399 SMLoc Loc = getLoc();
10400 if (getParser().parseAbsoluteExpression(Sels[i]))
10402 if (0 > Sels[i] || 7 < Sels[i])
10403 return Error(Loc,
"expected a 3-bit value");
10406 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10410 for (
size_t i = 0; i < 8; ++i)
10411 DPP8 |= (Sels[i] << (i * 3));
10413 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10418AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10420 if (Ctrl ==
"row_newbcast")
10423 if (Ctrl ==
"row_share" ||
10424 Ctrl ==
"row_xmask")
10427 if (Ctrl ==
"wave_shl" ||
10428 Ctrl ==
"wave_shr" ||
10429 Ctrl ==
"wave_rol" ||
10430 Ctrl ==
"wave_ror" ||
10431 Ctrl ==
"row_bcast")
10434 return Ctrl ==
"row_mirror" ||
10435 Ctrl ==
"row_half_mirror" ||
10436 Ctrl ==
"quad_perm" ||
10437 Ctrl ==
"row_shl" ||
10438 Ctrl ==
"row_shr" ||
10443AMDGPUAsmParser::parseDPPCtrlPerm() {
10446 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10450 for (
int i = 0; i < 4; ++i) {
10455 SMLoc Loc = getLoc();
10456 if (getParser().parseAbsoluteExpression(Temp))
10458 if (Temp < 0 || Temp > 3) {
10459 Error(Loc,
"expected a 2-bit value");
10463 Val += (Temp << i * 2);
10466 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10473AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10474 using namespace AMDGPU::DPP;
10479 SMLoc Loc = getLoc();
10481 if (getParser().parseAbsoluteExpression(Val))
10484 struct DppCtrlCheck {
10490 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10491 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10492 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10493 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10494 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10495 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10496 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10497 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10498 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10499 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10500 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10504 if (
Check.Ctrl == -1) {
10505 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10513 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10520ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10521 using namespace AMDGPU::DPP;
10524 !isSupportedDPPCtrl(getTokenStr(), Operands))
10527 SMLoc S = getLoc();
10533 if (Ctrl ==
"row_mirror") {
10534 Val = DppCtrl::ROW_MIRROR;
10535 }
else if (Ctrl ==
"row_half_mirror") {
10536 Val = DppCtrl::ROW_HALF_MIRROR;
10539 if (Ctrl ==
"quad_perm") {
10540 Val = parseDPPCtrlPerm();
10542 Val = parseDPPCtrlSel(Ctrl);
10551 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10555void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10557 OptionalImmIndexMap OptionalIdx;
10564 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10566 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10567 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10571 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10572 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10576 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10577 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10578 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx13 ||
10579 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10580 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx13 ||
10581 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10582 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx13 ||
10583 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
10584 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx13;
10586 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10590 if (OldIdx == NumOperands) {
10592 constexpr int DST_IDX = 0;
10594 }
else if (Src2ModIdx == NumOperands) {
10604 if (IsVOP3CvtSrDpp) {
10613 if (TiedTo != -1) {
10618 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10620 if (IsDPP8 &&
Op.isDppFI()) {
10623 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10624 }
else if (
Op.isReg()) {
10625 Op.addRegOperands(Inst, 1);
10626 }
else if (
Op.isImm() &&
10628 Op.addImmOperands(Inst, 1);
10629 }
else if (
Op.isImm()) {
10630 OptionalIdx[
Op.getImmTy()] =
I;
10638 AMDGPUOperand::ImmTyClamp);
10644 AMDGPUOperand::ImmTyByteSel);
10651 cvtVOP3P(Inst, Operands, OptionalIdx);
10653 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10660 using namespace llvm::AMDGPU::DPP;
10670 AMDGPUOperand::ImmTyDppFI);
10674void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10675 OptionalImmIndexMap OptionalIdx;
10679 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10680 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10684 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10687 if (TiedTo != -1) {
10692 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10694 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10702 Op.addImmOperands(Inst, 1);
10704 Op.addRegWithFPInputModsOperands(Inst, 2);
10705 }
else if (
Op.isDppFI()) {
10707 }
else if (
Op.isReg()) {
10708 Op.addRegOperands(Inst, 1);
10714 Op.addRegWithFPInputModsOperands(Inst, 2);
10715 }
else if (
Op.isReg()) {
10716 Op.addRegOperands(Inst, 1);
10717 }
else if (
Op.isDPPCtrl()) {
10718 Op.addImmOperands(Inst, 1);
10719 }
else if (
Op.isImm()) {
10721 OptionalIdx[
Op.getImmTy()] =
I;
10729 using namespace llvm::AMDGPU::DPP;
10737 AMDGPUOperand::ImmTyDppFI);
10746ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10748 AMDGPUOperand::ImmTy
Type) {
10749 return parseStringOrIntWithPrefix(
10751 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10755ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10756 return parseStringOrIntWithPrefix(
10757 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10758 AMDGPUOperand::ImmTySDWADstUnused);
10761void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10762 cvtSDWA(Inst, Operands, SDWAInstType::VOP1);
10765void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10766 cvtSDWA(Inst, Operands, SDWAInstType::VOP2);
10769void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10770 cvtSDWA(Inst, Operands, SDWAInstType::VOP2,
true,
true);
10773void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10774 cvtSDWA(Inst, Operands, SDWAInstType::VOP2,
false,
true);
10777void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10778 cvtSDWA(Inst, Operands, SDWAInstType::VOPC,
isVI());
10781void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10782 SDWAInstType BasicInstType,
bool SkipDstVcc,
10784 using namespace llvm::AMDGPU::SDWA;
10786 OptionalImmIndexMap OptionalIdx;
10787 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10788 bool SkippedVcc =
false;
10792 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10793 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10796 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10797 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10798 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10799 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10805 if (BasicInstType == SDWAInstType::VOP2 &&
10811 if (BasicInstType == SDWAInstType::VOPC && Inst.
getNumOperands() == 0) {
10817 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10818 }
else if (
Op.isImm()) {
10820 OptionalIdx[
Op.getImmTy()] =
I;
10824 SkippedVcc =
false;
10828 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10829 Opc != AMDGPU::V_NOP_sdwa_vi) {
10831 switch (BasicInstType) {
10832 case SDWAInstType::VOP1:
10835 AMDGPUOperand::ImmTyClamp, 0);
10839 AMDGPUOperand::ImmTyOModSI, 0);
10843 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10847 AMDGPUOperand::ImmTySDWADstUnused,
10848 DstUnused::UNUSED_PRESERVE);
10850 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10853 case SDWAInstType::VOP2:
10855 AMDGPUOperand::ImmTyClamp, 0);
10860 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10861 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10862 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10863 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10866 case SDWAInstType::VOPC:
10869 AMDGPUOperand::ImmTyClamp, 0);
10870 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10871 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10878 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10879 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10880 auto *it = Inst.
begin();
10882 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10895#define GET_MATCHER_IMPLEMENTATION
10896#define GET_MNEMONIC_SPELL_CHECKER
10897#define GET_MNEMONIC_CHECKER
10898#include "AMDGPUGenAsmMatcher.inc"
10904 return parseTokenOp(
"addr64",
Operands);
10906 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10908 return parseTokenOp(
"idxen",
Operands);
10910 return parseNamedBit(
"lds",
Operands, AMDGPUOperand::ImmTyLDS,
10913 return parseTokenOp(
"offen",
Operands);
10915 return parseTokenOp(
"off",
Operands);
10916 case MCK_row_95_en:
10917 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10919 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10921 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10923 return tryCustomParseOperand(
Operands, MCK);
10928unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10934 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10937 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10939 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10941 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10943 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10945 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10947 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10949 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10950 case MCK_row_95_en:
10951 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10959 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10961 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10962 case MCK_SOPPBrTarget:
10963 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10964 case MCK_VReg32OrOff:
10965 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10966 case MCK_InterpSlot:
10967 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10968 case MCK_InterpAttr:
10969 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10970 case MCK_InterpAttrChan:
10971 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10973 case MCK_SReg_64_XEXEC:
10983 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10985 return Match_InvalidOperand;
10993ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10994 SMLoc S = getLoc();
11003 return Error(S,
"expected a 16-bit value");
11006 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
11010bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
11016bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
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.
Enums shared between the AMDGPU backend (LLVM) and the ELF linker (LLD) for the .amdgpu....
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(GsymDataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Loop::LoopBounds::Direction Direction
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
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.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
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 void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static unsigned getNumExpectedArgs(VariantKind Kind)
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
static std::optional< TargetID > parseTargetIDString(StringRef TargetIDDirective)
Parse and validate a TargetID from a full "<triple>-<processor>:<features>" directive string.
TargetIDSetting getXnackSetting() const
GPUKind getGPUKind() const
StringRef getTargetTripleString() const
std::string toString() const
TargetIDSetting getSramEccSetting() const
static const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
size_t size() const
Get the array size.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
int16_t getOpRegClassID(const MCOperandInfo &OpInfo, unsigned HwModeId) const
Return the ID of the register class to use for OpInfo, for the active HwMode HwModeId.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
void setReg(MCRegister Reg)
Set the register number.
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterClass - Base class of TargetRegisterClass.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool regsOverlap(MCRegister RegA, MCRegister RegB) const
Returns true if the two registers are equal or alias each other.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
LLVM_ABI void setVariableValue(const MCExpr *Value)
void setRedefinable(bool Value)
Mark this symbol as redefinable.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
uint64_t getScalarSizeInBits() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
reference emplace_back(ArgTypes &&... Args)
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
unsigned getTgtId(const StringRef Name)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI)
static constexpr CustomOperand Operands[]
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getAddressableNumSGPRs(const MCSubtargetInfo &STI)
unsigned getVGPREncodingGranule(const MCSubtargetInfo &STI, std::optional< bool > EnableWavefrontSize32)
unsigned getSGPREncodingGranule(const MCSubtargetInfo &STI)
bool targetIDSettingsConflict(TargetIDSetting Lhs, TargetIDSetting Rhs)
Returns true if Lhs and Rhs are incompatible (both specific but different).
unsigned getLocalMemorySize(const MCSubtargetInfo &STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
constexpr const char *const ModMatrixFmt[]
constexpr const char *const ModMatrixScaleFmt[]
constexpr const char *const ModMatrixScale[]
bool isPackedFP32Inst(unsigned Opc)
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
bool isInlineValue(MCRegister Reg)
bool isPKFMACF16InlineConstant(uint32_t Literal, bool IsGFX11Plus)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
bool isSGPR(MCRegister Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
FuncInfoFlags
Per-function flags packed into INFO_FLAGS entries.
uint8_t wmmaScaleF8F6F4FormatToNumRegs(unsigned Fmt)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
unsigned getTemporalHintType(const MCInstrDesc TID)
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
bool isGFX10(const MCSubtargetInfo &STI)
LLVM_READONLY bool isLitExpr(const MCExpr *Expr)
bool isInlinableLiteralV2BF16(uint32_t Literal)
LLVM_ABI bool isCPUValidForSubArch(Triple::SubArchType SubArch, GPUKind AK)
Return true if the GPU AK is usable with the triple subarch SubArch.
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
bool hasA16(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset, bool IsBuffer)
bool isGFX12Plus(const MCSubtargetInfo &STI)
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool isHsaAbi(const MCSubtargetInfo &STI)
bool isGFX11(const MCSubtargetInfo &STI)
const int OPR_VAL_INVALID
bool getSMEMIsBuffer(unsigned Opc)
bool isGFX13(const MCSubtargetInfo &STI)
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
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 isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool hasMAIInsts(const MCSubtargetInfo &STI)
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool isGFX13Plus(const MCSubtargetInfo &STI)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
AMDGPU::TargetID TargetID
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
bool isValidWMMAScaleFmtCombination(unsigned AFmt, unsigned AScale, unsigned BFmt, unsigned BScale)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT64
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_IMM_V2FP16_SPLAT
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
LLVM_ABI StringRef getArchNameAMDGCN(GPUKind AK)
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
bool isGFX1250Plus(const MCSubtargetInfo &STI)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
constexpr bool hasIntClamp(const T &...O)
@ Valid
The data is already valid.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
LLVM_ABI void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target & getTheGCNLegacyTarget()
The target for GCN GPUs, registered under the legacy "amdgcn" architecture name for use with -march.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ Default
The result value is uniform if and only if all operands are uniform.
void initDefault(const MCSubtargetInfo &STI, MCContext &Ctx, bool InitMCExpr=true)
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
uint32_t PrivateSegmentSize
SmallVector< std::pair< MCSymbol *, std::string >, 4 > IndirectCalls
SmallVector< std::pair< MCSymbol *, MCSymbol * >, 8 > Calls
SmallVector< FuncInfo, 8 > Funcs
SmallVector< std::pair< MCSymbol *, std::string >, 4 > TypeIds
SmallVector< std::pair< MCSymbol *, MCSymbol * >, 4 > Uses
Instruction set architecture version.
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
const MCExpr * compute_pgm_rsrc1
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * group_segment_fixed_size
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * kernel_code_properties
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size