70 enum KindTy { Token, Immediate, Register, Expression } Kind;
72 SMLoc StartLoc, EndLoc;
73 const AMDGPUAsmParser *AsmParser;
76 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
77 : Kind(Kind_), AsmParser(AsmParser_) {}
79 using Ptr = std::unique_ptr<AMDGPUOperand>;
87 bool hasFPModifiers()
const {
return Abs || Neg; }
88 bool hasIntModifiers()
const {
return Sext; }
89 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
90 bool isForcedLit()
const {
return Lit == LitModifier::Lit; }
91 bool isForcedLit64()
const {
return Lit == LitModifier::Lit64; }
93 int64_t getFPModifiersOperand()
const {
100 int64_t getIntModifiersOperand()
const {
106 int64_t getModifiersOperand()
const {
107 assert(!(hasFPModifiers() && hasIntModifiers()) &&
108 "fp and int modifiers should not be used simultaneously");
109 if (hasFPModifiers())
110 return getFPModifiersOperand();
111 if (hasIntModifiers())
112 return getIntModifiersOperand();
116 friend raw_ostream &
operator<<(raw_ostream &OS,
117 AMDGPUOperand::Modifiers Mods);
191 ImmTyMatrixAScaleFmt,
192 ImmTyMatrixBScaleFmt,
225 mutable int MCOpIdx = -1;
228 bool isToken()
const override {
return Kind == Token; }
230 bool isSymbolRefExpr()
const {
234 bool isImm()
const override {
return Kind == Immediate; }
236 bool isInlinableImm(MVT type)
const;
237 bool isLiteralImm(MVT type)
const;
239 bool isRegKind()
const {
return Kind == Register; }
241 bool isReg()
const override {
return isRegKind() && !hasModifiers(); }
243 bool isRegOrInline(
unsigned RCID, MVT type)
const {
244 return isRegClass(RCID) || isInlinableImm(type);
248 return isRegOrInline(RCID, type) || isLiteralImm(type);
251 bool isRegOrImmWithInt16InputMods()
const {
255 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
257 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
260 bool isRegOrImmWithInt32InputMods()
const {
264 bool isRegOrInlineImmWithInt16InputMods()
const {
265 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
268 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
269 return isRegOrInline(
270 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
273 bool isRegOrInlineImmWithInt32InputMods()
const {
274 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
277 bool isRegOrImmWithInt64InputMods()
const {
281 bool isRegOrImmWithFP16InputMods()
const {
285 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
287 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
290 bool isRegOrImmWithFP32InputMods()
const {
294 bool isRegOrImmWithFP64InputMods()
const {
298 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
299 return isRegOrInline(
300 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
303 bool isRegOrInlineImmWithFP32InputMods()
const {
304 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
307 bool isRegOrInlineImmWithFP64InputMods()
const {
308 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
311 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
313 bool isVRegWithFP32InputMods()
const {
314 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
317 bool isVRegWithFP64InputMods()
const {
318 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
321 bool isPackedFP16InputMods()
const {
325 bool isPackedVGPRFP32InputMods()
const {
329 bool isVReg()
const {
330 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
331 isRegClass(AMDGPU::VReg_64RegClassID) ||
332 isRegClass(AMDGPU::VReg_96RegClassID) ||
333 isRegClass(AMDGPU::VReg_128RegClassID) ||
334 isRegClass(AMDGPU::VReg_160RegClassID) ||
335 isRegClass(AMDGPU::VReg_192RegClassID) ||
336 isRegClass(AMDGPU::VReg_256RegClassID) ||
337 isRegClass(AMDGPU::VReg_512RegClassID) ||
338 isRegClass(AMDGPU::VReg_1024RegClassID);
341 bool isVReg32()
const {
return isRegClass(AMDGPU::VGPR_32RegClassID); }
343 bool isVReg32OrOff()
const {
return isOff() || isVReg32(); }
345 bool isRsrcReg32()
const {
return isRegClass(AMDGPU::RsrcReg32RegClassID); }
347 bool isNull()
const {
return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL; }
349 bool isAV_LdSt_32_Align2_RegOp()
const {
350 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
351 isRegClass(AMDGPU::AGPR_32RegClassID);
354 bool isVRegWithInputMods()
const;
355 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
356 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
358 bool isSDWAOperand(MVT type)
const;
359 bool isSDWAFP16Operand()
const;
360 bool isSDWAFP32Operand()
const;
361 bool isSDWAInt16Operand()
const;
362 bool isSDWAInt32Operand()
const;
364 bool isImmTy(ImmTy ImmT)
const {
return isImm() &&
Imm.Type == ImmT; }
366 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
368 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
370 bool isImmModifier()
const {
return isImm() &&
Imm.Type != ImmTyNone; }
372 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
373 bool isDim()
const {
return isImmTy(ImmTyDim); }
374 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
375 bool isOff()
const {
return isImmTy(ImmTyOff); }
376 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
377 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
378 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
379 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
380 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
381 bool isFlatOffset()
const {
382 return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset);
384 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
385 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
386 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
387 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
388 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
389 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
390 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
391 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
392 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
393 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
394 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
395 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
396 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
397 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
398 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
399 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
400 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
401 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
402 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
403 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
404 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
405 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
406 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
407 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
408 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
409 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
410 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
411 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
412 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
413 bool isDone()
const {
return isImmTy(ImmTyDone); }
414 bool isRowEn()
const {
return isImmTy(ImmTyRowEn); }
416 bool isRegOrImm()
const {
return isReg() || isImm(); }
418 bool isRegClass(
unsigned RCID)
const;
422 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
423 return isRegOrInline(RCID, type) && !hasModifiers();
426 bool isSCSrcB16()
const {
427 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
430 bool isSCSrcV2B16()
const {
return isSCSrcB16(); }
432 bool isSCSrc_b32()
const {
433 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
436 bool isSCSrc_b64()
const {
437 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
440 bool isBoolReg()
const;
442 bool isSCSrcF16()
const {
443 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
446 bool isSCSrcV2F16()
const {
return isSCSrcF16(); }
448 bool isSCSrcF32()
const {
449 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
452 bool isSCSrcF64()
const {
453 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
456 bool isSSrc_b32()
const {
457 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
460 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
462 bool isSSrcV2B16()
const {
467 bool isSSrc_b64()
const {
470 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
471 (((
const MCTargetAsmParser *)AsmParser)
472 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
476 bool isSSrc_f32()
const {
477 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
480 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
482 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
484 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
486 bool isSSrc_NoInline_f16()
const {
return isSSrc_f16(); }
488 bool isSSrcV2F16()
const {
493 bool isSSrcV2FP32()
const {
498 bool isSCSrcV2FP32()
const {
503 bool isSSrcV2INT32()
const {
508 bool isSCSrcV2INT32()
const {
510 return isSCSrc_b32();
513 bool isSSrcOrLds_b32()
const {
514 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
515 isLiteralImm(MVT::i32) || isExpr();
518 bool isVCSrc_b32()
const {
519 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
522 bool isVCSrc_b32_Lo256()
const {
523 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
526 bool isVCSrc_b64_Lo256()
const {
527 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
530 bool isVCSrc_b64()
const {
531 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
534 bool isVCSrcT_b16()
const {
535 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
538 bool isVCSrcTB16_Lo128()
const {
539 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
542 bool isVCSrcFake16B16_Lo128()
const {
543 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
546 bool isVCSrc_b16()
const {
547 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
550 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
552 bool isVCSrc_f32()
const {
553 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
556 bool isVCSrc_f64()
const {
557 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
560 bool isVCSrcTBF16()
const {
561 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
564 bool isVCSrcT_f16()
const {
565 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
568 bool isVCSrcT_bf16()
const {
569 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
572 bool isVCSrcTBF16_Lo128()
const {
573 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
576 bool isVCSrcTF16_Lo128()
const {
577 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
580 bool isVCSrcFake16BF16_Lo128()
const {
581 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
584 bool isVCSrcFake16F16_Lo128()
const {
585 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
588 bool isVCSrc_bf16()
const {
589 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
592 bool isVCSrc_f16()
const {
593 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
596 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
598 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
600 bool isVSrc_b32()
const {
601 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
604 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
606 bool isVSrc_v2b64()
const {
607 return isRegOrInlineNoMods(AMDGPU::VS_128RegClassID, MVT::i64) ||
608 isLiteralImm(MVT::i64);
611 bool isVSrc_v2f64()
const {
612 return isRegOrInlineNoMods(AMDGPU::VS_128RegClassID, MVT::f64) ||
613 isLiteralImm(MVT::f64);
616 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
618 bool isVSrcT_b16_Lo128()
const {
619 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
622 bool isVSrcFake16_b16_Lo128()
const {
623 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
626 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
628 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
630 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
632 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
634 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
636 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
638 bool isVSrc_f32()
const {
639 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
642 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
644 bool isVSrcT_bf16()
const {
645 return isVCSrcTBF16() || isLiteralImm(MVT::bf16);
648 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
650 bool isVSrcT_bf16_Lo128()
const {
651 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
654 bool isVSrcT_f16_Lo128()
const {
655 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
658 bool isVSrcFake16_bf16_Lo128()
const {
659 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
662 bool isVSrcFake16_f16_Lo128()
const {
663 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
666 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
668 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
670 bool isVSrc_v2bf16()
const {
671 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
674 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
676 bool isVSrc_v2f16_splat()
const {
return isVSrc_v2f16(); }
678 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
680 bool isVISrcB32()
const {
681 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
684 bool isVISrcB16()
const {
685 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
688 bool isVISrcV2B16()
const {
return isVISrcB16(); }
690 bool isVISrcF32()
const {
691 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
694 bool isVISrcF16()
const {
695 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
698 bool isVISrcV2F16()
const {
return isVISrcF16() || isVISrcB32(); }
700 bool isVISrc_64_bf16()
const {
701 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
704 bool isVISrc_64_f16()
const {
705 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
708 bool isVISrc_64_b32()
const {
709 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
712 bool isVISrc_64B64()
const {
713 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
716 bool isVISrc_64_f64()
const {
717 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
720 bool isVISrc_64V2FP32()
const {
721 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
724 bool isVISrc_64V2INT32()
const {
725 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
728 bool isVISrc_256_b32()
const {
729 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
732 bool isVISrc_256_f32()
const {
733 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
736 bool isVISrc_256B64()
const {
737 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
740 bool isVISrc_256_f64()
const {
741 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
744 bool isVISrc_512_f64()
const {
745 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
748 bool isVISrc_128B16()
const {
749 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
752 bool isVISrc_128V2B16()
const {
return isVISrc_128B16(); }
754 bool isVISrc_128_b32()
const {
755 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
758 bool isVISrc_128_f32()
const {
759 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
762 bool isVISrc_256V2FP32()
const {
763 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
766 bool isVISrc_256V2INT32()
const {
767 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
770 bool isVISrc_512_b32()
const {
771 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
774 bool isVISrc_512B16()
const {
775 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
778 bool isVISrc_512V2B16()
const {
return isVISrc_512B16(); }
780 bool isVISrc_512_f32()
const {
781 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
784 bool isVISrc_512F16()
const {
785 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
788 bool isVISrc_512V2F16()
const {
789 return isVISrc_512F16() || isVISrc_512_b32();
792 bool isVISrc_1024_b32()
const {
793 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
796 bool isVISrc_1024B16()
const {
797 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
800 bool isVISrc_1024V2B16()
const {
return isVISrc_1024B16(); }
802 bool isVISrc_1024_f32()
const {
803 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
806 bool isVISrc_1024F16()
const {
807 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
810 bool isVISrc_1024V2F16()
const {
811 return isVISrc_1024F16() || isVISrc_1024_b32();
814 bool isAISrcB32()
const {
815 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
818 bool isAISrcB16()
const {
819 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
822 bool isAISrcV2B16()
const {
return isAISrcB16(); }
824 bool isAISrcF32()
const {
825 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
828 bool isAISrcF16()
const {
829 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
832 bool isAISrcV2F16()
const {
return isAISrcF16() || isAISrcB32(); }
834 bool isAISrc_64B64()
const {
835 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
838 bool isAISrc_64_f64()
const {
839 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
842 bool isAISrc_128_b32()
const {
843 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
846 bool isAISrc_128B16()
const {
847 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
850 bool isAISrc_128V2B16()
const {
return isAISrc_128B16(); }
852 bool isAISrc_128_f32()
const {
853 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
856 bool isAISrc_128F16()
const {
857 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
860 bool isAISrc_128V2F16()
const {
861 return isAISrc_128F16() || isAISrc_128_b32();
864 bool isVISrc_128_bf16()
const {
865 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
868 bool isVISrc_128_f16()
const {
869 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
872 bool isVISrc_128V2F16()
const {
873 return isVISrc_128_f16() || isVISrc_128_b32();
876 bool isAISrc_256B64()
const {
877 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
880 bool isAISrc_256_f64()
const {
881 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
884 bool isAISrc_512_b32()
const {
885 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
888 bool isAISrc_512B16()
const {
889 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
892 bool isAISrc_512V2B16()
const {
return isAISrc_512B16(); }
894 bool isAISrc_512_f32()
const {
895 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
898 bool isAISrc_512F16()
const {
899 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
902 bool isAISrc_512V2F16()
const {
903 return isAISrc_512F16() || isAISrc_512_b32();
906 bool isAISrc_1024_b32()
const {
907 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
910 bool isAISrc_1024B16()
const {
911 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
914 bool isAISrc_1024V2B16()
const {
return isAISrc_1024B16(); }
916 bool isAISrc_1024_f32()
const {
917 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
920 bool isAISrc_1024F16()
const {
921 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
924 bool isAISrc_1024V2F16()
const {
925 return isAISrc_1024F16() || isAISrc_1024_b32();
928 bool isKImmFP32()
const {
return isLiteralImm(MVT::f32); }
930 bool isKImmFP16()
const {
return isLiteralImm(MVT::f16); }
932 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
934 bool isMem()
const override {
return false; }
936 bool isExpr()
const {
return Kind == Expression; }
938 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
940 bool isSWaitCnt()
const;
941 bool isDepCtr()
const;
942 bool isSDelayALU()
const;
943 bool isHwreg()
const;
944 bool isSendMsg()
const;
945 bool isWaitEvent()
const;
946 bool isSplitBarrier()
const;
947 bool isSwizzle()
const;
948 bool isSMRDOffset8()
const;
949 bool isSMEMOffset()
const;
950 bool isSMRDLiteralOffset()
const;
952 bool isDPPCtrl()
const;
954 bool isGPRIdxMode()
const;
955 bool isS16Imm()
const;
956 bool isU16Imm()
const;
957 bool isEndpgm()
const;
959 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
960 return [
this,
P]() {
return P(*
this); };
965 return StringRef(Tok.Data, Tok.Length);
973 void setImm(int64_t Val) {
978 ImmTy getImmTy()
const {
983 MCRegister
getReg()
const override {
988 SMLoc getStartLoc()
const override {
return StartLoc; }
990 SMLoc getEndLoc()
const override {
return EndLoc; }
992 SMRange getLocRange()
const {
return SMRange(StartLoc, EndLoc); }
994 int getMCOpIdx()
const {
return MCOpIdx; }
996 Modifiers getModifiers()
const {
997 assert(isRegKind() || isImmTy(ImmTyNone));
998 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1001 void setModifiers(Modifiers Mods) {
1002 assert(isRegKind() || isImmTy(ImmTyNone));
1009 bool hasModifiers()
const {
return getModifiers().hasModifiers(); }
1011 bool hasFPModifiers()
const {
return getModifiers().hasFPModifiers(); }
1013 bool hasIntModifiers()
const {
return getModifiers().hasIntModifiers(); }
1015 bool isForcedLit()
const {
1016 return isImmLiteral() && getModifiers().isForcedLit();
1019 bool isForcedLit64()
const {
1020 return isImmLiteral() && getModifiers().isForcedLit64();
1025 void addImmOperands(MCInst &Inst,
unsigned N,
1026 bool ApplyModifiers =
true)
const;
1028 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
1029 bool ApplyModifiers)
const;
1031 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1033 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1035 addRegOperands(Inst,
N);
1037 addImmOperands(Inst,
N);
1040 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1041 Modifiers Mods = getModifiers();
1044 addRegOperands(Inst,
N);
1046 addImmOperands(Inst,
N,
false);
1050 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1051 assert(!hasIntModifiers());
1052 addRegOrImmWithInputModsOperands(Inst,
N);
1055 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1056 assert(!hasFPModifiers());
1057 addRegOrImmWithInputModsOperands(Inst,
N);
1060 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1061 Modifiers Mods = getModifiers();
1064 addRegOperands(Inst,
N);
1067 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1068 assert(!hasIntModifiers());
1069 addRegWithInputModsOperands(Inst,
N);
1072 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1073 assert(!hasFPModifiers());
1074 addRegWithInputModsOperands(Inst,
N);
1077 static void printImmTy(raw_ostream &OS, ImmTy
Type) {
1080 case ImmTyNone: OS <<
"None";
break;
1081 case ImmTyGDS: OS <<
"GDS";
break;
1082 case ImmTyLDS: OS <<
"LDS";
break;
1083 case ImmTyOffen: OS <<
"Offen";
break;
1084 case ImmTyIdxen: OS <<
"Idxen";
break;
1085 case ImmTyAddr64: OS <<
"Addr64";
break;
1086 case ImmTyOffset: OS <<
"Offset";
break;
1087 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1088 case ImmTyOffset0: OS <<
"Offset0";
break;
1089 case ImmTyOffset1: OS <<
"Offset1";
break;
1090 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1091 case ImmTyCPol: OS <<
"CPol";
break;
1092 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1093 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1094 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1095 case ImmTyTFE: OS <<
"TFE";
break;
1096 case ImmTyIsAsync: OS <<
"IsAsync";
break;
1097 case ImmTyD16: OS <<
"D16";
break;
1098 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1099 case ImmTyClamp: OS <<
"Clamp";
break;
1100 case ImmTyOModSI: OS <<
"OModSI";
break;
1101 case ImmTyDPP8: OS <<
"DPP8";
break;
1102 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1103 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1104 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1105 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1106 case ImmTyDppFI: OS <<
"DppFI";
break;
1107 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1108 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1109 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1110 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1111 case ImmTyDMask: OS <<
"DMask";
break;
1112 case ImmTyDim: OS <<
"Dim";
break;
1113 case ImmTyUNorm: OS <<
"UNorm";
break;
1114 case ImmTyDA: OS <<
"DA";
break;
1115 case ImmTyR128A16: OS <<
"R128A16";
break;
1116 case ImmTyA16: OS <<
"A16";
break;
1117 case ImmTyLWE: OS <<
"LWE";
break;
1118 case ImmTyOff: OS <<
"Off";
break;
1119 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1120 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1121 case ImmTyExpVM: OS <<
"ExpVM";
break;
1122 case ImmTyDone: OS <<
"Done";
break;
1123 case ImmTyRowEn: OS <<
"RowEn";
break;
1124 case ImmTyHwreg: OS <<
"Hwreg";
break;
1125 case ImmTySendMsg: OS <<
"SendMsg";
break;
1126 case ImmTyWaitEvent: OS <<
"WaitEvent";
break;
1127 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1128 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1129 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1130 case ImmTyOpSel: OS <<
"OpSel";
break;
1131 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1132 case ImmTyNegLo: OS <<
"NegLo";
break;
1133 case ImmTyNegHi: OS <<
"NegHi";
break;
1134 case ImmTySwizzle: OS <<
"Swizzle";
break;
1135 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1136 case ImmTyHigh: OS <<
"High";
break;
1137 case ImmTyBLGP: OS <<
"BLGP";
break;
1138 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1139 case ImmTyABID: OS <<
"ABID";
break;
1140 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1141 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1142 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1143 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1144 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1145 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1146 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1147 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1148 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1149 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1150 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1151 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1152 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1153 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1154 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1155 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1160 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1164 <<
" mods: " <<
Reg.Mods <<
'>';
1168 if (getImmTy() != ImmTyNone) {
1170 printImmTy(OS, getImmTy());
1172 OS <<
" mods: " <<
Imm.Mods <<
'>';
1185 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1186 int64_t Val, SMLoc Loc,
1187 ImmTy
Type = ImmTyNone,
1188 bool IsFPImm =
false) {
1189 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1191 Op->Imm.IsFPImm = IsFPImm;
1193 Op->Imm.Mods = Modifiers();
1199 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1200 StringRef Str, SMLoc Loc,
1201 bool HasExplicitEncodingSize =
true) {
1202 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1203 Res->Tok.Data = Str.data();
1204 Res->Tok.Length = Str.size();
1205 Res->StartLoc = Loc;
1210 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1211 MCRegister
Reg, SMLoc S, SMLoc
E) {
1212 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1213 Op->Reg.RegNo =
Reg;
1214 Op->Reg.Mods = Modifiers();
1220 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1221 const class MCExpr *Expr, SMLoc S) {
1222 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1231 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1240#define GET_REGISTER_MATCHER
1241#include "AMDGPUGenAsmMatcher.inc"
1242#undef GET_REGISTER_MATCHER
1243#undef GET_SUBTARGET_FEATURE_NAME
1248class KernelScopeInfo {
1249 int SgprIndexUnusedMin = -1;
1250 int VgprIndexUnusedMin = -1;
1251 int AgprIndexUnusedMin = -1;
1255 void usesSgprAt(
int i) {
1256 if (i >= SgprIndexUnusedMin) {
1257 SgprIndexUnusedMin = ++i;
1260 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1266 void usesVgprAt(
int i) {
1267 if (i >= VgprIndexUnusedMin) {
1268 VgprIndexUnusedMin = ++i;
1271 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1273 VgprIndexUnusedMin);
1279 void usesAgprAt(
int i) {
1284 if (i >= AgprIndexUnusedMin) {
1285 AgprIndexUnusedMin = ++i;
1288 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1293 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1295 VgprIndexUnusedMin);
1302 KernelScopeInfo() =
default;
1306 MSTI = Ctx->getSubtargetInfo();
1308 usesSgprAt(SgprIndexUnusedMin = -1);
1309 usesVgprAt(VgprIndexUnusedMin = -1);
1311 usesAgprAt(AgprIndexUnusedMin = -1);
1315 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1316 unsigned RegWidth) {
1319 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1322 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1325 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1334 MCAsmParser &Parser;
1336 unsigned ForcedEncodingSize = 0;
1337 bool ForcedDPP =
false;
1338 bool ForcedSDWA =
false;
1339 KernelScopeInfo KernelScope;
1340 const unsigned HwMode;
1342 const AMDGPU::IsaVersion ISA;
1347#define GET_ASSEMBLER_HEADER
1348#include "AMDGPUGenAsmMatcher.inc"
1353 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1355 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1359 std::optional<AMDGPU::InfoSectionData> InfoData;
1366 bool TargetDirectiveEmitted =
false;
1375 SmallVector<unsigned> OpcodeStream;
1377 OpcodeStreamSymbols;
1378 SmallPtrSet<const MCSymbol *, 8> AMDHSAKernelSymbols;
1381 void checkKernelPrologues();
1384 void createConstantSymbol(StringRef Id, int64_t Val);
1386 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1387 bool OutOfRangeError(SMRange
Range);
1403 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1404 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1405 std::optional<bool> EnableWavefrontSize32,
1406 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1407 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1408 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1409 bool ParseDirectiveAMDGCNTarget();
1410 bool ParseDirectiveAMDHSACodeObjectVersion();
1411 bool ParseDirectiveAMDHSAKernel();
1412 bool ParseAMDKernelCodeTValue(StringRef ID, AMDGPUMCKernelCodeT &Header);
1413 bool ParseDirectiveAMDKernelCodeT();
1415 bool subtargetHasRegister(
const MCRegisterInfo &MRI, MCRegister
Reg);
1416 bool ParseDirectiveAMDGPUHsaKernel();
1418 bool ParseDirectiveISAVersion();
1419 bool ParseDirectiveHSAMetadata();
1420 bool ParseDirectivePALMetadataBegin();
1421 bool ParseDirectivePALMetadata();
1422 bool ParseDirectiveAMDGPULDS();
1423 bool ParseDirectiveAMDGPUInfo();
1427 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1428 const char *AssemblerDirectiveEnd,
1429 std::string &CollectString);
1431 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1432 RegisterKind RegKind, MCRegister Reg1,
1433 RegisterKind RegKind1, SMLoc Loc);
1434 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1435 unsigned &RegNum,
unsigned &RegWidth,
1436 bool RestoreOnFailure =
false);
1437 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1438 unsigned &RegNum,
unsigned &RegWidth,
1439 SmallVectorImpl<AsmToken> &Tokens);
1440 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1442 SmallVectorImpl<AsmToken> &Tokens);
1443 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1445 SmallVectorImpl<AsmToken> &Tokens);
1446 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1448 SmallVectorImpl<AsmToken> &Tokens);
1449 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &SubReg);
1450 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1451 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1454 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1455 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1456 void initializeGprCountSymbol(RegisterKind RegKind);
1457 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1463 OperandMode_Default,
1467 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1469 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1470 const MCInstrInfo &MII)
1471 : MCTargetAsmParser(STI, MII), Parser(_Parser),
1472 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)),
1477 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1479 if (ISA.Major >= 6 &&
isHsaAbi(getSTI())) {
1480 createConstantSymbol(
".amdgcn.gfx_generation_number", ISA.Major);
1481 createConstantSymbol(
".amdgcn.gfx_generation_minor", ISA.Minor);
1482 createConstantSymbol(
".amdgcn.gfx_generation_stepping", ISA.Stepping);
1484 createConstantSymbol(
".option.machine_version_major", ISA.Major);
1485 createConstantSymbol(
".option.machine_version_minor", ISA.Minor);
1486 createConstantSymbol(
".option.machine_version_stepping", ISA.Stepping);
1488 if (ISA.Major >= 6 &&
isHsaAbi(getSTI())) {
1489 initializeGprCountSymbol(IS_VGPR);
1490 initializeGprCountSymbol(IS_SGPR);
1495 createConstantSymbol(Symbol, Code);
1497 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1498 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1499 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1547 bool hasBVHRayTracingInsts()
const {
1548 return getFeatureBits()[AMDGPU::FeatureBVHRayTracingInsts];
1553 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1555 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1557 bool hasInv2PiInlineImm()
const {
1558 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1561 bool has64BitLiterals()
const {
1562 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1565 bool hasFlatOffsets()
const {
1566 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1569 bool hasTrue16Insts()
const {
1570 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1574 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1577 bool hasSGPR102_SGPR103()
const {
return !
isVI() && !
isGFX9(); }
1579 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1581 bool hasIntClamp()
const {
return getFeatureBits()[AMDGPU::FeatureIntClamp]; }
1583 bool hasPartialNSAEncoding()
const {
1584 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1587 bool hasGloballyAddressableScratch()
const {
1588 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1601 AMDGPUTargetStreamer &getTargetStreamer() {
1602 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1603 return static_cast<AMDGPUTargetStreamer &
>(TS);
1609 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1612 const MCRegisterInfo *getMRI()
const {
1616 const MCInstrInfo *getMII()
const {
return &MII; }
1620 const FeatureBitset &getFeatureBits()
const {
1621 return getSTI().getFeatureBits();
1624 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1625 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1626 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1628 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1629 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1630 bool isForcedDPP()
const {
return ForcedDPP; }
1631 bool isForcedSDWA()
const {
return ForcedSDWA; }
1632 ArrayRef<unsigned> getMatchedVariants()
const;
1633 StringRef getMatchedVariantName()
const;
1635 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1636 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1637 bool RestoreOnFailure);
1638 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1639 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1640 SMLoc &EndLoc)
override;
1641 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1642 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1643 unsigned Kind)
override;
1644 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1647 bool MatchingInlineAsm)
override;
1648 bool ParseDirective(AsmToken DirectiveID)
override;
1649 void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc)
override;
1650 void onEndOfFile()
override;
1652 OperandMode
Mode = OperandMode_Default);
1653 StringRef parseMnemonicSuffix(StringRef Name);
1654 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1660 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1664 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1665 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1667 ParseStatus parseOperandArrayWithPrefix(
1669 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1670 bool (*ConvertResult)(int64_t &) =
nullptr);
1674 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1675 bool IgnoreNegative =
false);
1676 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1680 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1684 ArrayRef<const char *> Ids,
1688 ArrayRef<const char *> Ids,
1689 AMDGPUOperand::ImmTy
Type);
1692 bool isOperandModifier(
const AsmToken &Token,
1693 const AsmToken &NextToken)
const;
1694 bool isRegOrOperandModifier(
const AsmToken &Token,
1695 const AsmToken &NextToken)
const;
1696 bool isNamedOperandModifier(
const AsmToken &Token,
1697 const AsmToken &NextToken)
const;
1698 bool isOpcodeModifierWithVal(
const AsmToken &Token,
1699 const AsmToken &NextToken)
const;
1700 bool parseSP3NegModifier();
1707 bool AllowImm =
true);
1709 bool AllowImm =
true);
1715 AMDGPUOperand::ImmTy ImmTy);
1720 AMDGPUOperand::ImmTy
Type);
1724 AMDGPUOperand::ImmTy
Type);
1728 AMDGPUOperand::ImmTy
Type);
1732 ParseStatus parseDfmtNfmt(int64_t &
Format);
1733 ParseStatus parseUfmt(int64_t &
Format);
1734 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1736 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1739 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1740 ParseStatus parseNumericFormat(int64_t &
Format);
1744 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1745 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr,
1750 bool parseCnt(int64_t &IntVal);
1753 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1754 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1757 bool parseDelay(int64_t &Delay);
1763 struct OperandInfoTy {
1766 bool IsSymbolic =
false;
1767 bool IsDefined =
false;
1769 constexpr OperandInfoTy(int64_t Val) : Val(Val) {}
1772 struct StructuredOpField : OperandInfoTy {
1776 bool IsDefined =
false;
1778 constexpr StructuredOpField(StringLiteral Id, StringLiteral Desc,
1779 unsigned Width, int64_t
Default)
1780 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1781 virtual ~StructuredOpField() =
default;
1783 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1784 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1788 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1790 return Error(Parser,
"not supported on this GPU");
1792 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1800 bool parseSendMsgBody(OperandInfoTy &
Msg, OperandInfoTy &
Op,
1801 OperandInfoTy &Stream);
1802 bool validateSendMsg(
const OperandInfoTy &
Msg,
const OperandInfoTy &
Op,
1803 const OperandInfoTy &Stream);
1805 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1806 OperandInfoTy &Width);
1811 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1818 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand &)>
Test,
1820 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1824 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1830 bool validateConstantBusLimitations(
const MCInst &Inst,
1832 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1835 bool tryVOPD(
const MCInst &Inst);
1836 bool tryVOPD3(
const MCInst &Inst);
1837 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1839 bool validateIntClampSupported(
const MCInst &Inst);
1840 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1841 bool validateMIMGGatherDMask(
const MCInst &Inst);
1843 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1844 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1845 bool validateMIMGD16(
const MCInst &Inst);
1847 bool validateTensorR128(
const MCInst &Inst);
1848 bool validateMIMGMSAA(
const MCInst &Inst);
1849 bool validateOpSel(
const MCInst &Inst);
1850 bool validateTrue16OpSel(
const MCInst &Inst);
1851 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1853 bool validateVccOperand(MCRegister
Reg)
const;
1858 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1859 bool validateVGPRAlign(
const MCInst &Inst)
const;
1863 bool validateDivScale(
const MCInst &Inst);
1868 const unsigned CPol);
1873 bool validateClusterBarrierIsFirst(
const MCInst &Inst,
1875 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1876 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1877 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1878 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1880 bool isSupportedMnemo(StringRef Mnemo,
const FeatureBitset &FBS);
1881 bool isSupportedMnemo(StringRef Mnemo,
const FeatureBitset &FBS,
1882 ArrayRef<unsigned> Variants);
1883 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1885 bool isId(
const StringRef Id)
const;
1886 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1888 StringRef getId()
const;
1889 bool trySkipId(
const StringRef Id);
1890 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1894 bool parseString(StringRef &Val,
1895 const StringRef ErrMsg =
"expected a string");
1896 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1902 StringRef getTokenStr()
const;
1903 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1905 SMLoc getLoc()
const;
1909 void onBeginOfFile()
override;
1913 void emitTargetDirective();
1914 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1926 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1927 const unsigned MaxVal,
const Twine &ErrMsg,
1929 bool parseSwizzleOperands(
const unsigned OpNum, int64_t *
Op,
1930 const unsigned MinVal,
const unsigned MaxVal,
1931 const StringRef ErrMsg);
1933 bool parseSwizzleOffset(int64_t &
Imm);
1934 bool parseSwizzleMacro(int64_t &
Imm);
1935 bool parseSwizzleQuadPerm(int64_t &
Imm);
1936 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1937 bool parseSwizzleBroadcast(int64_t &
Imm);
1938 bool parseSwizzleSwap(int64_t &
Imm);
1939 bool parseSwizzleReverse(int64_t &
Imm);
1940 bool parseSwizzleFFT(int64_t &
Imm);
1941 bool parseSwizzleRotate(int64_t &
Imm);
1944 int64_t parseGPRIdxMacro();
1947 cvtMubufImpl(Inst,
Operands,
false);
1950 cvtMubufImpl(Inst,
Operands,
true);
1956 OptionalImmIndexMap &OptionalIdx);
1965 OptionalImmIndexMap &OptionalIdx);
1967 OptionalImmIndexMap &OptionalIdx);
1971 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1973 bool parseDimId(
unsigned &Encoding);
1975 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1979 int64_t parseDPPCtrlSel(StringRef Ctrl);
1980 int64_t parseDPPCtrlPerm();
1986 bool IsDPP8 =
false);
1992 AMDGPUOperand::ImmTy
Type);
2000 enum class SDWAInstType :
unsigned {
VOP1 = 0,
VOP2 = 1,
VOPC = 2 };
2003 SDWAInstType BasicInstType,
bool SkipDstVcc =
false,
2004 bool SkipSrcVcc =
false);
2114bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2124 if (!isImmTy(ImmTyNone)) {
2129 if (getModifiers().
Lit != LitModifier::None)
2139 if (type == MVT::f64 || type == MVT::i64) {
2141 AsmParser->hasInv2PiInlineImm());
2144 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2163 APFloat::rmNearestTiesToEven, &Lost);
2170 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2172 AsmParser->hasInv2PiInlineImm());
2177 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2178 AsmParser->hasInv2PiInlineImm());
2182 if (type == MVT::f64 || type == MVT::i64) {
2184 AsmParser->hasInv2PiInlineImm());
2193 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()), type,
2194 AsmParser->hasInv2PiInlineImm());
2198 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2199 AsmParser->hasInv2PiInlineImm());
2202bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2204 if (!isImmTy(ImmTyNone)) {
2209 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2214 if (type == MVT::f64 && hasFPModifiers()) {
2234 if (type == MVT::f64) {
2239 if (type == MVT::i64) {
2252 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2253 : (type == MVT::v2i16) ? MVT::f32
2254 : (type == MVT::v2f32) ? MVT::f32
2257 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2261bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2262 return isRegKind() &&
2263 AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2266bool AMDGPUOperand::isVRegWithInputMods()
const {
2267 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2269 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2270 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2273template <
bool IsFake16>
2274bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2275 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2276 : AMDGPU::VGPR_16_Lo128RegClassID);
2279template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2280 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2281 : AMDGPU::VGPR_16RegClassID);
2284bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2285 if (AsmParser->isVI())
2287 if (AsmParser->isGFX9Plus())
2288 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2292bool AMDGPUOperand::isSDWAFP16Operand()
const {
2293 return isSDWAOperand(MVT::f16);
2296bool AMDGPUOperand::isSDWAFP32Operand()
const {
2297 return isSDWAOperand(MVT::f32);
2300bool AMDGPUOperand::isSDWAInt16Operand()
const {
2301 return isSDWAOperand(MVT::i16);
2304bool AMDGPUOperand::isSDWAInt32Operand()
const {
2305 return isSDWAOperand(MVT::i32);
2308bool AMDGPUOperand::isBoolReg()
const {
2309 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2310 (AsmParser->isWave32() && isSCSrc_b32()));
2314 unsigned Size)
const {
2315 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2330void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
2331 bool ApplyModifiers)
const {
2341 addLiteralImmOperand(Inst,
Imm.Val,
2342 ApplyModifiers & isImmTy(ImmTyNone) &&
2343 Imm.Mods.hasFPModifiers());
2345 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2350void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
2351 bool ApplyModifiers)
const {
2352 const auto &InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2357 if (ApplyModifiers) {
2359 const unsigned Size =
2361 Val = applyInputFPModifiers(Val,
Size);
2365 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2367 bool CanUse64BitLiterals =
2370 MCContext &Ctx = AsmParser->getContext();
2381 if (
Lit == LitModifier::None &&
2383 AsmParser->hasInv2PiInlineImm())) {
2391 bool HasMandatoryLiteral =
2394 if (
Literal.getLoBits(32) != 0 &&
2395 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2396 !HasMandatoryLiteral) {
2397 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2399 "Can't encode literal as exact 64-bit floating-point operand. "
2400 "Low 32-bits will be set to zero");
2401 Val &= 0xffffffff00000000u;
2407 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2413 Lit = LitModifier::Lit64;
2414 }
else if (
Lit == LitModifier::Lit) {
2428 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2430 Lit = LitModifier::Lit64;
2437 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2438 Literal == 0x3fc45f306725feed) {
2478 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2485 if (
Lit != LitModifier::None) {
2516 if (
Lit == LitModifier::None &&
2526 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2534 if (
Lit == LitModifier::None &&
2542 if (!AsmParser->has64BitLiterals()) {
2543 Val =
static_cast<uint64_t>(Val) << 32;
2550 if (
Lit == LitModifier::Lit ||
2552 Val =
static_cast<uint64_t>(Val) << 32;
2556 if (
Lit == LitModifier::Lit)
2583 if (
Lit != LitModifier::None) {
2591void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2597bool AMDGPUOperand::isInlineValue()
const {
2605void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2616 if (Is == IS_VGPR) {
2621 return AMDGPU::VGPR_32RegClassID;
2623 return AMDGPU::VReg_64RegClassID;
2625 return AMDGPU::VReg_96RegClassID;
2627 return AMDGPU::VReg_128RegClassID;
2629 return AMDGPU::VReg_160RegClassID;
2631 return AMDGPU::VReg_192RegClassID;
2633 return AMDGPU::VReg_224RegClassID;
2635 return AMDGPU::VReg_256RegClassID;
2637 return AMDGPU::VReg_288RegClassID;
2639 return AMDGPU::VReg_320RegClassID;
2641 return AMDGPU::VReg_352RegClassID;
2643 return AMDGPU::VReg_384RegClassID;
2645 return AMDGPU::VReg_512RegClassID;
2647 return AMDGPU::VReg_1024RegClassID;
2649 }
else if (Is == IS_TTMP) {
2654 return AMDGPU::TTMP_32RegClassID;
2656 return AMDGPU::TTMP_64RegClassID;
2658 return AMDGPU::TTMP_128RegClassID;
2660 return AMDGPU::TTMP_256RegClassID;
2662 return AMDGPU::TTMP_512RegClassID;
2664 }
else if (Is == IS_SGPR) {
2669 return AMDGPU::SGPR_32RegClassID;
2671 return AMDGPU::SGPR_64RegClassID;
2673 return AMDGPU::SGPR_96RegClassID;
2675 return AMDGPU::SGPR_128RegClassID;
2677 return AMDGPU::SGPR_160RegClassID;
2679 return AMDGPU::SGPR_192RegClassID;
2681 return AMDGPU::SGPR_224RegClassID;
2683 return AMDGPU::SGPR_256RegClassID;
2685 return AMDGPU::SGPR_288RegClassID;
2687 return AMDGPU::SGPR_320RegClassID;
2689 return AMDGPU::SGPR_352RegClassID;
2691 return AMDGPU::SGPR_384RegClassID;
2693 return AMDGPU::SGPR_512RegClassID;
2695 }
else if (Is == IS_AGPR) {
2700 return AMDGPU::AGPR_32RegClassID;
2702 return AMDGPU::AReg_64RegClassID;
2704 return AMDGPU::AReg_96RegClassID;
2706 return AMDGPU::AReg_128RegClassID;
2708 return AMDGPU::AReg_160RegClassID;
2710 return AMDGPU::AReg_192RegClassID;
2712 return AMDGPU::AReg_224RegClassID;
2714 return AMDGPU::AReg_256RegClassID;
2716 return AMDGPU::AReg_288RegClassID;
2718 return AMDGPU::AReg_320RegClassID;
2720 return AMDGPU::AReg_352RegClassID;
2722 return AMDGPU::AReg_384RegClassID;
2724 return AMDGPU::AReg_512RegClassID;
2726 return AMDGPU::AReg_1024RegClassID;
2734 .
Case(
"exec", AMDGPU::EXEC)
2735 .
Case(
"vcc", AMDGPU::VCC)
2736 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2737 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2738 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2739 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2740 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2741 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2742 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2743 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2744 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2745 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2746 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2747 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2748 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2749 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2750 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2751 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2752 .
Case(
"m0", AMDGPU::M0)
2753 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2754 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2755 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2756 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2757 .
Case(
"scc", AMDGPU::SRC_SCC)
2758 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2759 .
Case(
"tba", AMDGPU::TBA)
2760 .
Case(
"tma", AMDGPU::TMA)
2761 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2762 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2763 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2764 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2765 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2766 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2767 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2768 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2769 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2770 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2771 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2772 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2773 .
Case(
"pc", AMDGPU::PC_REG)
2774 .
Case(
"null", AMDGPU::SGPR_NULL)
2778bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2779 SMLoc &EndLoc,
bool RestoreOnFailure) {
2780 auto R = parseRegister();
2784 RegNo =
R->getReg();
2785 StartLoc =
R->getStartLoc();
2786 EndLoc =
R->getEndLoc();
2790bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2792 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2795ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2797 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2798 bool PendingErrors = getParser().hasPendingError();
2799 getParser().clearPendingErrors();
2807bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2808 RegisterKind RegKind,
2810 RegisterKind RegKind1, SMLoc Loc) {
2812 if (RegKind == IS_SGPR) {
2813 unsigned RegIdx = (
Reg - AMDGPU::SGPR0) + RegWidth / 32;
2814 if ((RegIdx == 106 && Reg1 == AMDGPU::VCC_LO) ||
2815 (RegIdx == 107 && Reg1 == AMDGPU::VCC_HI)) {
2821 if (RegKind != RegKind1) {
2822 Error(Loc,
"registers in a list must be of the same kind");
2828 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2833 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2834 Reg = AMDGPU::FLAT_SCR;
2838 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2839 Reg = AMDGPU::XNACK_MASK;
2843 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2848 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2853 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2858 Error(Loc,
"register does not fit in the list");
2864 if (Reg1 !=
Reg + RegWidth / 32) {
2865 Error(Loc,
"registers in a list must have consecutive indices");
2881 {{
"v"}, IS_VGPR}, {{
"s"}, IS_SGPR}, {{
"ttmp"}, IS_TTMP},
2882 {{
"acc"}, IS_AGPR}, {{
"a"}, IS_AGPR},
2886 return Kind == IS_VGPR || Kind == IS_SGPR || Kind == IS_TTMP ||
2892 if (Str.starts_with(
Reg.Name))
2898 return !Str.getAsInteger(10, Num);
2901bool AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2902 const AsmToken &NextToken)
const {
2917 StringRef RegSuffix = Str.substr(
RegName.size());
2918 if (!RegSuffix.
empty()) {
2935bool AMDGPUAsmParser::isRegister() {
2936 return isRegister(
getToken(), peekToken());
2939MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2940 unsigned SubReg,
unsigned RegWidth,
2944 unsigned AlignSize = 1;
2945 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2951 if (RegNum % AlignSize != 0) {
2952 Error(Loc,
"invalid register alignment");
2953 return MCRegister();
2956 unsigned RegIdx = RegNum / AlignSize;
2959 Error(Loc,
"invalid or unsupported register size");
2960 return MCRegister();
2964 const MCRegisterClass &RC =
TRI->getRegClass(RCID);
2965 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2966 Error(Loc,
"register index is out of range");
2967 return AMDGPU::NoRegister;
2970 if (RegKind == IS_VGPR && !
isGFX1250Plus() && RegIdx + RegWidth / 32 > 256) {
2971 Error(Loc,
"register index is out of range");
2972 return MCRegister();
2988bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2990 int64_t RegLo, RegHi;
2994 SMLoc FirstIdxLoc = getLoc();
3001 SecondIdxLoc = getLoc();
3012 Error(FirstIdxLoc,
"invalid register index");
3017 Error(SecondIdxLoc,
"invalid register index");
3021 if (RegLo > RegHi) {
3022 Error(FirstIdxLoc,
"first register index should not exceed second index");
3026 if (RegHi == RegLo) {
3027 StringRef RegSuffix = getTokenStr();
3028 if (RegSuffix ==
".l") {
3029 SubReg = AMDGPU::lo16;
3031 }
else if (RegSuffix ==
".h") {
3032 SubReg = AMDGPU::hi16;
3037 Num =
static_cast<unsigned>(RegLo);
3038 RegWidth = 32 * ((RegHi - RegLo) + 1);
3043MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3046 SmallVectorImpl<AsmToken> &Tokens) {
3052 RegKind = IS_SPECIAL;
3059MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3062 SmallVectorImpl<AsmToken> &Tokens) {
3064 StringRef
RegName = getTokenStr();
3065 auto Loc = getLoc();
3069 Error(Loc,
"invalid register name");
3070 return MCRegister();
3078 unsigned SubReg = NoSubRegister;
3079 bool IsRange =
false;
3080 if (!RegSuffix.
empty()) {
3082 SubReg = AMDGPU::lo16;
3084 SubReg = AMDGPU::hi16;
3088 Error(Loc,
"invalid register index");
3089 return MCRegister();
3095 if (!ParseRegRange(RegNum, RegWidth, SubReg))
3096 return MCRegister();
3100 MCRegister
Reg = getRegularReg(RegKind, RegNum, SubReg, RegWidth, Loc);
3101 const MCRegisterInfo &
TRI = *
getContext().getRegisterInfo();
3102 if (RegKind == IS_SGPR && IsRange
3103 ? (
TRI.isSubRegister(
Reg, VCC_LO) ||
TRI.isSubRegister(
Reg, VCC_HI))
3104 : (
Reg == VCC_LO ||
Reg == VCC_HI)) {
3105 Error(Loc,
"register index is out of range");
3106 return MCRegister();
3112MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3113 unsigned &RegNum,
unsigned &RegWidth,
3114 SmallVectorImpl<AsmToken> &Tokens) {
3116 auto ListLoc = getLoc();
3119 "expected a register or a list of registers")) {
3120 return MCRegister();
3125 auto Loc = getLoc();
3126 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3127 return MCRegister();
3128 if (RegWidth != 32) {
3129 Error(Loc,
"expected a single 32-bit register");
3130 return MCRegister();
3134 RegisterKind NextRegKind;
3136 unsigned NextRegNum, NextRegWidth;
3139 if (!ParseAMDGPURegister(NextRegKind, NextReg, NextRegNum, NextRegWidth,
3141 return MCRegister();
3143 if (NextRegWidth != 32) {
3144 Error(Loc,
"expected a single 32-bit register");
3145 return MCRegister();
3147 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, NextRegKind,
3149 return MCRegister();
3153 "expected a comma or a closing square bracket")) {
3154 return MCRegister();
3158 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3163bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3164 MCRegister &
Reg,
unsigned &RegNum,
3166 SmallVectorImpl<AsmToken> &Tokens) {
3167 auto Loc = getLoc();
3171 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3173 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3175 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3180 assert(Parser.hasPendingError());
3184 if (!subtargetHasRegister(*
TRI,
Reg)) {
3185 if (
Reg == AMDGPU::SGPR_NULL) {
3186 Error(Loc,
"'null' operand is not supported on this GPU");
3189 " register not available on this GPU");
3197bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3198 MCRegister &
Reg,
unsigned &RegNum,
3200 bool RestoreOnFailure ) {
3204 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3205 if (RestoreOnFailure) {
3206 while (!Tokens.
empty()) {
3215std::optional<StringRef>
3216AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3219 return StringRef(
".amdgcn.next_free_vgpr");
3221 return StringRef(
".amdgcn.next_free_sgpr");
3223 return std::nullopt;
3227void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3228 auto SymbolName = getGprCountSymbolName(RegKind);
3229 assert(SymbolName &&
"initializing invalid register kind");
3235bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3236 unsigned DwordRegIndex,
3237 unsigned RegWidth) {
3242 auto SymbolName = getGprCountSymbolName(RegKind);
3247 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3251 return !
Error(getLoc(),
3252 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3256 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3258 if (OldCount <= NewMax)
3264std::unique_ptr<AMDGPUOperand>
3265AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3267 SMLoc StartLoc = Tok.getLoc();
3268 SMLoc EndLoc = Tok.getEndLoc();
3269 RegisterKind RegKind;
3271 unsigned RegNum, RegWidth;
3273 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3277 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3280 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3281 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3288 if (isRegister() || isModifier())
3291 if (
Lit == LitModifier::None) {
3292 if (trySkipId(
"lit"))
3293 Lit = LitModifier::Lit;
3294 else if (trySkipId(
"lit64"))
3295 Lit = LitModifier::Lit64;
3297 if (
Lit != LitModifier::None) {
3300 ParseStatus S = parseImm(
Operands, HasSP3AbsModifier,
Lit);
3309 const auto &NextTok = peekToken();
3312 bool Negate =
false;
3320 AMDGPUOperand::Modifiers Mods;
3328 StringRef Num = getTokenStr();
3331 APFloat RealVal(APFloat::IEEEdouble());
3332 auto roundMode = APFloat::rmNearestTiesToEven;
3333 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3336 RealVal.changeSign();
3339 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(),
3340 S, AMDGPUOperand::ImmTyNone,
true));
3341 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3342 Op.setModifiers(Mods);
3351 if (HasSP3AbsModifier) {
3360 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3363 if (Parser.parseExpression(Expr))
3367 if (Expr->evaluateAsAbsolute(IntVal)) {
3369 return Error(S,
"literal value out of range");
3370 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3371 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3372 Op.setModifiers(Mods);
3374 if (
Lit != LitModifier::None)
3376 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3389 if (
auto R = parseRegister()) {
3399 ParseStatus Res = parseReg(
Operands);
3407bool AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
3408 const AsmToken &NextToken)
const {
3411 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3416bool AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
3417 const AsmToken &NextToken)
const {
3421bool AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
3422 const AsmToken &NextToken)
const {
3423 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3426bool AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
3427 const AsmToken &NextToken)
const {
3428 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3444bool AMDGPUAsmParser::isModifier() {
3447 AsmToken NextToken[2];
3448 peekTokens(NextToken);
3450 return isOperandModifier(Tok, NextToken[0]) ||
3452 isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3453 isOpcodeModifierWithVal(Tok, NextToken[0]);
3478bool AMDGPUAsmParser::parseSP3NegModifier() {
3480 AsmToken NextToken[2];
3481 peekTokens(NextToken);
3484 (isRegister(NextToken[0], NextToken[1]) ||
3502 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3504 SP3Neg = parseSP3NegModifier();
3507 Neg = trySkipId(
"neg");
3509 return Error(Loc,
"expected register or immediate");
3513 Abs = trySkipId(
"abs");
3518 if (trySkipId(
"lit")) {
3519 Lit = LitModifier::Lit;
3522 }
else if (trySkipId(
"lit64")) {
3523 Lit = LitModifier::Lit64;
3526 if (!has64BitLiterals())
3527 return Error(Loc,
"lit64 is not supported on this GPU");
3533 return Error(Loc,
"expected register or immediate");
3542 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3546 if (
Lit != LitModifier::None && !
Operands.back()->isImm())
3547 Error(Loc,
"expected immediate with lit modifier");
3549 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3555 if (
Lit != LitModifier::None &&
3559 AMDGPUOperand::Modifiers Mods;
3560 Mods.Abs = Abs || SP3Abs;
3561 Mods.Neg = Neg || SP3Neg;
3564 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3565 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3567 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3568 Op.setModifiers(Mods);
3576 bool Sext = trySkipId(
"sext");
3577 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3592 AMDGPUOperand::Modifiers Mods;
3595 if (Mods.hasIntModifiers()) {
3596 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3598 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3599 Op.setModifiers(Mods);
3606 return parseRegOrImmWithFPInputMods(
Operands,
false);
3610 return parseRegOrImmWithIntInputMods(
Operands,
false);
3617 if (!trySkipId(
"rsrcidx"))
3623 SMLoc RegLoc = getLoc();
3624 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3632 if (!
Reg->isRsrcReg32())
3633 return Error(RegLoc,
"rsrcidx operand must be a 32-bit SGPR or VGPR");
3643 auto Loc = getLoc();
3644 if (trySkipId(
"off")) {
3646 AMDGPUOperand::CreateImm(
this, 0, Loc, AMDGPUOperand::ImmTyOff,
false));
3653 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3662unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3667 return Match_InvalidOperand;
3669 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3670 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3673 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3675 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3676 return Match_InvalidOperand;
3684 if (tryAnotherVOPDEncoding(Inst))
3685 return Match_InvalidOperand;
3687 return Match_Success;
3691 static const unsigned Variants[] = {
3700ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3701 if (isForcedDPP() && isForcedVOP3()) {
3705 if (getForcedEncodingSize() == 32) {
3710 if (isForcedVOP3()) {
3715 if (isForcedSDWA()) {
3721 if (isForcedDPP()) {
3729StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3730 if (isForcedDPP() && isForcedVOP3())
3733 if (getForcedEncodingSize() == 32)
3749AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3753 case AMDGPU::FLAT_SCR:
3755 case AMDGPU::VCC_LO:
3756 case AMDGPU::VCC_HI:
3763 return MCRegister();
3770bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3771 unsigned OpIdx)
const {
3779 const MCOperand &MO = Inst.
getOperand(OpIdx);
3829unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3835 case AMDGPU::V_LSHLREV_B64_e64:
3836 case AMDGPU::V_LSHLREV_B64_gfx10:
3837 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3838 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3839 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3840 case AMDGPU::V_LSHRREV_B64_e64:
3841 case AMDGPU::V_LSHRREV_B64_gfx10:
3842 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3843 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3844 case AMDGPU::V_ASHRREV_I64_e64:
3845 case AMDGPU::V_ASHRREV_I64_gfx10:
3846 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3847 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3848 case AMDGPU::V_LSHL_B64_e64:
3849 case AMDGPU::V_LSHR_B64_e64:
3850 case AMDGPU::V_ASHR_I64_e64:
3863 bool AddMandatoryLiterals =
false) {
3866 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3870 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3872 return {getNamedOperandIdx(Opcode, OpName::src0X),
3873 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3874 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3875 getNamedOperandIdx(Opcode, OpName::src0Y),
3876 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3877 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3882 return {getNamedOperandIdx(Opcode, OpName::src0),
3883 getNamedOperandIdx(Opcode, OpName::src1),
3884 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3887bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3888 const MCOperand &MO = Inst.
getOperand(OpIdx);
3890 return !isInlineConstant(Inst, OpIdx);
3897 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3908 const unsigned Opcode = Inst.
getOpcode();
3909 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3912 if (!LaneSelOp.
isReg())
3915 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3918bool AMDGPUAsmParser::validateConstantBusLimitations(
3920 const unsigned Opcode = Inst.
getOpcode();
3921 const MCInstrDesc &
Desc = MII.
get(Opcode);
3922 MCRegister LastSGPR;
3923 unsigned ConstantBusUseCount = 0;
3924 unsigned NumLiterals = 0;
3925 unsigned LiteralSize;
3941 SmallDenseSet<MCRegister> SGPRsUsed;
3942 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3944 SGPRsUsed.
insert(SGPRUsed);
3945 ++ConstantBusUseCount;
3950 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3952 for (
int OpIdx : OpIndices) {
3956 const MCOperand &MO = Inst.
getOperand(OpIdx);
3957 if (usesConstantBus(Inst, OpIdx)) {
3966 if (SGPRsUsed.
insert(LastSGPR).second) {
3967 ++ConstantBusUseCount;
3987 if (NumLiterals == 0) {
3990 }
else if (LiteralSize !=
Size) {
3996 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3998 "invalid operand (violates constant bus restrictions)");
4005std::optional<unsigned>
4006AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
4008 const unsigned Opcode = Inst.
getOpcode();
4014 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
4015 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
4024 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1170 ||
4025 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
4026 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
4027 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx13 ||
4028 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250 ||
4029 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx13;
4033 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
4034 int I = getNamedOperandIdx(Opcode, OpName);
4038 int64_t
Imm =
Op.getImm();
4044 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
4045 OpName::vsrc2Y, OpName::imm}) {
4046 int I = getNamedOperandIdx(Opcode, OpName);
4056 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
4057 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
4059 return InvalidCompOprIdx;
4062bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
4069 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand :
Operands) {
4070 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
4071 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
4073 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
4077 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
4078 if (!InvalidCompOprIdx.has_value())
4081 auto CompOprIdx = *InvalidCompOprIdx;
4084 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
4085 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
4088 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
4089 if (CompOprIdx == VOPD::Component::DST) {
4091 Error(Loc,
"dst registers must be distinct");
4093 Error(Loc,
"one dst register must be even and the other odd");
4095 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4096 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4097 " operands must use different VGPR banks");
4105bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4107 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4108 if (!InvalidCompOprIdx.has_value())
4112 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4113 if (InvalidCompOprIdx.has_value()) {
4118 if (*InvalidCompOprIdx == VOPD::Component::DST)
4131bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4132 const unsigned Opcode = Inst.
getOpcode();
4147 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4148 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4149 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4150 int I = getNamedOperandIdx(Opcode, OpName);
4157 return !tryVOPD3(Inst);
4162bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4167 return tryVOPD(Inst);
4168 return tryVOPD3(Inst);
4171bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4176 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4184bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc) {
4192 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4193 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4194 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4199 if ((DMaskIdx == -1 || TFEIdx == -1) &&
4200 hasBVHRayTracingInsts())
4203 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4204 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4209 bool IsPackedD16 =
false;
4212 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4213 IsPackedD16 = D16Idx >= 0;
4215 DataSize = (DataSize + 1) / 2;
4218 if ((VDataSize / 4) == DataSize + TFESize)
4223 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4225 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4227 Error(IDLoc, Twine(
"image data size does not match ") + Modifiers);
4231bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4240 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4242 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4243 AMDGPU::OpName RSrcOpName =
4245 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4246 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4247 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4251 assert(SrsrcIdx > VAddr0Idx);
4254 if (BaseOpcode->
BVH) {
4255 if (IsA16 == BaseOpcode->
A16)
4257 Error(IDLoc,
"image address size does not match a16");
4263 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4264 unsigned ActualAddrSize =
4265 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4267 unsigned ExpectedAddrSize =
4271 if (hasPartialNSAEncoding() &&
4273 int VAddrLastIdx = SrsrcIdx - 1;
4274 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4276 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4279 if (ExpectedAddrSize > 12)
4280 ExpectedAddrSize = 16;
4285 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4289 if (ActualAddrSize == ExpectedAddrSize)
4292 Error(IDLoc,
"image address size does not match dim and a16");
4296bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4303 if (!
Desc.mayLoad() || !
Desc.mayStore())
4306 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4313 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4316bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4323 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4331 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4334bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4348 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4349 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4356bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4363 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4366 if (!BaseOpcode->
MSAA)
4369 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4375 return DimInfo->
MSAA;
4380 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4381 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4382 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4392bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4400 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4403 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4411 Error(getOperandLoc(
Operands, Src0Idx),
"source operand must be a VGPR");
4415bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4420 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4423 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4426 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4434 "source operand must be either a VGPR or an inline constant");
4441bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4446 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4449 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4453 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4455 "inline constants are not allowed for this operand");
4462bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4470 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4471 if (BlgpIdx != -1) {
4472 if (
const MFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4473 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4483 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4485 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4490 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4492 "wrong register tuple size for blgp value " + Twine(BLGP));
4500 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4504 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4508 MCRegister Src2Reg = Src2.
getReg();
4510 if (Src2Reg == DstReg)
4515 .getSizeInBits() <= 128)
4518 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4520 "source 2 operand must not partially overlap with dst");
4527bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4531 case V_DIV_SCALE_F32_gfx6_gfx7:
4532 case V_DIV_SCALE_F32_vi:
4533 case V_DIV_SCALE_F32_gfx10:
4534 case V_DIV_SCALE_F64_gfx6_gfx7:
4535 case V_DIV_SCALE_F64_vi:
4536 case V_DIV_SCALE_F64_gfx10:
4543 {AMDGPU::OpName::src0_modifiers, AMDGPU::OpName::src2_modifiers,
4544 AMDGPU::OpName::src2_modifiers}) {
4555bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4562 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4571bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4577 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4584 case AMDGPU::V_SUBREV_F32_e32:
4585 case AMDGPU::V_SUBREV_F32_e64:
4586 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4587 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4588 case AMDGPU::V_SUBREV_F32_e32_vi:
4589 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4590 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4591 case AMDGPU::V_SUBREV_F32_e64_vi:
4593 case AMDGPU::V_SUBREV_CO_U32_e32:
4594 case AMDGPU::V_SUBREV_CO_U32_e64:
4595 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4596 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4598 case AMDGPU::V_SUBBREV_U32_e32:
4599 case AMDGPU::V_SUBBREV_U32_e64:
4600 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4601 case AMDGPU::V_SUBBREV_U32_e32_vi:
4602 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4603 case AMDGPU::V_SUBBREV_U32_e64_vi:
4605 case AMDGPU::V_SUBREV_U32_e32:
4606 case AMDGPU::V_SUBREV_U32_e64:
4607 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4608 case AMDGPU::V_SUBREV_U32_e32_vi:
4609 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4610 case AMDGPU::V_SUBREV_U32_e64_vi:
4612 case AMDGPU::V_SUBREV_F16_e32:
4613 case AMDGPU::V_SUBREV_F16_e64:
4614 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4615 case AMDGPU::V_SUBREV_F16_e32_vi:
4616 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4617 case AMDGPU::V_SUBREV_F16_e64_vi:
4619 case AMDGPU::V_SUBREV_U16_e32:
4620 case AMDGPU::V_SUBREV_U16_e64:
4621 case AMDGPU::V_SUBREV_U16_e32_vi:
4622 case AMDGPU::V_SUBREV_U16_e64_vi:
4624 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4625 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4626 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4628 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4629 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4631 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4632 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4634 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4635 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4637 case AMDGPU::V_LSHRREV_B32_e32:
4638 case AMDGPU::V_LSHRREV_B32_e64:
4639 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4640 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4641 case AMDGPU::V_LSHRREV_B32_e32_vi:
4642 case AMDGPU::V_LSHRREV_B32_e64_vi:
4643 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4644 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4646 case AMDGPU::V_ASHRREV_I32_e32:
4647 case AMDGPU::V_ASHRREV_I32_e64:
4648 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4649 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4650 case AMDGPU::V_ASHRREV_I32_e32_vi:
4651 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4652 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4653 case AMDGPU::V_ASHRREV_I32_e64_vi:
4655 case AMDGPU::V_LSHLREV_B32_e32:
4656 case AMDGPU::V_LSHLREV_B32_e64:
4657 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4658 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4659 case AMDGPU::V_LSHLREV_B32_e32_vi:
4660 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4661 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4662 case AMDGPU::V_LSHLREV_B32_e64_vi:
4664 case AMDGPU::V_LSHLREV_B16_e32:
4665 case AMDGPU::V_LSHLREV_B16_e64:
4666 case AMDGPU::V_LSHLREV_B16_e32_vi:
4667 case AMDGPU::V_LSHLREV_B16_e64_vi:
4668 case AMDGPU::V_LSHLREV_B16_gfx10:
4670 case AMDGPU::V_LSHRREV_B16_e32:
4671 case AMDGPU::V_LSHRREV_B16_e64:
4672 case AMDGPU::V_LSHRREV_B16_e32_vi:
4673 case AMDGPU::V_LSHRREV_B16_e64_vi:
4674 case AMDGPU::V_LSHRREV_B16_gfx10:
4676 case AMDGPU::V_ASHRREV_I16_e32:
4677 case AMDGPU::V_ASHRREV_I16_e64:
4678 case AMDGPU::V_ASHRREV_I16_e32_vi:
4679 case AMDGPU::V_ASHRREV_I16_e64_vi:
4680 case AMDGPU::V_ASHRREV_I16_gfx10:
4682 case AMDGPU::V_LSHLREV_B64_e64:
4683 case AMDGPU::V_LSHLREV_B64_gfx10:
4684 case AMDGPU::V_LSHLREV_B64_vi:
4686 case AMDGPU::V_LSHRREV_B64_e64:
4687 case AMDGPU::V_LSHRREV_B64_gfx10:
4688 case AMDGPU::V_LSHRREV_B64_vi:
4690 case AMDGPU::V_ASHRREV_I64_e64:
4691 case AMDGPU::V_ASHRREV_I64_gfx10:
4692 case AMDGPU::V_ASHRREV_I64_vi:
4694 case AMDGPU::V_PK_LSHLREV_B16:
4695 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4696 case AMDGPU::V_PK_LSHLREV_B16_vi:
4698 case AMDGPU::V_PK_LSHRREV_B16:
4699 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4700 case AMDGPU::V_PK_LSHRREV_B16_vi:
4701 case AMDGPU::V_PK_ASHRREV_I16:
4702 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4703 case AMDGPU::V_PK_ASHRREV_I16_vi:
4710bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4712 const unsigned Opcode = Inst.
getOpcode();
4721 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4722 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4726 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4730 "lds_direct is not supported on this GPU");
4736 "lds_direct cannot be used with this instruction");
4740 if (SrcName != OpName::src0) {
4742 "lds_direct may be used as src0 only");
4752 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4753 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4754 if (
Op.isFlatOffset())
4755 return Op.getStartLoc();
4760bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4763 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4768 return validateFlatOffset(Inst,
Operands);
4771 return validateSMEMOffset(Inst,
Operands);
4776 const unsigned OffsetSize = 24;
4777 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4779 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4780 "-bit unsigned offset for buffer ops");
4784 const unsigned OffsetSize = 16;
4785 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4787 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4794bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4800 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4804 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4806 "flat offset modifier is not supported on this GPU");
4813 bool AllowNegative =
4815 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4817 Twine(
"expected a ") +
4818 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4819 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4828 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4829 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4830 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4831 return Op.getStartLoc();
4836bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4845 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4861 ?
"expected a 23-bit unsigned offset for buffer ops"
4862 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4863 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4864 :
"expected a 21-bit signed offset");
4869bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4872 const MCInstrDesc &
Desc = MII.
get(Opcode);
4876 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4877 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4879 const int OpIndices[] = {Src0Idx, Src1Idx};
4881 unsigned NumExprs = 0;
4882 unsigned NumLiterals = 0;
4885 for (
int OpIdx : OpIndices) {
4889 const MCOperand &MO = Inst.
getOperand(OpIdx);
4893 std::optional<int64_t>
Imm;
4896 }
else if (MO.
isExpr()) {
4905 if (!
Imm.has_value()) {
4907 }
else if (!isInlineConstant(Inst, OpIdx)) {
4911 if (NumLiterals == 0 || LiteralValue !=
Value) {
4919 if (NumLiterals + NumExprs <= 1)
4923 "only one unique literal operand is allowed");
4927bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4930 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4938 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4939 if (OpSelIdx != -1) {
4943 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4944 if (OpSelHiIdx != -1) {
4953 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4963 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4964 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4965 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4966 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4968 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4969 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4975 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4977 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4987 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4988 if (Src2Idx != -1) {
4989 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4999bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
5000 if (!hasTrue16Insts())
5002 const MCRegisterInfo *MRI = getMRI();
5004 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
5010 if (OpSelOpValue == 0)
5012 unsigned OpCount = 0;
5013 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
5014 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
5015 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
5022 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
5023 if (OpSelOpIsHi != VGPRSuffixIsHi)
5032bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
5033 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
5045 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
5056 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
5057 AMDGPU::OpName::src1_modifiers,
5058 AMDGPU::OpName::src2_modifiers};
5060 for (
unsigned i = 0; i < 3; ++i) {
5070bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5073 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5074 if (DppCtrlIdx >= 0) {
5081 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl,
Operands);
5082 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5083 :
"DP ALU dpp only supports row_newbcast");
5088 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5089 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5092 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5094 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5098 "invalid operand for instruction");
5103 "src1 immediate operand invalid for instruction");
5113bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5114 return (
Reg == AMDGPU::VCC && isWave64()) ||
5115 (
Reg == AMDGPU::VCC_LO && isWave32());
5119bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5122 const MCInstrDesc &
Desc = MII.
get(Opcode);
5123 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5130 std::optional<unsigned> LiteralOpIdx;
5133 for (
int OpIdx : OpIndices) {
5137 const MCOperand &MO = Inst.
getOperand(OpIdx);
5143 std::optional<int64_t>
Imm;
5149 bool IsAnotherLiteral =
false;
5150 bool IsForcedLit = findMCOperand(
Operands, OpIdx).isForcedLit();
5151 bool IsForcedLit64 = findMCOperand(
Operands, OpIdx).isForcedLit64();
5152 if (!
Imm.has_value()) {
5154 IsAnotherLiteral =
true;
5155 }
else if (IsForcedLit || IsForcedLit64 || !isInlineConstant(Inst, OpIdx)) {
5160 HasMandatoryLiteral);
5172 (IsForcedLit64 && !HasMandatoryLiteral)) &&
5173 (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5175 "invalid operand for instruction");
5180 if (!IsForcedFP64 && (IsForcedLit64 || !IsValid32Op) &&
5181 OpIdx != getNamedOperandIdx(Opcode, OpName::src0)) {
5183 "invalid operand for instruction");
5188 if (IsValid32Op && !IsForcedFP64 && !IsForcedLit64) {
5189 Value =
static_cast<uint32_t
>(
5197 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5198 !getFeatureBits()[FeatureVOP3Literal]) {
5200 "literal operands are not supported");
5204 if (LiteralOpIdx && IsAnotherLiteral) {
5206 getOperandLoc(
Operands, *LiteralOpIdx)),
5207 "only one unique literal operand is allowed");
5211 if (IsAnotherLiteral)
5212 LiteralOpIdx = OpIdx;
5221 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), Name);
5235bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5241 ? AMDGPU::OpName::data0
5242 : AMDGPU::OpName::vdata;
5244 const MCRegisterInfo *MRI = getMRI();
5245 int DstAreg =
IsAGPROperand(Inst, AMDGPU::OpName::vdst, MRI);
5249 int Data2Areg =
IsAGPROperand(Inst, AMDGPU::OpName::data1, MRI);
5250 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5254 auto FB = getFeatureBits();
5255 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5256 if (DataAreg < 0 || DstAreg < 0)
5258 return DstAreg == DataAreg;
5261 return DstAreg < 1 && DataAreg < 1;
5264bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5265 auto FB = getFeatureBits();
5266 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5270 const MCRegisterInfo *MRI = getMRI();
5273 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5276 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5280 case AMDGPU::DS_LOAD_TR6_B96:
5281 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5285 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5286 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5290 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5291 if (VAddrIdx != -1) {
5294 if ((
Sub - AMDGPU::VGPR0) & 1)
5299 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5300 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5305 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5306 const MCRegisterClass &AGPR32 = MRI->
getRegClass(AMDGPU::AGPR_32RegClassID);
5326 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
5327 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
5329 return Op.getStartLoc();
5334bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5337 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5340 SMLoc BLGPLoc = getBLGPLoc(
Operands);
5343 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5344 auto FB = getFeatureBits();
5345 bool UsesNeg =
false;
5346 if (FB[AMDGPU::FeatureGFX940Insts]) {
5348 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5349 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5350 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5351 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5356 if (IsNeg == UsesNeg)
5359 Error(BLGPLoc, UsesNeg ?
"invalid modifier: blgp is not supported"
5360 :
"invalid modifier: neg is not supported");
5365bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5371 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5372 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5373 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5374 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5377 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5380 if (
Reg == AMDGPU::SGPR_NULL)
5383 Error(getOperandLoc(
Operands, Src0Idx),
"src0 must be null");
5387bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5392 return validateGWS(Inst,
Operands);
5397 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5402 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS,
Operands);
5403 Error(S,
"gds modifier is not supported on this GPU");
5411bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5413 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5417 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5418 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5421 const MCRegisterInfo *MRI = getMRI();
5422 const MCRegisterClass &VGPR32 = MRI->
getRegClass(AMDGPU::VGPR_32RegClassID);
5424 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5427 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5429 Error(getOperandLoc(
Operands, Data0Pos),
"vgpr must be even aligned");
5436bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5440 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::cpol);
5448 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5451 Error(S,
"scale_offset is not supported on this GPU");
5454 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5457 Error(S,
"nv is not supported on this GPU");
5462 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5465 Error(S,
"scale_offset is not supported for this instruction");
5469 return validateTHAndScopeBits(Inst,
Operands, CPol);
5473 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5474 Error(S,
"cache policy is not supported for SMRD instructions");
5478 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5485 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5489 "scc modifier is not supported for this instruction on this GPU");
5500 :
"instruction must use glc");
5505 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5508 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5510 :
"instruction must not use glc");
5518bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5520 const unsigned CPol) {
5525 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5532 return PrintError(
"th:TH_ATOMIC_RETURN requires a destination operand");
5537 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5545 return PrintError(
"invalid th value for SMEM instruction");
5552 return PrintError(
"scope and th combination is not valid");
5558 return PrintError(
"invalid th value for atomic instructions");
5561 return PrintError(
"invalid th value for store instructions");
5564 return PrintError(
"invalid th value for load instructions");
5570bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5574 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE,
Operands);
5576 Error(Loc,
"TFE modifier has no meaning for store instructions");
5584bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5590 int AFmtIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
5594 int BFmtIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
5597 auto validateFmt = [&](
unsigned Fmt, AMDGPU::OpName SrcOp) ->
bool {
5598 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5607 "wrong register tuple size for " +
5612 if (!validateFmt(AFmt, AMDGPU::OpName::src0) ||
5613 !validateFmt(BFmt, AMDGPU::OpName::src1))
5617 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
5618 if (AScaleIdx == -1)
5622 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
5626 "invalid matrix and scale format combination");
5633bool AMDGPUAsmParser::validateMonitorSleep(
const MCInst &Inst,
5636 if (
Opc != AMDGPU::S_MONITOR_SLEEP_gfx12 ||
5637 !getSTI().
hasFeature(AMDGPU::FeatureNoSleepForever))
5640 int ImmIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::simm16);
5643 "sleep forever is unsuported on the target");
5650bool AMDGPUAsmParser::validateClusterBarrierIsFirst(
5653 if (
Opc != AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM_gfx12 &&
5654 Opc != AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM_gfx13)
5657 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
5664 "s_barrier_signal_isfirst does not support user_cluster_barrier_id (-3)");
5668bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5670 if (!validateLdsDirect(Inst,
Operands))
5672 if (!validateTrue16OpSel(Inst)) {
5674 "op_sel operand conflicts with 16-bit operand suffix");
5677 if (!validateSOPLiteral(Inst,
Operands))
5679 if (!validateVOPLiteral(Inst,
Operands)) {
5682 if (!validateConstantBusLimitations(Inst,
Operands)) {
5685 if (!validateVOPD(Inst,
Operands)) {
5688 if (!validateIntClampSupported(Inst)) {
5690 "integer clamping is not supported on this GPU");
5693 if (!validateOpSel(Inst)) {
5695 "invalid op_sel operand");
5698 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5700 "invalid neg_lo operand");
5703 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5705 "invalid neg_hi operand");
5708 if (!validateDPP(Inst,
Operands)) {
5712 if (!validateMIMGD16(Inst)) {
5714 "d16 modifier is not supported on this GPU");
5717 if (!validateMIMGDim(Inst,
Operands)) {
5718 Error(IDLoc,
"missing dim operand");
5721 if (!validateTensorR128(Inst)) {
5723 "instruction must set modifier r128=0");
5726 if (!validateMIMGMSAA(Inst)) {
5728 "invalid dim; must be MSAA type");
5731 if (!validateMIMGDataSize(Inst, IDLoc)) {
5734 if (!validateMIMGAddrSize(Inst, IDLoc))
5736 if (!validateMIMGAtomicDMask(Inst)) {
5738 "invalid atomic image dmask");
5741 if (!validateMIMGGatherDMask(Inst)) {
5743 "invalid image_gather dmask: only one bit must be set");
5746 if (!validateMovrels(Inst,
Operands)) {
5749 if (!validateOffset(Inst,
Operands)) {
5752 if (!validateMAIAccWrite(Inst,
Operands)) {
5755 if (!validateMAISrc2(Inst,
Operands)) {
5758 if (!validateMFMA(Inst,
Operands)) {
5761 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5765 if (!validateAGPRLdSt(Inst)) {
5768 getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5769 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5770 :
"invalid register class: agpr loads and stores not supported on "
5774 if (!validateVGPRAlign(Inst)) {
5775 Error(IDLoc,
"invalid register class: vgpr tuples must be 64 bit aligned");
5782 if (!validateBLGP(Inst,
Operands)) {
5786 if (!validateDivScale(Inst)) {
5787 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5790 if (!validateWaitCnt(Inst,
Operands)) {
5793 if (!validateTFE(Inst,
Operands)) {
5796 if (!validateWMMA(Inst,
Operands)) {
5799 if (!validateMonitorSleep(Inst,
Operands)) {
5802 if (!validateClusterBarrierIsFirst(Inst,
Operands)) {
5811 unsigned VariantID = 0);
5815 unsigned VariantID);
5817bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5822bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5823 const FeatureBitset &FBS,
5824 ArrayRef<unsigned> Variants) {
5825 for (
auto Variant : Variants) {
5833bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5835 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5838 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5843 getParser().clearPendingErrors();
5847 StringRef VariantName = getMatchedVariantName();
5848 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5849 return Error(IDLoc, Twine(VariantName,
5850 " variant of this instruction is not supported"));
5854 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5855 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5857 FeatureBitset FeaturesWS32 = getFeatureBits();
5858 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5859 .
flip(AMDGPU::FeatureWavefrontSize32);
5860 FeatureBitset AvailableFeaturesWS32 =
5861 ComputeAvailableFeatures(FeaturesWS32);
5863 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5864 return Error(IDLoc,
"instruction requires wavesize=32");
5868 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5869 return Error(IDLoc,
"instruction not supported on this GPU (" +
5870 getSTI().
getCPU() +
")" +
": " + Mnemo);
5875 return Error(IDLoc,
"invalid instruction" + Suggestion);
5881 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5882 if (
Op.isToken() && InvalidOprIdx > 1) {
5883 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5884 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5889bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5893 bool MatchingInlineAsm) {
5896 unsigned Result = Match_Success;
5901 auto atLeastAsSpecific = [](
unsigned New,
unsigned Cur) {
5902 auto rank = [](
unsigned M) {
5903 return M == Match_MnemonicFail ? 1
5904 :
M == Match_InvalidOperand ? 2
5905 :
M == Match_MissingFeature ? 3
5908 return rank(New) >= rank(Cur);
5911 for (
auto Variant : getMatchedVariants()) {
5914 MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm, Variant);
5915 if (R == Match_Success || atLeastAsSpecific(R, Result)) {
5919 if (R == Match_Success)
5923 if (Result == Match_Success) {
5924 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5927 emitTargetDirective();
5928 Out.emitInstruction(Inst, getSTI());
5935 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5942 case Match_MissingFeature:
5946 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5948 case Match_InvalidOperand: {
5949 SMLoc ErrorLoc = IDLoc;
5950 if (ErrorInfo != ~0ULL) {
5951 if (ErrorInfo >=
Operands.size()) {
5952 return Error(IDLoc,
"too few operands for instruction");
5954 ErrorLoc = ((AMDGPUOperand &)*
Operands[ErrorInfo]).getStartLoc();
5955 if (ErrorLoc == SMLoc())
5959 return Error(ErrorLoc,
"invalid VOPDY instruction");
5961 return Error(ErrorLoc,
"invalid operand for instruction");
5964 case Match_MnemonicFail:
5970bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5975 if (getParser().parseAbsoluteExpression(Tmp)) {
5978 Ret =
static_cast<uint32_t
>(Tmp);
5982bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5983 if (!getSTI().getTargetTriple().isAMDGCN())
5984 return TokError(
"directive only supported for amdgcn architecture");
5986 std::string TargetIDDirective;
5987 SMLoc TargetStart = getTok().getLoc();
5988 if (getParser().parseEscapedString(TargetIDDirective))
5991 std::optional<AMDGPU::TargetID> MaybeParsed =
5994 return getParser().Error(TargetStart,
5995 "malformed target id '" + TargetIDDirective +
"'");
5998 const Triple &
TT = getSTI().getTargetTriple();
6004 return getParser().Error(
6005 TargetStart,
"target id '" + TargetIDDirective +
6006 "' specifies a processor that is not valid for "
6008 TT.getArchName() +
"'");
6011 const std::optional<AMDGPU::TargetID> &CurrentTargetID =
6012 getTargetStreamer().getTargetID();
6015 const Triple &STITriple = getSTI().getTargetTriple();
6016 if (!DirectiveTriple.isCompatibleWith(STITriple)) {
6017 return getParser().Error(
6018 TargetStart,
".amdgcn_target " + Twine(ParsedTargetID.
toString()) +
6019 " is incompatible with " +
6020 Twine(CurrentTargetID->toString()));
6024 StringRef DirectiveProcessor =
6027 if (DirectiveISA != ISA) {
6028 return getParser().Error(TargetStart,
6029 ".amdgcn_target directive processor " +
6030 Twine(DirectiveProcessor) +
6031 " does not match the specified processor " +
6032 Twine(getSTI().
getCPU()));
6038 CurrentTargetID->getXnackSetting())) {
6040 ".amdgcn_target directive has conflicting xnack settings");
6044 CurrentTargetID->getSramEccSetting())) {
6046 ".amdgcn_target directive has conflicting sramecc settings");
6052 getTargetStreamer().getTargetID()->setXnackSetting(
6054 getTargetStreamer().getTargetID()->setSramEccSetting(
6060bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
6064bool AMDGPUAsmParser::calculateGPRBlocks(
6065 const FeatureBitset &Features,
const MCExpr *VCCUsed,
6066 const MCExpr *FlatScrUsed,
bool XNACKUsed,
6067 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
6068 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
6069 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
6074 const MCExpr *
NumSGPRs = NextFreeSGPR;
6075 int64_t EvaluatedSGPRs;
6077 if (
ISA.Major >= 10)
6082 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
ISA.Major >= 8 &&
6083 !Features.
test(FeatureSGPRInitBug) &&
6084 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
6085 return OutOfRangeError(SGPRRange);
6087 const MCExpr *ExtraSGPRs =
6091 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
6092 (
ISA.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
6093 static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
6094 return OutOfRangeError(SGPRRange);
6096 if (Features.
test(FeatureSGPRInitBug))
6103 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
6104 unsigned Granule) ->
const MCExpr * {
6108 const MCExpr *AlignToGPR =
6110 const MCExpr *DivGPR =
6116 VGPRBlocks = GetNumGPRBlocks(
6125bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
6126 if (!getSTI().getTargetTriple().isAMDGCN())
6127 return TokError(
"directive only supported for amdgcn architecture");
6130 return TokError(
"directive only supported for amdhsa OS");
6132 StringRef KernelName;
6133 if (getParser().parseIdentifier(KernelName))
6140 AMDGPU::MCKernelDescriptor KD =
6150 const MCExpr *NextFreeVGPR = ZeroExpr;
6152 const MCExpr *NamedBarCnt = ZeroExpr;
6157 const MCExpr *NextFreeSGPR = ZeroExpr;
6160 unsigned ImpliedUserSGPRCount = 0;
6164 std::optional<unsigned> ExplicitUserSGPRCount;
6165 const MCExpr *ReserveVCC = OneExpr;
6166 const MCExpr *ReserveFlatScr = OneExpr;
6167 std::optional<bool> EnableWavefrontSize32;
6174 SMRange IDRange = getTok().getLocRange();
6175 if (!parseId(ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
6178 if (ID ==
".end_amdhsa_kernel")
6181 if (!Seen.
insert(ID).second)
6182 return TokError(
".amdhsa_ directives cannot be repeated");
6184 SMLoc ValStart = getLoc();
6185 const MCExpr *ExprVal;
6186 if (getParser().parseExpression(ExprVal))
6188 SMLoc ValEnd = getLoc();
6189 SMRange ValRange = SMRange(ValStart, ValEnd);
6193 bool EvaluatableExpr;
6194 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
6196 return OutOfRangeError(ValRange);
6200#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6201 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6202 return OutOfRangeError(RANGE); \
6203 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6208#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6210 return Error(IDRange.Start, "directive should have resolvable expression", \
6213 if (ID ==
".amdhsa_group_segment_fixed_size") {
6216 return OutOfRangeError(ValRange);
6218 }
else if (ID ==
".amdhsa_private_segment_fixed_size") {
6221 return OutOfRangeError(ValRange);
6223 }
else if (ID ==
".amdhsa_kernarg_size") {
6225 return OutOfRangeError(ValRange);
6227 }
else if (ID ==
".amdhsa_user_sgpr_count") {
6229 ExplicitUserSGPRCount = Val;
6230 }
else if (ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6234 "directive is not supported with architected flat scratch",
6237 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6240 ImpliedUserSGPRCount += 4;
6241 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6244 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6247 return OutOfRangeError(ValRange);
6251 ImpliedUserSGPRCount += Val;
6252 PreloadLength = Val;
6254 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6257 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6260 return OutOfRangeError(ValRange);
6264 PreloadOffset = Val;
6265 }
else if (ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6268 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6271 ImpliedUserSGPRCount += 2;
6272 }
else if (ID ==
".amdhsa_user_sgpr_queue_ptr") {
6275 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6278 ImpliedUserSGPRCount += 2;
6279 }
else if (ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6282 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6285 ImpliedUserSGPRCount += 2;
6286 }
else if (ID ==
".amdhsa_user_sgpr_dispatch_id") {
6289 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6292 ImpliedUserSGPRCount += 2;
6293 }
else if (ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6296 "directive is not supported with architected flat scratch",
6300 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6303 ImpliedUserSGPRCount += 2;
6304 }
else if (ID ==
".amdhsa_user_sgpr_private_segment_size") {
6307 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6310 ImpliedUserSGPRCount += 1;
6311 }
else if (ID ==
".amdhsa_wavefront_size32") {
6314 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6315 EnableWavefrontSize32 = Val;
6317 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6319 }
else if (ID ==
".amdhsa_uses_dynamic_stack") {
6321 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6323 }
else if (ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6326 "directive is not supported with architected flat scratch",
6329 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6331 }
else if (ID ==
".amdhsa_enable_private_segment") {
6335 "directive is not supported without architected flat scratch",
6338 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6340 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6342 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6344 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6346 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6348 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6350 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6352 }
else if (ID ==
".amdhsa_system_sgpr_workgroup_info") {
6354 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6356 }
else if (ID ==
".amdhsa_system_vgpr_workitem_id") {
6358 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6360 }
else if (ID ==
".amdhsa_next_free_vgpr") {
6361 VGPRRange = ValRange;
6362 NextFreeVGPR = ExprVal;
6363 }
else if (ID ==
".amdhsa_next_free_sgpr") {
6364 SGPRRange = ValRange;
6365 NextFreeSGPR = ExprVal;
6366 }
else if (ID ==
".amdhsa_accum_offset") {
6368 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6369 AccumOffset = ExprVal;
6370 }
else if (ID ==
".amdhsa_named_barrier_count") {
6372 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6373 NamedBarCnt = ExprVal;
6374 }
else if (ID ==
".amdhsa_reserve_vcc") {
6376 return OutOfRangeError(ValRange);
6377 ReserveVCC = ExprVal;
6378 }
else if (ID ==
".amdhsa_reserve_flat_scratch") {
6380 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6383 "directive is not supported with architected flat scratch",
6386 return OutOfRangeError(ValRange);
6387 ReserveFlatScr = ExprVal;
6388 }
else if (ID ==
".amdhsa_reserve_xnack_mask") {
6390 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6392 return OutOfRangeError(ValRange);
6393 bool XnackOn = getTargetStreamer().getTargetID()->isXnackOnOrAny();
6394 if (Val != XnackOn) {
6395 return getParser().Error(
6397 ".amdhsa_reserve_xnack_mask does not match target id", IDRange);
6399 }
else if (ID ==
".amdhsa_float_round_mode_32") {
6401 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6403 }
else if (ID ==
".amdhsa_float_round_mode_16_64") {
6405 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6407 }
else if (ID ==
".amdhsa_float_denorm_mode_32") {
6409 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6411 }
else if (ID ==
".amdhsa_float_denorm_mode_16_64") {
6413 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6415 }
else if (ID ==
".amdhsa_dx10_clamp") {
6416 if (!getSTI().
hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6417 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6420 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6422 }
else if (ID ==
".amdhsa_ieee_mode") {
6423 if (!getSTI().
hasFeature(AMDGPU::FeatureDX10ClampAndIEEEMode))
6424 return Error(IDRange.
Start,
"directive unsupported on gfx1170+",
6427 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6429 }
else if (ID ==
".amdhsa_fp16_overflow") {
6431 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6433 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6435 }
else if (ID ==
".amdhsa_tg_split") {
6437 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6440 }
else if (ID ==
".amdhsa_workgroup_processor_mode") {
6443 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6445 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6447 }
else if (ID ==
".amdhsa_memory_ordered") {
6449 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6451 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6453 }
else if (ID ==
".amdhsa_forward_progress") {
6455 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6457 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6459 }
else if (ID ==
".amdhsa_shared_vgpr_count") {
6461 if (
ISA.Major < 10 ||
ISA.Major >= 12)
6462 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6464 SharedVGPRCount = Val;
6466 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6468 }
else if (ID ==
".amdhsa_inst_pref_size") {
6470 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6471 if (
ISA.Major == 11) {
6473 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6477 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6480 }
else if (ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6483 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6485 }
else if (ID ==
".amdhsa_exception_fp_denorm_src") {
6487 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6489 }
else if (ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6492 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6494 }
else if (ID ==
".amdhsa_exception_fp_ieee_overflow") {
6496 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6498 }
else if (ID ==
".amdhsa_exception_fp_ieee_underflow") {
6500 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6502 }
else if (ID ==
".amdhsa_exception_fp_ieee_inexact") {
6504 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6506 }
else if (ID ==
".amdhsa_exception_int_div_zero") {
6508 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6510 }
else if (ID ==
".amdhsa_round_robin_scheduling") {
6512 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6514 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6517 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6520#undef PARSE_BITS_ENTRY
6523 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6524 return TokError(
".amdhsa_next_free_vgpr directive is required");
6526 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6527 return TokError(
".amdhsa_next_free_sgpr directive is required");
6529 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6531 return TokError(
"too many user SGPRs enabled, found " +
6532 Twine(UserSGPRCount) +
", but only " +
6538 if (PreloadLength) {
6544 const MCExpr *VGPRBlocks;
6545 const MCExpr *SGPRBlocks;
6546 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6547 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6548 EnableWavefrontSize32, NextFreeVGPR, VGPRRange,
6549 NextFreeSGPR, SGPRRange, VGPRBlocks, SGPRBlocks))
6552 int64_t EvaluatedVGPRBlocks;
6553 bool VGPRBlocksEvaluatable =
6554 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6555 if (VGPRBlocksEvaluatable &&
6557 static_cast<uint64_t>(EvaluatedVGPRBlocks))) {
6558 return OutOfRangeError(VGPRRange);
6562 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6563 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6565 int64_t EvaluatedSGPRBlocks;
6566 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6568 static_cast<uint64_t>(EvaluatedSGPRBlocks)))
6569 return OutOfRangeError(SGPRRange);
6572 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6573 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6575 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6576 return TokError(
"amdgpu_user_sgpr_count smaller than implied by "
6577 "enabled user SGPRs");
6583 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6584 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6589 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6590 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6595 return TokError(
"Kernarg size should be resolvable");
6597 if (PreloadLength && kernarg_size &&
6598 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6599 return TokError(
"Kernarg preload length + offset is larger than the "
6600 "kernarg segment size");
6603 if (!Seen.
contains(
".amdhsa_accum_offset"))
6604 return TokError(
".amdhsa_accum_offset directive is required");
6605 int64_t EvaluatedAccum;
6606 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6607 uint64_t UEvaluatedAccum = EvaluatedAccum;
6608 if (AccumEvaluatable &&
6609 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6610 return TokError(
"accum_offset should be in range [4..256] in "
6613 int64_t EvaluatedNumVGPR;
6614 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6618 return TokError(
"accum_offset exceeds total VGPR allocation");
6624 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6625 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6631 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6632 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6635 if (
ISA.Major >= 10 &&
ISA.Major < 12) {
6637 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6638 return TokError(
"shared_vgpr_count directive not valid on "
6639 "wavefront size 32");
6642 if (VGPRBlocksEvaluatable &&
6643 (SharedVGPRCount * 2 +
static_cast<uint64_t>(EvaluatedVGPRBlocks) >
6645 return TokError(
"shared_vgpr_count*2 + "
6646 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6651 emitTargetDirective();
6652 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6653 NextFreeVGPR, NextFreeSGPR,
6654 ReserveVCC, ReserveFlatScr);
6658bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6660 if (ParseAsAbsoluteExpression(
Version))
6663 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6664 emitTargetDirective();
6668bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef ID,
6669 AMDGPUMCKernelCodeT &
C) {
6672 if (ID ==
"max_scratch_backing_memory_byte_size") {
6673 Parser.eatToEndOfStatement();
6677 SmallString<40> ErrStr;
6678 raw_svector_ostream Err(ErrStr);
6679 if (!
C.ParseKernelCodeT(ID, getParser(), Err)) {
6680 return TokError(Err.
str());
6684 if (ID ==
"enable_wavefront_size32") {
6687 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6689 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6692 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6696 if (ID ==
"wavefront_size") {
6697 if (
C.wavefront_size == 5) {
6699 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6701 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6702 }
else if (
C.wavefront_size == 6) {
6704 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6711bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6712 AMDGPUMCKernelCodeT KernelCode;
6722 if (!parseId(ID,
"expected value identifier or .end_amd_kernel_code_t"))
6725 if (ID ==
".end_amd_kernel_code_t")
6728 if (ParseAMDKernelCodeTValue(ID, KernelCode))
6733 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6738bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6739 StringRef KernelName;
6740 if (!parseId(KernelName,
"expected symbol name"))
6743 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6750bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6751 if (!getSTI().getTargetTriple().isAMDGCN()) {
6752 return Error(getLoc(),
6753 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6757 StringRef TargetIDDirective = getLexer().getTok().getStringContents();
6759 std::optional<AMDGPU::TargetID> MaybeParsed =
6762 return Error(getParser().getTok().getLoc(),
6763 "malformed target id '" + TargetIDDirective +
"'");
6766 const Triple &
TT = getSTI().getTargetTriple();
6772 return Error(getParser().getTok().getLoc(),
6773 "target id '" + TargetIDDirective +
6774 "' specifies a processor that is not valid for subarch '" +
6775 TT.getArchName() +
"'");
6778 const std::optional<AMDGPU::TargetID> &CurrentTargetID =
6779 getTargetStreamer().getTargetID();
6782 const Triple &STITriple = getSTI().getTargetTriple();
6783 if (!DirectiveTriple.isCompatibleWith(STITriple)) {
6784 return Error(getParser().getTok().getLoc(),
6785 ".amd_amdgpu_isa " + Twine(ParsedTargetID.
toString()) +
6786 " is incompatible with " +
6787 Twine(CurrentTargetID->toString()));
6791 StringRef DirectiveProcessor =
6794 if (DirectiveISA != ISA) {
6795 return Error(getParser().getTok().getLoc(),
6796 ".amd_amdgpu_isa directive processor " +
6797 Twine(DirectiveProcessor) +
6798 " does not match the specified processor " +
6799 Twine(getSTI().
getCPU()));
6802 getTargetStreamer().EmitISAVersion();
6808bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6811 std::string HSAMetadataString;
6816 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6817 return Error(getLoc(),
"invalid HSA metadata");
6824bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6825 const char *AssemblerDirectiveEnd,
6826 std::string &CollectString) {
6828 raw_string_ostream CollectStream(CollectString);
6830 getLexer().setSkipSpace(
false);
6832 bool FoundEnd =
false;
6835 CollectStream << getTokenStr();
6839 if (trySkipId(AssemblerDirectiveEnd)) {
6844 CollectStream << Parser.parseStringToEndOfStatement()
6845 <<
getContext().getAsmInfo().getSeparatorString();
6847 Parser.eatToEndOfStatement();
6850 getLexer().setSkipSpace(
true);
6853 return TokError(Twine(
"expected directive ") +
6854 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6861bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6867 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6868 if (!PALMetadata->setFromString(
String))
6869 return Error(getLoc(),
"invalid PAL metadata");
6874bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6877 Twine(
" directive is "
6878 "not available on non-amdpal OSes"))
6882 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6883 PALMetadata->setLegacy();
6886 if (ParseAsAbsoluteExpression(
Key)) {
6887 return TokError(Twine(
"invalid value in ") +
6891 return TokError(Twine(
"expected an even number of values in ") +
6894 if (ParseAsAbsoluteExpression(
Value)) {
6895 return TokError(Twine(
"invalid value in ") +
6898 PALMetadata->setRegister(
Key,
Value);
6907bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6908 if (getParser().checkForValidSection())
6912 SMLoc NameLoc = getLoc();
6913 if (getParser().parseIdentifier(Name))
6914 return TokError(
"expected identifier in directive");
6917 if (getParser().parseComma())
6923 SMLoc SizeLoc = getLoc();
6924 if (getParser().parseAbsoluteExpression(
Size))
6927 return Error(SizeLoc,
"size must be non-negative");
6928 if (
Size > LocalMemorySize)
6929 return Error(SizeLoc,
"size is too large");
6933 SMLoc AlignLoc = getLoc();
6934 if (getParser().parseAbsoluteExpression(Alignment))
6937 return Error(AlignLoc,
"alignment must be a power of two");
6942 if (Alignment >= 1u << 31)
6943 return Error(AlignLoc,
"alignment is too large");
6949 Symbol->redefineIfPossible();
6950 if (!
Symbol->isUndefined())
6951 return Error(NameLoc,
"invalid symbol redefinition");
6953 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6957bool AMDGPUAsmParser::ParseDirectiveAMDGPUInfo() {
6958 if (getParser().checkForValidSection())
6962 if (getParser().parseIdentifier(FuncName))
6963 return TokError(
"expected symbol name after .amdgpu_info");
6966 AMDGPU::InfoSectionData ParsedInfoData;
6967 AMDGPU::FuncInfo FI;
6969 bool HasScalarAttrs =
false;
6976 SMLoc IDLoc = getLoc();
6977 if (!parseId(ID,
"expected directive or .end_amdgpu_info"))
6980 if (ID ==
".end_amdgpu_info")
6988 return Error(IDLoc,
"unknown .amdgpu_info directive '" + ID +
"'");
6990 if (Dir ==
"flags") {
6992 if (getParser().parseAbsoluteExpression(Val))
6995 FI.
UsesVCC = !!(
Flags & AMDGPU::FuncInfoFlags::FUNC_USES_VCC);
6997 !!(
Flags & AMDGPU::FuncInfoFlags::FUNC_USES_FLAT_SCRATCH);
6999 HasScalarAttrs =
true;
7000 }
else if (Dir ==
"num_sgpr") {
7002 if (getParser().parseAbsoluteExpression(Val))
7004 FI.
NumSGPR =
static_cast<uint32_t
>(Val);
7005 HasScalarAttrs =
true;
7006 }
else if (Dir ==
"num_vgpr") {
7008 if (getParser().parseAbsoluteExpression(Val))
7011 HasScalarAttrs =
true;
7012 }
else if (Dir ==
"num_agpr") {
7014 if (getParser().parseAbsoluteExpression(Val))
7017 HasScalarAttrs =
true;
7018 }
else if (Dir ==
"private_segment_size") {
7020 if (getParser().parseAbsoluteExpression(Val))
7023 HasScalarAttrs =
true;
7024 }
else if (Dir ==
"use") {
7026 if (getParser().parseIdentifier(ResName))
7027 return TokError(
"expected resource symbol for .amdgpu_use");
7028 ParsedInfoData.
Uses.push_back(
7029 {FuncSym,
getContext().getOrCreateSymbol(ResName)});
7030 }
else if (Dir ==
"call") {
7032 if (getParser().parseIdentifier(DstName))
7033 return TokError(
"expected callee symbol for .amdgpu_call");
7034 ParsedInfoData.
Calls.push_back(
7035 {FuncSym,
getContext().getOrCreateSymbol(DstName)});
7036 }
else if (Dir ==
"indirect_call") {
7038 if (getParser().parseEscapedString(TypeId))
7039 return TokError(
"expected type ID string for .amdgpu_indirect_call");
7040 ParsedInfoData.
IndirectCalls.push_back({FuncSym, std::move(TypeId)});
7041 }
else if (Dir ==
"typeid") {
7043 if (getParser().parseEscapedString(TypeId))
7044 return TokError(
"expected type ID string for .amdgpu_typeid");
7045 ParsedInfoData.
TypeIds.push_back({FuncSym, std::move(TypeId)});
7047 return Error(IDLoc,
"unknown .amdgpu_info directive '" + ID +
"'");
7052 ParsedInfoData.
Funcs.push_back(std::move(FI));
7054 AMDGPU::InfoSectionData &
Data = InfoData ? *InfoData : InfoData.emplace();
7055 for (AMDGPU::FuncInfo &Func : ParsedInfoData.
Funcs)
7056 Data.Funcs.push_back(std::move(Func));
7057 for (std::pair<MCSymbol *, MCSymbol *> &Use : ParsedInfoData.
Uses)
7058 Data.Uses.push_back(Use);
7059 for (std::pair<MCSymbol *, MCSymbol *> &
Call : ParsedInfoData.
Calls)
7061 for (std::pair<MCSymbol *, std::string> &
IndirectCall :
7064 for (std::pair<MCSymbol *, std::string> &TypeId : ParsedInfoData.
TypeIds)
7065 Data.TypeIds.push_back(std::move(TypeId));
7070void AMDGPUAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
7077void AMDGPUAsmParser::checkKernelPrologues() {
7078 if (getFeatureBits()[AMDGPU::FeatureRequiresInitialUnclausedVmem]) {
7079 static const unsigned Required[] = {S_MOV_B64_gfx12, V_NOP_e32_gfx12,
7080 GLOBAL_PREFETCH_B8_SADDR_gfx1250};
7081 for (
auto [Sym, Loc,
Offset] : OpcodeStreamSymbols) {
7082 if (!AMDHSAKernelSymbols.
contains(Sym))
7084 ArrayRef<unsigned> Prologue =
ArrayRef(OpcodeStream).drop_front(
Offset);
7085 if (!Prologue.
empty() && Prologue.
front() == S_SETREG_IMM32_B32_gfx12)
7089 "' does not begin with the required prologue "
7090 "sequence: s_mov_b64 followed by v_nop and "
7091 "global_prefetch_b8");
7095 OpcodeStream.
clear();
7096 OpcodeStreamSymbols.clear();
7097 AMDHSAKernelSymbols.
clear();
7100void AMDGPUAsmParser::onEndOfFile() {
7101 emitTargetDirective();
7102 checkKernelPrologues();
7104 getTargetStreamer().emitAMDGPUInfo(*InfoData);
7107bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
7108 StringRef IDVal = DirectiveID.
getString();
7111 if (IDVal ==
".amdhsa_kernel")
7112 return ParseDirectiveAMDHSAKernel();
7114 if (IDVal ==
".amdhsa_code_object_version")
7115 return ParseDirectiveAMDHSACodeObjectVersion();
7119 return ParseDirectiveHSAMetadata();
7121 if (IDVal ==
".amd_kernel_code_t")
7122 return ParseDirectiveAMDKernelCodeT();
7124 if (IDVal ==
".amdgpu_hsa_kernel")
7125 return ParseDirectiveAMDGPUHsaKernel();
7127 if (IDVal ==
".amd_amdgpu_isa")
7128 return ParseDirectiveISAVersion();
7132 Twine(
" directive is "
7133 "not available on non-amdhsa OSes"))
7138 if (IDVal ==
".amdgcn_target")
7139 return ParseDirectiveAMDGCNTarget();
7141 if (IDVal ==
".amdgpu_lds")
7142 return ParseDirectiveAMDGPULDS();
7144 if (IDVal ==
".amdgpu_info")
7145 return ParseDirectiveAMDGPUInfo();
7148 return ParseDirectivePALMetadataBegin();
7151 return ParseDirectivePALMetadata();
7156bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &MRI,
7163 return hasSGPR104_SGPR105();
7166 case SRC_SHARED_BASE_LO:
7167 case SRC_SHARED_BASE:
7168 case SRC_SHARED_LIMIT_LO:
7169 case SRC_SHARED_LIMIT:
7171 case SRC_PRIVATE_BASE_LO:
7172 case SRC_PRIVATE_BASE:
7173 case SRC_PRIVATE_LIMIT_LO:
7174 case SRC_PRIVATE_LIMIT:
7176 case SRC_FLAT_SCRATCH_BASE_LO:
7177 case SRC_FLAT_SCRATCH_BASE_HI:
7178 return hasGloballyAddressableScratch();
7179 case SRC_POPS_EXITING_WAVE_ID:
7192 getTargetStreamer().getTargetID()->isXnackSupported();
7222 return hasSGPR102_SGPR103();
7230 ParseStatus Res = parseVOPD(
Operands);
7235 Res = MatchOperandParserImpl(
Operands, Mnemonic);
7247 SMLoc LBraceLoc = getLoc();
7252 auto Loc = getLoc();
7255 Error(Loc,
"expected a register");
7259 RBraceLoc = getLoc();
7264 "expected a comma or a closing square bracket"))
7268 if (
Operands.size() - Prefix > 1) {
7270 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
7271 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
7280StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
7282 setForcedEncodingSize(0);
7283 setForcedDPP(
false);
7284 setForcedSDWA(
false);
7286 if (
Name.consume_back(
"_e64_dpp")) {
7288 setForcedEncodingSize(64);
7291 if (
Name.consume_back(
"_e64")) {
7292 setForcedEncodingSize(64);
7295 if (
Name.consume_back(
"_e32")) {
7296 setForcedEncodingSize(32);
7299 if (
Name.consume_back(
"_dpp")) {
7303 if (
Name.consume_back(
"_sdwa")) {
7304 setForcedSDWA(
true);
7312 unsigned VariantID);
7318 Name = parseMnemonicSuffix(Name);
7324 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
7326 bool IsMIMG = Name.starts_with(
"image_");
7329 OperandMode
Mode = OperandMode_Default;
7331 Mode = OperandMode_NSA;
7335 checkUnsupportedInstruction(Name, NameLoc);
7336 if (!Parser.hasPendingError()) {
7339 :
"not a valid operand.";
7359ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
7362 if (!trySkipId(Name))
7365 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, S));
7369ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
7378ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
7380 std::function<
bool(int64_t &)> ConvertResult) {
7384 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
7388 if (ConvertResult && !ConvertResult(
Value)) {
7389 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
7392 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
7396ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
7398 bool (*ConvertResult)(int64_t &)) {
7407 const unsigned MaxSize = 4;
7411 for (
int I = 0;; ++
I) {
7413 SMLoc Loc = getLoc();
7417 if (
Op != 0 &&
Op != 1)
7418 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7425 if (
I + 1 == MaxSize)
7426 return Error(getLoc(),
"expected a closing square bracket");
7432 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7436ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7438 AMDGPUOperand::ImmTy ImmTy,
7439 bool IgnoreNegative) {
7443 if (trySkipId(Name)) {
7445 }
else if (trySkipId(
"no", Name)) {
7454 return Error(S,
"r128 modifier is not supported on this GPU");
7455 if (Name ==
"a16" && !
hasA16())
7456 return Error(S,
"a16 modifier is not supported on this GPU");
7458 if (Bit == 0 && Name ==
"gds") {
7461 return Error(S,
"nogds is not allowed");
7464 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7465 ImmTy = AMDGPUOperand::ImmTyR128A16;
7467 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7471unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7472 bool &Disabling)
const {
7473 Disabling =
Id.consume_front(
"no");
7476 return StringSwitch<unsigned>(Id)
7483 return StringSwitch<unsigned>(Id)
7493 SMLoc StringLoc = getLoc();
7495 int64_t CPolVal = 0;
7515 ResScope = parseScope(
Operands, Scope);
7528 if (trySkipId(
"nv")) {
7532 }
else if (trySkipId(
"no",
"nv")) {
7539 if (trySkipId(
"scale_offset")) {
7543 }
else if (trySkipId(
"no",
"scale_offset")) {
7556 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7557 AMDGPUOperand::ImmTyCPol));
7562 SMLoc OpLoc = getLoc();
7563 unsigned Enabled = 0, Seen = 0;
7567 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7574 return Error(S,
"dlc modifier is not supported on this GPU");
7577 return Error(S,
"scc modifier is not supported on this GPU");
7580 return Error(S,
"duplicate cache policy modifier");
7592 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7601 ParseStatus Res = parseStringOrIntWithPrefix(
7602 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7616 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7620 if (
Value ==
"TH_DEFAULT")
7622 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7623 Value ==
"TH_LOAD_NT_WB") {
7624 return Error(StringLoc,
"invalid th value");
7625 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7627 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7629 }
else if (
Value.consume_front(
"TH_STORE_")) {
7632 return Error(StringLoc,
"invalid th value");
7635 if (
Value ==
"BYPASS")
7640 TH |= StringSwitch<int64_t>(
Value)
7650 .Default(0xffffffff);
7652 TH |= StringSwitch<int64_t>(
Value)
7663 .Default(0xffffffff);
7666 if (TH == 0xffffffff)
7667 return Error(StringLoc,
"invalid th value");
7674 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7675 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7676 std::optional<unsigned> InsertAt = std::nullopt) {
7677 auto i = OptionalIdx.find(ImmT);
7678 if (i != OptionalIdx.end()) {
7679 unsigned Idx = i->second;
7680 const AMDGPUOperand &
Op =
7681 static_cast<const AMDGPUOperand &
>(*
Operands[Idx]);
7685 Op.addImmOperands(Inst, 1);
7687 if (InsertAt.has_value())
7694ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7700 StringLoc = getLoc();
7705ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7711 SMLoc StringLoc = getLoc();
7715 Value = getTokenStr();
7719 if (
Value == Ids[IntVal])
7724 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7725 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7730ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7732 AMDGPUOperand::ImmTy
Type) {
7736 ParseStatus Res = parseStringOrIntWithPrefix(
Operands, Name, Ids, IntVal);
7738 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7747bool AMDGPUAsmParser::tryParseFmt(
const char *Pref, int64_t MaxVal,
7750 SMLoc Loc = getLoc();
7752 auto Res = parseIntWithPrefix(Pref, Val);
7758 if (Val < 0 || Val > MaxVal) {
7759 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7768 AMDGPUOperand::ImmTy ImmTy) {
7769 const char *Pref =
"index_key";
7771 SMLoc Loc = getLoc();
7772 auto Res = parseIntWithPrefix(Pref, ImmVal);
7776 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7777 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7778 (ImmVal < 0 || ImmVal > 1))
7779 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7781 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7782 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7784 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7789 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7793 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7797 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7802 AMDGPUOperand::ImmTy
Type) {
7808 return tryParseMatrixFMT(
Operands,
"matrix_a_fmt",
7809 AMDGPUOperand::ImmTyMatrixAFMT);
7813 return tryParseMatrixFMT(
Operands,
"matrix_b_fmt",
7814 AMDGPUOperand::ImmTyMatrixBFMT);
7819 AMDGPUOperand::ImmTy
Type) {
7825 return tryParseMatrixScale(
Operands,
"matrix_a_scale",
7826 AMDGPUOperand::ImmTyMatrixAScale);
7830 return tryParseMatrixScale(
Operands,
"matrix_b_scale",
7831 AMDGPUOperand::ImmTyMatrixBScale);
7836 AMDGPUOperand::ImmTy
Type) {
7842 return tryParseMatrixScaleFmt(
Operands,
"matrix_a_scale_fmt",
7843 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7847 return tryParseMatrixScaleFmt(
Operands,
"matrix_b_scale_fmt",
7848 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7853ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7854 using namespace llvm::AMDGPU::MTBUFFormat;
7860 for (
int I = 0;
I < 2; ++
I) {
7861 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7864 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7869 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7875 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7878 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7879 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7885ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7886 using namespace llvm::AMDGPU::MTBUFFormat;
7890 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7893 if (Fmt == UFMT_UNDEF)
7900bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt,
7901 StringRef FormatStr, SMLoc Loc) {
7902 using namespace llvm::AMDGPU::MTBUFFormat;
7906 if (
Format != DFMT_UNDEF) {
7912 if (
Format != NFMT_UNDEF) {
7917 Error(Loc,
"unsupported format");
7921ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7924 using namespace llvm::AMDGPU::MTBUFFormat;
7928 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7933 SMLoc Loc = getLoc();
7934 if (!parseId(Str,
"expected a format string") ||
7935 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7937 if (Dfmt == DFMT_UNDEF)
7938 return Error(Loc,
"duplicate numeric format");
7939 if (Nfmt == NFMT_UNDEF)
7940 return Error(Loc,
"duplicate data format");
7943 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7944 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7948 if (Ufmt == UFMT_UNDEF)
7949 return Error(FormatLoc,
"unsupported format");
7958ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7961 using namespace llvm::AMDGPU::MTBUFFormat;
7964 if (Id == UFMT_UNDEF)
7968 return Error(Loc,
"unified format is not supported on this GPU");
7974ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7975 using namespace llvm::AMDGPU::MTBUFFormat;
7976 SMLoc Loc = getLoc();
7981 return Error(Loc,
"out of range format");
7986ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7987 using namespace llvm::AMDGPU::MTBUFFormat;
7993 StringRef FormatStr;
7994 SMLoc Loc = getLoc();
7995 if (!parseId(FormatStr,
"expected a format string"))
7998 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
8000 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
8010 return parseNumericFormat(
Format);
8014 using namespace llvm::AMDGPU::MTBUFFormat;
8018 SMLoc Loc = getLoc();
8028 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
8047 Res = parseSymbolicOrNumericFormat(
Format);
8052 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
8053 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
8060 return Error(getLoc(),
"duplicate format");
8066 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
8068 Res = parseIntWithPrefix(
"inst_offset",
Operands,
8069 AMDGPUOperand::ImmTyInstOffset);
8076 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
8078 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
8084 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
8087 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
8097 OptionalImmIndexMap OptionalIdx;
8099 unsigned OperandIdx[4];
8100 unsigned EnMask = 0;
8103 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
8104 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8109 OperandIdx[SrcIdx] = Inst.
size();
8110 Op.addRegOperands(Inst, 1);
8117 OperandIdx[SrcIdx] = Inst.
size();
8123 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
8124 Op.addImmOperands(Inst, 1);
8128 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
8132 OptionalIdx[
Op.getImmTy()] = i;
8138 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
8145 for (
auto i = 0; i < SrcIdx; ++i) {
8147 EnMask |= Compr ? (0x3 << i * 2) : (0x1 << i);
8153 AMDGPUOperand::ImmTyExpCompr);
8163 int64_t CntVal,
bool Saturate,
8169 IntVal =
encode(ISA, IntVal, CntVal);
8170 if (CntVal !=
decode(ISA, IntVal)) {
8172 IntVal =
encode(ISA, IntVal, -1);
8180bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
8182 SMLoc CntLoc = getLoc();
8183 StringRef CntName = getTokenStr();
8190 SMLoc ValLoc = getLoc();
8197 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
8199 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
8201 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
8204 Error(CntLoc,
"invalid counter name " + CntName);
8209 Error(ValLoc,
"too large value for " + CntName);
8218 Error(getLoc(),
"expected a counter name");
8232 if (!parseCnt(Waitcnt))
8240 Operands.push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
8244bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
8245 SMLoc FieldLoc = getLoc();
8246 StringRef FieldName = getTokenStr();
8251 SMLoc ValueLoc = getLoc();
8258 if (FieldName ==
"instid0") {
8260 }
else if (FieldName ==
"instskip") {
8262 }
else if (FieldName ==
"instid1") {
8265 Error(FieldLoc,
"invalid field name " + FieldName);
8284 .Case(
"VALU_DEP_1", 1)
8285 .Case(
"VALU_DEP_2", 2)
8286 .Case(
"VALU_DEP_3", 3)
8287 .Case(
"VALU_DEP_4", 4)
8288 .Case(
"TRANS32_DEP_1", 5)
8289 .Case(
"TRANS32_DEP_2", 6)
8290 .Case(
"TRANS32_DEP_3", 7)
8291 .Case(
"FMA_ACCUM_CYCLE_1", 8)
8292 .Case(
"SALU_CYCLE_1", 9)
8293 .Case(
"SALU_CYCLE_2", 10)
8294 .Case(
"SALU_CYCLE_3", 11)
8302 Delay |=
Value << Shift;
8312 if (!parseDelay(Delay))
8320 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
8324bool AMDGPUOperand::isSWaitCnt()
const {
return isImm(); }
8326bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
8332void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
8333 StringRef DepCtrName) {
8336 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
8339 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
8342 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
8345 Error(Loc, Twine(
"invalid value for ", DepCtrName));
8352bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
8354 using namespace llvm::AMDGPU::DepCtr;
8356 SMLoc DepCtrLoc = getLoc();
8357 StringRef DepCtrName = getTokenStr();
8367 unsigned PrevOprMask = UsedOprMask;
8368 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
8371 depCtrError(DepCtrLoc, CntVal, DepCtrName);
8380 Error(getLoc(),
"expected a counter name");
8385 int64_t CntValMask = PrevOprMask ^ UsedOprMask;
8386 DepCtr = (DepCtr & ~CntValMask) | CntVal;
8391 using namespace llvm::AMDGPU::DepCtr;
8394 SMLoc Loc = getLoc();
8397 unsigned UsedOprMask = 0;
8399 if (!parseDepCtr(DepCtr, UsedOprMask))
8407 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8411bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8417ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8419 OperandInfoTy &Width) {
8420 using namespace llvm::AMDGPU::Hwreg;
8426 HwReg.Loc = getLoc();
8429 HwReg.IsSymbolic =
true;
8431 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8439 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8449 Width.Loc = getLoc();
8458 using namespace llvm::AMDGPU::Hwreg;
8461 SMLoc Loc = getLoc();
8463 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8465 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8466 HwregOffset::Default);
8467 struct : StructuredOpField {
8468 using StructuredOpField::StructuredOpField;
8469 bool validate(AMDGPUAsmParser &Parser)
const override {
8471 return Error(Parser,
"only values from 1 to 32 are legal");
8474 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8475 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8478 Res = parseHwregFunc(HwReg,
Offset, Width);
8481 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8483 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8487 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8494 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8496 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8500bool AMDGPUOperand::isHwreg()
const {
return isImmTy(ImmTyHwreg); }
8506bool AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &
Msg, OperandInfoTy &
Op,
8507 OperandInfoTy &Stream) {
8508 using namespace llvm::AMDGPU::SendMsg;
8513 Msg.IsSymbolic =
true;
8520 Op.IsDefined =
true;
8526 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8531 Stream.IsDefined =
true;
8532 Stream.Loc = getLoc();
8541bool AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &
Msg,
8542 const OperandInfoTy &
Op,
8543 const OperandInfoTy &Stream) {
8544 using namespace llvm::AMDGPU::SendMsg;
8553 Error(
Msg.Loc,
"specified message id is not supported on this GPU");
8558 Error(
Msg.Loc,
"invalid message id");
8564 Error(
Op.Loc,
"message does not support operations");
8566 Error(
Msg.Loc,
"missing message operation");
8572 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8574 Error(
Op.Loc,
"invalid operation id");
8579 Error(Stream.Loc,
"message operation does not support streams");
8583 Error(Stream.Loc,
"invalid message stream id");
8590 using namespace llvm::AMDGPU::SendMsg;
8593 SMLoc Loc = getLoc();
8597 OperandInfoTy
Op(OP_NONE_);
8598 OperandInfoTy Stream(STREAM_ID_NONE_);
8599 if (parseSendMsgBody(
Msg,
Op, Stream) && validateSendMsg(
Msg,
Op, Stream)) {
8604 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8606 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8612 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8616bool AMDGPUOperand::isSendMsg()
const {
return isImmTy(ImmTySendMsg); }
8619 using namespace llvm::AMDGPU::WaitEvent;
8621 SMLoc Loc = getLoc();
8624 StructuredOpField DontWaitExportReady(
"dont_wait_export_ready",
"bit value",
8626 StructuredOpField ExportReady(
"export_ready",
"bit value", 1, 0);
8628 StructuredOpField *TargetBitfield =
8629 isGFX11() ? &DontWaitExportReady : &ExportReady;
8631 ParseStatus Res = parseStructuredOpFields({TargetBitfield});
8635 if (!validateStructuredOpFields({TargetBitfield}))
8637 ImmVal = TargetBitfield->Val;
8644 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8646 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc,
8647 AMDGPUOperand::ImmTyWaitEvent));
8651bool AMDGPUOperand::isWaitEvent()
const {
return isImmTy(ImmTyWaitEvent); }
8664 int Slot = StringSwitch<int>(Str)
8671 return Error(S,
"invalid interpolation slot");
8674 AMDGPUOperand::CreateImm(
this, Slot, S, AMDGPUOperand::ImmTyInterpSlot));
8685 if (!Str.starts_with(
"attr"))
8686 return Error(S,
"invalid interpolation attribute");
8688 StringRef Chan = Str.take_back(2);
8689 int AttrChan = StringSwitch<int>(Chan)
8696 return Error(S,
"invalid or missing interpolation attribute channel");
8698 Str = Str.drop_back(2).drop_front(4);
8701 if (Str.getAsInteger(10, Attr))
8702 return Error(S,
"invalid or missing interpolation attribute number");
8705 return Error(S,
"out of bounds interpolation attribute number");
8710 AMDGPUOperand::CreateImm(
this, Attr, S, AMDGPUOperand::ImmTyInterpAttr));
8711 Operands.push_back(AMDGPUOperand::CreateImm(
8712 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8721 using namespace llvm::AMDGPU::Exp;
8731 return Error(S, (Id == ET_INVALID)
8732 ?
"invalid exp target"
8733 :
"exp target is not supported on this GPU");
8736 AMDGPUOperand::CreateImm(
this, Id, S, AMDGPUOperand::ImmTyExpTgt));
8744bool AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8748bool AMDGPUAsmParser::isId(
const StringRef Id)
const {
8753 return getTokenKind() ==
Kind;
8756StringRef AMDGPUAsmParser::getId()
const {
8760bool AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8768bool AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8770 StringRef Tok = getTokenStr();
8779bool AMDGPUAsmParser::trySkipId(
const StringRef Id,
8781 if (isId(Id) && peekToken().is(Kind)) {
8790 if (isToken(Kind)) {
8798 const StringRef ErrMsg) {
8799 if (!trySkipToken(Kind)) {
8800 Error(getLoc(), ErrMsg);
8806bool AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8810 if (Parser.parseExpression(Expr))
8813 if (Expr->evaluateAsAbsolute(
Imm))
8816 if (Expected.empty()) {
8817 Error(S,
"expected absolute expression");
8820 Twine(
"expected ", Expected) + Twine(
" or an absolute expression"));
8829 if (Parser.parseExpression(Expr))
8833 if (Expr->evaluateAsAbsolute(IntVal)) {
8834 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8836 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8841bool AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8843 Val =
getToken().getStringContents();
8847 Error(getLoc(), ErrMsg);
8851bool AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8853 Val = getTokenStr();
8857 if (!ErrMsg.
empty())
8858 Error(getLoc(), ErrMsg);
8862AsmToken AMDGPUAsmParser::getToken()
const {
return Parser.getTok(); }
8864AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8867 : getLexer().peekTok(ShouldSkipSpace);
8871 auto TokCount = getLexer().peekTokens(Tokens);
8873 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8878 return getLexer().getKind();
8881SMLoc AMDGPUAsmParser::getLoc()
const {
return getToken().getLoc(); }
8883StringRef AMDGPUAsmParser::getTokenStr()
const {
8887void AMDGPUAsmParser::lex() { Parser.Lex(); }
8889const AMDGPUOperand &
8891 int MCOpIdx)
const {
8893 const AMDGPUOperand &TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8894 if (TargetOp.getMCOpIdx() == MCOpIdx)
8901 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
8905SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8910 int MCOpIdx)
const {
8911 return findMCOperand(
Operands, MCOpIdx).getStartLoc();
8914SMLoc AMDGPUAsmParser::getOperandLoc(
8915 std::function<
bool(
const AMDGPUOperand &)>
Test,
8917 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
8918 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8920 return Op.getStartLoc();
8925SMLoc AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8927 auto Test = [=](
const AMDGPUOperand &
Op) {
return Op.isImmTy(
Type); };
8942 StringRef
Id = getTokenStr();
8943 SMLoc IdLoc = getLoc();
8949 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8950 if (
I == Fields.
end())
8951 return Error(IdLoc,
"unknown field");
8952 if ((*I)->IsDefined)
8953 return Error(IdLoc,
"duplicate field");
8956 (*I)->Loc = getLoc();
8959 (*I)->IsDefined =
true;
8966bool AMDGPUAsmParser::validateStructuredOpFields(
8968 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8969 return F->validate(*
this);
8979 const unsigned XorMask) {
8986bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8987 const unsigned MaxVal,
8988 const Twine &ErrMsg, SMLoc &Loc) {
9004bool AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t *
Op,
9005 const unsigned MinVal,
9006 const unsigned MaxVal,
9007 const StringRef ErrMsg) {
9009 for (
unsigned i = 0; i < OpNum; ++i) {
9010 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
9017bool AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
9018 using namespace llvm::AMDGPU::Swizzle;
9021 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
9022 "expected a 2-bit lane id")) {
9032bool AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
9033 using namespace llvm::AMDGPU::Swizzle;
9039 if (!parseSwizzleOperand(GroupSize, 2, 32,
9040 "group size must be in the interval [2,32]", Loc)) {
9044 Error(Loc,
"group size must be a power of two");
9047 if (parseSwizzleOperand(LaneIdx, 0, GroupSize - 1,
9048 "lane id must be in the interval [0,group size - 1]",
9056bool AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
9057 using namespace llvm::AMDGPU::Swizzle;
9062 if (!parseSwizzleOperand(GroupSize, 2, 32,
9063 "group size must be in the interval [2,32]", Loc)) {
9067 Error(Loc,
"group size must be a power of two");
9075bool AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
9076 using namespace llvm::AMDGPU::Swizzle;
9081 if (!parseSwizzleOperand(GroupSize, 1, 16,
9082 "group size must be in the interval [1,16]", Loc)) {
9086 Error(Loc,
"group size must be a power of two");
9094bool AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
9095 using namespace llvm::AMDGPU::Swizzle;
9102 SMLoc StrLoc = getLoc();
9103 if (!parseString(Ctl)) {
9106 if (Ctl.
size() != BITMASK_WIDTH) {
9107 Error(StrLoc,
"expected a 5-character mask");
9111 unsigned AndMask = 0;
9112 unsigned OrMask = 0;
9113 unsigned XorMask = 0;
9115 for (
size_t i = 0; i < Ctl.
size(); ++i) {
9119 Error(StrLoc,
"invalid mask");
9140bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
9141 using namespace llvm::AMDGPU::Swizzle;
9144 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
9150 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
9151 "FFT swizzle must be in the interval [0," +
9152 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
9160bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
9161 using namespace llvm::AMDGPU::Swizzle;
9164 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
9171 if (!parseSwizzleOperand(
Direction, 0, 1,
9172 "direction must be 0 (left) or 1 (right)", Loc))
9176 if (!parseSwizzleOperand(
9177 RotateSize, 0, ROTATE_MAX_SIZE,
9178 "number of threads to rotate must be in the interval [0," +
9179 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
9184 (RotateSize << ROTATE_SIZE_SHIFT);
9188bool AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
9190 SMLoc OffsetLoc = getLoc();
9196 Error(OffsetLoc,
"expected a 16-bit offset");
9202bool AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
9203 using namespace llvm::AMDGPU::Swizzle;
9207 SMLoc ModeLoc = getLoc();
9210 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
9211 Ok = parseSwizzleQuadPerm(
Imm);
9212 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
9213 Ok = parseSwizzleBitmaskPerm(
Imm);
9214 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
9215 Ok = parseSwizzleBroadcast(
Imm);
9216 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
9217 Ok = parseSwizzleSwap(
Imm);
9218 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
9219 Ok = parseSwizzleReverse(
Imm);
9220 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
9221 Ok = parseSwizzleFFT(
Imm);
9222 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
9223 Ok = parseSwizzleRotate(
Imm);
9225 Error(ModeLoc,
"expected a swizzle mode");
9228 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
9238 if (trySkipId(
"offset")) {
9242 if (trySkipId(
"swizzle")) {
9243 Ok = parseSwizzleMacro(
Imm);
9245 Ok = parseSwizzleOffset(
Imm);
9250 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
9257bool AMDGPUOperand::isSwizzle()
const {
return isImmTy(ImmTySwizzle); }
9263int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
9265 using namespace llvm::AMDGPU::VGPRIndexMode;
9277 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
9278 if (trySkipId(IdSymbolic[ModeId])) {
9286 ?
"expected a VGPR index mode or a closing parenthesis"
9287 :
"expected a VGPR index mode");
9292 Error(S,
"duplicate VGPR index mode");
9300 "expected a comma or a closing parenthesis"))
9309 using namespace llvm::AMDGPU::VGPRIndexMode;
9315 Imm = parseGPRIdxMacro();
9319 if (getParser().parseAbsoluteExpression(
Imm))
9322 return Error(S,
"invalid immediate: only 4-bit values are legal");
9326 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
9330bool AMDGPUOperand::isGPRIdxMode()
const {
return isImmTy(ImmTyGprIdxMode); }
9341 if (isRegister() || isModifier())
9348 assert(Opr.isImm() || Opr.isExpr());
9349 SMLoc Loc = Opr.getStartLoc();
9353 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
9354 Error(Loc,
"expected an absolute expression or a label");
9355 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
9356 Error(Loc,
"expected a 16-bit signed jump offset");
9376 OptionalImmIndexMap OptionalIdx;
9377 unsigned FirstOperandIdx = 1;
9378 bool IsAtomicReturn =
false;
9384 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
9385 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
9389 Op.addRegOperands(Inst, 1);
9393 if (IsAtomicReturn && i == FirstOperandIdx)
9394 Op.addRegOperands(Inst, 1);
9399 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9400 Op.addImmOperands(Inst, 1);
9412 OptionalIdx[
Op.getImmTy()] = i;
9416 AMDGPUOperand::ImmTyOffset);
9432bool AMDGPUOperand::isSMRDOffset8()
const {
9436bool AMDGPUOperand::isSMEMOffset()
const {
9438 return isImmLiteral();
9441bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9476bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9477 if (BoundCtrl == 0 || BoundCtrl == 1) {
9485void AMDGPUAsmParser::onBeginOfFile() {
9486 if (!getParser().getStreamer().getTargetStreamer())
9489 if (!getTargetStreamer().getTargetID())
9490 getTargetStreamer().initializeTargetID(getSTI(),
9494void AMDGPUAsmParser::emitTargetDirective() {
9495 if (TargetDirectiveEmitted)
9497 TargetDirectiveEmitted =
true;
9499 if (!getParser().getStreamer().getTargetStreamer() ||
9504 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9513bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9517 StringRef TokenId = getTokenStr();
9518 AGVK VK = StringSwitch<AGVK>(TokenId)
9519 .Case(
"max", AGVK::AGVK_Max)
9520 .Case(
"min", AGVK::AGVK_Min)
9521 .Case(
"or", AGVK::AGVK_Or)
9522 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9523 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9524 .Case(
"alignto", AGVK::AGVK_AlignTo)
9525 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9526 .Case(
"instprefsize", AGVK::AGVK_InstPrefSize)
9527 .Default(AGVK::AGVK_None);
9536 if (Exprs.
empty()) {
9538 "empty " + Twine(TokenId) +
" expression");
9541 if (CommaCount + 1 != Exprs.
size()) {
9543 "mismatch of commas in " + Twine(TokenId) +
" expression");
9547 Expected && Exprs.
size() != Expected) {
9548 Error(
getToken().getLoc(), Twine(TokenId) +
" expression expects " +
9549 Twine(Expected) +
" operands");
9556 if (getParser().parseExpression(Expr, EndLoc))
9560 if (LastTokenWasComma)
9564 "unexpected token in " + Twine(TokenId) +
" expression");
9570 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9574 StringRef
Name = getTokenStr();
9575 if (Name ==
"mul") {
9576 return parseIntWithPrefix(
"mul",
Operands, AMDGPUOperand::ImmTyOModSI,
9580 if (Name ==
"div") {
9581 return parseIntWithPrefix(
"div",
Operands, AMDGPUOperand::ImmTyOModSI,
9592 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9597 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9598 AMDGPU::OpName::src2};
9606 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9611 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9613 if (
DstOp.isReg() &&
9618 if ((OpSel & (1 << SrcNum)) != 0)
9624void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9631 OptionalImmIndexMap &OptionalIdx) {
9632 cvtVOP3P(Inst,
Operands, OptionalIdx);
9641 &&
Desc.NumOperands > (OpNum + 1)
9643 &&
Desc.operands()[OpNum + 1].RegClass != -1
9645 &&
Desc.getOperandConstraint(OpNum + 1,
9649void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9651 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9652 AMDGPU::OpName::src2};
9653 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9654 AMDGPU::OpName::src1_modifiers,
9655 AMDGPU::OpName::src2_modifiers};
9656 for (
int J = 0; J < 3; ++J) {
9657 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9663 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9666 if ((OpSel & (1 << J)) != 0)
9669 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9676void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
9678 OptionalImmIndexMap OptionalIdx;
9683 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9684 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9688 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9690 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9691 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9692 Op.isInterpAttrChan()) {
9694 }
else if (
Op.isImmModifier()) {
9695 OptionalIdx[
Op.getImmTy()] =
I;
9703 AMDGPUOperand::ImmTyHigh);
9707 AMDGPUOperand::ImmTyClamp);
9711 AMDGPUOperand::ImmTyOModSI);
9716 AMDGPUOperand::ImmTyOpSel);
9717 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9720 cvtOpSelHelper(Inst, OpSel);
9725 OptionalImmIndexMap OptionalIdx;
9730 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9731 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9735 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9737 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9738 }
else if (
Op.isImmModifier()) {
9739 OptionalIdx[
Op.getImmTy()] =
I;
9747 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9750 AMDGPUOperand::ImmTyOpSel);
9753 AMDGPUOperand::ImmTyWaitEXP);
9759 cvtOpSelHelper(Inst, OpSel);
9762void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9764 OptionalImmIndexMap OptionalIdx;
9767 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9771 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9772 static_cast<AMDGPUOperand &
>(*
Operands[
I++]).addRegOperands(Inst, 1);
9775 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
I]);
9780 if (NumOperands == CbszOpIdx) {
9785 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9786 }
else if (
Op.isImmModifier()) {
9787 OptionalIdx[
Op.getImmTy()] =
I;
9789 Op.addRegOrImmOperands(Inst, 1);
9794 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9795 if (CbszIdx != OptionalIdx.end()) {
9796 int CbszVal = ((AMDGPUOperand &)*
Operands[CbszIdx->second]).
getImm();
9800 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9801 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9802 if (BlgpIdx != OptionalIdx.end()) {
9803 int BlgpVal = ((AMDGPUOperand &)*
Operands[BlgpIdx->second]).
getImm();
9814 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9815 if (OpselIdx != OptionalIdx.end()) {
9816 OpSel =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselIdx->second])
9820 unsigned OpSelHi = 0;
9821 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9822 if (OpselHiIdx != OptionalIdx.end()) {
9823 OpSelHi =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselHiIdx->second])
9826 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9827 AMDGPU::OpName::src1_modifiers};
9829 for (
unsigned J = 0; J < 2; ++J) {
9830 unsigned ModVal = 0;
9831 if (OpSel & (1 << J))
9833 if (OpSelHi & (1 << J))
9836 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9842 OptionalImmIndexMap &OptionalIdx) {
9847 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9848 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9852 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9854 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9855 }
else if (
Op.isImmModifier()) {
9856 OptionalIdx[
Op.getImmTy()] =
I;
9858 Op.addRegOrImmOperands(Inst, 1);
9864 AMDGPUOperand::ImmTyScaleSel);
9868 AMDGPUOperand::ImmTyClamp);
9874 AMDGPUOperand::ImmTyByteSel);
9879 AMDGPUOperand::ImmTyOModSI);
9886 auto *it = Inst.
begin();
9888 it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9897 OptionalImmIndexMap OptionalIdx;
9898 cvtVOP3(Inst,
Operands, OptionalIdx);
9902 OptionalImmIndexMap &OptIdx) {
9907 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9908 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9909 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9910 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9911 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx11 ||
9912 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx11 ||
9913 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9914 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12 ||
9915 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx13 ||
9916 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx13) {
9925 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
9926 if (VdstInIdx != -1 && VdstInIdx ==
static_cast<int>(Inst.
getNumOperands()))
9929 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9930 if (BitOp3Idx != -1) {
9937 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9938 if (OpSelIdx != -1) {
9942 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9943 if (OpSelHiIdx != -1) {
9944 int DefaultVal =
IsPacked ? -1 : 0;
9950 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9951 if (MatrixAFMTIdx != -1) {
9953 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9957 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9958 if (MatrixBFMTIdx != -1) {
9960 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9963 int MatrixAScaleIdx =
9964 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9965 if (MatrixAScaleIdx != -1) {
9967 AMDGPUOperand::ImmTyMatrixAScale, 0);
9970 int MatrixBScaleIdx =
9971 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9972 if (MatrixBScaleIdx != -1) {
9974 AMDGPUOperand::ImmTyMatrixBScale, 0);
9977 int MatrixAScaleFmtIdx =
9978 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9979 if (MatrixAScaleFmtIdx != -1) {
9981 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9984 int MatrixBScaleFmtIdx =
9985 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9986 if (MatrixBScaleFmtIdx != -1) {
9988 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9993 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9997 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9999 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
10000 if (NegLoIdx != -1)
10003 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
10004 if (NegHiIdx != -1)
10007 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
10008 AMDGPU::OpName::src2};
10009 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
10010 AMDGPU::OpName::src1_modifiers,
10011 AMDGPU::OpName::src2_modifiers};
10013 unsigned OpSel = 0;
10014 unsigned OpSelHi = 0;
10015 unsigned NegLo = 0;
10016 unsigned NegHi = 0;
10018 if (OpSelIdx != -1)
10021 if (OpSelHiIdx != -1)
10024 if (NegLoIdx != -1)
10027 if (NegHiIdx != -1)
10030 for (
int J = 0; J < 3; ++J) {
10031 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
10035 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
10045 uint32_t ModVal = 0;
10047 const MCOperand &SrcOp = Inst.
getOperand(OpIdx);
10048 if (SrcOp.
isReg() && getMRI()
10052 if (VGPRSuffixIsHi)
10055 if ((OpSel & (1 << J)) != 0)
10059 if ((OpSelHi & (1 << J)) != 0)
10062 if ((NegLo & (1 << J)) != 0)
10065 if ((NegHi & (1 << J)) != 0)
10073 OptionalImmIndexMap OptIdx;
10079 unsigned i,
unsigned Opc,
10080 AMDGPU::OpName
OpName) {
10081 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
10082 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
10084 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
10090 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
10093 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
10094 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
10096 OptionalImmIndexMap OptIdx;
10097 for (
unsigned i = 5; i <
Operands.size(); ++i) {
10098 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
10099 OptIdx[
Op.getImmTy()] = i;
10104 AMDGPUOperand::ImmTyIndexKey8bit);
10108 AMDGPUOperand::ImmTyIndexKey16bit);
10112 AMDGPUOperand::ImmTyIndexKey32bit);
10129 SMLoc S = getLoc();
10132 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
10133 SMLoc OpYLoc = getLoc();
10136 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
10139 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
10148 auto addOp = [&](uint16_t ParsedOprIdx) {
10149 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
10151 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10155 Op.addRegOperands(Inst, 1);
10159 Op.addImmOperands(Inst, 1);
10171 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
10175 const auto &CInfo = InstInfo[CompIdx];
10176 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
10177 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
10178 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
10179 if (CInfo.hasSrc2Acc())
10180 addOp(CInfo.getIndexOfDstInParsedOperands());
10184 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
10185 if (BitOp3Idx != -1) {
10186 OptionalImmIndexMap OptIdx;
10187 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands.back());
10189 OptIdx[
Op.getImmTy()] =
Operands.size() - 1;
10199bool AMDGPUOperand::isDPP8()
const {
return isImmTy(ImmTyDPP8); }
10201bool AMDGPUOperand::isDPPCtrl()
const {
10202 using namespace AMDGPU::DPP;
10204 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
10207 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
10208 Imm <= DppCtrl::QUAD_PERM_LAST) ||
10209 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
10210 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
10211 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
10212 (
Imm == DppCtrl::WAVE_SHL1) || (
Imm == DppCtrl::WAVE_ROL1) ||
10213 (
Imm == DppCtrl::WAVE_SHR1) || (
Imm == DppCtrl::WAVE_ROR1) ||
10214 (
Imm == DppCtrl::ROW_MIRROR) || (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
10215 (
Imm == DppCtrl::BCAST15) || (
Imm == DppCtrl::BCAST31) ||
10216 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
10217 Imm <= DppCtrl::ROW_SHARE_LAST) ||
10218 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
10227bool AMDGPUOperand::isBLGP()
const {
10231bool AMDGPUOperand::isS16Imm()
const {
10235bool AMDGPUOperand::isU16Imm()
const {
10243bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
10248 SMLoc Loc =
getToken().getEndLoc();
10249 Token = std::string(getTokenStr());
10251 if (getLoc() != Loc)
10256 if (!parseId(Suffix))
10260 StringRef DimId = Token;
10275 SMLoc S = getLoc();
10281 SMLoc Loc = getLoc();
10282 if (!parseDimId(Encoding))
10283 return Error(Loc,
"invalid dim value");
10286 AMDGPUOperand::CreateImm(
this, Encoding, S, AMDGPUOperand::ImmTyDim));
10295 SMLoc S = getLoc();
10304 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10307 for (
size_t i = 0; i < 8; ++i) {
10311 SMLoc Loc = getLoc();
10312 if (getParser().parseAbsoluteExpression(Sels[i]))
10314 if (0 > Sels[i] || 7 < Sels[i])
10315 return Error(Loc,
"expected a 3-bit value");
10318 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10322 for (
size_t i = 0; i < 8; ++i)
10323 DPP8 |= (Sels[i] << (i * 3));
10326 AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
10330bool AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
10332 if (Ctrl ==
"row_newbcast")
10335 if (Ctrl ==
"row_share" || Ctrl ==
"row_xmask")
10338 if (Ctrl ==
"wave_shl" || Ctrl ==
"wave_shr" || Ctrl ==
"wave_rol" ||
10339 Ctrl ==
"wave_ror" || Ctrl ==
"row_bcast")
10342 return Ctrl ==
"row_mirror" ||
Ctrl ==
"row_half_mirror" ||
10343 Ctrl ==
"quad_perm" ||
Ctrl ==
"row_shl" ||
Ctrl ==
"row_shr" ||
10347int64_t AMDGPUAsmParser::parseDPPCtrlPerm() {
10350 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
10354 for (
int i = 0; i < 4; ++i) {
10359 SMLoc Loc = getLoc();
10360 if (getParser().parseAbsoluteExpression(Temp))
10362 if (Temp < 0 || Temp > 3) {
10363 Error(Loc,
"expected a 2-bit value");
10367 Val += (Temp << i * 2);
10370 if (!skipToken(
AsmToken::RBrac,
"expected a closing square bracket"))
10376int64_t AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10377 using namespace AMDGPU::DPP;
10382 SMLoc Loc = getLoc();
10384 if (getParser().parseAbsoluteExpression(Val))
10387 struct DppCtrlCheck {
10393 DppCtrlCheck
Check =
10394 StringSwitch<DppCtrlCheck>(Ctrl)
10395 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10396 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10397 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10398 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10399 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10400 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10401 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10402 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10403 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10404 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10408 if (
Check.Ctrl == -1) {
10409 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10417 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10425 using namespace AMDGPU::DPP;
10428 !isSupportedDPPCtrl(getTokenStr(),
Operands))
10431 SMLoc S = getLoc();
10437 if (Ctrl ==
"row_mirror") {
10438 Val = DppCtrl::ROW_MIRROR;
10439 }
else if (Ctrl ==
"row_half_mirror") {
10440 Val = DppCtrl::ROW_HALF_MIRROR;
10443 if (Ctrl ==
"quad_perm") {
10444 Val = parseDPPCtrlPerm();
10446 Val = parseDPPCtrlSel(Ctrl);
10455 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10461 OptionalImmIndexMap OptionalIdx;
10468 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10470 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10471 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10475 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10476 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10480 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10481 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10482 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx13 ||
10483 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10484 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx13 ||
10485 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10486 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx13 ||
10487 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
10488 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx13;
10494 if (OldIdx == NumOperands) {
10496 constexpr int DST_IDX = 0;
10498 }
else if (Src2ModIdx == NumOperands) {
10508 if (IsVOP3CvtSrDpp) {
10517 if (TiedTo != -1) {
10522 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10524 if (IsDPP8 &&
Op.isDppFI()) {
10527 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10528 }
else if (
Op.isReg()) {
10529 Op.addRegOperands(Inst, 1);
10530 }
else if (
Op.isImm() &&
10532 Op.addImmOperands(Inst, 1);
10533 }
else if (
Op.isImm()) {
10534 OptionalIdx[
Op.getImmTy()] =
I;
10542 AMDGPUOperand::ImmTyClamp);
10548 AMDGPUOperand::ImmTyByteSel);
10553 AMDGPUOperand::ImmTyOModSI);
10556 cvtVOP3P(Inst,
Operands, OptionalIdx);
10558 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
10561 AMDGPUOperand::ImmTyOpSel);
10566 AMDGPUOperand::ImmTyDPP8);
10567 using namespace llvm::AMDGPU::DPP;
10571 AMDGPUOperand::ImmTyDppCtrl, 0xe4);
10573 AMDGPUOperand::ImmTyDppRowMask, 0xf);
10575 AMDGPUOperand::ImmTyDppBankMask, 0xf);
10577 AMDGPUOperand::ImmTyDppBoundCtrl);
10581 AMDGPUOperand::ImmTyDppFI);
10587 OptionalImmIndexMap OptionalIdx;
10591 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10592 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10599 if (TiedTo != -1) {
10604 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10606 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10614 Op.addImmOperands(Inst, 1);
10616 Op.addRegWithFPInputModsOperands(Inst, 2);
10617 }
else if (
Op.isDppFI()) {
10619 }
else if (
Op.isReg()) {
10620 Op.addRegOperands(Inst, 1);
10626 Op.addRegWithFPInputModsOperands(Inst, 2);
10627 }
else if (
Op.isReg()) {
10628 Op.addRegOperands(Inst, 1);
10629 }
else if (
Op.isDPPCtrl()) {
10630 Op.addImmOperands(Inst, 1);
10631 }
else if (
Op.isImm()) {
10633 OptionalIdx[
Op.getImmTy()] =
I;
10641 using namespace llvm::AMDGPU::DPP;
10645 AMDGPUOperand::ImmTyDppRowMask, 0xf);
10647 AMDGPUOperand::ImmTyDppBankMask, 0xf);
10649 AMDGPUOperand::ImmTyDppBoundCtrl);
10652 AMDGPUOperand::ImmTyDppFI);
10663 AMDGPUOperand::ImmTy
Type) {
10664 return parseStringOrIntWithPrefix(
10666 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10671 return parseStringOrIntWithPrefix(
10672 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10673 AMDGPUOperand::ImmTySDWADstUnused);
10677 cvtSDWA(Inst,
Operands, SDWAInstType::VOP1);
10681 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2);
10684void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
10686 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2,
true,
true);
10689void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
10691 cvtSDWA(Inst,
Operands, SDWAInstType::VOP2,
false,
true);
10699 SDWAInstType BasicInstType,
bool SkipDstVcc,
10701 using namespace llvm::AMDGPU::SDWA;
10703 OptionalImmIndexMap OptionalIdx;
10704 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10705 bool SkippedVcc =
false;
10709 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10710 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10714 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10715 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10716 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10722 if (BasicInstType == SDWAInstType::VOP2 &&
10728 if (BasicInstType == SDWAInstType::VOPC && Inst.
getNumOperands() == 0) {
10734 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10735 }
else if (
Op.isImm()) {
10737 OptionalIdx[
Op.getImmTy()] =
I;
10741 SkippedVcc =
false;
10745 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10746 Opc != AMDGPU::V_NOP_sdwa_vi) {
10748 switch (BasicInstType) {
10749 case SDWAInstType::VOP1:
10752 AMDGPUOperand::ImmTyClamp, 0);
10756 AMDGPUOperand::ImmTyOModSI, 0);
10760 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10764 AMDGPUOperand::ImmTySDWADstUnused,
10765 DstUnused::UNUSED_PRESERVE);
10768 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10771 case SDWAInstType::VOP2:
10773 AMDGPUOperand::ImmTyClamp, 0);
10777 AMDGPUOperand::ImmTyOModSI, 0);
10780 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10782 AMDGPUOperand::ImmTySDWADstUnused,
10783 DstUnused::UNUSED_PRESERVE);
10785 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10787 AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10790 case SDWAInstType::VOPC:
10793 AMDGPUOperand::ImmTyClamp, 0);
10795 AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10797 AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10804 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10805 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10806 auto *it = Inst.
begin();
10808 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10821#define GET_MATCHER_IMPLEMENTATION
10822#define GET_MNEMONIC_SPELL_CHECKER
10823#define GET_MNEMONIC_CHECKER
10824#include "AMDGPUGenAsmMatcher.inc"
10830 return parseTokenOp(
"addr64",
Operands);
10832 return parseNamedBit(
"done",
Operands, AMDGPUOperand::ImmTyDone,
true);
10834 return parseTokenOp(
"idxen",
Operands);
10836 return parseNamedBit(
"lds",
Operands, AMDGPUOperand::ImmTyLDS,
10839 return parseTokenOp(
"offen",
Operands);
10841 return parseTokenOp(
"off",
Operands);
10842 case MCK_row_95_en:
10843 return parseNamedBit(
"row_en",
Operands, AMDGPUOperand::ImmTyRowEn,
true);
10845 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10847 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10849 return tryCustomParseOperand(
Operands, MCK);
10854unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10860 AMDGPUOperand &Operand = (AMDGPUOperand &)
Op;
10863 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10865 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10867 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10869 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10871 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10873 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10875 return Operand.isDone() ? Match_Success : Match_InvalidOperand;
10876 case MCK_row_95_en:
10877 return Operand.isRowEn() ? Match_Success : Match_InvalidOperand;
10885 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10887 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10888 case MCK_SOPPBrTarget:
10889 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10890 case MCK_VReg32OrOff:
10891 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10892 case MCK_InterpSlot:
10893 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10894 case MCK_InterpAttr:
10895 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10896 case MCK_InterpAttrChan:
10897 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10899 case MCK_SReg_64_XEXEC:
10909 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10911 return Match_InvalidOperand;
10920 SMLoc S = getLoc();
10929 return Error(S,
"expected a 16-bit value");
10932 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10936bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10942bool AMDGPUOperand::isSplitBarrier()
const {
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, AMDGPU::OpName OpName)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static int IsAGPROperand(const MCInst &Inst, AMDGPU::OpName Name, const MCRegisterInfo *MRI)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static bool IsRevOpcode(const unsigned Opcode)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static MCRegister getSpecialRegForName(StringRef RegName)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0, std::optional< unsigned > InsertAt=std::nullopt)
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
Enums shared between the AMDGPU backend (LLVM) and the ELF linker (LLD) for the .amdgpu....
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(GsymDataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Loop::LoopBounds::Direction Direction
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static unsigned getNumExpectedArgs(VariantKind Kind)
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
static std::optional< TargetID > parseTargetIDString(StringRef TargetIDDirective)
Parse and validate a TargetID from a full "<triple>-<processor>:<features>" directive string.
TargetIDSetting getXnackSetting() const
GPUKind getGPUKind() const
StringRef getTargetTripleString() const
std::string toString() const
TargetIDSetting getSramEccSetting() const
static const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
const T & front() const
Get the first element.
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
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
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)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
unsigned getTgtId(const StringRef Name)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getVGPREncodingGranule(const MCSubtargetInfo &STI, std::optional< bool > EnableWavefrontSize32)
unsigned getSGPREncodingGranule(const MCSubtargetInfo &STI)
bool targetIDSettingsConflict(TargetIDSetting Lhs, TargetIDSetting Rhs)
Returns true if Lhs and Rhs are incompatible (both specific but different).
unsigned getLocalMemorySize(const MCSubtargetInfo &STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
constexpr const char *const ModMatrixFmt[]
constexpr const char *const ModMatrixScaleFmt[]
constexpr const char *const ModMatrixScale[]
bool 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)
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 isPackedSingleSGPRFP32Inst(unsigned Opc)
The opcode is a packed fp32 instruction which only reads low 32 bits of a scalar operand and propagat...
bool isGFX13(const MCSubtargetInfo &STI)
LLVM_ABI unsigned getAddressableNumSGPRs(GPUKind AK)
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
LLVM_ABI unsigned getTotalNumVGPRs(GPUKind AK, bool IsWave32)
CanBeVOPD getCanBeVOPD(unsigned Opc, unsigned EncodingFamily, bool VOPD3)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
bool isSI(const MCSubtargetInfo &STI)
bool hasPrivateApertureRegs(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
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?
GPUKind
GPU kinds supported by the AMDGPU target.
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool hasMAIInsts(const MCSubtargetInfo &STI)
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
LLVM_ABI GPUKind parseArchAMDGCN(StringRef CPU)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool 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_IMM_NOINLINE_FP16
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT64
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_IMM_V2FP16_SPLAT
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
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)
bool hasPopsExitingWaveID(const MCSubtargetInfo &STI)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
constexpr bool isAtomicRet(const T &...O)
constexpr bool isVOPC(const T &...O)
constexpr bool isVOP3(const T &...O)
constexpr bool isVOP1(const T &...O)
constexpr bool usesTENSOR_CNT(const T &...O)
constexpr bool isMAI(const T &...O)
constexpr bool isVOP2(const T &...O)
constexpr bool isSWMMAC(const T &...O)
constexpr bool isSOP2(const T &...O)
constexpr bool isFLAT(const T &...O)
constexpr bool isVOP3P(const T &...O)
constexpr bool isBuffer(const T &...O)
constexpr bool hasIntClamp(const T &...O)
constexpr bool isAtomicNoRet(const T &...O)
constexpr bool isSMRD(const T &...O)
constexpr bool isVOP3Like(const T &...O)
constexpr bool isMIMG(const T &...O)
constexpr bool isVMEM(const T &...O)
constexpr bool isImage(const T &...O)
constexpr bool isWMMA(const T &...O)
constexpr bool isVOPD3(const T &...O)
constexpr bool isGWS(const T &...O)
constexpr bool isMUBUF(const T &...O)
constexpr bool isSDWA(const T &...O)
constexpr bool isSOPC(const T &...O)
constexpr bool isDOT(const T &...O)
constexpr bool isVSAMPLE(const T &...O)
constexpr bool isDS(const T &...O)
constexpr bool isAtomic(const T &...O)
constexpr bool isGather4(const T &...O)
constexpr bool isPacked(const T &...O)
constexpr bool isDPP(const T &...O)
constexpr bool isSegmentSpecificFLAT(const T &...O)
@ Valid
The data is already valid.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
EnumSet< Modifier, Modifier_enumSize > Modifiers
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
LLVM_ABI void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Target & getTheGCNLegacyTarget()
The target for GCN GPUs, registered under the legacy "amdgcn" architecture name for use with -march.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ 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