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 unsigned 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)
3668unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3672 case AMDGPU::FLAT_SCR:
3674 case AMDGPU::VCC_LO:
3675 case AMDGPU::VCC_HI:
3682 return AMDGPU::NoRegister;
3689bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3690 unsigned OpIdx)
const {
3744unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3750 case AMDGPU::V_LSHLREV_B64_e64:
3751 case AMDGPU::V_LSHLREV_B64_gfx10:
3752 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3753 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3754 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3755 case AMDGPU::V_LSHRREV_B64_e64:
3756 case AMDGPU::V_LSHRREV_B64_gfx10:
3757 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3758 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3759 case AMDGPU::V_ASHRREV_I64_e64:
3760 case AMDGPU::V_ASHRREV_I64_gfx10:
3761 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3762 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3763 case AMDGPU::V_LSHL_B64_e64:
3764 case AMDGPU::V_LSHR_B64_e64:
3765 case AMDGPU::V_ASHR_I64_e64:
3778 bool AddMandatoryLiterals =
false) {
3781 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3785 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3787 return {getNamedOperandIdx(Opcode, OpName::src0X),
3788 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3789 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3790 getNamedOperandIdx(Opcode, OpName::src0Y),
3791 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3792 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3797 return {getNamedOperandIdx(Opcode, OpName::src0),
3798 getNamedOperandIdx(Opcode, OpName::src1),
3799 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3802bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3805 return !isInlineConstant(Inst,
OpIdx);
3812 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3823 const unsigned Opcode = Inst.
getOpcode();
3824 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3827 if (!LaneSelOp.
isReg())
3830 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3833bool AMDGPUAsmParser::validateConstantBusLimitations(
3835 const unsigned Opcode = Inst.
getOpcode();
3836 const MCInstrDesc &
Desc = MII.
get(Opcode);
3837 MCRegister LastSGPR;
3838 unsigned ConstantBusUseCount = 0;
3839 unsigned NumLiterals = 0;
3840 unsigned LiteralSize;
3842 if (!(
Desc.TSFlags &
3857 SmallDenseSet<unsigned> SGPRsUsed;
3858 unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3859 if (SGPRUsed != AMDGPU::NoRegister) {
3860 SGPRsUsed.
insert(SGPRUsed);
3861 ++ConstantBusUseCount;
3866 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3868 for (
int OpIdx : OpIndices) {
3873 if (usesConstantBus(Inst,
OpIdx)) {
3882 if (SGPRsUsed.
insert(LastSGPR).second) {
3883 ++ConstantBusUseCount;
3903 if (NumLiterals == 0) {
3906 }
else if (LiteralSize !=
Size) {
3912 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3914 "invalid operand (violates constant bus restrictions)");
3921std::optional<unsigned>
3922AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3924 const unsigned Opcode = Inst.
getOpcode();
3930 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3931 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3939 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3940 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3941 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250;
3945 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3946 int I = getNamedOperandIdx(Opcode, OpName);
3950 int64_t
Imm =
Op.getImm();
3956 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3957 OpName::vsrc2Y, OpName::imm}) {
3958 int I = getNamedOperandIdx(Opcode, OpName);
3968 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3969 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3971 return InvalidCompOprIdx;
3974bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
3981 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
3982 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
3983 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
3985 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
3989 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
3990 if (!InvalidCompOprIdx.has_value())
3993 auto CompOprIdx = *InvalidCompOprIdx;
3996 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3997 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3998 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4000 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4001 if (CompOprIdx == VOPD::Component::DST) {
4003 Error(Loc,
"dst registers must be distinct");
4005 Error(Loc,
"one dst register must be even and the other odd");
4007 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4008 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4009 " operands must use different VGPR banks");
4017bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4019 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4020 if (!InvalidCompOprIdx.has_value())
4024 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4025 if (InvalidCompOprIdx.has_value()) {
4030 if (*InvalidCompOprIdx == VOPD::Component::DST)
4043bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4044 const unsigned Opcode = Inst.
getOpcode();
4059 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4060 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4061 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4062 int I = getNamedOperandIdx(Opcode, OpName);
4069 return !tryVOPD3(Inst);
4074bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4075 const unsigned Opcode = Inst.
getOpcode();
4080 return tryVOPD(Inst);
4081 return tryVOPD3(Inst);
4084bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4090 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4101bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4109 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4110 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4111 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4119 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4120 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4125 bool IsPackedD16 =
false;
4129 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4130 IsPackedD16 = D16Idx >= 0;
4135 if ((VDataSize / 4) ==
DataSize + TFESize)
4140 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4142 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4144 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4148bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4157 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4159 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4161 ? AMDGPU::OpName::srsrc
4162 : AMDGPU::OpName::rsrc;
4163 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4164 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4165 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4169 assert(SrsrcIdx > VAddr0Idx);
4172 if (BaseOpcode->
BVH) {
4173 if (IsA16 == BaseOpcode->
A16)
4175 Error(IDLoc,
"image address size does not match a16");
4181 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4182 unsigned ActualAddrSize =
4183 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4185 unsigned ExpectedAddrSize =
4189 if (hasPartialNSAEncoding() &&
4192 int VAddrLastIdx = SrsrcIdx - 1;
4193 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4195 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4198 if (ExpectedAddrSize > 12)
4199 ExpectedAddrSize = 16;
4204 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4208 if (ActualAddrSize == ExpectedAddrSize)
4211 Error(IDLoc,
"image address size does not match dim and a16");
4215bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4222 if (!
Desc.mayLoad() || !
Desc.mayStore())
4225 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4232 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4235bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4243 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4251 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4254bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4269 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4270 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4277bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4285 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4288 if (!BaseOpcode->
MSAA)
4291 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4297 return DimInfo->
MSAA;
4303 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4304 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4305 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4315bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4324 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4327 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4335 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4339bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4344 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4347 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4350 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4357 Error(getOperandLoc(Operands, Src0Idx),
4358 "source operand must be either a VGPR or an inline constant");
4365bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4368 const MCInstrDesc &
Desc = MII.
get(Opcode);
4371 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4374 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4378 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4379 Error(getOperandLoc(Operands, Src2Idx),
4380 "inline constants are not allowed for this operand");
4387bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4395 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4396 if (BlgpIdx != -1) {
4397 if (
const MFMA_F8F6F4_Info *
Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4398 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4408 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4409 Error(getOperandLoc(Operands, Src0Idx),
4410 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4415 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4416 Error(getOperandLoc(Operands, Src1Idx),
4417 "wrong register tuple size for blgp value " + Twine(BLGP));
4425 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4429 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4433 MCRegister Src2Reg = Src2.
getReg();
4435 if (Src2Reg == DstReg)
4440 .getSizeInBits() <= 128)
4443 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4444 Error(getOperandLoc(Operands, Src2Idx),
4445 "source 2 operand must not partially overlap with dst");
4452bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4456 case V_DIV_SCALE_F32_gfx6_gfx7:
4457 case V_DIV_SCALE_F32_vi:
4458 case V_DIV_SCALE_F32_gfx10:
4459 case V_DIV_SCALE_F64_gfx6_gfx7:
4460 case V_DIV_SCALE_F64_vi:
4461 case V_DIV_SCALE_F64_gfx10:
4467 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4468 AMDGPU::OpName::src2_modifiers,
4469 AMDGPU::OpName::src2_modifiers}) {
4480bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4488 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4497bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4504 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4512 case AMDGPU::V_SUBREV_F32_e32:
4513 case AMDGPU::V_SUBREV_F32_e64:
4514 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4515 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4516 case AMDGPU::V_SUBREV_F32_e32_vi:
4517 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4518 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4519 case AMDGPU::V_SUBREV_F32_e64_vi:
4521 case AMDGPU::V_SUBREV_CO_U32_e32:
4522 case AMDGPU::V_SUBREV_CO_U32_e64:
4523 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4524 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4526 case AMDGPU::V_SUBBREV_U32_e32:
4527 case AMDGPU::V_SUBBREV_U32_e64:
4528 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4529 case AMDGPU::V_SUBBREV_U32_e32_vi:
4530 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4531 case AMDGPU::V_SUBBREV_U32_e64_vi:
4533 case AMDGPU::V_SUBREV_U32_e32:
4534 case AMDGPU::V_SUBREV_U32_e64:
4535 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4536 case AMDGPU::V_SUBREV_U32_e32_vi:
4537 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4538 case AMDGPU::V_SUBREV_U32_e64_vi:
4540 case AMDGPU::V_SUBREV_F16_e32:
4541 case AMDGPU::V_SUBREV_F16_e64:
4542 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4543 case AMDGPU::V_SUBREV_F16_e32_vi:
4544 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4545 case AMDGPU::V_SUBREV_F16_e64_vi:
4547 case AMDGPU::V_SUBREV_U16_e32:
4548 case AMDGPU::V_SUBREV_U16_e64:
4549 case AMDGPU::V_SUBREV_U16_e32_vi:
4550 case AMDGPU::V_SUBREV_U16_e64_vi:
4552 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4553 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4554 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4556 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4557 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4559 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4560 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4562 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4563 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4565 case AMDGPU::V_LSHRREV_B32_e32:
4566 case AMDGPU::V_LSHRREV_B32_e64:
4567 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4568 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4569 case AMDGPU::V_LSHRREV_B32_e32_vi:
4570 case AMDGPU::V_LSHRREV_B32_e64_vi:
4571 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4572 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4574 case AMDGPU::V_ASHRREV_I32_e32:
4575 case AMDGPU::V_ASHRREV_I32_e64:
4576 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4577 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4578 case AMDGPU::V_ASHRREV_I32_e32_vi:
4579 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4580 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4581 case AMDGPU::V_ASHRREV_I32_e64_vi:
4583 case AMDGPU::V_LSHLREV_B32_e32:
4584 case AMDGPU::V_LSHLREV_B32_e64:
4585 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4586 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4587 case AMDGPU::V_LSHLREV_B32_e32_vi:
4588 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4589 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4590 case AMDGPU::V_LSHLREV_B32_e64_vi:
4592 case AMDGPU::V_LSHLREV_B16_e32:
4593 case AMDGPU::V_LSHLREV_B16_e64:
4594 case AMDGPU::V_LSHLREV_B16_e32_vi:
4595 case AMDGPU::V_LSHLREV_B16_e64_vi:
4596 case AMDGPU::V_LSHLREV_B16_gfx10:
4598 case AMDGPU::V_LSHRREV_B16_e32:
4599 case AMDGPU::V_LSHRREV_B16_e64:
4600 case AMDGPU::V_LSHRREV_B16_e32_vi:
4601 case AMDGPU::V_LSHRREV_B16_e64_vi:
4602 case AMDGPU::V_LSHRREV_B16_gfx10:
4604 case AMDGPU::V_ASHRREV_I16_e32:
4605 case AMDGPU::V_ASHRREV_I16_e64:
4606 case AMDGPU::V_ASHRREV_I16_e32_vi:
4607 case AMDGPU::V_ASHRREV_I16_e64_vi:
4608 case AMDGPU::V_ASHRREV_I16_gfx10:
4610 case AMDGPU::V_LSHLREV_B64_e64:
4611 case AMDGPU::V_LSHLREV_B64_gfx10:
4612 case AMDGPU::V_LSHLREV_B64_vi:
4614 case AMDGPU::V_LSHRREV_B64_e64:
4615 case AMDGPU::V_LSHRREV_B64_gfx10:
4616 case AMDGPU::V_LSHRREV_B64_vi:
4618 case AMDGPU::V_ASHRREV_I64_e64:
4619 case AMDGPU::V_ASHRREV_I64_gfx10:
4620 case AMDGPU::V_ASHRREV_I64_vi:
4622 case AMDGPU::V_PK_LSHLREV_B16:
4623 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4624 case AMDGPU::V_PK_LSHLREV_B16_vi:
4626 case AMDGPU::V_PK_LSHRREV_B16:
4627 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4628 case AMDGPU::V_PK_LSHRREV_B16_vi:
4629 case AMDGPU::V_PK_ASHRREV_I16:
4630 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4631 case AMDGPU::V_PK_ASHRREV_I16_vi:
4638bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4640 using namespace SIInstrFlags;
4641 const unsigned Opcode = Inst.
getOpcode();
4642 const MCInstrDesc &
Desc = MII.
get(Opcode);
4647 if ((
Desc.TSFlags & Enc) == 0)
4650 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4651 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4655 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4658 Error(getOperandLoc(Operands, SrcIdx),
4659 "lds_direct is not supported on this GPU");
4664 Error(getOperandLoc(Operands, SrcIdx),
4665 "lds_direct cannot be used with this instruction");
4669 if (SrcName != OpName::src0) {
4670 Error(getOperandLoc(Operands, SrcIdx),
4671 "lds_direct may be used as src0 only");
4680SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4681 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4682 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4683 if (
Op.isFlatOffset())
4684 return Op.getStartLoc();
4689bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4692 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4698 return validateFlatOffset(Inst, Operands);
4701 return validateSMEMOffset(Inst, Operands);
4707 const unsigned OffsetSize = 24;
4708 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4709 Error(getFlatOffsetLoc(Operands),
4710 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4711 "-bit unsigned offset for buffer ops");
4715 const unsigned OffsetSize = 16;
4716 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4717 Error(getFlatOffsetLoc(Operands),
4718 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4725bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4732 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4736 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4737 Error(getFlatOffsetLoc(Operands),
4738 "flat offset modifier is not supported on this GPU");
4745 bool AllowNegative =
4748 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4749 Error(getFlatOffsetLoc(Operands),
4750 Twine(
"expected a ") +
4751 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4752 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4759SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4761 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4762 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4763 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4764 return Op.getStartLoc();
4769bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4779 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4793 Error(getSMEMOffsetLoc(Operands),
4795 ?
"expected a 23-bit unsigned offset for buffer ops"
4796 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4797 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4798 :
"expected a 21-bit signed offset");
4803bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4806 const MCInstrDesc &
Desc = MII.
get(Opcode);
4810 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4811 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4813 const int OpIndices[] = { Src0Idx, Src1Idx };
4815 unsigned NumExprs = 0;
4816 unsigned NumLiterals = 0;
4819 for (
int OpIdx : OpIndices) {
4820 if (
OpIdx == -1)
break;
4826 std::optional<int64_t>
Imm;
4829 }
else if (MO.
isExpr()) {
4838 if (!
Imm.has_value()) {
4840 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4844 if (NumLiterals == 0 || LiteralValue !=
Value) {
4852 if (NumLiterals + NumExprs <= 1)
4855 Error(getOperandLoc(Operands, Src1Idx),
4856 "only one unique literal operand is allowed");
4860bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4863 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4873 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4874 if (OpSelIdx != -1) {
4878 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4879 if (OpSelHiIdx != -1) {
4888 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4898 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4899 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4900 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4901 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4903 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4904 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4910 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4912 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4922 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4923 if (Src2Idx != -1) {
4924 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4934bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4935 if (!hasTrue16Insts())
4937 const MCRegisterInfo *
MRI = getMRI();
4939 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4945 if (OpSelOpValue == 0)
4947 unsigned OpCount = 0;
4948 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4949 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4950 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4955 MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(
Op.getReg())) {
4957 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4958 if (OpSelOpIsHi != VGPRSuffixIsHi)
4967bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4968 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4981 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
4992 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4993 AMDGPU::OpName::src1_modifiers,
4994 AMDGPU::OpName::src2_modifiers};
4996 for (
unsigned i = 0; i < 3; ++i) {
5006bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5009 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5010 if (DppCtrlIdx >= 0) {
5017 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5018 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5019 :
"DP ALU dpp only supports row_newbcast");
5024 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5025 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5028 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5030 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5033 Error(getOperandLoc(Operands, Src1Idx),
5034 "invalid operand for instruction");
5038 Error(getInstLoc(Operands),
5039 "src1 immediate operand invalid for instruction");
5049bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5050 return (
Reg == AMDGPU::VCC && isWave64()) ||
5051 (
Reg == AMDGPU::VCC_LO && isWave32());
5055bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5058 const MCInstrDesc &
Desc = MII.
get(Opcode);
5059 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5061 !HasMandatoryLiteral && !
isVOPD(Opcode))
5066 std::optional<unsigned> LiteralOpIdx;
5069 for (
int OpIdx : OpIndices) {
5079 std::optional<int64_t>
Imm;
5085 bool IsAnotherLiteral =
false;
5086 if (!
Imm.has_value()) {
5088 IsAnotherLiteral =
true;
5089 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5094 HasMandatoryLiteral);
5100 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5102 "invalid operand for instruction");
5106 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5113 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5114 !getFeatureBits()[FeatureVOP3Literal]) {
5116 "literal operands are not supported");
5120 if (LiteralOpIdx && IsAnotherLiteral) {
5121 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5122 getOperandLoc(Operands, *LiteralOpIdx)),
5123 "only one unique literal operand is allowed");
5127 if (IsAnotherLiteral)
5128 LiteralOpIdx =
OpIdx;
5151bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5159 ? AMDGPU::OpName::data0
5160 : AMDGPU::OpName::vdata;
5162 const MCRegisterInfo *
MRI = getMRI();
5168 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5172 auto FB = getFeatureBits();
5173 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5174 if (DataAreg < 0 || DstAreg < 0)
5176 return DstAreg == DataAreg;
5179 return DstAreg < 1 && DataAreg < 1;
5182bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5183 auto FB = getFeatureBits();
5184 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5188 const MCRegisterInfo *
MRI = getMRI();
5191 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5194 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5198 case AMDGPU::DS_LOAD_TR6_B96:
5199 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5203 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5204 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5208 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5209 if (VAddrIdx != -1) {
5211 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5212 if ((
Sub - AMDGPU::VGPR0) & 1)
5217 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5218 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5223 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5224 const MCRegisterClass &AGPR32 =
MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
5230 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5243SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5244 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5245 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5247 return Op.getStartLoc();
5252bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5255 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5258 SMLoc BLGPLoc = getBLGPLoc(Operands);
5261 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5262 auto FB = getFeatureBits();
5263 bool UsesNeg =
false;
5264 if (FB[AMDGPU::FeatureGFX940Insts]) {
5266 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5267 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5268 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5269 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5274 if (IsNeg == UsesNeg)
5278 UsesNeg ?
"invalid modifier: blgp is not supported"
5279 :
"invalid modifier: neg is not supported");
5284bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5290 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5291 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5292 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5293 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5296 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5299 if (
Reg == AMDGPU::SGPR_NULL)
5302 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5306bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5312 return validateGWS(Inst, Operands);
5317 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5322 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5323 Error(S,
"gds modifier is not supported on this GPU");
5331bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5333 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5337 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5338 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5341 const MCRegisterInfo *
MRI = getMRI();
5342 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5344 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5347 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5349 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5356bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5359 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5360 AMDGPU::OpName::cpol);
5368 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5371 Error(S,
"scale_offset is not supported on this GPU");
5374 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5377 Error(S,
"nv is not supported on this GPU");
5382 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5385 Error(S,
"scale_offset is not supported for this instruction");
5389 return validateTHAndScopeBits(Inst, Operands, CPol);
5394 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5395 Error(S,
"cache policy is not supported for SMRD instructions");
5399 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5408 if (!(TSFlags & AllowSCCModifier)) {
5409 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5413 "scc modifier is not supported for this instruction on this GPU");
5424 :
"instruction must use glc");
5429 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5432 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5434 :
"instruction must not use glc");
5442bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5444 const unsigned CPol) {
5448 const unsigned Opcode = Inst.
getOpcode();
5449 const MCInstrDesc &TID = MII.
get(Opcode);
5452 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5460 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5468 return PrintError(
"invalid th value for SMEM instruction");
5475 return PrintError(
"scope and th combination is not valid");
5481 return PrintError(
"invalid th value for atomic instructions");
5484 return PrintError(
"invalid th value for store instructions");
5487 return PrintError(
"invalid th value for load instructions");
5493bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5496 if (
Desc.mayStore() &&
5498 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5499 if (Loc != getInstLoc(Operands)) {
5500 Error(Loc,
"TFE modifier has no meaning for store instructions");
5508bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5514 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5515 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5519 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5527 static const char *FmtNames[] = {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
5528 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
5531 Error(getOperandLoc(Operands, SrcIdx),
5532 "wrong register tuple size for " + Twine(FmtNames[Fmt]));
5536 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5537 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5540bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5542 if (!validateLdsDirect(Inst, Operands))
5544 if (!validateTrue16OpSel(Inst)) {
5545 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5546 "op_sel operand conflicts with 16-bit operand suffix");
5549 if (!validateSOPLiteral(Inst, Operands))
5551 if (!validateVOPLiteral(Inst, Operands)) {
5554 if (!validateConstantBusLimitations(Inst, Operands)) {
5557 if (!validateVOPD(Inst, Operands)) {
5560 if (!validateIntClampSupported(Inst)) {
5561 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5562 "integer clamping is not supported on this GPU");
5565 if (!validateOpSel(Inst)) {
5566 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5567 "invalid op_sel operand");
5570 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5571 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5572 "invalid neg_lo operand");
5575 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5576 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5577 "invalid neg_hi operand");
5580 if (!validateDPP(Inst, Operands)) {
5584 if (!validateMIMGD16(Inst)) {
5585 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5586 "d16 modifier is not supported on this GPU");
5589 if (!validateMIMGDim(Inst, Operands)) {
5590 Error(IDLoc,
"missing dim operand");
5593 if (!validateTensorR128(Inst)) {
5594 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5595 "instruction must set modifier r128=0");
5598 if (!validateMIMGMSAA(Inst)) {
5599 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5600 "invalid dim; must be MSAA type");
5603 if (!validateMIMGDataSize(Inst, IDLoc)) {
5606 if (!validateMIMGAddrSize(Inst, IDLoc))
5608 if (!validateMIMGAtomicDMask(Inst)) {
5609 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5610 "invalid atomic image dmask");
5613 if (!validateMIMGGatherDMask(Inst)) {
5614 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5615 "invalid image_gather dmask: only one bit must be set");
5618 if (!validateMovrels(Inst, Operands)) {
5621 if (!validateOffset(Inst, Operands)) {
5624 if (!validateMAIAccWrite(Inst, Operands)) {
5627 if (!validateMAISrc2(Inst, Operands)) {
5630 if (!validateMFMA(Inst, Operands)) {
5633 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5637 if (!validateAGPRLdSt(Inst)) {
5638 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5639 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5640 :
"invalid register class: agpr loads and stores not supported on this GPU"
5644 if (!validateVGPRAlign(Inst)) {
5646 "invalid register class: vgpr tuples must be 64 bit aligned");
5649 if (!validateDS(Inst, Operands)) {
5653 if (!validateBLGP(Inst, Operands)) {
5657 if (!validateDivScale(Inst)) {
5658 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5661 if (!validateWaitCnt(Inst, Operands)) {
5664 if (!validateTFE(Inst, Operands)) {
5667 if (!validateWMMA(Inst, Operands)) {
5676 unsigned VariantID = 0);
5680 unsigned VariantID);
5682bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5687bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5688 const FeatureBitset &FBS,
5689 ArrayRef<unsigned> Variants) {
5690 for (
auto Variant : Variants) {
5698bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5700 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5703 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5708 getParser().clearPendingErrors();
5712 StringRef VariantName = getMatchedVariantName();
5713 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5716 " variant of this instruction is not supported"));
5720 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5721 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5723 FeatureBitset FeaturesWS32 = getFeatureBits();
5724 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5725 .
flip(AMDGPU::FeatureWavefrontSize32);
5726 FeatureBitset AvailableFeaturesWS32 =
5727 ComputeAvailableFeatures(FeaturesWS32);
5729 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5730 return Error(IDLoc,
"instruction requires wavesize=32");
5734 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5735 return Error(IDLoc,
"instruction not supported on this GPU");
5740 return Error(IDLoc,
"invalid instruction" + Suggestion);
5746 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5747 if (
Op.isToken() && InvalidOprIdx > 1) {
5748 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5749 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5754bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5757 uint64_t &ErrorInfo,
5758 bool MatchingInlineAsm) {
5761 unsigned Result = Match_Success;
5762 for (
auto Variant : getMatchedVariants()) {
5764 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5769 if (R == Match_Success || R == Match_MissingFeature ||
5770 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5771 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5772 Result != Match_MissingFeature)) {
5776 if (R == Match_Success)
5780 if (Result == Match_Success) {
5781 if (!validateInstruction(Inst, IDLoc, Operands)) {
5788 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5789 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5795 case Match_MissingFeature:
5799 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5801 case Match_InvalidOperand: {
5802 SMLoc ErrorLoc = IDLoc;
5803 if (ErrorInfo != ~0ULL) {
5804 if (ErrorInfo >= Operands.
size()) {
5805 return Error(IDLoc,
"too few operands for instruction");
5807 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5808 if (ErrorLoc == SMLoc())
5812 return Error(ErrorLoc,
"invalid VOPDY instruction");
5814 return Error(ErrorLoc,
"invalid operand for instruction");
5817 case Match_MnemonicFail:
5823bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5828 if (getParser().parseAbsoluteExpression(Tmp)) {
5831 Ret =
static_cast<uint32_t
>(Tmp);
5835bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5836 if (!getSTI().getTargetTriple().isAMDGCN())
5837 return TokError(
"directive only supported for amdgcn architecture");
5839 std::string TargetIDDirective;
5840 SMLoc TargetStart = getTok().getLoc();
5841 if (getParser().parseEscapedString(TargetIDDirective))
5844 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5845 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5846 return getParser().Error(TargetRange.
Start,
5847 (Twine(
".amdgcn_target directive's target id ") +
5848 Twine(TargetIDDirective) +
5849 Twine(
" does not match the specified target id ") +
5850 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5855bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5859bool AMDGPUAsmParser::calculateGPRBlocks(
5860 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5861 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5862 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5863 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5864 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5870 const MCExpr *
NumSGPRs = NextFreeSGPR;
5871 int64_t EvaluatedSGPRs;
5876 unsigned MaxAddressableNumSGPRs =
5879 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5880 !Features.
test(FeatureSGPRInitBug) &&
5881 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5882 return OutOfRangeError(SGPRRange);
5884 const MCExpr *ExtraSGPRs =
5888 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5889 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5890 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5891 return OutOfRangeError(SGPRRange);
5893 if (Features.
test(FeatureSGPRInitBug))
5900 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5901 unsigned Granule) ->
const MCExpr * {
5905 const MCExpr *AlignToGPR =
5907 const MCExpr *DivGPR =
5913 VGPRBlocks = GetNumGPRBlocks(
5922bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5923 if (!getSTI().getTargetTriple().isAMDGCN())
5924 return TokError(
"directive only supported for amdgcn architecture");
5927 return TokError(
"directive only supported for amdhsa OS");
5929 StringRef KernelName;
5930 if (getParser().parseIdentifier(KernelName))
5933 AMDGPU::MCKernelDescriptor KD =
5945 const MCExpr *NextFreeVGPR = ZeroExpr;
5947 const MCExpr *NamedBarCnt = ZeroExpr;
5948 uint64_t SharedVGPRCount = 0;
5949 uint64_t PreloadLength = 0;
5950 uint64_t PreloadOffset = 0;
5952 const MCExpr *NextFreeSGPR = ZeroExpr;
5955 unsigned ImpliedUserSGPRCount = 0;
5959 std::optional<unsigned> ExplicitUserSGPRCount;
5960 const MCExpr *ReserveVCC = OneExpr;
5961 const MCExpr *ReserveFlatScr = OneExpr;
5962 std::optional<bool> EnableWavefrontSize32;
5968 SMRange IDRange = getTok().getLocRange();
5969 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5972 if (
ID ==
".end_amdhsa_kernel")
5976 return TokError(
".amdhsa_ directives cannot be repeated");
5978 SMLoc ValStart = getLoc();
5979 const MCExpr *ExprVal;
5980 if (getParser().parseExpression(ExprVal))
5982 SMLoc ValEnd = getLoc();
5983 SMRange ValRange = SMRange(ValStart, ValEnd);
5986 uint64_t Val = IVal;
5987 bool EvaluatableExpr;
5988 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5990 return OutOfRangeError(ValRange);
5994#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5995 if (!isUInt<ENTRY##_WIDTH>(Val)) \
5996 return OutOfRangeError(RANGE); \
5997 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6002#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6004 return Error(IDRange.Start, "directive should have resolvable expression", \
6007 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6010 return OutOfRangeError(ValRange);
6012 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6015 return OutOfRangeError(ValRange);
6017 }
else if (
ID ==
".amdhsa_kernarg_size") {
6019 return OutOfRangeError(ValRange);
6021 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6023 ExplicitUserSGPRCount = Val;
6024 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6028 "directive is not supported with architected flat scratch",
6031 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6034 ImpliedUserSGPRCount += 4;
6035 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6038 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6041 return OutOfRangeError(ValRange);
6045 ImpliedUserSGPRCount += Val;
6046 PreloadLength = Val;
6048 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6051 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6054 return OutOfRangeError(ValRange);
6058 PreloadOffset = Val;
6059 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6062 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6065 ImpliedUserSGPRCount += 2;
6066 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6069 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6072 ImpliedUserSGPRCount += 2;
6073 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6076 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6079 ImpliedUserSGPRCount += 2;
6080 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6083 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6086 ImpliedUserSGPRCount += 2;
6087 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6090 "directive is not supported with architected flat scratch",
6094 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6097 ImpliedUserSGPRCount += 2;
6098 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6101 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6104 ImpliedUserSGPRCount += 1;
6105 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6107 if (IVersion.
Major < 10)
6108 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6109 EnableWavefrontSize32 = Val;
6111 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6113 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6115 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6117 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6120 "directive is not supported with architected flat scratch",
6123 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6125 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6129 "directive is not supported without architected flat scratch",
6132 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6134 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6136 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6138 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6140 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6142 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6144 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6146 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6148 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6150 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6152 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6154 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6155 VGPRRange = ValRange;
6156 NextFreeVGPR = ExprVal;
6157 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6158 SGPRRange = ValRange;
6159 NextFreeSGPR = ExprVal;
6160 }
else if (
ID ==
".amdhsa_accum_offset") {
6162 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6163 AccumOffset = ExprVal;
6164 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6166 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6167 NamedBarCnt = ExprVal;
6168 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6170 return OutOfRangeError(ValRange);
6171 ReserveVCC = ExprVal;
6172 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6173 if (IVersion.
Major < 7)
6174 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6177 "directive is not supported with architected flat scratch",
6180 return OutOfRangeError(ValRange);
6181 ReserveFlatScr = ExprVal;
6182 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6183 if (IVersion.
Major < 8)
6184 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6186 return OutOfRangeError(ValRange);
6187 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6188 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6190 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6192 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6194 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6196 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6198 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6200 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6202 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6204 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6206 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6207 if (IVersion.
Major >= 12)
6208 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6210 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6212 }
else if (
ID ==
".amdhsa_ieee_mode") {
6213 if (IVersion.
Major >= 12)
6214 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6216 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6218 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6219 if (IVersion.
Major < 9)
6220 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6222 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6224 }
else if (
ID ==
".amdhsa_tg_split") {
6226 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6229 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6232 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6234 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6236 }
else if (
ID ==
".amdhsa_memory_ordered") {
6237 if (IVersion.
Major < 10)
6238 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6240 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6242 }
else if (
ID ==
".amdhsa_forward_progress") {
6243 if (IVersion.
Major < 10)
6244 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6246 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6248 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6250 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6251 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6253 SharedVGPRCount = Val;
6255 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6257 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6258 if (IVersion.
Major < 11)
6259 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6260 if (IVersion.
Major == 11) {
6262 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6266 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6269 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6272 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6274 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6276 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6278 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6281 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6283 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6285 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6287 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6289 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6291 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6293 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6295 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6297 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6299 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6300 if (IVersion.
Major < 12)
6301 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6303 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6306 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6309#undef PARSE_BITS_ENTRY
6312 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6313 return TokError(
".amdhsa_next_free_vgpr directive is required");
6315 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6316 return TokError(
".amdhsa_next_free_sgpr directive is required");
6318 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6323 if (PreloadLength) {
6329 const MCExpr *VGPRBlocks;
6330 const MCExpr *SGPRBlocks;
6331 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6332 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6333 EnableWavefrontSize32, NextFreeVGPR,
6334 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6338 int64_t EvaluatedVGPRBlocks;
6339 bool VGPRBlocksEvaluatable =
6340 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6341 if (VGPRBlocksEvaluatable &&
6343 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6344 return OutOfRangeError(VGPRRange);
6348 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6349 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6351 int64_t EvaluatedSGPRBlocks;
6352 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6354 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6355 return OutOfRangeError(SGPRRange);
6358 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6359 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6361 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6362 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6363 "enabled user SGPRs");
6367 return TokError(
"too many user SGPRs enabled");
6371 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6372 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6376 return TokError(
"too many user SGPRs enabled");
6380 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6381 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6386 return TokError(
"Kernarg size should be resolvable");
6387 uint64_t kernarg_size = IVal;
6388 if (PreloadLength && kernarg_size &&
6389 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6390 return TokError(
"Kernarg preload length + offset is larger than the "
6391 "kernarg segment size");
6394 if (!Seen.
contains(
".amdhsa_accum_offset"))
6395 return TokError(
".amdhsa_accum_offset directive is required");
6396 int64_t EvaluatedAccum;
6397 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6398 uint64_t UEvaluatedAccum = EvaluatedAccum;
6399 if (AccumEvaluatable &&
6400 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6401 return TokError(
"accum_offset should be in range [4..256] in "
6404 int64_t EvaluatedNumVGPR;
6405 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6408 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6409 return TokError(
"accum_offset exceeds total VGPR allocation");
6415 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6416 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6422 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6423 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6426 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6428 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6429 return TokError(
"shared_vgpr_count directive not valid on "
6430 "wavefront size 32");
6433 if (VGPRBlocksEvaluatable &&
6434 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6436 return TokError(
"shared_vgpr_count*2 + "
6437 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6442 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6443 NextFreeVGPR, NextFreeSGPR,
6444 ReserveVCC, ReserveFlatScr);
6448bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6450 if (ParseAsAbsoluteExpression(
Version))
6453 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6457bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6458 AMDGPUMCKernelCodeT &
C) {
6461 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6462 Parser.eatToEndOfStatement();
6466 SmallString<40> ErrStr;
6467 raw_svector_ostream Err(ErrStr);
6468 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6469 return TokError(Err.
str());
6473 if (
ID ==
"enable_wavefront_size32") {
6476 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6478 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6481 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6485 if (
ID ==
"wavefront_size") {
6486 if (
C.wavefront_size == 5) {
6488 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6490 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6491 }
else if (
C.wavefront_size == 6) {
6493 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6500bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6501 AMDGPUMCKernelCodeT KernelCode;
6510 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6513 if (
ID ==
".end_amd_kernel_code_t")
6516 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6521 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6526bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6527 StringRef KernelName;
6528 if (!parseId(KernelName,
"expected symbol name"))
6531 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6538bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6539 if (!getSTI().getTargetTriple().isAMDGCN()) {
6540 return Error(getLoc(),
6541 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6545 auto TargetIDDirective = getLexer().getTok().getStringContents();
6546 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6547 return Error(getParser().getTok().getLoc(),
"target id must match options");
6549 getTargetStreamer().EmitISAVersion();
6555bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6558 std::string HSAMetadataString;
6563 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6564 return Error(getLoc(),
"invalid HSA metadata");
6571bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6572 const char *AssemblerDirectiveEnd,
6573 std::string &CollectString) {
6575 raw_string_ostream CollectStream(CollectString);
6577 getLexer().setSkipSpace(
false);
6579 bool FoundEnd =
false;
6582 CollectStream << getTokenStr();
6586 if (trySkipId(AssemblerDirectiveEnd)) {
6591 CollectStream << Parser.parseStringToEndOfStatement()
6592 <<
getContext().getAsmInfo()->getSeparatorString();
6594 Parser.eatToEndOfStatement();
6597 getLexer().setSkipSpace(
true);
6600 return TokError(Twine(
"expected directive ") +
6601 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6608bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6614 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6615 if (!PALMetadata->setFromString(
String))
6616 return Error(getLoc(),
"invalid PAL metadata");
6621bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6623 return Error(getLoc(),
6625 "not available on non-amdpal OSes")).str());
6628 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6629 PALMetadata->setLegacy();
6632 if (ParseAsAbsoluteExpression(
Key)) {
6633 return TokError(Twine(
"invalid value in ") +
6637 return TokError(Twine(
"expected an even number of values in ") +
6640 if (ParseAsAbsoluteExpression(
Value)) {
6641 return TokError(Twine(
"invalid value in ") +
6644 PALMetadata->setRegister(
Key,
Value);
6653bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6654 if (getParser().checkForValidSection())
6658 SMLoc NameLoc = getLoc();
6659 if (getParser().parseIdentifier(Name))
6660 return TokError(
"expected identifier in directive");
6663 if (getParser().parseComma())
6669 SMLoc SizeLoc = getLoc();
6670 if (getParser().parseAbsoluteExpression(
Size))
6673 return Error(SizeLoc,
"size must be non-negative");
6674 if (
Size > LocalMemorySize)
6675 return Error(SizeLoc,
"size is too large");
6677 int64_t Alignment = 4;
6679 SMLoc AlignLoc = getLoc();
6680 if (getParser().parseAbsoluteExpression(Alignment))
6683 return Error(AlignLoc,
"alignment must be a power of two");
6688 if (Alignment >= 1u << 31)
6689 return Error(AlignLoc,
"alignment is too large");
6695 Symbol->redefineIfPossible();
6696 if (!
Symbol->isUndefined())
6697 return Error(NameLoc,
"invalid symbol redefinition");
6699 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6703bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6704 StringRef IDVal = DirectiveID.
getString();
6707 if (IDVal ==
".amdhsa_kernel")
6708 return ParseDirectiveAMDHSAKernel();
6710 if (IDVal ==
".amdhsa_code_object_version")
6711 return ParseDirectiveAMDHSACodeObjectVersion();
6715 return ParseDirectiveHSAMetadata();
6717 if (IDVal ==
".amd_kernel_code_t")
6718 return ParseDirectiveAMDKernelCodeT();
6720 if (IDVal ==
".amdgpu_hsa_kernel")
6721 return ParseDirectiveAMDGPUHsaKernel();
6723 if (IDVal ==
".amd_amdgpu_isa")
6724 return ParseDirectiveISAVersion();
6728 Twine(
" directive is "
6729 "not available on non-amdhsa OSes"))
6734 if (IDVal ==
".amdgcn_target")
6735 return ParseDirectiveAMDGCNTarget();
6737 if (IDVal ==
".amdgpu_lds")
6738 return ParseDirectiveAMDGPULDS();
6741 return ParseDirectivePALMetadataBegin();
6744 return ParseDirectivePALMetadata();
6749bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
6751 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
6755 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
6756 return hasSGPR104_SGPR105();
6759 case SRC_SHARED_BASE_LO:
6760 case SRC_SHARED_BASE:
6761 case SRC_SHARED_LIMIT_LO:
6762 case SRC_SHARED_LIMIT:
6763 case SRC_PRIVATE_BASE_LO:
6764 case SRC_PRIVATE_BASE:
6765 case SRC_PRIVATE_LIMIT_LO:
6766 case SRC_PRIVATE_LIMIT:
6768 case SRC_FLAT_SCRATCH_BASE_LO:
6769 case SRC_FLAT_SCRATCH_BASE_HI:
6770 return hasGloballyAddressableScratch();
6771 case SRC_POPS_EXITING_WAVE_ID:
6783 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6812 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
6813 return hasSGPR102_SGPR103();
6818ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6821 ParseStatus Res = parseVOPD(Operands);
6826 Res = MatchOperandParserImpl(Operands, Mnemonic);
6838 SMLoc LBraceLoc = getLoc();
6843 auto Loc = getLoc();
6844 Res = parseReg(Operands);
6846 Error(Loc,
"expected a register");
6850 RBraceLoc = getLoc();
6855 "expected a comma or a closing square bracket"))
6859 if (Operands.
size() - Prefix > 1) {
6861 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6862 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6868 return parseRegOrImm(Operands);
6871StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6873 setForcedEncodingSize(0);
6874 setForcedDPP(
false);
6875 setForcedSDWA(
false);
6877 if (
Name.consume_back(
"_e64_dpp")) {
6879 setForcedEncodingSize(64);
6882 if (
Name.consume_back(
"_e64")) {
6883 setForcedEncodingSize(64);
6886 if (
Name.consume_back(
"_e32")) {
6887 setForcedEncodingSize(32);
6890 if (
Name.consume_back(
"_dpp")) {
6894 if (
Name.consume_back(
"_sdwa")) {
6895 setForcedSDWA(
true);
6903 unsigned VariantID);
6909 Name = parseMnemonicSuffix(Name);
6915 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6917 bool IsMIMG = Name.starts_with(
"image_");
6920 OperandMode
Mode = OperandMode_Default;
6922 Mode = OperandMode_NSA;
6926 checkUnsupportedInstruction(Name, NameLoc);
6927 if (!Parser.hasPendingError()) {
6930 :
"not a valid operand.";
6931 Error(getLoc(), Msg);
6950ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6953 if (!trySkipId(Name))
6956 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6960ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6969ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6970 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6971 std::function<
bool(int64_t &)> ConvertResult) {
6975 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
6979 if (ConvertResult && !ConvertResult(
Value)) {
6980 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
6983 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6987ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6988 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6989 bool (*ConvertResult)(int64_t &)) {
6998 const unsigned MaxSize = 4;
7002 for (
int I = 0; ; ++
I) {
7004 SMLoc Loc = getLoc();
7008 if (
Op != 0 &&
Op != 1)
7009 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7016 if (
I + 1 == MaxSize)
7017 return Error(getLoc(),
"expected a closing square bracket");
7023 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7027ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7029 AMDGPUOperand::ImmTy ImmTy) {
7033 if (trySkipId(Name)) {
7035 }
else if (trySkipId(
"no", Name)) {
7042 return Error(S,
"r128 modifier is not supported on this GPU");
7043 if (Name ==
"a16" && !
hasA16())
7044 return Error(S,
"a16 modifier is not supported on this GPU");
7046 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7047 ImmTy = AMDGPUOperand::ImmTyR128A16;
7049 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7053unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7054 bool &Disabling)
const {
7055 Disabling =
Id.consume_front(
"no");
7058 return StringSwitch<unsigned>(Id)
7065 return StringSwitch<unsigned>(Id)
7073ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7075 SMLoc StringLoc = getLoc();
7077 int64_t CPolVal = 0;
7086 ResTH = parseTH(Operands, TH);
7097 ResScope = parseScope(Operands, Scope);
7110 if (trySkipId(
"nv")) {
7114 }
else if (trySkipId(
"no",
"nv")) {
7121 if (trySkipId(
"scale_offset")) {
7125 }
else if (trySkipId(
"no",
"scale_offset")) {
7138 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7139 AMDGPUOperand::ImmTyCPol));
7143 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7144 SMLoc OpLoc = getLoc();
7145 unsigned Enabled = 0, Seen = 0;
7149 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7156 return Error(S,
"dlc modifier is not supported on this GPU");
7159 return Error(S,
"scc modifier is not supported on this GPU");
7162 return Error(S,
"duplicate cache policy modifier");
7174 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7178ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7183 ParseStatus Res = parseStringOrIntWithPrefix(
7184 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7193ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7198 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7202 if (
Value ==
"TH_DEFAULT")
7204 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7205 Value ==
"TH_LOAD_NT_WB") {
7206 return Error(StringLoc,
"invalid th value");
7207 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7209 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7211 }
else if (
Value.consume_front(
"TH_STORE_")) {
7214 return Error(StringLoc,
"invalid th value");
7217 if (
Value ==
"BYPASS")
7222 TH |= StringSwitch<int64_t>(
Value)
7232 .Default(0xffffffff);
7234 TH |= StringSwitch<int64_t>(
Value)
7245 .Default(0xffffffff);
7248 if (TH == 0xffffffff)
7249 return Error(StringLoc,
"invalid th value");
7256 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7257 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7258 std::optional<unsigned> InsertAt = std::nullopt) {
7259 auto i = OptionalIdx.find(ImmT);
7260 if (i != OptionalIdx.end()) {
7261 unsigned Idx = i->second;
7262 const AMDGPUOperand &
Op =
7263 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7267 Op.addImmOperands(Inst, 1);
7269 if (InsertAt.has_value())
7276ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7282 StringLoc = getLoc();
7287ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7288 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7293 SMLoc StringLoc = getLoc();
7297 Value = getTokenStr();
7301 if (
Value == Ids[IntVal])
7306 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7307 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7312ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7313 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7314 AMDGPUOperand::ImmTy
Type) {
7318 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7320 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7329bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7333 SMLoc Loc = getLoc();
7335 auto Res = parseIntWithPrefix(Pref, Val);
7341 if (Val < 0 || Val > MaxVal) {
7342 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7350ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7351 AMDGPUOperand::ImmTy ImmTy) {
7352 const char *Pref =
"index_key";
7354 SMLoc Loc = getLoc();
7355 auto Res = parseIntWithPrefix(Pref, ImmVal);
7359 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7360 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7361 (ImmVal < 0 || ImmVal > 1))
7362 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7364 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7365 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7367 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7371ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7372 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7375ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7376 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7379ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7380 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7383ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7385 AMDGPUOperand::ImmTy
Type) {
7386 return parseStringOrIntWithPrefix(Operands, Name,
7387 {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
7388 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
7393ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7394 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7395 AMDGPUOperand::ImmTyMatrixAFMT);
7398ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7399 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7400 AMDGPUOperand::ImmTyMatrixBFMT);
7403ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7405 AMDGPUOperand::ImmTy
Type) {
7406 return parseStringOrIntWithPrefix(
7407 Operands, Name, {
"MATRIX_SCALE_ROW0",
"MATRIX_SCALE_ROW1"},
Type);
7410ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7411 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7412 AMDGPUOperand::ImmTyMatrixAScale);
7415ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7416 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7417 AMDGPUOperand::ImmTyMatrixBScale);
7420ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7422 AMDGPUOperand::ImmTy
Type) {
7423 return parseStringOrIntWithPrefix(
7425 {
"MATRIX_SCALE_FMT_E8",
"MATRIX_SCALE_FMT_E5M3",
"MATRIX_SCALE_FMT_E4M3"},
7429ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7430 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7431 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7434ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7435 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7436 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7441ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7442 using namespace llvm::AMDGPU::MTBUFFormat;
7448 for (
int I = 0;
I < 2; ++
I) {
7449 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7452 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7457 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7463 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7466 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7467 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7473ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7474 using namespace llvm::AMDGPU::MTBUFFormat;
7478 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7481 if (Fmt == UFMT_UNDEF)
7488bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7490 StringRef FormatStr,
7492 using namespace llvm::AMDGPU::MTBUFFormat;
7496 if (
Format != DFMT_UNDEF) {
7502 if (
Format != NFMT_UNDEF) {
7507 Error(Loc,
"unsupported format");
7511ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7514 using namespace llvm::AMDGPU::MTBUFFormat;
7518 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7523 SMLoc Loc = getLoc();
7524 if (!parseId(Str,
"expected a format string") ||
7525 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7527 if (Dfmt == DFMT_UNDEF)
7528 return Error(Loc,
"duplicate numeric format");
7529 if (Nfmt == NFMT_UNDEF)
7530 return Error(Loc,
"duplicate data format");
7533 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7534 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7538 if (Ufmt == UFMT_UNDEF)
7539 return Error(FormatLoc,
"unsupported format");
7548ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7551 using namespace llvm::AMDGPU::MTBUFFormat;
7554 if (Id == UFMT_UNDEF)
7558 return Error(Loc,
"unified format is not supported on this GPU");
7564ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7565 using namespace llvm::AMDGPU::MTBUFFormat;
7566 SMLoc Loc = getLoc();
7571 return Error(Loc,
"out of range format");
7576ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7577 using namespace llvm::AMDGPU::MTBUFFormat;
7583 StringRef FormatStr;
7584 SMLoc Loc = getLoc();
7585 if (!parseId(FormatStr,
"expected a format string"))
7588 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7590 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7600 return parseNumericFormat(
Format);
7603ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7604 using namespace llvm::AMDGPU::MTBUFFormat;
7608 SMLoc Loc = getLoc();
7618 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7630 Res = parseRegOrImm(Operands);
7637 Res = parseSymbolicOrNumericFormat(
Format);
7642 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7643 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7650 return Error(getLoc(),
"duplicate format");
7654ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7656 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7658 Res = parseIntWithPrefix(
"inst_offset", Operands,
7659 AMDGPUOperand::ImmTyInstOffset);
7664ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7666 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7668 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7672ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7674 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7677 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7686void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7687 OptionalImmIndexMap OptionalIdx;
7689 unsigned OperandIdx[4];
7690 unsigned EnMask = 0;
7693 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7694 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7699 OperandIdx[SrcIdx] = Inst.
size();
7700 Op.addRegOperands(Inst, 1);
7707 OperandIdx[SrcIdx] = Inst.
size();
7713 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7714 Op.addImmOperands(Inst, 1);
7718 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7722 OptionalIdx[
Op.getImmTy()] = i;
7728 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7735 for (
auto i = 0; i < SrcIdx; ++i) {
7737 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7762 IntVal =
encode(ISA, IntVal, CntVal);
7763 if (CntVal !=
decode(ISA, IntVal)) {
7765 IntVal =
encode(ISA, IntVal, -1);
7773bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7775 SMLoc CntLoc = getLoc();
7776 StringRef CntName = getTokenStr();
7783 SMLoc ValLoc = getLoc();
7792 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7794 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7796 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7799 Error(CntLoc,
"invalid counter name " + CntName);
7804 Error(ValLoc,
"too large value for " + CntName);
7813 Error(getLoc(),
"expected a counter name");
7821ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7828 if (!parseCnt(Waitcnt))
7836 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7840bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7841 SMLoc FieldLoc = getLoc();
7842 StringRef FieldName = getTokenStr();
7847 SMLoc ValueLoc = getLoc();
7854 if (FieldName ==
"instid0") {
7856 }
else if (FieldName ==
"instskip") {
7858 }
else if (FieldName ==
"instid1") {
7861 Error(FieldLoc,
"invalid field name " + FieldName);
7880 .Case(
"VALU_DEP_1", 1)
7881 .Case(
"VALU_DEP_2", 2)
7882 .Case(
"VALU_DEP_3", 3)
7883 .Case(
"VALU_DEP_4", 4)
7884 .Case(
"TRANS32_DEP_1", 5)
7885 .Case(
"TRANS32_DEP_2", 6)
7886 .Case(
"TRANS32_DEP_3", 7)
7887 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7888 .Case(
"SALU_CYCLE_1", 9)
7889 .Case(
"SALU_CYCLE_2", 10)
7890 .Case(
"SALU_CYCLE_3", 11)
7898 Delay |=
Value << Shift;
7902ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7908 if (!parseDelay(Delay))
7916 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7921AMDGPUOperand::isSWaitCnt()
const {
7925bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7931void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7932 StringRef DepCtrName) {
7935 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7938 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7941 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7944 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7951bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7953 using namespace llvm::AMDGPU::DepCtr;
7955 SMLoc DepCtrLoc = getLoc();
7956 StringRef DepCtrName = getTokenStr();
7966 unsigned PrevOprMask = UsedOprMask;
7967 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7970 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7979 Error(getLoc(),
"expected a counter name");
7984 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7985 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7989ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
7990 using namespace llvm::AMDGPU::DepCtr;
7993 SMLoc Loc = getLoc();
7996 unsigned UsedOprMask = 0;
7998 if (!parseDepCtr(DepCtr, UsedOprMask))
8006 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8010bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8016ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8018 OperandInfoTy &Width) {
8019 using namespace llvm::AMDGPU::Hwreg;
8025 HwReg.Loc = getLoc();
8028 HwReg.IsSymbolic =
true;
8030 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8038 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8048 Width.Loc = getLoc();
8056ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8057 using namespace llvm::AMDGPU::Hwreg;
8060 SMLoc Loc = getLoc();
8062 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8064 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8065 HwregOffset::Default);
8066 struct : StructuredOpField {
8067 using StructuredOpField::StructuredOpField;
8068 bool validate(AMDGPUAsmParser &Parser)
const override {
8070 return Error(Parser,
"only values from 1 to 32 are legal");
8073 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8074 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8077 Res = parseHwregFunc(HwReg,
Offset, Width);
8080 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8082 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8086 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8093 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8095 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8099bool AMDGPUOperand::isHwreg()
const {
8100 return isImmTy(ImmTyHwreg);
8108AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8110 OperandInfoTy &Stream) {
8111 using namespace llvm::AMDGPU::SendMsg;
8116 Msg.IsSymbolic =
true;
8118 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8123 Op.IsDefined =
true;
8126 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8129 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8134 Stream.IsDefined =
true;
8135 Stream.Loc = getLoc();
8145AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8146 const OperandInfoTy &
Op,
8147 const OperandInfoTy &Stream) {
8148 using namespace llvm::AMDGPU::SendMsg;
8153 bool Strict = Msg.IsSymbolic;
8157 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8162 Error(Msg.Loc,
"invalid message id");
8168 Error(
Op.Loc,
"message does not support operations");
8170 Error(Msg.Loc,
"missing message operation");
8176 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8178 Error(
Op.Loc,
"invalid operation id");
8183 Error(Stream.Loc,
"message operation does not support streams");
8187 Error(Stream.Loc,
"invalid message stream id");
8193ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8194 using namespace llvm::AMDGPU::SendMsg;
8197 SMLoc Loc = getLoc();
8201 OperandInfoTy
Op(OP_NONE_);
8202 OperandInfoTy Stream(STREAM_ID_NONE_);
8203 if (parseSendMsgBody(Msg,
Op, Stream) &&
8204 validateSendMsg(Msg,
Op, Stream)) {
8209 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8211 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8216 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8220bool AMDGPUOperand::isSendMsg()
const {
8221 return isImmTy(ImmTySendMsg);
8228ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8235 int Slot = StringSwitch<int>(Str)
8242 return Error(S,
"invalid interpolation slot");
8244 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8245 AMDGPUOperand::ImmTyInterpSlot));
8249ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8256 if (!Str.starts_with(
"attr"))
8257 return Error(S,
"invalid interpolation attribute");
8259 StringRef Chan = Str.take_back(2);
8260 int AttrChan = StringSwitch<int>(Chan)
8267 return Error(S,
"invalid or missing interpolation attribute channel");
8269 Str = Str.drop_back(2).drop_front(4);
8272 if (Str.getAsInteger(10, Attr))
8273 return Error(S,
"invalid or missing interpolation attribute number");
8276 return Error(S,
"out of bounds interpolation attribute number");
8280 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8281 AMDGPUOperand::ImmTyInterpAttr));
8282 Operands.
push_back(AMDGPUOperand::CreateImm(
8283 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8291ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8292 using namespace llvm::AMDGPU::Exp;
8302 return Error(S, (Id == ET_INVALID)
8303 ?
"invalid exp target"
8304 :
"exp target is not supported on this GPU");
8306 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8307 AMDGPUOperand::ImmTyExpTgt));
8316AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8321AMDGPUAsmParser::isId(
const StringRef Id)
const {
8327 return getTokenKind() ==
Kind;
8330StringRef AMDGPUAsmParser::getId()
const {
8335AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8344AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8346 StringRef Tok = getTokenStr();
8357 if (isId(Id) && peekToken().is(Kind)) {
8367 if (isToken(Kind)) {
8376 const StringRef ErrMsg) {
8377 if (!trySkipToken(Kind)) {
8378 Error(getLoc(), ErrMsg);
8385AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8389 if (Parser.parseExpression(Expr))
8392 if (Expr->evaluateAsAbsolute(
Imm))
8395 if (Expected.empty()) {
8396 Error(S,
"expected absolute expression");
8398 Error(S, Twine(
"expected ", Expected) +
8399 Twine(
" or an absolute expression"));
8409 if (Parser.parseExpression(Expr))
8413 if (Expr->evaluateAsAbsolute(IntVal)) {
8414 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8416 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8422AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8424 Val =
getToken().getStringContents();
8428 Error(getLoc(), ErrMsg);
8433AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8435 Val = getTokenStr();
8439 if (!ErrMsg.
empty())
8440 Error(getLoc(), ErrMsg);
8445AMDGPUAsmParser::getToken()
const {
8446 return Parser.getTok();
8449AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8452 : getLexer().peekTok(ShouldSkipSpace);
8457 auto TokCount = getLexer().peekTokens(Tokens);
8459 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8464AMDGPUAsmParser::getTokenKind()
const {
8465 return getLexer().getKind();
8469AMDGPUAsmParser::getLoc()
const {
8474AMDGPUAsmParser::getTokenStr()
const {
8479AMDGPUAsmParser::lex() {
8483SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8484 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8488SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8492SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8493 int MCOpIdx)
const {
8494 for (
const auto &
Op : Operands) {
8495 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8496 if (TargetOp.getMCOpIdx() == MCOpIdx)
8497 return TargetOp.getStartLoc();
8503AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8505 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8506 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8508 return Op.getStartLoc();
8510 return getInstLoc(Operands);
8514AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8516 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8517 return getOperandLoc(
Test, Operands);
8531 StringRef
Id = getTokenStr();
8532 SMLoc IdLoc = getLoc();
8538 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8539 if (
I == Fields.
end())
8540 return Error(IdLoc,
"unknown field");
8541 if ((*I)->IsDefined)
8542 return Error(IdLoc,
"duplicate field");
8545 (*I)->Loc = getLoc();
8548 (*I)->IsDefined =
true;
8555bool AMDGPUAsmParser::validateStructuredOpFields(
8557 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8558 return F->validate(*
this);
8569 const unsigned OrMask,
8570 const unsigned XorMask) {
8579bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8580 const unsigned MaxVal,
8581 const Twine &ErrMsg, SMLoc &Loc) {
8598AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8599 const unsigned MinVal,
8600 const unsigned MaxVal,
8601 const StringRef ErrMsg) {
8603 for (
unsigned i = 0; i < OpNum; ++i) {
8604 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8612AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8613 using namespace llvm::AMDGPU::Swizzle;
8616 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8617 "expected a 2-bit lane id")) {
8628AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8629 using namespace llvm::AMDGPU::Swizzle;
8635 if (!parseSwizzleOperand(GroupSize,
8637 "group size must be in the interval [2,32]",
8642 Error(Loc,
"group size must be a power of two");
8645 if (parseSwizzleOperand(LaneIdx,
8647 "lane id must be in the interval [0,group size - 1]",
8656AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8657 using namespace llvm::AMDGPU::Swizzle;
8662 if (!parseSwizzleOperand(GroupSize,
8664 "group size must be in the interval [2,32]",
8669 Error(Loc,
"group size must be a power of two");
8678AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8679 using namespace llvm::AMDGPU::Swizzle;
8684 if (!parseSwizzleOperand(GroupSize,
8686 "group size must be in the interval [1,16]",
8691 Error(Loc,
"group size must be a power of two");
8700AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8701 using namespace llvm::AMDGPU::Swizzle;
8708 SMLoc StrLoc = getLoc();
8709 if (!parseString(Ctl)) {
8712 if (Ctl.
size() != BITMASK_WIDTH) {
8713 Error(StrLoc,
"expected a 5-character mask");
8717 unsigned AndMask = 0;
8718 unsigned OrMask = 0;
8719 unsigned XorMask = 0;
8721 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8725 Error(StrLoc,
"invalid mask");
8746bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8747 using namespace llvm::AMDGPU::Swizzle;
8750 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8756 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8757 "FFT swizzle must be in the interval [0," +
8758 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8766bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8767 using namespace llvm::AMDGPU::Swizzle;
8770 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8777 if (!parseSwizzleOperand(
Direction, 0, 1,
8778 "direction must be 0 (left) or 1 (right)", Loc))
8782 if (!parseSwizzleOperand(
8783 RotateSize, 0, ROTATE_MAX_SIZE,
8784 "number of threads to rotate must be in the interval [0," +
8785 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8790 (RotateSize << ROTATE_SIZE_SHIFT);
8795AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8797 SMLoc OffsetLoc = getLoc();
8803 Error(OffsetLoc,
"expected a 16-bit offset");
8810AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8811 using namespace llvm::AMDGPU::Swizzle;
8815 SMLoc ModeLoc = getLoc();
8818 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8819 Ok = parseSwizzleQuadPerm(
Imm);
8820 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8821 Ok = parseSwizzleBitmaskPerm(
Imm);
8822 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8823 Ok = parseSwizzleBroadcast(
Imm);
8824 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8825 Ok = parseSwizzleSwap(
Imm);
8826 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8827 Ok = parseSwizzleReverse(
Imm);
8828 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8829 Ok = parseSwizzleFFT(
Imm);
8830 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8831 Ok = parseSwizzleRotate(
Imm);
8833 Error(ModeLoc,
"expected a swizzle mode");
8836 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8842ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8846 if (trySkipId(
"offset")) {
8850 if (trySkipId(
"swizzle")) {
8851 Ok = parseSwizzleMacro(
Imm);
8853 Ok = parseSwizzleOffset(
Imm);
8857 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8865AMDGPUOperand::isSwizzle()
const {
8866 return isImmTy(ImmTySwizzle);
8873int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8875 using namespace llvm::AMDGPU::VGPRIndexMode;
8887 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8888 if (trySkipId(IdSymbolic[ModeId])) {
8896 "expected a VGPR index mode or a closing parenthesis" :
8897 "expected a VGPR index mode");
8902 Error(S,
"duplicate VGPR index mode");
8910 "expected a comma or a closing parenthesis"))
8917ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8919 using namespace llvm::AMDGPU::VGPRIndexMode;
8925 Imm = parseGPRIdxMacro();
8929 if (getParser().parseAbsoluteExpression(
Imm))
8932 return Error(S,
"invalid immediate: only 4-bit values are legal");
8936 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8940bool AMDGPUOperand::isGPRIdxMode()
const {
8941 return isImmTy(ImmTyGprIdxMode);
8948ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
8953 if (isRegister() || isModifier())
8959 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
8960 assert(Opr.isImm() || Opr.isExpr());
8961 SMLoc Loc = Opr.getStartLoc();
8965 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8966 Error(Loc,
"expected an absolute expression or a label");
8967 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8968 Error(Loc,
"expected a 16-bit signed jump offset");
8978ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
8979 return parseReg(Operands);
8986void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
8989 OptionalImmIndexMap OptionalIdx;
8990 unsigned FirstOperandIdx = 1;
8991 bool IsAtomicReturn =
false;
8998 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
8999 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9003 Op.addRegOperands(Inst, 1);
9007 if (IsAtomicReturn && i == FirstOperandIdx)
9008 Op.addRegOperands(Inst, 1);
9013 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9014 Op.addImmOperands(Inst, 1);
9026 OptionalIdx[
Op.getImmTy()] = i;
9040bool AMDGPUOperand::isSMRDOffset8()
const {
9044bool AMDGPUOperand::isSMEMOffset()
const {
9046 return isImmLiteral();
9049bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9084bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9085 if (BoundCtrl == 0 || BoundCtrl == 1) {
9093void AMDGPUAsmParser::onBeginOfFile() {
9094 if (!getParser().getStreamer().getTargetStreamer() ||
9098 if (!getTargetStreamer().getTargetID())
9099 getTargetStreamer().initializeTargetID(getSTI(),
9100 getSTI().getFeatureString());
9103 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9111bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9115 StringRef TokenId = getTokenStr();
9116 AGVK VK = StringSwitch<AGVK>(TokenId)
9117 .Case(
"max", AGVK::AGVK_Max)
9118 .Case(
"or", AGVK::AGVK_Or)
9119 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9120 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9121 .Case(
"alignto", AGVK::AGVK_AlignTo)
9122 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9123 .Default(AGVK::AGVK_None);
9127 uint64_t CommaCount = 0;
9132 if (Exprs.
empty()) {
9134 "empty " + Twine(TokenId) +
" expression");
9137 if (CommaCount + 1 != Exprs.
size()) {
9139 "mismatch of commas in " + Twine(TokenId) +
" expression");
9146 if (getParser().parseExpression(Expr, EndLoc))
9150 if (LastTokenWasComma)
9154 "unexpected token in " + Twine(TokenId) +
" expression");
9160 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9163ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9164 StringRef
Name = getTokenStr();
9165 if (Name ==
"mul") {
9166 return parseIntWithPrefix(
"mul", Operands,
9170 if (Name ==
"div") {
9171 return parseIntWithPrefix(
"div", Operands,
9182 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9187 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9188 AMDGPU::OpName::src2};
9196 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9201 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9203 if (
DstOp.isReg() &&
9204 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9208 if ((OpSel & (1 << SrcNum)) != 0)
9214void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9216 cvtVOP3P(Inst, Operands);
9220void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9221 OptionalImmIndexMap &OptionalIdx) {
9222 cvtVOP3P(Inst, Operands, OptionalIdx);
9231 &&
Desc.NumOperands > (OpNum + 1)
9233 &&
Desc.operands()[OpNum + 1].RegClass != -1
9235 &&
Desc.getOperandConstraint(OpNum + 1,
9239void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9241 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9242 AMDGPU::OpName::src2};
9243 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9244 AMDGPU::OpName::src1_modifiers,
9245 AMDGPU::OpName::src2_modifiers};
9246 for (
int J = 0; J < 3; ++J) {
9247 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9253 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9256 if ((OpSel & (1 << J)) != 0)
9259 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9266void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9268 OptionalImmIndexMap OptionalIdx;
9273 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9274 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9277 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9278 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9280 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9281 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9282 Op.isInterpAttrChan()) {
9284 }
else if (
Op.isImmModifier()) {
9285 OptionalIdx[
Op.getImmTy()] =
I;
9293 AMDGPUOperand::ImmTyHigh);
9297 AMDGPUOperand::ImmTyClamp);
9301 AMDGPUOperand::ImmTyOModSI);
9306 AMDGPUOperand::ImmTyOpSel);
9307 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9310 cvtOpSelHelper(Inst, OpSel);
9314void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9316 OptionalImmIndexMap OptionalIdx;
9321 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9322 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9325 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9326 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9328 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9329 }
else if (
Op.isImmModifier()) {
9330 OptionalIdx[
Op.getImmTy()] =
I;
9338 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9348 cvtOpSelHelper(Inst, OpSel);
9351void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9353 OptionalImmIndexMap OptionalIdx;
9356 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9360 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9361 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9363 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9364 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9369 if (NumOperands == CbszOpIdx) {
9374 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9375 }
else if (
Op.isImmModifier()) {
9376 OptionalIdx[
Op.getImmTy()] =
I;
9378 Op.addRegOrImmOperands(Inst, 1);
9383 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9384 if (CbszIdx != OptionalIdx.end()) {
9385 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9389 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9390 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9391 if (BlgpIdx != OptionalIdx.end()) {
9392 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9403 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9404 if (OpselIdx != OptionalIdx.end()) {
9405 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9409 unsigned OpSelHi = 0;
9410 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9411 if (OpselHiIdx != OptionalIdx.end()) {
9412 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9415 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9416 AMDGPU::OpName::src1_modifiers};
9418 for (
unsigned J = 0; J < 2; ++J) {
9419 unsigned ModVal = 0;
9420 if (OpSel & (1 << J))
9422 if (OpSelHi & (1 << J))
9425 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9430void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9431 OptionalImmIndexMap &OptionalIdx) {
9436 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9437 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9440 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9441 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9443 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9444 }
else if (
Op.isImmModifier()) {
9445 OptionalIdx[
Op.getImmTy()] =
I;
9447 Op.addRegOrImmOperands(Inst, 1);
9453 AMDGPUOperand::ImmTyScaleSel);
9457 AMDGPUOperand::ImmTyClamp);
9463 AMDGPUOperand::ImmTyByteSel);
9468 AMDGPUOperand::ImmTyOModSI);
9475 auto *it = Inst.
begin();
9476 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9484void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9485 OptionalImmIndexMap OptionalIdx;
9486 cvtVOP3(Inst, Operands, OptionalIdx);
9489void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9490 OptionalImmIndexMap &OptIdx) {
9496 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9497 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9498 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9499 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9500 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9501 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9509 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9510 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9511 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9512 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9513 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9514 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9515 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9516 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9517 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9518 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9519 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9520 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9521 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9522 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9523 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9524 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9525 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9526 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9527 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9528 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9529 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9530 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9531 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9532 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9533 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9534 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9538 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9539 if (BitOp3Idx != -1) {
9546 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9547 if (OpSelIdx != -1) {
9551 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9552 if (OpSelHiIdx != -1) {
9559 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9560 if (MatrixAFMTIdx != -1) {
9562 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9566 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9567 if (MatrixBFMTIdx != -1) {
9569 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9572 int MatrixAScaleIdx =
9573 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9574 if (MatrixAScaleIdx != -1) {
9576 AMDGPUOperand::ImmTyMatrixAScale, 0);
9579 int MatrixBScaleIdx =
9580 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9581 if (MatrixBScaleIdx != -1) {
9583 AMDGPUOperand::ImmTyMatrixBScale, 0);
9586 int MatrixAScaleFmtIdx =
9587 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9588 if (MatrixAScaleFmtIdx != -1) {
9590 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9593 int MatrixBScaleFmtIdx =
9594 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9595 if (MatrixBScaleFmtIdx != -1) {
9597 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9602 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9606 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9608 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9612 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9616 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9617 AMDGPU::OpName::src2};
9618 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9619 AMDGPU::OpName::src1_modifiers,
9620 AMDGPU::OpName::src2_modifiers};
9623 unsigned OpSelHi = 0;
9630 if (OpSelHiIdx != -1)
9639 for (
int J = 0; J < 3; ++J) {
9640 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9644 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9649 uint32_t ModVal = 0;
9652 if (SrcOp.
isReg() && getMRI()
9659 if ((OpSel & (1 << J)) != 0)
9663 if ((OpSelHi & (1 << J)) != 0)
9666 if ((NegLo & (1 << J)) != 0)
9669 if ((NegHi & (1 << J)) != 0)
9676void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9677 OptionalImmIndexMap OptIdx;
9678 cvtVOP3(Inst, Operands, OptIdx);
9679 cvtVOP3P(Inst, Operands, OptIdx);
9683 unsigned i,
unsigned Opc,
9685 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9686 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9688 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9691void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9694 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9697 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9698 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9700 OptionalImmIndexMap OptIdx;
9701 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9702 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9703 OptIdx[
Op.getImmTy()] = i;
9708 AMDGPUOperand::ImmTyIndexKey8bit);
9712 AMDGPUOperand::ImmTyIndexKey16bit);
9716 AMDGPUOperand::ImmTyIndexKey32bit);
9721 cvtVOP3P(Inst, Operands, OptIdx);
9728ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9736 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9737 SMLoc OpYLoc = getLoc();
9740 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9743 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9749void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9752 auto addOp = [&](uint16_t ParsedOprIdx) {
9753 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9755 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9759 Op.addRegOperands(Inst, 1);
9763 Op.addImmOperands(Inst, 1);
9775 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9779 const auto &CInfo = InstInfo[CompIdx];
9780 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9781 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9782 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9783 if (CInfo.hasSrc2Acc())
9784 addOp(CInfo.getIndexOfDstInParsedOperands());
9788 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9789 if (BitOp3Idx != -1) {
9790 OptionalImmIndexMap OptIdx;
9791 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9793 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9803bool AMDGPUOperand::isDPP8()
const {
9804 return isImmTy(ImmTyDPP8);
9807bool AMDGPUOperand::isDPPCtrl()
const {
9808 using namespace AMDGPU::DPP;
9810 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9813 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9814 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9815 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9816 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9817 (
Imm == DppCtrl::WAVE_SHL1) ||
9818 (
Imm == DppCtrl::WAVE_ROL1) ||
9819 (
Imm == DppCtrl::WAVE_SHR1) ||
9820 (
Imm == DppCtrl::WAVE_ROR1) ||
9821 (
Imm == DppCtrl::ROW_MIRROR) ||
9822 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9823 (
Imm == DppCtrl::BCAST15) ||
9824 (
Imm == DppCtrl::BCAST31) ||
9825 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9826 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9835bool AMDGPUOperand::isBLGP()
const {
9839bool AMDGPUOperand::isS16Imm()
const {
9843bool AMDGPUOperand::isU16Imm()
const {
9851bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9856 SMLoc Loc =
getToken().getEndLoc();
9857 Token = std::string(getTokenStr());
9859 if (getLoc() != Loc)
9864 if (!parseId(Suffix))
9868 StringRef DimId = Token;
9879ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9889 SMLoc Loc = getLoc();
9890 if (!parseDimId(Encoding))
9891 return Error(Loc,
"invalid dim value");
9893 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9894 AMDGPUOperand::ImmTyDim));
9902ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
9912 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9915 for (
size_t i = 0; i < 8; ++i) {
9919 SMLoc Loc = getLoc();
9920 if (getParser().parseAbsoluteExpression(Sels[i]))
9922 if (0 > Sels[i] || 7 < Sels[i])
9923 return Error(Loc,
"expected a 3-bit value");
9930 for (
size_t i = 0; i < 8; ++i)
9931 DPP8 |= (Sels[i] << (i * 3));
9933 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9938AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
9940 if (Ctrl ==
"row_newbcast")
9943 if (Ctrl ==
"row_share" ||
9944 Ctrl ==
"row_xmask")
9947 if (Ctrl ==
"wave_shl" ||
9948 Ctrl ==
"wave_shr" ||
9949 Ctrl ==
"wave_rol" ||
9950 Ctrl ==
"wave_ror" ||
9951 Ctrl ==
"row_bcast")
9954 return Ctrl ==
"row_mirror" ||
9955 Ctrl ==
"row_half_mirror" ||
9956 Ctrl ==
"quad_perm" ||
9957 Ctrl ==
"row_shl" ||
9958 Ctrl ==
"row_shr" ||
9963AMDGPUAsmParser::parseDPPCtrlPerm() {
9966 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9970 for (
int i = 0; i < 4; ++i) {
9975 SMLoc Loc = getLoc();
9976 if (getParser().parseAbsoluteExpression(Temp))
9978 if (Temp < 0 || Temp > 3) {
9979 Error(Loc,
"expected a 2-bit value");
9983 Val += (Temp << i * 2);
9993AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
9994 using namespace AMDGPU::DPP;
9999 SMLoc Loc = getLoc();
10001 if (getParser().parseAbsoluteExpression(Val))
10004 struct DppCtrlCheck {
10010 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10011 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10012 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10013 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10014 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10015 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10016 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10017 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10018 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10019 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10020 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10024 if (
Check.Ctrl == -1) {
10025 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10033 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10040ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10041 using namespace AMDGPU::DPP;
10044 !isSupportedDPPCtrl(getTokenStr(), Operands))
10047 SMLoc S = getLoc();
10053 if (Ctrl ==
"row_mirror") {
10054 Val = DppCtrl::ROW_MIRROR;
10055 }
else if (Ctrl ==
"row_half_mirror") {
10056 Val = DppCtrl::ROW_HALF_MIRROR;
10059 if (Ctrl ==
"quad_perm") {
10060 Val = parseDPPCtrlPerm();
10062 Val = parseDPPCtrlSel(Ctrl);
10071 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10075void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10077 OptionalImmIndexMap OptionalIdx;
10084 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10086 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10087 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10091 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10092 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10096 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10097 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10098 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10099 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10100 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10102 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10106 if (OldIdx == NumOperands) {
10108 constexpr int DST_IDX = 0;
10110 }
else if (Src2ModIdx == NumOperands) {
10120 if (IsVOP3CvtSrDpp) {
10129 if (TiedTo != -1) {
10134 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10136 if (IsDPP8 &&
Op.isDppFI()) {
10139 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10140 }
else if (
Op.isReg()) {
10141 Op.addRegOperands(Inst, 1);
10142 }
else if (
Op.isImm() &&
10144 Op.addImmOperands(Inst, 1);
10145 }
else if (
Op.isImm()) {
10146 OptionalIdx[
Op.getImmTy()] =
I;
10154 AMDGPUOperand::ImmTyClamp);
10160 AMDGPUOperand::ImmTyByteSel);
10167 cvtVOP3P(Inst, Operands, OptionalIdx);
10169 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10176 using namespace llvm::AMDGPU::DPP;
10186 AMDGPUOperand::ImmTyDppFI);
10190void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10191 OptionalImmIndexMap OptionalIdx;
10195 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10196 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10200 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10203 if (TiedTo != -1) {
10208 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10210 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10218 Op.addImmOperands(Inst, 1);
10220 Op.addRegWithFPInputModsOperands(Inst, 2);
10221 }
else if (
Op.isDppFI()) {
10223 }
else if (
Op.isReg()) {
10224 Op.addRegOperands(Inst, 1);
10230 Op.addRegWithFPInputModsOperands(Inst, 2);
10231 }
else if (
Op.isReg()) {
10232 Op.addRegOperands(Inst, 1);
10233 }
else if (
Op.isDPPCtrl()) {
10234 Op.addImmOperands(Inst, 1);
10235 }
else if (
Op.isImm()) {
10237 OptionalIdx[
Op.getImmTy()] =
I;
10245 using namespace llvm::AMDGPU::DPP;
10253 AMDGPUOperand::ImmTyDppFI);
10262ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10264 AMDGPUOperand::ImmTy
Type) {
10265 return parseStringOrIntWithPrefix(
10267 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10271ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10272 return parseStringOrIntWithPrefix(
10273 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10274 AMDGPUOperand::ImmTySDWADstUnused);
10277void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10281void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10285void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10289void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10293void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10297void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10298 uint64_t BasicInstType,
10301 using namespace llvm::AMDGPU::SDWA;
10303 OptionalImmIndexMap OptionalIdx;
10304 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10305 bool SkippedVcc =
false;
10309 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10310 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10313 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10314 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10315 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10316 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10334 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10335 }
else if (
Op.isImm()) {
10337 OptionalIdx[
Op.getImmTy()] =
I;
10341 SkippedVcc =
false;
10345 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10346 Opc != AMDGPU::V_NOP_sdwa_vi) {
10348 switch (BasicInstType) {
10352 AMDGPUOperand::ImmTyClamp, 0);
10356 AMDGPUOperand::ImmTyOModSI, 0);
10360 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10364 AMDGPUOperand::ImmTySDWADstUnused,
10365 DstUnused::UNUSED_PRESERVE);
10367 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10372 AMDGPUOperand::ImmTyClamp, 0);
10377 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10378 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10379 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10380 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10386 AMDGPUOperand::ImmTyClamp, 0);
10387 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10388 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10392 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10398 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10399 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10400 auto *it = Inst.
begin();
10402 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10414#define GET_MATCHER_IMPLEMENTATION
10415#define GET_MNEMONIC_SPELL_CHECKER
10416#define GET_MNEMONIC_CHECKER
10417#include "AMDGPUGenAsmMatcher.inc"
10423 return parseTokenOp(
"addr64",
Operands);
10425 return parseTokenOp(
"done",
Operands);
10427 return parseTokenOp(
"idxen",
Operands);
10429 return parseTokenOp(
"lds",
Operands);
10431 return parseTokenOp(
"offen",
Operands);
10433 return parseTokenOp(
"off",
Operands);
10434 case MCK_row_95_en:
10435 return parseTokenOp(
"row_en",
Operands);
10437 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10439 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10441 return tryCustomParseOperand(
Operands, MCK);
10446unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10452 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10455 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10457 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10459 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10461 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10463 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10465 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10473 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10475 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10476 case MCK_SOPPBrTarget:
10477 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10478 case MCK_VReg32OrOff:
10479 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10480 case MCK_InterpSlot:
10481 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10482 case MCK_InterpAttr:
10483 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10484 case MCK_InterpAttrChan:
10485 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10487 case MCK_SReg_64_XEXEC:
10497 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10499 return Match_InvalidOperand;
10507ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10508 SMLoc S = getLoc();
10517 return Error(S,
"expected a 16-bit value");
10520 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10524bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10530bool 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 unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
MachineInstr unsigned OpIdx
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
unsigned unsigned DefaultVal
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * 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)
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 isInlineValue(unsigned Reg)
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)
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.
@ 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