56enum RegisterKind { IS_UNKNOWN,
IS_VGPR, IS_SGPR,
IS_AGPR, IS_TTMP, IS_SPECIAL };
70 SMLoc StartLoc, EndLoc;
71 const AMDGPUAsmParser *AsmParser;
74 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
75 : Kind(Kind_), AsmParser(AsmParser_) {}
77 using Ptr = std::unique_ptr<AMDGPUOperand>;
85 bool hasFPModifiers()
const {
return Abs || Neg; }
86 bool hasIntModifiers()
const {
return Sext; }
87 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
89 int64_t getFPModifiersOperand()
const {
96 int64_t getIntModifiersOperand()
const {
102 int64_t getModifiersOperand()
const {
103 assert(!(hasFPModifiers() && hasIntModifiers())
104 &&
"fp and int modifiers should not be used simultaneously");
105 if (hasFPModifiers())
106 return getFPModifiersOperand();
107 if (hasIntModifiers())
108 return getIntModifiersOperand();
112 friend raw_ostream &
operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
182 ImmTyMatrixAScaleFmt,
183 ImmTyMatrixBScaleFmt,
216 mutable int MCOpIdx = -1;
219 bool isToken()
const override {
return Kind == Token; }
221 bool isSymbolRefExpr()
const {
225 bool isImm()
const override {
226 return Kind == Immediate;
229 bool isInlinableImm(MVT type)
const;
230 bool isLiteralImm(MVT type)
const;
232 bool isRegKind()
const {
233 return Kind == Register;
236 bool isReg()
const override {
237 return isRegKind() && !hasModifiers();
240 bool isRegOrInline(
unsigned RCID, MVT type)
const {
241 return isRegClass(RCID) || isInlinableImm(type);
245 return isRegOrInline(RCID, type) || isLiteralImm(type);
248 bool isRegOrImmWithInt16InputMods()
const {
252 template <
bool IsFake16>
bool isRegOrImmWithIntT16InputMods()
const {
254 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
257 bool isRegOrImmWithInt32InputMods()
const {
261 bool isRegOrInlineImmWithInt16InputMods()
const {
262 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
265 template <
bool IsFake16>
bool isRegOrInlineImmWithIntT16InputMods()
const {
266 return isRegOrInline(
267 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
270 bool isRegOrInlineImmWithInt32InputMods()
const {
271 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
274 bool isRegOrImmWithInt64InputMods()
const {
278 bool isRegOrImmWithFP16InputMods()
const {
282 template <
bool IsFake16>
bool isRegOrImmWithFPT16InputMods()
const {
284 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
287 bool isRegOrImmWithFP32InputMods()
const {
291 bool isRegOrImmWithFP64InputMods()
const {
295 template <
bool IsFake16>
bool isRegOrInlineImmWithFP16InputMods()
const {
296 return isRegOrInline(
297 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
300 bool isRegOrInlineImmWithFP32InputMods()
const {
301 return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
304 bool isRegOrInlineImmWithFP64InputMods()
const {
305 return isRegOrInline(AMDGPU::VS_64RegClassID, MVT::f64);
308 bool isVRegWithInputMods(
unsigned RCID)
const {
return isRegClass(RCID); }
310 bool isVRegWithFP32InputMods()
const {
311 return isVRegWithInputMods(AMDGPU::VGPR_32RegClassID);
314 bool isVRegWithFP64InputMods()
const {
315 return isVRegWithInputMods(AMDGPU::VReg_64RegClassID);
318 bool isPackedFP16InputMods()
const {
322 bool isPackedVGPRFP32InputMods()
const {
326 bool isVReg()
const {
327 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
328 isRegClass(AMDGPU::VReg_64RegClassID) ||
329 isRegClass(AMDGPU::VReg_96RegClassID) ||
330 isRegClass(AMDGPU::VReg_128RegClassID) ||
331 isRegClass(AMDGPU::VReg_160RegClassID) ||
332 isRegClass(AMDGPU::VReg_192RegClassID) ||
333 isRegClass(AMDGPU::VReg_256RegClassID) ||
334 isRegClass(AMDGPU::VReg_512RegClassID) ||
335 isRegClass(AMDGPU::VReg_1024RegClassID);
338 bool isVReg32()
const {
339 return isRegClass(AMDGPU::VGPR_32RegClassID);
342 bool isVReg32OrOff()
const {
343 return isOff() || isVReg32();
347 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
350 bool isVRegWithInputMods()
const;
351 template <
bool IsFake16>
bool isT16_Lo128VRegWithInputMods()
const;
352 template <
bool IsFake16>
bool isT16VRegWithInputMods()
const;
354 bool isSDWAOperand(MVT type)
const;
355 bool isSDWAFP16Operand()
const;
356 bool isSDWAFP32Operand()
const;
357 bool isSDWAInt16Operand()
const;
358 bool isSDWAInt32Operand()
const;
360 bool isImmTy(ImmTy ImmT)
const {
361 return isImm() &&
Imm.Type == ImmT;
364 template <ImmTy Ty>
bool isImmTy()
const {
return isImmTy(Ty); }
366 bool isImmLiteral()
const {
return isImmTy(ImmTyNone); }
368 bool isImmModifier()
const {
369 return isImm() &&
Imm.Type != ImmTyNone;
372 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
373 bool isDim()
const {
return isImmTy(ImmTyDim); }
374 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
375 bool isOff()
const {
return isImmTy(ImmTyOff); }
376 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
377 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
378 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
379 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
380 bool isSMEMOffsetMod()
const {
return isImmTy(ImmTySMEMOffsetMod); }
381 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
382 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
383 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
384 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
385 bool isIndexKey8bit()
const {
return isImmTy(ImmTyIndexKey8bit); }
386 bool isIndexKey16bit()
const {
return isImmTy(ImmTyIndexKey16bit); }
387 bool isIndexKey32bit()
const {
return isImmTy(ImmTyIndexKey32bit); }
388 bool isMatrixAFMT()
const {
return isImmTy(ImmTyMatrixAFMT); }
389 bool isMatrixBFMT()
const {
return isImmTy(ImmTyMatrixBFMT); }
390 bool isMatrixAScale()
const {
return isImmTy(ImmTyMatrixAScale); }
391 bool isMatrixBScale()
const {
return isImmTy(ImmTyMatrixBScale); }
392 bool isMatrixAScaleFmt()
const {
return isImmTy(ImmTyMatrixAScaleFmt); }
393 bool isMatrixBScaleFmt()
const {
return isImmTy(ImmTyMatrixBScaleFmt); }
394 bool isMatrixAReuse()
const {
return isImmTy(ImmTyMatrixAReuse); }
395 bool isMatrixBReuse()
const {
return isImmTy(ImmTyMatrixBReuse); }
396 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
397 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) &&
isUInt<7>(
getImm()); }
398 bool isDppFI()
const {
return isImmTy(ImmTyDppFI); }
399 bool isSDWADstSel()
const {
return isImmTy(ImmTySDWADstSel); }
400 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySDWASrc0Sel); }
401 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySDWASrc1Sel); }
402 bool isSDWADstUnused()
const {
return isImmTy(ImmTySDWADstUnused); }
403 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
404 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
405 bool isInterpAttrChan()
const {
return isImmTy(ImmTyInterpAttrChan); }
406 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
407 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
408 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
409 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
410 bool isBitOp3()
const {
return isImmTy(ImmTyBitOp3) &&
isUInt<8>(
getImm()); }
412 bool isRegOrImm()
const {
413 return isReg() || isImm();
416 bool isRegClass(
unsigned RCID)
const;
420 bool isRegOrInlineNoMods(
unsigned RCID, MVT type)
const {
421 return isRegOrInline(RCID, type) && !hasModifiers();
424 bool isSCSrcB16()
const {
425 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
428 bool isSCSrcV2B16()
const {
432 bool isSCSrc_b32()
const {
433 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
436 bool isSCSrc_b64()
const {
437 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
440 bool isBoolReg()
const;
442 bool isSCSrcF16()
const {
443 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
446 bool isSCSrcV2F16()
const {
450 bool isSCSrcF32()
const {
451 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
454 bool isSCSrcF64()
const {
455 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
458 bool isSSrc_b32()
const {
459 return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
462 bool isSSrc_b16()
const {
return isSCSrcB16() || isLiteralImm(MVT::i16); }
464 bool isSSrcV2B16()
const {
469 bool isSSrc_b64()
const {
472 return isSCSrc_b64() || isLiteralImm(MVT::i64) ||
473 (((
const MCTargetAsmParser *)AsmParser)
474 ->getAvailableFeatures()[AMDGPU::Feature64BitLiterals] &&
478 bool isSSrc_f32()
const {
479 return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
482 bool isSSrcF64()
const {
return isSCSrc_b64() || isLiteralImm(MVT::f64); }
484 bool isSSrc_bf16()
const {
return isSCSrcB16() || isLiteralImm(MVT::bf16); }
486 bool isSSrc_f16()
const {
return isSCSrcB16() || isLiteralImm(MVT::f16); }
488 bool isSSrcV2F16()
const {
493 bool isSSrcV2FP32()
const {
498 bool isSCSrcV2FP32()
const {
503 bool isSSrcV2INT32()
const {
508 bool isSCSrcV2INT32()
const {
510 return isSCSrc_b32();
513 bool isSSrcOrLds_b32()
const {
514 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
515 isLiteralImm(MVT::i32) || isExpr();
518 bool isVCSrc_b32()
const {
519 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
522 bool isVCSrc_b32_Lo256()
const {
523 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo256RegClassID, MVT::i32);
526 bool isVCSrc_b64_Lo256()
const {
527 return isRegOrInlineNoMods(AMDGPU::VS_64_Lo256RegClassID, MVT::i64);
530 bool isVCSrc_b64()
const {
531 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
534 bool isVCSrcT_b16()
const {
535 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
538 bool isVCSrcTB16_Lo128()
const {
539 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
542 bool isVCSrcFake16B16_Lo128()
const {
543 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
546 bool isVCSrc_b16()
const {
547 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
550 bool isVCSrc_v2b16()
const {
return isVCSrc_b16(); }
552 bool isVCSrc_f32()
const {
553 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
556 bool isVCSrc_f64()
const {
557 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
560 bool isVCSrcTBF16()
const {
561 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
564 bool isVCSrcT_f16()
const {
565 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
568 bool isVCSrcT_bf16()
const {
569 return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
572 bool isVCSrcTBF16_Lo128()
const {
573 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
576 bool isVCSrcTF16_Lo128()
const {
577 return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
580 bool isVCSrcFake16BF16_Lo128()
const {
581 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
584 bool isVCSrcFake16F16_Lo128()
const {
585 return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
588 bool isVCSrc_bf16()
const {
589 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
592 bool isVCSrc_f16()
const {
593 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
596 bool isVCSrc_v2bf16()
const {
return isVCSrc_bf16(); }
598 bool isVCSrc_v2f16()
const {
return isVCSrc_f16(); }
600 bool isVSrc_b32()
const {
601 return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
604 bool isVSrc_b64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::i64); }
606 bool isVSrcT_b16()
const {
return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
608 bool isVSrcT_b16_Lo128()
const {
609 return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
612 bool isVSrcFake16_b16_Lo128()
const {
613 return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
616 bool isVSrc_b16()
const {
return isVCSrc_b16() || isLiteralImm(MVT::i16); }
618 bool isVSrc_v2b16()
const {
return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
620 bool isVCSrcV2FP32()
const {
return isVCSrc_f64(); }
622 bool isVSrc_v2f32()
const {
return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
624 bool isVCSrc_v2b32()
const {
return isVCSrc_b64(); }
626 bool isVSrc_v2b32()
const {
return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
628 bool isVSrc_f32()
const {
629 return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
632 bool isVSrc_f64()
const {
return isVCSrc_f64() || isLiteralImm(MVT::f64); }
634 bool isVSrcT_bf16()
const {
return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
636 bool isVSrcT_f16()
const {
return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
638 bool isVSrcT_bf16_Lo128()
const {
639 return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
642 bool isVSrcT_f16_Lo128()
const {
643 return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
646 bool isVSrcFake16_bf16_Lo128()
const {
647 return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
650 bool isVSrcFake16_f16_Lo128()
const {
651 return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
654 bool isVSrc_bf16()
const {
return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
656 bool isVSrc_f16()
const {
return isVCSrc_f16() || isLiteralImm(MVT::f16); }
658 bool isVSrc_v2bf16()
const {
659 return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
662 bool isVSrc_v2f16()
const {
return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
664 bool isVSrc_NoInline_v2f16()
const {
return isVSrc_v2f16(); }
666 bool isVISrcB32()
const {
667 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
670 bool isVISrcB16()
const {
671 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
674 bool isVISrcV2B16()
const {
678 bool isVISrcF32()
const {
679 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
682 bool isVISrcF16()
const {
683 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
686 bool isVISrcV2F16()
const {
687 return isVISrcF16() || isVISrcB32();
690 bool isVISrc_64_bf16()
const {
691 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
694 bool isVISrc_64_f16()
const {
695 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
698 bool isVISrc_64_b32()
const {
699 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
702 bool isVISrc_64B64()
const {
703 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
706 bool isVISrc_64_f64()
const {
707 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
710 bool isVISrc_64V2FP32()
const {
711 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
714 bool isVISrc_64V2INT32()
const {
715 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
718 bool isVISrc_256_b32()
const {
719 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
722 bool isVISrc_256_f32()
const {
723 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
726 bool isVISrc_256B64()
const {
727 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
730 bool isVISrc_256_f64()
const {
731 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
734 bool isVISrc_512_f64()
const {
735 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f64);
738 bool isVISrc_128B16()
const {
739 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
742 bool isVISrc_128V2B16()
const {
743 return isVISrc_128B16();
746 bool isVISrc_128_b32()
const {
747 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
750 bool isVISrc_128_f32()
const {
751 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
754 bool isVISrc_256V2FP32()
const {
755 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
758 bool isVISrc_256V2INT32()
const {
759 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
762 bool isVISrc_512_b32()
const {
763 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
766 bool isVISrc_512B16()
const {
767 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
770 bool isVISrc_512V2B16()
const {
771 return isVISrc_512B16();
774 bool isVISrc_512_f32()
const {
775 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
778 bool isVISrc_512F16()
const {
779 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
782 bool isVISrc_512V2F16()
const {
783 return isVISrc_512F16() || isVISrc_512_b32();
786 bool isVISrc_1024_b32()
const {
787 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
790 bool isVISrc_1024B16()
const {
791 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
794 bool isVISrc_1024V2B16()
const {
795 return isVISrc_1024B16();
798 bool isVISrc_1024_f32()
const {
799 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
802 bool isVISrc_1024F16()
const {
803 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
806 bool isVISrc_1024V2F16()
const {
807 return isVISrc_1024F16() || isVISrc_1024_b32();
810 bool isAISrcB32()
const {
811 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
814 bool isAISrcB16()
const {
815 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
818 bool isAISrcV2B16()
const {
822 bool isAISrcF32()
const {
823 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
826 bool isAISrcF16()
const {
827 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
830 bool isAISrcV2F16()
const {
831 return isAISrcF16() || isAISrcB32();
834 bool isAISrc_64B64()
const {
835 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
838 bool isAISrc_64_f64()
const {
839 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
842 bool isAISrc_128_b32()
const {
843 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
846 bool isAISrc_128B16()
const {
847 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
850 bool isAISrc_128V2B16()
const {
851 return isAISrc_128B16();
854 bool isAISrc_128_f32()
const {
855 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
858 bool isAISrc_128F16()
const {
859 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
862 bool isAISrc_128V2F16()
const {
863 return isAISrc_128F16() || isAISrc_128_b32();
866 bool isVISrc_128_bf16()
const {
867 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
870 bool isVISrc_128_f16()
const {
871 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
874 bool isVISrc_128V2F16()
const {
875 return isVISrc_128_f16() || isVISrc_128_b32();
878 bool isAISrc_256B64()
const {
879 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
882 bool isAISrc_256_f64()
const {
883 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
886 bool isAISrc_512_b32()
const {
887 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
890 bool isAISrc_512B16()
const {
891 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
894 bool isAISrc_512V2B16()
const {
895 return isAISrc_512B16();
898 bool isAISrc_512_f32()
const {
899 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
902 bool isAISrc_512F16()
const {
903 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
906 bool isAISrc_512V2F16()
const {
907 return isAISrc_512F16() || isAISrc_512_b32();
910 bool isAISrc_1024_b32()
const {
911 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
914 bool isAISrc_1024B16()
const {
915 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
918 bool isAISrc_1024V2B16()
const {
919 return isAISrc_1024B16();
922 bool isAISrc_1024_f32()
const {
923 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
926 bool isAISrc_1024F16()
const {
927 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
930 bool isAISrc_1024V2F16()
const {
931 return isAISrc_1024F16() || isAISrc_1024_b32();
934 bool isKImmFP32()
const {
935 return isLiteralImm(MVT::f32);
938 bool isKImmFP16()
const {
939 return isLiteralImm(MVT::f16);
942 bool isKImmFP64()
const {
return isLiteralImm(MVT::f64); }
944 bool isMem()
const override {
948 bool isExpr()
const {
949 return Kind == Expression;
952 bool isSOPPBrTarget()
const {
return isExpr() || isImm(); }
954 bool isSWaitCnt()
const;
955 bool isDepCtr()
const;
956 bool isSDelayALU()
const;
957 bool isHwreg()
const;
958 bool isSendMsg()
const;
959 bool isSplitBarrier()
const;
960 bool isSwizzle()
const;
961 bool isSMRDOffset8()
const;
962 bool isSMEMOffset()
const;
963 bool isSMRDLiteralOffset()
const;
965 bool isDPPCtrl()
const;
967 bool isGPRIdxMode()
const;
968 bool isS16Imm()
const;
969 bool isU16Imm()
const;
970 bool isEndpgm()
const;
972 auto getPredicate(std::function<
bool(
const AMDGPUOperand &
Op)>
P)
const {
973 return [
this,
P]() {
return P(*
this); };
978 return StringRef(Tok.Data, Tok.Length);
986 void setImm(int64_t Val) {
991 ImmTy getImmTy()
const {
996 MCRegister
getReg()
const override {
1001 SMLoc getStartLoc()
const override {
1005 SMLoc getEndLoc()
const override {
1009 SMRange getLocRange()
const {
1010 return SMRange(StartLoc, EndLoc);
1013 int getMCOpIdx()
const {
return MCOpIdx; }
1015 Modifiers getModifiers()
const {
1016 assert(isRegKind() || isImmTy(ImmTyNone));
1017 return isRegKind() ?
Reg.Mods :
Imm.Mods;
1020 void setModifiers(Modifiers Mods) {
1021 assert(isRegKind() || isImmTy(ImmTyNone));
1028 bool hasModifiers()
const {
1029 return getModifiers().hasModifiers();
1032 bool hasFPModifiers()
const {
1033 return getModifiers().hasFPModifiers();
1036 bool hasIntModifiers()
const {
1037 return getModifiers().hasIntModifiers();
1040 uint64_t applyInputFPModifiers(uint64_t Val,
unsigned Size)
const;
1042 void addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
1044 void addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
1046 void addRegOperands(MCInst &Inst,
unsigned N)
const;
1048 void addRegOrImmOperands(MCInst &Inst,
unsigned N)
const {
1050 addRegOperands(Inst,
N);
1052 addImmOperands(Inst,
N);
1055 void addRegOrImmWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1056 Modifiers Mods = getModifiers();
1059 addRegOperands(Inst,
N);
1061 addImmOperands(Inst,
N,
false);
1065 void addRegOrImmWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1066 assert(!hasIntModifiers());
1067 addRegOrImmWithInputModsOperands(Inst,
N);
1070 void addRegOrImmWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1071 assert(!hasFPModifiers());
1072 addRegOrImmWithInputModsOperands(Inst,
N);
1075 void addRegWithInputModsOperands(MCInst &Inst,
unsigned N)
const {
1076 Modifiers Mods = getModifiers();
1079 addRegOperands(Inst,
N);
1082 void addRegWithFPInputModsOperands(MCInst &Inst,
unsigned N)
const {
1083 assert(!hasIntModifiers());
1084 addRegWithInputModsOperands(Inst,
N);
1087 void addRegWithIntInputModsOperands(MCInst &Inst,
unsigned N)
const {
1088 assert(!hasFPModifiers());
1089 addRegWithInputModsOperands(Inst,
N);
1092 static void printImmTy(raw_ostream& OS, ImmTy
Type) {
1095 case ImmTyNone: OS <<
"None";
break;
1096 case ImmTyGDS: OS <<
"GDS";
break;
1097 case ImmTyLDS: OS <<
"LDS";
break;
1098 case ImmTyOffen: OS <<
"Offen";
break;
1099 case ImmTyIdxen: OS <<
"Idxen";
break;
1100 case ImmTyAddr64: OS <<
"Addr64";
break;
1101 case ImmTyOffset: OS <<
"Offset";
break;
1102 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1103 case ImmTyOffset0: OS <<
"Offset0";
break;
1104 case ImmTyOffset1: OS <<
"Offset1";
break;
1105 case ImmTySMEMOffsetMod: OS <<
"SMEMOffsetMod";
break;
1106 case ImmTyCPol: OS <<
"CPol";
break;
1107 case ImmTyIndexKey8bit: OS <<
"index_key";
break;
1108 case ImmTyIndexKey16bit: OS <<
"index_key";
break;
1109 case ImmTyIndexKey32bit: OS <<
"index_key";
break;
1110 case ImmTyTFE: OS <<
"TFE";
break;
1111 case ImmTyD16: OS <<
"D16";
break;
1112 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1113 case ImmTyClamp: OS <<
"Clamp";
break;
1114 case ImmTyOModSI: OS <<
"OModSI";
break;
1115 case ImmTyDPP8: OS <<
"DPP8";
break;
1116 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1117 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1118 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1119 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1120 case ImmTyDppFI: OS <<
"DppFI";
break;
1121 case ImmTySDWADstSel: OS <<
"SDWADstSel";
break;
1122 case ImmTySDWASrc0Sel: OS <<
"SDWASrc0Sel";
break;
1123 case ImmTySDWASrc1Sel: OS <<
"SDWASrc1Sel";
break;
1124 case ImmTySDWADstUnused: OS <<
"SDWADstUnused";
break;
1125 case ImmTyDMask: OS <<
"DMask";
break;
1126 case ImmTyDim: OS <<
"Dim";
break;
1127 case ImmTyUNorm: OS <<
"UNorm";
break;
1128 case ImmTyDA: OS <<
"DA";
break;
1129 case ImmTyR128A16: OS <<
"R128A16";
break;
1130 case ImmTyA16: OS <<
"A16";
break;
1131 case ImmTyLWE: OS <<
"LWE";
break;
1132 case ImmTyOff: OS <<
"Off";
break;
1133 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1134 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1135 case ImmTyExpVM: OS <<
"ExpVM";
break;
1136 case ImmTyHwreg: OS <<
"Hwreg";
break;
1137 case ImmTySendMsg: OS <<
"SendMsg";
break;
1138 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1139 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1140 case ImmTyInterpAttrChan: OS <<
"InterpAttrChan";
break;
1141 case ImmTyOpSel: OS <<
"OpSel";
break;
1142 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1143 case ImmTyNegLo: OS <<
"NegLo";
break;
1144 case ImmTyNegHi: OS <<
"NegHi";
break;
1145 case ImmTySwizzle: OS <<
"Swizzle";
break;
1146 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1147 case ImmTyHigh: OS <<
"High";
break;
1148 case ImmTyBLGP: OS <<
"BLGP";
break;
1149 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1150 case ImmTyABID: OS <<
"ABID";
break;
1151 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1152 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1153 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1154 case ImmTyWaitVAVDst: OS <<
"WaitVAVDst";
break;
1155 case ImmTyWaitVMVSrc: OS <<
"WaitVMVSrc";
break;
1156 case ImmTyBitOp3: OS <<
"BitOp3";
break;
1157 case ImmTyMatrixAFMT: OS <<
"ImmTyMatrixAFMT";
break;
1158 case ImmTyMatrixBFMT: OS <<
"ImmTyMatrixBFMT";
break;
1159 case ImmTyMatrixAScale: OS <<
"ImmTyMatrixAScale";
break;
1160 case ImmTyMatrixBScale: OS <<
"ImmTyMatrixBScale";
break;
1161 case ImmTyMatrixAScaleFmt: OS <<
"ImmTyMatrixAScaleFmt";
break;
1162 case ImmTyMatrixBScaleFmt: OS <<
"ImmTyMatrixBScaleFmt";
break;
1163 case ImmTyMatrixAReuse: OS <<
"ImmTyMatrixAReuse";
break;
1164 case ImmTyMatrixBReuse: OS <<
"ImmTyMatrixBReuse";
break;
1165 case ImmTyScaleSel: OS <<
"ScaleSel" ;
break;
1166 case ImmTyByteSel: OS <<
"ByteSel" ;
break;
1171 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1175 <<
" mods: " <<
Reg.Mods <<
'>';
1179 if (getImmTy() != ImmTyNone) {
1180 OS <<
" type: "; printImmTy(OS, getImmTy());
1182 OS <<
" mods: " <<
Imm.Mods <<
'>';
1195 static AMDGPUOperand::Ptr CreateImm(
const AMDGPUAsmParser *AsmParser,
1196 int64_t Val, SMLoc Loc,
1197 ImmTy
Type = ImmTyNone,
1198 bool IsFPImm =
false) {
1199 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1201 Op->Imm.IsFPImm = IsFPImm;
1203 Op->Imm.Mods = Modifiers();
1209 static AMDGPUOperand::Ptr CreateToken(
const AMDGPUAsmParser *AsmParser,
1210 StringRef Str, SMLoc Loc,
1211 bool HasExplicitEncodingSize =
true) {
1212 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1213 Res->Tok.Data = Str.data();
1214 Res->Tok.Length = Str.size();
1215 Res->StartLoc = Loc;
1220 static AMDGPUOperand::Ptr CreateReg(
const AMDGPUAsmParser *AsmParser,
1221 MCRegister
Reg, SMLoc S, SMLoc
E) {
1222 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1223 Op->Reg.RegNo =
Reg;
1224 Op->Reg.Mods = Modifiers();
1230 static AMDGPUOperand::Ptr CreateExpr(
const AMDGPUAsmParser *AsmParser,
1231 const class MCExpr *Expr, SMLoc S) {
1232 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1241 OS <<
"abs:" << Mods.Abs <<
" neg: " << Mods.Neg <<
" sext:" << Mods.Sext;
1250#define GET_REGISTER_MATCHER
1251#include "AMDGPUGenAsmMatcher.inc"
1252#undef GET_REGISTER_MATCHER
1253#undef GET_SUBTARGET_FEATURE_NAME
1258class KernelScopeInfo {
1259 int SgprIndexUnusedMin = -1;
1260 int VgprIndexUnusedMin = -1;
1261 int AgprIndexUnusedMin = -1;
1265 void usesSgprAt(
int i) {
1266 if (i >= SgprIndexUnusedMin) {
1267 SgprIndexUnusedMin = ++i;
1270 Ctx->getOrCreateSymbol(
Twine(
".kernel.sgpr_count"));
1276 void usesVgprAt(
int i) {
1277 if (i >= VgprIndexUnusedMin) {
1278 VgprIndexUnusedMin = ++i;
1281 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1283 VgprIndexUnusedMin);
1289 void usesAgprAt(
int i) {
1294 if (i >= AgprIndexUnusedMin) {
1295 AgprIndexUnusedMin = ++i;
1298 Ctx->getOrCreateSymbol(
Twine(
".kernel.agpr_count"));
1303 Ctx->getOrCreateSymbol(
Twine(
".kernel.vgpr_count"));
1305 VgprIndexUnusedMin);
1312 KernelScopeInfo() =
default;
1316 MSTI = Ctx->getSubtargetInfo();
1318 usesSgprAt(SgprIndexUnusedMin = -1);
1319 usesVgprAt(VgprIndexUnusedMin = -1);
1321 usesAgprAt(AgprIndexUnusedMin = -1);
1325 void usesRegister(RegisterKind RegKind,
unsigned DwordRegIndex,
1326 unsigned RegWidth) {
1329 usesSgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1332 usesAgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1335 usesVgprAt(DwordRegIndex +
divideCeil(RegWidth, 32) - 1);
1344 MCAsmParser &Parser;
1346 unsigned ForcedEncodingSize = 0;
1347 bool ForcedDPP =
false;
1348 bool ForcedSDWA =
false;
1349 KernelScopeInfo KernelScope;
1350 const unsigned HwMode;
1355#define GET_ASSEMBLER_HEADER
1356#include "AMDGPUGenAsmMatcher.inc"
1361 unsigned getRegOperandSize(
const MCInstrDesc &
Desc,
unsigned OpNo)
const {
1363 int16_t RCID = MII.getOpRegClassID(
Desc.operands()[OpNo], HwMode);
1368 void createConstantSymbol(StringRef Id, int64_t Val);
1370 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1371 bool OutOfRangeError(SMRange
Range);
1387 bool calculateGPRBlocks(
const FeatureBitset &Features,
const MCExpr *VCCUsed,
1388 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1389 std::optional<bool> EnableWavefrontSize32,
1390 const MCExpr *NextFreeVGPR, SMRange VGPRRange,
1391 const MCExpr *NextFreeSGPR, SMRange SGPRRange,
1392 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks);
1393 bool ParseDirectiveAMDGCNTarget();
1394 bool ParseDirectiveAMDHSACodeObjectVersion();
1395 bool ParseDirectiveAMDHSAKernel();
1396 bool ParseAMDKernelCodeTValue(StringRef
ID, AMDGPUMCKernelCodeT &Header);
1397 bool ParseDirectiveAMDKernelCodeT();
1399 bool subtargetHasRegister(
const MCRegisterInfo &
MRI, MCRegister
Reg);
1400 bool ParseDirectiveAMDGPUHsaKernel();
1402 bool ParseDirectiveISAVersion();
1403 bool ParseDirectiveHSAMetadata();
1404 bool ParseDirectivePALMetadataBegin();
1405 bool ParseDirectivePALMetadata();
1406 bool ParseDirectiveAMDGPULDS();
1410 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1411 const char *AssemblerDirectiveEnd,
1412 std::string &CollectString);
1414 bool AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
1415 RegisterKind RegKind, MCRegister Reg1, SMLoc Loc);
1416 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1417 unsigned &RegNum,
unsigned &RegWidth,
1418 bool RestoreOnFailure =
false);
1419 bool ParseAMDGPURegister(RegisterKind &RegKind, MCRegister &
Reg,
1420 unsigned &RegNum,
unsigned &RegWidth,
1421 SmallVectorImpl<AsmToken> &Tokens);
1422 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1424 SmallVectorImpl<AsmToken> &Tokens);
1425 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1427 SmallVectorImpl<AsmToken> &Tokens);
1428 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1430 SmallVectorImpl<AsmToken> &Tokens);
1431 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &
SubReg);
1432 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1433 unsigned SubReg,
unsigned RegWidth, SMLoc Loc);
1436 bool isRegister(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1437 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1438 void initializeGprCountSymbol(RegisterKind RegKind);
1439 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1441 void cvtMubufImpl(MCInst &Inst,
const OperandVector &Operands,
1446 OperandMode_Default,
1450 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1452 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1453 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
1454 : MCTargetAsmParser(
Options, STI, MII), Parser(_Parser),
1455 HwMode(STI.getHwMode(MCSubtargetInfo::HwMode_RegInfo)) {
1458 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1462 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1463 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1464 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1466 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1467 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1468 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1471 initializeGprCountSymbol(IS_VGPR);
1472 initializeGprCountSymbol(IS_SGPR);
1477 createConstantSymbol(Symbol, Code);
1479 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1480 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1481 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1553 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1555 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1557 bool hasInv2PiInlineImm()
const {
1558 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1561 bool has64BitLiterals()
const {
1562 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1565 bool hasFlatOffsets()
const {
1566 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1569 bool hasTrue16Insts()
const {
1570 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1574 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1577 bool hasSGPR102_SGPR103()
const {
1581 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1583 bool hasIntClamp()
const {
1584 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1587 bool hasPartialNSAEncoding()
const {
1588 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1591 bool hasGloballyAddressableScratch()
const {
1592 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1605 AMDGPUTargetStreamer &getTargetStreamer() {
1606 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1607 return static_cast<AMDGPUTargetStreamer &
>(TS);
1613 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1616 const MCRegisterInfo *getMRI()
const {
1620 const MCInstrInfo *getMII()
const {
1626 const FeatureBitset &getFeatureBits()
const {
1627 return getSTI().getFeatureBits();
1630 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1631 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1632 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1634 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1635 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1636 bool isForcedDPP()
const {
return ForcedDPP; }
1637 bool isForcedSDWA()
const {
return ForcedSDWA; }
1638 ArrayRef<unsigned> getMatchedVariants()
const;
1639 StringRef getMatchedVariantName()
const;
1641 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1642 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1643 bool RestoreOnFailure);
1644 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1645 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1646 SMLoc &EndLoc)
override;
1647 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1648 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1649 unsigned Kind)
override;
1650 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1652 uint64_t &ErrorInfo,
1653 bool MatchingInlineAsm)
override;
1654 bool ParseDirective(AsmToken DirectiveID)
override;
1655 ParseStatus parseOperand(
OperandVector &Operands, StringRef Mnemonic,
1656 OperandMode
Mode = OperandMode_Default);
1657 StringRef parseMnemonicSuffix(StringRef Name);
1658 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
1662 ParseStatus parseTokenOp(StringRef Name,
OperandVector &Operands);
1664 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1667 parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1668 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1669 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1671 ParseStatus parseOperandArrayWithPrefix(
1673 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1674 bool (*ConvertResult)(int64_t &) =
nullptr);
1678 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1679 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1681 ParseStatus parseScope(
OperandVector &Operands, int64_t &Scope);
1683 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1685 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1687 ArrayRef<const char *> Ids,
1689 ParseStatus parseStringOrIntWithPrefix(
OperandVector &Operands,
1691 ArrayRef<const char *> Ids,
1692 AMDGPUOperand::ImmTy
Type);
1695 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1696 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1697 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1698 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1699 bool parseSP3NegModifier();
1700 ParseStatus parseImm(
OperandVector &Operands,
bool HasSP3AbsModifier =
false,
1703 ParseStatus parseRegOrImm(
OperandVector &Operands,
bool HasSP3AbsMod =
false,
1705 ParseStatus parseRegOrImmWithFPInputMods(
OperandVector &Operands,
1706 bool AllowImm =
true);
1707 ParseStatus parseRegOrImmWithIntInputMods(
OperandVector &Operands,
1708 bool AllowImm =
true);
1709 ParseStatus parseRegWithFPInputMods(
OperandVector &Operands);
1710 ParseStatus parseRegWithIntInputMods(
OperandVector &Operands);
1713 AMDGPUOperand::ImmTy ImmTy);
1717 ParseStatus tryParseMatrixFMT(
OperandVector &Operands, StringRef Name,
1718 AMDGPUOperand::ImmTy
Type);
1721 ParseStatus tryParseMatrixScale(
OperandVector &Operands, StringRef Name,
1722 AMDGPUOperand::ImmTy
Type);
1725 ParseStatus tryParseMatrixScaleFmt(
OperandVector &Operands, StringRef Name,
1726 AMDGPUOperand::ImmTy
Type);
1730 ParseStatus parseDfmtNfmt(int64_t &
Format);
1731 ParseStatus parseUfmt(int64_t &
Format);
1732 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1734 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1737 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1738 ParseStatus parseNumericFormat(int64_t &
Format);
1742 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1743 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1747 bool parseCnt(int64_t &IntVal);
1750 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1751 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1754 bool parseDelay(int64_t &Delay);
1760 struct OperandInfoTy {
1763 bool IsSymbolic =
false;
1764 bool IsDefined =
false;
1766 OperandInfoTy(int64_t Val) : Val(Val) {}
1769 struct StructuredOpField : OperandInfoTy {
1773 bool IsDefined =
false;
1775 StructuredOpField(StringLiteral Id, StringLiteral Desc,
unsigned Width,
1777 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1778 virtual ~StructuredOpField() =
default;
1780 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1781 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1785 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1787 return Error(Parser,
"not supported on this GPU");
1789 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1797 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1798 bool validateSendMsg(
const OperandInfoTy &Msg,
1799 const OperandInfoTy &
Op,
1800 const OperandInfoTy &Stream);
1802 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1803 OperandInfoTy &Width);
1805 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1807 SMLoc getFlatOffsetLoc(
const OperandVector &Operands)
const;
1808 SMLoc getSMEMOffsetLoc(
const OperandVector &Operands)
const;
1811 SMLoc getOperandLoc(
const OperandVector &Operands,
int MCOpIdx)
const;
1812 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1814 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1818 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1820 bool validateOffset(
const MCInst &Inst,
const OperandVector &Operands);
1821 bool validateFlatOffset(
const MCInst &Inst,
const OperandVector &Operands);
1822 bool validateSMEMOffset(
const MCInst &Inst,
const OperandVector &Operands);
1823 bool validateSOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1824 bool validateConstantBusLimitations(
const MCInst &Inst,
const OperandVector &Operands);
1825 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1827 bool validateVOPD(
const MCInst &Inst,
const OperandVector &Operands);
1828 bool tryVOPD(
const MCInst &Inst);
1829 bool tryVOPD3(
const MCInst &Inst);
1830 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1832 bool validateIntClampSupported(
const MCInst &Inst);
1833 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1834 bool validateMIMGGatherDMask(
const MCInst &Inst);
1835 bool validateMovrels(
const MCInst &Inst,
const OperandVector &Operands);
1836 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1837 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1838 bool validateMIMGD16(
const MCInst &Inst);
1839 bool validateMIMGDim(
const MCInst &Inst,
const OperandVector &Operands);
1840 bool validateTensorR128(
const MCInst &Inst);
1841 bool validateMIMGMSAA(
const MCInst &Inst);
1842 bool validateOpSel(
const MCInst &Inst);
1843 bool validateTrue16OpSel(
const MCInst &Inst);
1844 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1845 bool validateDPP(
const MCInst &Inst,
const OperandVector &Operands);
1846 bool validateVccOperand(MCRegister
Reg)
const;
1847 bool validateVOPLiteral(
const MCInst &Inst,
const OperandVector &Operands);
1848 bool validateMAIAccWrite(
const MCInst &Inst,
const OperandVector &Operands);
1849 bool validateMAISrc2(
const MCInst &Inst,
const OperandVector &Operands);
1850 bool validateMFMA(
const MCInst &Inst,
const OperandVector &Operands);
1851 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1852 bool validateVGPRAlign(
const MCInst &Inst)
const;
1853 bool validateBLGP(
const MCInst &Inst,
const OperandVector &Operands);
1854 bool validateDS(
const MCInst &Inst,
const OperandVector &Operands);
1855 bool validateGWS(
const MCInst &Inst,
const OperandVector &Operands);
1856 bool validateDivScale(
const MCInst &Inst);
1857 bool validateWaitCnt(
const MCInst &Inst,
const OperandVector &Operands);
1858 bool validateCoherencyBits(
const MCInst &Inst,
const OperandVector &Operands,
1860 bool validateTHAndScopeBits(
const MCInst &Inst,
const OperandVector &Operands,
1861 const unsigned CPol);
1862 bool validateTFE(
const MCInst &Inst,
const OperandVector &Operands);
1863 bool validateLdsDirect(
const MCInst &Inst,
const OperandVector &Operands);
1864 bool validateWMMA(
const MCInst &Inst,
const OperandVector &Operands);
1865 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1866 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1867 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1868 MCRegister findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1870 bool isSupportedMnemo(StringRef Mnemo,
1871 const FeatureBitset &FBS);
1872 bool isSupportedMnemo(StringRef Mnemo,
1873 const FeatureBitset &FBS,
1874 ArrayRef<unsigned> Variants);
1875 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1877 bool isId(
const StringRef Id)
const;
1878 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1880 StringRef getId()
const;
1881 bool trySkipId(
const StringRef Id);
1882 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1886 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1887 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1893 StringRef getTokenStr()
const;
1894 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1896 SMLoc getLoc()
const;
1900 void onBeginOfFile()
override;
1901 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1903 ParseStatus parseCustomOperand(
OperandVector &Operands,
unsigned MCK);
1912 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1913 const unsigned MaxVal,
const Twine &ErrMsg,
1915 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1916 const unsigned MinVal,
1917 const unsigned MaxVal,
1918 const StringRef ErrMsg);
1920 bool parseSwizzleOffset(int64_t &
Imm);
1921 bool parseSwizzleMacro(int64_t &
Imm);
1922 bool parseSwizzleQuadPerm(int64_t &
Imm);
1923 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1924 bool parseSwizzleBroadcast(int64_t &
Imm);
1925 bool parseSwizzleSwap(int64_t &
Imm);
1926 bool parseSwizzleReverse(int64_t &
Imm);
1927 bool parseSwizzleFFT(int64_t &
Imm);
1928 bool parseSwizzleRotate(int64_t &
Imm);
1931 int64_t parseGPRIdxMacro();
1933 void cvtMubuf(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
false); }
1934 void cvtMubufAtomic(MCInst &Inst,
const OperandVector &Operands) { cvtMubufImpl(Inst, Operands,
true); }
1939 OptionalImmIndexMap &OptionalIdx);
1940 void cvtScaledMFMA(MCInst &Inst,
const OperandVector &Operands);
1941 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands);
1944 void cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands);
1947 void cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
1948 OptionalImmIndexMap &OptionalIdx);
1950 OptionalImmIndexMap &OptionalIdx);
1952 void cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands);
1953 void cvtVINTERP(MCInst &Inst,
const OperandVector &Operands);
1954 void cvtOpSelHelper(MCInst &Inst,
unsigned OpSel);
1956 bool parseDimId(
unsigned &Encoding);
1958 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1961 bool isSupportedDPPCtrl(StringRef Ctrl,
const OperandVector &Operands);
1962 int64_t parseDPPCtrlSel(StringRef Ctrl);
1963 int64_t parseDPPCtrlPerm();
1964 void cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8 =
false);
1966 cvtDPP(Inst, Operands,
true);
1968 void cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
1969 bool IsDPP8 =
false);
1970 void cvtVOP3DPP8(MCInst &Inst,
const OperandVector &Operands) {
1971 cvtVOP3DPP(Inst, Operands,
true);
1974 ParseStatus parseSDWASel(
OperandVector &Operands, StringRef Prefix,
1975 AMDGPUOperand::ImmTy
Type);
1977 void cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands);
1978 void cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands);
1979 void cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands);
1980 void cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands);
1981 void cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands);
1983 uint64_t BasicInstType,
1984 bool SkipDstVcc =
false,
1985 bool SkipSrcVcc =
false);
2093bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2103 if (!isImmTy(ImmTyNone)) {
2108 if (getModifiers().
Lit != LitModifier::None)
2118 if (type == MVT::f64 || type == MVT::i64) {
2120 AsmParser->hasInv2PiInlineImm());
2123 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2142 APFloat::rmNearestTiesToEven, &Lost);
2149 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2151 AsmParser->hasInv2PiInlineImm());
2156 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2157 AsmParser->hasInv2PiInlineImm());
2161 if (type == MVT::f64 || type == MVT::i64) {
2163 AsmParser->hasInv2PiInlineImm());
2172 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2173 type, AsmParser->hasInv2PiInlineImm());
2177 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2178 AsmParser->hasInv2PiInlineImm());
2181bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2183 if (!isImmTy(ImmTyNone)) {
2188 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2193 if (type == MVT::f64 && hasFPModifiers()) {
2213 if (type == MVT::f64) {
2218 if (type == MVT::i64) {
2231 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2232 : (type == MVT::v2i16) ? MVT::f32
2233 : (type == MVT::v2f32) ? MVT::f32
2236 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2240bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2241 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2244bool AMDGPUOperand::isVRegWithInputMods()
const {
2245 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2247 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2248 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2251template <
bool IsFake16>
2252bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2253 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2254 : AMDGPU::VGPR_16_Lo128RegClassID);
2257template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2258 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2259 : AMDGPU::VGPR_16RegClassID);
2262bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2263 if (AsmParser->isVI())
2265 if (AsmParser->isGFX9Plus())
2266 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2270bool AMDGPUOperand::isSDWAFP16Operand()
const {
2271 return isSDWAOperand(MVT::f16);
2274bool AMDGPUOperand::isSDWAFP32Operand()
const {
2275 return isSDWAOperand(MVT::f32);
2278bool AMDGPUOperand::isSDWAInt16Operand()
const {
2279 return isSDWAOperand(MVT::i16);
2282bool AMDGPUOperand::isSDWAInt32Operand()
const {
2283 return isSDWAOperand(MVT::i32);
2286bool AMDGPUOperand::isBoolReg()
const {
2287 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2288 (AsmParser->isWave32() && isSCSrc_b32()));
2291uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2293 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2296 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2308void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2318 addLiteralImmOperand(Inst,
Imm.Val,
2320 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2322 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2327void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2328 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2333 if (ApplyModifiers) {
2336 Val = applyInputFPModifiers(Val,
Size);
2340 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2342 bool CanUse64BitLiterals =
2343 AsmParser->has64BitLiterals() &&
2346 MCContext &Ctx = AsmParser->getContext();
2355 if (
Lit == LitModifier::None &&
2357 AsmParser->hasInv2PiInlineImm())) {
2365 bool HasMandatoryLiteral =
2368 if (
Literal.getLoBits(32) != 0 &&
2369 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2370 !HasMandatoryLiteral) {
2371 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2373 "Can't encode literal as exact 64-bit floating-point operand. "
2374 "Low 32-bits will be set to zero");
2375 Val &= 0xffffffff00000000u;
2381 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2387 Lit = LitModifier::Lit64;
2388 }
else if (
Lit == LitModifier::Lit) {
2402 if (CanUse64BitLiterals &&
Lit == LitModifier::None &&
2404 Lit = LitModifier::Lit64;
2411 if (
Lit == LitModifier::None && AsmParser->hasInv2PiInlineImm() &&
2412 Literal == 0x3fc45f306725feed) {
2446 APFloat::rmNearestTiesToEven, &lost);
2450 Val = FPLiteral.bitcastToAPInt().getZExtValue();
2457 if (
Lit != LitModifier::None) {
2486 if (
Lit == LitModifier::None &&
2496 if (!AsmParser->has64BitLiterals() ||
Lit == LitModifier::Lit)
2503 if (
Lit == LitModifier::None &&
2511 if (!AsmParser->has64BitLiterals()) {
2512 Val =
static_cast<uint64_t
>(Val) << 32;
2519 if (
Lit == LitModifier::Lit ||
2521 Val =
static_cast<uint64_t
>(Val) << 32;
2525 if (
Lit == LitModifier::Lit)
2551 if (
Lit != LitModifier::None) {
2559void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2564bool AMDGPUOperand::isInlineValue()
const {
2572void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2583 if (Is == IS_VGPR) {
2587 return AMDGPU::VGPR_32RegClassID;
2589 return AMDGPU::VReg_64RegClassID;
2591 return AMDGPU::VReg_96RegClassID;
2593 return AMDGPU::VReg_128RegClassID;
2595 return AMDGPU::VReg_160RegClassID;
2597 return AMDGPU::VReg_192RegClassID;
2599 return AMDGPU::VReg_224RegClassID;
2601 return AMDGPU::VReg_256RegClassID;
2603 return AMDGPU::VReg_288RegClassID;
2605 return AMDGPU::VReg_320RegClassID;
2607 return AMDGPU::VReg_352RegClassID;
2609 return AMDGPU::VReg_384RegClassID;
2611 return AMDGPU::VReg_512RegClassID;
2613 return AMDGPU::VReg_1024RegClassID;
2615 }
else if (Is == IS_TTMP) {
2619 return AMDGPU::TTMP_32RegClassID;
2621 return AMDGPU::TTMP_64RegClassID;
2623 return AMDGPU::TTMP_128RegClassID;
2625 return AMDGPU::TTMP_256RegClassID;
2627 return AMDGPU::TTMP_512RegClassID;
2629 }
else if (Is == IS_SGPR) {
2633 return AMDGPU::SGPR_32RegClassID;
2635 return AMDGPU::SGPR_64RegClassID;
2637 return AMDGPU::SGPR_96RegClassID;
2639 return AMDGPU::SGPR_128RegClassID;
2641 return AMDGPU::SGPR_160RegClassID;
2643 return AMDGPU::SGPR_192RegClassID;
2645 return AMDGPU::SGPR_224RegClassID;
2647 return AMDGPU::SGPR_256RegClassID;
2649 return AMDGPU::SGPR_288RegClassID;
2651 return AMDGPU::SGPR_320RegClassID;
2653 return AMDGPU::SGPR_352RegClassID;
2655 return AMDGPU::SGPR_384RegClassID;
2657 return AMDGPU::SGPR_512RegClassID;
2659 }
else if (Is == IS_AGPR) {
2663 return AMDGPU::AGPR_32RegClassID;
2665 return AMDGPU::AReg_64RegClassID;
2667 return AMDGPU::AReg_96RegClassID;
2669 return AMDGPU::AReg_128RegClassID;
2671 return AMDGPU::AReg_160RegClassID;
2673 return AMDGPU::AReg_192RegClassID;
2675 return AMDGPU::AReg_224RegClassID;
2677 return AMDGPU::AReg_256RegClassID;
2679 return AMDGPU::AReg_288RegClassID;
2681 return AMDGPU::AReg_320RegClassID;
2683 return AMDGPU::AReg_352RegClassID;
2685 return AMDGPU::AReg_384RegClassID;
2687 return AMDGPU::AReg_512RegClassID;
2689 return AMDGPU::AReg_1024RegClassID;
2697 .
Case(
"exec", AMDGPU::EXEC)
2698 .
Case(
"vcc", AMDGPU::VCC)
2699 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2700 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2701 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2702 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2703 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2704 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2705 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2706 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2707 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2708 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2709 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2710 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2711 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2712 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2713 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2714 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2715 .
Case(
"m0", AMDGPU::M0)
2716 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2717 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2718 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2719 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2720 .
Case(
"scc", AMDGPU::SRC_SCC)
2721 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2722 .
Case(
"tba", AMDGPU::TBA)
2723 .
Case(
"tma", AMDGPU::TMA)
2724 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2725 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2726 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2727 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2728 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2729 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2730 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2731 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2732 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2733 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2734 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2735 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2736 .
Case(
"pc", AMDGPU::PC_REG)
2737 .
Case(
"null", AMDGPU::SGPR_NULL)
2741bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2742 SMLoc &EndLoc,
bool RestoreOnFailure) {
2743 auto R = parseRegister();
2744 if (!R)
return true;
2746 RegNo =
R->getReg();
2747 StartLoc =
R->getStartLoc();
2748 EndLoc =
R->getEndLoc();
2752bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2754 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2757ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2759 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2760 bool PendingErrors = getParser().hasPendingError();
2761 getParser().clearPendingErrors();
2769bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2770 RegisterKind RegKind,
2771 MCRegister Reg1, SMLoc Loc) {
2774 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2779 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2780 Reg = AMDGPU::FLAT_SCR;
2784 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2785 Reg = AMDGPU::XNACK_MASK;
2789 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2794 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2799 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2804 Error(Loc,
"register does not fit in the list");
2810 if (Reg1 !=
Reg + RegWidth / 32) {
2811 Error(Loc,
"registers in a list must have consecutive indices");
2829 {{
"ttmp"}, IS_TTMP},
2835 return Kind == IS_VGPR ||
2843 if (Str.starts_with(
Reg.Name))
2849 return !Str.getAsInteger(10, Num);
2853AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2854 const AsmToken &NextToken)
const {
2869 StringRef RegSuffix = Str.substr(
RegName.size());
2870 if (!RegSuffix.
empty()) {
2888AMDGPUAsmParser::isRegister()
2890 return isRegister(
getToken(), peekToken());
2893MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2894 unsigned SubReg,
unsigned RegWidth,
2898 unsigned AlignSize = 1;
2899 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2905 if (RegNum % AlignSize != 0) {
2906 Error(Loc,
"invalid register alignment");
2907 return MCRegister();
2910 unsigned RegIdx = RegNum / AlignSize;
2913 Error(Loc,
"invalid or unsupported register size");
2914 return MCRegister();
2918 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2919 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2920 Error(Loc,
"register index is out of range");
2921 return AMDGPU::NoRegister;
2924 if (RegKind == IS_VGPR && !
isGFX1250() && RegIdx + RegWidth / 32 > 256) {
2925 Error(Loc,
"register index is out of range");
2926 return MCRegister();
2942bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2944 int64_t RegLo, RegHi;
2948 SMLoc FirstIdxLoc = getLoc();
2955 SecondIdxLoc = getLoc();
2966 Error(FirstIdxLoc,
"invalid register index");
2971 Error(SecondIdxLoc,
"invalid register index");
2975 if (RegLo > RegHi) {
2976 Error(FirstIdxLoc,
"first register index should not exceed second index");
2980 if (RegHi == RegLo) {
2981 StringRef RegSuffix = getTokenStr();
2982 if (RegSuffix ==
".l") {
2985 }
else if (RegSuffix ==
".h") {
2991 Num =
static_cast<unsigned>(RegLo);
2992 RegWidth = 32 * ((RegHi - RegLo) + 1);
2997MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
3000 SmallVectorImpl<AsmToken> &Tokens) {
3006 RegKind = IS_SPECIAL;
3013MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3016 SmallVectorImpl<AsmToken> &Tokens) {
3018 StringRef
RegName = getTokenStr();
3019 auto Loc = getLoc();
3023 Error(Loc,
"invalid register name");
3024 return MCRegister();
3032 unsigned SubReg = NoSubRegister;
3033 if (!RegSuffix.
empty()) {
3041 Error(Loc,
"invalid register index");
3042 return MCRegister();
3047 if (!ParseRegRange(RegNum, RegWidth,
SubReg))
3048 return MCRegister();
3051 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
3054MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3055 unsigned &RegNum,
unsigned &RegWidth,
3056 SmallVectorImpl<AsmToken> &Tokens) {
3058 auto ListLoc = getLoc();
3061 "expected a register or a list of registers")) {
3062 return MCRegister();
3067 auto Loc = getLoc();
3068 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3069 return MCRegister();
3070 if (RegWidth != 32) {
3071 Error(Loc,
"expected a single 32-bit register");
3072 return MCRegister();
3076 RegisterKind NextRegKind;
3078 unsigned NextRegNum, NextRegWidth;
3081 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3082 NextRegNum, NextRegWidth,
3084 return MCRegister();
3086 if (NextRegWidth != 32) {
3087 Error(Loc,
"expected a single 32-bit register");
3088 return MCRegister();
3090 if (NextRegKind != RegKind) {
3091 Error(Loc,
"registers in a list must be of the same kind");
3092 return MCRegister();
3094 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3095 return MCRegister();
3099 "expected a comma or a closing square bracket")) {
3100 return MCRegister();
3104 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3109bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3110 MCRegister &
Reg,
unsigned &RegNum,
3112 SmallVectorImpl<AsmToken> &Tokens) {
3113 auto Loc = getLoc();
3117 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3119 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3121 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3126 assert(Parser.hasPendingError());
3130 if (!subtargetHasRegister(*
TRI,
Reg)) {
3131 if (
Reg == AMDGPU::SGPR_NULL) {
3132 Error(Loc,
"'null' operand is not supported on this GPU");
3135 " register not available on this GPU");
3143bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3144 MCRegister &
Reg,
unsigned &RegNum,
3146 bool RestoreOnFailure ) {
3150 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3151 if (RestoreOnFailure) {
3152 while (!Tokens.
empty()) {
3161std::optional<StringRef>
3162AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3165 return StringRef(
".amdgcn.next_free_vgpr");
3167 return StringRef(
".amdgcn.next_free_sgpr");
3169 return std::nullopt;
3173void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3174 auto SymbolName = getGprCountSymbolName(RegKind);
3175 assert(SymbolName &&
"initializing invalid register kind");
3181bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3182 unsigned DwordRegIndex,
3183 unsigned RegWidth) {
3188 auto SymbolName = getGprCountSymbolName(RegKind);
3193 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3197 return !
Error(getLoc(),
3198 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3202 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3204 if (OldCount <= NewMax)
3210std::unique_ptr<AMDGPUOperand>
3211AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3213 SMLoc StartLoc = Tok.getLoc();
3214 SMLoc EndLoc = Tok.getEndLoc();
3215 RegisterKind RegKind;
3217 unsigned RegNum, RegWidth;
3219 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3223 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3226 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3227 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3230ParseStatus AMDGPUAsmParser::parseImm(
OperandVector &Operands,
3234 if (isRegister() || isModifier())
3237 if (
Lit == LitModifier::None) {
3238 if (trySkipId(
"lit"))
3239 Lit = LitModifier::Lit;
3240 else if (trySkipId(
"lit64"))
3241 Lit = LitModifier::Lit64;
3243 if (
Lit != LitModifier::None) {
3246 ParseStatus S = parseImm(Operands, HasSP3AbsModifier,
Lit);
3255 const auto& NextTok = peekToken();
3258 bool Negate =
false;
3266 AMDGPUOperand::Modifiers Mods;
3274 StringRef Num = getTokenStr();
3277 APFloat RealVal(APFloat::IEEEdouble());
3278 auto roundMode = APFloat::rmNearestTiesToEven;
3279 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3282 RealVal.changeSign();
3285 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3286 AMDGPUOperand::ImmTyNone,
true));
3287 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3288 Op.setModifiers(Mods);
3297 if (HasSP3AbsModifier) {
3306 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3309 if (Parser.parseExpression(Expr))
3313 if (Expr->evaluateAsAbsolute(IntVal)) {
3314 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3315 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3316 Op.setModifiers(Mods);
3318 if (
Lit != LitModifier::None)
3320 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3329ParseStatus AMDGPUAsmParser::parseReg(
OperandVector &Operands) {
3333 if (
auto R = parseRegister()) {
3341ParseStatus AMDGPUAsmParser::parseRegOrImm(
OperandVector &Operands,
3343 ParseStatus Res = parseReg(Operands);
3348 return parseImm(Operands, HasSP3AbsMod,
Lit);
3352AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3355 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3361AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3366AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3367 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3371AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3372 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3389AMDGPUAsmParser::isModifier() {
3392 AsmToken NextToken[2];
3393 peekTokens(NextToken);
3395 return isOperandModifier(Tok, NextToken[0]) ||
3396 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3397 isOpcodeModifierWithVal(Tok, NextToken[0]);
3423AMDGPUAsmParser::parseSP3NegModifier() {
3425 AsmToken NextToken[2];
3426 peekTokens(NextToken);
3429 (isRegister(NextToken[0], NextToken[1]) ||
3431 isId(NextToken[0],
"abs"))) {
3440AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
3448 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3450 SP3Neg = parseSP3NegModifier();
3453 Neg = trySkipId(
"neg");
3455 return Error(Loc,
"expected register or immediate");
3459 Abs = trySkipId(
"abs");
3464 if (trySkipId(
"lit")) {
3465 Lit = LitModifier::Lit;
3468 }
else if (trySkipId(
"lit64")) {
3469 Lit = LitModifier::Lit64;
3472 if (!has64BitLiterals())
3473 return Error(Loc,
"lit64 is not supported on this GPU");
3479 return Error(Loc,
"expected register or immediate");
3483 Res = parseRegOrImm(Operands, SP3Abs,
Lit);
3485 Res = parseReg(Operands);
3488 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3492 if (
Lit != LitModifier::None && !Operands.
back()->isImm())
3493 Error(Loc,
"expected immediate with lit modifier");
3495 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3501 if (
Lit != LitModifier::None &&
3505 AMDGPUOperand::Modifiers Mods;
3506 Mods.Abs = Abs || SP3Abs;
3507 Mods.Neg = Neg || SP3Neg;
3510 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3511 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3513 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3514 Op.setModifiers(Mods);
3520AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
3522 bool Sext = trySkipId(
"sext");
3523 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3528 Res = parseRegOrImm(Operands);
3530 Res = parseReg(Operands);
3538 AMDGPUOperand::Modifiers Mods;
3541 if (Mods.hasIntModifiers()) {
3542 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
3544 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3545 Op.setModifiers(Mods);
3551ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
3552 return parseRegOrImmWithFPInputMods(Operands,
false);
3555ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
3556 return parseRegOrImmWithIntInputMods(Operands,
false);
3559ParseStatus AMDGPUAsmParser::parseVReg32OrOff(
OperandVector &Operands) {
3560 auto Loc = getLoc();
3561 if (trySkipId(
"off")) {
3562 Operands.
push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3563 AMDGPUOperand::ImmTyOff,
false));
3570 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3579unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3586 return Match_InvalidOperand;
3588 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3589 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3592 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3594 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3595 return Match_InvalidOperand;
3603 if (tryAnotherVOPDEncoding(Inst))
3604 return Match_InvalidOperand;
3606 return Match_Success;
3610 static const unsigned Variants[] = {
3620ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3621 if (isForcedDPP() && isForcedVOP3()) {
3625 if (getForcedEncodingSize() == 32) {
3630 if (isForcedVOP3()) {
3635 if (isForcedSDWA()) {
3641 if (isForcedDPP()) {
3649StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3650 if (isForcedDPP() && isForcedVOP3())
3653 if (getForcedEncodingSize() == 32)
3669AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3673 case AMDGPU::FLAT_SCR:
3675 case AMDGPU::VCC_LO:
3676 case AMDGPU::VCC_HI:
3683 return MCRegister();
3690bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3691 unsigned OpIdx)
const {
3745unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3751 case AMDGPU::V_LSHLREV_B64_e64:
3752 case AMDGPU::V_LSHLREV_B64_gfx10:
3753 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3754 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3755 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3756 case AMDGPU::V_LSHRREV_B64_e64:
3757 case AMDGPU::V_LSHRREV_B64_gfx10:
3758 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3759 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3760 case AMDGPU::V_ASHRREV_I64_e64:
3761 case AMDGPU::V_ASHRREV_I64_gfx10:
3762 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3763 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3764 case AMDGPU::V_LSHL_B64_e64:
3765 case AMDGPU::V_LSHR_B64_e64:
3766 case AMDGPU::V_ASHR_I64_e64:
3779 bool AddMandatoryLiterals =
false) {
3782 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3786 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3788 return {getNamedOperandIdx(Opcode, OpName::src0X),
3789 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3790 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3791 getNamedOperandIdx(Opcode, OpName::src0Y),
3792 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3793 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3798 return {getNamedOperandIdx(Opcode, OpName::src0),
3799 getNamedOperandIdx(Opcode, OpName::src1),
3800 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3803bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3806 return !isInlineConstant(Inst,
OpIdx);
3813 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3824 const unsigned Opcode = Inst.
getOpcode();
3825 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3828 if (!LaneSelOp.
isReg())
3831 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3834bool AMDGPUAsmParser::validateConstantBusLimitations(
3836 const unsigned Opcode = Inst.
getOpcode();
3837 const MCInstrDesc &
Desc = MII.
get(Opcode);
3838 MCRegister LastSGPR;
3839 unsigned ConstantBusUseCount = 0;
3840 unsigned NumLiterals = 0;
3841 unsigned LiteralSize;
3843 if (!(
Desc.TSFlags &
3858 SmallDenseSet<MCRegister> SGPRsUsed;
3859 MCRegister SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3861 SGPRsUsed.
insert(SGPRUsed);
3862 ++ConstantBusUseCount;
3867 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3869 for (
int OpIdx : OpIndices) {
3874 if (usesConstantBus(Inst,
OpIdx)) {
3883 if (SGPRsUsed.
insert(LastSGPR).second) {
3884 ++ConstantBusUseCount;
3904 if (NumLiterals == 0) {
3907 }
else if (LiteralSize !=
Size) {
3913 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3915 "invalid operand (violates constant bus restrictions)");
3922std::optional<unsigned>
3923AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3925 const unsigned Opcode = Inst.
getOpcode();
3931 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3932 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3940 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3941 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3942 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250;
3946 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3947 int I = getNamedOperandIdx(Opcode, OpName);
3951 int64_t
Imm =
Op.getImm();
3957 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3958 OpName::vsrc2Y, OpName::imm}) {
3959 int I = getNamedOperandIdx(Opcode, OpName);
3969 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3970 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3972 return InvalidCompOprIdx;
3975bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
3982 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand : Operands) {
3983 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
3984 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
3986 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
3990 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
3991 if (!InvalidCompOprIdx.has_value())
3994 auto CompOprIdx = *InvalidCompOprIdx;
3997 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3998 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3999 assert(ParsedIdx > 0 && ParsedIdx < Operands.size());
4001 auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
4002 if (CompOprIdx == VOPD::Component::DST) {
4004 Error(Loc,
"dst registers must be distinct");
4006 Error(Loc,
"one dst register must be even and the other odd");
4008 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
4009 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
4010 " operands must use different VGPR banks");
4018bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4020 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4021 if (!InvalidCompOprIdx.has_value())
4025 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4026 if (InvalidCompOprIdx.has_value()) {
4031 if (*InvalidCompOprIdx == VOPD::Component::DST)
4044bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4045 const unsigned Opcode = Inst.
getOpcode();
4060 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4061 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4062 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4063 int I = getNamedOperandIdx(Opcode, OpName);
4070 return !tryVOPD3(Inst);
4075bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4076 const unsigned Opcode = Inst.
getOpcode();
4081 return tryVOPD(Inst);
4082 return tryVOPD3(Inst);
4085bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4091 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4102bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4110 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4111 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4112 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4120 unsigned VDataSize = getRegOperandSize(
Desc, VDataIdx);
4121 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4126 bool IsPackedD16 =
false;
4130 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4131 IsPackedD16 = D16Idx >= 0;
4136 if ((VDataSize / 4) ==
DataSize + TFESize)
4141 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4143 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4145 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4149bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4158 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4160 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4162 ? AMDGPU::OpName::srsrc
4163 : AMDGPU::OpName::rsrc;
4164 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4165 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4166 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4170 assert(SrsrcIdx > VAddr0Idx);
4173 if (BaseOpcode->
BVH) {
4174 if (IsA16 == BaseOpcode->
A16)
4176 Error(IDLoc,
"image address size does not match a16");
4182 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4183 unsigned ActualAddrSize =
4184 IsNSA ? SrsrcIdx - VAddr0Idx : getRegOperandSize(
Desc, VAddr0Idx) / 4;
4186 unsigned ExpectedAddrSize =
4190 if (hasPartialNSAEncoding() &&
4193 int VAddrLastIdx = SrsrcIdx - 1;
4194 unsigned VAddrLastSize = getRegOperandSize(
Desc, VAddrLastIdx) / 4;
4196 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4199 if (ExpectedAddrSize > 12)
4200 ExpectedAddrSize = 16;
4205 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4209 if (ActualAddrSize == ExpectedAddrSize)
4212 Error(IDLoc,
"image address size does not match dim and a16");
4216bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4223 if (!
Desc.mayLoad() || !
Desc.mayStore())
4226 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4233 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4236bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4244 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4252 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4255bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4270 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4271 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4278bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4286 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4289 if (!BaseOpcode->
MSAA)
4292 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4298 return DimInfo->
MSAA;
4304 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4305 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4306 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4316bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4325 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4328 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4336 Error(getOperandLoc(Operands, Src0Idx),
"source operand must be a VGPR");
4340bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4345 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4348 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4351 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4358 Error(getOperandLoc(Operands, Src0Idx),
4359 "source operand must be either a VGPR or an inline constant");
4366bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4369 const MCInstrDesc &
Desc = MII.
get(Opcode);
4372 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4375 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4379 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4380 Error(getOperandLoc(Operands, Src2Idx),
4381 "inline constants are not allowed for this operand");
4388bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4396 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4397 if (BlgpIdx != -1) {
4398 if (
const MFMA_F8F6F4_Info *
Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4399 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4409 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4410 Error(getOperandLoc(Operands, Src0Idx),
4411 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4416 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4417 Error(getOperandLoc(Operands, Src1Idx),
4418 "wrong register tuple size for blgp value " + Twine(BLGP));
4426 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4430 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4434 MCRegister Src2Reg = Src2.
getReg();
4436 if (Src2Reg == DstReg)
4441 .getSizeInBits() <= 128)
4444 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4445 Error(getOperandLoc(Operands, Src2Idx),
4446 "source 2 operand must not partially overlap with dst");
4453bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4457 case V_DIV_SCALE_F32_gfx6_gfx7:
4458 case V_DIV_SCALE_F32_vi:
4459 case V_DIV_SCALE_F32_gfx10:
4460 case V_DIV_SCALE_F64_gfx6_gfx7:
4461 case V_DIV_SCALE_F64_vi:
4462 case V_DIV_SCALE_F64_gfx10:
4468 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4469 AMDGPU::OpName::src2_modifiers,
4470 AMDGPU::OpName::src2_modifiers}) {
4481bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4489 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4498bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4505 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4513 case AMDGPU::V_SUBREV_F32_e32:
4514 case AMDGPU::V_SUBREV_F32_e64:
4515 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4516 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4517 case AMDGPU::V_SUBREV_F32_e32_vi:
4518 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4519 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4520 case AMDGPU::V_SUBREV_F32_e64_vi:
4522 case AMDGPU::V_SUBREV_CO_U32_e32:
4523 case AMDGPU::V_SUBREV_CO_U32_e64:
4524 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4525 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4527 case AMDGPU::V_SUBBREV_U32_e32:
4528 case AMDGPU::V_SUBBREV_U32_e64:
4529 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4530 case AMDGPU::V_SUBBREV_U32_e32_vi:
4531 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4532 case AMDGPU::V_SUBBREV_U32_e64_vi:
4534 case AMDGPU::V_SUBREV_U32_e32:
4535 case AMDGPU::V_SUBREV_U32_e64:
4536 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4537 case AMDGPU::V_SUBREV_U32_e32_vi:
4538 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4539 case AMDGPU::V_SUBREV_U32_e64_vi:
4541 case AMDGPU::V_SUBREV_F16_e32:
4542 case AMDGPU::V_SUBREV_F16_e64:
4543 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4544 case AMDGPU::V_SUBREV_F16_e32_vi:
4545 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4546 case AMDGPU::V_SUBREV_F16_e64_vi:
4548 case AMDGPU::V_SUBREV_U16_e32:
4549 case AMDGPU::V_SUBREV_U16_e64:
4550 case AMDGPU::V_SUBREV_U16_e32_vi:
4551 case AMDGPU::V_SUBREV_U16_e64_vi:
4553 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4554 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4555 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4557 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4558 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4560 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4561 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4563 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4564 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4566 case AMDGPU::V_LSHRREV_B32_e32:
4567 case AMDGPU::V_LSHRREV_B32_e64:
4568 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4569 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4570 case AMDGPU::V_LSHRREV_B32_e32_vi:
4571 case AMDGPU::V_LSHRREV_B32_e64_vi:
4572 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4573 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4575 case AMDGPU::V_ASHRREV_I32_e32:
4576 case AMDGPU::V_ASHRREV_I32_e64:
4577 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4578 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4579 case AMDGPU::V_ASHRREV_I32_e32_vi:
4580 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4581 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4582 case AMDGPU::V_ASHRREV_I32_e64_vi:
4584 case AMDGPU::V_LSHLREV_B32_e32:
4585 case AMDGPU::V_LSHLREV_B32_e64:
4586 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4587 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4588 case AMDGPU::V_LSHLREV_B32_e32_vi:
4589 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4590 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4591 case AMDGPU::V_LSHLREV_B32_e64_vi:
4593 case AMDGPU::V_LSHLREV_B16_e32:
4594 case AMDGPU::V_LSHLREV_B16_e64:
4595 case AMDGPU::V_LSHLREV_B16_e32_vi:
4596 case AMDGPU::V_LSHLREV_B16_e64_vi:
4597 case AMDGPU::V_LSHLREV_B16_gfx10:
4599 case AMDGPU::V_LSHRREV_B16_e32:
4600 case AMDGPU::V_LSHRREV_B16_e64:
4601 case AMDGPU::V_LSHRREV_B16_e32_vi:
4602 case AMDGPU::V_LSHRREV_B16_e64_vi:
4603 case AMDGPU::V_LSHRREV_B16_gfx10:
4605 case AMDGPU::V_ASHRREV_I16_e32:
4606 case AMDGPU::V_ASHRREV_I16_e64:
4607 case AMDGPU::V_ASHRREV_I16_e32_vi:
4608 case AMDGPU::V_ASHRREV_I16_e64_vi:
4609 case AMDGPU::V_ASHRREV_I16_gfx10:
4611 case AMDGPU::V_LSHLREV_B64_e64:
4612 case AMDGPU::V_LSHLREV_B64_gfx10:
4613 case AMDGPU::V_LSHLREV_B64_vi:
4615 case AMDGPU::V_LSHRREV_B64_e64:
4616 case AMDGPU::V_LSHRREV_B64_gfx10:
4617 case AMDGPU::V_LSHRREV_B64_vi:
4619 case AMDGPU::V_ASHRREV_I64_e64:
4620 case AMDGPU::V_ASHRREV_I64_gfx10:
4621 case AMDGPU::V_ASHRREV_I64_vi:
4623 case AMDGPU::V_PK_LSHLREV_B16:
4624 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4625 case AMDGPU::V_PK_LSHLREV_B16_vi:
4627 case AMDGPU::V_PK_LSHRREV_B16:
4628 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4629 case AMDGPU::V_PK_LSHRREV_B16_vi:
4630 case AMDGPU::V_PK_ASHRREV_I16:
4631 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4632 case AMDGPU::V_PK_ASHRREV_I16_vi:
4639bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4641 using namespace SIInstrFlags;
4642 const unsigned Opcode = Inst.
getOpcode();
4643 const MCInstrDesc &
Desc = MII.
get(Opcode);
4648 if ((
Desc.TSFlags & Enc) == 0)
4651 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4652 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4656 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4659 Error(getOperandLoc(Operands, SrcIdx),
4660 "lds_direct is not supported on this GPU");
4665 Error(getOperandLoc(Operands, SrcIdx),
4666 "lds_direct cannot be used with this instruction");
4670 if (SrcName != OpName::src0) {
4671 Error(getOperandLoc(Operands, SrcIdx),
4672 "lds_direct may be used as src0 only");
4681SMLoc AMDGPUAsmParser::getFlatOffsetLoc(
const OperandVector &Operands)
const {
4682 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
4683 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4684 if (
Op.isFlatOffset())
4685 return Op.getStartLoc();
4690bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4693 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4699 return validateFlatOffset(Inst, Operands);
4702 return validateSMEMOffset(Inst, Operands);
4708 const unsigned OffsetSize = 24;
4709 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4710 Error(getFlatOffsetLoc(Operands),
4711 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4712 "-bit unsigned offset for buffer ops");
4716 const unsigned OffsetSize = 16;
4717 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4718 Error(getFlatOffsetLoc(Operands),
4719 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4726bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4733 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4737 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4738 Error(getFlatOffsetLoc(Operands),
4739 "flat offset modifier is not supported on this GPU");
4746 bool AllowNegative =
4749 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4750 Error(getFlatOffsetLoc(Operands),
4751 Twine(
"expected a ") +
4752 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4753 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4760SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(
const OperandVector &Operands)
const {
4762 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
4763 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
4764 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4765 return Op.getStartLoc();
4770bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4780 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4794 Error(getSMEMOffsetLoc(Operands),
4796 ?
"expected a 23-bit unsigned offset for buffer ops"
4797 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4798 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4799 :
"expected a 21-bit signed offset");
4804bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4807 const MCInstrDesc &
Desc = MII.
get(Opcode);
4811 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4812 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4814 const int OpIndices[] = { Src0Idx, Src1Idx };
4816 unsigned NumExprs = 0;
4817 unsigned NumLiterals = 0;
4820 for (
int OpIdx : OpIndices) {
4821 if (
OpIdx == -1)
break;
4827 std::optional<int64_t>
Imm;
4830 }
else if (MO.
isExpr()) {
4839 if (!
Imm.has_value()) {
4841 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4845 if (NumLiterals == 0 || LiteralValue !=
Value) {
4853 if (NumLiterals + NumExprs <= 1)
4856 Error(getOperandLoc(Operands, Src1Idx),
4857 "only one unique literal operand is allowed");
4861bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4864 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4874 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4875 if (OpSelIdx != -1) {
4879 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4880 if (OpSelHiIdx != -1) {
4889 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4899 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4900 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4901 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4902 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4904 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4905 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4911 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4913 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4923 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4924 if (Src2Idx != -1) {
4925 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4935bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4936 if (!hasTrue16Insts())
4938 const MCRegisterInfo *
MRI = getMRI();
4940 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4946 if (OpSelOpValue == 0)
4948 unsigned OpCount = 0;
4949 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4950 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4951 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4956 MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(
Op.getReg())) {
4958 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4959 if (OpSelOpIsHi != VGPRSuffixIsHi)
4968bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4969 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4982 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
4993 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4994 AMDGPU::OpName::src1_modifiers,
4995 AMDGPU::OpName::src2_modifiers};
4997 for (
unsigned i = 0; i < 3; ++i) {
5007bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
5010 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
5011 if (DppCtrlIdx >= 0) {
5018 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl, Operands);
5019 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5020 :
"DP ALU dpp only supports row_newbcast");
5025 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5026 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5029 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5031 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5034 Error(getOperandLoc(Operands, Src1Idx),
5035 "invalid operand for instruction");
5039 Error(getInstLoc(Operands),
5040 "src1 immediate operand invalid for instruction");
5050bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5051 return (
Reg == AMDGPU::VCC && isWave64()) ||
5052 (
Reg == AMDGPU::VCC_LO && isWave32());
5056bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5059 const MCInstrDesc &
Desc = MII.
get(Opcode);
5060 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5062 !HasMandatoryLiteral && !
isVOPD(Opcode))
5067 std::optional<unsigned> LiteralOpIdx;
5070 for (
int OpIdx : OpIndices) {
5080 std::optional<int64_t>
Imm;
5086 bool IsAnotherLiteral =
false;
5087 if (!
Imm.has_value()) {
5089 IsAnotherLiteral =
true;
5090 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5095 HasMandatoryLiteral);
5101 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5103 "invalid operand for instruction");
5107 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5114 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5115 !getFeatureBits()[FeatureVOP3Literal]) {
5117 "literal operands are not supported");
5121 if (LiteralOpIdx && IsAnotherLiteral) {
5122 Error(getLaterLoc(getOperandLoc(Operands,
OpIdx),
5123 getOperandLoc(Operands, *LiteralOpIdx)),
5124 "only one unique literal operand is allowed");
5128 if (IsAnotherLiteral)
5129 LiteralOpIdx =
OpIdx;
5152bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5160 ? AMDGPU::OpName::data0
5161 : AMDGPU::OpName::vdata;
5163 const MCRegisterInfo *
MRI = getMRI();
5169 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5173 auto FB = getFeatureBits();
5174 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5175 if (DataAreg < 0 || DstAreg < 0)
5177 return DstAreg == DataAreg;
5180 return DstAreg < 1 && DataAreg < 1;
5183bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5184 auto FB = getFeatureBits();
5185 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5189 const MCRegisterInfo *
MRI = getMRI();
5192 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5195 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5199 case AMDGPU::DS_LOAD_TR6_B96:
5200 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5204 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5205 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5209 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5210 if (VAddrIdx != -1) {
5212 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5213 if ((
Sub - AMDGPU::VGPR0) & 1)
5218 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5219 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5224 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5225 const MCRegisterClass &AGPR32 =
MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
5231 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5244SMLoc AMDGPUAsmParser::getBLGPLoc(
const OperandVector &Operands)
const {
5245 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
5246 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
5248 return Op.getStartLoc();
5253bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5256 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5259 SMLoc BLGPLoc = getBLGPLoc(Operands);
5262 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5263 auto FB = getFeatureBits();
5264 bool UsesNeg =
false;
5265 if (FB[AMDGPU::FeatureGFX940Insts]) {
5267 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5268 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5269 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5270 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5275 if (IsNeg == UsesNeg)
5279 UsesNeg ?
"invalid modifier: blgp is not supported"
5280 :
"invalid modifier: neg is not supported");
5285bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5291 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5292 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5293 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5294 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5297 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5300 if (
Reg == AMDGPU::SGPR_NULL)
5303 Error(getOperandLoc(Operands, Src0Idx),
"src0 must be null");
5307bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5313 return validateGWS(Inst, Operands);
5318 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5323 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS, Operands);
5324 Error(S,
"gds modifier is not supported on this GPU");
5332bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5334 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5338 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5339 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5342 const MCRegisterInfo *
MRI = getMRI();
5343 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5345 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5348 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5350 Error(getOperandLoc(Operands, Data0Pos),
"vgpr must be even aligned");
5357bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5360 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5361 AMDGPU::OpName::cpol);
5369 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5372 Error(S,
"scale_offset is not supported on this GPU");
5375 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5378 Error(S,
"nv is not supported on this GPU");
5383 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5386 Error(S,
"scale_offset is not supported for this instruction");
5390 return validateTHAndScopeBits(Inst, Operands, CPol);
5395 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5396 Error(S,
"cache policy is not supported for SMRD instructions");
5400 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5409 if (!(TSFlags & AllowSCCModifier)) {
5410 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5414 "scc modifier is not supported for this instruction on this GPU");
5425 :
"instruction must use glc");
5430 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5433 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5435 :
"instruction must not use glc");
5443bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5445 const unsigned CPol) {
5449 const unsigned Opcode = Inst.
getOpcode();
5450 const MCInstrDesc &TID = MII.
get(Opcode);
5453 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol, Operands);
5461 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5469 return PrintError(
"invalid th value for SMEM instruction");
5476 return PrintError(
"scope and th combination is not valid");
5482 return PrintError(
"invalid th value for atomic instructions");
5485 return PrintError(
"invalid th value for store instructions");
5488 return PrintError(
"invalid th value for load instructions");
5494bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5497 if (
Desc.mayStore() &&
5499 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE, Operands);
5500 if (Loc != getInstLoc(Operands)) {
5501 Error(Loc,
"TFE modifier has no meaning for store instructions");
5509bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5515 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5516 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5520 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5528 static const char *FmtNames[] = {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
5529 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
5532 Error(getOperandLoc(Operands, SrcIdx),
5533 "wrong register tuple size for " + Twine(FmtNames[Fmt]));
5537 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5538 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5541bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5543 if (!validateLdsDirect(Inst, Operands))
5545 if (!validateTrue16OpSel(Inst)) {
5546 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5547 "op_sel operand conflicts with 16-bit operand suffix");
5550 if (!validateSOPLiteral(Inst, Operands))
5552 if (!validateVOPLiteral(Inst, Operands)) {
5555 if (!validateConstantBusLimitations(Inst, Operands)) {
5558 if (!validateVOPD(Inst, Operands)) {
5561 if (!validateIntClampSupported(Inst)) {
5562 Error(getImmLoc(AMDGPUOperand::ImmTyClamp, Operands),
5563 "integer clamping is not supported on this GPU");
5566 if (!validateOpSel(Inst)) {
5567 Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands),
5568 "invalid op_sel operand");
5571 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5572 Error(getImmLoc(AMDGPUOperand::ImmTyNegLo, Operands),
5573 "invalid neg_lo operand");
5576 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5577 Error(getImmLoc(AMDGPUOperand::ImmTyNegHi, Operands),
5578 "invalid neg_hi operand");
5581 if (!validateDPP(Inst, Operands)) {
5585 if (!validateMIMGD16(Inst)) {
5586 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5587 "d16 modifier is not supported on this GPU");
5590 if (!validateMIMGDim(Inst, Operands)) {
5591 Error(IDLoc,
"missing dim operand");
5594 if (!validateTensorR128(Inst)) {
5595 Error(getImmLoc(AMDGPUOperand::ImmTyD16, Operands),
5596 "instruction must set modifier r128=0");
5599 if (!validateMIMGMSAA(Inst)) {
5600 Error(getImmLoc(AMDGPUOperand::ImmTyDim, Operands),
5601 "invalid dim; must be MSAA type");
5604 if (!validateMIMGDataSize(Inst, IDLoc)) {
5607 if (!validateMIMGAddrSize(Inst, IDLoc))
5609 if (!validateMIMGAtomicDMask(Inst)) {
5610 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5611 "invalid atomic image dmask");
5614 if (!validateMIMGGatherDMask(Inst)) {
5615 Error(getImmLoc(AMDGPUOperand::ImmTyDMask, Operands),
5616 "invalid image_gather dmask: only one bit must be set");
5619 if (!validateMovrels(Inst, Operands)) {
5622 if (!validateOffset(Inst, Operands)) {
5625 if (!validateMAIAccWrite(Inst, Operands)) {
5628 if (!validateMAISrc2(Inst, Operands)) {
5631 if (!validateMFMA(Inst, Operands)) {
5634 if (!validateCoherencyBits(Inst, Operands, IDLoc)) {
5638 if (!validateAGPRLdSt(Inst)) {
5639 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5640 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5641 :
"invalid register class: agpr loads and stores not supported on this GPU"
5645 if (!validateVGPRAlign(Inst)) {
5647 "invalid register class: vgpr tuples must be 64 bit aligned");
5650 if (!validateDS(Inst, Operands)) {
5654 if (!validateBLGP(Inst, Operands)) {
5658 if (!validateDivScale(Inst)) {
5659 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5662 if (!validateWaitCnt(Inst, Operands)) {
5665 if (!validateTFE(Inst, Operands)) {
5668 if (!validateWMMA(Inst, Operands)) {
5677 unsigned VariantID = 0);
5681 unsigned VariantID);
5683bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5688bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5689 const FeatureBitset &FBS,
5690 ArrayRef<unsigned> Variants) {
5691 for (
auto Variant : Variants) {
5699bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5701 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5704 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5709 getParser().clearPendingErrors();
5713 StringRef VariantName = getMatchedVariantName();
5714 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5717 " variant of this instruction is not supported"));
5721 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5722 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5724 FeatureBitset FeaturesWS32 = getFeatureBits();
5725 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5726 .
flip(AMDGPU::FeatureWavefrontSize32);
5727 FeatureBitset AvailableFeaturesWS32 =
5728 ComputeAvailableFeatures(FeaturesWS32);
5730 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5731 return Error(IDLoc,
"instruction requires wavesize=32");
5735 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5736 return Error(IDLoc,
"instruction not supported on this GPU");
5741 return Error(IDLoc,
"invalid instruction" + Suggestion);
5747 const auto &
Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5748 if (
Op.isToken() && InvalidOprIdx > 1) {
5749 const auto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5750 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5755bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5758 uint64_t &ErrorInfo,
5759 bool MatchingInlineAsm) {
5762 unsigned Result = Match_Success;
5763 for (
auto Variant : getMatchedVariants()) {
5765 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5770 if (R == Match_Success || R == Match_MissingFeature ||
5771 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5772 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5773 Result != Match_MissingFeature)) {
5777 if (R == Match_Success)
5781 if (Result == Match_Success) {
5782 if (!validateInstruction(Inst, IDLoc, Operands)) {
5789 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
5790 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5796 case Match_MissingFeature:
5800 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5802 case Match_InvalidOperand: {
5803 SMLoc ErrorLoc = IDLoc;
5804 if (ErrorInfo != ~0ULL) {
5805 if (ErrorInfo >= Operands.
size()) {
5806 return Error(IDLoc,
"too few operands for instruction");
5808 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5809 if (ErrorLoc == SMLoc())
5813 return Error(ErrorLoc,
"invalid VOPDY instruction");
5815 return Error(ErrorLoc,
"invalid operand for instruction");
5818 case Match_MnemonicFail:
5824bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5829 if (getParser().parseAbsoluteExpression(Tmp)) {
5832 Ret =
static_cast<uint32_t
>(Tmp);
5836bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5837 if (!getSTI().getTargetTriple().isAMDGCN())
5838 return TokError(
"directive only supported for amdgcn architecture");
5840 std::string TargetIDDirective;
5841 SMLoc TargetStart = getTok().getLoc();
5842 if (getParser().parseEscapedString(TargetIDDirective))
5845 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5846 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5847 return getParser().Error(TargetRange.
Start,
5848 (Twine(
".amdgcn_target directive's target id ") +
5849 Twine(TargetIDDirective) +
5850 Twine(
" does not match the specified target id ") +
5851 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5856bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5860bool AMDGPUAsmParser::calculateGPRBlocks(
5861 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5862 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5863 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5864 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5865 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5871 const MCExpr *
NumSGPRs = NextFreeSGPR;
5872 int64_t EvaluatedSGPRs;
5877 unsigned MaxAddressableNumSGPRs =
5880 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5881 !Features.
test(FeatureSGPRInitBug) &&
5882 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5883 return OutOfRangeError(SGPRRange);
5885 const MCExpr *ExtraSGPRs =
5889 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5890 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5891 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5892 return OutOfRangeError(SGPRRange);
5894 if (Features.
test(FeatureSGPRInitBug))
5901 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5902 unsigned Granule) ->
const MCExpr * {
5906 const MCExpr *AlignToGPR =
5908 const MCExpr *DivGPR =
5914 VGPRBlocks = GetNumGPRBlocks(
5923bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5924 if (!getSTI().getTargetTriple().isAMDGCN())
5925 return TokError(
"directive only supported for amdgcn architecture");
5928 return TokError(
"directive only supported for amdhsa OS");
5930 StringRef KernelName;
5931 if (getParser().parseIdentifier(KernelName))
5934 AMDGPU::MCKernelDescriptor KD =
5946 const MCExpr *NextFreeVGPR = ZeroExpr;
5948 const MCExpr *NamedBarCnt = ZeroExpr;
5949 uint64_t SharedVGPRCount = 0;
5950 uint64_t PreloadLength = 0;
5951 uint64_t PreloadOffset = 0;
5953 const MCExpr *NextFreeSGPR = ZeroExpr;
5956 unsigned ImpliedUserSGPRCount = 0;
5960 std::optional<unsigned> ExplicitUserSGPRCount;
5961 const MCExpr *ReserveVCC = OneExpr;
5962 const MCExpr *ReserveFlatScr = OneExpr;
5963 std::optional<bool> EnableWavefrontSize32;
5969 SMRange IDRange = getTok().getLocRange();
5970 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5973 if (
ID ==
".end_amdhsa_kernel")
5977 return TokError(
".amdhsa_ directives cannot be repeated");
5979 SMLoc ValStart = getLoc();
5980 const MCExpr *ExprVal;
5981 if (getParser().parseExpression(ExprVal))
5983 SMLoc ValEnd = getLoc();
5984 SMRange ValRange = SMRange(ValStart, ValEnd);
5987 uint64_t Val = IVal;
5988 bool EvaluatableExpr;
5989 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5991 return OutOfRangeError(ValRange);
5995#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5996 if (!isUInt<ENTRY##_WIDTH>(Val)) \
5997 return OutOfRangeError(RANGE); \
5998 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6003#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6005 return Error(IDRange.Start, "directive should have resolvable expression", \
6008 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6011 return OutOfRangeError(ValRange);
6013 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6016 return OutOfRangeError(ValRange);
6018 }
else if (
ID ==
".amdhsa_kernarg_size") {
6020 return OutOfRangeError(ValRange);
6022 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6024 ExplicitUserSGPRCount = Val;
6025 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6029 "directive is not supported with architected flat scratch",
6032 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6035 ImpliedUserSGPRCount += 4;
6036 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6039 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6042 return OutOfRangeError(ValRange);
6046 ImpliedUserSGPRCount += Val;
6047 PreloadLength = Val;
6049 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6052 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6055 return OutOfRangeError(ValRange);
6059 PreloadOffset = Val;
6060 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6063 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6066 ImpliedUserSGPRCount += 2;
6067 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6070 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6073 ImpliedUserSGPRCount += 2;
6074 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6077 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6080 ImpliedUserSGPRCount += 2;
6081 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6084 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6087 ImpliedUserSGPRCount += 2;
6088 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6091 "directive is not supported with architected flat scratch",
6095 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6098 ImpliedUserSGPRCount += 2;
6099 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6102 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6105 ImpliedUserSGPRCount += 1;
6106 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6108 if (IVersion.
Major < 10)
6109 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6110 EnableWavefrontSize32 = Val;
6112 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6114 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6116 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6118 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6121 "directive is not supported with architected flat scratch",
6124 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6126 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6130 "directive is not supported without architected flat scratch",
6133 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6135 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6137 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6139 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6141 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6143 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6145 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6147 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6149 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6151 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6153 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6155 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6156 VGPRRange = ValRange;
6157 NextFreeVGPR = ExprVal;
6158 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6159 SGPRRange = ValRange;
6160 NextFreeSGPR = ExprVal;
6161 }
else if (
ID ==
".amdhsa_accum_offset") {
6163 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6164 AccumOffset = ExprVal;
6165 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6167 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6168 NamedBarCnt = ExprVal;
6169 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6171 return OutOfRangeError(ValRange);
6172 ReserveVCC = ExprVal;
6173 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6174 if (IVersion.
Major < 7)
6175 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6178 "directive is not supported with architected flat scratch",
6181 return OutOfRangeError(ValRange);
6182 ReserveFlatScr = ExprVal;
6183 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6184 if (IVersion.
Major < 8)
6185 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6187 return OutOfRangeError(ValRange);
6188 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6189 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6191 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6193 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6195 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6197 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6199 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6201 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6203 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6205 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6207 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6208 if (IVersion.
Major >= 12)
6209 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6211 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6213 }
else if (
ID ==
".amdhsa_ieee_mode") {
6214 if (IVersion.
Major >= 12)
6215 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6217 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6219 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6220 if (IVersion.
Major < 9)
6221 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6223 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6225 }
else if (
ID ==
".amdhsa_tg_split") {
6227 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6230 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6233 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6235 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6237 }
else if (
ID ==
".amdhsa_memory_ordered") {
6238 if (IVersion.
Major < 10)
6239 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6241 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6243 }
else if (
ID ==
".amdhsa_forward_progress") {
6244 if (IVersion.
Major < 10)
6245 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6247 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6249 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6251 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6252 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6254 SharedVGPRCount = Val;
6256 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6258 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6259 if (IVersion.
Major < 11)
6260 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6261 if (IVersion.
Major == 11) {
6263 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6267 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6270 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6273 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6275 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6277 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6279 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6282 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6284 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6286 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6288 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6290 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6292 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6294 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6296 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6298 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6300 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6301 if (IVersion.
Major < 12)
6302 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6304 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6307 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6310#undef PARSE_BITS_ENTRY
6313 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6314 return TokError(
".amdhsa_next_free_vgpr directive is required");
6316 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6317 return TokError(
".amdhsa_next_free_sgpr directive is required");
6319 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6324 if (PreloadLength) {
6330 const MCExpr *VGPRBlocks;
6331 const MCExpr *SGPRBlocks;
6332 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6333 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6334 EnableWavefrontSize32, NextFreeVGPR,
6335 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6339 int64_t EvaluatedVGPRBlocks;
6340 bool VGPRBlocksEvaluatable =
6341 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6342 if (VGPRBlocksEvaluatable &&
6344 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6345 return OutOfRangeError(VGPRRange);
6349 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6350 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6352 int64_t EvaluatedSGPRBlocks;
6353 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6355 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6356 return OutOfRangeError(SGPRRange);
6359 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6360 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6362 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6363 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6364 "enabled user SGPRs");
6368 return TokError(
"too many user SGPRs enabled");
6372 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6373 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6377 return TokError(
"too many user SGPRs enabled");
6381 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6382 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6387 return TokError(
"Kernarg size should be resolvable");
6388 uint64_t kernarg_size = IVal;
6389 if (PreloadLength && kernarg_size &&
6390 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6391 return TokError(
"Kernarg preload length + offset is larger than the "
6392 "kernarg segment size");
6395 if (!Seen.
contains(
".amdhsa_accum_offset"))
6396 return TokError(
".amdhsa_accum_offset directive is required");
6397 int64_t EvaluatedAccum;
6398 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6399 uint64_t UEvaluatedAccum = EvaluatedAccum;
6400 if (AccumEvaluatable &&
6401 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6402 return TokError(
"accum_offset should be in range [4..256] in "
6405 int64_t EvaluatedNumVGPR;
6406 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6409 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6410 return TokError(
"accum_offset exceeds total VGPR allocation");
6416 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6417 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6423 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6424 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6427 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6429 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6430 return TokError(
"shared_vgpr_count directive not valid on "
6431 "wavefront size 32");
6434 if (VGPRBlocksEvaluatable &&
6435 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6437 return TokError(
"shared_vgpr_count*2 + "
6438 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6443 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6444 NextFreeVGPR, NextFreeSGPR,
6445 ReserveVCC, ReserveFlatScr);
6449bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6451 if (ParseAsAbsoluteExpression(
Version))
6454 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6458bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6459 AMDGPUMCKernelCodeT &
C) {
6462 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6463 Parser.eatToEndOfStatement();
6467 SmallString<40> ErrStr;
6468 raw_svector_ostream Err(ErrStr);
6469 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6470 return TokError(Err.
str());
6474 if (
ID ==
"enable_wavefront_size32") {
6477 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6479 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6482 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6486 if (
ID ==
"wavefront_size") {
6487 if (
C.wavefront_size == 5) {
6489 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6491 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6492 }
else if (
C.wavefront_size == 6) {
6494 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6501bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6502 AMDGPUMCKernelCodeT KernelCode;
6511 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6514 if (
ID ==
".end_amd_kernel_code_t")
6517 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6522 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6527bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6528 StringRef KernelName;
6529 if (!parseId(KernelName,
"expected symbol name"))
6532 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6539bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6540 if (!getSTI().getTargetTriple().isAMDGCN()) {
6541 return Error(getLoc(),
6542 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6546 auto TargetIDDirective = getLexer().getTok().getStringContents();
6547 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6548 return Error(getParser().getTok().getLoc(),
"target id must match options");
6550 getTargetStreamer().EmitISAVersion();
6556bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6559 std::string HSAMetadataString;
6564 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6565 return Error(getLoc(),
"invalid HSA metadata");
6572bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6573 const char *AssemblerDirectiveEnd,
6574 std::string &CollectString) {
6576 raw_string_ostream CollectStream(CollectString);
6578 getLexer().setSkipSpace(
false);
6580 bool FoundEnd =
false;
6583 CollectStream << getTokenStr();
6587 if (trySkipId(AssemblerDirectiveEnd)) {
6592 CollectStream << Parser.parseStringToEndOfStatement()
6593 <<
getContext().getAsmInfo()->getSeparatorString();
6595 Parser.eatToEndOfStatement();
6598 getLexer().setSkipSpace(
true);
6601 return TokError(Twine(
"expected directive ") +
6602 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6609bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6615 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6616 if (!PALMetadata->setFromString(
String))
6617 return Error(getLoc(),
"invalid PAL metadata");
6622bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6624 return Error(getLoc(),
6626 "not available on non-amdpal OSes")).str());
6629 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6630 PALMetadata->setLegacy();
6633 if (ParseAsAbsoluteExpression(
Key)) {
6634 return TokError(Twine(
"invalid value in ") +
6638 return TokError(Twine(
"expected an even number of values in ") +
6641 if (ParseAsAbsoluteExpression(
Value)) {
6642 return TokError(Twine(
"invalid value in ") +
6645 PALMetadata->setRegister(
Key,
Value);
6654bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6655 if (getParser().checkForValidSection())
6659 SMLoc NameLoc = getLoc();
6660 if (getParser().parseIdentifier(Name))
6661 return TokError(
"expected identifier in directive");
6664 if (getParser().parseComma())
6670 SMLoc SizeLoc = getLoc();
6671 if (getParser().parseAbsoluteExpression(
Size))
6674 return Error(SizeLoc,
"size must be non-negative");
6675 if (
Size > LocalMemorySize)
6676 return Error(SizeLoc,
"size is too large");
6678 int64_t Alignment = 4;
6680 SMLoc AlignLoc = getLoc();
6681 if (getParser().parseAbsoluteExpression(Alignment))
6684 return Error(AlignLoc,
"alignment must be a power of two");
6689 if (Alignment >= 1u << 31)
6690 return Error(AlignLoc,
"alignment is too large");
6696 Symbol->redefineIfPossible();
6697 if (!
Symbol->isUndefined())
6698 return Error(NameLoc,
"invalid symbol redefinition");
6700 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6704bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6705 StringRef IDVal = DirectiveID.
getString();
6708 if (IDVal ==
".amdhsa_kernel")
6709 return ParseDirectiveAMDHSAKernel();
6711 if (IDVal ==
".amdhsa_code_object_version")
6712 return ParseDirectiveAMDHSACodeObjectVersion();
6716 return ParseDirectiveHSAMetadata();
6718 if (IDVal ==
".amd_kernel_code_t")
6719 return ParseDirectiveAMDKernelCodeT();
6721 if (IDVal ==
".amdgpu_hsa_kernel")
6722 return ParseDirectiveAMDGPUHsaKernel();
6724 if (IDVal ==
".amd_amdgpu_isa")
6725 return ParseDirectiveISAVersion();
6729 Twine(
" directive is "
6730 "not available on non-amdhsa OSes"))
6735 if (IDVal ==
".amdgcn_target")
6736 return ParseDirectiveAMDGCNTarget();
6738 if (IDVal ==
".amdgpu_lds")
6739 return ParseDirectiveAMDGPULDS();
6742 return ParseDirectivePALMetadataBegin();
6745 return ParseDirectivePALMetadata();
6750bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
6752 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
6756 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
6757 return hasSGPR104_SGPR105();
6760 case SRC_SHARED_BASE_LO:
6761 case SRC_SHARED_BASE:
6762 case SRC_SHARED_LIMIT_LO:
6763 case SRC_SHARED_LIMIT:
6764 case SRC_PRIVATE_BASE_LO:
6765 case SRC_PRIVATE_BASE:
6766 case SRC_PRIVATE_LIMIT_LO:
6767 case SRC_PRIVATE_LIMIT:
6769 case SRC_FLAT_SCRATCH_BASE_LO:
6770 case SRC_FLAT_SCRATCH_BASE_HI:
6771 return hasGloballyAddressableScratch();
6772 case SRC_POPS_EXITING_WAVE_ID:
6784 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6813 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
6814 return hasSGPR102_SGPR103();
6819ParseStatus AMDGPUAsmParser::parseOperand(
OperandVector &Operands,
6822 ParseStatus Res = parseVOPD(Operands);
6827 Res = MatchOperandParserImpl(Operands, Mnemonic);
6839 SMLoc LBraceLoc = getLoc();
6844 auto Loc = getLoc();
6845 Res = parseReg(Operands);
6847 Error(Loc,
"expected a register");
6851 RBraceLoc = getLoc();
6856 "expected a comma or a closing square bracket"))
6860 if (Operands.
size() - Prefix > 1) {
6862 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6863 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6869 return parseRegOrImm(Operands);
6872StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6874 setForcedEncodingSize(0);
6875 setForcedDPP(
false);
6876 setForcedSDWA(
false);
6878 if (
Name.consume_back(
"_e64_dpp")) {
6880 setForcedEncodingSize(64);
6883 if (
Name.consume_back(
"_e64")) {
6884 setForcedEncodingSize(64);
6887 if (
Name.consume_back(
"_e32")) {
6888 setForcedEncodingSize(32);
6891 if (
Name.consume_back(
"_dpp")) {
6895 if (
Name.consume_back(
"_sdwa")) {
6896 setForcedSDWA(
true);
6904 unsigned VariantID);
6910 Name = parseMnemonicSuffix(Name);
6916 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6918 bool IsMIMG = Name.starts_with(
"image_");
6921 OperandMode
Mode = OperandMode_Default;
6923 Mode = OperandMode_NSA;
6927 checkUnsupportedInstruction(Name, NameLoc);
6928 if (!Parser.hasPendingError()) {
6931 :
"not a valid operand.";
6932 Error(getLoc(), Msg);
6951ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6954 if (!trySkipId(Name))
6957 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6961ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6970ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6971 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6972 std::function<
bool(int64_t &)> ConvertResult) {
6976 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
6980 if (ConvertResult && !ConvertResult(
Value)) {
6981 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
6984 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6988ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6989 const char *Prefix,
OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6990 bool (*ConvertResult)(int64_t &)) {
6999 const unsigned MaxSize = 4;
7003 for (
int I = 0; ; ++
I) {
7005 SMLoc Loc = getLoc();
7009 if (
Op != 0 &&
Op != 1)
7010 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7017 if (
I + 1 == MaxSize)
7018 return Error(getLoc(),
"expected a closing square bracket");
7024 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7028ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7030 AMDGPUOperand::ImmTy ImmTy) {
7034 if (trySkipId(Name)) {
7036 }
else if (trySkipId(
"no", Name)) {
7043 return Error(S,
"r128 modifier is not supported on this GPU");
7044 if (Name ==
"a16" && !
hasA16())
7045 return Error(S,
"a16 modifier is not supported on this GPU");
7047 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7048 ImmTy = AMDGPUOperand::ImmTyR128A16;
7050 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7054unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7055 bool &Disabling)
const {
7056 Disabling =
Id.consume_front(
"no");
7059 return StringSwitch<unsigned>(Id)
7066 return StringSwitch<unsigned>(Id)
7074ParseStatus AMDGPUAsmParser::parseCPol(
OperandVector &Operands) {
7076 SMLoc StringLoc = getLoc();
7078 int64_t CPolVal = 0;
7087 ResTH = parseTH(Operands, TH);
7098 ResScope = parseScope(Operands, Scope);
7111 if (trySkipId(
"nv")) {
7115 }
else if (trySkipId(
"no",
"nv")) {
7122 if (trySkipId(
"scale_offset")) {
7126 }
else if (trySkipId(
"no",
"scale_offset")) {
7139 Operands.
push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7140 AMDGPUOperand::ImmTyCPol));
7144 StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).
getToken();
7145 SMLoc OpLoc = getLoc();
7146 unsigned Enabled = 0, Seen = 0;
7150 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7157 return Error(S,
"dlc modifier is not supported on this GPU");
7160 return Error(S,
"scc modifier is not supported on this GPU");
7163 return Error(S,
"duplicate cache policy modifier");
7175 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7179ParseStatus AMDGPUAsmParser::parseScope(
OperandVector &Operands,
7184 ParseStatus Res = parseStringOrIntWithPrefix(
7185 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7194ParseStatus AMDGPUAsmParser::parseTH(
OperandVector &Operands, int64_t &TH) {
7199 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7203 if (
Value ==
"TH_DEFAULT")
7205 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7206 Value ==
"TH_LOAD_NT_WB") {
7207 return Error(StringLoc,
"invalid th value");
7208 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7210 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7212 }
else if (
Value.consume_front(
"TH_STORE_")) {
7215 return Error(StringLoc,
"invalid th value");
7218 if (
Value ==
"BYPASS")
7223 TH |= StringSwitch<int64_t>(
Value)
7233 .Default(0xffffffff);
7235 TH |= StringSwitch<int64_t>(
Value)
7246 .Default(0xffffffff);
7249 if (TH == 0xffffffff)
7250 return Error(StringLoc,
"invalid th value");
7257 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7258 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7259 std::optional<unsigned> InsertAt = std::nullopt) {
7260 auto i = OptionalIdx.find(ImmT);
7261 if (i != OptionalIdx.end()) {
7262 unsigned Idx = i->second;
7263 const AMDGPUOperand &
Op =
7264 static_cast<const AMDGPUOperand &
>(*Operands[Idx]);
7268 Op.addImmOperands(Inst, 1);
7270 if (InsertAt.has_value())
7277ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7283 StringLoc = getLoc();
7288ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7289 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7294 SMLoc StringLoc = getLoc();
7298 Value = getTokenStr();
7302 if (
Value == Ids[IntVal])
7307 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7308 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7313ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7314 OperandVector &Operands, StringRef Name, ArrayRef<const char *> Ids,
7315 AMDGPUOperand::ImmTy
Type) {
7319 ParseStatus Res = parseStringOrIntWithPrefix(Operands, Name, Ids, IntVal);
7321 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7330bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7334 SMLoc Loc = getLoc();
7336 auto Res = parseIntWithPrefix(Pref, Val);
7342 if (Val < 0 || Val > MaxVal) {
7343 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7351ParseStatus AMDGPUAsmParser::tryParseIndexKey(
OperandVector &Operands,
7352 AMDGPUOperand::ImmTy ImmTy) {
7353 const char *Pref =
"index_key";
7355 SMLoc Loc = getLoc();
7356 auto Res = parseIntWithPrefix(Pref, ImmVal);
7360 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7361 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7362 (ImmVal < 0 || ImmVal > 1))
7363 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7365 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7366 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7368 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7372ParseStatus AMDGPUAsmParser::parseIndexKey8bit(
OperandVector &Operands) {
7373 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7376ParseStatus AMDGPUAsmParser::parseIndexKey16bit(
OperandVector &Operands) {
7377 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7380ParseStatus AMDGPUAsmParser::parseIndexKey32bit(
OperandVector &Operands) {
7381 return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7384ParseStatus AMDGPUAsmParser::tryParseMatrixFMT(
OperandVector &Operands,
7386 AMDGPUOperand::ImmTy
Type) {
7387 return parseStringOrIntWithPrefix(Operands, Name,
7388 {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
7389 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
7394ParseStatus AMDGPUAsmParser::parseMatrixAFMT(
OperandVector &Operands) {
7395 return tryParseMatrixFMT(Operands,
"matrix_a_fmt",
7396 AMDGPUOperand::ImmTyMatrixAFMT);
7399ParseStatus AMDGPUAsmParser::parseMatrixBFMT(
OperandVector &Operands) {
7400 return tryParseMatrixFMT(Operands,
"matrix_b_fmt",
7401 AMDGPUOperand::ImmTyMatrixBFMT);
7404ParseStatus AMDGPUAsmParser::tryParseMatrixScale(
OperandVector &Operands,
7406 AMDGPUOperand::ImmTy
Type) {
7407 return parseStringOrIntWithPrefix(
7408 Operands, Name, {
"MATRIX_SCALE_ROW0",
"MATRIX_SCALE_ROW1"},
Type);
7411ParseStatus AMDGPUAsmParser::parseMatrixAScale(
OperandVector &Operands) {
7412 return tryParseMatrixScale(Operands,
"matrix_a_scale",
7413 AMDGPUOperand::ImmTyMatrixAScale);
7416ParseStatus AMDGPUAsmParser::parseMatrixBScale(
OperandVector &Operands) {
7417 return tryParseMatrixScale(Operands,
"matrix_b_scale",
7418 AMDGPUOperand::ImmTyMatrixBScale);
7421ParseStatus AMDGPUAsmParser::tryParseMatrixScaleFmt(
OperandVector &Operands,
7423 AMDGPUOperand::ImmTy
Type) {
7424 return parseStringOrIntWithPrefix(
7426 {
"MATRIX_SCALE_FMT_E8",
"MATRIX_SCALE_FMT_E5M3",
"MATRIX_SCALE_FMT_E4M3"},
7430ParseStatus AMDGPUAsmParser::parseMatrixAScaleFmt(
OperandVector &Operands) {
7431 return tryParseMatrixScaleFmt(Operands,
"matrix_a_scale_fmt",
7432 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7435ParseStatus AMDGPUAsmParser::parseMatrixBScaleFmt(
OperandVector &Operands) {
7436 return tryParseMatrixScaleFmt(Operands,
"matrix_b_scale_fmt",
7437 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7442ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7443 using namespace llvm::AMDGPU::MTBUFFormat;
7449 for (
int I = 0;
I < 2; ++
I) {
7450 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7453 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7458 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7464 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7467 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7468 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7474ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7475 using namespace llvm::AMDGPU::MTBUFFormat;
7479 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7482 if (Fmt == UFMT_UNDEF)
7489bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7491 StringRef FormatStr,
7493 using namespace llvm::AMDGPU::MTBUFFormat;
7497 if (
Format != DFMT_UNDEF) {
7503 if (
Format != NFMT_UNDEF) {
7508 Error(Loc,
"unsupported format");
7512ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7515 using namespace llvm::AMDGPU::MTBUFFormat;
7519 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7524 SMLoc Loc = getLoc();
7525 if (!parseId(Str,
"expected a format string") ||
7526 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7528 if (Dfmt == DFMT_UNDEF)
7529 return Error(Loc,
"duplicate numeric format");
7530 if (Nfmt == NFMT_UNDEF)
7531 return Error(Loc,
"duplicate data format");
7534 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7535 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7539 if (Ufmt == UFMT_UNDEF)
7540 return Error(FormatLoc,
"unsupported format");
7549ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7552 using namespace llvm::AMDGPU::MTBUFFormat;
7555 if (Id == UFMT_UNDEF)
7559 return Error(Loc,
"unified format is not supported on this GPU");
7565ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7566 using namespace llvm::AMDGPU::MTBUFFormat;
7567 SMLoc Loc = getLoc();
7572 return Error(Loc,
"out of range format");
7577ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7578 using namespace llvm::AMDGPU::MTBUFFormat;
7584 StringRef FormatStr;
7585 SMLoc Loc = getLoc();
7586 if (!parseId(FormatStr,
"expected a format string"))
7589 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7591 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7601 return parseNumericFormat(
Format);
7604ParseStatus AMDGPUAsmParser::parseFORMAT(
OperandVector &Operands) {
7605 using namespace llvm::AMDGPU::MTBUFFormat;
7609 SMLoc Loc = getLoc();
7619 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7631 Res = parseRegOrImm(Operands);
7638 Res = parseSymbolicOrNumericFormat(
Format);
7643 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
Size - 2]);
7644 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7651 return Error(getLoc(),
"duplicate format");
7655ParseStatus AMDGPUAsmParser::parseFlatOffset(
OperandVector &Operands) {
7657 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
7659 Res = parseIntWithPrefix(
"inst_offset", Operands,
7660 AMDGPUOperand::ImmTyInstOffset);
7665ParseStatus AMDGPUAsmParser::parseR128A16(
OperandVector &Operands) {
7667 parseNamedBit(
"r128", Operands, AMDGPUOperand::ImmTyR128A16);
7669 Res = parseNamedBit(
"a16", Operands, AMDGPUOperand::ImmTyA16);
7673ParseStatus AMDGPUAsmParser::parseBLGP(
OperandVector &Operands) {
7675 parseIntWithPrefix(
"blgp", Operands, AMDGPUOperand::ImmTyBLGP);
7678 parseOperandArrayWithPrefix(
"neg", Operands, AMDGPUOperand::ImmTyBLGP);
7687void AMDGPUAsmParser::cvtExp(MCInst &Inst,
const OperandVector &Operands) {
7688 OptionalImmIndexMap OptionalIdx;
7690 unsigned OperandIdx[4];
7691 unsigned EnMask = 0;
7694 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
7695 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
7700 OperandIdx[SrcIdx] = Inst.
size();
7701 Op.addRegOperands(Inst, 1);
7708 OperandIdx[SrcIdx] = Inst.
size();
7714 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7715 Op.addImmOperands(Inst, 1);
7719 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7723 OptionalIdx[
Op.getImmTy()] = i;
7729 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7736 for (
auto i = 0; i < SrcIdx; ++i) {
7738 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7763 IntVal =
encode(ISA, IntVal, CntVal);
7764 if (CntVal !=
decode(ISA, IntVal)) {
7766 IntVal =
encode(ISA, IntVal, -1);
7774bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7776 SMLoc CntLoc = getLoc();
7777 StringRef CntName = getTokenStr();
7784 SMLoc ValLoc = getLoc();
7793 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7795 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7797 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7800 Error(CntLoc,
"invalid counter name " + CntName);
7805 Error(ValLoc,
"too large value for " + CntName);
7814 Error(getLoc(),
"expected a counter name");
7822ParseStatus AMDGPUAsmParser::parseSWaitCnt(
OperandVector &Operands) {
7829 if (!parseCnt(Waitcnt))
7837 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7841bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7842 SMLoc FieldLoc = getLoc();
7843 StringRef FieldName = getTokenStr();
7848 SMLoc ValueLoc = getLoc();
7855 if (FieldName ==
"instid0") {
7857 }
else if (FieldName ==
"instskip") {
7859 }
else if (FieldName ==
"instid1") {
7862 Error(FieldLoc,
"invalid field name " + FieldName);
7881 .Case(
"VALU_DEP_1", 1)
7882 .Case(
"VALU_DEP_2", 2)
7883 .Case(
"VALU_DEP_3", 3)
7884 .Case(
"VALU_DEP_4", 4)
7885 .Case(
"TRANS32_DEP_1", 5)
7886 .Case(
"TRANS32_DEP_2", 6)
7887 .Case(
"TRANS32_DEP_3", 7)
7888 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7889 .Case(
"SALU_CYCLE_1", 9)
7890 .Case(
"SALU_CYCLE_2", 10)
7891 .Case(
"SALU_CYCLE_3", 11)
7899 Delay |=
Value << Shift;
7903ParseStatus AMDGPUAsmParser::parseSDelayALU(
OperandVector &Operands) {
7909 if (!parseDelay(Delay))
7917 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7922AMDGPUOperand::isSWaitCnt()
const {
7926bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7932void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7933 StringRef DepCtrName) {
7936 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7939 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7942 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7945 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7952bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7954 using namespace llvm::AMDGPU::DepCtr;
7956 SMLoc DepCtrLoc = getLoc();
7957 StringRef DepCtrName = getTokenStr();
7967 unsigned PrevOprMask = UsedOprMask;
7968 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7971 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7980 Error(getLoc(),
"expected a counter name");
7985 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7986 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7990ParseStatus AMDGPUAsmParser::parseDepCtr(
OperandVector &Operands) {
7991 using namespace llvm::AMDGPU::DepCtr;
7994 SMLoc Loc = getLoc();
7997 unsigned UsedOprMask = 0;
7999 if (!parseDepCtr(DepCtr, UsedOprMask))
8007 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8011bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8017ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8019 OperandInfoTy &Width) {
8020 using namespace llvm::AMDGPU::Hwreg;
8026 HwReg.Loc = getLoc();
8029 HwReg.IsSymbolic =
true;
8031 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8039 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8049 Width.Loc = getLoc();
8057ParseStatus AMDGPUAsmParser::parseHwreg(
OperandVector &Operands) {
8058 using namespace llvm::AMDGPU::Hwreg;
8061 SMLoc Loc = getLoc();
8063 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8065 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8066 HwregOffset::Default);
8067 struct : StructuredOpField {
8068 using StructuredOpField::StructuredOpField;
8069 bool validate(AMDGPUAsmParser &Parser)
const override {
8071 return Error(Parser,
"only values from 1 to 32 are legal");
8074 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8075 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8078 Res = parseHwregFunc(HwReg,
Offset, Width);
8081 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8083 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8087 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8094 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8096 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8100bool AMDGPUOperand::isHwreg()
const {
8101 return isImmTy(ImmTyHwreg);
8109AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8111 OperandInfoTy &Stream) {
8112 using namespace llvm::AMDGPU::SendMsg;
8117 Msg.IsSymbolic =
true;
8119 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8124 Op.IsDefined =
true;
8127 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8130 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8135 Stream.IsDefined =
true;
8136 Stream.Loc = getLoc();
8146AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8147 const OperandInfoTy &
Op,
8148 const OperandInfoTy &Stream) {
8149 using namespace llvm::AMDGPU::SendMsg;
8154 bool Strict = Msg.IsSymbolic;
8158 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8163 Error(Msg.Loc,
"invalid message id");
8169 Error(
Op.Loc,
"message does not support operations");
8171 Error(Msg.Loc,
"missing message operation");
8177 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8179 Error(
Op.Loc,
"invalid operation id");
8184 Error(Stream.Loc,
"message operation does not support streams");
8188 Error(Stream.Loc,
"invalid message stream id");
8194ParseStatus AMDGPUAsmParser::parseSendMsg(
OperandVector &Operands) {
8195 using namespace llvm::AMDGPU::SendMsg;
8198 SMLoc Loc = getLoc();
8202 OperandInfoTy
Op(OP_NONE_);
8203 OperandInfoTy Stream(STREAM_ID_NONE_);
8204 if (parseSendMsgBody(Msg,
Op, Stream) &&
8205 validateSendMsg(Msg,
Op, Stream)) {
8210 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8212 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8217 Operands.
push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8221bool AMDGPUOperand::isSendMsg()
const {
8222 return isImmTy(ImmTySendMsg);
8229ParseStatus AMDGPUAsmParser::parseInterpSlot(
OperandVector &Operands) {
8236 int Slot = StringSwitch<int>(Str)
8243 return Error(S,
"invalid interpolation slot");
8245 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8246 AMDGPUOperand::ImmTyInterpSlot));
8250ParseStatus AMDGPUAsmParser::parseInterpAttr(
OperandVector &Operands) {
8257 if (!Str.starts_with(
"attr"))
8258 return Error(S,
"invalid interpolation attribute");
8260 StringRef Chan = Str.take_back(2);
8261 int AttrChan = StringSwitch<int>(Chan)
8268 return Error(S,
"invalid or missing interpolation attribute channel");
8270 Str = Str.drop_back(2).drop_front(4);
8273 if (Str.getAsInteger(10, Attr))
8274 return Error(S,
"invalid or missing interpolation attribute number");
8277 return Error(S,
"out of bounds interpolation attribute number");
8281 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8282 AMDGPUOperand::ImmTyInterpAttr));
8283 Operands.
push_back(AMDGPUOperand::CreateImm(
8284 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8292ParseStatus AMDGPUAsmParser::parseExpTgt(
OperandVector &Operands) {
8293 using namespace llvm::AMDGPU::Exp;
8303 return Error(S, (Id == ET_INVALID)
8304 ?
"invalid exp target"
8305 :
"exp target is not supported on this GPU");
8307 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8308 AMDGPUOperand::ImmTyExpTgt));
8317AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8322AMDGPUAsmParser::isId(
const StringRef Id)
const {
8328 return getTokenKind() ==
Kind;
8331StringRef AMDGPUAsmParser::getId()
const {
8336AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8345AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8347 StringRef Tok = getTokenStr();
8358 if (isId(Id) && peekToken().is(Kind)) {
8368 if (isToken(Kind)) {
8377 const StringRef ErrMsg) {
8378 if (!trySkipToken(Kind)) {
8379 Error(getLoc(), ErrMsg);
8386AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8390 if (Parser.parseExpression(Expr))
8393 if (Expr->evaluateAsAbsolute(
Imm))
8396 if (Expected.empty()) {
8397 Error(S,
"expected absolute expression");
8399 Error(S, Twine(
"expected ", Expected) +
8400 Twine(
" or an absolute expression"));
8410 if (Parser.parseExpression(Expr))
8414 if (Expr->evaluateAsAbsolute(IntVal)) {
8415 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8417 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8423AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8425 Val =
getToken().getStringContents();
8429 Error(getLoc(), ErrMsg);
8434AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8436 Val = getTokenStr();
8440 if (!ErrMsg.
empty())
8441 Error(getLoc(), ErrMsg);
8446AMDGPUAsmParser::getToken()
const {
8447 return Parser.getTok();
8450AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8453 : getLexer().peekTok(ShouldSkipSpace);
8458 auto TokCount = getLexer().peekTokens(Tokens);
8460 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8465AMDGPUAsmParser::getTokenKind()
const {
8466 return getLexer().getKind();
8470AMDGPUAsmParser::getLoc()
const {
8475AMDGPUAsmParser::getTokenStr()
const {
8480AMDGPUAsmParser::lex() {
8484SMLoc AMDGPUAsmParser::getInstLoc(
const OperandVector &Operands)
const {
8485 return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
8489SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8493SMLoc AMDGPUAsmParser::getOperandLoc(
const OperandVector &Operands,
8494 int MCOpIdx)
const {
8495 for (
const auto &
Op : Operands) {
8496 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8497 if (TargetOp.getMCOpIdx() == MCOpIdx)
8498 return TargetOp.getStartLoc();
8504AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8506 for (
unsigned i = Operands.
size() - 1; i > 0; --i) {
8507 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
8509 return Op.getStartLoc();
8511 return getInstLoc(Operands);
8515AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8517 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8518 return getOperandLoc(
Test, Operands);
8532 StringRef
Id = getTokenStr();
8533 SMLoc IdLoc = getLoc();
8539 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8540 if (
I == Fields.
end())
8541 return Error(IdLoc,
"unknown field");
8542 if ((*I)->IsDefined)
8543 return Error(IdLoc,
"duplicate field");
8546 (*I)->Loc = getLoc();
8549 (*I)->IsDefined =
true;
8556bool AMDGPUAsmParser::validateStructuredOpFields(
8558 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8559 return F->validate(*
this);
8570 const unsigned OrMask,
8571 const unsigned XorMask) {
8580bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8581 const unsigned MaxVal,
8582 const Twine &ErrMsg, SMLoc &Loc) {
8599AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8600 const unsigned MinVal,
8601 const unsigned MaxVal,
8602 const StringRef ErrMsg) {
8604 for (
unsigned i = 0; i < OpNum; ++i) {
8605 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8613AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8614 using namespace llvm::AMDGPU::Swizzle;
8617 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8618 "expected a 2-bit lane id")) {
8629AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8630 using namespace llvm::AMDGPU::Swizzle;
8636 if (!parseSwizzleOperand(GroupSize,
8638 "group size must be in the interval [2,32]",
8643 Error(Loc,
"group size must be a power of two");
8646 if (parseSwizzleOperand(LaneIdx,
8648 "lane id must be in the interval [0,group size - 1]",
8657AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8658 using namespace llvm::AMDGPU::Swizzle;
8663 if (!parseSwizzleOperand(GroupSize,
8665 "group size must be in the interval [2,32]",
8670 Error(Loc,
"group size must be a power of two");
8679AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8680 using namespace llvm::AMDGPU::Swizzle;
8685 if (!parseSwizzleOperand(GroupSize,
8687 "group size must be in the interval [1,16]",
8692 Error(Loc,
"group size must be a power of two");
8701AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8702 using namespace llvm::AMDGPU::Swizzle;
8709 SMLoc StrLoc = getLoc();
8710 if (!parseString(Ctl)) {
8713 if (Ctl.
size() != BITMASK_WIDTH) {
8714 Error(StrLoc,
"expected a 5-character mask");
8718 unsigned AndMask = 0;
8719 unsigned OrMask = 0;
8720 unsigned XorMask = 0;
8722 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8726 Error(StrLoc,
"invalid mask");
8747bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8748 using namespace llvm::AMDGPU::Swizzle;
8751 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8757 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8758 "FFT swizzle must be in the interval [0," +
8759 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8767bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8768 using namespace llvm::AMDGPU::Swizzle;
8771 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8778 if (!parseSwizzleOperand(
Direction, 0, 1,
8779 "direction must be 0 (left) or 1 (right)", Loc))
8783 if (!parseSwizzleOperand(
8784 RotateSize, 0, ROTATE_MAX_SIZE,
8785 "number of threads to rotate must be in the interval [0," +
8786 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8791 (RotateSize << ROTATE_SIZE_SHIFT);
8796AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8798 SMLoc OffsetLoc = getLoc();
8804 Error(OffsetLoc,
"expected a 16-bit offset");
8811AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8812 using namespace llvm::AMDGPU::Swizzle;
8816 SMLoc ModeLoc = getLoc();
8819 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8820 Ok = parseSwizzleQuadPerm(
Imm);
8821 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8822 Ok = parseSwizzleBitmaskPerm(
Imm);
8823 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8824 Ok = parseSwizzleBroadcast(
Imm);
8825 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8826 Ok = parseSwizzleSwap(
Imm);
8827 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8828 Ok = parseSwizzleReverse(
Imm);
8829 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8830 Ok = parseSwizzleFFT(
Imm);
8831 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8832 Ok = parseSwizzleRotate(
Imm);
8834 Error(ModeLoc,
"expected a swizzle mode");
8837 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8843ParseStatus AMDGPUAsmParser::parseSwizzle(
OperandVector &Operands) {
8847 if (trySkipId(
"offset")) {
8851 if (trySkipId(
"swizzle")) {
8852 Ok = parseSwizzleMacro(
Imm);
8854 Ok = parseSwizzleOffset(
Imm);
8858 Operands.
push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8866AMDGPUOperand::isSwizzle()
const {
8867 return isImmTy(ImmTySwizzle);
8874int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8876 using namespace llvm::AMDGPU::VGPRIndexMode;
8888 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8889 if (trySkipId(IdSymbolic[ModeId])) {
8897 "expected a VGPR index mode or a closing parenthesis" :
8898 "expected a VGPR index mode");
8903 Error(S,
"duplicate VGPR index mode");
8911 "expected a comma or a closing parenthesis"))
8918ParseStatus AMDGPUAsmParser::parseGPRIdxMode(
OperandVector &Operands) {
8920 using namespace llvm::AMDGPU::VGPRIndexMode;
8926 Imm = parseGPRIdxMacro();
8930 if (getParser().parseAbsoluteExpression(
Imm))
8933 return Error(S,
"invalid immediate: only 4-bit values are legal");
8937 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8941bool AMDGPUOperand::isGPRIdxMode()
const {
8942 return isImmTy(ImmTyGprIdxMode);
8949ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(
OperandVector &Operands) {
8954 if (isRegister() || isModifier())
8960 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
8961 assert(Opr.isImm() || Opr.isExpr());
8962 SMLoc Loc = Opr.getStartLoc();
8966 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8967 Error(Loc,
"expected an absolute expression or a label");
8968 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8969 Error(Loc,
"expected a 16-bit signed jump offset");
8979ParseStatus AMDGPUAsmParser::parseBoolReg(
OperandVector &Operands) {
8980 return parseReg(Operands);
8987void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
8990 OptionalImmIndexMap OptionalIdx;
8991 unsigned FirstOperandIdx = 1;
8992 bool IsAtomicReturn =
false;
8999 for (
unsigned i = FirstOperandIdx, e = Operands.
size(); i != e; ++i) {
9000 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9004 Op.addRegOperands(Inst, 1);
9008 if (IsAtomicReturn && i == FirstOperandIdx)
9009 Op.addRegOperands(Inst, 1);
9014 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9015 Op.addImmOperands(Inst, 1);
9027 OptionalIdx[
Op.getImmTy()] = i;
9041bool AMDGPUOperand::isSMRDOffset8()
const {
9045bool AMDGPUOperand::isSMEMOffset()
const {
9047 return isImmLiteral();
9050bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9085bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9086 if (BoundCtrl == 0 || BoundCtrl == 1) {
9094void AMDGPUAsmParser::onBeginOfFile() {
9095 if (!getParser().getStreamer().getTargetStreamer() ||
9099 if (!getTargetStreamer().getTargetID())
9100 getTargetStreamer().initializeTargetID(getSTI(),
9101 getSTI().getFeatureString());
9104 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9112bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9116 StringRef TokenId = getTokenStr();
9117 AGVK VK = StringSwitch<AGVK>(TokenId)
9118 .Case(
"max", AGVK::AGVK_Max)
9119 .Case(
"or", AGVK::AGVK_Or)
9120 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9121 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9122 .Case(
"alignto", AGVK::AGVK_AlignTo)
9123 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9124 .Default(AGVK::AGVK_None);
9128 uint64_t CommaCount = 0;
9133 if (Exprs.
empty()) {
9135 "empty " + Twine(TokenId) +
" expression");
9138 if (CommaCount + 1 != Exprs.
size()) {
9140 "mismatch of commas in " + Twine(TokenId) +
" expression");
9147 if (getParser().parseExpression(Expr, EndLoc))
9151 if (LastTokenWasComma)
9155 "unexpected token in " + Twine(TokenId) +
" expression");
9161 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9164ParseStatus AMDGPUAsmParser::parseOModSI(
OperandVector &Operands) {
9165 StringRef
Name = getTokenStr();
9166 if (Name ==
"mul") {
9167 return parseIntWithPrefix(
"mul", Operands,
9171 if (Name ==
"div") {
9172 return parseIntWithPrefix(
"div", Operands,
9183 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9188 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9189 AMDGPU::OpName::src2};
9197 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9202 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9204 if (
DstOp.isReg() &&
9205 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9209 if ((OpSel & (1 << SrcNum)) != 0)
9215void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9217 cvtVOP3P(Inst, Operands);
9221void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
const OperandVector &Operands,
9222 OptionalImmIndexMap &OptionalIdx) {
9223 cvtVOP3P(Inst, Operands, OptionalIdx);
9232 &&
Desc.NumOperands > (OpNum + 1)
9234 &&
Desc.operands()[OpNum + 1].RegClass != -1
9236 &&
Desc.getOperandConstraint(OpNum + 1,
9240void AMDGPUAsmParser::cvtOpSelHelper(MCInst &Inst,
unsigned OpSel) {
9242 constexpr AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9243 AMDGPU::OpName::src2};
9244 constexpr AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9245 AMDGPU::OpName::src1_modifiers,
9246 AMDGPU::OpName::src2_modifiers};
9247 for (
int J = 0; J < 3; ++J) {
9248 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9254 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9257 if ((OpSel & (1 << J)) != 0)
9260 if (ModOps[J] == AMDGPU::OpName::src0_modifiers && (OpSel & (1 << 3)) != 0)
9267void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,
const OperandVector &Operands)
9269 OptionalImmIndexMap OptionalIdx;
9274 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9275 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9278 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9279 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9281 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9282 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9283 Op.isInterpAttrChan()) {
9285 }
else if (
Op.isImmModifier()) {
9286 OptionalIdx[
Op.getImmTy()] =
I;
9294 AMDGPUOperand::ImmTyHigh);
9298 AMDGPUOperand::ImmTyClamp);
9302 AMDGPUOperand::ImmTyOModSI);
9307 AMDGPUOperand::ImmTyOpSel);
9308 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9311 cvtOpSelHelper(Inst, OpSel);
9315void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,
const OperandVector &Operands)
9317 OptionalImmIndexMap OptionalIdx;
9322 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9323 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9326 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9327 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9329 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9330 }
else if (
Op.isImmModifier()) {
9331 OptionalIdx[
Op.getImmTy()] =
I;
9339 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9349 cvtOpSelHelper(Inst, OpSel);
9352void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9354 OptionalImmIndexMap OptionalIdx;
9357 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9361 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9362 static_cast<AMDGPUOperand &
>(*Operands[
I++]).addRegOperands(Inst, 1);
9364 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9365 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands[
I]);
9370 if (NumOperands == CbszOpIdx) {
9375 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9376 }
else if (
Op.isImmModifier()) {
9377 OptionalIdx[
Op.getImmTy()] =
I;
9379 Op.addRegOrImmOperands(Inst, 1);
9384 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9385 if (CbszIdx != OptionalIdx.end()) {
9386 int CbszVal = ((AMDGPUOperand &)*Operands[CbszIdx->second]).
getImm();
9390 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9391 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9392 if (BlgpIdx != OptionalIdx.end()) {
9393 int BlgpVal = ((AMDGPUOperand &)*Operands[BlgpIdx->second]).
getImm();
9404 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9405 if (OpselIdx != OptionalIdx.end()) {
9406 OpSel =
static_cast<const AMDGPUOperand &
>(*Operands[OpselIdx->second])
9410 unsigned OpSelHi = 0;
9411 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9412 if (OpselHiIdx != OptionalIdx.end()) {
9413 OpSelHi =
static_cast<const AMDGPUOperand &
>(*Operands[OpselHiIdx->second])
9416 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9417 AMDGPU::OpName::src1_modifiers};
9419 for (
unsigned J = 0; J < 2; ++J) {
9420 unsigned ModVal = 0;
9421 if (OpSel & (1 << J))
9423 if (OpSelHi & (1 << J))
9426 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9431void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands,
9432 OptionalImmIndexMap &OptionalIdx) {
9437 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9438 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
9441 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
9442 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
9444 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9445 }
else if (
Op.isImmModifier()) {
9446 OptionalIdx[
Op.getImmTy()] =
I;
9448 Op.addRegOrImmOperands(Inst, 1);
9454 AMDGPUOperand::ImmTyScaleSel);
9458 AMDGPUOperand::ImmTyClamp);
9464 AMDGPUOperand::ImmTyByteSel);
9469 AMDGPUOperand::ImmTyOModSI);
9476 auto *it = Inst.
begin();
9477 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9485void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,
const OperandVector &Operands) {
9486 OptionalImmIndexMap OptionalIdx;
9487 cvtVOP3(Inst, Operands, OptionalIdx);
9490void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands,
9491 OptionalImmIndexMap &OptIdx) {
9497 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9498 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9499 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9500 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9501 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9502 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9510 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9511 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9512 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9513 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9514 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9515 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9516 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9517 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9518 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9519 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9520 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9521 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9522 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9523 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9524 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9525 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9526 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9527 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9528 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9529 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9530 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9531 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9532 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9533 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9534 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9535 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9539 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9540 if (BitOp3Idx != -1) {
9547 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9548 if (OpSelIdx != -1) {
9552 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9553 if (OpSelHiIdx != -1) {
9560 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9561 if (MatrixAFMTIdx != -1) {
9563 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9567 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9568 if (MatrixBFMTIdx != -1) {
9570 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9573 int MatrixAScaleIdx =
9574 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9575 if (MatrixAScaleIdx != -1) {
9577 AMDGPUOperand::ImmTyMatrixAScale, 0);
9580 int MatrixBScaleIdx =
9581 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9582 if (MatrixBScaleIdx != -1) {
9584 AMDGPUOperand::ImmTyMatrixBScale, 0);
9587 int MatrixAScaleFmtIdx =
9588 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9589 if (MatrixAScaleFmtIdx != -1) {
9591 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9594 int MatrixBScaleFmtIdx =
9595 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9596 if (MatrixBScaleFmtIdx != -1) {
9598 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9603 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9607 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9609 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9613 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9617 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9618 AMDGPU::OpName::src2};
9619 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9620 AMDGPU::OpName::src1_modifiers,
9621 AMDGPU::OpName::src2_modifiers};
9624 unsigned OpSelHi = 0;
9631 if (OpSelHiIdx != -1)
9640 for (
int J = 0; J < 3; ++J) {
9641 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9645 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9650 uint32_t ModVal = 0;
9653 if (SrcOp.
isReg() && getMRI()
9660 if ((OpSel & (1 << J)) != 0)
9664 if ((OpSelHi & (1 << J)) != 0)
9667 if ((NegLo & (1 << J)) != 0)
9670 if ((NegHi & (1 << J)) != 0)
9677void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,
const OperandVector &Operands) {
9678 OptionalImmIndexMap OptIdx;
9679 cvtVOP3(Inst, Operands, OptIdx);
9680 cvtVOP3P(Inst, Operands, OptIdx);
9684 unsigned i,
unsigned Opc,
9686 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9687 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9689 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9692void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,
const OperandVector &Operands) {
9695 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9698 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
9699 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);
9701 OptionalImmIndexMap OptIdx;
9702 for (
unsigned i = 5; i < Operands.
size(); ++i) {
9703 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[i]);
9704 OptIdx[
Op.getImmTy()] = i;
9709 AMDGPUOperand::ImmTyIndexKey8bit);
9713 AMDGPUOperand::ImmTyIndexKey16bit);
9717 AMDGPUOperand::ImmTyIndexKey32bit);
9722 cvtVOP3P(Inst, Operands, OptIdx);
9729ParseStatus AMDGPUAsmParser::parseVOPD(
OperandVector &Operands) {
9737 Operands.
push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9738 SMLoc OpYLoc = getLoc();
9741 Operands.
push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9744 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9750void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,
const OperandVector &Operands) {
9753 auto addOp = [&](uint16_t ParsedOprIdx) {
9754 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9756 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9760 Op.addRegOperands(Inst, 1);
9764 Op.addImmOperands(Inst, 1);
9776 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9780 const auto &CInfo = InstInfo[CompIdx];
9781 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9782 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9783 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9784 if (CInfo.hasSrc2Acc())
9785 addOp(CInfo.getIndexOfDstInParsedOperands());
9789 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9790 if (BitOp3Idx != -1) {
9791 OptionalImmIndexMap OptIdx;
9792 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands.
back());
9794 OptIdx[
Op.getImmTy()] = Operands.
size() - 1;
9804bool AMDGPUOperand::isDPP8()
const {
9805 return isImmTy(ImmTyDPP8);
9808bool AMDGPUOperand::isDPPCtrl()
const {
9809 using namespace AMDGPU::DPP;
9811 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9814 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9815 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9816 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9817 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9818 (
Imm == DppCtrl::WAVE_SHL1) ||
9819 (
Imm == DppCtrl::WAVE_ROL1) ||
9820 (
Imm == DppCtrl::WAVE_SHR1) ||
9821 (
Imm == DppCtrl::WAVE_ROR1) ||
9822 (
Imm == DppCtrl::ROW_MIRROR) ||
9823 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9824 (
Imm == DppCtrl::BCAST15) ||
9825 (
Imm == DppCtrl::BCAST31) ||
9826 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9827 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9836bool AMDGPUOperand::isBLGP()
const {
9840bool AMDGPUOperand::isS16Imm()
const {
9844bool AMDGPUOperand::isU16Imm()
const {
9852bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9857 SMLoc Loc =
getToken().getEndLoc();
9858 Token = std::string(getTokenStr());
9860 if (getLoc() != Loc)
9865 if (!parseId(Suffix))
9869 StringRef DimId = Token;
9880ParseStatus AMDGPUAsmParser::parseDim(
OperandVector &Operands) {
9890 SMLoc Loc = getLoc();
9891 if (!parseDimId(Encoding))
9892 return Error(Loc,
"invalid dim value");
9894 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9895 AMDGPUOperand::ImmTyDim));
9903ParseStatus AMDGPUAsmParser::parseDPP8(
OperandVector &Operands) {
9913 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9916 for (
size_t i = 0; i < 8; ++i) {
9920 SMLoc Loc = getLoc();
9921 if (getParser().parseAbsoluteExpression(Sels[i]))
9923 if (0 > Sels[i] || 7 < Sels[i])
9924 return Error(Loc,
"expected a 3-bit value");
9931 for (
size_t i = 0; i < 8; ++i)
9932 DPP8 |= (Sels[i] << (i * 3));
9934 Operands.
push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9939AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
9941 if (Ctrl ==
"row_newbcast")
9944 if (Ctrl ==
"row_share" ||
9945 Ctrl ==
"row_xmask")
9948 if (Ctrl ==
"wave_shl" ||
9949 Ctrl ==
"wave_shr" ||
9950 Ctrl ==
"wave_rol" ||
9951 Ctrl ==
"wave_ror" ||
9952 Ctrl ==
"row_bcast")
9955 return Ctrl ==
"row_mirror" ||
9956 Ctrl ==
"row_half_mirror" ||
9957 Ctrl ==
"quad_perm" ||
9958 Ctrl ==
"row_shl" ||
9959 Ctrl ==
"row_shr" ||
9964AMDGPUAsmParser::parseDPPCtrlPerm() {
9967 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9971 for (
int i = 0; i < 4; ++i) {
9976 SMLoc Loc = getLoc();
9977 if (getParser().parseAbsoluteExpression(Temp))
9979 if (Temp < 0 || Temp > 3) {
9980 Error(Loc,
"expected a 2-bit value");
9984 Val += (Temp << i * 2);
9994AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
9995 using namespace AMDGPU::DPP;
10000 SMLoc Loc = getLoc();
10002 if (getParser().parseAbsoluteExpression(Val))
10005 struct DppCtrlCheck {
10011 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
10012 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
10013 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10014 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10015 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10016 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10017 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10018 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10019 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10020 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10021 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10025 if (
Check.Ctrl == -1) {
10026 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10034 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10041ParseStatus AMDGPUAsmParser::parseDPPCtrl(
OperandVector &Operands) {
10042 using namespace AMDGPU::DPP;
10045 !isSupportedDPPCtrl(getTokenStr(), Operands))
10048 SMLoc S = getLoc();
10054 if (Ctrl ==
"row_mirror") {
10055 Val = DppCtrl::ROW_MIRROR;
10056 }
else if (Ctrl ==
"row_half_mirror") {
10057 Val = DppCtrl::ROW_HALF_MIRROR;
10060 if (Ctrl ==
"quad_perm") {
10061 Val = parseDPPCtrlPerm();
10063 Val = parseDPPCtrlSel(Ctrl);
10072 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10076void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,
const OperandVector &Operands,
10078 OptionalImmIndexMap OptionalIdx;
10085 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10087 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10088 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10092 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10093 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10097 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10098 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10099 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10100 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10101 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10103 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10107 if (OldIdx == NumOperands) {
10109 constexpr int DST_IDX = 0;
10111 }
else if (Src2ModIdx == NumOperands) {
10121 if (IsVOP3CvtSrDpp) {
10130 if (TiedTo != -1) {
10135 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10137 if (IsDPP8 &&
Op.isDppFI()) {
10140 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10141 }
else if (
Op.isReg()) {
10142 Op.addRegOperands(Inst, 1);
10143 }
else if (
Op.isImm() &&
10145 Op.addImmOperands(Inst, 1);
10146 }
else if (
Op.isImm()) {
10147 OptionalIdx[
Op.getImmTy()] =
I;
10155 AMDGPUOperand::ImmTyClamp);
10161 AMDGPUOperand::ImmTyByteSel);
10168 cvtVOP3P(Inst, Operands, OptionalIdx);
10170 cvtVOP3OpSel(Inst, Operands, OptionalIdx);
10177 using namespace llvm::AMDGPU::DPP;
10187 AMDGPUOperand::ImmTyDppFI);
10191void AMDGPUAsmParser::cvtDPP(MCInst &Inst,
const OperandVector &Operands,
bool IsDPP8) {
10192 OptionalImmIndexMap OptionalIdx;
10196 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10197 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10201 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10204 if (TiedTo != -1) {
10209 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10211 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10219 Op.addImmOperands(Inst, 1);
10221 Op.addRegWithFPInputModsOperands(Inst, 2);
10222 }
else if (
Op.isDppFI()) {
10224 }
else if (
Op.isReg()) {
10225 Op.addRegOperands(Inst, 1);
10231 Op.addRegWithFPInputModsOperands(Inst, 2);
10232 }
else if (
Op.isReg()) {
10233 Op.addRegOperands(Inst, 1);
10234 }
else if (
Op.isDPPCtrl()) {
10235 Op.addImmOperands(Inst, 1);
10236 }
else if (
Op.isImm()) {
10238 OptionalIdx[
Op.getImmTy()] =
I;
10246 using namespace llvm::AMDGPU::DPP;
10254 AMDGPUOperand::ImmTyDppFI);
10263ParseStatus AMDGPUAsmParser::parseSDWASel(
OperandVector &Operands,
10265 AMDGPUOperand::ImmTy
Type) {
10266 return parseStringOrIntWithPrefix(
10268 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10272ParseStatus AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
10273 return parseStringOrIntWithPrefix(
10274 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10275 AMDGPUOperand::ImmTySDWADstUnused);
10278void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,
const OperandVector &Operands) {
10282void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,
const OperandVector &Operands) {
10286void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,
const OperandVector &Operands) {
10290void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,
const OperandVector &Operands) {
10294void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,
const OperandVector &Operands) {
10298void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,
const OperandVector &Operands,
10299 uint64_t BasicInstType,
10302 using namespace llvm::AMDGPU::SDWA;
10304 OptionalImmIndexMap OptionalIdx;
10305 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10306 bool SkippedVcc =
false;
10310 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10311 ((AMDGPUOperand &)*Operands[
I++]).addRegOperands(Inst, 1);
10314 for (
unsigned E = Operands.
size();
I !=
E; ++
I) {
10315 AMDGPUOperand &
Op = ((AMDGPUOperand &)*Operands[
I]);
10316 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10317 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10335 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10336 }
else if (
Op.isImm()) {
10338 OptionalIdx[
Op.getImmTy()] =
I;
10342 SkippedVcc =
false;
10346 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10347 Opc != AMDGPU::V_NOP_sdwa_vi) {
10349 switch (BasicInstType) {
10353 AMDGPUOperand::ImmTyClamp, 0);
10357 AMDGPUOperand::ImmTyOModSI, 0);
10361 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10365 AMDGPUOperand::ImmTySDWADstUnused,
10366 DstUnused::UNUSED_PRESERVE);
10368 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10373 AMDGPUOperand::ImmTyClamp, 0);
10378 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10379 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
10380 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10381 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10387 AMDGPUOperand::ImmTyClamp, 0);
10388 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
10389 addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
10393 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10399 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10400 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10401 auto *it = Inst.
begin();
10403 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10415#define GET_MATCHER_IMPLEMENTATION
10416#define GET_MNEMONIC_SPELL_CHECKER
10417#define GET_MNEMONIC_CHECKER
10418#include "AMDGPUGenAsmMatcher.inc"
10424 return parseTokenOp(
"addr64",
Operands);
10426 return parseTokenOp(
"done",
Operands);
10428 return parseTokenOp(
"idxen",
Operands);
10430 return parseTokenOp(
"lds",
Operands);
10432 return parseTokenOp(
"offen",
Operands);
10434 return parseTokenOp(
"off",
Operands);
10435 case MCK_row_95_en:
10436 return parseTokenOp(
"row_en",
Operands);
10438 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10440 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10442 return tryCustomParseOperand(
Operands, MCK);
10447unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10453 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10456 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10458 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10460 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10462 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10464 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10466 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10474 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10476 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10477 case MCK_SOPPBrTarget:
10478 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10479 case MCK_VReg32OrOff:
10480 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10481 case MCK_InterpSlot:
10482 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10483 case MCK_InterpAttr:
10484 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10485 case MCK_InterpAttrChan:
10486 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10488 case MCK_SReg_64_XEXEC:
10498 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10500 return Match_InvalidOperand;
10508ParseStatus AMDGPUAsmParser::parseEndpgm(
OperandVector &Operands) {
10509 SMLoc S = getLoc();
10518 return Error(S,
"expected a 16-bit value");
10521 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10525bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10531bool AMDGPUOperand::isSplitBarrier()
const {
return isInlinableImm(MVT::i32); }
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
SmallVector< int16_t, MAX_SRC_OPERANDS_NUM > OperandIndices
static bool checkWriteLane(const MCInst &Inst)
static bool getRegNum(StringRef Str, unsigned &Num)
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, AMDGPU::OpName OpName)
static constexpr RegInfo RegularRegisters[]
static const RegInfo * getRegularRegInfo(StringRef Str)
static ArrayRef< unsigned > getAllVariants()
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
static int IsAGPROperand(const MCInst &Inst, AMDGPU::OpName Name, const MCRegisterInfo *MRI)
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
static const fltSemantics * getFltSemantics(unsigned Size)
static bool isRegularReg(RegisterKind Kind)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
static bool ConvertOmodMul(int64_t &Mul)
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
constexpr uint64_t MIMGFlags
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
constexpr unsigned MAX_SRC_OPERANDS_NUM
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
static bool ConvertOmodDiv(int64_t &Div)
static bool IsRevOpcode(const unsigned Opcode)
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
static MCRegister getSpecialRegForName(StringRef RegName)
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0, std::optional< unsigned > InsertAt=std::nullopt)
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
static bool isSafeTruncation(int64_t Val, unsigned Size)
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
Provides AMDGPU specific target descriptions.
AMDHSA kernel descriptor definitions.
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Loop::LoopBounds::Direction Direction
Register const TargetRegisterInfo * TRI
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
MachineInstr unsigned OpIdx
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
unsigned unsigned DefaultVal
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, 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)
bool isInlineValue(MCRegister Reg)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
bool isSGPR(MCRegister Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
uint8_t wmmaScaleF8F6F4FormatToNumRegs(unsigned Fmt)
const int OPR_ID_UNSUPPORTED
bool isInlinableLiteralV2I16(uint32_t Literal)
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
unsigned getTemporalHintType(const MCInstrDesc TID)
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
bool isGFX10(const MCSubtargetInfo &STI)
LLVM_READONLY bool isLitExpr(const MCExpr *Expr)
bool isInlinableLiteralV2BF16(uint32_t Literal)
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
bool hasA16(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset, bool IsBuffer)
bool isGFX12Plus(const MCSubtargetInfo &STI)
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
bool hasPackedD16(const MCSubtargetInfo &STI)
bool isGFX940(const MCSubtargetInfo &STI)
bool isInlinableLiteralV2F16(uint32_t Literal)
bool isHsaAbi(const MCSubtargetInfo &STI)
bool isGFX11(const MCSubtargetInfo &STI)
const int OPR_VAL_INVALID
bool getSMEMIsBuffer(unsigned Opc)
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
CanBeVOPD getCanBeVOPD(unsigned Opc, unsigned EncodingFamily, bool VOPD3)
LLVM_READNONE bool isLegalDPALU_DPPControl(const MCSubtargetInfo &ST, unsigned DC)
bool isSI(const MCSubtargetInfo &STI)
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getWaitcntBitMask(const IsaVersion &Version)
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
bool isGFX9(const MCSubtargetInfo &STI)
unsigned getVOPDEncodingFamily(const MCSubtargetInfo &ST)
bool isGFX10_AEncoding(const MCSubtargetInfo &STI)
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
bool isGFX90A(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool isGFX12(const MCSubtargetInfo &STI)
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
bool hasMAIInsts(const MCSubtargetInfo &STI)
constexpr bool isSISrcOperand(const MCOperandInfo &OpInfo)
Is this an AMDGPU specific source operand?
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type, bool IsLit)
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
@ OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_INT32
Operands with register, 32-bit, or 64-bit immediate.
@ OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
@ OPERAND_REG_IMM_NOINLINE_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_AC_INT32
Operands with an AccVGPR register or inline constant.
@ OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_C_FP16
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCInstrInfo &MII, const MCSubtargetInfo &ST)
bool hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
unsigned getRegBitWidth(const TargetRegisterClass &RC)
Get the size in bits of a register from the register class RC.
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
@ Valid
The data is already valid.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
FunctionAddr VTableAddr uintptr_t uintptr_t Version
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Target & getTheGCNTarget()
The target for GCN GPUs.
@ Sub
Subtraction of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
unsigned M0(unsigned Val)
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
@ 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