56enum RegisterKind { IS_UNKNOWN,
IS_VGPR, IS_SGPR,
IS_AGPR, IS_TTMP, IS_SPECIAL };
70 SMLoc StartLoc, EndLoc;
71 const AMDGPUAsmParser *AsmParser;
74 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
75 : Kind(Kind_), AsmParser(AsmParser_) {}
77 using Ptr = std::unique_ptr<AMDGPUOperand>;
85 bool hasFPModifiers()
const {
return Abs || Neg; }
86 bool hasIntModifiers()
const {
return Sext; }
87 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
89 int64_t getFPModifiersOperand()
const {
96 int64_t getIntModifiersOperand()
const {
102 int64_t getModifiersOperand()
const {
103 assert(!(hasFPModifiers() && hasIntModifiers())
104 &&
"fp and int modifiers should not be used simultaneously");
105 if (hasFPModifiers())
106 return getFPModifiersOperand();
107 if (hasIntModifiers())
108 return getIntModifiersOperand();
112 friend raw_ostream &
operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
182 ImmTyMatrixAScaleFmt,
183 ImmTyMatrixBScaleFmt,
216 mutable int MCOpIdx = -1;
219 bool isToken()
const override {
return Kind == Token; }
221 bool isSymbolRefExpr()
const {
225 bool isImm()
const override {
226 return Kind == Immediate;
229 bool isInlinableImm(MVT type)
const;
230 bool isLiteralImm(MVT type)
const;
232 bool isRegKind()
const {
233 return Kind == Register;
236 bool isReg()
const override {
237 return isRegKind() && !hasModifiers();
240 bool isRegOrInline(
unsigned RCID, MVT type)
const {
241 return isRegClass(RCID) || isInlinableImm(type);
245 return isRegOrInline(RCID, type) || isLiteralImm(type);
248 bool isRegOrImmWithInt16InputMods()
const {
252 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
254 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
257 bool isRegOrImmWithInt32InputMods()
const {
261 bool isRegOrInlineImmWithInt16InputMods()
const {
262 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
265 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
266 return isRegOrInline(
267 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
270 bool isRegOrInlineImmWithInt32InputMods()
const {
271 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
274 bool isRegOrImmWithInt64InputMods()
const {
278 bool isRegOrImmWithFP16InputMods()
const {
282 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
284 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
287 bool isRegOrImmWithFP32InputMods()
const {
291 bool isRegOrImmWithFP64InputMods()
const {
295 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
296 return isRegOrInline(
297 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
300 bool isRegOrInlineImmWithFP32InputMods()
const {
301 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
304 bool isRegOrInlineImmWithFP64InputMods()
const {
305 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
308 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
310 bool isVRegWithFP32InputMods()
const {
311 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
314 bool isVRegWithFP64InputMods()
const {
315 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
318 bool isPackedFP16InputMods()
const {
322 bool isPackedVGPRFP32InputMods()
const {
326 bool isVReg()
const {
327 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
328 isRegClass(AMDGPU::VReg_64RegClassID) ||
329 isRegClass(AMDGPU::VReg_96RegClassID) ||
330 isRegClass(AMDGPU::VReg_128RegClassID) ||
331 isRegClass(AMDGPU::VReg_160RegClassID) ||
332 isRegClass(AMDGPU::VReg_192RegClassID) ||
333 isRegClass(AMDGPU::VReg_256RegClassID) ||
334 isRegClass(AMDGPU::VReg_512RegClassID) ||
335 isRegClass(AMDGPU::VReg_1024RegClassID);
338 bool isVReg32()
const {
339 return isRegClass(AMDGPU::VGPR_32RegClassID);
342 bool isVReg32OrOff()
const {
343 return isOff() || isVReg32();
347 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
350 bool isVRegWithInputMods()
const;
351 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
352 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
354 bool isSDWAOperand(MVT type)
const;
355 bool isSDWAFP16Operand()
const;
356 bool isSDWAFP32Operand()
const;
357 bool isSDWAInt16Operand()
const;
358 bool isSDWAInt32Operand()
const;
360 bool isImmTy(ImmTy ImmT)
const {
361 return isImm() &&
Imm.Type == ImmT;
364 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
366 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
368 bool isImmModifier()
const {
369 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 {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
382 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
383 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
384 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
385 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
386 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
387 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
388 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
389 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
390 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
391 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
392 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
393 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
394 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
395 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
396 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
397 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
398 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
399 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
400 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
401 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
402 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
403 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
404 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
405 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
406 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
407 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
408 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
409 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
410 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
412 bool isRegOrImm()
const {
413 return isReg() || isImm();
416 bool isRegClass(
unsigned RCID)
const;
420 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
421 return isRegOrInline(RCID, type) && !hasModifiers();
424 bool isSCSrcB16()
const {
425 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
428 bool isSCSrcV2B16()
const {
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 {
450 bool isSCSrcF32()
const {
451 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
454 bool isSCSrcF64()
const {
455 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
458 bool isSSrc_b32()
const {
459 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
462 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
464 bool isSSrcV2B16()
const {
469 bool isSSrc_b64()
const {
472 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
473 (((
const MCTargetAsmParser *)AsmParser)
474 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
478 bool isSSrc_f32()
const {
479 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
482 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
484 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
486 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::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 isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
608 bool isVSrcT_b16_Lo128()
const {
609 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
612 bool isVSrcFake16_b16_Lo128()
const {
613 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
616 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
618 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
620 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
622 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
624 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
626 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
628 bool isVSrc_f32()
const {
629 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
632 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
634 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
636 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
638 bool isVSrcT_bf16_Lo128()
const {
639 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
642 bool isVSrcT_f16_Lo128()
const {
643 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
646 bool isVSrcFake16_bf16_Lo128()
const {
647 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
650 bool isVSrcFake16_f16_Lo128()
const {
651 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
654 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
656 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
658 bool isVSrc_v2bf16()
const {
659 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
662 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
664 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
666 bool isVISrcB32()
const {
667 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
670 bool isVISrcB16()
const {
671 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
674 bool isVISrcV2B16()
const {
678 bool isVISrcF32()
const {
679 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
682 bool isVISrcF16()
const {
683 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
686 bool isVISrcV2F16()
const {
687 return isVISrcF16() || isVISrcB32();
690 bool isVISrc_64_bf16()
const {
691 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
694 bool isVISrc_64_f16()
const {
695 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
698 bool isVISrc_64_b32()
const {
699 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
702 bool isVISrc_64B64()
const {
703 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
706 bool isVISrc_64_f64()
const {
707 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
710 bool isVISrc_64V2FP32()
const {
711 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
714 bool isVISrc_64V2INT32()
const {
715 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
718 bool isVISrc_256_b32()
const {
719 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
722 bool isVISrc_256_f32()
const {
723 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
726 bool isVISrc_256B64()
const {
727 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
730 bool isVISrc_256_f64()
const {
731 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
734 bool isVISrc_512_f64()
const {
735 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
738 bool isVISrc_128B16()
const {
739 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
742 bool isVISrc_128V2B16()
const {
743 return isVISrc_128B16();
746 bool isVISrc_128_b32()
const {
747 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
750 bool isVISrc_128_f32()
const {
751 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
754 bool isVISrc_256V2FP32()
const {
755 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
758 bool isVISrc_256V2INT32()
const {
759 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
762 bool isVISrc_512_b32()
const {
763 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
766 bool isVISrc_512B16()
const {
767 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
770 bool isVISrc_512V2B16()
const {
771 return isVISrc_512B16();
774 bool isVISrc_512_f32()
const {
775 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
778 bool isVISrc_512F16()
const {
779 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
782 bool isVISrc_512V2F16()
const {
783 return isVISrc_512F16() || isVISrc_512_b32();
786 bool isVISrc_1024_b32()
const {
787 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
790 bool isVISrc_1024B16()
const {
791 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
794 bool isVISrc_1024V2B16()
const {
795 return isVISrc_1024B16();
798 bool isVISrc_1024_f32()
const {
799 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
802 bool isVISrc_1024F16()
const {
803 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
806 bool isVISrc_1024V2F16()
const {
807 return isVISrc_1024F16() || isVISrc_1024_b32();
810 bool isAISrcB32()
const {
811 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
814 bool isAISrcB16()
const {
815 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
818 bool isAISrcV2B16()
const {
822 bool isAISrcF32()
const {
823 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
826 bool isAISrcF16()
const {
827 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
830 bool isAISrcV2F16()
const {
831 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 {
851 return isAISrc_128B16();
854 bool isAISrc_128_f32()
const {
855 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
858 bool isAISrc_128F16()
const {
859 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
862 bool isAISrc_128V2F16()
const {
863 return isAISrc_128F16() || isAISrc_128_b32();
866 bool isVISrc_128_bf16()
const {
867 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
870 bool isVISrc_128_f16()
const {
871 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
874 bool isVISrc_128V2F16()
const {
875 return isVISrc_128_f16() || isVISrc_128_b32();
878 bool isAISrc_256B64()
const {
879 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
882 bool isAISrc_256_f64()
const {
883 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
886 bool isAISrc_512_b32()
const {
887 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
890 bool isAISrc_512B16()
const {
891 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
894 bool isAISrc_512V2B16()
const {
895 return isAISrc_512B16();
898 bool isAISrc_512_f32()
const {
899 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
902 bool isAISrc_512F16()
const {
903 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
906 bool isAISrc_512V2F16()
const {
907 return isAISrc_512F16() || isAISrc_512_b32();
910 bool isAISrc_1024_b32()
const {
911 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
914 bool isAISrc_1024B16()
const {
915 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
918 bool isAISrc_1024V2B16()
const {
919 return isAISrc_1024B16();
922 bool isAISrc_1024_f32()
const {
923 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
926 bool isAISrc_1024F16()
const {
927 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
930 bool isAISrc_1024V2F16()
const {
931 return isAISrc_1024F16() || isAISrc_1024_b32();
934 bool isKImmFP32()
const {
935 return isLiteralImm(MVT::f32);
938 bool isKImmFP16()
const {
939 return isLiteralImm(MVT::f16);
942 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
944 bool isMem()
const override {
948 bool isExpr()
const {
949 return Kind == Expression;
952 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
954 bool isSWaitCnt()
const;
955 bool isDepCtr()
const;
956 bool isSDelayALU()
const;
957 bool isHwreg()
const;
958 bool isSendMsg()
const;
959 bool isSplitBarrier()
const;
960 bool isSwizzle()
const;
961 bool isSMRDOffset8()
const;
962 bool isSMEMOffset()
const;
963 bool isSMRDLiteralOffset()
const;
965 bool isDPPCtrl()
const;
967 bool isGPRIdxMode()
const;
968 bool isS16Imm()
const;
969 bool isU16Imm()
const;
970 bool isEndpgm()
const;
972 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
973 return [
this,
P]() {
return P(*
this); };
978 return StringRef(Tok.Data, Tok.Length);
986 void setImm(int64_t Val) {
991 ImmTy getImmTy()
const {
996 MCRegister
getReg()
const override {
1001 SMLoc getStartLoc()
const override {
1005 SMLoc getEndLoc()
const override {
1009 SMRange getLocRange()
const {
1010 return SMRange(StartLoc, EndLoc);
1013 int getMCOpIdx()
const {
return MCOpIdx; }
1015 Modifiers getModifiers()
const {
1016 assert(isRegKind() || isImmTy(ImmTyNone));
1017 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1020 void setModifiers(Modifiers Mods) {
1021 assert(isRegKind() || isImmTy(ImmTyNone));
1028 bool hasModifiers()
const {
1029 return getModifiers().hasModifiers();
1032 bool hasFPModifiers()
const {
1033 return getModifiers().hasFPModifiers();
1036 bool hasIntModifiers()
const {
1037 return getModifiers().hasIntModifiers();
1040 uint64_t applyInputFPModifiers(uint64_t Val,
unsigned Size)
const;
1042 void addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1044 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1046 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1048 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1050 addRegOperands(Inst,
N);
1052 addImmOperands(Inst,
N);
1055 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1056 Modifiers Mods = getModifiers();
1059 addRegOperands(Inst,
N);
1061 addImmOperands(Inst,
N,
false);
1065 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1066 assert(!hasIntModifiers());
1067 addRegOrImmWithInputModsOperands(Inst,
N);
1070 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1071 assert(!hasFPModifiers());
1072 addRegOrImmWithInputModsOperands(Inst,
N);
1075 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1076 Modifiers Mods = getModifiers();
1079 addRegOperands(Inst,
N);
1082 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1083 assert(!hasIntModifiers());
1084 addRegWithInputModsOperands(Inst,
N);
1087 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1088 assert(!hasFPModifiers());
1089 addRegWithInputModsOperands(Inst,
N);
1092 static void printImmTy(raw_ostream& OS, ImmTy
Type) {
1095 case ImmTyNone: OS <<
"None";
break;
1096 case ImmTyGDS: OS <<
"GDS";
break;
1097 case ImmTyLDS: OS <<
"LDS";
break;
1098 case ImmTyOffen: OS <<
"Offen";
break;
1099 case ImmTyIdxen: OS <<
"Idxen";
break;
1100 case ImmTyAddr64: OS <<
"Addr64";
break;
1101 case ImmTyOffset: OS <<
"Offset";
break;
1102 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1103 case ImmTyOffset0: OS <<
"Offset0";
break;
1104 case ImmTyOffset1: OS <<
"Offset1";
break;
1105 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1106 case ImmTyCPol: OS <<
"CPol";
break;
1107 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1108 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1109 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1110 case ImmTyTFE: OS <<
"TFE";
break;
1111 case ImmTyD16: OS <<
"D16";
break;
1112 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1113 case ImmTyClamp: OS <<
"Clamp";
break;
1114 case ImmTyOModSI: OS <<
"OModSI";
break;
1115 case ImmTyDPP8: OS <<
"DPP8";
break;
1116 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1117 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1118 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1119 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1120 case ImmTyDppFI: OS <<
"DppFI";
break;
1121 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1122 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1123 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1124 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1125 case ImmTyDMask: OS <<
"DMask";
break;
1126 case ImmTyDim: OS <<
"Dim";
break;
1127 case ImmTyUNorm: OS <<
"UNorm";
break;
1128 case ImmTyDA: OS <<
"DA";
break;
1129 case ImmTyR128A16: OS <<
"R128A16";
break;
1130 case ImmTyA16: OS <<
"A16";
break;
1131 case ImmTyLWE: OS <<
"LWE";
break;
1132 case ImmTyOff: OS <<
"Off";
break;
1133 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1134 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1135 case ImmTyExpVM: OS <<
"ExpVM";
break;
1136 case ImmTyHwreg: OS <<
"Hwreg";
break;
1137 case ImmTySendMsg: OS <<
"SendMsg";
break;
1138 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1139 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1140 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1141 case ImmTyOpSel: OS <<
"OpSel";
break;
1142 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1143 case ImmTyNegLo: OS <<
"NegLo";
break;
1144 case ImmTyNegHi: OS <<
"NegHi";
break;
1145 case ImmTySwizzle: OS <<
"Swizzle";
break;
1146 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1147 case ImmTyHigh: OS <<
"High";
break;
1148 case ImmTyBLGP: OS <<
"BLGP";
break;
1149 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1150 case ImmTyABID: OS <<
"ABID";
break;
1151 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1152 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1153 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1154 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1155 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1156 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1157 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1158 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1159 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1160 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1161 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1162 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1163 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1164 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1165 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1166 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1171 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1175 <<
" mods: " <<
Reg.Mods <<
'>';
1179 if (getImmTy() != ImmTyNone) {
1180 OS <<
" type: "; printImmTy(OS, getImmTy());
1182 OS <<
" mods: " <<
Imm.Mods <<
'>';
1195 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1196 int64_t Val, SMLoc Loc,
1197 ImmTy
Type = ImmTyNone,
1198 bool IsFPImm =
false) {
1199 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1201 Op->Imm.IsFPImm = IsFPImm;
1203 Op->Imm.Mods = Modifiers();
1209 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1210 StringRef Str, SMLoc Loc,
1211 bool HasExplicitEncodingSize =
true) {
1212 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1213 Res->Tok.Data = Str.data();
1214 Res->Tok.Length = Str.size();
1215 Res->StartLoc = Loc;
1220 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1221 MCRegister
Reg, SMLoc S, SMLoc
E) {
1222 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1223 Op->Reg.RegNo =
Reg;
1224 Op->Reg.Mods = Modifiers();
1230 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1231 const class MCExpr *Expr, SMLoc S) {
1232 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1241 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1250#define GET_REGISTER_MATCHER
1251#include "AMDGPUGenAsmMatcher.inc"
1252#undef GET_REGISTER_MATCHER
1253#undef GET_SUBTARGET_FEATURE_NAME
1258class KernelScopeInfo {
1259 int SgprIndexUnusedMin = -1;
1260 int VgprIndexUnusedMin = -1;
1261 int AgprIndexUnusedMin = -1;
1265 void usesSgprAt(
int i) {
1266 if (i >= SgprIndexUnusedMin) {
1267 SgprIndexUnusedMin = ++i;
1270 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1276 void usesVgprAt(
int i) {
1277 if (i >= VgprIndexUnusedMin) {
1278 VgprIndexUnusedMin = ++i;
1281 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1283 VgprIndexUnusedMin);
1289 void usesAgprAt(
int i) {
1294 if (i >= AgprIndexUnusedMin) {
1295 AgprIndexUnusedMin = ++i;
1298 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1303 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1305 VgprIndexUnusedMin);
1312 KernelScopeInfo() =
default;
1316 MSTI = Ctx->getSubtargetInfo();
1318 usesSgprAt(SgprIndexUnusedMin = -1);
1319 usesVgprAt(VgprIndexUnusedMin = -1);
1321 usesAgprAt(AgprIndexUnusedMin = -1);
1325 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1326 unsigned RegWidth) {
1329 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1332 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1335 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1344 MCAsmParser &Parser;
1346 unsigned ForcedEncodingSize = 0;
1347 bool ForcedDPP =
false;
1348 bool ForcedSDWA =
false;
1349 KernelScopeInfo KernelScope;
1350 const unsigned HwMode;
1355#define GET_ASSEMBLER_HEADER
1356#include "AMDGPUGenAsmMatcher.inc"
1361 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1363 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1368 void createConstantSymbol(StringRef Id, int64_t Val);
1370 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1371 bool OutOfRangeError(SMRange
Range);
1387 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1388 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1389 std::optional<bool> EnableWavefrontSize32,
1390 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1391 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1392 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1393 bool ParseDirectiveAMDGCNTarget();
1394 bool ParseDirectiveAMDHSACodeObjectVersion();
1395 bool ParseDirectiveAMDHSAKernel();
1396 bool ParseAMDKernelCodeTValue(StringRef
ID, AMDGPUMCKernelCodeT &Header);
1397 bool ParseDirectiveAMDKernelCodeT();
1399 bool subtargetHasRegister(
const MCRegisterInfo &
MRI, MCRegister
Reg);
1400 bool ParseDirectiveAMDGPUHsaKernel();
1402 bool ParseDirectiveISAVersion();
1403 bool ParseDirectiveHSAMetadata();
1404 bool ParseDirectivePALMetadataBegin();
1405 bool ParseDirectivePALMetadata();
1406 bool ParseDirectiveAMDGPULDS();
1410 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1411 const char *AssemblerDirectiveEnd,
1412 std::string &CollectString);
1414 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1415 RegisterKind RegKind, MCRegister Reg1, SMLoc Loc);
1416 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1417 unsigned &RegNum,
unsigned &RegWidth,
1418 bool RestoreOnFailure =
false);
1419 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1420 unsigned &RegNum,
unsigned &RegWidth,
1421 SmallVectorImpl<AsmToken> &Tokens);
1422 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1424 SmallVectorImpl<AsmToken> &Tokens);
1425 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1427 SmallVectorImpl<AsmToken> &Tokens);
1428 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1430 SmallVectorImpl<AsmToken> &Tokens);
1431 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &
SubReg);
1432 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1433 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1436 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1437 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1438 void initializeGprCountSymbol(RegisterKind RegKind);
1439 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1441 void cvtMubufImpl(MCInst &Inst,
const OperandVector &Operands,
1446 OperandMode_Default,
1450 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1452 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1453 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
1454 : MCTargetAsmParser(
Options, STI, MII), Parser(_Parser),
1455 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)) {
1458 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1462 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1463 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1464 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1466 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1467 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1468 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1471 initializeGprCountSymbol(IS_VGPR);
1472 initializeGprCountSymbol(IS_SGPR);
1477 createConstantSymbol(Symbol, Code);
1479 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1480 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1481 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
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 {
1581 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1583 bool hasIntClamp()
const {
1584 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1587 bool hasPartialNSAEncoding()
const {
1588 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1591 bool hasGloballyAddressableScratch()
const {
1592 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1605 AMDGPUTargetStreamer &getTargetStreamer() {
1606 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1607 return static_cast<AMDGPUTargetStreamer &
>(TS);
1613 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1616 const MCRegisterInfo *getMRI()
const {
1620 const MCInstrInfo *getMII()
const {
1626 const FeatureBitset &getFeatureBits()
const {
1627 return getSTI().getFeatureBits();
1630 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1631 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1632 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1634 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1635 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1636 bool isForcedDPP()
const {
return ForcedDPP; }
1637 bool isForcedSDWA()
const {
return ForcedSDWA; }
1638 ArrayRef<unsigned> getMatchedVariants()
const;
1639 StringRef getMatchedVariantName()
const;
1641 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1642 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1643 bool RestoreOnFailure);
1644 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1645 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1646 SMLoc &EndLoc)
override;
1647 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1648 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1649 unsigned Kind)
override;
1650 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1652 uint64_t &ErrorInfo,
1653 bool MatchingInlineAsm)
override;
1654 bool ParseDirective(AsmToken DirectiveID)
override;
1655 ParseStatus parseOperand(
OperandVector &Operands, StringRef Mnemonic,
1656 OperandMode
Mode = OperandMode_Default);
1657 StringRef parseMnemonicSuffix(StringRef Name);
1658 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
1662 ParseStatus parseTokenOp(StringRef Name,
OperandVector &Operands);
1664 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1667 parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1668 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1669 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1671 ParseStatus parseOperandArrayWithPrefix(
1673 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1674 bool (*ConvertResult)(int64_t &) =
nullptr);
1678 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1679 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1681 ParseStatus parseScope(
OperandVector &Operands, int64_t &Scope);
1683 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1685 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1687 ArrayRef<const char *> Ids,
1689 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1691 ArrayRef<const char *> Ids,
1692 AMDGPUOperand::ImmTy
Type);
1695 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1696 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1697 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1698 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1699 bool parseSP3NegModifier();
1700 ParseStatus parseImm(
OperandVector &Operands,
bool HasSP3AbsModifier =
false,
1703 ParseStatus parseRegOrImm(
OperandVector &Operands,
bool HasSP3AbsMod =
false,
1705 ParseStatus parseRegOrImmWithFPInputMods(
OperandVector &Operands,
1706 bool AllowImm =
true);
1707 ParseStatus parseRegOrImmWithIntInputMods(
OperandVector &Operands,
1708 bool AllowImm =
true);
1709 ParseStatus parseRegWithFPInputMods(
OperandVector &Operands);
1710 ParseStatus parseRegWithIntInputMods(
OperandVector &Operands);
1713 AMDGPUOperand::ImmTy ImmTy);
1717 ParseStatus tryParseMatrixFMT(
OperandVector &Operands, StringRef Name,
1718 AMDGPUOperand::ImmTy
Type);
1721 ParseStatus tryParseMatrixScale(
OperandVector &Operands, StringRef Name,
1722 AMDGPUOperand::ImmTy
Type);
1725 ParseStatus tryParseMatrixScaleFmt(
OperandVector &Operands, StringRef Name,
1726 AMDGPUOperand::ImmTy
Type);
1730 ParseStatus parseDfmtNfmt(int64_t &
Format);
1731 ParseStatus parseUfmt(int64_t &
Format);
1732 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1734 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1737 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1738 ParseStatus parseNumericFormat(int64_t &
Format);
1742 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1743 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1747 bool parseCnt(int64_t &IntVal);
1750 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1751 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1754 bool parseDelay(int64_t &Delay);
1760 struct OperandInfoTy {
1763 bool IsSymbolic =
false;
1764 bool IsDefined =
false;
1766 OperandInfoTy(int64_t Val) : Val(Val) {}
1769 struct StructuredOpField : OperandInfoTy {
1773 bool IsDefined =
false;
1775 StructuredOpField(StringLiteral Id, StringLiteral Desc,
unsigned Width,
1777 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1778 virtual ~StructuredOpField() =
default;
1780 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1781 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1785 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1787 return Error(Parser,
"not supported on this GPU");
1789 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1797 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1798 bool validateSendMsg(
const OperandInfoTy &Msg,
1799 const OperandInfoTy &
Op,
1800 const OperandInfoTy &Stream);
1802 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1803 OperandInfoTy &Width);
1805 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1807 SMLoc getFlatOffsetLoc(
const OperandVector &Operands)
const;
1808 SMLoc getSMEMOffsetLoc(
const OperandVector &Operands)
const;
1811 SMLoc getOperandLoc(
const OperandVector &Operands,
int MCOpIdx)
const;
1812 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1814 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1818 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1820 bool validateOffset(
const MCInst &Inst,
const OperandVector &Operands);
1821 bool validateFlatOffset(
const MCInst &Inst,
const OperandVector &Operands);
1822 bool validateSMEMOffset(
const MCInst &Inst,
const OperandVector &Operands);
1823 bool validateSOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1824 bool validateConstantBusLimitations(
const MCInst &Inst,
const OperandVector &Operands);
1825 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1827 bool validateVOPD(
const MCInst &Inst,
const OperandVector &Operands);
1828 bool tryVOPD(
const MCInst &Inst);
1829 bool tryVOPD3(
const MCInst &Inst);
1830 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1832 bool validateIntClampSupported(
const MCInst &Inst);
1833 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1834 bool validateMIMGGatherDMask(
const MCInst &Inst);
1835 bool validateMovrels(
const MCInst &Inst,
const OperandVector &Operands);
1836 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1837 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1838 bool validateMIMGD16(
const MCInst &Inst);
1839 bool validateMIMGDim(
const MCInst &Inst,
const OperandVector &Operands);
1840 bool validateTensorR128(
const MCInst &Inst);
1841 bool validateMIMGMSAA(
const MCInst &Inst);
1842 bool validateOpSel(
const MCInst &Inst);
1843 bool validateTrue16OpSel(
const MCInst &Inst);
1844 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1845 bool validateDPP(
const MCInst &Inst,
const OperandVector &Operands);
1846 bool validateVccOperand(MCRegister
Reg)
const;
1847 bool validateVOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1848 bool validateMAIAccWrite(
const MCInst &Inst,
const OperandVector &Operands);
1849 bool validateMAISrc2(
const MCInst &Inst,
const OperandVector &Operands);
1850 bool validateMFMA(
const MCInst &Inst,
const OperandVector &Operands);
1851 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1852 bool validateVGPRAlign(
const MCInst &Inst)
const;
1853 bool validateBLGP(
const MCInst &Inst,
const OperandVector &Operands);
1854 bool validateDS(
const MCInst &Inst,
const OperandVector &Operands);
1855 bool validateGWS(
const MCInst &Inst,
const OperandVector &Operands);
1856 bool validateDivScale(
const MCInst &Inst);
1857 bool validateWaitCnt(
const MCInst &Inst,
const OperandVector &Operands);
1858 bool validateCoherencyBits(
const MCInst &Inst,
const OperandVector &Operands,
1860 bool validateTHAndScopeBits(
const MCInst &Inst,
const OperandVector &Operands,
1861 const unsigned CPol);
1862 bool validateTFE(
const MCInst &Inst,
const OperandVector &Operands);
1863 bool validateLdsDirect(
const MCInst &Inst,
const OperandVector &Operands);
1864 bool validateWMMA(
const MCInst &Inst,
const OperandVector &Operands);
1865 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1866 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1867 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1868 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1870 bool isSupportedMnemo(StringRef Mnemo,
1871 const FeatureBitset &FBS);
1872 bool isSupportedMnemo(StringRef Mnemo,
1873 const FeatureBitset &FBS,
1874 ArrayRef<unsigned> Variants);
1875 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1877 bool isId(
const StringRef Id)
const;
1878 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1880 StringRef getId()
const;
1881 bool trySkipId(
const StringRef Id);
1882 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1886 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1887 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1893 StringRef getTokenStr()
const;
1894 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1896 SMLoc getLoc()
const;
1900 void onBeginOfFile()
override;
1901 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1903 ParseStatus parseCustomOperand(
OperandVector &Operands,
unsigned MCK);
1912 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1913 const unsigned MaxVal,
const Twine &ErrMsg,
1915 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1916 const unsigned MinVal,
1917 const unsigned MaxVal,
1918 const StringRef ErrMsg);
1920 bool parseSwizzleOffset(int64_t &
Imm);
1921 bool parseSwizzleMacro(int64_t &
Imm);
1922 bool parseSwizzleQuadPerm(int64_t &
Imm);
1923 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1924 bool parseSwizzleBroadcast(int64_t &
Imm);
1925 bool parseSwizzleSwap(int64_t &
Imm);
1926 bool parseSwizzleReverse(int64_t &
Imm);
1927 bool parseSwizzleFFT(int64_t &
Imm);
1928 bool parseSwizzleRotate(int64_t &
Imm);
1931 int64_t parseGPRIdxMacro();
1933 void cvtMubuf(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
false); }
1934 void cvtMubufAtomic(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
true); }
1939 OptionalImmIndexMap &OptionalIdx);
1940 void cvtScaledMFMA(MCInst &Inst,
const OperandVector &Operands);
1941 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands);
1944 void cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands);
1947 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
1948 OptionalImmIndexMap &OptionalIdx);
1950 OptionalImmIndexMap &OptionalIdx);
1952 void cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands);
1953 void cvtVINTERP(MCInst &Inst,
const OperandVector &Operands);
1954 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1956 bool parseDimId(
unsigned &Encoding);
1958 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1961 bool isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands);
1962 int64_t parseDPPCtrlSel(StringRef Ctrl);
1963 int64_t parseDPPCtrlPerm();
1964 void cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8 =
false);
1966 cvtDPP(Inst, Operands,
true);
1968 void cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
1969 bool IsDPP8 =
false);
1970 void cvtVOP3DPP8(MCInst &Inst,
const OperandVector &Operands) {
1971 cvtVOP3DPP(Inst, Operands,
true);
1974 ParseStatus parseSDWASel(
OperandVector &Operands, StringRef Prefix,
1975 AMDGPUOperand::ImmTy
Type);
1977 void cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands);
1978 void cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands);
1979 void cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands);
1980 void cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands);
1981 void cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands);
1983 uint64_t BasicInstType,
1984 bool SkipDstVcc =
false,
1985 bool SkipSrcVcc =
false);
2093bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2103 if (!isImmTy(ImmTyNone)) {
2108 if (getModifiers().
Lit != LitModifier::None)
2118 if (type == MVT::f64 || type == MVT::i64) {
2120 AsmParser->hasInv2PiInlineImm());
2123 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2142 APFloat::rmNearestTiesToEven, &Lost);
2149 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2151 AsmParser->hasInv2PiInlineImm());
2156 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2157 AsmParser->hasInv2PiInlineImm());
2161 if (type == MVT::f64 || type == MVT::i64) {
2163 AsmParser->hasInv2PiInlineImm());
2172 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2173 type, AsmParser->hasInv2PiInlineImm());
2177 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2178 AsmParser->hasInv2PiInlineImm());
2181bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2183 if (!isImmTy(ImmTyNone)) {
2188 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2193 if (type == MVT::f64 && hasFPModifiers()) {
2213 if (type == MVT::f64) {
2218 if (type == MVT::i64) {
2231 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2232 : (type == MVT::v2i16) ? MVT::f32
2233 : (type == MVT::v2f32) ? MVT::f32
2236 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2240bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2241 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2244bool AMDGPUOperand::isVRegWithInputMods()
const {
2245 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2247 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2248 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2251template <
bool IsFake16>
2252bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2253 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2254 : AMDGPU::VGPR_16_Lo128RegClassID);
2257template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2258 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2259 : AMDGPU::VGPR_16RegClassID);
2262bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2263 if (AsmParser->isVI())
2265 if (AsmParser->isGFX9Plus())
2266 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2270bool AMDGPUOperand::isSDWAFP16Operand()
const {
2271 return isSDWAOperand(MVT::f16);
2274bool AMDGPUOperand::isSDWAFP32Operand()
const {
2275 return isSDWAOperand(MVT::f32);
2278bool AMDGPUOperand::isSDWAInt16Operand()
const {
2279 return isSDWAOperand(MVT::i16);
2282bool AMDGPUOperand::isSDWAInt32Operand()
const {
2283 return isSDWAOperand(MVT::i32);
2286bool AMDGPUOperand::isBoolReg()
const {
2287 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2288 (AsmParser->isWave32() && isSCSrc_b32()));
2291uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2293 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2296 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2308void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2318 addLiteralImmOperand(Inst,
Imm.Val,
2320 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2322 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2327void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2328 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2333 if (ApplyModifiers) {
2336 Val = applyInputFPModifiers(Val,
Size);
2340 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2342 bool CanUse64BitLiterals =
2343 AsmParser->has64BitLiterals() &&
2346 MCContext &Ctx = AsmParser->getContext();
2355 if (
Lit == LitModifier::None &&
2357 AsmParser->hasInv2PiInlineImm())) {
2365 bool HasMandatoryLiteral =
2368 if (
Literal.getLoBits(32) != 0 &&
2369 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2370 !HasMandatoryLiteral) {
2371 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2373 "Can't encode literal as exact 64-bit floating-point operand. "
2374 "Low 32-bits will be set to zero");
2375 Val &= 0xffffffff00000000u;
2381 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2387 Lit = LitModifier::Lit64;
2388 }
else if (
Lit == LitModifier::Lit) {
2402 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2404 Lit = LitModifier::Lit64;
2411 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2412 Literal == 0x3fc45f306725feed) {
2446 APFloat::rmNearestTiesToEven, &lost);
2450 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2457 if (
Lit != LitModifier::None) {
2486 if (
Lit == LitModifier::None &&
2496 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2503 if (
Lit == LitModifier::None &&
2511 if (!AsmParser->has64BitLiterals()) {
2512 Val =
static_cast<uint64_t
>(Val) << 32;
2519 if (
Lit == LitModifier::Lit ||
2521 Val =
static_cast<uint64_t
>(Val) << 32;
2525 if (
Lit == LitModifier::Lit)
2551 if (
Lit != LitModifier::None) {
2559void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2564bool AMDGPUOperand::isInlineValue()
const {
2572void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2583 if (Is == IS_VGPR) {
2587 return AMDGPU::VGPR_32RegClassID;
2589 return AMDGPU::VReg_64RegClassID;
2591 return AMDGPU::VReg_96RegClassID;
2593 return AMDGPU::VReg_128RegClassID;
2595 return AMDGPU::VReg_160RegClassID;
2597 return AMDGPU::VReg_192RegClassID;
2599 return AMDGPU::VReg_224RegClassID;
2601 return AMDGPU::VReg_256RegClassID;
2603 return AMDGPU::VReg_288RegClassID;
2605 return AMDGPU::VReg_320RegClassID;
2607 return AMDGPU::VReg_352RegClassID;
2609 return AMDGPU::VReg_384RegClassID;
2611 return AMDGPU::VReg_512RegClassID;
2613 return AMDGPU::VReg_1024RegClassID;
2615 }
else if (Is == IS_TTMP) {
2619 return AMDGPU::TTMP_32RegClassID;
2621 return AMDGPU::TTMP_64RegClassID;
2623 return AMDGPU::TTMP_128RegClassID;
2625 return AMDGPU::TTMP_256RegClassID;
2627 return AMDGPU::TTMP_512RegClassID;
2629 }
else if (Is == IS_SGPR) {
2633 return AMDGPU::SGPR_32RegClassID;
2635 return AMDGPU::SGPR_64RegClassID;
2637 return AMDGPU::SGPR_96RegClassID;
2639 return AMDGPU::SGPR_128RegClassID;
2641 return AMDGPU::SGPR_160RegClassID;
2643 return AMDGPU::SGPR_192RegClassID;
2645 return AMDGPU::SGPR_224RegClassID;
2647 return AMDGPU::SGPR_256RegClassID;
2649 return AMDGPU::SGPR_288RegClassID;
2651 return AMDGPU::SGPR_320RegClassID;
2653 return AMDGPU::SGPR_352RegClassID;
2655 return AMDGPU::SGPR_384RegClassID;
2657 return AMDGPU::SGPR_512RegClassID;
2659 }
else if (Is == IS_AGPR) {
2663 return AMDGPU::AGPR_32RegClassID;
2665 return AMDGPU::AReg_64RegClassID;
2667 return AMDGPU::AReg_96RegClassID;
2669 return AMDGPU::AReg_128RegClassID;
2671 return AMDGPU::AReg_160RegClassID;
2673 return AMDGPU::AReg_192RegClassID;
2675 return AMDGPU::AReg_224RegClassID;
2677 return AMDGPU::AReg_256RegClassID;
2679 return AMDGPU::AReg_288RegClassID;
2681 return AMDGPU::AReg_320RegClassID;
2683 return AMDGPU::AReg_352RegClassID;
2685 return AMDGPU::AReg_384RegClassID;
2687 return AMDGPU::AReg_512RegClassID;
2689 return AMDGPU::AReg_1024RegClassID;
2697 .
Case(
"exec", AMDGPU::EXEC)
2698 .
Case(
"vcc", AMDGPU::VCC)
2699 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2700 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2701 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2702 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2703 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2704 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2705 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2706 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2707 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2708 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2709 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2710 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2711 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2712 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2713 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2714 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2715 .
Case(
"m0", AMDGPU::M0)
2716 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2717 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2718 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2719 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2720 .
Case(
"scc", AMDGPU::SRC_SCC)
2721 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2722 .
Case(
"tba", AMDGPU::TBA)
2723 .
Case(
"tma", AMDGPU::TMA)
2724 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2725 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2726 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2727 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2728 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2729 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2730 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2731 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2732 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2733 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2734 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2735 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2736 .
Case(
"pc", AMDGPU::PC_REG)
2737 .
Case(
"null", AMDGPU::SGPR_NULL)
2741bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2742 SMLoc &EndLoc,
bool RestoreOnFailure) {
2743 auto R = parseRegister();
2744 if (!R)
return true;
2746 RegNo =
R->getReg();
2747 StartLoc =
R->getStartLoc();
2748 EndLoc =
R->getEndLoc();
2752bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2754 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2757ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2759 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2760 bool PendingErrors = getParser().hasPendingError();
2761 getParser().clearPendingErrors();
2769bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2770 RegisterKind RegKind,
2771 MCRegister Reg1, SMLoc Loc) {
2774 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2779 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2780 Reg = AMDGPU::FLAT_SCR;
2784 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2785 Reg = AMDGPU::XNACK_MASK;
2789 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2794 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2799 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2804 Error(Loc,
"register does not fit in the list");
2810 if (Reg1 !=
Reg + RegWidth / 32) {
2811 Error(Loc,
"registers in a list must have consecutive indices");
2829 {{
"ttmp"}, IS_TTMP},
2835 return Kind == IS_VGPR ||
2843 if (Str.starts_with(
Reg.Name))
2849 return !Str.getAsInteger(10, Num);
2853AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2854 const AsmToken &NextToken)
const {
2869 StringRef RegSuffix = Str.substr(
RegName.size());
2870 if (!RegSuffix.
empty()) {
2888AMDGPUAsmParser::isRegister()
2890 return isRegister(
getToken(), peekToken());
2893MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2894 unsigned SubReg,
unsigned RegWidth,
2898 unsigned AlignSize = 1;
2899 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2905 if (RegNum % AlignSize != 0) {
2906 Error(Loc,
"invalid register alignment");
2907 return MCRegister();
2910 unsigned RegIdx = RegNum / AlignSize;
2913 Error(Loc,
"invalid or unsupported register size");
2914 return MCRegister();
2918 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2919 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2920 Error(Loc,
"register index is out of range");
2921 return AMDGPU::NoRegister;
2924 if (RegKind == IS_VGPR && !
isGFX1250() && RegIdx + RegWidth / 32 > 256) {
2925 Error(Loc,
"register index is out of range");
2926 return MCRegister();
2942bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2944 int64_t RegLo, RegHi;
2948 SMLoc FirstIdxLoc = getLoc();
2955 SecondIdxLoc = getLoc();
2966 Error(FirstIdxLoc,
"invalid register index");
2971 Error(SecondIdxLoc,
"invalid register index");
2975 if (RegLo > RegHi) {
2976 Error(FirstIdxLoc,
"first register index should not exceed second index");
2980 if (RegHi == RegLo) {
2981 StringRef RegSuffix = getTokenStr();
2982 if (RegSuffix ==
".l") {
2985 }
else if (RegSuffix ==
".h") {
2991 Num =
static_cast<unsigned>(RegLo);
2992 RegWidth = 32 * ((RegHi - RegLo) + 1);
2997MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3000 SmallVectorImpl<AsmToken> &Tokens) {
3006 RegKind = IS_SPECIAL;
3013MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3016 SmallVectorImpl<AsmToken> &Tokens) {
3018 StringRef
RegName = getTokenStr();
3019 auto Loc = getLoc();
3023 Error(Loc,
"invalid register name");
3024 return MCRegister();
3032 unsigned SubReg = NoSubRegister;
3033 if (!RegSuffix.
empty()) {
3041 Error(Loc,
"invalid register index");
3042 return MCRegister();
3047 if (!ParseRegRange(RegNum, RegWidth,
SubReg))
3048 return MCRegister();
3051 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
3054MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3055 unsigned &RegNum,
unsigned &RegWidth,
3056 SmallVectorImpl<AsmToken> &Tokens) {
3058 auto ListLoc = getLoc();
3061 "expected a register or a list of registers")) {
3062 return MCRegister();
3067 auto Loc = getLoc();
3068 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3069 return MCRegister();
3070 if (RegWidth != 32) {
3071 Error(Loc,
"expected a single 32-bit register");
3072 return MCRegister();
3076 RegisterKind NextRegKind;
3078 unsigned NextRegNum, NextRegWidth;
3081 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3082 NextRegNum, NextRegWidth,
3084 return MCRegister();
3086 if (NextRegWidth != 32) {
3087 Error(Loc,
"expected a single 32-bit register");
3088 return MCRegister();
3090 if (NextRegKind != RegKind) {
3091 Error(Loc,
"registers in a list must be of the same kind");
3092 return MCRegister();
3094 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3095 return MCRegister();
3099 "expected a comma or a closing square bracket")) {
3100 return MCRegister();
3104 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3109bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3110 MCRegister &
Reg,
unsigned &RegNum,
3112 SmallVectorImpl<AsmToken> &Tokens) {
3113 auto Loc = getLoc();
3117 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3119 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3121 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3126 assert(Parser.hasPendingError());
3130 if (!subtargetHasRegister(*
TRI,
Reg)) {
3131 if (
Reg == AMDGPU::SGPR_NULL) {
3132 Error(Loc,
"'null' operand is not supported on this GPU");
3135 " register not available on this GPU");
3143bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3144 MCRegister &
Reg,
unsigned &RegNum,
3146 bool RestoreOnFailure ) {
3150 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3151 if (RestoreOnFailure) {
3152 while (!Tokens.
empty()) {
3161std::optional<StringRef>
3162AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3165 return StringRef(
".amdgcn.next_free_vgpr");
3167 return StringRef(
".amdgcn.next_free_sgpr");
3169 return std::nullopt;
3173void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3174 auto SymbolName = getGprCountSymbolName(RegKind);
3175 assert(SymbolName &&
"initializing invalid register kind");
3181bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3182 unsigned DwordRegIndex,
3183 unsigned RegWidth) {
3188 auto SymbolName = getGprCountSymbolName(RegKind);
3193 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3197 return !
Error(getLoc(),
3198 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3202 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3204 if (OldCount <= NewMax)
3210std::unique_ptr<AMDGPUOperand>
3211AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3213 SMLoc StartLoc = Tok.getLoc();
3214 SMLoc EndLoc = Tok.getEndLoc();
3215 RegisterKind RegKind;
3217 unsigned RegNum, RegWidth;
3219 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3223 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3226 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3227 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3230ParseStatus AMDGPUAsmParser::parseImm(
OperandVector &Operands,
3234 if (isRegister() || isModifier())
3237 if (
Lit == LitModifier::None) {
3238 if (trySkipId(
"lit"))
3239 Lit = LitModifier::Lit;
3240 else if (trySkipId(
"lit64"))
3241 Lit = LitModifier::Lit64;
3243 if (
Lit != LitModifier::None) {
3246 ParseStatus S = parseImm(Operands, HasSP3AbsModifier,
Lit);
3255 const auto& NextTok = peekToken();
3258 bool Negate =
false;
3266 AMDGPUOperand::Modifiers Mods;
3274 StringRef Num = getTokenStr();
3277 APFloat RealVal(APFloat::IEEEdouble());
3278 auto roundMode = APFloat::rmNearestTiesToEven;
3279 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3282 RealVal.changeSign();
3285 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3286 AMDGPUOperand::ImmTyNone,
true));
3287 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3288 Op.setModifiers(Mods);
3297 if (HasSP3AbsModifier) {
3306 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3309 if (Parser.parseExpression(Expr))
3313 if (Expr->evaluateAsAbsolute(IntVal)) {
3314 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3315 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3316 Op.setModifiers(Mods);
3318 if (
Lit != LitModifier::None)
3320 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3329ParseStatus AMDGPUAsmParser::parseReg(
OperandVector &Operands) {
3333 if (
auto R = parseRegister()) {
3341ParseStatus AMDGPUAsmParser::parseRegOrImm(
OperandVector &Operands,
3343 ParseStatus Res = parseReg(Operands);
3348 return parseImm(Operands, HasSP3AbsMod,
Lit);
3352AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3355 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3361AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3366AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3367 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3371AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3372 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3389AMDGPUAsmParser::isModifier() {
3392 AsmToken NextToken[2];
3393 peekTokens(NextToken);
3395 return isOperandModifier(Tok, NextToken[0]) ||
3396 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3397 isOpcodeModifierWithVal(Tok, NextToken[0]);
3423AMDGPUAsmParser::parseSP3NegModifier() {
3425 AsmToken NextToken[2];
3426 peekTokens(NextToken);
3429 (isRegister(NextToken[0], NextToken[1]) ||
3431 isId(NextToken[0],
"abs"))) {
3440AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
3448 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3450 SP3Neg = parseSP3NegModifier();
3453 Neg = trySkipId(
"neg");
3455 return Error(Loc,
"expected register or immediate");
3459 Abs = trySkipId(
"abs");
3464 if (trySkipId(
"lit")) {
3465 Lit = LitModifier::Lit;
3468 }
else if (trySkipId(
"lit64")) {
3469 Lit = LitModifier::Lit64;
3472 if (!has64BitLiterals())
3473 return Error(Loc,
"lit64 is not supported on this GPU");
3479 return Error(Loc,
"expected register or immediate");
3483 Res = parseRegOrImm(Operands, SP3Abs,
Lit);
3485 Res = parseReg(Operands);
3488 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3492 if (
Lit != LitModifier::None && !Operands.
back()->isImm())
3493 Error(Loc,
"expected immediate with lit modifier");
3495 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3501 if (
Lit != LitModifier::None &&
3505 AMDGPUOperand::Modifiers Mods;
3506 Mods.Abs = Abs || SP3Abs;
3507 Mods.Neg = Neg || SP3Neg;
3510 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3511 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3513 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3514 Op.setModifiers(Mods);
3520AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
3522 bool Sext = trySkipId(
"sext");
3523 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3528 Res = parseRegOrImm(Operands);
3530 Res = parseReg(Operands);
3538 AMDGPUOperand::Modifiers Mods;
3541 if (Mods.hasIntModifiers()) {
3542 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3544 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3545 Op.setModifiers(Mods);
3551ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
3552 return parseRegOrImmWithFPInputMods(Operands,
false);
3555ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
3556 return parseRegOrImmWithIntInputMods(Operands,
false);
3559ParseStatus AMDGPUAsmParser::parseVReg32OrOff(
OperandVector &Operands) {
3560 auto Loc = getLoc();
3561 if (trySkipId(
"off")) {
3562 Operands.
push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3563 AMDGPUOperand::ImmTyOff,
false));
3570 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3579unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3586 return Match_InvalidOperand;
3588 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3589 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3592 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3594 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3595 return Match_InvalidOperand;
3603 if (tryAnotherVOPDEncoding(Inst))
3604 return Match_InvalidOperand;
3606 return Match_Success;
3610 static const unsigned Variants[] = {
3620ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3621 if (isForcedDPP() && isForcedVOP3()) {
3625 if (getForcedEncodingSize() == 32) {
3630 if (isForcedVOP3()) {
3635 if (isForcedSDWA()) {
3641 if (isForcedDPP()) {
3649StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3650 if (isForcedDPP() && isForcedVOP3())
3653 if (getForcedEncodingSize() == 32)
3669AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3673 case AMDGPU::FLAT_SCR:
3675 case AMDGPU::VCC_LO:
3676 case AMDGPU::VCC_HI:
3683 return MCRegister();
3690bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3691 unsigned OpIdx)
const {
3745unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3751 case AMDGPU::V_LSHLREV_B64_e64:
3752 case AMDGPU::V_LSHLREV_B64_gfx10:
3753 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3754 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3755 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3756 case AMDGPU::V_LSHRREV_B64_e64:
3757 case AMDGPU::V_LSHRREV_B64_gfx10:
3758 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3759 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3760 case AMDGPU::V_ASHRREV_I64_e64:
3761 case AMDGPU::V_ASHRREV_I64_gfx10:
3762 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3763 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3764 case AMDGPU::V_LSHL_B64_e64:
3765 case AMDGPU::V_LSHR_B64_e64:
3766 case AMDGPU::V_ASHR_I64_e64:
3779 bool AddMandatoryLiterals =
false) {
3782 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3786 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3788 return {getNamedOperandIdx(Opcode, OpName::src0X),
3789 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3790 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3791 getNamedOperandIdx(Opcode, OpName::src0Y),
3792 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3793 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3798 return {getNamedOperandIdx(Opcode, OpName::src0),
3799 getNamedOperandIdx(Opcode, OpName::src1),
3800 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3803bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3806 return !isInlineConstant(Inst,
OpIdx);
3813 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3824 const unsigned Opcode = Inst.
getOpcode();
3825 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3828 if (!LaneSelOp.
isReg())
3831 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3834bool AMDGPUAsmParser::validateConstantBusLimitations(
3836 const unsigned Opcode = Inst.
getOpcode();
3837 const MCInstrDesc &
Desc = MII.
get(Opcode);
3838 MCRegister LastSGPR;
3839 unsigned ConstantBusUseCount = 0;
3840 unsigned NumLiterals = 0;
3841 unsigned LiteralSize;
3843 if (!(
Desc.TSFlags &
3858 SmallDenseSet<MCRegister> SGPRsUsed;
3859 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3861 SGPRsUsed.
insert(SGPRUsed);
3862 ++ConstantBusUseCount;
3867 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3869 for (
int OpIdx : OpIndices) {
3874 if (usesConstantBus(Inst,
OpIdx)) {
3883 if (SGPRsUsed.
insert(LastSGPR).second) {
3884 ++ConstantBusUseCount;
3904 if (NumLiterals == 0) {
3907 }
else if (LiteralSize !=
Size) {
3913 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3915 "invalid operand (violates constant bus restrictions)");
3922std::optional<unsigned>
3923AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3925 const unsigned Opcode = Inst.
getOpcode();
3931 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3932 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3940 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3941 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3942 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250;
3946 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3947 int I = getNamedOperandIdx(Opcode, OpName);
3951 int64_t
Imm =
Op.getImm();
3957 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3958 OpName::vsrc2Y, OpName::imm}) {
3959 int I = getNamedOperandIdx(Opcode, OpName);
3969 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3970 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3972 return InvalidCompOprIdx;
3975bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
3982 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
3983 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
3984 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
3986 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
3990 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
3991 if (!InvalidCompOprIdx.has_value())
3994 auto CompOprIdx = *InvalidCompOprIdx;
3997 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3998 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3999 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4001 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4002 if (CompOprIdx == VOPD::Component::DST) {
4004 Error(Loc,
"dst registers must be distinct");
4006 Error(Loc,
"one dst register must be even and the other odd");
4008 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4009 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4010 " operands must use different VGPR banks");
4018bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4020 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4021 if (!InvalidCompOprIdx.has_value())
4025 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4026 if (InvalidCompOprIdx.has_value()) {
4031 if (*InvalidCompOprIdx == VOPD::Component::DST)
4044bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4045 const unsigned Opcode = Inst.
getOpcode();
4060 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4061 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4062 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4063 int I = getNamedOperandIdx(Opcode, OpName);
4070 return !tryVOPD3(Inst);
4075bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4076 const unsigned Opcode = Inst.
getOpcode();
4081 return tryVOPD(Inst);
4082 return tryVOPD3(Inst);
4085bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4091 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4102bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4110 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4111 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4112 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4120 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4121 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4126 bool IsPackedD16 =
false;
4130 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4131 IsPackedD16 = D16Idx >= 0;
4136 if ((VDataSize / 4) ==
DataSize + TFESize)
4141 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4143 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4145 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4149bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4158 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4160 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4162 ? AMDGPU::OpName::srsrc
4163 : AMDGPU::OpName::rsrc;
4164 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4165 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4166 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4170 assert(SrsrcIdx > VAddr0Idx);
4173 if (BaseOpcode->
BVH) {
4174 if (IsA16 == BaseOpcode->
A16)
4176 Error(IDLoc,
"image address size does not match a16");
4182 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4183 unsigned ActualAddrSize =
4184 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4186 unsigned ExpectedAddrSize =
4190 if (hasPartialNSAEncoding() &&
4193 int VAddrLastIdx = SrsrcIdx - 1;
4194 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4196 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4199 if (ExpectedAddrSize > 12)
4200 ExpectedAddrSize = 16;
4205 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4209 if (ActualAddrSize == ExpectedAddrSize)
4212 Error(IDLoc,
"image address size does not match dim and a16");
4216bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4223 if (!
Desc.mayLoad() || !
Desc.mayStore())
4226 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4233 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4236bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4244 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4252 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4255bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4270 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4271 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4278bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4286 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4289 if (!BaseOpcode->
MSAA)
4292 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4298 return DimInfo->
MSAA;
4304 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4305 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4306 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4316bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4325 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4328 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4336 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4340bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4345 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4348 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4351 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4358 Error(getOperandLoc(Operands, Src0Idx),
4359 "source operand must be either a VGPR or an inline constant");
4366bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4369 const MCInstrDesc &
Desc = MII.
get(Opcode);
4372 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4375 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4379 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4380 Error(getOperandLoc(Operands, Src2Idx),
4381 "inline constants are not allowed for this operand");
4388bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4396 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4397 if (BlgpIdx != -1) {
4398 if (
const MFMA_F8F6F4_Info *
Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4399 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4409 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4410 Error(getOperandLoc(Operands, Src0Idx),
4411 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4416 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4417 Error(getOperandLoc(Operands, Src1Idx),
4418 "wrong register tuple size for blgp value " + Twine(BLGP));
4426 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4430 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4434 MCRegister Src2Reg = Src2.
getReg();
4436 if (Src2Reg == DstReg)
4441 .getSizeInBits() <= 128)
4444 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4445 Error(getOperandLoc(Operands, Src2Idx),
4446 "source 2 operand must not partially overlap with dst");
4453bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4457 case V_DIV_SCALE_F32_gfx6_gfx7:
4458 case V_DIV_SCALE_F32_vi:
4459 case V_DIV_SCALE_F32_gfx10:
4460 case V_DIV_SCALE_F64_gfx6_gfx7:
4461 case V_DIV_SCALE_F64_vi:
4462 case V_DIV_SCALE_F64_gfx10:
4468 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4469 AMDGPU::OpName::src2_modifiers,
4470 AMDGPU::OpName::src2_modifiers}) {
4481bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4489 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4498bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4505 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4513 case AMDGPU::V_SUBREV_F32_e32:
4514 case AMDGPU::V_SUBREV_F32_e64:
4515 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4516 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4517 case AMDGPU::V_SUBREV_F32_e32_vi:
4518 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4519 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4520 case AMDGPU::V_SUBREV_F32_e64_vi:
4522 case AMDGPU::V_SUBREV_CO_U32_e32:
4523 case AMDGPU::V_SUBREV_CO_U32_e64:
4524 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4525 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4527 case AMDGPU::V_SUBBREV_U32_e32:
4528 case AMDGPU::V_SUBBREV_U32_e64:
4529 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4530 case AMDGPU::V_SUBBREV_U32_e32_vi:
4531 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4532 case AMDGPU::V_SUBBREV_U32_e64_vi:
4534 case AMDGPU::V_SUBREV_U32_e32:
4535 case AMDGPU::V_SUBREV_U32_e64:
4536 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4537 case AMDGPU::V_SUBREV_U32_e32_vi:
4538 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4539 case AMDGPU::V_SUBREV_U32_e64_vi:
4541 case AMDGPU::V_SUBREV_F16_e32:
4542 case AMDGPU::V_SUBREV_F16_e64:
4543 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4544 case AMDGPU::V_SUBREV_F16_e32_vi:
4545 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4546 case AMDGPU::V_SUBREV_F16_e64_vi:
4548 case AMDGPU::V_SUBREV_U16_e32:
4549 case AMDGPU::V_SUBREV_U16_e64:
4550 case AMDGPU::V_SUBREV_U16_e32_vi:
4551 case AMDGPU::V_SUBREV_U16_e64_vi:
4553 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4554 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4555 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4557 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4558 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4560 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4561 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4563 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4564 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4566 case AMDGPU::V_LSHRREV_B32_e32:
4567 case AMDGPU::V_LSHRREV_B32_e64:
4568 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4569 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4570 case AMDGPU::V_LSHRREV_B32_e32_vi:
4571 case AMDGPU::V_LSHRREV_B32_e64_vi:
4572 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4573 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4575 case AMDGPU::V_ASHRREV_I32_e32:
4576 case AMDGPU::V_ASHRREV_I32_e64:
4577 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4578 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4579 case AMDGPU::V_ASHRREV_I32_e32_vi:
4580 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4581 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4582 case AMDGPU::V_ASHRREV_I32_e64_vi:
4584 case AMDGPU::V_LSHLREV_B32_e32:
4585 case AMDGPU::V_LSHLREV_B32_e64:
4586 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4587 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4588 case AMDGPU::V_LSHLREV_B32_e32_vi:
4589 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4590 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4591 case AMDGPU::V_LSHLREV_B32_e64_vi:
4593 case AMDGPU::V_LSHLREV_B16_e32:
4594 case AMDGPU::V_LSHLREV_B16_e64:
4595 case AMDGPU::V_LSHLREV_B16_e32_vi:
4596 case AMDGPU::V_LSHLREV_B16_e64_vi:
4597 case AMDGPU::V_LSHLREV_B16_gfx10:
4599 case AMDGPU::V_LSHRREV_B16_e32:
4600 case AMDGPU::V_LSHRREV_B16_e64:
4601 case AMDGPU::V_LSHRREV_B16_e32_vi:
4602 case AMDGPU::V_LSHRREV_B16_e64_vi:
4603 case AMDGPU::V_LSHRREV_B16_gfx10:
4605 case AMDGPU::V_ASHRREV_I16_e32:
4606 case AMDGPU::V_ASHRREV_I16_e64:
4607 case AMDGPU::V_ASHRREV_I16_e32_vi:
4608 case AMDGPU::V_ASHRREV_I16_e64_vi:
4609 case AMDGPU::V_ASHRREV_I16_gfx10:
4611 case AMDGPU::V_LSHLREV_B64_e64:
4612 case AMDGPU::V_LSHLREV_B64_gfx10:
4613 case AMDGPU::V_LSHLREV_B64_vi:
4615 case AMDGPU::V_LSHRREV_B64_e64:
4616 case AMDGPU::V_LSHRREV_B64_gfx10:
4617 case AMDGPU::V_LSHRREV_B64_vi:
4619 case AMDGPU::V_ASHRREV_I64_e64:
4620 case AMDGPU::V_ASHRREV_I64_gfx10:
4621 case AMDGPU::V_ASHRREV_I64_vi:
4623 case AMDGPU::V_PK_LSHLREV_B16:
4624 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4625 case AMDGPU::V_PK_LSHLREV_B16_vi:
4627 case AMDGPU::V_PK_LSHRREV_B16:
4628 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4629 case AMDGPU::V_PK_LSHRREV_B16_vi:
4630 case AMDGPU::V_PK_ASHRREV_I16:
4631 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4632 case AMDGPU::V_PK_ASHRREV_I16_vi:
4639bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4641 using namespace SIInstrFlags;
4642 const unsigned Opcode = Inst.
getOpcode();
4643 const MCInstrDesc &
Desc = MII.
get(Opcode);
4648 if ((
Desc.TSFlags & Enc) == 0)
4651 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4652 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4656 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4659 Error(getOperandLoc(Operands, SrcIdx),
4660 "lds_direct is not supported on this GPU");
4665 Error(getOperandLoc(Operands, SrcIdx),
4666 "lds_direct cannot be used with this instruction");
4670 if (SrcName != OpName::src0) {
4671 Error(getOperandLoc(Operands, SrcIdx),
4672 "lds_direct may be used as src0 only");
4681SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4682 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4683 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4684 if (
Op.isFlatOffset())
4685 return Op.getStartLoc();
4690bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4693 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4699 return validateFlatOffset(Inst, Operands);
4702 return validateSMEMOffset(Inst, Operands);
4708 const unsigned OffsetSize = 24;
4709 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4710 Error(getFlatOffsetLoc(Operands),
4711 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4712 "-bit unsigned offset for buffer ops");
4716 const unsigned OffsetSize = 16;
4717 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4718 Error(getFlatOffsetLoc(Operands),
4719 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4726bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4733 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4737 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4738 Error(getFlatOffsetLoc(Operands),
4739 "flat offset modifier is not supported on this GPU");
4746 bool AllowNegative =
4749 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4750 Error(getFlatOffsetLoc(Operands),
4751 Twine(
"expected a ") +
4752 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4753 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4760SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4762 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4763 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4764 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4765 return Op.getStartLoc();
4770bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4780 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4794 Error(getSMEMOffsetLoc(Operands),
4796 ?
"expected a 23-bit unsigned offset for buffer ops"
4797 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4798 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4799 :
"expected a 21-bit signed offset");
4804bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4807 const MCInstrDesc &
Desc = MII.
get(Opcode);
4811 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4812 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4814 const int OpIndices[] = { Src0Idx, Src1Idx };
4816 unsigned NumExprs = 0;
4817 unsigned NumLiterals = 0;
4820 for (
int OpIdx : OpIndices) {
4821 if (
OpIdx == -1)
break;
4827 std::optional<int64_t>
Imm;
4830 }
else if (MO.
isExpr()) {
4839 if (!
Imm.has_value()) {
4841 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4845 if (NumLiterals == 0 || LiteralValue !=
Value) {
4853 if (NumLiterals + NumExprs <= 1)
4856 Error(getOperandLoc(Operands, Src1Idx),
4857 "only one unique literal operand is allowed");
4861bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4864 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4874 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4875 if (OpSelIdx != -1) {
4879 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4880 if (OpSelHiIdx != -1) {
4889 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4899 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4900 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4901 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4902 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4904 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4905 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4911 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4913 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4923 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4924 if (Src2Idx != -1) {
4925 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4935bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4936 if (!hasTrue16Insts())
4938 const MCRegisterInfo *
MRI = getMRI();
4940 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4946 if (OpSelOpValue == 0)
4948 unsigned OpCount = 0;
4949 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4950 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4951 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4956 MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(
Op.getReg())) {
4958 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4959 if (OpSelOpIsHi != VGPRSuffixIsHi)
4968bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4969 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4982 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
4993 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4994 AMDGPU::OpName::src1_modifiers,
4995 AMDGPU::OpName::src2_modifiers};
4997 for (
unsigned i = 0; i < 3; ++i) {
5007bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5010 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5011 if (DppCtrlIdx >= 0) {
5018 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5019 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5020 :
"DP ALU dpp only supports row_newbcast");
5025 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5026 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5029 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5031 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5034 Error(getOperandLoc(Operands, Src1Idx),
5035 "invalid operand for instruction");
5039 Error(getInstLoc(Operands),
5040 "src1 immediate operand invalid for instruction");
5050bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5051 return (
Reg == AMDGPU::VCC && isWave64()) ||
5052 (
Reg == AMDGPU::VCC_LO && isWave32());
5056bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5059 const MCInstrDesc &
Desc = MII.
get(Opcode);
5060 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5062 !HasMandatoryLiteral && !
isVOPD(Opcode))
5067 std::optional<unsigned> LiteralOpIdx;
5070 for (
int OpIdx : OpIndices) {
5080 std::optional<int64_t>
Imm;
5086 bool IsAnotherLiteral =
false;
5087 if (!
Imm.has_value()) {
5089 IsAnotherLiteral =
true;
5090 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5095 HasMandatoryLiteral);
5101 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5103 "invalid operand for instruction");
5107 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5114 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5115 !getFeatureBits()[FeatureVOP3Literal]) {
5117 "literal operands are not supported");
5121 if (LiteralOpIdx && IsAnotherLiteral) {
5122 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5123 getOperandLoc(Operands, *LiteralOpIdx)),
5124 "only one unique literal operand is allowed");
5128 if (IsAnotherLiteral)
5129 LiteralOpIdx =
OpIdx;
5152bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5160 ? AMDGPU::OpName::data0
5161 : AMDGPU::OpName::vdata;
5163 const MCRegisterInfo *
MRI = getMRI();
5169 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5173 auto FB = getFeatureBits();
5174 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5175 if (DataAreg < 0 || DstAreg < 0)
5177 return DstAreg == DataAreg;
5180 return DstAreg < 1 && DataAreg < 1;
5183bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5184 auto FB = getFeatureBits();
5185 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5189 const MCRegisterInfo *
MRI = getMRI();
5192 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5195 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5199 case AMDGPU::DS_LOAD_TR6_B96:
5200 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5204 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5205 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5209 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5210 if (VAddrIdx != -1) {
5212 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5213 if ((
Sub - AMDGPU::VGPR0) & 1)
5218 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5219 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5224 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5225 const MCRegisterClass &AGPR32 =
MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
5231 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5244SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5245 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5246 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5248 return Op.getStartLoc();
5253bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5256 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5259 SMLoc BLGPLoc = getBLGPLoc(Operands);
5262 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5263 auto FB = getFeatureBits();
5264 bool UsesNeg =
false;
5265 if (FB[AMDGPU::FeatureGFX940Insts]) {
5267 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5268 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5269 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5270 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5275 if (IsNeg == UsesNeg)
5279 UsesNeg ?
"invalid modifier: blgp is not supported"
5280 :
"invalid modifier: neg is not supported");
5285bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5291 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5292 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5293 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5294 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5297 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5300 if (
Reg == AMDGPU::SGPR_NULL)
5303 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5307bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5313 return validateGWS(Inst, Operands);
5318 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5323 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5324 Error(S,
"gds modifier is not supported on this GPU");
5332bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5334 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5338 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5339 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5342 const MCRegisterInfo *
MRI = getMRI();
5343 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5345 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5348 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5350 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5357bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5360 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5361 AMDGPU::OpName::cpol);
5369 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5372 Error(S,
"scale_offset is not supported on this GPU");
5375 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5378 Error(S,
"nv is not supported on this GPU");
5383 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5386 Error(S,
"scale_offset is not supported for this instruction");
5390 return validateTHAndScopeBits(Inst, Operands, CPol);
5395 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5396 Error(S,
"cache policy is not supported for SMRD instructions");
5400 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5409 if (!(TSFlags & AllowSCCModifier)) {
5410 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5414 "scc modifier is not supported for this instruction on this GPU");
5425 :
"instruction must use glc");
5430 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5433 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5435 :
"instruction must not use glc");
5443bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5445 const unsigned CPol) {
5449 const unsigned Opcode = Inst.
getOpcode();
5450 const MCInstrDesc &TID = MII.
get(Opcode);
5453 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5461 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5469 return PrintError(
"invalid th value for SMEM instruction");
5476 return PrintError(
"scope and th combination is not valid");
5482 return PrintError(
"invalid th value for atomic instructions");
5485 return PrintError(
"invalid th value for store instructions");
5488 return PrintError(
"invalid th value for load instructions");
5494bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5497 if (
Desc.mayStore() &&
5499 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5500 if (Loc != getInstLoc(Operands)) {
5501 Error(Loc,
"TFE modifier has no meaning for store instructions");
5509bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5515 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5516 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5520 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5528 static const char *FmtNames[] = {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
5529 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
5532 Error(getOperandLoc(Operands, SrcIdx),
5533 "wrong register tuple size for " + Twine(FmtNames[Fmt]));
5537 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5538 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5541bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5543 if (!validateLdsDirect(Inst, Operands))
5545 if (!validateTrue16OpSel(Inst)) {
5546 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5547 "op_sel operand conflicts with 16-bit operand suffix");
5550 if (!validateSOPLiteral(Inst, Operands))
5552 if (!validateVOPLiteral(Inst, Operands)) {
5555 if (!validateConstantBusLimitations(Inst, Operands)) {
5558 if (!validateVOPD(Inst, Operands)) {
5561 if (!validateIntClampSupported(Inst)) {
5562 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5563 "integer clamping is not supported on this GPU");
5566 if (!validateOpSel(Inst)) {
5567 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5568 "invalid op_sel operand");
5571 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5572 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5573 "invalid neg_lo operand");
5576 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5577 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5578 "invalid neg_hi operand");
5581 if (!validateDPP(Inst, Operands)) {
5585 if (!validateMIMGD16(Inst)) {
5586 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5587 "d16 modifier is not supported on this GPU");
5590 if (!validateMIMGDim(Inst, Operands)) {
5591 Error(IDLoc,
"missing dim operand");
5594 if (!validateTensorR128(Inst)) {
5595 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5596 "instruction must set modifier r128=0");
5599 if (!validateMIMGMSAA(Inst)) {
5600 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5601 "invalid dim; must be MSAA type");
5604 if (!validateMIMGDataSize(Inst, IDLoc)) {
5607 if (!validateMIMGAddrSize(Inst, IDLoc))
5609 if (!validateMIMGAtomicDMask(Inst)) {
5610 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5611 "invalid atomic image dmask");
5614 if (!validateMIMGGatherDMask(Inst)) {
5615 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5616 "invalid image_gather dmask: only one bit must be set");
5619 if (!validateMovrels(Inst, Operands)) {
5622 if (!validateOffset(Inst, Operands)) {
5625 if (!validateMAIAccWrite(Inst, Operands)) {
5628 if (!validateMAISrc2(Inst, Operands)) {
5631 if (!validateMFMA(Inst, Operands)) {
5634 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5638 if (!validateAGPRLdSt(Inst)) {
5639 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5640 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5641 :
"invalid register class: agpr loads and stores not supported on this GPU"
5645 if (!validateVGPRAlign(Inst)) {
5647 "invalid register class: vgpr tuples must be 64 bit aligned");
5650 if (!validateDS(Inst, Operands)) {
5654 if (!validateBLGP(Inst, Operands)) {
5658 if (!validateDivScale(Inst)) {
5659 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5662 if (!validateWaitCnt(Inst, Operands)) {
5665 if (!validateTFE(Inst, Operands)) {
5668 if (!validateWMMA(Inst, Operands)) {
5677 unsigned VariantID = 0);
5681 unsigned VariantID);
5683bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5688bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5689 const FeatureBitset &FBS,
5690 ArrayRef<unsigned> Variants) {
5691 for (
auto Variant : Variants) {
5699bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5701 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5704 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5709 getParser().clearPendingErrors();
5713 StringRef VariantName = getMatchedVariantName();
5714 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5717 " variant of this instruction is not supported"));
5721 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5722 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5724 FeatureBitset FeaturesWS32 = getFeatureBits();
5725 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5726 .
flip(AMDGPU::FeatureWavefrontSize32);
5727 FeatureBitset AvailableFeaturesWS32 =
5728 ComputeAvailableFeatures(FeaturesWS32);
5730 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5731 return Error(IDLoc,
"instruction requires wavesize=32");
5735 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5736 return Error(IDLoc,
"instruction not supported on this GPU");
5741 return Error(IDLoc,
"invalid instruction" + Suggestion);
5747 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5748 if (
Op.isToken() && InvalidOprIdx > 1) {
5749 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5750 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5755bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5758 uint64_t &ErrorInfo,
5759 bool MatchingInlineAsm) {
5762 unsigned Result = Match_Success;
5763 for (
auto Variant : getMatchedVariants()) {
5765 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5770 if (R == Match_Success || R == Match_MissingFeature ||
5771 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5772 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5773 Result != Match_MissingFeature)) {
5777 if (R == Match_Success)
5781 if (Result == Match_Success) {
5782 if (!validateInstruction(Inst, IDLoc, Operands)) {
5789 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5790 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5796 case Match_MissingFeature:
5800 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5802 case Match_InvalidOperand: {
5803 SMLoc ErrorLoc = IDLoc;
5804 if (ErrorInfo != ~0ULL) {
5805 if (ErrorInfo >= Operands.
size()) {
5806 return Error(IDLoc,
"too few operands for instruction");
5808 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5809 if (ErrorLoc == SMLoc())
5813 return Error(ErrorLoc,
"invalid VOPDY instruction");
5815 return Error(ErrorLoc,
"invalid operand for instruction");
5818 case Match_MnemonicFail:
5824bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5829 if (getParser().parseAbsoluteExpression(Tmp)) {
5832 Ret =
static_cast<uint32_t
>(Tmp);
5836bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5837 if (!getSTI().getTargetTriple().isAMDGCN())
5838 return TokError(
"directive only supported for amdgcn architecture");
5840 std::string TargetIDDirective;
5841 SMLoc TargetStart = getTok().getLoc();
5842 if (getParser().parseEscapedString(TargetIDDirective))
5845 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5846 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5847 return getParser().Error(TargetRange.
Start,
5848 (Twine(
".amdgcn_target directive's target id ") +
5849 Twine(TargetIDDirective) +
5850 Twine(
" does not match the specified target id ") +
5851 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5856bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5860bool AMDGPUAsmParser::calculateGPRBlocks(
5861 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5862 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5863 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5864 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5865 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5871 const MCExpr *
NumSGPRs = NextFreeSGPR;
5872 int64_t EvaluatedSGPRs;
5877 unsigned MaxAddressableNumSGPRs =
5880 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5881 !Features.
test(FeatureSGPRInitBug) &&
5882 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5883 return OutOfRangeError(SGPRRange);
5885 const MCExpr *ExtraSGPRs =
5889 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5890 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5891 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5892 return OutOfRangeError(SGPRRange);
5894 if (Features.
test(FeatureSGPRInitBug))
5901 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5902 unsigned Granule) ->
const MCExpr * {
5906 const MCExpr *AlignToGPR =
5908 const MCExpr *DivGPR =
5914 VGPRBlocks = GetNumGPRBlocks(
5923bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5924 if (!getSTI().getTargetTriple().isAMDGCN())
5925 return TokError(
"directive only supported for amdgcn architecture");
5928 return TokError(
"directive only supported for amdhsa OS");
5930 StringRef KernelName;
5931 if (getParser().parseIdentifier(KernelName))
5934 AMDGPU::MCKernelDescriptor KD =
5946 const MCExpr *NextFreeVGPR = ZeroExpr;
5948 const MCExpr *NamedBarCnt = ZeroExpr;
5949 uint64_t SharedVGPRCount = 0;
5950 uint64_t PreloadLength = 0;
5951 uint64_t PreloadOffset = 0;
5953 const MCExpr *NextFreeSGPR = ZeroExpr;
5956 unsigned ImpliedUserSGPRCount = 0;
5960 std::optional<unsigned> ExplicitUserSGPRCount;
5961 const MCExpr *ReserveVCC = OneExpr;
5962 const MCExpr *ReserveFlatScr = OneExpr;
5963 std::optional<bool> EnableWavefrontSize32;
5969 SMRange IDRange = getTok().getLocRange();
5970 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5973 if (
ID ==
".end_amdhsa_kernel")
5977 return TokError(
".amdhsa_ directives cannot be repeated");
5979 SMLoc ValStart = getLoc();
5980 const MCExpr *ExprVal;
5981 if (getParser().parseExpression(ExprVal))
5983 SMLoc ValEnd = getLoc();
5984 SMRange ValRange = SMRange(ValStart, ValEnd);
5987 uint64_t Val = IVal;
5988 bool EvaluatableExpr;
5989 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5991 return OutOfRangeError(ValRange);
5995#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5996 if (!isUInt<ENTRY##_WIDTH>(Val)) \
5997 return OutOfRangeError(RANGE); \
5998 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6003#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6005 return Error(IDRange.Start, "directive should have resolvable expression", \
6008 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6011 return OutOfRangeError(ValRange);
6013 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6016 return OutOfRangeError(ValRange);
6018 }
else if (
ID ==
".amdhsa_kernarg_size") {
6020 return OutOfRangeError(ValRange);
6022 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6024 ExplicitUserSGPRCount = Val;
6025 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6029 "directive is not supported with architected flat scratch",
6032 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6035 ImpliedUserSGPRCount += 4;
6036 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6039 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6042 return OutOfRangeError(ValRange);
6046 ImpliedUserSGPRCount += Val;
6047 PreloadLength = Val;
6049 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6052 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6055 return OutOfRangeError(ValRange);
6059 PreloadOffset = Val;
6060 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6063 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6066 ImpliedUserSGPRCount += 2;
6067 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6070 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6073 ImpliedUserSGPRCount += 2;
6074 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6077 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6080 ImpliedUserSGPRCount += 2;
6081 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6084 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6087 ImpliedUserSGPRCount += 2;
6088 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6091 "directive is not supported with architected flat scratch",
6095 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6098 ImpliedUserSGPRCount += 2;
6099 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6102 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6105 ImpliedUserSGPRCount += 1;
6106 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6108 if (IVersion.
Major < 10)
6109 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6110 EnableWavefrontSize32 = Val;
6112 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6114 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6116 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6118 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6121 "directive is not supported with architected flat scratch",
6124 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6126 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6130 "directive is not supported without architected flat scratch",
6133 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6135 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6137 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6139 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6141 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6143 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6145 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6147 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6149 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6151 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6153 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6155 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6156 VGPRRange = ValRange;
6157 NextFreeVGPR = ExprVal;
6158 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6159 SGPRRange = ValRange;
6160 NextFreeSGPR = ExprVal;
6161 }
else if (
ID ==
".amdhsa_accum_offset") {
6163 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6164 AccumOffset = ExprVal;
6165 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6167 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6168 NamedBarCnt = ExprVal;
6169 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6171 return OutOfRangeError(ValRange);
6172 ReserveVCC = ExprVal;
6173 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6174 if (IVersion.
Major < 7)
6175 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6178 "directive is not supported with architected flat scratch",
6181 return OutOfRangeError(ValRange);
6182 ReserveFlatScr = ExprVal;
6183 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6184 if (IVersion.
Major < 8)
6185 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6187 return OutOfRangeError(ValRange);
6188 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6189 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6191 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6193 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6195 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6197 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6199 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6201 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6203 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6205 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6207 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6208 if (IVersion.
Major >= 12)
6209 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6211 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6213 }
else if (
ID ==
".amdhsa_ieee_mode") {
6214 if (IVersion.
Major >= 12)
6215 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6217 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6219 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6220 if (IVersion.
Major < 9)
6221 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6223 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6225 }
else if (
ID ==
".amdhsa_tg_split") {
6227 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6230 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6233 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6235 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6237 }
else if (
ID ==
".amdhsa_memory_ordered") {
6238 if (IVersion.
Major < 10)
6239 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6241 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6243 }
else if (
ID ==
".amdhsa_forward_progress") {
6244 if (IVersion.
Major < 10)
6245 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6247 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6249 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6251 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6252 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6254 SharedVGPRCount = Val;
6256 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6258 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6259 if (IVersion.
Major < 11)
6260 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6261 if (IVersion.
Major == 11) {
6263 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6267 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6270 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6273 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6275 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6277 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6279 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6282 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6284 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6286 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6288 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6290 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6292 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6294 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6296 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6298 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6300 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6301 if (IVersion.
Major < 12)
6302 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6304 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6307 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6310#undef PARSE_BITS_ENTRY
6313 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6314 return TokError(
".amdhsa_next_free_vgpr directive is required");
6316 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6317 return TokError(
".amdhsa_next_free_sgpr directive is required");
6319 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6324 if (PreloadLength) {
6330 const MCExpr *VGPRBlocks;
6331 const MCExpr *SGPRBlocks;
6332 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6333 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6334 EnableWavefrontSize32, NextFreeVGPR,
6335 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6339 int64_t EvaluatedVGPRBlocks;
6340 bool VGPRBlocksEvaluatable =
6341 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6342 if (VGPRBlocksEvaluatable &&
6344 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6345 return OutOfRangeError(VGPRRange);
6349 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6350 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6352 int64_t EvaluatedSGPRBlocks;
6353 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6355 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6356 return OutOfRangeError(SGPRRange);
6359 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6360 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6362 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6363 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6364 "enabled user SGPRs");
6368 return TokError(
"too many user SGPRs enabled");
6372 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6373 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6377 return TokError(
"too many user SGPRs enabled");
6381 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6382 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6387 return TokError(
"Kernarg size should be resolvable");
6388 uint64_t kernarg_size = IVal;
6389 if (PreloadLength && kernarg_size &&
6390 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6391 return TokError(
"Kernarg preload length + offset is larger than the "
6392 "kernarg segment size");
6395 if (!Seen.
contains(
".amdhsa_accum_offset"))
6396 return TokError(
".amdhsa_accum_offset directive is required");
6397 int64_t EvaluatedAccum;
6398 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6399 uint64_t UEvaluatedAccum = EvaluatedAccum;
6400 if (AccumEvaluatable &&
6401 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6402 return TokError(
"accum_offset should be in range [4..256] in "
6405 int64_t EvaluatedNumVGPR;
6406 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6409 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6410 return TokError(
"accum_offset exceeds total VGPR allocation");
6416 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6417 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6423 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6424 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6427 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6429 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6430 return TokError(
"shared_vgpr_count directive not valid on "
6431 "wavefront size 32");
6434 if (VGPRBlocksEvaluatable &&
6435 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6437 return TokError(
"shared_vgpr_count*2 + "
6438 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6443 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6444 NextFreeVGPR, NextFreeSGPR,
6445 ReserveVCC, ReserveFlatScr);
6449bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6451 if (ParseAsAbsoluteExpression(
Version))
6454 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6458bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6459 AMDGPUMCKernelCodeT &
C) {
6462 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6463 Parser.eatToEndOfStatement();
6467 SmallString<40> ErrStr;
6468 raw_svector_ostream Err(ErrStr);
6469 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6470 return TokError(Err.
str());
6474 if (
ID ==
"enable_wavefront_size32") {
6477 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6479 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6482 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6486 if (
ID ==
"wavefront_size") {
6487 if (
C.wavefront_size == 5) {
6489 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6491 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6492 }
else if (
C.wavefront_size == 6) {
6494 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6501bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6502 AMDGPUMCKernelCodeT KernelCode;
6511 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6514 if (
ID ==
".end_amd_kernel_code_t")
6517 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6522 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6527bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6528 StringRef KernelName;
6529 if (!parseId(KernelName,
"expected symbol name"))
6532 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6539bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6540 if (!getSTI().getTargetTriple().isAMDGCN()) {
6541 return Error(getLoc(),
6542 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6546 auto TargetIDDirective = getLexer().getTok().getStringContents();
6547 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6548 return Error(getParser().getTok().getLoc(),
"target id must match options");
6550 getTargetStreamer().EmitISAVersion();
6556bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6559 std::string HSAMetadataString;
6564 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6565 return Error(getLoc(),
"invalid HSA metadata");
6572bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6573 const char *AssemblerDirectiveEnd,
6574 std::string &CollectString) {
6576 raw_string_ostream CollectStream(CollectString);
6578 getLexer().setSkipSpace(
false);
6580 bool FoundEnd =
false;
6583 CollectStream << getTokenStr();
6587 if (trySkipId(AssemblerDirectiveEnd)) {
6592 CollectStream << Parser.parseStringToEndOfStatement()
6593 <<
getContext().getAsmInfo()->getSeparatorString();
6595 Parser.eatToEndOfStatement();
6598 getLexer().setSkipSpace(
true);
6601 return TokError(Twine(
"expected directive ") +
6602 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6609bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6615 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6616 if (!PALMetadata->setFromString(
String))
6617 return Error(getLoc(),
"invalid PAL metadata");
6622bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6624 return Error(getLoc(),
6626 "not available on non-amdpal OSes")).str());
6629 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6630 PALMetadata->setLegacy();
6633 if (ParseAsAbsoluteExpression(
Key)) {
6634 return TokError(Twine(
"invalid value in ") +
6638 return TokError(Twine(
"expected an even number of values in ") +
6641 if (ParseAsAbsoluteExpression(
Value)) {
6642 return TokError(Twine(
"invalid value in ") +
6645 PALMetadata->setRegister(
Key,
Value);
6654bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6655 if (getParser().checkForValidSection())
6659 SMLoc NameLoc = getLoc();
6660 if (getParser().parseIdentifier(Name))
6661 return TokError(
"expected identifier in directive");
6664 if (getParser().parseComma())
6670 SMLoc SizeLoc = getLoc();
6671 if (getParser().parseAbsoluteExpression(
Size))
6674 return Error(SizeLoc,
"size must be non-negative");
6675 if (
Size > LocalMemorySize)
6676 return Error(SizeLoc,
"size is too large");
6678 int64_t Alignment = 4;
6680 SMLoc AlignLoc = getLoc();
6681 if (getParser().parseAbsoluteExpression(Alignment))
6684 return Error(AlignLoc,
"alignment must be a power of two");
6689 if (Alignment >= 1u << 31)
6690 return Error(AlignLoc,
"alignment is too large");
6696 Symbol->redefineIfPossible();
6697 if (!
Symbol->isUndefined())
6698 return Error(NameLoc,
"invalid symbol redefinition");
6700 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6704bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6705 StringRef IDVal = DirectiveID.
getString();
6708 if (IDVal ==
".amdhsa_kernel")
6709 return ParseDirectiveAMDHSAKernel();
6711 if (IDVal ==
".amdhsa_code_object_version")
6712 return ParseDirectiveAMDHSACodeObjectVersion();
6716 return ParseDirectiveHSAMetadata();
6718 if (IDVal ==
".amd_kernel_code_t")
6719 return ParseDirectiveAMDKernelCodeT();
6721 if (IDVal ==
".amdgpu_hsa_kernel")
6722 return ParseDirectiveAMDGPUHsaKernel();
6724 if (IDVal ==
".amd_amdgpu_isa")
6725 return ParseDirectiveISAVersion();
6729 Twine(
" directive is "
6730 "not available on non-amdhsa OSes"))
6735 if (IDVal ==
".amdgcn_target")
6736 return ParseDirectiveAMDGCNTarget();
6738 if (IDVal ==
".amdgpu_lds")
6739 return ParseDirectiveAMDGPULDS();
6742 return ParseDirectivePALMetadataBegin();
6745 return ParseDirectivePALMetadata();
6750bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
6752 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
6756 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
6757 return hasSGPR104_SGPR105();
6760 case SRC_SHARED_BASE_LO:
6761 case SRC_SHARED_BASE:
6762 case SRC_SHARED_LIMIT_LO:
6763 case SRC_SHARED_LIMIT:
6764 case SRC_PRIVATE_BASE_LO:
6765 case SRC_PRIVATE_BASE:
6766 case SRC_PRIVATE_LIMIT_LO:
6767 case SRC_PRIVATE_LIMIT:
6769 case SRC_FLAT_SCRATCH_BASE_LO:
6770 case SRC_FLAT_SCRATCH_BASE_HI:
6771 return hasGloballyAddressableScratch();
6772 case SRC_POPS_EXITING_WAVE_ID:
6784 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6813 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
6814 return hasSGPR102_SGPR103();
6819ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6822 ParseStatus Res = parseVOPD(Operands);
6827 Res = MatchOperandParserImpl(Operands, Mnemonic);
6839 SMLoc LBraceLoc = getLoc();
6844 auto Loc = getLoc();
6845 Res = parseReg(Operands);
6847 Error(Loc,
"expected a register");
6851 RBraceLoc = getLoc();
6856 "expected a comma or a closing square bracket"))
6860 if (Operands.
size() - Prefix > 1) {
6862 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6863 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6869 return parseRegOrImm(Operands);
6872StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6874 setForcedEncodingSize(0);
6875 setForcedDPP(
false);
6876 setForcedSDWA(
false);
6878 if (
Name.consume_back(
"_e64_dpp")) {
6880 setForcedEncodingSize(64);
6883 if (
Name.consume_back(
"_e64")) {
6884 setForcedEncodingSize(64);
6887 if (
Name.consume_back(
"_e32")) {
6888 setForcedEncodingSize(32);
6891 if (
Name.consume_back(
"_dpp")) {
6895 if (
Name.consume_back(
"_sdwa")) {
6896 setForcedSDWA(
true);
6904 unsigned VariantID);
6910 Name = parseMnemonicSuffix(Name);
6916 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6918 bool IsMIMG = Name.starts_with(
"image_");
6921 OperandMode
Mode = OperandMode_Default;
6923 Mode = OperandMode_NSA;
6927 checkUnsupportedInstruction(Name, NameLoc);
6928 if (!Parser.hasPendingError()) {
6931 :
"not a valid operand.";
6932 Error(getLoc(), Msg);
6951ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6954 if (!trySkipId(Name))
6957 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6961ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6970ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6971 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6972 std::function<
bool(int64_t &)> ConvertResult) {
6976 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
6980 if (ConvertResult && !ConvertResult(
Value)) {
6981 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
6984 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6988ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6989 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6990 bool (*ConvertResult)(int64_t &)) {
6999 const unsigned MaxSize = 4;
7003 for (
int I = 0; ; ++
I) {
7005 SMLoc Loc = getLoc();
7009 if (
Op != 0 &&
Op != 1)
7010 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7017 if (
I + 1 == MaxSize)
7018 return Error(getLoc(),
"expected a closing square bracket");
7024 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7028ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7030 AMDGPUOperand::ImmTy ImmTy) {
7034 if (trySkipId(Name)) {
7036 }
else if (trySkipId(
"no", Name)) {
7043 return Error(S,
"r128 modifier is not supported on this GPU");
7044 if (Name ==
"a16" && !
hasA16())
7045 return Error(S,
"a16 modifier is not supported on this GPU");
7047 if (Bit == 0 && Name ==
"gds") {
7048 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7050 return Error(S,
"nogds is not allowed");
7053 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7054 ImmTy = AMDGPUOperand::ImmTyR128A16;
7056 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7060unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7061 bool &Disabling)
const {
7062 Disabling =
Id.consume_front(
"no");
7065 return StringSwitch<unsigned>(Id)
7072 return StringSwitch<unsigned>(Id)
7080ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7082 SMLoc StringLoc = getLoc();
7084 int64_t CPolVal = 0;
7093 ResTH = parseTH(Operands, TH);
7104 ResScope = parseScope(Operands, Scope);
7117 if (trySkipId(
"nv")) {
7121 }
else if (trySkipId(
"no",
"nv")) {
7128 if (trySkipId(
"scale_offset")) {
7132 }
else if (trySkipId(
"no",
"scale_offset")) {
7145 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7146 AMDGPUOperand::ImmTyCPol));
7150 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7151 SMLoc OpLoc = getLoc();
7152 unsigned Enabled = 0, Seen = 0;
7156 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7163 return Error(S,
"dlc modifier is not supported on this GPU");
7166 return Error(S,
"scc modifier is not supported on this GPU");
7169 return Error(S,
"duplicate cache policy modifier");
7181 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7185ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7190 ParseStatus Res = parseStringOrIntWithPrefix(
7191 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7200ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7205 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7209 if (
Value ==
"TH_DEFAULT")
7211 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7212 Value ==
"TH_LOAD_NT_WB") {
7213 return Error(StringLoc,
"invalid th value");
7214 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7216 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7218 }
else if (
Value.consume_front(
"TH_STORE_")) {
7221 return Error(StringLoc,
"invalid th value");
7224 if (
Value ==
"BYPASS")
7229 TH |= StringSwitch<int64_t>(
Value)
7239 .Default(0xffffffff);
7241 TH |= StringSwitch<int64_t>(
Value)
7252 .Default(0xffffffff);
7255 if (TH == 0xffffffff)
7256 return Error(StringLoc,
"invalid th value");
7263 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7264 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7265 std::optional<unsigned> InsertAt = std::nullopt) {
7266 auto i = OptionalIdx.find(ImmT);
7267 if (i != OptionalIdx.end()) {
7268 unsigned Idx = i->second;
7269 const AMDGPUOperand &
Op =
7270 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7274 Op.addImmOperands(Inst, 1);
7276 if (InsertAt.has_value())
7283ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7289 StringLoc = getLoc();
7294ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7295 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7300 SMLoc StringLoc = getLoc();
7304 Value = getTokenStr();
7308 if (
Value == Ids[IntVal])
7313 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7314 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7319ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7320 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7321 AMDGPUOperand::ImmTy
Type) {
7325 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7327 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7336bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7340 SMLoc Loc = getLoc();
7342 auto Res = parseIntWithPrefix(Pref, Val);
7348 if (Val < 0 || Val > MaxVal) {
7349 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7357ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7358 AMDGPUOperand::ImmTy ImmTy) {
7359 const char *Pref =
"index_key";
7361 SMLoc Loc = getLoc();
7362 auto Res = parseIntWithPrefix(Pref, ImmVal);
7366 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7367 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7368 (ImmVal < 0 || ImmVal > 1))
7369 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7371 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7372 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7374 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7378ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7379 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7382ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7383 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7386ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7387 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7390ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7392 AMDGPUOperand::ImmTy
Type) {
7393 return parseStringOrIntWithPrefix(Operands, Name,
7394 {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
7395 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
7400ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7401 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7402 AMDGPUOperand::ImmTyMatrixAFMT);
7405ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7406 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7407 AMDGPUOperand::ImmTyMatrixBFMT);
7410ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7412 AMDGPUOperand::ImmTy
Type) {
7413 return parseStringOrIntWithPrefix(
7414 Operands, Name, {
"MATRIX_SCALE_ROW0",
"MATRIX_SCALE_ROW1"},
Type);
7417ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7418 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7419 AMDGPUOperand::ImmTyMatrixAScale);
7422ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7423 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7424 AMDGPUOperand::ImmTyMatrixBScale);
7427ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7429 AMDGPUOperand::ImmTy
Type) {
7430 return parseStringOrIntWithPrefix(
7432 {
"MATRIX_SCALE_FMT_E8",
"MATRIX_SCALE_FMT_E5M3",
"MATRIX_SCALE_FMT_E4M3"},
7436ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7437 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7438 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7441ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7442 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7443 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7448ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7449 using namespace llvm::AMDGPU::MTBUFFormat;
7455 for (
int I = 0;
I < 2; ++
I) {
7456 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7459 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7464 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7470 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7473 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7474 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7480ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7481 using namespace llvm::AMDGPU::MTBUFFormat;
7485 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7488 if (Fmt == UFMT_UNDEF)
7495bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7497 StringRef FormatStr,
7499 using namespace llvm::AMDGPU::MTBUFFormat;
7503 if (
Format != DFMT_UNDEF) {
7509 if (
Format != NFMT_UNDEF) {
7514 Error(Loc,
"unsupported format");
7518ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7521 using namespace llvm::AMDGPU::MTBUFFormat;
7525 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7530 SMLoc Loc = getLoc();
7531 if (!parseId(Str,
"expected a format string") ||
7532 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7534 if (Dfmt == DFMT_UNDEF)
7535 return Error(Loc,
"duplicate numeric format");
7536 if (Nfmt == NFMT_UNDEF)
7537 return Error(Loc,
"duplicate data format");
7540 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7541 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7545 if (Ufmt == UFMT_UNDEF)
7546 return Error(FormatLoc,
"unsupported format");
7555ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7558 using namespace llvm::AMDGPU::MTBUFFormat;
7561 if (Id == UFMT_UNDEF)
7565 return Error(Loc,
"unified format is not supported on this GPU");
7571ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7572 using namespace llvm::AMDGPU::MTBUFFormat;
7573 SMLoc Loc = getLoc();
7578 return Error(Loc,
"out of range format");
7583ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7584 using namespace llvm::AMDGPU::MTBUFFormat;
7590 StringRef FormatStr;
7591 SMLoc Loc = getLoc();
7592 if (!parseId(FormatStr,
"expected a format string"))
7595 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7597 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7607 return parseNumericFormat(
Format);
7610ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7611 using namespace llvm::AMDGPU::MTBUFFormat;
7615 SMLoc Loc = getLoc();
7625 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7637 Res = parseRegOrImm(Operands);
7644 Res = parseSymbolicOrNumericFormat(
Format);
7649 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7650 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7657 return Error(getLoc(),
"duplicate format");
7661ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7663 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7665 Res = parseIntWithPrefix(
"inst_offset", Operands,
7666 AMDGPUOperand::ImmTyInstOffset);
7671ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7673 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7675 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7679ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7681 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7684 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7693void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7694 OptionalImmIndexMap OptionalIdx;
7696 unsigned OperandIdx[4];
7697 unsigned EnMask = 0;
7700 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7701 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7706 OperandIdx[SrcIdx] = Inst.
size();
7707 Op.addRegOperands(Inst, 1);
7714 OperandIdx[SrcIdx] = Inst.
size();
7720 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7721 Op.addImmOperands(Inst, 1);
7725 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7729 OptionalIdx[
Op.getImmTy()] = i;
7735 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7742 for (
auto i = 0; i < SrcIdx; ++i) {
7744 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7769 IntVal =
encode(ISA, IntVal, CntVal);
7770 if (CntVal !=
decode(ISA, IntVal)) {
7772 IntVal =
encode(ISA, IntVal, -1);
7780bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7782 SMLoc CntLoc = getLoc();
7783 StringRef CntName = getTokenStr();
7790 SMLoc ValLoc = getLoc();
7799 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7801 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7803 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7806 Error(CntLoc,
"invalid counter name " + CntName);
7811 Error(ValLoc,
"too large value for " + CntName);
7820 Error(getLoc(),
"expected a counter name");
7828ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7835 if (!parseCnt(Waitcnt))
7843 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7847bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7848 SMLoc FieldLoc = getLoc();
7849 StringRef FieldName = getTokenStr();
7854 SMLoc ValueLoc = getLoc();
7861 if (FieldName ==
"instid0") {
7863 }
else if (FieldName ==
"instskip") {
7865 }
else if (FieldName ==
"instid1") {
7868 Error(FieldLoc,
"invalid field name " + FieldName);
7887 .Case(
"VALU_DEP_1", 1)
7888 .Case(
"VALU_DEP_2", 2)
7889 .Case(
"VALU_DEP_3", 3)
7890 .Case(
"VALU_DEP_4", 4)
7891 .Case(
"TRANS32_DEP_1", 5)
7892 .Case(
"TRANS32_DEP_2", 6)
7893 .Case(
"TRANS32_DEP_3", 7)
7894 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7895 .Case(
"SALU_CYCLE_1", 9)
7896 .Case(
"SALU_CYCLE_2", 10)
7897 .Case(
"SALU_CYCLE_3", 11)
7905 Delay |=
Value << Shift;
7909ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7915 if (!parseDelay(Delay))
7923 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7928AMDGPUOperand::isSWaitCnt()
const {
7932bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7938void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7939 StringRef DepCtrName) {
7942 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7945 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7948 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7951 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7958bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7960 using namespace llvm::AMDGPU::DepCtr;
7962 SMLoc DepCtrLoc = getLoc();
7963 StringRef DepCtrName = getTokenStr();
7973 unsigned PrevOprMask = UsedOprMask;
7974 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7977 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7986 Error(getLoc(),
"expected a counter name");
7991 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7992 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7996ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
7997 using namespace llvm::AMDGPU::DepCtr;
8000 SMLoc Loc = getLoc();
8003 unsigned UsedOprMask = 0;
8005 if (!parseDepCtr(DepCtr, UsedOprMask))
8013 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8017bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8023ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8025 OperandInfoTy &Width) {
8026 using namespace llvm::AMDGPU::Hwreg;
8032 HwReg.Loc = getLoc();
8035 HwReg.IsSymbolic =
true;
8037 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8045 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8055 Width.Loc = getLoc();
8063ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8064 using namespace llvm::AMDGPU::Hwreg;
8067 SMLoc Loc = getLoc();
8069 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8071 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8072 HwregOffset::Default);
8073 struct : StructuredOpField {
8074 using StructuredOpField::StructuredOpField;
8075 bool validate(AMDGPUAsmParser &Parser)
const override {
8077 return Error(Parser,
"only values from 1 to 32 are legal");
8080 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8081 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8084 Res = parseHwregFunc(HwReg,
Offset, Width);
8087 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8089 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8093 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8100 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8102 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8106bool AMDGPUOperand::isHwreg()
const {
8107 return isImmTy(ImmTyHwreg);
8115AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8117 OperandInfoTy &Stream) {
8118 using namespace llvm::AMDGPU::SendMsg;
8123 Msg.IsSymbolic =
true;
8125 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8130 Op.IsDefined =
true;
8133 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8136 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8141 Stream.IsDefined =
true;
8142 Stream.Loc = getLoc();
8152AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8153 const OperandInfoTy &
Op,
8154 const OperandInfoTy &Stream) {
8155 using namespace llvm::AMDGPU::SendMsg;
8160 bool Strict = Msg.IsSymbolic;
8164 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8169 Error(Msg.Loc,
"invalid message id");
8175 Error(
Op.Loc,
"message does not support operations");
8177 Error(Msg.Loc,
"missing message operation");
8183 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8185 Error(
Op.Loc,
"invalid operation id");
8190 Error(Stream.Loc,
"message operation does not support streams");
8194 Error(Stream.Loc,
"invalid message stream id");
8200ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8201 using namespace llvm::AMDGPU::SendMsg;
8204 SMLoc Loc = getLoc();
8208 OperandInfoTy
Op(OP_NONE_);
8209 OperandInfoTy Stream(STREAM_ID_NONE_);
8210 if (parseSendMsgBody(Msg,
Op, Stream) &&
8211 validateSendMsg(Msg,
Op, Stream)) {
8216 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8218 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8223 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8227bool AMDGPUOperand::isSendMsg()
const {
8228 return isImmTy(ImmTySendMsg);
8235ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8242 int Slot = StringSwitch<int>(Str)
8249 return Error(S,
"invalid interpolation slot");
8251 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8252 AMDGPUOperand::ImmTyInterpSlot));
8256ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8263 if (!Str.starts_with(
"attr"))
8264 return Error(S,
"invalid interpolation attribute");
8266 StringRef Chan = Str.take_back(2);
8267 int AttrChan = StringSwitch<int>(Chan)
8274 return Error(S,
"invalid or missing interpolation attribute channel");
8276 Str = Str.drop_back(2).drop_front(4);
8279 if (Str.getAsInteger(10, Attr))
8280 return Error(S,
"invalid or missing interpolation attribute number");
8283 return Error(S,
"out of bounds interpolation attribute number");
8287 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8288 AMDGPUOperand::ImmTyInterpAttr));
8289 Operands.
push_back(AMDGPUOperand::CreateImm(
8290 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8298ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8299 using namespace llvm::AMDGPU::Exp;
8309 return Error(S, (Id == ET_INVALID)
8310 ?
"invalid exp target"
8311 :
"exp target is not supported on this GPU");
8313 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8314 AMDGPUOperand::ImmTyExpTgt));
8323AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8328AMDGPUAsmParser::isId(
const StringRef Id)
const {
8334 return getTokenKind() ==
Kind;
8337StringRef AMDGPUAsmParser::getId()
const {
8342AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8351AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8353 StringRef Tok = getTokenStr();
8364 if (isId(Id) && peekToken().is(Kind)) {
8374 if (isToken(Kind)) {
8383 const StringRef ErrMsg) {
8384 if (!trySkipToken(Kind)) {
8385 Error(getLoc(), ErrMsg);
8392AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8396 if (Parser.parseExpression(Expr))
8399 if (Expr->evaluateAsAbsolute(
Imm))
8402 if (Expected.empty()) {
8403 Error(S,
"expected absolute expression");
8405 Error(S, Twine(
"expected ", Expected) +
8406 Twine(
" or an absolute expression"));
8416 if (Parser.parseExpression(Expr))
8420 if (Expr->evaluateAsAbsolute(IntVal)) {
8421 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8423 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8429AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8431 Val =
getToken().getStringContents();
8435 Error(getLoc(), ErrMsg);
8440AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8442 Val = getTokenStr();
8446 if (!ErrMsg.
empty())
8447 Error(getLoc(), ErrMsg);
8452AMDGPUAsmParser::getToken()
const {
8453 return Parser.getTok();
8456AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8459 : getLexer().peekTok(ShouldSkipSpace);
8464 auto TokCount = getLexer().peekTokens(Tokens);
8466 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8471AMDGPUAsmParser::getTokenKind()
const {
8472 return getLexer().getKind();
8476AMDGPUAsmParser::getLoc()
const {
8481AMDGPUAsmParser::getTokenStr()
const {
8486AMDGPUAsmParser::lex() {
8490SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8491 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8495SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8499SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8500 int MCOpIdx)
const {
8501 for (
const auto &
Op : Operands) {
8502 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8503 if (TargetOp.getMCOpIdx() == MCOpIdx)
8504 return TargetOp.getStartLoc();
8510AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8512 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8513 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8515 return Op.getStartLoc();
8517 return getInstLoc(Operands);
8521AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8523 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8524 return getOperandLoc(
Test, Operands);
8538 StringRef
Id = getTokenStr();
8539 SMLoc IdLoc = getLoc();
8545 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8546 if (
I == Fields.
end())
8547 return Error(IdLoc,
"unknown field");
8548 if ((*I)->IsDefined)
8549 return Error(IdLoc,
"duplicate field");
8552 (*I)->Loc = getLoc();
8555 (*I)->IsDefined =
true;
8562bool AMDGPUAsmParser::validateStructuredOpFields(
8564 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8565 return F->validate(*
this);
8576 const unsigned OrMask,
8577 const unsigned XorMask) {
8586bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8587 const unsigned MaxVal,
8588 const Twine &ErrMsg, SMLoc &Loc) {
8605AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8606 const unsigned MinVal,
8607 const unsigned MaxVal,
8608 const StringRef ErrMsg) {
8610 for (
unsigned i = 0; i < OpNum; ++i) {
8611 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8619AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8620 using namespace llvm::AMDGPU::Swizzle;
8623 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8624 "expected a 2-bit lane id")) {
8635AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8636 using namespace llvm::AMDGPU::Swizzle;
8642 if (!parseSwizzleOperand(GroupSize,
8644 "group size must be in the interval [2,32]",
8649 Error(Loc,
"group size must be a power of two");
8652 if (parseSwizzleOperand(LaneIdx,
8654 "lane id must be in the interval [0,group size - 1]",
8663AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8664 using namespace llvm::AMDGPU::Swizzle;
8669 if (!parseSwizzleOperand(GroupSize,
8671 "group size must be in the interval [2,32]",
8676 Error(Loc,
"group size must be a power of two");
8685AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8686 using namespace llvm::AMDGPU::Swizzle;
8691 if (!parseSwizzleOperand(GroupSize,
8693 "group size must be in the interval [1,16]",
8698 Error(Loc,
"group size must be a power of two");
8707AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8708 using namespace llvm::AMDGPU::Swizzle;
8715 SMLoc StrLoc = getLoc();
8716 if (!parseString(Ctl)) {
8719 if (Ctl.
size() != BITMASK_WIDTH) {
8720 Error(StrLoc,
"expected a 5-character mask");
8724 unsigned AndMask = 0;
8725 unsigned OrMask = 0;
8726 unsigned XorMask = 0;
8728 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8732 Error(StrLoc,
"invalid mask");
8753bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8754 using namespace llvm::AMDGPU::Swizzle;
8757 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8763 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8764 "FFT swizzle must be in the interval [0," +
8765 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8773bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8774 using namespace llvm::AMDGPU::Swizzle;
8777 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8784 if (!parseSwizzleOperand(
Direction, 0, 1,
8785 "direction must be 0 (left) or 1 (right)", Loc))
8789 if (!parseSwizzleOperand(
8790 RotateSize, 0, ROTATE_MAX_SIZE,
8791 "number of threads to rotate must be in the interval [0," +
8792 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8797 (RotateSize << ROTATE_SIZE_SHIFT);
8802AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8804 SMLoc OffsetLoc = getLoc();
8810 Error(OffsetLoc,
"expected a 16-bit offset");
8817AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8818 using namespace llvm::AMDGPU::Swizzle;
8822 SMLoc ModeLoc = getLoc();
8825 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8826 Ok = parseSwizzleQuadPerm(
Imm);
8827 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8828 Ok = parseSwizzleBitmaskPerm(
Imm);
8829 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8830 Ok = parseSwizzleBroadcast(
Imm);
8831 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8832 Ok = parseSwizzleSwap(
Imm);
8833 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8834 Ok = parseSwizzleReverse(
Imm);
8835 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8836 Ok = parseSwizzleFFT(
Imm);
8837 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8838 Ok = parseSwizzleRotate(
Imm);
8840 Error(ModeLoc,
"expected a swizzle mode");
8843 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8849ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8853 if (trySkipId(
"offset")) {
8857 if (trySkipId(
"swizzle")) {
8858 Ok = parseSwizzleMacro(
Imm);
8860 Ok = parseSwizzleOffset(
Imm);
8864 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8872AMDGPUOperand::isSwizzle()
const {
8873 return isImmTy(ImmTySwizzle);
8880int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8882 using namespace llvm::AMDGPU::VGPRIndexMode;
8894 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8895 if (trySkipId(IdSymbolic[ModeId])) {
8903 "expected a VGPR index mode or a closing parenthesis" :
8904 "expected a VGPR index mode");
8909 Error(S,
"duplicate VGPR index mode");
8917 "expected a comma or a closing parenthesis"))
8924ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8926 using namespace llvm::AMDGPU::VGPRIndexMode;
8932 Imm = parseGPRIdxMacro();
8936 if (getParser().parseAbsoluteExpression(
Imm))
8939 return Error(S,
"invalid immediate: only 4-bit values are legal");
8943 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8947bool AMDGPUOperand::isGPRIdxMode()
const {
8948 return isImmTy(ImmTyGprIdxMode);
8955ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
8960 if (isRegister() || isModifier())
8966 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
8967 assert(Opr.isImm() || Opr.isExpr());
8968 SMLoc Loc = Opr.getStartLoc();
8972 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8973 Error(Loc,
"expected an absolute expression or a label");
8974 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8975 Error(Loc,
"expected a 16-bit signed jump offset");
8985ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
8986 return parseReg(Operands);
8993void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
8996 OptionalImmIndexMap OptionalIdx;
8997 unsigned FirstOperandIdx = 1;
8998 bool IsAtomicReturn =
false;
9005 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9006 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9010 Op.addRegOperands(Inst, 1);
9014 if (IsAtomicReturn && i == FirstOperandIdx)
9015 Op.addRegOperands(Inst, 1);
9020 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9021 Op.addImmOperands(Inst, 1);
9033 OptionalIdx[
Op.getImmTy()] = i;
9047bool AMDGPUOperand::isSMRDOffset8()
const {
9051bool AMDGPUOperand::isSMEMOffset()
const {
9053 return isImmLiteral();
9056bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9091bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9092 if (BoundCtrl == 0 || BoundCtrl == 1) {
9100void AMDGPUAsmParser::onBeginOfFile() {
9101 if (!getParser().getStreamer().getTargetStreamer() ||
9105 if (!getTargetStreamer().getTargetID())
9106 getTargetStreamer().initializeTargetID(getSTI(),
9107 getSTI().getFeatureString());
9110 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9118bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9122 StringRef TokenId = getTokenStr();
9123 AGVK VK = StringSwitch<AGVK>(TokenId)
9124 .Case(
"max", AGVK::AGVK_Max)
9125 .Case(
"or", AGVK::AGVK_Or)
9126 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9127 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9128 .Case(
"alignto", AGVK::AGVK_AlignTo)
9129 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9130 .Default(AGVK::AGVK_None);
9134 uint64_t CommaCount = 0;
9139 if (Exprs.
empty()) {
9141 "empty " + Twine(TokenId) +
" expression");
9144 if (CommaCount + 1 != Exprs.
size()) {
9146 "mismatch of commas in " + Twine(TokenId) +
" expression");
9153 if (getParser().parseExpression(Expr, EndLoc))
9157 if (LastTokenWasComma)
9161 "unexpected token in " + Twine(TokenId) +
" expression");
9167 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9170ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9171 StringRef
Name = getTokenStr();
9172 if (Name ==
"mul") {
9173 return parseIntWithPrefix(
"mul", Operands,
9177 if (Name ==
"div") {
9178 return parseIntWithPrefix(
"div", Operands,
9189 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9194 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9195 AMDGPU::OpName::src2};
9203 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9208 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9210 if (
DstOp.isReg() &&
9211 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9215 if ((OpSel & (1 << SrcNum)) != 0)
9221void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9223 cvtVOP3P(Inst, Operands);
9227void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9228 OptionalImmIndexMap &OptionalIdx) {
9229 cvtVOP3P(Inst, Operands, OptionalIdx);
9238 &&
Desc.NumOperands > (OpNum + 1)
9240 &&
Desc.operands()[OpNum + 1].RegClass != -1
9242 &&
Desc.getOperandConstraint(OpNum + 1,
9246void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9248 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9249 AMDGPU::OpName::src2};
9250 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9251 AMDGPU::OpName::src1_modifiers,
9252 AMDGPU::OpName::src2_modifiers};
9253 for (
int J = 0; J < 3; ++J) {
9254 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9260 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9263 if ((OpSel & (1 << J)) != 0)
9266 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9273void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9275 OptionalImmIndexMap OptionalIdx;
9280 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9281 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9284 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9285 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9287 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9288 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9289 Op.isInterpAttrChan()) {
9291 }
else if (
Op.isImmModifier()) {
9292 OptionalIdx[
Op.getImmTy()] =
I;
9300 AMDGPUOperand::ImmTyHigh);
9304 AMDGPUOperand::ImmTyClamp);
9308 AMDGPUOperand::ImmTyOModSI);
9313 AMDGPUOperand::ImmTyOpSel);
9314 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9317 cvtOpSelHelper(Inst, OpSel);
9321void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9323 OptionalImmIndexMap OptionalIdx;
9328 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9329 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9332 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9333 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9335 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9336 }
else if (
Op.isImmModifier()) {
9337 OptionalIdx[
Op.getImmTy()] =
I;
9345 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9355 cvtOpSelHelper(Inst, OpSel);
9358void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9360 OptionalImmIndexMap OptionalIdx;
9363 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9367 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9368 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9370 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9371 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9376 if (NumOperands == CbszOpIdx) {
9381 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9382 }
else if (
Op.isImmModifier()) {
9383 OptionalIdx[
Op.getImmTy()] =
I;
9385 Op.addRegOrImmOperands(Inst, 1);
9390 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9391 if (CbszIdx != OptionalIdx.end()) {
9392 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9396 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9397 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9398 if (BlgpIdx != OptionalIdx.end()) {
9399 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9410 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9411 if (OpselIdx != OptionalIdx.end()) {
9412 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9416 unsigned OpSelHi = 0;
9417 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9418 if (OpselHiIdx != OptionalIdx.end()) {
9419 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9422 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9423 AMDGPU::OpName::src1_modifiers};
9425 for (
unsigned J = 0; J < 2; ++J) {
9426 unsigned ModVal = 0;
9427 if (OpSel & (1 << J))
9429 if (OpSelHi & (1 << J))
9432 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9437void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9438 OptionalImmIndexMap &OptionalIdx) {
9443 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9444 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9447 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9448 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9450 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9451 }
else if (
Op.isImmModifier()) {
9452 OptionalIdx[
Op.getImmTy()] =
I;
9454 Op.addRegOrImmOperands(Inst, 1);
9460 AMDGPUOperand::ImmTyScaleSel);
9464 AMDGPUOperand::ImmTyClamp);
9470 AMDGPUOperand::ImmTyByteSel);
9475 AMDGPUOperand::ImmTyOModSI);
9482 auto *it = Inst.
begin();
9483 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9491void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9492 OptionalImmIndexMap OptionalIdx;
9493 cvtVOP3(Inst, Operands, OptionalIdx);
9496void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9497 OptionalImmIndexMap &OptIdx) {
9503 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9504 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9505 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9506 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9507 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9508 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9516 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9517 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9518 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9519 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9520 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9521 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9522 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9523 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9524 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9525 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9526 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9527 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9528 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9529 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9530 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9531 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9532 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9533 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9534 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9535 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9536 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9537 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9538 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9539 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9540 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9541 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9545 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9546 if (BitOp3Idx != -1) {
9553 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9554 if (OpSelIdx != -1) {
9558 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9559 if (OpSelHiIdx != -1) {
9566 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9567 if (MatrixAFMTIdx != -1) {
9569 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9573 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9574 if (MatrixBFMTIdx != -1) {
9576 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9579 int MatrixAScaleIdx =
9580 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9581 if (MatrixAScaleIdx != -1) {
9583 AMDGPUOperand::ImmTyMatrixAScale, 0);
9586 int MatrixBScaleIdx =
9587 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9588 if (MatrixBScaleIdx != -1) {
9590 AMDGPUOperand::ImmTyMatrixBScale, 0);
9593 int MatrixAScaleFmtIdx =
9594 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9595 if (MatrixAScaleFmtIdx != -1) {
9597 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9600 int MatrixBScaleFmtIdx =
9601 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9602 if (MatrixBScaleFmtIdx != -1) {
9604 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9609 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9613 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9615 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9619 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9623 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9624 AMDGPU::OpName::src2};
9625 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9626 AMDGPU::OpName::src1_modifiers,
9627 AMDGPU::OpName::src2_modifiers};
9630 unsigned OpSelHi = 0;
9637 if (OpSelHiIdx != -1)
9646 for (
int J = 0; J < 3; ++J) {
9647 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9651 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9656 uint32_t ModVal = 0;
9659 if (SrcOp.
isReg() && getMRI()
9666 if ((OpSel & (1 << J)) != 0)
9670 if ((OpSelHi & (1 << J)) != 0)
9673 if ((NegLo & (1 << J)) != 0)
9676 if ((NegHi & (1 << J)) != 0)
9683void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9684 OptionalImmIndexMap OptIdx;
9685 cvtVOP3(Inst, Operands, OptIdx);
9686 cvtVOP3P(Inst, Operands, OptIdx);
9690 unsigned i,
unsigned Opc,
9692 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9693 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9695 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9698void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9701 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9704 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9705 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9707 OptionalImmIndexMap OptIdx;
9708 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9709 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9710 OptIdx[
Op.getImmTy()] = i;
9715 AMDGPUOperand::ImmTyIndexKey8bit);
9719 AMDGPUOperand::ImmTyIndexKey16bit);
9723 AMDGPUOperand::ImmTyIndexKey32bit);
9728 cvtVOP3P(Inst, Operands, OptIdx);
9735ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9743 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9744 SMLoc OpYLoc = getLoc();
9747 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9750 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9756void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9759 auto addOp = [&](uint16_t ParsedOprIdx) {
9760 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9762 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9766 Op.addRegOperands(Inst, 1);
9770 Op.addImmOperands(Inst, 1);
9782 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9786 const auto &CInfo = InstInfo[CompIdx];
9787 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9788 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9789 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9790 if (CInfo.hasSrc2Acc())
9791 addOp(CInfo.getIndexOfDstInParsedOperands());
9795 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9796 if (BitOp3Idx != -1) {
9797 OptionalImmIndexMap OptIdx;
9798 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9800 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9810bool AMDGPUOperand::isDPP8()
const {
9811 return isImmTy(ImmTyDPP8);
9814bool AMDGPUOperand::isDPPCtrl()
const {
9815 using namespace AMDGPU::DPP;
9817 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9820 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9821 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9822 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9823 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9824 (
Imm == DppCtrl::WAVE_SHL1) ||
9825 (
Imm == DppCtrl::WAVE_ROL1) ||
9826 (
Imm == DppCtrl::WAVE_SHR1) ||
9827 (
Imm == DppCtrl::WAVE_ROR1) ||
9828 (
Imm == DppCtrl::ROW_MIRROR) ||
9829 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9830 (
Imm == DppCtrl::BCAST15) ||
9831 (
Imm == DppCtrl::BCAST31) ||
9832 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9833 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9842bool AMDGPUOperand::isBLGP()
const {
9846bool AMDGPUOperand::isS16Imm()
const {
9850bool AMDGPUOperand::isU16Imm()
const {
9858bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9863 SMLoc Loc =
getToken().getEndLoc();
9864 Token = std::string(getTokenStr());
9866 if (getLoc() != Loc)
9871 if (!parseId(Suffix))
9875 StringRef DimId = Token;
9886ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9896 SMLoc Loc = getLoc();
9897 if (!parseDimId(Encoding))
9898 return Error(Loc,
"invalid dim value");
9900 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9901 AMDGPUOperand::ImmTyDim));
9909ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
9919 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9922 for (
size_t i = 0; i < 8; ++i) {
9926 SMLoc Loc = getLoc();
9927 if (getParser().parseAbsoluteExpression(Sels[i]))
9929 if (0 > Sels[i] || 7 < Sels[i])
9930 return Error(Loc,
"expected a 3-bit value");
9937 for (
size_t i = 0; i < 8; ++i)
9938 DPP8 |= (Sels[i] << (i * 3));
9940 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9945AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
9947 if (Ctrl ==
"row_newbcast")
9950 if (Ctrl ==
"row_share" ||
9951 Ctrl ==
"row_xmask")
9954 if (Ctrl ==
"wave_shl" ||
9955 Ctrl ==
"wave_shr" ||
9956 Ctrl ==
"wave_rol" ||
9957 Ctrl ==
"wave_ror" ||
9958 Ctrl ==
"row_bcast")
9961 return Ctrl ==
"row_mirror" ||
9962 Ctrl ==
"row_half_mirror" ||
9963 Ctrl ==
"quad_perm" ||
9964 Ctrl ==
"row_shl" ||
9965 Ctrl ==
"row_shr" ||
9970AMDGPUAsmParser::parseDPPCtrlPerm() {
9973 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9977 for (
int i = 0; i < 4; ++i) {
9982 SMLoc Loc = getLoc();
9983 if (getParser().parseAbsoluteExpression(Temp))
9985 if (Temp < 0 || Temp > 3) {
9986 Error(Loc,
"expected a 2-bit value");
9990 Val += (Temp << i * 2);
10000AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
10001 using namespace AMDGPU::DPP;
10006 SMLoc Loc = getLoc();
10008 if (getParser().parseAbsoluteExpression(Val))
10011 struct DppCtrlCheck {
10017 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10018 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10019 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10020 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10021 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10022 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10023 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10024 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10025 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10026 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10027 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10031 if (
Check.Ctrl == -1) {
10032 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10040 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10047ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10048 using namespace AMDGPU::DPP;
10051 !isSupportedDPPCtrl(getTokenStr(), Operands))
10054 SMLoc S = getLoc();
10060 if (Ctrl ==
"row_mirror") {
10061 Val = DppCtrl::ROW_MIRROR;
10062 }
else if (Ctrl ==
"row_half_mirror") {
10063 Val = DppCtrl::ROW_HALF_MIRROR;
10066 if (Ctrl ==
"quad_perm") {
10067 Val = parseDPPCtrlPerm();
10069 Val = parseDPPCtrlSel(Ctrl);
10078 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10082void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10084 OptionalImmIndexMap OptionalIdx;
10091 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10093 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10094 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10098 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10099 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10103 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10104 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10105 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10106 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10107 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10109 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10113 if (OldIdx == NumOperands) {
10115 constexpr int DST_IDX = 0;
10117 }
else if (Src2ModIdx == NumOperands) {
10127 if (IsVOP3CvtSrDpp) {
10136 if (TiedTo != -1) {
10141 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10143 if (IsDPP8 &&
Op.isDppFI()) {
10146 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10147 }
else if (
Op.isReg()) {
10148 Op.addRegOperands(Inst, 1);
10149 }
else if (
Op.isImm() &&
10151 Op.addImmOperands(Inst, 1);
10152 }
else if (
Op.isImm()) {
10153 OptionalIdx[
Op.getImmTy()] =
I;
10161 AMDGPUOperand::ImmTyClamp);
10167 AMDGPUOperand::ImmTyByteSel);
10174 cvtVOP3P(Inst, Operands, OptionalIdx);
10176 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10183 using namespace llvm::AMDGPU::DPP;
10193 AMDGPUOperand::ImmTyDppFI);
10197void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10198 OptionalImmIndexMap OptionalIdx;
10202 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10203 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10207 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10210 if (TiedTo != -1) {
10215 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10217 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10225 Op.addImmOperands(Inst, 1);
10227 Op.addRegWithFPInputModsOperands(Inst, 2);
10228 }
else if (
Op.isDppFI()) {
10230 }
else if (
Op.isReg()) {
10231 Op.addRegOperands(Inst, 1);
10237 Op.addRegWithFPInputModsOperands(Inst, 2);
10238 }
else if (
Op.isReg()) {
10239 Op.addRegOperands(Inst, 1);
10240 }
else if (
Op.isDPPCtrl()) {
10241 Op.addImmOperands(Inst, 1);
10242 }
else if (
Op.isImm()) {
10244 OptionalIdx[
Op.getImmTy()] =
I;
10252 using namespace llvm::AMDGPU::DPP;
10260 AMDGPUOperand::ImmTyDppFI);
10269ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10271 AMDGPUOperand::ImmTy
Type) {
10272 return parseStringOrIntWithPrefix(
10274 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10278ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10279 return parseStringOrIntWithPrefix(
10280 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10281 AMDGPUOperand::ImmTySDWADstUnused);
10284void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10288void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10292void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10296void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10300void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10304void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10305 uint64_t BasicInstType,
10308 using namespace llvm::AMDGPU::SDWA;
10310 OptionalImmIndexMap OptionalIdx;
10311 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10312 bool SkippedVcc =
false;
10316 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10317 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10320 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10321 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10322 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10323 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10341 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10342 }
else if (
Op.isImm()) {
10344 OptionalIdx[
Op.getImmTy()] =
I;
10348 SkippedVcc =
false;
10352 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10353 Opc != AMDGPU::V_NOP_sdwa_vi) {
10355 switch (BasicInstType) {
10359 AMDGPUOperand::ImmTyClamp, 0);
10363 AMDGPUOperand::ImmTyOModSI, 0);
10367 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10371 AMDGPUOperand::ImmTySDWADstUnused,
10372 DstUnused::UNUSED_PRESERVE);
10374 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10379 AMDGPUOperand::ImmTyClamp, 0);
10384 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10385 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10386 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10387 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10393 AMDGPUOperand::ImmTyClamp, 0);
10394 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10395 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10399 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10405 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10406 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10407 auto *it = Inst.
begin();
10409 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10421#define GET_MATCHER_IMPLEMENTATION
10422#define GET_MNEMONIC_SPELL_CHECKER
10423#define GET_MNEMONIC_CHECKER
10424#include "AMDGPUGenAsmMatcher.inc"
10430 return parseTokenOp(
"addr64",
Operands);
10432 return parseTokenOp(
"done",
Operands);
10434 return parseTokenOp(
"idxen",
Operands);
10436 return parseTokenOp(
"lds",
Operands);
10438 return parseTokenOp(
"offen",
Operands);
10440 return parseTokenOp(
"off",
Operands);
10441 case MCK_row_95_en:
10442 return parseTokenOp(
"row_en",
Operands);
10444 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10446 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10448 return tryCustomParseOperand(
Operands, MCK);
10453unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10459 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10462 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10464 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10466 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10468 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10470 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10472 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10480 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10482 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10483 case MCK_SOPPBrTarget:
10484 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10485 case MCK_VReg32OrOff:
10486 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10487 case MCK_InterpSlot:
10488 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10489 case MCK_InterpAttr:
10490 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10491 case MCK_InterpAttrChan:
10492 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10494 case MCK_SReg_64_XEXEC:
10504 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10506 return Match_InvalidOperand;
10514ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10515 SMLoc S = getLoc();
10524 return Error(S,
"expected a 16-bit value");
10527 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10531bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10537bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, AMDGPU::OpName OpName)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static int IsAGPROperand(const MCInst &Inst, AMDGPU::OpName Name, const MCRegisterInfo *MRI)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
constexpr uint64_t MIMGFlags
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static bool IsRevOpcode(const unsigned Opcode)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static MCRegister getSpecialRegForName(StringRef RegName)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0, std::optional< unsigned > InsertAt=std::nullopt)
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Loop::LoopBounds::Direction Direction
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
MachineInstr unsigned OpIdx
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
unsigned unsigned DefaultVal
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
static const fltSemantics & IEEEsingle()
static const fltSemantics & BFloat()
static const fltSemantics & IEEEdouble()
static constexpr roundingMode rmNearestTiesToEven
static const fltSemantics & IEEEhalf()
opStatus
IEEE-754R 7: Default exception handling.
LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
Container class for subtarget features.
constexpr bool test(unsigned I) const
constexpr FeatureBitset & flip(unsigned I)
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
int16_t getOpRegClassID(const MCOperandInfo &OpInfo, unsigned HwModeId) const
Return the ID of the register class to use for OpInfo, for the active HwMode HwModeId.
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
void setReg(MCRegister Reg)
Set the register number.
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterClass - Base class of TargetRegisterClass.
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isVariable() const
isVariable - Check if this is a variable symbol.
LLVM_ABI void setVariableValue(const MCExpr *Value)
void setRedefinable(bool Value)
Mark this symbol as redefinable.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
uint64_t getScalarSizeInBits() const
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
constexpr unsigned id() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
constexpr bool isValid() const
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringRef - Represent a constant reference to a string, i.e.
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
bool contains(StringRef key) const
Check if the set contains the given key.
std::pair< typename Base::iterator, bool > insert(StringRef key)
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
std::pair< iterator, bool > insert(const ValueT &V)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
unsigned getTgtId(const StringRef Name)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI)
static constexpr CustomOperand Operands[]
unsigned getVGPREncodingGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI)
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
bool isPackedFP32Inst(unsigned Opc)
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
bool isInlineValue(MCRegister Reg)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
bool isSGPR(MCRegister Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
uint8_t wmmaScaleF8F6F4FormatToNumRegs(unsigned Fmt)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
unsigned getTemporalHintType(const MCInstrDesc TID)
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
bool isGFX10(const MCSubtargetInfo &STI)
LLVM_READONLY bool isLitExpr(const MCExpr *Expr)
bool isInlinableLiteralV2BF16(uint32_t Literal)
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
bool hasA16(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset, bool IsBuffer)
bool isGFX12Plus(const MCSubtargetInfo &STI)
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool isHsaAbi(const MCSubtargetInfo &STI)
bool isGFX11(const MCSubtargetInfo &STI)
const int OPR_VAL_INVALID
bool getSMEMIsBuffer(unsigned Opc)
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
CanBeVOPD getCanBeVOPD(unsigned Opc, unsigned EncodingFamily, bool VOPD3)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
bool isSI(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isGFX9(const MCSubtargetInfo &STI)
unsigned getVOPDEncodingFamily(const MCSubtargetInfo &ST)
bool isGFX10_AEncoding(const MCSubtargetInfo &STI)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool hasMAIInsts(const MCSubtargetInfo &STI)
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
@ Valid
The data is already valid.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
FunctionAddr VTableAddr uintptr_t uintptr_t Version
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
@ Enabled
Convert any .debug_str_offsets tables to DWARF64 if needed.
@ Default
The result values are uniform if and only if all operands are uniform.
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
Instruction set architecture version.
const MCExpr * compute_pgm_rsrc2
const MCExpr * kernarg_size
const MCExpr * kernarg_preload
const MCExpr * compute_pgm_rsrc3
const MCExpr * private_segment_fixed_size
const MCExpr * compute_pgm_rsrc1
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
const MCExpr * group_segment_fixed_size
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
const MCExpr * kernel_code_properties
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size