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;
1354#define GET_ASSEMBLER_HEADER
1355#include "AMDGPUGenAsmMatcher.inc"
1360 void createConstantSymbol(
StringRef Id, int64_t Val);
1362 bool ParseAsAbsoluteExpression(
uint32_t &Ret);
1380 const MCExpr *FlatScrUsed,
bool XNACKUsed,
1381 std::optional<bool> EnableWavefrontSize32,
1385 bool ParseDirectiveAMDGCNTarget();
1386 bool ParseDirectiveAMDHSACodeObjectVersion();
1387 bool ParseDirectiveAMDHSAKernel();
1389 bool ParseDirectiveAMDKernelCodeT();
1392 bool ParseDirectiveAMDGPUHsaKernel();
1394 bool ParseDirectiveISAVersion();
1395 bool ParseDirectiveHSAMetadata();
1396 bool ParseDirectivePALMetadataBegin();
1397 bool ParseDirectivePALMetadata();
1398 bool ParseDirectiveAMDGPULDS();
1402 bool ParseToEndDirective(
const char *AssemblerDirectiveBegin,
1403 const char *AssemblerDirectiveEnd,
1404 std::string &CollectString);
1406 bool AddNextRegisterToList(
MCRegister &
Reg,
unsigned &RegWidth,
1408 bool ParseAMDGPURegister(RegisterKind &RegKind,
MCRegister &
Reg,
1409 unsigned &RegNum,
unsigned &RegWidth,
1410 bool RestoreOnFailure =
false);
1411 bool ParseAMDGPURegister(RegisterKind &RegKind,
MCRegister &
Reg,
1412 unsigned &RegNum,
unsigned &RegWidth,
1414 MCRegister ParseRegularReg(RegisterKind &RegKind,
unsigned &RegNum,
1417 MCRegister ParseSpecialReg(RegisterKind &RegKind,
unsigned &RegNum,
1420 MCRegister ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
1423 bool ParseRegRange(
unsigned &Num,
unsigned &Width,
unsigned &
SubReg);
1424 MCRegister getRegularReg(RegisterKind RegKind,
unsigned RegNum,
1429 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1430 void initializeGprCountSymbol(RegisterKind RegKind);
1431 bool updateGprCountSymbols(RegisterKind RegKind,
unsigned DwordRegIndex,
1438 OperandMode_Default,
1442 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1444 AMDGPUAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1445 const MCInstrInfo &MII,
1446 const MCTargetOptions &
Options)
1447 : MCTargetAsmParser(
Options, STI, MII), Parser(_Parser) {
1450 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1454 createConstantSymbol(
".amdgcn.gfx_generation_number",
ISA.Major);
1455 createConstantSymbol(
".amdgcn.gfx_generation_minor",
ISA.Minor);
1456 createConstantSymbol(
".amdgcn.gfx_generation_stepping",
ISA.Stepping);
1458 createConstantSymbol(
".option.machine_version_major",
ISA.Major);
1459 createConstantSymbol(
".option.machine_version_minor",
ISA.Minor);
1460 createConstantSymbol(
".option.machine_version_stepping",
ISA.Stepping);
1463 initializeGprCountSymbol(IS_VGPR);
1464 initializeGprCountSymbol(IS_SGPR);
1469 createConstantSymbol(Symbol, Code);
1471 createConstantSymbol(
"UC_VERSION_W64_BIT", 0x2000);
1472 createConstantSymbol(
"UC_VERSION_W32_BIT", 0x4000);
1473 createConstantSymbol(
"UC_VERSION_MDP_BIT", 0x8000);
1545 bool isWave32()
const {
return getAvailableFeatures()[Feature_isWave32Bit]; }
1547 bool isWave64()
const {
return getAvailableFeatures()[Feature_isWave64Bit]; }
1549 bool hasInv2PiInlineImm()
const {
1550 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1553 bool has64BitLiterals()
const {
1554 return getFeatureBits()[AMDGPU::Feature64BitLiterals];
1557 bool hasFlatOffsets()
const {
1558 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1561 bool hasTrue16Insts()
const {
1562 return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts];
1566 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1569 bool hasSGPR102_SGPR103()
const {
1573 bool hasSGPR104_SGPR105()
const {
return isGFX10Plus(); }
1575 bool hasIntClamp()
const {
1576 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1579 bool hasPartialNSAEncoding()
const {
1580 return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1583 bool hasGloballyAddressableScratch()
const {
1584 return getFeatureBits()[AMDGPU::FeatureGloballyAddressableScratch];
1597 AMDGPUTargetStreamer &getTargetStreamer() {
1598 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1599 return static_cast<AMDGPUTargetStreamer &
>(TS);
1605 return const_cast<AMDGPUAsmParser *
>(
this)->MCTargetAsmParser::getContext();
1608 const MCRegisterInfo *getMRI()
const {
1612 const MCInstrInfo *getMII()
const {
1618 const FeatureBitset &getFeatureBits()
const {
1619 return getSTI().getFeatureBits();
1622 void setForcedEncodingSize(
unsigned Size) { ForcedEncodingSize =
Size; }
1623 void setForcedDPP(
bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1624 void setForcedSDWA(
bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1626 unsigned getForcedEncodingSize()
const {
return ForcedEncodingSize; }
1627 bool isForcedVOP3()
const {
return ForcedEncodingSize == 64; }
1628 bool isForcedDPP()
const {
return ForcedDPP; }
1629 bool isForcedSDWA()
const {
return ForcedSDWA; }
1630 ArrayRef<unsigned> getMatchedVariants()
const;
1631 StringRef getMatchedVariantName()
const;
1633 std::unique_ptr<AMDGPUOperand> parseRegister(
bool RestoreOnFailure =
false);
1634 bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1635 bool RestoreOnFailure);
1636 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
1637 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1638 SMLoc &EndLoc)
override;
1639 unsigned checkTargetMatchPredicate(MCInst &Inst)
override;
1640 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
1641 unsigned Kind)
override;
1642 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1644 uint64_t &ErrorInfo,
1645 bool MatchingInlineAsm)
override;
1646 bool ParseDirective(AsmToken DirectiveID)
override;
1648 OperandMode
Mode = OperandMode_Default);
1649 StringRef parseMnemonicSuffix(StringRef Name);
1650 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
1656 ParseStatus parseIntWithPrefix(
const char *Prefix, int64_t &
Int);
1660 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1661 std::function<
bool(int64_t &)> ConvertResult =
nullptr);
1663 ParseStatus parseOperandArrayWithPrefix(
1665 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1666 bool (*ConvertResult)(int64_t &) =
nullptr);
1670 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1671 unsigned getCPolKind(StringRef Id, StringRef Mnemo,
bool &Disabling)
const;
1675 ParseStatus parseStringWithPrefix(StringRef Prefix, StringRef &
Value,
1679 ArrayRef<const char *> Ids,
1683 ArrayRef<const char *> Ids,
1684 AMDGPUOperand::ImmTy
Type);
1687 bool isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1688 bool isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1689 bool isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1690 bool isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const;
1691 bool parseSP3NegModifier();
1698 bool AllowImm =
true);
1700 bool AllowImm =
true);
1705 AMDGPUOperand::ImmTy ImmTy);
1710 AMDGPUOperand::ImmTy
Type);
1714 AMDGPUOperand::ImmTy
Type);
1718 AMDGPUOperand::ImmTy
Type);
1722 ParseStatus parseDfmtNfmt(int64_t &
Format);
1723 ParseStatus parseUfmt(int64_t &
Format);
1724 ParseStatus parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc,
1726 ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc,
1729 ParseStatus parseSymbolicOrNumericFormat(int64_t &
Format);
1730 ParseStatus parseNumericFormat(int64_t &
Format);
1734 bool tryParseFmt(
const char *Pref, int64_t MaxVal, int64_t &Val);
1735 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1739 bool parseCnt(int64_t &IntVal);
1742 bool parseDepCtr(int64_t &IntVal,
unsigned &Mask);
1743 void depCtrError(SMLoc Loc,
int ErrorId, StringRef DepCtrName);
1746 bool parseDelay(int64_t &Delay);
1752 struct OperandInfoTy {
1755 bool IsSymbolic =
false;
1756 bool IsDefined =
false;
1758 OperandInfoTy(int64_t Val) : Val(Val) {}
1761 struct StructuredOpField : OperandInfoTy {
1765 bool IsDefined =
false;
1767 StructuredOpField(StringLiteral Id, StringLiteral Desc,
unsigned Width,
1769 : OperandInfoTy(
Default), Id(Id), Desc(Desc), Width(Width) {}
1770 virtual ~StructuredOpField() =
default;
1772 bool Error(AMDGPUAsmParser &Parser,
const Twine &Err)
const {
1773 Parser.Error(Loc,
"invalid " + Desc +
": " + Err);
1777 virtual bool validate(AMDGPUAsmParser &Parser)
const {
1779 return Error(Parser,
"not supported on this GPU");
1781 return Error(Parser,
"only " + Twine(Width) +
"-bit values are legal");
1789 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &
Op, OperandInfoTy &Stream);
1790 bool validateSendMsg(
const OperandInfoTy &Msg,
1791 const OperandInfoTy &
Op,
1792 const OperandInfoTy &Stream);
1794 ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &
Offset,
1795 OperandInfoTy &Width);
1797 static SMLoc getLaterLoc(SMLoc a, SMLoc b);
1804 SMLoc getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
1806 SMLoc getImmLoc(AMDGPUOperand::ImmTy
Type,
1810 bool validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
1817 std::optional<unsigned> checkVOPDRegBankConstraints(
const MCInst &Inst,
1820 bool tryVOPD(
const MCInst &Inst);
1821 bool tryVOPD3(
const MCInst &Inst);
1822 bool tryAnotherVOPDEncoding(
const MCInst &Inst);
1824 bool validateIntClampSupported(
const MCInst &Inst);
1825 bool validateMIMGAtomicDMask(
const MCInst &Inst);
1826 bool validateMIMGGatherDMask(
const MCInst &Inst);
1828 bool validateMIMGDataSize(
const MCInst &Inst, SMLoc IDLoc);
1829 bool validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc);
1830 bool validateMIMGD16(
const MCInst &Inst);
1832 bool validateTensorR128(
const MCInst &Inst);
1833 bool validateMIMGMSAA(
const MCInst &Inst);
1834 bool validateOpSel(
const MCInst &Inst);
1835 bool validateTrue16OpSel(
const MCInst &Inst);
1836 bool validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName);
1838 bool validateVccOperand(MCRegister
Reg)
const;
1843 bool validateAGPRLdSt(
const MCInst &Inst)
const;
1844 bool validateVGPRAlign(
const MCInst &Inst)
const;
1848 bool validateDivScale(
const MCInst &Inst);
1853 const unsigned CPol);
1858 unsigned getConstantBusLimit(
unsigned Opcode)
const;
1859 bool usesConstantBus(
const MCInst &Inst,
unsigned OpIdx);
1860 bool isInlineConstant(
const MCInst &Inst,
unsigned OpIdx)
const;
1861 unsigned findImplicitSGPRReadInVOP(
const MCInst &Inst)
const;
1863 bool isSupportedMnemo(StringRef Mnemo,
1864 const FeatureBitset &FBS);
1865 bool isSupportedMnemo(StringRef Mnemo,
1866 const FeatureBitset &FBS,
1867 ArrayRef<unsigned> Variants);
1868 bool checkUnsupportedInstruction(StringRef Name, SMLoc IDLoc);
1870 bool isId(
const StringRef Id)
const;
1871 bool isId(
const AsmToken &Token,
const StringRef Id)
const;
1873 StringRef getId()
const;
1874 bool trySkipId(
const StringRef Id);
1875 bool trySkipId(
const StringRef Pref,
const StringRef Id);
1879 bool parseString(StringRef &Val,
const StringRef ErrMsg =
"expected a string");
1880 bool parseId(StringRef &Val,
const StringRef ErrMsg =
"");
1886 StringRef getTokenStr()
const;
1887 AsmToken peekToken(
bool ShouldSkipSpace =
true);
1889 SMLoc getLoc()
const;
1893 void onBeginOfFile()
override;
1894 bool parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc)
override;
1905 bool parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
1906 const unsigned MaxVal,
const Twine &ErrMsg,
1908 bool parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
1909 const unsigned MinVal,
1910 const unsigned MaxVal,
1911 const StringRef ErrMsg);
1913 bool parseSwizzleOffset(int64_t &
Imm);
1914 bool parseSwizzleMacro(int64_t &
Imm);
1915 bool parseSwizzleQuadPerm(int64_t &
Imm);
1916 bool parseSwizzleBitmaskPerm(int64_t &
Imm);
1917 bool parseSwizzleBroadcast(int64_t &
Imm);
1918 bool parseSwizzleSwap(int64_t &
Imm);
1919 bool parseSwizzleReverse(int64_t &
Imm);
1920 bool parseSwizzleFFT(int64_t &
Imm);
1921 bool parseSwizzleRotate(int64_t &
Imm);
1924 int64_t parseGPRIdxMacro();
1932 OptionalImmIndexMap &OptionalIdx);
1941 OptionalImmIndexMap &OptionalIdx);
1943 OptionalImmIndexMap &OptionalIdx);
1948 bool parseDimId(
unsigned &Encoding);
1950 bool convertDppBoundCtrl(int64_t &BoundCtrl);
1954 int64_t parseDPPCtrlSel(StringRef Ctrl);
1955 int64_t parseDPPCtrlPerm();
1961 bool IsDPP8 =
false);
1967 AMDGPUOperand::ImmTy
Type);
1975 uint64_t BasicInstType,
1976 bool SkipDstVcc =
false,
1977 bool SkipSrcVcc =
false);
2085bool AMDGPUOperand::isInlinableImm(
MVT type)
const {
2095 if (!isImmTy(ImmTyNone)) {
2106 if (type == MVT::f64 || type == MVT::i64) {
2108 AsmParser->hasInv2PiInlineImm());
2111 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2130 APFloat::rmNearestTiesToEven, &Lost);
2137 uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2139 AsmParser->hasInv2PiInlineImm());
2144 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
2145 AsmParser->hasInv2PiInlineImm());
2149 if (type == MVT::f64 || type == MVT::i64) {
2151 AsmParser->hasInv2PiInlineImm());
2160 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
2161 type, AsmParser->hasInv2PiInlineImm());
2165 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
2166 AsmParser->hasInv2PiInlineImm());
2169bool AMDGPUOperand::isLiteralImm(MVT type)
const {
2171 if (!isImmTy(ImmTyNone)) {
2176 (type == MVT::i64 || type == MVT::f64) && AsmParser->has64BitLiterals();
2181 if (type == MVT::f64 && hasFPModifiers()) {
2201 if (type == MVT::f64) {
2206 if (type == MVT::i64) {
2219 MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2220 : (type == MVT::v2i16) ? MVT::f32
2221 : (type == MVT::v2f32) ? MVT::f32
2224 APFloat FPLiteral(APFloat::IEEEdouble(), APInt(64,
Imm.Val));
2228bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
2229 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
2232bool AMDGPUOperand::isVRegWithInputMods()
const {
2233 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2235 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2236 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2239template <
bool IsFake16>
2240bool AMDGPUOperand::isT16_Lo128VRegWithInputMods()
const {
2241 return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2242 : AMDGPU::VGPR_16_Lo128RegClassID);
2245template <
bool IsFake16>
bool AMDGPUOperand::isT16VRegWithInputMods()
const {
2246 return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2247 : AMDGPU::VGPR_16RegClassID);
2250bool AMDGPUOperand::isSDWAOperand(MVT type)
const {
2251 if (AsmParser->isVI())
2253 if (AsmParser->isGFX9Plus())
2254 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2258bool AMDGPUOperand::isSDWAFP16Operand()
const {
2259 return isSDWAOperand(MVT::f16);
2262bool AMDGPUOperand::isSDWAFP32Operand()
const {
2263 return isSDWAOperand(MVT::f32);
2266bool AMDGPUOperand::isSDWAInt16Operand()
const {
2267 return isSDWAOperand(MVT::i16);
2270bool AMDGPUOperand::isSDWAInt32Operand()
const {
2271 return isSDWAOperand(MVT::i32);
2274bool AMDGPUOperand::isBoolReg()
const {
2275 return isReg() && ((AsmParser->isWave64() && isSCSrc_b64()) ||
2276 (AsmParser->isWave32() && isSCSrc_b32()));
2279uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,
unsigned Size)
const
2281 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2284 const uint64_t FpSignMask = (1ULL << (
Size * 8 - 1));
2296void AMDGPUOperand::addImmOperands(MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2306 addLiteralImmOperand(Inst,
Imm.Val,
2308 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2310 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2315void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2316 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2321 if (ApplyModifiers) {
2324 Val = applyInputFPModifiers(Val,
Size);
2328 uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2330 bool CanUse64BitLiterals =
2331 AsmParser->has64BitLiterals() &&
2333 MCContext &Ctx = AsmParser->getContext();
2343 AsmParser->hasInv2PiInlineImm())) {
2351 bool HasMandatoryLiteral =
2354 if (
Literal.getLoBits(32) != 0 &&
2355 (InstDesc.getSize() != 4 || !AsmParser->has64BitLiterals()) &&
2356 !HasMandatoryLiteral) {
2357 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(
2359 "Can't encode literal as exact 64-bit floating-point operand. "
2360 "Low 32-bits will be set to zero");
2361 Val &= 0xffffffff00000000u;
2367 CanUse64BitLiterals &&
Lo_32(Val) != 0) {
2382 if (CanUse64BitLiterals &&
Lo_32(Val) != 0) {
2394 if (AsmParser->hasInv2PiInlineImm() &&
Literal == 0x3fc45f306725feed) {
2428 APFloat::rmNearestTiesToEven, &lost);
2432 uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2473 if (!AsmParser->has64BitLiterals() ||
2474 getModifiers().
Lit == LitModifier::Lit)
2495 if (!AsmParser->has64BitLiterals()) {
2496 Val =
static_cast<uint64_t
>(Val) << 32;
2503 if (getModifiers().
Lit == LitModifier::Lit ||
2504 (getModifiers().
Lit != LitModifier::Lit64 &&
2506 Val =
static_cast<uint64_t
>(Val) << 32;
2509 if (CanUse64BitLiterals &&
Lo_32(Val) != 0) {
2533 getModifiers().
Lit != LitModifier::Lit64)
2536 if (CanUse64BitLiterals &&
Lo_32(Val) != 0) {
2549void AMDGPUOperand::addRegOperands(MCInst &Inst,
unsigned N)
const {
2554bool AMDGPUOperand::isInlineValue()
const {
2562void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2573 if (Is == IS_VGPR) {
2577 return AMDGPU::VGPR_32RegClassID;
2579 return AMDGPU::VReg_64RegClassID;
2581 return AMDGPU::VReg_96RegClassID;
2583 return AMDGPU::VReg_128RegClassID;
2585 return AMDGPU::VReg_160RegClassID;
2587 return AMDGPU::VReg_192RegClassID;
2589 return AMDGPU::VReg_224RegClassID;
2591 return AMDGPU::VReg_256RegClassID;
2593 return AMDGPU::VReg_288RegClassID;
2595 return AMDGPU::VReg_320RegClassID;
2597 return AMDGPU::VReg_352RegClassID;
2599 return AMDGPU::VReg_384RegClassID;
2601 return AMDGPU::VReg_512RegClassID;
2603 return AMDGPU::VReg_1024RegClassID;
2605 }
else if (Is == IS_TTMP) {
2609 return AMDGPU::TTMP_32RegClassID;
2611 return AMDGPU::TTMP_64RegClassID;
2613 return AMDGPU::TTMP_128RegClassID;
2615 return AMDGPU::TTMP_256RegClassID;
2617 return AMDGPU::TTMP_512RegClassID;
2619 }
else if (Is == IS_SGPR) {
2623 return AMDGPU::SGPR_32RegClassID;
2625 return AMDGPU::SGPR_64RegClassID;
2627 return AMDGPU::SGPR_96RegClassID;
2629 return AMDGPU::SGPR_128RegClassID;
2631 return AMDGPU::SGPR_160RegClassID;
2633 return AMDGPU::SGPR_192RegClassID;
2635 return AMDGPU::SGPR_224RegClassID;
2637 return AMDGPU::SGPR_256RegClassID;
2639 return AMDGPU::SGPR_288RegClassID;
2641 return AMDGPU::SGPR_320RegClassID;
2643 return AMDGPU::SGPR_352RegClassID;
2645 return AMDGPU::SGPR_384RegClassID;
2647 return AMDGPU::SGPR_512RegClassID;
2649 }
else if (Is == IS_AGPR) {
2653 return AMDGPU::AGPR_32RegClassID;
2655 return AMDGPU::AReg_64RegClassID;
2657 return AMDGPU::AReg_96RegClassID;
2659 return AMDGPU::AReg_128RegClassID;
2661 return AMDGPU::AReg_160RegClassID;
2663 return AMDGPU::AReg_192RegClassID;
2665 return AMDGPU::AReg_224RegClassID;
2667 return AMDGPU::AReg_256RegClassID;
2669 return AMDGPU::AReg_288RegClassID;
2671 return AMDGPU::AReg_320RegClassID;
2673 return AMDGPU::AReg_352RegClassID;
2675 return AMDGPU::AReg_384RegClassID;
2677 return AMDGPU::AReg_512RegClassID;
2679 return AMDGPU::AReg_1024RegClassID;
2687 .
Case(
"exec", AMDGPU::EXEC)
2688 .
Case(
"vcc", AMDGPU::VCC)
2689 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2690 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2691 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2692 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2693 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2694 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2695 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2696 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2697 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2698 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2699 .
Case(
"src_flat_scratch_base_lo", AMDGPU::SRC_FLAT_SCRATCH_BASE_LO)
2700 .
Case(
"src_flat_scratch_base_hi", AMDGPU::SRC_FLAT_SCRATCH_BASE_HI)
2701 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2702 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2703 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2704 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2705 .
Case(
"m0", AMDGPU::M0)
2706 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2707 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2708 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2709 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2710 .
Case(
"scc", AMDGPU::SRC_SCC)
2711 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2712 .
Case(
"tba", AMDGPU::TBA)
2713 .
Case(
"tma", AMDGPU::TMA)
2714 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2715 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2716 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2717 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2718 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2719 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2720 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2721 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2722 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2723 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2724 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2725 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2726 .
Case(
"pc", AMDGPU::PC_REG)
2727 .
Case(
"null", AMDGPU::SGPR_NULL)
2731bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc,
2732 SMLoc &EndLoc,
bool RestoreOnFailure) {
2733 auto R = parseRegister();
2734 if (!R)
return true;
2736 RegNo =
R->getReg();
2737 StartLoc =
R->getStartLoc();
2738 EndLoc =
R->getEndLoc();
2742bool AMDGPUAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2744 return ParseRegister(
Reg, StartLoc, EndLoc,
false);
2747ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
2749 bool Result = ParseRegister(
Reg, StartLoc, EndLoc,
true);
2750 bool PendingErrors = getParser().hasPendingError();
2751 getParser().clearPendingErrors();
2759bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &
Reg,
unsigned &RegWidth,
2760 RegisterKind RegKind,
2761 MCRegister Reg1, SMLoc Loc) {
2764 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2769 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2770 Reg = AMDGPU::FLAT_SCR;
2774 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2775 Reg = AMDGPU::XNACK_MASK;
2779 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2784 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2789 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2794 Error(Loc,
"register does not fit in the list");
2800 if (Reg1 !=
Reg + RegWidth / 32) {
2801 Error(Loc,
"registers in a list must have consecutive indices");
2819 {{
"ttmp"}, IS_TTMP},
2825 return Kind == IS_VGPR ||
2833 if (Str.starts_with(
Reg.Name))
2839 return !Str.getAsInteger(10, Num);
2843AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2844 const AsmToken &NextToken)
const {
2859 StringRef RegSuffix = Str.substr(
RegName.size());
2860 if (!RegSuffix.
empty()) {
2878AMDGPUAsmParser::isRegister()
2880 return isRegister(
getToken(), peekToken());
2883MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
unsigned RegNum,
2884 unsigned SubReg,
unsigned RegWidth,
2888 unsigned AlignSize = 1;
2889 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2895 if (RegNum % AlignSize != 0) {
2896 Error(Loc,
"invalid register alignment");
2897 return MCRegister();
2900 unsigned RegIdx = RegNum / AlignSize;
2903 Error(Loc,
"invalid or unsupported register size");
2904 return MCRegister();
2908 const MCRegisterClass RC =
TRI->getRegClass(RCID);
2909 if (RegIdx >= RC.
getNumRegs() || (RegKind == IS_VGPR && RegIdx > 255)) {
2910 Error(Loc,
"register index is out of range");
2911 return AMDGPU::NoRegister;
2914 if (RegKind == IS_VGPR && !
isGFX1250() && RegIdx + RegWidth / 32 > 256) {
2915 Error(Loc,
"register index is out of range");
2916 return MCRegister();
2932bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth,
2934 int64_t RegLo, RegHi;
2938 SMLoc FirstIdxLoc = getLoc();
2945 SecondIdxLoc = getLoc();
2956 Error(FirstIdxLoc,
"invalid register index");
2961 Error(SecondIdxLoc,
"invalid register index");
2965 if (RegLo > RegHi) {
2966 Error(FirstIdxLoc,
"first register index should not exceed second index");
2970 if (RegHi == RegLo) {
2971 StringRef RegSuffix = getTokenStr();
2972 if (RegSuffix ==
".l") {
2975 }
else if (RegSuffix ==
".h") {
2981 Num =
static_cast<unsigned>(RegLo);
2982 RegWidth = 32 * ((RegHi - RegLo) + 1);
2987MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2990 SmallVectorImpl<AsmToken> &Tokens) {
2996 RegKind = IS_SPECIAL;
3003MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
3006 SmallVectorImpl<AsmToken> &Tokens) {
3008 StringRef
RegName = getTokenStr();
3009 auto Loc = getLoc();
3013 Error(Loc,
"invalid register name");
3014 return MCRegister();
3022 unsigned SubReg = NoSubRegister;
3023 if (!RegSuffix.
empty()) {
3031 Error(Loc,
"invalid register index");
3032 return MCRegister();
3037 if (!ParseRegRange(RegNum, RegWidth,
SubReg))
3038 return MCRegister();
3041 return getRegularReg(RegKind, RegNum,
SubReg, RegWidth, Loc);
3044MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
3045 unsigned &RegNum,
unsigned &RegWidth,
3046 SmallVectorImpl<AsmToken> &Tokens) {
3048 auto ListLoc = getLoc();
3051 "expected a register or a list of registers")) {
3052 return MCRegister();
3057 auto Loc = getLoc();
3058 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
3059 return MCRegister();
3060 if (RegWidth != 32) {
3061 Error(Loc,
"expected a single 32-bit register");
3062 return MCRegister();
3066 RegisterKind NextRegKind;
3068 unsigned NextRegNum, NextRegWidth;
3071 if (!ParseAMDGPURegister(NextRegKind, NextReg,
3072 NextRegNum, NextRegWidth,
3074 return MCRegister();
3076 if (NextRegWidth != 32) {
3077 Error(Loc,
"expected a single 32-bit register");
3078 return MCRegister();
3080 if (NextRegKind != RegKind) {
3081 Error(Loc,
"registers in a list must be of the same kind");
3082 return MCRegister();
3084 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
3085 return MCRegister();
3089 "expected a comma or a closing square bracket")) {
3090 return MCRegister();
3094 Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3099bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3100 MCRegister &
Reg,
unsigned &RegNum,
3102 SmallVectorImpl<AsmToken> &Tokens) {
3103 auto Loc = getLoc();
3107 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3109 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3111 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3116 assert(Parser.hasPendingError());
3120 if (!subtargetHasRegister(*
TRI,
Reg)) {
3121 if (
Reg == AMDGPU::SGPR_NULL) {
3122 Error(Loc,
"'null' operand is not supported on this GPU");
3125 " register not available on this GPU");
3133bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3134 MCRegister &
Reg,
unsigned &RegNum,
3136 bool RestoreOnFailure ) {
3140 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
3141 if (RestoreOnFailure) {
3142 while (!Tokens.
empty()) {
3151std::optional<StringRef>
3152AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3155 return StringRef(
".amdgcn.next_free_vgpr");
3157 return StringRef(
".amdgcn.next_free_sgpr");
3159 return std::nullopt;
3163void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3164 auto SymbolName = getGprCountSymbolName(RegKind);
3165 assert(SymbolName &&
"initializing invalid register kind");
3171bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3172 unsigned DwordRegIndex,
3173 unsigned RegWidth) {
3178 auto SymbolName = getGprCountSymbolName(RegKind);
3183 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
3187 return !
Error(getLoc(),
3188 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
3192 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3194 if (OldCount <= NewMax)
3200std::unique_ptr<AMDGPUOperand>
3201AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
3203 SMLoc StartLoc = Tok.getLoc();
3204 SMLoc EndLoc = Tok.getEndLoc();
3205 RegisterKind RegKind;
3207 unsigned RegNum, RegWidth;
3209 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
3213 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3216 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3217 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
3224 if (isRegister() || isModifier())
3227 if (
Lit == LitModifier::None) {
3228 if (trySkipId(
"lit"))
3229 Lit = LitModifier::Lit;
3230 else if (trySkipId(
"lit64"))
3231 Lit = LitModifier::Lit64;
3233 if (
Lit != LitModifier::None) {
3236 ParseStatus S = parseImm(
Operands, HasSP3AbsModifier,
Lit);
3245 const auto& NextTok = peekToken();
3248 bool Negate =
false;
3256 AMDGPUOperand::Modifiers Mods;
3264 StringRef Num = getTokenStr();
3267 APFloat RealVal(APFloat::IEEEdouble());
3268 auto roundMode = APFloat::rmNearestTiesToEven;
3269 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3272 RealVal.changeSign();
3275 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(), S,
3276 AMDGPUOperand::ImmTyNone,
true));
3277 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3278 Op.setModifiers(Mods);
3287 if (HasSP3AbsModifier) {
3296 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
3299 if (Parser.parseExpression(Expr))
3303 if (Expr->evaluateAsAbsolute(IntVal)) {
3304 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
3305 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3306 Op.setModifiers(Mods);
3308 if (
Lit != LitModifier::None)
3310 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
3323 if (
auto R = parseRegister()) {
3333 ParseStatus Res = parseReg(
Operands);
3342AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3345 return str ==
"abs" || str ==
"neg" || str ==
"sext";
3351AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3356AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3357 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
3361AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
3362 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3379AMDGPUAsmParser::isModifier() {
3382 AsmToken NextToken[2];
3383 peekTokens(NextToken);
3385 return isOperandModifier(Tok, NextToken[0]) ||
3386 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3387 isOpcodeModifierWithVal(Tok, NextToken[0]);
3413AMDGPUAsmParser::parseSP3NegModifier() {
3415 AsmToken NextToken[2];
3416 peekTokens(NextToken);
3419 (isRegister(NextToken[0], NextToken[1]) ||
3421 isId(NextToken[0],
"abs"))) {
3438 return Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3440 SP3Neg = parseSP3NegModifier();
3443 Neg = trySkipId(
"neg");
3445 return Error(Loc,
"expected register or immediate");
3449 Abs = trySkipId(
"abs");
3454 if (trySkipId(
"lit")) {
3455 Lit = LitModifier::Lit;
3458 }
else if (trySkipId(
"lit64")) {
3459 Lit = LitModifier::Lit64;
3462 if (!has64BitLiterals())
3463 return Error(Loc,
"lit64 is not supported on this GPU");
3469 return Error(Loc,
"expected register or immediate");
3478 return (SP3Neg || Neg || SP3Abs || Abs ||
Lit != LitModifier::None)
3482 if (
Lit != LitModifier::None && !
Operands.back()->isImm())
3483 Error(Loc,
"expected immediate with lit modifier");
3485 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3491 if (
Lit != LitModifier::None &&
3495 AMDGPUOperand::Modifiers Mods;
3496 Mods.Abs = Abs || SP3Abs;
3497 Mods.Neg = Neg || SP3Neg;
3500 if (Mods.hasFPModifiers() ||
Lit != LitModifier::None) {
3501 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3503 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3504 Op.setModifiers(Mods);
3512 bool Sext = trySkipId(
"sext");
3513 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3528 AMDGPUOperand::Modifiers Mods;
3531 if (Mods.hasIntModifiers()) {
3532 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3534 return Error(
Op.getStartLoc(),
"expected an absolute expression");
3535 Op.setModifiers(Mods);
3542 return parseRegOrImmWithFPInputMods(
Operands,
false);
3546 return parseRegOrImmWithIntInputMods(
Operands,
false);
3550 auto Loc = getLoc();
3551 if (trySkipId(
"off")) {
3552 Operands.push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3553 AMDGPUOperand::ImmTyOff,
false));
3560 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3569unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3576 return Match_InvalidOperand;
3578 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3579 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3582 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::dst_sel);
3584 if (!
Op.isImm() ||
Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3585 return Match_InvalidOperand;
3593 if (tryAnotherVOPDEncoding(Inst))
3594 return Match_InvalidOperand;
3596 return Match_Success;
3600 static const unsigned Variants[] = {
3610ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants()
const {
3611 if (isForcedDPP() && isForcedVOP3()) {
3615 if (getForcedEncodingSize() == 32) {
3620 if (isForcedVOP3()) {
3625 if (isForcedSDWA()) {
3631 if (isForcedDPP()) {
3639StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3640 if (isForcedDPP() && isForcedVOP3())
3643 if (getForcedEncodingSize() == 32)
3658unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3662 case AMDGPU::FLAT_SCR:
3664 case AMDGPU::VCC_LO:
3665 case AMDGPU::VCC_HI:
3672 return AMDGPU::NoRegister;
3679bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3680 unsigned OpIdx)
const {
3734unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3740 case AMDGPU::V_LSHLREV_B64_e64:
3741 case AMDGPU::V_LSHLREV_B64_gfx10:
3742 case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3743 case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3744 case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3745 case AMDGPU::V_LSHRREV_B64_e64:
3746 case AMDGPU::V_LSHRREV_B64_gfx10:
3747 case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3748 case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3749 case AMDGPU::V_ASHRREV_I64_e64:
3750 case AMDGPU::V_ASHRREV_I64_gfx10:
3751 case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3752 case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3753 case AMDGPU::V_LSHL_B64_e64:
3754 case AMDGPU::V_LSHR_B64_e64:
3755 case AMDGPU::V_ASHR_I64_e64:
3768 bool AddMandatoryLiterals =
false) {
3771 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::imm) : -1;
3775 AddMandatoryLiterals ? getNamedOperandIdx(Opcode, OpName::immX) : -1;
3777 return {getNamedOperandIdx(Opcode, OpName::src0X),
3778 getNamedOperandIdx(Opcode, OpName::vsrc1X),
3779 getNamedOperandIdx(Opcode, OpName::vsrc2X),
3780 getNamedOperandIdx(Opcode, OpName::src0Y),
3781 getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3782 getNamedOperandIdx(Opcode, OpName::vsrc2Y),
3787 return {getNamedOperandIdx(Opcode, OpName::src0),
3788 getNamedOperandIdx(Opcode, OpName::src1),
3789 getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3792bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3795 return !isInlineConstant(Inst,
OpIdx);
3802 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3813 const unsigned Opcode = Inst.
getOpcode();
3814 if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3817 if (!LaneSelOp.
isReg())
3820 return LaneSelReg ==
M0 || LaneSelReg == M0_gfxpre11;
3823bool AMDGPUAsmParser::validateConstantBusLimitations(
3825 const unsigned Opcode = Inst.
getOpcode();
3826 const MCInstrDesc &
Desc = MII.
get(Opcode);
3827 MCRegister LastSGPR;
3828 unsigned ConstantBusUseCount = 0;
3829 unsigned NumLiterals = 0;
3830 unsigned LiteralSize;
3832 if (!(
Desc.TSFlags &
3847 SmallDenseSet<unsigned> SGPRsUsed;
3848 unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3849 if (SGPRUsed != AMDGPU::NoRegister) {
3850 SGPRsUsed.
insert(SGPRUsed);
3851 ++ConstantBusUseCount;
3856 unsigned ConstantBusLimit = getConstantBusLimit(Opcode);
3858 for (
int OpIdx : OpIndices) {
3863 if (usesConstantBus(Inst,
OpIdx)) {
3872 if (SGPRsUsed.
insert(LastSGPR).second) {
3873 ++ConstantBusUseCount;
3893 if (NumLiterals == 0) {
3896 }
else if (LiteralSize !=
Size) {
3902 if (ConstantBusUseCount + NumLiterals > ConstantBusLimit) {
3904 "invalid operand (violates constant bus restrictions)");
3911std::optional<unsigned>
3912AMDGPUAsmParser::checkVOPDRegBankConstraints(
const MCInst &Inst,
bool AsVOPD3) {
3914 const unsigned Opcode = Inst.
getOpcode();
3920 auto getVRegIdx = [&](unsigned,
unsigned OperandIdx) {
3921 const MCOperand &Opr = Inst.
getOperand(OperandIdx);
3929 bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12 ||
3930 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx1250 ||
3931 Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_e96_gfx1250;
3935 for (
auto OpName : {OpName::src0X, OpName::src0Y}) {
3936 int I = getNamedOperandIdx(Opcode, OpName);
3940 int64_t
Imm =
Op.getImm();
3946 for (
auto OpName : {OpName::vsrc1X, OpName::vsrc1Y, OpName::vsrc2X,
3947 OpName::vsrc2Y, OpName::imm}) {
3948 int I = getNamedOperandIdx(Opcode, OpName);
3958 auto InvalidCompOprIdx = InstInfo.getInvalidCompOperandIndex(
3959 getVRegIdx, *
TRI, SkipSrc, AllowSameVGPR, AsVOPD3);
3961 return InvalidCompOprIdx;
3964bool AMDGPUAsmParser::validateVOPD(
const MCInst &Inst,
3971 for (
const std::unique_ptr<MCParsedAsmOperand> &Operand :
Operands) {
3972 AMDGPUOperand &
Op = (AMDGPUOperand &)*Operand;
3973 if ((
Op.isRegKind() ||
Op.isImmTy(AMDGPUOperand::ImmTyNone)) &&
3975 Error(
Op.getStartLoc(),
"ABS not allowed in VOPD3 instructions");
3979 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst, AsVOPD3);
3980 if (!InvalidCompOprIdx.has_value())
3983 auto CompOprIdx = *InvalidCompOprIdx;
3986 std::max(InstInfo[
VOPD::X].getIndexInParsedOperands(CompOprIdx),
3987 InstInfo[
VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3990 auto Loc = ((AMDGPUOperand &)*
Operands[ParsedIdx]).getStartLoc();
3991 if (CompOprIdx == VOPD::Component::DST) {
3993 Error(Loc,
"dst registers must be distinct");
3995 Error(Loc,
"one dst register must be even and the other odd");
3997 auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3998 Error(Loc, Twine(
"src") + Twine(CompSrcIdx) +
3999 " operands must use different VGPR banks");
4007bool AMDGPUAsmParser::tryVOPD3(
const MCInst &Inst) {
4009 auto InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
false);
4010 if (!InvalidCompOprIdx.has_value())
4014 InvalidCompOprIdx = checkVOPDRegBankConstraints(Inst,
true);
4015 if (InvalidCompOprIdx.has_value()) {
4020 if (*InvalidCompOprIdx == VOPD::Component::DST)
4033bool AMDGPUAsmParser::tryVOPD(
const MCInst &Inst) {
4034 const unsigned Opcode = Inst.
getOpcode();
4049 for (
auto OpName : {OpName::src0X_modifiers, OpName::src0Y_modifiers,
4050 OpName::vsrc1X_modifiers, OpName::vsrc1Y_modifiers,
4051 OpName::vsrc2X_modifiers, OpName::vsrc2Y_modifiers}) {
4052 int I = getNamedOperandIdx(Opcode, OpName);
4059 return !tryVOPD3(Inst);
4064bool AMDGPUAsmParser::tryAnotherVOPDEncoding(
const MCInst &Inst) {
4065 const unsigned Opcode = Inst.
getOpcode();
4070 return tryVOPD(Inst);
4071 return tryVOPD3(Inst);
4074bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
4080 int ClampIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::clamp);
4091bool AMDGPUAsmParser::validateMIMGDataSize(
const MCInst &Inst,
SMLoc IDLoc) {
4099 int VDataIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdata);
4100 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4101 int TFEIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::tfe);
4110 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
4115 bool IsPackedD16 =
false;
4119 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4120 IsPackedD16 = D16Idx >= 0;
4125 if ((VDataSize / 4) ==
DataSize + TFESize)
4130 Modifiers = IsPackedD16 ?
"dmask and d16" :
"dmask";
4132 Modifiers = IsPackedD16 ?
"dmask, d16 and tfe" :
"dmask and tfe";
4134 Error(IDLoc,
Twine(
"image data size does not match ") + Modifiers);
4138bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst, SMLoc IDLoc) {
4147 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4149 int VAddr0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr0);
4151 ? AMDGPU::OpName::srsrc
4152 : AMDGPU::OpName::rsrc;
4153 int SrsrcIdx = AMDGPU::getNamedOperandIdx(
Opc, RSrcOpName);
4154 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4155 int A16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::a16);
4159 assert(SrsrcIdx > VAddr0Idx);
4162 if (BaseOpcode->
BVH) {
4163 if (IsA16 == BaseOpcode->
A16)
4165 Error(IDLoc,
"image address size does not match a16");
4171 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
4172 unsigned ActualAddrSize =
4173 IsNSA ? SrsrcIdx - VAddr0Idx
4176 unsigned ExpectedAddrSize =
4180 if (hasPartialNSAEncoding() &&
4183 int VAddrLastIdx = SrsrcIdx - 1;
4184 unsigned VAddrLastSize =
4187 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
4190 if (ExpectedAddrSize > 12)
4191 ExpectedAddrSize = 16;
4196 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4200 if (ActualAddrSize == ExpectedAddrSize)
4203 Error(IDLoc,
"image address size does not match dim and a16");
4207bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
4214 if (!
Desc.mayLoad() || !
Desc.mayStore())
4217 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4224 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4227bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
4235 int DMaskIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dmask);
4243 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4246bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst,
4261 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4262 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4269bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
4277 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4280 if (!BaseOpcode->
MSAA)
4283 int DimIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dim);
4289 return DimInfo->
MSAA;
4295 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4296 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4297 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4307bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
4316 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4319 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4327 Error(getOperandLoc(
Operands, Src0Idx),
"source operand must be a VGPR");
4331bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
4336 if (
Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4339 const int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4342 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4350 "source operand must be either a VGPR or an inline constant");
4357bool AMDGPUAsmParser::validateMAISrc2(
const MCInst &Inst,
4360 const MCInstrDesc &
Desc = MII.
get(Opcode);
4363 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4366 const int Src2Idx = getNamedOperandIdx(Opcode, OpName::src2);
4370 if (Inst.
getOperand(Src2Idx).
isImm() && isInlineConstant(Inst, Src2Idx)) {
4372 "inline constants are not allowed for this operand");
4379bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
4387 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
4388 if (BlgpIdx != -1) {
4389 if (
const MFMA_F8F6F4_Info *
Info = AMDGPU::isMFMA_F8F6F4(
Opc)) {
4390 int CbszIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
4400 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4402 "wrong register tuple size for cbsz value " + Twine(CBSZ));
4407 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4409 "wrong register tuple size for blgp value " + Twine(BLGP));
4417 const int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4421 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4425 MCRegister Src2Reg = Src2.
getReg();
4427 if (Src2Reg == DstReg)
4431 if (
TRI->getRegClass(
Desc.operands()[0].RegClass).getSizeInBits() <= 128)
4434 if (
TRI->regsOverlap(Src2Reg, DstReg)) {
4436 "source 2 operand must not partially overlap with dst");
4443bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
4447 case V_DIV_SCALE_F32_gfx6_gfx7:
4448 case V_DIV_SCALE_F32_vi:
4449 case V_DIV_SCALE_F32_gfx10:
4450 case V_DIV_SCALE_F64_gfx6_gfx7:
4451 case V_DIV_SCALE_F64_vi:
4452 case V_DIV_SCALE_F64_gfx10:
4458 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
4459 AMDGPU::OpName::src2_modifiers,
4460 AMDGPU::OpName::src2_modifiers}) {
4471bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
4479 int D16Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::d16);
4488bool AMDGPUAsmParser::validateTensorR128(
const MCInst &Inst) {
4495 int R128Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::r128);
4503 case AMDGPU::V_SUBREV_F32_e32:
4504 case AMDGPU::V_SUBREV_F32_e64:
4505 case AMDGPU::V_SUBREV_F32_e32_gfx10:
4506 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4507 case AMDGPU::V_SUBREV_F32_e32_vi:
4508 case AMDGPU::V_SUBREV_F32_e64_gfx10:
4509 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4510 case AMDGPU::V_SUBREV_F32_e64_vi:
4512 case AMDGPU::V_SUBREV_CO_U32_e32:
4513 case AMDGPU::V_SUBREV_CO_U32_e64:
4514 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4515 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4517 case AMDGPU::V_SUBBREV_U32_e32:
4518 case AMDGPU::V_SUBBREV_U32_e64:
4519 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4520 case AMDGPU::V_SUBBREV_U32_e32_vi:
4521 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4522 case AMDGPU::V_SUBBREV_U32_e64_vi:
4524 case AMDGPU::V_SUBREV_U32_e32:
4525 case AMDGPU::V_SUBREV_U32_e64:
4526 case AMDGPU::V_SUBREV_U32_e32_gfx9:
4527 case AMDGPU::V_SUBREV_U32_e32_vi:
4528 case AMDGPU::V_SUBREV_U32_e64_gfx9:
4529 case AMDGPU::V_SUBREV_U32_e64_vi:
4531 case AMDGPU::V_SUBREV_F16_e32:
4532 case AMDGPU::V_SUBREV_F16_e64:
4533 case AMDGPU::V_SUBREV_F16_e32_gfx10:
4534 case AMDGPU::V_SUBREV_F16_e32_vi:
4535 case AMDGPU::V_SUBREV_F16_e64_gfx10:
4536 case AMDGPU::V_SUBREV_F16_e64_vi:
4538 case AMDGPU::V_SUBREV_U16_e32:
4539 case AMDGPU::V_SUBREV_U16_e64:
4540 case AMDGPU::V_SUBREV_U16_e32_vi:
4541 case AMDGPU::V_SUBREV_U16_e64_vi:
4543 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4544 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4545 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4547 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4548 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4550 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4551 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4553 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4554 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4556 case AMDGPU::V_LSHRREV_B32_e32:
4557 case AMDGPU::V_LSHRREV_B32_e64:
4558 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4559 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4560 case AMDGPU::V_LSHRREV_B32_e32_vi:
4561 case AMDGPU::V_LSHRREV_B32_e64_vi:
4562 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4563 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4565 case AMDGPU::V_ASHRREV_I32_e32:
4566 case AMDGPU::V_ASHRREV_I32_e64:
4567 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4568 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4569 case AMDGPU::V_ASHRREV_I32_e32_vi:
4570 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4571 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4572 case AMDGPU::V_ASHRREV_I32_e64_vi:
4574 case AMDGPU::V_LSHLREV_B32_e32:
4575 case AMDGPU::V_LSHLREV_B32_e64:
4576 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4577 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4578 case AMDGPU::V_LSHLREV_B32_e32_vi:
4579 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4580 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4581 case AMDGPU::V_LSHLREV_B32_e64_vi:
4583 case AMDGPU::V_LSHLREV_B16_e32:
4584 case AMDGPU::V_LSHLREV_B16_e64:
4585 case AMDGPU::V_LSHLREV_B16_e32_vi:
4586 case AMDGPU::V_LSHLREV_B16_e64_vi:
4587 case AMDGPU::V_LSHLREV_B16_gfx10:
4589 case AMDGPU::V_LSHRREV_B16_e32:
4590 case AMDGPU::V_LSHRREV_B16_e64:
4591 case AMDGPU::V_LSHRREV_B16_e32_vi:
4592 case AMDGPU::V_LSHRREV_B16_e64_vi:
4593 case AMDGPU::V_LSHRREV_B16_gfx10:
4595 case AMDGPU::V_ASHRREV_I16_e32:
4596 case AMDGPU::V_ASHRREV_I16_e64:
4597 case AMDGPU::V_ASHRREV_I16_e32_vi:
4598 case AMDGPU::V_ASHRREV_I16_e64_vi:
4599 case AMDGPU::V_ASHRREV_I16_gfx10:
4601 case AMDGPU::V_LSHLREV_B64_e64:
4602 case AMDGPU::V_LSHLREV_B64_gfx10:
4603 case AMDGPU::V_LSHLREV_B64_vi:
4605 case AMDGPU::V_LSHRREV_B64_e64:
4606 case AMDGPU::V_LSHRREV_B64_gfx10:
4607 case AMDGPU::V_LSHRREV_B64_vi:
4609 case AMDGPU::V_ASHRREV_I64_e64:
4610 case AMDGPU::V_ASHRREV_I64_gfx10:
4611 case AMDGPU::V_ASHRREV_I64_vi:
4613 case AMDGPU::V_PK_LSHLREV_B16:
4614 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4615 case AMDGPU::V_PK_LSHLREV_B16_vi:
4617 case AMDGPU::V_PK_LSHRREV_B16:
4618 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4619 case AMDGPU::V_PK_LSHRREV_B16_vi:
4620 case AMDGPU::V_PK_ASHRREV_I16:
4621 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4622 case AMDGPU::V_PK_ASHRREV_I16_vi:
4629bool AMDGPUAsmParser::validateLdsDirect(
const MCInst &Inst,
4631 using namespace SIInstrFlags;
4632 const unsigned Opcode = Inst.
getOpcode();
4633 const MCInstrDesc &
Desc = MII.
get(Opcode);
4638 if ((
Desc.TSFlags & Enc) == 0)
4641 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4642 auto SrcIdx = getNamedOperandIdx(Opcode, SrcName);
4646 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4650 "lds_direct is not supported on this GPU");
4656 "lds_direct cannot be used with this instruction");
4660 if (SrcName != OpName::src0) {
4662 "lds_direct may be used as src0 only");
4672 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
4673 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4674 if (
Op.isFlatOffset())
4675 return Op.getStartLoc();
4680bool AMDGPUAsmParser::validateOffset(
const MCInst &Inst,
4683 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4689 return validateFlatOffset(Inst,
Operands);
4692 return validateSMEMOffset(Inst,
Operands);
4698 const unsigned OffsetSize = 24;
4699 if (!
isUIntN(OffsetSize - 1,
Op.getImm())) {
4701 Twine(
"expected a ") + Twine(OffsetSize - 1) +
4702 "-bit unsigned offset for buffer ops");
4706 const unsigned OffsetSize = 16;
4707 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4709 Twine(
"expected a ") + Twine(OffsetSize) +
"-bit unsigned offset");
4716bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4723 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4727 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4729 "flat offset modifier is not supported on this GPU");
4736 bool AllowNegative =
4739 if (!
isIntN(OffsetSize,
Op.getImm()) || (!AllowNegative &&
Op.getImm() < 0)) {
4741 Twine(
"expected a ") +
4742 (AllowNegative ? Twine(OffsetSize) +
"-bit signed offset"
4743 : Twine(OffsetSize - 1) +
"-bit unsigned offset"));
4752 for (
unsigned i = 2, e =
Operands.size(); i != e; ++i) {
4753 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
4754 if (
Op.isSMEMOffset() ||
Op.isSMEMOffsetMod())
4755 return Op.getStartLoc();
4760bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4770 auto OpNum = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4786 ?
"expected a 23-bit unsigned offset for buffer ops"
4787 :
isGFX12Plus() ?
"expected a 24-bit signed offset"
4788 : (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset"
4789 :
"expected a 21-bit signed offset");
4794bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst,
4797 const MCInstrDesc &
Desc = MII.
get(Opcode);
4801 const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4802 const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4804 const int OpIndices[] = { Src0Idx, Src1Idx };
4806 unsigned NumExprs = 0;
4807 unsigned NumLiterals = 0;
4810 for (
int OpIdx : OpIndices) {
4811 if (
OpIdx == -1)
break;
4816 std::optional<int64_t>
Imm;
4819 }
else if (MO.
isExpr()) {
4826 if (!
Imm.has_value()) {
4828 }
else if (!isInlineConstant(Inst,
OpIdx)) {
4832 if (NumLiterals == 0 || LiteralValue !=
Value) {
4840 if (NumLiterals + NumExprs <= 1)
4844 "only one unique literal operand is allowed");
4848bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4851 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4861 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4862 if (OpSelIdx != -1) {
4866 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4867 if (OpSelHiIdx != -1) {
4876 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4886 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0);
4887 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
4888 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4889 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
4891 const MCOperand &Src0 = Inst.
getOperand(Src0Idx);
4892 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
4898 auto VerifyOneSGPR = [
OpSel, OpSelHi](
unsigned Index) ->
bool {
4900 return ((OpSel & Mask) == 0) && ((OpSelHi &
Mask) == 0);
4910 int Src2Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2);
4911 if (Src2Idx != -1) {
4912 const MCOperand &Src2 = Inst.
getOperand(Src2Idx);
4922bool AMDGPUAsmParser::validateTrue16OpSel(
const MCInst &Inst) {
4923 if (!hasTrue16Insts())
4925 const MCRegisterInfo *
MRI = getMRI();
4927 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
4933 if (OpSelOpValue == 0)
4935 unsigned OpCount = 0;
4936 for (AMDGPU::OpName OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
4937 AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) {
4938 int OpIdx = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), OpName);
4943 MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(
Op.getReg())) {
4945 bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0);
4946 if (OpSelOpIsHi != VGPRSuffixIsHi)
4955bool AMDGPUAsmParser::validateNeg(
const MCInst &Inst, AMDGPU::OpName OpName) {
4956 assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi);
4969 int NegIdx = AMDGPU::getNamedOperandIdx(
Opc, OpName);
4980 const AMDGPU::OpName SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4981 AMDGPU::OpName::src1_modifiers,
4982 AMDGPU::OpName::src2_modifiers};
4984 for (
unsigned i = 0; i < 3; ++i) {
4994bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4997 int DppCtrlIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp_ctrl);
4998 if (DppCtrlIdx >= 0) {
5005 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl,
Operands);
5006 Error(S,
isGFX12() ?
"DP ALU dpp only supports row_share"
5007 :
"DP ALU dpp only supports row_newbcast");
5012 int Dpp8Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::dpp8);
5013 bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
5016 int Src1Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src1);
5018 const MCOperand &Src1 = Inst.
getOperand(Src1Idx);
5022 "invalid operand for instruction");
5027 "src1 immediate operand invalid for instruction");
5037bool AMDGPUAsmParser::validateVccOperand(MCRegister
Reg)
const {
5038 return (
Reg == AMDGPU::VCC && isWave64()) ||
5039 (
Reg == AMDGPU::VCC_LO && isWave32());
5043bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
5046 const MCInstrDesc &
Desc = MII.
get(Opcode);
5047 bool HasMandatoryLiteral = getNamedOperandIdx(Opcode, OpName::imm) != -1;
5049 !HasMandatoryLiteral && !
isVOPD(Opcode))
5054 std::optional<unsigned> LiteralOpIdx;
5057 for (
int OpIdx : OpIndices) {
5067 std::optional<int64_t>
Imm;
5073 bool IsAnotherLiteral =
false;
5074 if (!
Imm.has_value()) {
5076 IsAnotherLiteral =
true;
5077 }
else if (!isInlineConstant(Inst,
OpIdx)) {
5082 HasMandatoryLiteral);
5088 !IsForcedFP64 && (!has64BitLiterals() ||
Desc.getSize() != 4)) {
5090 "invalid operand for instruction");
5094 if (IsFP64 && IsValid32Op && !IsForcedFP64)
5101 if (IsAnotherLiteral && !HasMandatoryLiteral &&
5102 !getFeatureBits()[FeatureVOP3Literal]) {
5104 "literal operands are not supported");
5108 if (LiteralOpIdx && IsAnotherLiteral) {
5110 getOperandLoc(
Operands, *LiteralOpIdx)),
5111 "only one unique literal operand is allowed");
5115 if (IsAnotherLiteral)
5116 LiteralOpIdx =
OpIdx;
5139bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
5147 ? AMDGPU::OpName::data0
5148 : AMDGPU::OpName::vdata;
5150 const MCRegisterInfo *
MRI = getMRI();
5156 if (Data2Areg >= 0 && Data2Areg != DataAreg)
5160 auto FB = getFeatureBits();
5161 if (FB[AMDGPU::FeatureGFX90AInsts]) {
5162 if (DataAreg < 0 || DstAreg < 0)
5164 return DstAreg == DataAreg;
5167 return DstAreg < 1 && DataAreg < 1;
5170bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
5171 auto FB = getFeatureBits();
5172 if (!FB[AMDGPU::FeatureRequiresAlignedVGPRs])
5176 const MCRegisterInfo *
MRI = getMRI();
5179 if (FB[AMDGPU::FeatureGFX90AInsts] &&
Opc == AMDGPU::DS_READ_B96_TR_B6_vi)
5182 if (FB[AMDGPU::FeatureGFX1250Insts]) {
5186 case AMDGPU::DS_LOAD_TR6_B96:
5187 case AMDGPU::DS_LOAD_TR6_B96_gfx12:
5191 case AMDGPU::GLOBAL_LOAD_TR6_B96:
5192 case AMDGPU::GLOBAL_LOAD_TR6_B96_gfx1250: {
5196 int VAddrIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vaddr);
5197 if (VAddrIdx != -1) {
5199 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5200 if ((
Sub - AMDGPU::VGPR0) & 1)
5205 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR:
5206 case AMDGPU::GLOBAL_LOAD_TR6_B96_SADDR_gfx1250:
5211 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5212 const MCRegisterClass &AGPR32 =
MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
5218 MCRegister
Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
5232 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
5233 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
5235 return Op.getStartLoc();
5240bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
5243 int BlgpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
5246 SMLoc BLGPLoc = getBLGPLoc(
Operands);
5249 bool IsNeg = StringRef(BLGPLoc.
getPointer()).starts_with(
"neg:");
5250 auto FB = getFeatureBits();
5251 bool UsesNeg =
false;
5252 if (FB[AMDGPU::FeatureGFX940Insts]) {
5254 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
5255 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
5256 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
5257 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
5262 if (IsNeg == UsesNeg)
5266 UsesNeg ?
"invalid modifier: blgp is not supported"
5267 :
"invalid modifier: neg is not supported");
5272bool AMDGPUAsmParser::validateWaitCnt(
const MCInst &Inst,
5278 if (
Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
5279 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
5280 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
5281 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
5284 int Src0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::sdst);
5287 if (
Reg == AMDGPU::SGPR_NULL)
5290 Error(getOperandLoc(
Operands, Src0Idx),
"src0 must be null");
5294bool AMDGPUAsmParser::validateDS(
const MCInst &Inst,
5300 return validateGWS(Inst,
Operands);
5305 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::gds);
5310 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS,
Operands);
5311 Error(S,
"gds modifier is not supported on this GPU");
5319bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
5321 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
5325 if (
Opc != AMDGPU::DS_GWS_INIT_vi &&
Opc != AMDGPU::DS_GWS_BARRIER_vi &&
5326 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
5329 const MCRegisterInfo *
MRI = getMRI();
5330 const MCRegisterClass &VGPR32 =
MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
5332 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::data0);
5335 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
5337 Error(getOperandLoc(
Operands, Data0Pos),
"vgpr must be even aligned");
5344bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
5347 int CPolPos = AMDGPU::getNamedOperandIdx(Inst.
getOpcode(),
5348 AMDGPU::OpName::cpol);
5356 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5359 Error(S,
"scale_offset is not supported on this GPU");
5362 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5365 Error(S,
"nv is not supported on this GPU");
5370 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5373 Error(S,
"scale_offset is not supported for this instruction");
5377 return validateTHAndScopeBits(Inst,
Operands, CPol);
5382 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5383 Error(S,
"cache policy is not supported for SMRD instructions");
5387 Error(IDLoc,
"invalid cache policy for SMEM instruction");
5396 if (!(TSFlags & AllowSCCModifier)) {
5397 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5401 "scc modifier is not supported for this instruction on this GPU");
5412 :
"instruction must use glc");
5417 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5420 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
5422 :
"instruction must not use glc");
5430bool AMDGPUAsmParser::validateTHAndScopeBits(
const MCInst &Inst,
5432 const unsigned CPol) {
5436 const unsigned Opcode = Inst.
getOpcode();
5437 const MCInstrDesc &TID = MII.
get(Opcode);
5440 SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,
Operands);
5448 return PrintError(
"instruction must use th:TH_ATOMIC_RETURN");
5456 return PrintError(
"invalid th value for SMEM instruction");
5463 return PrintError(
"scope and th combination is not valid");
5469 return PrintError(
"invalid th value for atomic instructions");
5472 return PrintError(
"invalid th value for store instructions");
5475 return PrintError(
"invalid th value for load instructions");
5481bool AMDGPUAsmParser::validateTFE(
const MCInst &Inst,
5484 if (
Desc.mayStore() &&
5486 SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE,
Operands);
5488 Error(Loc,
"TFE modifier has no meaning for store instructions");
5496bool AMDGPUAsmParser::validateSetVgprMSB(
const MCInst &Inst,
5498 if (Inst.
getOpcode() != AMDGPU::S_SET_VGPR_MSB_gfx12)
5502 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::simm16);
5504 SMLoc Loc =
Operands[1]->getStartLoc();
5505 Error(Loc,
"s_set_vgpr_msb accepts values in range [0..255]");
5512bool AMDGPUAsmParser::validateWMMA(
const MCInst &Inst,
5518 auto validateFmt = [&](AMDGPU::OpName FmtOp, AMDGPU::OpName SrcOp) ->
bool {
5519 int FmtIdx = AMDGPU::getNamedOperandIdx(
Opc, FmtOp);
5523 int SrcIdx = AMDGPU::getNamedOperandIdx(
Opc, SrcOp);
5525 TRI->getRegClass(
Desc.operands()[SrcIdx].RegClass).getSizeInBits();
5530 static const char *FmtNames[] = {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
5531 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
5535 "wrong register tuple size for " + Twine(FmtNames[Fmt]));
5539 return validateFmt(AMDGPU::OpName::matrix_a_fmt, AMDGPU::OpName::src0) &&
5540 validateFmt(AMDGPU::OpName::matrix_b_fmt, AMDGPU::OpName::src1);
5543bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst, SMLoc IDLoc,
5545 if (!validateLdsDirect(Inst,
Operands))
5547 if (!validateTrue16OpSel(Inst)) {
5549 "op_sel operand conflicts with 16-bit operand suffix");
5552 if (!validateSOPLiteral(Inst,
Operands))
5554 if (!validateVOPLiteral(Inst,
Operands)) {
5557 if (!validateConstantBusLimitations(Inst,
Operands)) {
5560 if (!validateVOPD(Inst,
Operands)) {
5563 if (!validateIntClampSupported(Inst)) {
5565 "integer clamping is not supported on this GPU");
5568 if (!validateOpSel(Inst)) {
5570 "invalid op_sel operand");
5573 if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5575 "invalid neg_lo operand");
5578 if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5580 "invalid neg_hi operand");
5583 if (!validateDPP(Inst,
Operands)) {
5587 if (!validateMIMGD16(Inst)) {
5589 "d16 modifier is not supported on this GPU");
5592 if (!validateMIMGDim(Inst,
Operands)) {
5593 Error(IDLoc,
"missing dim operand");
5596 if (!validateTensorR128(Inst)) {
5598 "instruction must set modifier r128=0");
5601 if (!validateMIMGMSAA(Inst)) {
5603 "invalid dim; must be MSAA type");
5606 if (!validateMIMGDataSize(Inst, IDLoc)) {
5609 if (!validateMIMGAddrSize(Inst, IDLoc))
5611 if (!validateMIMGAtomicDMask(Inst)) {
5613 "invalid atomic image dmask");
5616 if (!validateMIMGGatherDMask(Inst)) {
5618 "invalid image_gather dmask: only one bit must be set");
5621 if (!validateMovrels(Inst,
Operands)) {
5624 if (!validateOffset(Inst,
Operands)) {
5627 if (!validateMAIAccWrite(Inst,
Operands)) {
5630 if (!validateMAISrc2(Inst,
Operands)) {
5633 if (!validateMFMA(Inst,
Operands)) {
5636 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
5640 if (!validateAGPRLdSt(Inst)) {
5641 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5642 ?
"invalid register class: data and dst should be all VGPR or AGPR"
5643 :
"invalid register class: agpr loads and stores not supported on this GPU"
5647 if (!validateVGPRAlign(Inst)) {
5649 "invalid register class: vgpr tuples must be 64 bit aligned");
5656 if (!validateBLGP(Inst,
Operands)) {
5660 if (!validateDivScale(Inst)) {
5661 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
5664 if (!validateWaitCnt(Inst,
Operands)) {
5667 if (!validateTFE(Inst,
Operands)) {
5670 if (!validateSetVgprMSB(Inst,
Operands)) {
5673 if (!validateWMMA(Inst,
Operands)) {
5682 unsigned VariantID = 0);
5686 unsigned VariantID);
5688bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
5693bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5694 const FeatureBitset &FBS,
5695 ArrayRef<unsigned> Variants) {
5696 for (
auto Variant : Variants) {
5704bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5706 FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5709 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5714 getParser().clearPendingErrors();
5718 StringRef VariantName = getMatchedVariantName();
5719 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
5722 " variant of this instruction is not supported"));
5726 if (
isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5727 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5729 FeatureBitset FeaturesWS32 = getFeatureBits();
5730 FeaturesWS32.
flip(AMDGPU::FeatureWavefrontSize64)
5731 .
flip(AMDGPU::FeatureWavefrontSize32);
5732 FeatureBitset AvailableFeaturesWS32 =
5733 ComputeAvailableFeatures(FeaturesWS32);
5735 if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5736 return Error(IDLoc,
"instruction requires wavesize=32");
5740 if (isSupportedMnemo(Mnemo, FeatureBitset().set())) {
5741 return Error(IDLoc,
"instruction not supported on this GPU");
5746 return Error(IDLoc,
"invalid instruction" + Suggestion);
5752 const auto &
Op = ((AMDGPUOperand &)*
Operands[InvalidOprIdx]);
5753 if (
Op.isToken() && InvalidOprIdx > 1) {
5754 const auto &PrevOp = ((AMDGPUOperand &)*
Operands[InvalidOprIdx - 1]);
5755 return PrevOp.isToken() && PrevOp.getToken() ==
"::";
5760bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
5763 uint64_t &ErrorInfo,
5764 bool MatchingInlineAsm) {
5767 unsigned Result = Match_Success;
5768 for (
auto Variant : getMatchedVariants()) {
5770 auto R = MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm,
5775 if (R == Match_Success || R == Match_MissingFeature ||
5776 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5777 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5778 Result != Match_MissingFeature)) {
5782 if (R == Match_Success)
5786 if (Result == Match_Success) {
5787 if (!validateInstruction(Inst, IDLoc,
Operands)) {
5795 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5801 case Match_MissingFeature:
5805 return Error(IDLoc,
"operands are not valid for this GPU or mode");
5807 case Match_InvalidOperand: {
5808 SMLoc ErrorLoc = IDLoc;
5809 if (ErrorInfo != ~0ULL) {
5810 if (ErrorInfo >=
Operands.size()) {
5811 return Error(IDLoc,
"too few operands for instruction");
5813 ErrorLoc = ((AMDGPUOperand &)*
Operands[ErrorInfo]).getStartLoc();
5814 if (ErrorLoc == SMLoc())
5818 return Error(ErrorLoc,
"invalid VOPDY instruction");
5820 return Error(ErrorLoc,
"invalid operand for instruction");
5823 case Match_MnemonicFail:
5829bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5834 if (getParser().parseAbsoluteExpression(Tmp)) {
5837 Ret =
static_cast<uint32_t
>(Tmp);
5841bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5842 if (!getSTI().getTargetTriple().isAMDGCN())
5843 return TokError(
"directive only supported for amdgcn architecture");
5845 std::string TargetIDDirective;
5846 SMLoc TargetStart = getTok().getLoc();
5847 if (getParser().parseEscapedString(TargetIDDirective))
5850 SMRange TargetRange = SMRange(TargetStart, getTok().getLoc());
5851 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5852 return getParser().Error(TargetRange.
Start,
5853 (Twine(
".amdgcn_target directive's target id ") +
5854 Twine(TargetIDDirective) +
5855 Twine(
" does not match the specified target id ") +
5856 Twine(getTargetStreamer().getTargetID()->
toString())).str());
5861bool AMDGPUAsmParser::OutOfRangeError(SMRange
Range) {
5865bool AMDGPUAsmParser::calculateGPRBlocks(
5866 const FeatureBitset &Features,
const MCExpr *VCCUsed,
5867 const MCExpr *FlatScrUsed,
bool XNACKUsed,
5868 std::optional<bool> EnableWavefrontSize32,
const MCExpr *NextFreeVGPR,
5869 SMRange VGPRRange,
const MCExpr *NextFreeSGPR, SMRange SGPRRange,
5870 const MCExpr *&VGPRBlocks,
const MCExpr *&SGPRBlocks) {
5876 const MCExpr *
NumSGPRs = NextFreeSGPR;
5877 int64_t EvaluatedSGPRs;
5882 unsigned MaxAddressableNumSGPRs =
5885 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
Version.Major >= 8 &&
5886 !Features.
test(FeatureSGPRInitBug) &&
5887 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5888 return OutOfRangeError(SGPRRange);
5890 const MCExpr *ExtraSGPRs =
5894 if (
NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5895 (
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
5896 static_cast<uint64_t
>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5897 return OutOfRangeError(SGPRRange);
5899 if (Features.
test(FeatureSGPRInitBug))
5906 auto GetNumGPRBlocks = [&Ctx](
const MCExpr *NumGPR,
5907 unsigned Granule) ->
const MCExpr * {
5911 const MCExpr *AlignToGPR =
5913 const MCExpr *DivGPR =
5919 VGPRBlocks = GetNumGPRBlocks(
5928bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5929 if (!getSTI().getTargetTriple().isAMDGCN())
5930 return TokError(
"directive only supported for amdgcn architecture");
5933 return TokError(
"directive only supported for amdhsa OS");
5935 StringRef KernelName;
5936 if (getParser().parseIdentifier(KernelName))
5939 AMDGPU::MCKernelDescriptor KD =
5951 const MCExpr *NextFreeVGPR = ZeroExpr;
5953 const MCExpr *NamedBarCnt = ZeroExpr;
5954 uint64_t SharedVGPRCount = 0;
5955 uint64_t PreloadLength = 0;
5956 uint64_t PreloadOffset = 0;
5958 const MCExpr *NextFreeSGPR = ZeroExpr;
5961 unsigned ImpliedUserSGPRCount = 0;
5965 std::optional<unsigned> ExplicitUserSGPRCount;
5966 const MCExpr *ReserveVCC = OneExpr;
5967 const MCExpr *ReserveFlatScr = OneExpr;
5968 std::optional<bool> EnableWavefrontSize32;
5974 SMRange IDRange = getTok().getLocRange();
5975 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5978 if (
ID ==
".end_amdhsa_kernel")
5982 return TokError(
".amdhsa_ directives cannot be repeated");
5984 SMLoc ValStart = getLoc();
5985 const MCExpr *ExprVal;
5986 if (getParser().parseExpression(ExprVal))
5988 SMLoc ValEnd = getLoc();
5989 SMRange ValRange = SMRange(ValStart, ValEnd);
5992 uint64_t Val = IVal;
5993 bool EvaluatableExpr;
5994 if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5996 return OutOfRangeError(ValRange);
6000#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
6001 if (!isUInt<ENTRY##_WIDTH>(Val)) \
6002 return OutOfRangeError(RANGE); \
6003 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
6008#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
6010 return Error(IDRange.Start, "directive should have resolvable expression", \
6013 if (
ID ==
".amdhsa_group_segment_fixed_size") {
6016 return OutOfRangeError(ValRange);
6018 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
6021 return OutOfRangeError(ValRange);
6023 }
else if (
ID ==
".amdhsa_kernarg_size") {
6025 return OutOfRangeError(ValRange);
6027 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
6029 ExplicitUserSGPRCount = Val;
6030 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
6034 "directive is not supported with architected flat scratch",
6037 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
6040 ImpliedUserSGPRCount += 4;
6041 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_length") {
6044 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6047 return OutOfRangeError(ValRange);
6051 ImpliedUserSGPRCount += Val;
6052 PreloadLength = Val;
6054 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_preload_offset") {
6057 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6060 return OutOfRangeError(ValRange);
6064 PreloadOffset = Val;
6065 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
6068 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
6071 ImpliedUserSGPRCount += 2;
6072 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
6075 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
6078 ImpliedUserSGPRCount += 2;
6079 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
6082 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
6085 ImpliedUserSGPRCount += 2;
6086 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
6089 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
6092 ImpliedUserSGPRCount += 2;
6093 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
6096 "directive is not supported with architected flat scratch",
6100 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
6103 ImpliedUserSGPRCount += 2;
6104 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
6107 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
6110 ImpliedUserSGPRCount += 1;
6111 }
else if (
ID ==
".amdhsa_wavefront_size32") {
6113 if (IVersion.
Major < 10)
6114 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6115 EnableWavefrontSize32 = Val;
6117 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
6119 }
else if (
ID ==
".amdhsa_uses_dynamic_stack") {
6121 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
6123 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
6126 "directive is not supported with architected flat scratch",
6129 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6131 }
else if (
ID ==
".amdhsa_enable_private_segment") {
6135 "directive is not supported without architected flat scratch",
6138 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
6140 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
6142 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
6144 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
6146 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
6148 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
6150 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
6152 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
6154 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
6156 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
6158 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
6160 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
6161 VGPRRange = ValRange;
6162 NextFreeVGPR = ExprVal;
6163 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
6164 SGPRRange = ValRange;
6165 NextFreeSGPR = ExprVal;
6166 }
else if (
ID ==
".amdhsa_accum_offset") {
6168 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6169 AccumOffset = ExprVal;
6170 }
else if (
ID ==
".amdhsa_named_barrier_count") {
6172 return Error(IDRange.
Start,
"directive requires gfx1250+", IDRange);
6173 NamedBarCnt = ExprVal;
6174 }
else if (
ID ==
".amdhsa_reserve_vcc") {
6176 return OutOfRangeError(ValRange);
6177 ReserveVCC = ExprVal;
6178 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
6179 if (IVersion.
Major < 7)
6180 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
6183 "directive is not supported with architected flat scratch",
6186 return OutOfRangeError(ValRange);
6187 ReserveFlatScr = ExprVal;
6188 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
6189 if (IVersion.
Major < 8)
6190 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
6192 return OutOfRangeError(ValRange);
6193 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
6194 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
6196 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
6198 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
6200 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
6202 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
6204 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
6206 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
6208 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
6210 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
6212 }
else if (
ID ==
".amdhsa_dx10_clamp") {
6213 if (IVersion.
Major >= 12)
6214 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6216 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
6218 }
else if (
ID ==
".amdhsa_ieee_mode") {
6219 if (IVersion.
Major >= 12)
6220 return Error(IDRange.
Start,
"directive unsupported on gfx12+", IDRange);
6222 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
6224 }
else if (
ID ==
".amdhsa_fp16_overflow") {
6225 if (IVersion.
Major < 9)
6226 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
6228 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
6230 }
else if (
ID ==
".amdhsa_tg_split") {
6232 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
6235 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
6238 "directive unsupported on " + getSTI().
getCPU(), IDRange);
6240 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
6242 }
else if (
ID ==
".amdhsa_memory_ordered") {
6243 if (IVersion.
Major < 10)
6244 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6246 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
6248 }
else if (
ID ==
".amdhsa_forward_progress") {
6249 if (IVersion.
Major < 10)
6250 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
6252 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
6254 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
6256 if (IVersion.
Major < 10 || IVersion.
Major >= 12)
6257 return Error(IDRange.
Start,
"directive requires gfx10 or gfx11",
6259 SharedVGPRCount = Val;
6261 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
6263 }
else if (
ID ==
".amdhsa_inst_pref_size") {
6264 if (IVersion.
Major < 11)
6265 return Error(IDRange.
Start,
"directive requires gfx11+", IDRange);
6266 if (IVersion.
Major == 11) {
6268 COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE, ExprVal,
6272 COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE, ExprVal,
6275 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
6278 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
6280 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
6282 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
6284 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
6287 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
6289 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
6291 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
6293 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
6295 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
6297 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
6299 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
6301 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
6303 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
6305 }
else if (
ID ==
".amdhsa_round_robin_scheduling") {
6306 if (IVersion.
Major < 12)
6307 return Error(IDRange.
Start,
"directive requires gfx12+", IDRange);
6309 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
6312 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
6315#undef PARSE_BITS_ENTRY
6318 if (!Seen.
contains(
".amdhsa_next_free_vgpr"))
6319 return TokError(
".amdhsa_next_free_vgpr directive is required");
6321 if (!Seen.
contains(
".amdhsa_next_free_sgpr"))
6322 return TokError(
".amdhsa_next_free_sgpr directive is required");
6324 unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
6329 if (PreloadLength) {
6335 const MCExpr *VGPRBlocks;
6336 const MCExpr *SGPRBlocks;
6337 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
6338 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
6339 EnableWavefrontSize32, NextFreeVGPR,
6340 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
6344 int64_t EvaluatedVGPRBlocks;
6345 bool VGPRBlocksEvaluatable =
6346 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
6347 if (VGPRBlocksEvaluatable &&
6349 static_cast<uint64_t
>(EvaluatedVGPRBlocks))) {
6350 return OutOfRangeError(VGPRRange);
6354 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
6355 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT,
getContext());
6357 int64_t EvaluatedSGPRBlocks;
6358 if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
6360 static_cast<uint64_t
>(EvaluatedSGPRBlocks)))
6361 return OutOfRangeError(SGPRRange);
6364 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
6365 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
getContext());
6367 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
6368 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
6369 "enabled user SGPRs");
6373 return TokError(
"too many user SGPRs enabled");
6377 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT_SHIFT,
6378 COMPUTE_PGM_RSRC2_GFX125_USER_SGPR_COUNT,
getContext());
6382 return TokError(
"too many user SGPRs enabled");
6386 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT_SHIFT,
6387 COMPUTE_PGM_RSRC2_GFX6_GFX120_USER_SGPR_COUNT,
getContext());
6392 return TokError(
"Kernarg size should be resolvable");
6393 uint64_t kernarg_size = IVal;
6394 if (PreloadLength && kernarg_size &&
6395 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
6396 return TokError(
"Kernarg preload length + offset is larger than the "
6397 "kernarg segment size");
6400 if (!Seen.
contains(
".amdhsa_accum_offset"))
6401 return TokError(
".amdhsa_accum_offset directive is required");
6402 int64_t EvaluatedAccum;
6403 bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
6404 uint64_t UEvaluatedAccum = EvaluatedAccum;
6405 if (AccumEvaluatable &&
6406 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
6407 return TokError(
"accum_offset should be in range [4..256] in "
6410 int64_t EvaluatedNumVGPR;
6411 if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
6414 alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
6415 return TokError(
"accum_offset exceeds total VGPR allocation");
6421 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
6422 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
6428 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT_SHIFT,
6429 COMPUTE_PGM_RSRC3_GFX125_NAMED_BAR_CNT,
6432 if (IVersion.
Major >= 10 && IVersion.
Major < 12) {
6434 if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
6435 return TokError(
"shared_vgpr_count directive not valid on "
6436 "wavefront size 32");
6439 if (VGPRBlocksEvaluatable &&
6440 (SharedVGPRCount * 2 +
static_cast<uint64_t
>(EvaluatedVGPRBlocks) >
6442 return TokError(
"shared_vgpr_count*2 + "
6443 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
6448 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
6449 NextFreeVGPR, NextFreeSGPR,
6450 ReserveVCC, ReserveFlatScr);
6454bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
6456 if (ParseAsAbsoluteExpression(
Version))
6459 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(
Version);
6463bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRef
ID,
6464 AMDGPUMCKernelCodeT &
C) {
6467 if (
ID ==
"max_scratch_backing_memory_byte_size") {
6468 Parser.eatToEndOfStatement();
6472 SmallString<40> ErrStr;
6473 raw_svector_ostream Err(ErrStr);
6474 if (!
C.ParseKernelCodeT(
ID, getParser(), Err)) {
6475 return TokError(Err.
str());
6479 if (
ID ==
"enable_wavefront_size32") {
6482 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
6484 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
6487 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
6491 if (
ID ==
"wavefront_size") {
6492 if (
C.wavefront_size == 5) {
6494 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
6496 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
6497 }
else if (
C.wavefront_size == 6) {
6499 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
6506bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6507 AMDGPUMCKernelCodeT KernelCode;
6516 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
6519 if (
ID ==
".end_amd_kernel_code_t")
6522 if (ParseAMDKernelCodeTValue(
ID, KernelCode))
6527 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6532bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6533 StringRef KernelName;
6534 if (!parseId(KernelName,
"expected symbol name"))
6537 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6544bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6545 if (!getSTI().getTargetTriple().isAMDGCN()) {
6546 return Error(getLoc(),
6547 ".amd_amdgpu_isa directive is not available on non-amdgcn "
6551 auto TargetIDDirective = getLexer().getTok().getStringContents();
6552 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
6553 return Error(getParser().getTok().getLoc(),
"target id must match options");
6555 getTargetStreamer().EmitISAVersion();
6561bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6564 std::string HSAMetadataString;
6569 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6570 return Error(getLoc(),
"invalid HSA metadata");
6577bool AMDGPUAsmParser::ParseToEndDirective(
const char *AssemblerDirectiveBegin,
6578 const char *AssemblerDirectiveEnd,
6579 std::string &CollectString) {
6581 raw_string_ostream CollectStream(CollectString);
6583 getLexer().setSkipSpace(
false);
6585 bool FoundEnd =
false;
6588 CollectStream << getTokenStr();
6592 if (trySkipId(AssemblerDirectiveEnd)) {
6597 CollectStream << Parser.parseStringToEndOfStatement()
6598 <<
getContext().getAsmInfo()->getSeparatorString();
6600 Parser.eatToEndOfStatement();
6603 getLexer().setSkipSpace(
true);
6606 return TokError(Twine(
"expected directive ") +
6607 Twine(AssemblerDirectiveEnd) + Twine(
" not found"));
6614bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6620 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6621 if (!PALMetadata->setFromString(
String))
6622 return Error(getLoc(),
"invalid PAL metadata");
6627bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6629 return Error(getLoc(),
6631 "not available on non-amdpal OSes")).str());
6634 auto *PALMetadata = getTargetStreamer().getPALMetadata();
6635 PALMetadata->setLegacy();
6638 if (ParseAsAbsoluteExpression(
Key)) {
6639 return TokError(Twine(
"invalid value in ") +
6643 return TokError(Twine(
"expected an even number of values in ") +
6646 if (ParseAsAbsoluteExpression(
Value)) {
6647 return TokError(Twine(
"invalid value in ") +
6650 PALMetadata->setRegister(
Key,
Value);
6659bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6660 if (getParser().checkForValidSection())
6664 SMLoc NameLoc = getLoc();
6665 if (getParser().parseIdentifier(Name))
6666 return TokError(
"expected identifier in directive");
6669 if (getParser().parseComma())
6675 SMLoc SizeLoc = getLoc();
6676 if (getParser().parseAbsoluteExpression(
Size))
6679 return Error(SizeLoc,
"size must be non-negative");
6680 if (
Size > LocalMemorySize)
6681 return Error(SizeLoc,
"size is too large");
6683 int64_t Alignment = 4;
6685 SMLoc AlignLoc = getLoc();
6686 if (getParser().parseAbsoluteExpression(Alignment))
6689 return Error(AlignLoc,
"alignment must be a power of two");
6694 if (Alignment >= 1u << 31)
6695 return Error(AlignLoc,
"alignment is too large");
6701 Symbol->redefineIfPossible();
6702 if (!
Symbol->isUndefined())
6703 return Error(NameLoc,
"invalid symbol redefinition");
6705 getTargetStreamer().emitAMDGPULDS(Symbol,
Size,
Align(Alignment));
6709bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6710 StringRef IDVal = DirectiveID.
getString();
6713 if (IDVal ==
".amdhsa_kernel")
6714 return ParseDirectiveAMDHSAKernel();
6716 if (IDVal ==
".amdhsa_code_object_version")
6717 return ParseDirectiveAMDHSACodeObjectVersion();
6721 return ParseDirectiveHSAMetadata();
6723 if (IDVal ==
".amd_kernel_code_t")
6724 return ParseDirectiveAMDKernelCodeT();
6726 if (IDVal ==
".amdgpu_hsa_kernel")
6727 return ParseDirectiveAMDGPUHsaKernel();
6729 if (IDVal ==
".amd_amdgpu_isa")
6730 return ParseDirectiveISAVersion();
6734 Twine(
" directive is "
6735 "not available on non-amdhsa OSes"))
6740 if (IDVal ==
".amdgcn_target")
6741 return ParseDirectiveAMDGCNTarget();
6743 if (IDVal ==
".amdgpu_lds")
6744 return ParseDirectiveAMDGPULDS();
6747 return ParseDirectivePALMetadataBegin();
6750 return ParseDirectivePALMetadata();
6755bool AMDGPUAsmParser::subtargetHasRegister(
const MCRegisterInfo &
MRI,
6757 if (
MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15,
Reg))
6761 if (
MRI.regsOverlap(SGPR104_SGPR105,
Reg))
6762 return hasSGPR104_SGPR105();
6765 case SRC_SHARED_BASE_LO:
6766 case SRC_SHARED_BASE:
6767 case SRC_SHARED_LIMIT_LO:
6768 case SRC_SHARED_LIMIT:
6769 case SRC_PRIVATE_BASE_LO:
6770 case SRC_PRIVATE_BASE:
6771 case SRC_PRIVATE_LIMIT_LO:
6772 case SRC_PRIVATE_LIMIT:
6774 case SRC_FLAT_SCRATCH_BASE_LO:
6775 case SRC_FLAT_SCRATCH_BASE_HI:
6776 return hasGloballyAddressableScratch();
6777 case SRC_POPS_EXITING_WAVE_ID:
6789 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6818 if (
MRI.regsOverlap(SGPR102_SGPR103,
Reg))
6819 return hasSGPR102_SGPR103();
6827 ParseStatus Res = parseVOPD(
Operands);
6832 Res = MatchOperandParserImpl(
Operands, Mnemonic);
6844 SMLoc LBraceLoc = getLoc();
6849 auto Loc = getLoc();
6852 Error(Loc,
"expected a register");
6856 RBraceLoc = getLoc();
6861 "expected a comma or a closing square bracket"))
6865 if (
Operands.size() - Prefix > 1) {
6867 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
6868 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
6877StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRef Name) {
6879 setForcedEncodingSize(0);
6880 setForcedDPP(
false);
6881 setForcedSDWA(
false);
6883 if (
Name.consume_back(
"_e64_dpp")) {
6885 setForcedEncodingSize(64);
6888 if (
Name.consume_back(
"_e64")) {
6889 setForcedEncodingSize(64);
6892 if (
Name.consume_back(
"_e32")) {
6893 setForcedEncodingSize(32);
6896 if (
Name.consume_back(
"_dpp")) {
6900 if (
Name.consume_back(
"_sdwa")) {
6901 setForcedSDWA(
true);
6909 unsigned VariantID);
6915 Name = parseMnemonicSuffix(Name);
6921 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
6923 bool IsMIMG = Name.starts_with(
"image_");
6926 OperandMode
Mode = OperandMode_Default;
6928 Mode = OperandMode_NSA;
6932 checkUnsupportedInstruction(Name, NameLoc);
6933 if (!Parser.hasPendingError()) {
6936 :
"not a valid operand.";
6937 Error(getLoc(), Msg);
6956ParseStatus AMDGPUAsmParser::parseTokenOp(StringRef Name,
6959 if (!trySkipId(Name))
6962 Operands.push_back(AMDGPUOperand::CreateToken(
this, Name, S));
6966ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
6975ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6977 std::function<
bool(int64_t &)> ConvertResult) {
6981 ParseStatus Res = parseIntWithPrefix(Prefix,
Value);
6985 if (ConvertResult && !ConvertResult(
Value)) {
6986 Error(S,
"invalid " + StringRef(Prefix) +
" value.");
6989 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value, S, ImmTy));
6993ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6995 bool (*ConvertResult)(int64_t &)) {
7004 const unsigned MaxSize = 4;
7008 for (
int I = 0; ; ++
I) {
7010 SMLoc Loc = getLoc();
7014 if (
Op != 0 &&
Op != 1)
7015 return Error(Loc,
"invalid " + StringRef(Prefix) +
" value.");
7022 if (
I + 1 == MaxSize)
7023 return Error(getLoc(),
"expected a closing square bracket");
7029 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val, S, ImmTy));
7033ParseStatus AMDGPUAsmParser::parseNamedBit(StringRef Name,
7035 AMDGPUOperand::ImmTy ImmTy) {
7039 if (trySkipId(Name)) {
7041 }
else if (trySkipId(
"no", Name)) {
7048 return Error(S,
"r128 modifier is not supported on this GPU");
7049 if (Name ==
"a16" && !
hasA16())
7050 return Error(S,
"a16 modifier is not supported on this GPU");
7052 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
7053 ImmTy = AMDGPUOperand::ImmTyR128A16;
7055 Operands.push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
7059unsigned AMDGPUAsmParser::getCPolKind(StringRef Id, StringRef Mnemo,
7060 bool &Disabling)
const {
7061 Disabling =
Id.consume_front(
"no");
7064 return StringSwitch<unsigned>(Id)
7071 return StringSwitch<unsigned>(Id)
7081 SMLoc StringLoc = getLoc();
7083 int64_t CPolVal = 0;
7103 ResScope = parseScope(
Operands, Scope);
7116 if (trySkipId(
"nv")) {
7120 }
else if (trySkipId(
"no",
"nv")) {
7127 if (trySkipId(
"scale_offset")) {
7131 }
else if (trySkipId(
"no",
"scale_offset")) {
7144 Operands.push_back(AMDGPUOperand::CreateImm(
this, CPolVal, StringLoc,
7145 AMDGPUOperand::ImmTyCPol));
7150 SMLoc OpLoc = getLoc();
7151 unsigned Enabled = 0, Seen = 0;
7155 unsigned CPol = getCPolKind(getId(), Mnemo, Disabling);
7162 return Error(S,
"dlc modifier is not supported on this GPU");
7165 return Error(S,
"scc modifier is not supported on this GPU");
7168 return Error(S,
"duplicate cache policy modifier");
7180 AMDGPUOperand::CreateImm(
this,
Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
7189 ParseStatus Res = parseStringOrIntWithPrefix(
7190 Operands,
"scope", {
"SCOPE_CU",
"SCOPE_SE",
"SCOPE_DEV",
"SCOPE_SYS"},
7204 ParseStatus Res = parseStringWithPrefix(
"th",
Value, StringLoc);
7208 if (
Value ==
"TH_DEFAULT")
7210 else if (
Value ==
"TH_STORE_LU" ||
Value ==
"TH_LOAD_WB" ||
7211 Value ==
"TH_LOAD_NT_WB") {
7212 return Error(StringLoc,
"invalid th value");
7213 }
else if (
Value.consume_front(
"TH_ATOMIC_")) {
7215 }
else if (
Value.consume_front(
"TH_LOAD_")) {
7217 }
else if (
Value.consume_front(
"TH_STORE_")) {
7220 return Error(StringLoc,
"invalid th value");
7223 if (
Value ==
"BYPASS")
7228 TH |= StringSwitch<int64_t>(
Value)
7238 .Default(0xffffffff);
7240 TH |= StringSwitch<int64_t>(
Value)
7251 .Default(0xffffffff);
7254 if (TH == 0xffffffff)
7255 return Error(StringLoc,
"invalid th value");
7262 AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx,
7263 AMDGPUOperand::ImmTy ImmT, int64_t
Default = 0,
7264 std::optional<unsigned> InsertAt = std::nullopt) {
7265 auto i = OptionalIdx.find(ImmT);
7266 if (i != OptionalIdx.end()) {
7267 unsigned Idx = i->second;
7268 const AMDGPUOperand &
Op =
7269 static_cast<const AMDGPUOperand &
>(*
Operands[Idx]);
7273 Op.addImmOperands(Inst, 1);
7275 if (InsertAt.has_value())
7282ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
7288 StringLoc = getLoc();
7293ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7299 SMLoc StringLoc = getLoc();
7303 Value = getTokenStr();
7307 if (
Value == Ids[IntVal])
7312 if (IntVal < 0 || IntVal >= (int64_t)Ids.
size())
7313 return Error(StringLoc,
"invalid " + Twine(Name) +
" value");
7318ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
7320 AMDGPUOperand::ImmTy
Type) {
7324 ParseStatus Res = parseStringOrIntWithPrefix(
Operands, Name, Ids, IntVal);
7326 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S,
Type));
7335bool AMDGPUAsmParser::tryParseFmt(
const char *Pref,
7339 SMLoc Loc = getLoc();
7341 auto Res = parseIntWithPrefix(Pref, Val);
7347 if (Val < 0 || Val > MaxVal) {
7348 Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7357 AMDGPUOperand::ImmTy ImmTy) {
7358 const char *Pref =
"index_key";
7360 SMLoc Loc = getLoc();
7361 auto Res = parseIntWithPrefix(Pref, ImmVal);
7365 if ((ImmTy == AMDGPUOperand::ImmTyIndexKey16bit ||
7366 ImmTy == AMDGPUOperand::ImmTyIndexKey32bit) &&
7367 (ImmVal < 0 || ImmVal > 1))
7368 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7370 if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
7371 return Error(Loc, Twine(
"out of range ", StringRef(Pref)));
7373 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, ImmTy));
7378 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey8bit);
7382 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey16bit);
7386 return tryParseIndexKey(
Operands, AMDGPUOperand::ImmTyIndexKey32bit);
7391 AMDGPUOperand::ImmTy
Type) {
7392 return parseStringOrIntWithPrefix(
Operands, Name,
7393 {
"MATRIX_FMT_FP8",
"MATRIX_FMT_BF8",
7394 "MATRIX_FMT_FP6",
"MATRIX_FMT_BF6",
7400 return tryParseMatrixFMT(
Operands,
"matrix_a_fmt",
7401 AMDGPUOperand::ImmTyMatrixAFMT);
7405 return tryParseMatrixFMT(
Operands,
"matrix_b_fmt",
7406 AMDGPUOperand::ImmTyMatrixBFMT);
7411 AMDGPUOperand::ImmTy
Type) {
7412 return parseStringOrIntWithPrefix(
7413 Operands, Name, {
"MATRIX_SCALE_ROW0",
"MATRIX_SCALE_ROW1"},
Type);
7417 return tryParseMatrixScale(
Operands,
"matrix_a_scale",
7418 AMDGPUOperand::ImmTyMatrixAScale);
7422 return tryParseMatrixScale(
Operands,
"matrix_b_scale",
7423 AMDGPUOperand::ImmTyMatrixBScale);
7428 AMDGPUOperand::ImmTy
Type) {
7429 return parseStringOrIntWithPrefix(
7431 {
"MATRIX_SCALE_FMT_E8",
"MATRIX_SCALE_FMT_E5M3",
"MATRIX_SCALE_FMT_E4M3"},
7436 return tryParseMatrixScaleFmt(
Operands,
"matrix_a_scale_fmt",
7437 AMDGPUOperand::ImmTyMatrixAScaleFmt);
7441 return tryParseMatrixScaleFmt(
Operands,
"matrix_b_scale_fmt",
7442 AMDGPUOperand::ImmTyMatrixBScaleFmt);
7447ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &
Format) {
7448 using namespace llvm::AMDGPU::MTBUFFormat;
7454 for (
int I = 0;
I < 2; ++
I) {
7455 if (Dfmt == DFMT_UNDEF && !tryParseFmt(
"dfmt", DFMT_MAX, Dfmt))
7458 if (Nfmt == NFMT_UNDEF && !tryParseFmt(
"nfmt", NFMT_MAX, Nfmt))
7463 if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
7469 if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
7472 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7473 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7479ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &
Format) {
7480 using namespace llvm::AMDGPU::MTBUFFormat;
7484 if (!tryParseFmt(
"format", UFMT_MAX, Fmt))
7487 if (Fmt == UFMT_UNDEF)
7494bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
7496 StringRef FormatStr,
7498 using namespace llvm::AMDGPU::MTBUFFormat;
7502 if (
Format != DFMT_UNDEF) {
7508 if (
Format != NFMT_UNDEF) {
7513 Error(Loc,
"unsupported format");
7517ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
7520 using namespace llvm::AMDGPU::MTBUFFormat;
7524 if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
7529 SMLoc Loc = getLoc();
7530 if (!parseId(Str,
"expected a format string") ||
7531 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
7533 if (Dfmt == DFMT_UNDEF)
7534 return Error(Loc,
"duplicate numeric format");
7535 if (Nfmt == NFMT_UNDEF)
7536 return Error(Loc,
"duplicate data format");
7539 Dfmt = (Dfmt ==
DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
7540 Nfmt = (Nfmt ==
NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
7544 if (Ufmt == UFMT_UNDEF)
7545 return Error(FormatLoc,
"unsupported format");
7554ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
7557 using namespace llvm::AMDGPU::MTBUFFormat;
7560 if (Id == UFMT_UNDEF)
7564 return Error(Loc,
"unified format is not supported on this GPU");
7570ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &
Format) {
7571 using namespace llvm::AMDGPU::MTBUFFormat;
7572 SMLoc Loc = getLoc();
7577 return Error(Loc,
"out of range format");
7582ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &
Format) {
7583 using namespace llvm::AMDGPU::MTBUFFormat;
7589 StringRef FormatStr;
7590 SMLoc Loc = getLoc();
7591 if (!parseId(FormatStr,
"expected a format string"))
7594 auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc,
Format);
7596 Res = parseSymbolicSplitFormat(FormatStr, Loc,
Format);
7606 return parseNumericFormat(
Format);
7610 using namespace llvm::AMDGPU::MTBUFFormat;
7614 SMLoc Loc = getLoc();
7624 AMDGPUOperand::CreateImm(
this,
Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7643 Res = parseSymbolicOrNumericFormat(
Format);
7648 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
Size - 2]);
7649 assert(
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7656 return Error(getLoc(),
"duplicate format");
7662 parseIntWithPrefix(
"offset",
Operands, AMDGPUOperand::ImmTyOffset);
7664 Res = parseIntWithPrefix(
"inst_offset",
Operands,
7665 AMDGPUOperand::ImmTyInstOffset);
7672 parseNamedBit(
"r128",
Operands, AMDGPUOperand::ImmTyR128A16);
7674 Res = parseNamedBit(
"a16",
Operands, AMDGPUOperand::ImmTyA16);
7680 parseIntWithPrefix(
"blgp",
Operands, AMDGPUOperand::ImmTyBLGP);
7683 parseOperandArrayWithPrefix(
"neg",
Operands, AMDGPUOperand::ImmTyBLGP);
7693 OptionalImmIndexMap OptionalIdx;
7695 unsigned OperandIdx[4];
7696 unsigned EnMask = 0;
7699 for (
unsigned i = 1, e =
Operands.size(); i != e; ++i) {
7700 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
7705 OperandIdx[SrcIdx] = Inst.
size();
7706 Op.addRegOperands(Inst, 1);
7713 OperandIdx[SrcIdx] = Inst.
size();
7719 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7720 Op.addImmOperands(Inst, 1);
7724 if (
Op.isToken() && (
Op.getToken() ==
"done" ||
Op.getToken() ==
"row_en"))
7728 OptionalIdx[
Op.getImmTy()] = i;
7734 if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7741 for (
auto i = 0; i < SrcIdx; ++i) {
7743 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7768 IntVal =
encode(ISA, IntVal, CntVal);
7769 if (CntVal !=
decode(ISA, IntVal)) {
7771 IntVal =
encode(ISA, IntVal, -1);
7779bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7781 SMLoc CntLoc = getLoc();
7782 StringRef CntName = getTokenStr();
7789 SMLoc ValLoc = getLoc();
7798 if (CntName ==
"vmcnt" || CntName ==
"vmcnt_sat") {
7800 }
else if (CntName ==
"expcnt" || CntName ==
"expcnt_sat") {
7802 }
else if (CntName ==
"lgkmcnt" || CntName ==
"lgkmcnt_sat") {
7805 Error(CntLoc,
"invalid counter name " + CntName);
7810 Error(ValLoc,
"too large value for " + CntName);
7819 Error(getLoc(),
"expected a counter name");
7834 if (!parseCnt(Waitcnt))
7842 Operands.push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
7846bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7847 SMLoc FieldLoc = getLoc();
7848 StringRef FieldName = getTokenStr();
7853 SMLoc ValueLoc = getLoc();
7860 if (FieldName ==
"instid0") {
7862 }
else if (FieldName ==
"instskip") {
7864 }
else if (FieldName ==
"instid1") {
7867 Error(FieldLoc,
"invalid field name " + FieldName);
7886 .Case(
"VALU_DEP_1", 1)
7887 .Case(
"VALU_DEP_2", 2)
7888 .Case(
"VALU_DEP_3", 3)
7889 .Case(
"VALU_DEP_4", 4)
7890 .Case(
"TRANS32_DEP_1", 5)
7891 .Case(
"TRANS32_DEP_2", 6)
7892 .Case(
"TRANS32_DEP_3", 7)
7893 .Case(
"FMA_ACCUM_CYCLE_1", 8)
7894 .Case(
"SALU_CYCLE_1", 9)
7895 .Case(
"SALU_CYCLE_2", 10)
7896 .Case(
"SALU_CYCLE_3", 11)
7904 Delay |=
Value << Shift;
7914 if (!parseDelay(Delay))
7922 Operands.push_back(AMDGPUOperand::CreateImm(
this, Delay, S));
7927AMDGPUOperand::isSWaitCnt()
const {
7931bool AMDGPUOperand::isSDelayALU()
const {
return isImm(); }
7937void AMDGPUAsmParser::depCtrError(SMLoc Loc,
int ErrorId,
7938 StringRef DepCtrName) {
7941 Error(Loc, Twine(
"invalid counter name ", DepCtrName));
7944 Error(Loc, Twine(DepCtrName,
" is not supported on this GPU"));
7947 Error(Loc, Twine(
"duplicate counter name ", DepCtrName));
7950 Error(Loc, Twine(
"invalid value for ", DepCtrName));
7957bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,
unsigned &UsedOprMask) {
7959 using namespace llvm::AMDGPU::DepCtr;
7961 SMLoc DepCtrLoc = getLoc();
7962 StringRef DepCtrName = getTokenStr();
7972 unsigned PrevOprMask = UsedOprMask;
7973 int CntVal =
encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7976 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7985 Error(getLoc(),
"expected a counter name");
7990 unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7991 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7996 using namespace llvm::AMDGPU::DepCtr;
7999 SMLoc Loc = getLoc();
8002 unsigned UsedOprMask = 0;
8004 if (!parseDepCtr(DepCtr, UsedOprMask))
8012 Operands.push_back(AMDGPUOperand::CreateImm(
this, DepCtr, Loc));
8016bool AMDGPUOperand::isDepCtr()
const {
return isS16Imm(); }
8022ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
8024 OperandInfoTy &Width) {
8025 using namespace llvm::AMDGPU::Hwreg;
8031 HwReg.Loc = getLoc();
8034 HwReg.IsSymbolic =
true;
8036 }
else if (!
parseExpr(HwReg.Val,
"a register name")) {
8044 if (!skipToken(
AsmToken::Comma,
"expected a comma or a closing parenthesis"))
8054 Width.Loc = getLoc();
8063 using namespace llvm::AMDGPU::Hwreg;
8066 SMLoc Loc = getLoc();
8068 StructuredOpField HwReg(
"id",
"hardware register", HwregId::Width,
8070 StructuredOpField
Offset(
"offset",
"bit offset", HwregOffset::Width,
8071 HwregOffset::Default);
8072 struct : StructuredOpField {
8073 using StructuredOpField::StructuredOpField;
8074 bool validate(AMDGPUAsmParser &Parser)
const override {
8076 return Error(Parser,
"only values from 1 to 32 are legal");
8079 } Width(
"size",
"bitfield width", HwregSize::Width, HwregSize::Default);
8080 ParseStatus Res = parseStructuredOpFields({&HwReg, &
Offset, &Width});
8083 Res = parseHwregFunc(HwReg,
Offset, Width);
8086 if (!validateStructuredOpFields({&HwReg, &
Offset, &Width}))
8088 ImmVal = HwregEncoding::encode(HwReg.Val,
Offset.Val, Width.Val);
8092 parseExpr(ImmVal,
"a hwreg macro, structured immediate"))
8099 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8101 AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
8105bool AMDGPUOperand::isHwreg()
const {
8106 return isImmTy(ImmTyHwreg);
8114AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
8116 OperandInfoTy &Stream) {
8117 using namespace llvm::AMDGPU::SendMsg;
8122 Msg.IsSymbolic =
true;
8124 }
else if (!
parseExpr(Msg.Val,
"a message name")) {
8129 Op.IsDefined =
true;
8132 (
Op.Val =
getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
8135 }
else if (!
parseExpr(
Op.Val,
"an operation name")) {
8140 Stream.IsDefined =
true;
8141 Stream.Loc = getLoc();
8151AMDGPUAsmParser::validateSendMsg(
const OperandInfoTy &Msg,
8152 const OperandInfoTy &
Op,
8153 const OperandInfoTy &Stream) {
8154 using namespace llvm::AMDGPU::SendMsg;
8159 bool Strict = Msg.IsSymbolic;
8163 Error(Msg.Loc,
"specified message id is not supported on this GPU");
8168 Error(Msg.Loc,
"invalid message id");
8174 Error(
Op.Loc,
"message does not support operations");
8176 Error(Msg.Loc,
"missing message operation");
8182 Error(
Op.Loc,
"specified operation id is not supported on this GPU");
8184 Error(
Op.Loc,
"invalid operation id");
8189 Error(Stream.Loc,
"message operation does not support streams");
8193 Error(Stream.Loc,
"invalid message stream id");
8200 using namespace llvm::AMDGPU::SendMsg;
8203 SMLoc Loc = getLoc();
8207 OperandInfoTy
Op(OP_NONE_);
8208 OperandInfoTy Stream(STREAM_ID_NONE_);
8209 if (parseSendMsgBody(Msg,
Op, Stream) &&
8210 validateSendMsg(Msg,
Op, Stream)) {
8215 }
else if (
parseExpr(ImmVal,
"a sendmsg macro")) {
8217 return Error(Loc,
"invalid immediate: only 16-bit values are legal");
8222 Operands.push_back(AMDGPUOperand::CreateImm(
this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
8226bool AMDGPUOperand::isSendMsg()
const {
8227 return isImmTy(ImmTySendMsg);
8241 int Slot = StringSwitch<int>(Str)
8248 return Error(S,
"invalid interpolation slot");
8250 Operands.push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
8251 AMDGPUOperand::ImmTyInterpSlot));
8262 if (!Str.starts_with(
"attr"))
8263 return Error(S,
"invalid interpolation attribute");
8265 StringRef Chan = Str.take_back(2);
8266 int AttrChan = StringSwitch<int>(Chan)
8273 return Error(S,
"invalid or missing interpolation attribute channel");
8275 Str = Str.drop_back(2).drop_front(4);
8278 if (Str.getAsInteger(10, Attr))
8279 return Error(S,
"invalid or missing interpolation attribute number");
8282 return Error(S,
"out of bounds interpolation attribute number");
8286 Operands.push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
8287 AMDGPUOperand::ImmTyInterpAttr));
8288 Operands.push_back(AMDGPUOperand::CreateImm(
8289 this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
8298 using namespace llvm::AMDGPU::Exp;
8308 return Error(S, (Id == ET_INVALID)
8309 ?
"invalid exp target"
8310 :
"exp target is not supported on this GPU");
8312 Operands.push_back(AMDGPUOperand::CreateImm(
this, Id, S,
8313 AMDGPUOperand::ImmTyExpTgt));
8322AMDGPUAsmParser::isId(
const AsmToken &Token,
const StringRef Id)
const {
8327AMDGPUAsmParser::isId(
const StringRef Id)
const {
8333 return getTokenKind() ==
Kind;
8336StringRef AMDGPUAsmParser::getId()
const {
8341AMDGPUAsmParser::trySkipId(
const StringRef Id) {
8350AMDGPUAsmParser::trySkipId(
const StringRef Pref,
const StringRef Id) {
8352 StringRef Tok = getTokenStr();
8363 if (isId(Id) && peekToken().is(Kind)) {
8373 if (isToken(Kind)) {
8382 const StringRef ErrMsg) {
8383 if (!trySkipToken(Kind)) {
8384 Error(getLoc(), ErrMsg);
8391AMDGPUAsmParser::parseExpr(int64_t &
Imm, StringRef Expected) {
8395 if (Parser.parseExpression(Expr))
8398 if (Expr->evaluateAsAbsolute(
Imm))
8401 if (Expected.empty()) {
8402 Error(S,
"expected absolute expression");
8404 Error(S, Twine(
"expected ", Expected) +
8405 Twine(
" or an absolute expression"));
8415 if (Parser.parseExpression(Expr))
8419 if (Expr->evaluateAsAbsolute(IntVal)) {
8420 Operands.push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
8422 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
8428AMDGPUAsmParser::parseString(StringRef &Val,
const StringRef ErrMsg) {
8430 Val =
getToken().getStringContents();
8434 Error(getLoc(), ErrMsg);
8439AMDGPUAsmParser::parseId(StringRef &Val,
const StringRef ErrMsg) {
8441 Val = getTokenStr();
8445 if (!ErrMsg.
empty())
8446 Error(getLoc(), ErrMsg);
8451AMDGPUAsmParser::getToken()
const {
8452 return Parser.getTok();
8455AsmToken AMDGPUAsmParser::peekToken(
bool ShouldSkipSpace) {
8458 : getLexer().peekTok(ShouldSkipSpace);
8463 auto TokCount = getLexer().peekTokens(Tokens);
8465 for (
auto Idx = TokCount; Idx < Tokens.
size(); ++Idx)
8470AMDGPUAsmParser::getTokenKind()
const {
8471 return getLexer().getKind();
8475AMDGPUAsmParser::getLoc()
const {
8480AMDGPUAsmParser::getTokenStr()
const {
8485AMDGPUAsmParser::lex() {
8490 return ((AMDGPUOperand &)*
Operands[0]).getStartLoc();
8494SMLoc AMDGPUAsmParser::getLaterLoc(SMLoc a, SMLoc b) {
8499 int MCOpIdx)
const {
8501 const auto TargetOp =
static_cast<AMDGPUOperand &
>(*Op);
8502 if (TargetOp.getMCOpIdx() == MCOpIdx)
8503 return TargetOp.getStartLoc();
8509AMDGPUAsmParser::getOperandLoc(std::function<
bool(
const AMDGPUOperand&)>
Test,
8511 for (
unsigned i =
Operands.size() - 1; i > 0; --i) {
8512 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
8514 return Op.getStartLoc();
8520AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTy
Type,
8522 auto Test = [=](
const AMDGPUOperand&
Op) {
return Op.isImmTy(
Type); };
8537 StringRef
Id = getTokenStr();
8538 SMLoc IdLoc = getLoc();
8544 find_if(Fields, [Id](StructuredOpField *
F) {
return F->Id ==
Id; });
8545 if (
I == Fields.
end())
8546 return Error(IdLoc,
"unknown field");
8547 if ((*I)->IsDefined)
8548 return Error(IdLoc,
"duplicate field");
8551 (*I)->Loc = getLoc();
8554 (*I)->IsDefined =
true;
8561bool AMDGPUAsmParser::validateStructuredOpFields(
8563 return all_of(Fields, [
this](
const StructuredOpField *
F) {
8564 return F->validate(*
this);
8575 const unsigned OrMask,
8576 const unsigned XorMask) {
8585bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &
Op,
const unsigned MinVal,
8586 const unsigned MaxVal,
8587 const Twine &ErrMsg, SMLoc &Loc) {
8604AMDGPUAsmParser::parseSwizzleOperands(
const unsigned OpNum, int64_t*
Op,
8605 const unsigned MinVal,
8606 const unsigned MaxVal,
8607 const StringRef ErrMsg) {
8609 for (
unsigned i = 0; i < OpNum; ++i) {
8610 if (!parseSwizzleOperand(
Op[i], MinVal, MaxVal, ErrMsg, Loc))
8618AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &
Imm) {
8619 using namespace llvm::AMDGPU::Swizzle;
8622 if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8623 "expected a 2-bit lane id")) {
8634AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &
Imm) {
8635 using namespace llvm::AMDGPU::Swizzle;
8641 if (!parseSwizzleOperand(GroupSize,
8643 "group size must be in the interval [2,32]",
8648 Error(Loc,
"group size must be a power of two");
8651 if (parseSwizzleOperand(LaneIdx,
8653 "lane id must be in the interval [0,group size - 1]",
8662AMDGPUAsmParser::parseSwizzleReverse(int64_t &
Imm) {
8663 using namespace llvm::AMDGPU::Swizzle;
8668 if (!parseSwizzleOperand(GroupSize,
8670 "group size must be in the interval [2,32]",
8675 Error(Loc,
"group size must be a power of two");
8684AMDGPUAsmParser::parseSwizzleSwap(int64_t &
Imm) {
8685 using namespace llvm::AMDGPU::Swizzle;
8690 if (!parseSwizzleOperand(GroupSize,
8692 "group size must be in the interval [1,16]",
8697 Error(Loc,
"group size must be a power of two");
8706AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &
Imm) {
8707 using namespace llvm::AMDGPU::Swizzle;
8714 SMLoc StrLoc = getLoc();
8715 if (!parseString(Ctl)) {
8718 if (Ctl.
size() != BITMASK_WIDTH) {
8719 Error(StrLoc,
"expected a 5-character mask");
8723 unsigned AndMask = 0;
8724 unsigned OrMask = 0;
8725 unsigned XorMask = 0;
8727 for (
size_t i = 0; i < Ctl.
size(); ++i) {
8731 Error(StrLoc,
"invalid mask");
8752bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &
Imm) {
8753 using namespace llvm::AMDGPU::Swizzle;
8756 Error(getLoc(),
"FFT mode swizzle not supported on this GPU");
8762 if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8763 "FFT swizzle must be in the interval [0," +
8764 Twine(FFT_SWIZZLE_MAX) + Twine(
']'),
8772bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &
Imm) {
8773 using namespace llvm::AMDGPU::Swizzle;
8776 Error(getLoc(),
"Rotate mode swizzle not supported on this GPU");
8783 if (!parseSwizzleOperand(
Direction, 0, 1,
8784 "direction must be 0 (left) or 1 (right)", Loc))
8788 if (!parseSwizzleOperand(
8789 RotateSize, 0, ROTATE_MAX_SIZE,
8790 "number of threads to rotate must be in the interval [0," +
8791 Twine(ROTATE_MAX_SIZE) + Twine(
']'),
8796 (RotateSize << ROTATE_SIZE_SHIFT);
8801AMDGPUAsmParser::parseSwizzleOffset(int64_t &
Imm) {
8803 SMLoc OffsetLoc = getLoc();
8809 Error(OffsetLoc,
"expected a 16-bit offset");
8816AMDGPUAsmParser::parseSwizzleMacro(int64_t &
Imm) {
8817 using namespace llvm::AMDGPU::Swizzle;
8821 SMLoc ModeLoc = getLoc();
8824 if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8825 Ok = parseSwizzleQuadPerm(
Imm);
8826 }
else if (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8827 Ok = parseSwizzleBitmaskPerm(
Imm);
8828 }
else if (trySkipId(IdSymbolic[ID_BROADCAST])) {
8829 Ok = parseSwizzleBroadcast(
Imm);
8830 }
else if (trySkipId(IdSymbolic[ID_SWAP])) {
8831 Ok = parseSwizzleSwap(
Imm);
8832 }
else if (trySkipId(IdSymbolic[ID_REVERSE])) {
8833 Ok = parseSwizzleReverse(
Imm);
8834 }
else if (trySkipId(IdSymbolic[ID_FFT])) {
8835 Ok = parseSwizzleFFT(
Imm);
8836 }
else if (trySkipId(IdSymbolic[ID_ROTATE])) {
8837 Ok = parseSwizzleRotate(
Imm);
8839 Error(ModeLoc,
"expected a swizzle mode");
8842 return Ok && skipToken(
AsmToken::RParen,
"expected a closing parentheses");
8852 if (trySkipId(
"offset")) {
8856 if (trySkipId(
"swizzle")) {
8857 Ok = parseSwizzleMacro(
Imm);
8859 Ok = parseSwizzleOffset(
Imm);
8863 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTySwizzle));
8871AMDGPUOperand::isSwizzle()
const {
8872 return isImmTy(ImmTySwizzle);
8879int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8881 using namespace llvm::AMDGPU::VGPRIndexMode;
8893 for (
unsigned ModeId = ID_MIN; ModeId <=
ID_MAX; ++ModeId) {
8894 if (trySkipId(IdSymbolic[ModeId])) {
8902 "expected a VGPR index mode or a closing parenthesis" :
8903 "expected a VGPR index mode");
8908 Error(S,
"duplicate VGPR index mode");
8916 "expected a comma or a closing parenthesis"))
8925 using namespace llvm::AMDGPU::VGPRIndexMode;
8931 Imm = parseGPRIdxMacro();
8935 if (getParser().parseAbsoluteExpression(
Imm))
8938 return Error(S,
"invalid immediate: only 4-bit values are legal");
8942 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8946bool AMDGPUOperand::isGPRIdxMode()
const {
8947 return isImmTy(ImmTyGprIdxMode);
8959 if (isRegister() || isModifier())
8966 assert(Opr.isImm() || Opr.isExpr());
8967 SMLoc Loc = Opr.getStartLoc();
8971 if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8972 Error(Loc,
"expected an absolute expression or a label");
8973 }
else if (Opr.isImm() && !Opr.isS16Imm()) {
8974 Error(Loc,
"expected a 16-bit signed jump offset");
8992void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
8995 OptionalImmIndexMap OptionalIdx;
8996 unsigned FirstOperandIdx = 1;
8997 bool IsAtomicReturn =
false;
9004 for (
unsigned i = FirstOperandIdx, e =
Operands.size(); i != e; ++i) {
9005 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
9009 Op.addRegOperands(Inst, 1);
9013 if (IsAtomicReturn && i == FirstOperandIdx)
9014 Op.addRegOperands(Inst, 1);
9019 if (
Op.isImm() &&
Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
9020 Op.addImmOperands(Inst, 1);
9032 OptionalIdx[
Op.getImmTy()] = i;
9043bool AMDGPUOperand::isSMRDOffset8()
const {
9047bool AMDGPUOperand::isSMEMOffset()
const {
9049 return isImmLiteral();
9052bool AMDGPUOperand::isSMRDLiteralOffset()
const {
9087bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
9088 if (BoundCtrl == 0 || BoundCtrl == 1) {
9096void AMDGPUAsmParser::onBeginOfFile() {
9097 if (!getParser().getStreamer().getTargetStreamer() ||
9101 if (!getTargetStreamer().getTargetID())
9102 getTargetStreamer().initializeTargetID(getSTI(),
9103 getSTI().getFeatureString());
9106 getTargetStreamer().EmitDirectiveAMDGCNTarget();
9114bool AMDGPUAsmParser::parsePrimaryExpr(
const MCExpr *&Res, SMLoc &EndLoc) {
9118 StringRef TokenId = getTokenStr();
9119 AGVK VK = StringSwitch<AGVK>(TokenId)
9120 .Case(
"max", AGVK::AGVK_Max)
9121 .Case(
"or", AGVK::AGVK_Or)
9122 .Case(
"extrasgprs", AGVK::AGVK_ExtraSGPRs)
9123 .Case(
"totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
9124 .Case(
"alignto", AGVK::AGVK_AlignTo)
9125 .Case(
"occupancy", AGVK::AGVK_Occupancy)
9126 .Default(AGVK::AGVK_None);
9130 uint64_t CommaCount = 0;
9135 if (Exprs.
empty()) {
9137 "empty " + Twine(TokenId) +
" expression");
9140 if (CommaCount + 1 != Exprs.
size()) {
9142 "mismatch of commas in " + Twine(TokenId) +
" expression");
9149 if (getParser().parseExpression(Expr, EndLoc))
9153 if (LastTokenWasComma)
9157 "unexpected token in " + Twine(TokenId) +
" expression");
9163 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
9167 StringRef
Name = getTokenStr();
9168 if (Name ==
"mul") {
9169 return parseIntWithPrefix(
"mul",
Operands,
9173 if (Name ==
"div") {
9174 return parseIntWithPrefix(
"div",
Operands,
9185 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9190 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9191 AMDGPU::OpName::src2};
9199 int DstIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst);
9204 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src0_modifiers);
9206 if (
DstOp.isReg() &&
9207 MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(
DstOp.
getReg())) {
9211 if ((OpSel & (1 << SrcNum)) != 0)
9217void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
9224 OptionalImmIndexMap &OptionalIdx) {
9225 cvtVOP3P(Inst,
Operands, OptionalIdx);
9234 &&
Desc.NumOperands > (OpNum + 1)
9236 &&
Desc.operands()[OpNum + 1].RegClass != -1
9238 &&
Desc.getOperandConstraint(OpNum + 1,
9244 OptionalImmIndexMap OptionalIdx;
9249 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9250 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9254 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9256 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9257 }
else if (
Op.isInterpSlot() ||
Op.isInterpAttr() ||
9258 Op.isInterpAttrChan()) {
9260 }
else if (
Op.isImmModifier()) {
9261 OptionalIdx[
Op.getImmTy()] =
I;
9269 AMDGPUOperand::ImmTyHigh);
9273 AMDGPUOperand::ImmTyClamp);
9277 AMDGPUOperand::ImmTyOModSI);
9282 OptionalImmIndexMap OptionalIdx;
9287 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9288 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9292 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9294 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9295 }
else if (
Op.isImmModifier()) {
9296 OptionalIdx[
Op.getImmTy()] =
I;
9304 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9313 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9314 AMDGPU::OpName::src2};
9315 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9316 AMDGPU::OpName::src1_modifiers,
9317 AMDGPU::OpName::src2_modifiers};
9321 for (
int J = 0; J < 3; ++J) {
9322 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9326 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9329 if ((OpSel & (1 << J)) != 0)
9331 if (ModOps[J] == AMDGPU::OpName::src0_modifiers &&
9332 (OpSel & (1 << 3)) != 0)
9338void AMDGPUAsmParser::cvtScaledMFMA(MCInst &Inst,
9340 OptionalImmIndexMap OptionalIdx;
9343 int CbszOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::cbsz);
9347 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J)
9348 static_cast<AMDGPUOperand &
>(*
Operands[
I++]).addRegOperands(Inst, 1);
9351 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands[
I]);
9356 if (NumOperands == CbszOpIdx) {
9361 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9362 }
else if (
Op.isImmModifier()) {
9363 OptionalIdx[
Op.getImmTy()] =
I;
9365 Op.addRegOrImmOperands(Inst, 1);
9370 auto CbszIdx = OptionalIdx.find(AMDGPUOperand::ImmTyCBSZ);
9371 if (CbszIdx != OptionalIdx.end()) {
9372 int CbszVal = ((AMDGPUOperand &)*
Operands[CbszIdx->second]).
getImm();
9376 int BlgpOpIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::blgp);
9377 auto BlgpIdx = OptionalIdx.find(AMDGPUOperand::ImmTyBLGP);
9378 if (BlgpIdx != OptionalIdx.end()) {
9379 int BlgpVal = ((AMDGPUOperand &)*
Operands[BlgpIdx->second]).
getImm();
9390 auto OpselIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSel);
9391 if (OpselIdx != OptionalIdx.end()) {
9392 OpSel =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselIdx->second])
9396 unsigned OpSelHi = 0;
9397 auto OpselHiIdx = OptionalIdx.find(AMDGPUOperand::ImmTyOpSelHi);
9398 if (OpselHiIdx != OptionalIdx.end()) {
9399 OpSelHi =
static_cast<const AMDGPUOperand &
>(*
Operands[OpselHiIdx->second])
9402 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9403 AMDGPU::OpName::src1_modifiers};
9405 for (
unsigned J = 0; J < 2; ++J) {
9406 unsigned ModVal = 0;
9407 if (OpSel & (1 << J))
9409 if (OpSelHi & (1 << J))
9412 const int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9418 OptionalImmIndexMap &OptionalIdx) {
9423 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
9424 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
9428 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
9430 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9431 }
else if (
Op.isImmModifier()) {
9432 OptionalIdx[
Op.getImmTy()] =
I;
9434 Op.addRegOrImmOperands(Inst, 1);
9440 AMDGPUOperand::ImmTyScaleSel);
9444 AMDGPUOperand::ImmTyClamp);
9450 AMDGPUOperand::ImmTyByteSel);
9455 AMDGPUOperand::ImmTyOModSI);
9462 auto *it = Inst.
begin();
9463 std::advance(it, AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers));
9472 OptionalImmIndexMap OptionalIdx;
9473 cvtVOP3(Inst,
Operands, OptionalIdx);
9477 OptionalImmIndexMap &OptIdx) {
9483 if (
Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
9484 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
9485 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
9486 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
9487 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
9488 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
9496 !(
Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp_gfx12 ||
9497 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp_gfx12 ||
9498 Opc == AMDGPU::V_CVT_PK_BF8_F32_t16_e64_dpp8_gfx12 ||
9499 Opc == AMDGPU::V_CVT_PK_FP8_F32_t16_e64_dpp8_gfx12 ||
9500 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp_gfx12 ||
9501 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp_gfx12 ||
9502 Opc == AMDGPU::V_CVT_PK_BF8_F32_fake16_e64_dpp8_gfx12 ||
9503 Opc == AMDGPU::V_CVT_PK_FP8_F32_fake16_e64_dpp8_gfx12 ||
9504 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
9505 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9506 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp_gfx1250 ||
9507 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx1250_e64_dpp8_gfx1250 ||
9508 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9509 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9510 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp_gfx1250 ||
9511 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp_gfx1250 ||
9512 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_dpp8_gfx1250 ||
9513 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_dpp8_gfx1250 ||
9514 Opc == AMDGPU::V_CVT_SR_FP8_F16_t16_e64_gfx1250 ||
9515 Opc == AMDGPU::V_CVT_SR_FP8_F16_fake16_e64_gfx1250 ||
9516 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp_gfx1250 ||
9517 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp_gfx1250 ||
9518 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_dpp8_gfx1250 ||
9519 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_dpp8_gfx1250 ||
9520 Opc == AMDGPU::V_CVT_SR_BF8_F16_t16_e64_gfx1250 ||
9521 Opc == AMDGPU::V_CVT_SR_BF8_F16_fake16_e64_gfx1250)) {
9525 int BitOp3Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::bitop3);
9526 if (BitOp3Idx != -1) {
9533 int OpSelIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel);
9534 if (OpSelIdx != -1) {
9538 int OpSelHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::op_sel_hi);
9539 if (OpSelHiIdx != -1) {
9546 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_fmt);
9547 if (MatrixAFMTIdx != -1) {
9549 AMDGPUOperand::ImmTyMatrixAFMT, 0);
9553 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_fmt);
9554 if (MatrixBFMTIdx != -1) {
9556 AMDGPUOperand::ImmTyMatrixBFMT, 0);
9559 int MatrixAScaleIdx =
9560 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale);
9561 if (MatrixAScaleIdx != -1) {
9563 AMDGPUOperand::ImmTyMatrixAScale, 0);
9566 int MatrixBScaleIdx =
9567 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale);
9568 if (MatrixBScaleIdx != -1) {
9570 AMDGPUOperand::ImmTyMatrixBScale, 0);
9573 int MatrixAScaleFmtIdx =
9574 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_a_scale_fmt);
9575 if (MatrixAScaleFmtIdx != -1) {
9577 AMDGPUOperand::ImmTyMatrixAScaleFmt, 0);
9580 int MatrixBScaleFmtIdx =
9581 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::matrix_b_scale_fmt);
9582 if (MatrixBScaleFmtIdx != -1) {
9584 AMDGPUOperand::ImmTyMatrixBScaleFmt, 0);
9589 AMDGPUOperand::ImmTyMatrixAReuse, 0);
9593 AMDGPUOperand::ImmTyMatrixBReuse, 0);
9595 int NegLoIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_lo);
9599 int NegHiIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::neg_hi);
9603 const AMDGPU::OpName
Ops[] = {AMDGPU::OpName::src0, AMDGPU::OpName::src1,
9604 AMDGPU::OpName::src2};
9605 const AMDGPU::OpName ModOps[] = {AMDGPU::OpName::src0_modifiers,
9606 AMDGPU::OpName::src1_modifiers,
9607 AMDGPU::OpName::src2_modifiers};
9610 unsigned OpSelHi = 0;
9617 if (OpSelHiIdx != -1)
9626 for (
int J = 0; J < 3; ++J) {
9627 int OpIdx = AMDGPU::getNamedOperandIdx(
Opc,
Ops[J]);
9631 int ModIdx = AMDGPU::getNamedOperandIdx(
Opc, ModOps[J]);
9636 uint32_t ModVal = 0;
9639 if (SrcOp.
isReg() && getMRI()
9646 if ((OpSel & (1 << J)) != 0)
9650 if ((OpSelHi & (1 << J)) != 0)
9653 if ((NegLo & (1 << J)) != 0)
9656 if ((NegHi & (1 << J)) != 0)
9664 OptionalImmIndexMap OptIdx;
9670 unsigned i,
unsigned Opc,
9672 if (AMDGPU::getNamedOperandIdx(
Opc,
OpName) != -1)
9673 ((AMDGPUOperand &)*
Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
9675 ((AMDGPUOperand &)*
Operands[i]).addRegOperands(Inst, 1);
9681 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
9684 ((AMDGPUOperand &)*
Operands[1]).addRegOperands(Inst, 1);
9685 ((AMDGPUOperand &)*
Operands[4]).addRegOperands(Inst, 1);
9687 OptionalImmIndexMap OptIdx;
9688 for (
unsigned i = 5; i <
Operands.size(); ++i) {
9689 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[i]);
9690 OptIdx[
Op.getImmTy()] = i;
9695 AMDGPUOperand::ImmTyIndexKey8bit);
9699 AMDGPUOperand::ImmTyIndexKey16bit);
9703 AMDGPUOperand::ImmTyIndexKey32bit);
9723 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"::", S));
9724 SMLoc OpYLoc = getLoc();
9727 Operands.push_back(AMDGPUOperand::CreateToken(
this, OpYName, OpYLoc));
9730 return Error(OpYLoc,
"expected a VOPDY instruction after ::");
9739 auto addOp = [&](uint16_t ParsedOprIdx) {
9740 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[ParsedOprIdx]);
9742 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9746 Op.addRegOperands(Inst, 1);
9750 Op.addImmOperands(Inst, 1);
9762 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9766 const auto &CInfo = InstInfo[CompIdx];
9767 auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9768 for (
unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9769 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9770 if (CInfo.hasSrc2Acc())
9771 addOp(CInfo.getIndexOfDstInParsedOperands());
9775 AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::bitop3);
9776 if (BitOp3Idx != -1) {
9777 OptionalImmIndexMap OptIdx;
9778 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands.back());
9790bool AMDGPUOperand::isDPP8()
const {
9791 return isImmTy(ImmTyDPP8);
9794bool AMDGPUOperand::isDPPCtrl()
const {
9795 using namespace AMDGPU::DPP;
9797 bool result = isImm() && getImmTy() == ImmTyDppCtrl &&
isUInt<9>(
getImm());
9800 return (
Imm >= DppCtrl::QUAD_PERM_FIRST &&
Imm <= DppCtrl::QUAD_PERM_LAST) ||
9801 (
Imm >= DppCtrl::ROW_SHL_FIRST &&
Imm <= DppCtrl::ROW_SHL_LAST) ||
9802 (
Imm >= DppCtrl::ROW_SHR_FIRST &&
Imm <= DppCtrl::ROW_SHR_LAST) ||
9803 (
Imm >= DppCtrl::ROW_ROR_FIRST &&
Imm <= DppCtrl::ROW_ROR_LAST) ||
9804 (
Imm == DppCtrl::WAVE_SHL1) ||
9805 (
Imm == DppCtrl::WAVE_ROL1) ||
9806 (
Imm == DppCtrl::WAVE_SHR1) ||
9807 (
Imm == DppCtrl::WAVE_ROR1) ||
9808 (
Imm == DppCtrl::ROW_MIRROR) ||
9809 (
Imm == DppCtrl::ROW_HALF_MIRROR) ||
9810 (
Imm == DppCtrl::BCAST15) ||
9811 (
Imm == DppCtrl::BCAST31) ||
9812 (
Imm >= DppCtrl::ROW_SHARE_FIRST &&
Imm <= DppCtrl::ROW_SHARE_LAST) ||
9813 (
Imm >= DppCtrl::ROW_XMASK_FIRST &&
Imm <= DppCtrl::ROW_XMASK_LAST);
9822bool AMDGPUOperand::isBLGP()
const {
9826bool AMDGPUOperand::isS16Imm()
const {
9830bool AMDGPUOperand::isU16Imm()
const {
9838bool AMDGPUAsmParser::parseDimId(
unsigned &Encoding) {
9843 SMLoc Loc =
getToken().getEndLoc();
9844 Token = std::string(getTokenStr());
9846 if (getLoc() != Loc)
9851 if (!parseId(Suffix))
9855 StringRef DimId = Token;
9876 SMLoc Loc = getLoc();
9877 if (!parseDimId(Encoding))
9878 return Error(Loc,
"invalid dim value");
9880 Operands.push_back(AMDGPUOperand::CreateImm(
this, Encoding, S,
9881 AMDGPUOperand::ImmTyDim));
9899 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9902 for (
size_t i = 0; i < 8; ++i) {
9906 SMLoc Loc = getLoc();
9907 if (getParser().parseAbsoluteExpression(Sels[i]))
9909 if (0 > Sels[i] || 7 < Sels[i])
9910 return Error(Loc,
"expected a 3-bit value");
9917 for (
size_t i = 0; i < 8; ++i)
9918 DPP8 |= (Sels[i] << (i * 3));
9920 Operands.push_back(AMDGPUOperand::CreateImm(
this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9925AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
9927 if (Ctrl ==
"row_newbcast")
9930 if (Ctrl ==
"row_share" ||
9931 Ctrl ==
"row_xmask")
9934 if (Ctrl ==
"wave_shl" ||
9935 Ctrl ==
"wave_shr" ||
9936 Ctrl ==
"wave_rol" ||
9937 Ctrl ==
"wave_ror" ||
9938 Ctrl ==
"row_bcast")
9941 return Ctrl ==
"row_mirror" ||
9942 Ctrl ==
"row_half_mirror" ||
9943 Ctrl ==
"quad_perm" ||
9944 Ctrl ==
"row_shl" ||
9945 Ctrl ==
"row_shr" ||
9950AMDGPUAsmParser::parseDPPCtrlPerm() {
9953 if (!skipToken(
AsmToken::LBrac,
"expected an opening square bracket"))
9957 for (
int i = 0; i < 4; ++i) {
9962 SMLoc Loc = getLoc();
9963 if (getParser().parseAbsoluteExpression(Temp))
9965 if (Temp < 0 || Temp > 3) {
9966 Error(Loc,
"expected a 2-bit value");
9970 Val += (Temp << i * 2);
9980AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
9981 using namespace AMDGPU::DPP;
9986 SMLoc Loc = getLoc();
9988 if (getParser().parseAbsoluteExpression(Val))
9991 struct DppCtrlCheck {
9997 DppCtrlCheck
Check = StringSwitch<DppCtrlCheck>(Ctrl)
9998 .Case(
"wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
9999 .Case(
"wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
10000 .Case(
"wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
10001 .Case(
"wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
10002 .Case(
"row_shl", {DppCtrl::ROW_SHL0, 1, 15})
10003 .Case(
"row_shr", {DppCtrl::ROW_SHR0, 1, 15})
10004 .Case(
"row_ror", {DppCtrl::ROW_ROR0, 1, 15})
10005 .Case(
"row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
10006 .Case(
"row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
10007 .Case(
"row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
10011 if (
Check.Ctrl == -1) {
10012 Valid = (
Ctrl ==
"row_bcast" && (Val == 15 || Val == 31));
10020 Error(Loc, Twine(
"invalid ", Ctrl) + Twine(
" value"));
10028 using namespace AMDGPU::DPP;
10031 !isSupportedDPPCtrl(getTokenStr(),
Operands))
10034 SMLoc S = getLoc();
10040 if (Ctrl ==
"row_mirror") {
10041 Val = DppCtrl::ROW_MIRROR;
10042 }
else if (Ctrl ==
"row_half_mirror") {
10043 Val = DppCtrl::ROW_HALF_MIRROR;
10046 if (Ctrl ==
"quad_perm") {
10047 Val = parseDPPCtrlPerm();
10049 Val = parseDPPCtrlSel(Ctrl);
10058 AMDGPUOperand::CreateImm(
this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
10064 OptionalImmIndexMap OptionalIdx;
10071 int OldIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::old);
10073 AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::src2_modifiers);
10074 bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
10078 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10079 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10083 int VdstInIdx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::vdst_in);
10084 bool IsVOP3CvtSrDpp =
Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
10085 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
10086 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
10087 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
10093 if (OldIdx == NumOperands) {
10095 constexpr int DST_IDX = 0;
10097 }
else if (Src2ModIdx == NumOperands) {
10107 if (IsVOP3CvtSrDpp) {
10116 if (TiedTo != -1) {
10121 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10123 if (IsDPP8 &&
Op.isDppFI()) {
10126 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
10127 }
else if (
Op.isReg()) {
10128 Op.addRegOperands(Inst, 1);
10129 }
else if (
Op.isImm() &&
10131 Op.addImmOperands(Inst, 1);
10132 }
else if (
Op.isImm()) {
10133 OptionalIdx[
Op.getImmTy()] =
I;
10141 AMDGPUOperand::ImmTyClamp);
10147 AMDGPUOperand::ImmTyByteSel);
10154 cvtVOP3P(Inst,
Operands, OptionalIdx);
10156 cvtVOP3OpSel(Inst,
Operands, OptionalIdx);
10163 using namespace llvm::AMDGPU::DPP;
10173 AMDGPUOperand::ImmTyDppFI);
10178 OptionalImmIndexMap OptionalIdx;
10182 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10183 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10190 if (TiedTo != -1) {
10195 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10197 if (
Op.isReg() && validateVccOperand(
Op.getReg())) {
10205 Op.addImmOperands(Inst, 1);
10207 Op.addRegWithFPInputModsOperands(Inst, 2);
10208 }
else if (
Op.isDppFI()) {
10210 }
else if (
Op.isReg()) {
10211 Op.addRegOperands(Inst, 1);
10217 Op.addRegWithFPInputModsOperands(Inst, 2);
10218 }
else if (
Op.isReg()) {
10219 Op.addRegOperands(Inst, 1);
10220 }
else if (
Op.isDPPCtrl()) {
10221 Op.addImmOperands(Inst, 1);
10222 }
else if (
Op.isImm()) {
10224 OptionalIdx[
Op.getImmTy()] =
I;
10232 using namespace llvm::AMDGPU::DPP;
10240 AMDGPUOperand::ImmTyDppFI);
10251 AMDGPUOperand::ImmTy
Type) {
10252 return parseStringOrIntWithPrefix(
10254 {
"BYTE_0",
"BYTE_1",
"BYTE_2",
"BYTE_3",
"WORD_0",
"WORD_1",
"DWORD"},
10259 return parseStringOrIntWithPrefix(
10260 Operands,
"dst_unused", {
"UNUSED_PAD",
"UNUSED_SEXT",
"UNUSED_PRESERVE"},
10261 AMDGPUOperand::ImmTySDWADstUnused);
10285 uint64_t BasicInstType,
10288 using namespace llvm::AMDGPU::SDWA;
10290 OptionalImmIndexMap OptionalIdx;
10291 bool SkipVcc = SkipDstVcc || SkipSrcVcc;
10292 bool SkippedVcc =
false;
10296 for (
unsigned J = 0; J <
Desc.getNumDefs(); ++J) {
10297 ((AMDGPUOperand &)*
Operands[
I++]).addRegOperands(Inst, 1);
10301 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
I]);
10302 if (SkipVcc && !SkippedVcc &&
Op.isReg() &&
10303 (
Op.getReg() == AMDGPU::VCC ||
Op.getReg() == AMDGPU::VCC_LO)) {
10321 Op.addRegOrImmWithInputModsOperands(Inst, 2);
10322 }
else if (
Op.isImm()) {
10324 OptionalIdx[
Op.getImmTy()] =
I;
10328 SkippedVcc =
false;
10332 if (
Opc != AMDGPU::V_NOP_sdwa_gfx10 &&
Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
10333 Opc != AMDGPU::V_NOP_sdwa_vi) {
10335 switch (BasicInstType) {
10339 AMDGPUOperand::ImmTyClamp, 0);
10343 AMDGPUOperand::ImmTyOModSI, 0);
10347 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
10351 AMDGPUOperand::ImmTySDWADstUnused,
10352 DstUnused::UNUSED_PRESERVE);
10359 AMDGPUOperand::ImmTyClamp, 0);
10373 AMDGPUOperand::ImmTyClamp, 0);
10379 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
10385 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
10386 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
10387 auto *it = Inst.
begin();
10389 it, AMDGPU::getNamedOperandIdx(Inst.
getOpcode(), AMDGPU::OpName::src2));
10401#define GET_MATCHER_IMPLEMENTATION
10402#define GET_MNEMONIC_SPELL_CHECKER
10403#define GET_MNEMONIC_CHECKER
10404#include "AMDGPUGenAsmMatcher.inc"
10410 return parseTokenOp(
"addr64",
Operands);
10412 return parseTokenOp(
"done",
Operands);
10414 return parseTokenOp(
"idxen",
Operands);
10416 return parseTokenOp(
"lds",
Operands);
10418 return parseTokenOp(
"offen",
Operands);
10420 return parseTokenOp(
"off",
Operands);
10421 case MCK_row_95_en:
10422 return parseTokenOp(
"row_en",
Operands);
10424 return parseNamedBit(
"gds",
Operands, AMDGPUOperand::ImmTyGDS);
10426 return parseNamedBit(
"tfe",
Operands, AMDGPUOperand::ImmTyTFE);
10428 return tryCustomParseOperand(
Operands, MCK);
10433unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &
Op,
10439 AMDGPUOperand &Operand = (AMDGPUOperand&)
Op;
10442 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
10444 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
10446 return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
10448 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
10450 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
10452 return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
10460 return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
10462 return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
10463 case MCK_SOPPBrTarget:
10464 return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
10465 case MCK_VReg32OrOff:
10466 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
10467 case MCK_InterpSlot:
10468 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
10469 case MCK_InterpAttr:
10470 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
10471 case MCK_InterpAttrChan:
10472 return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
10474 case MCK_SReg_64_XEXEC:
10484 return Operand.isNull() ? Match_Success : Match_InvalidOperand;
10486 return Match_InvalidOperand;
10495 SMLoc S = getLoc();
10504 return Error(S,
"expected a 16-bit value");
10507 AMDGPUOperand::CreateImm(
this,
Imm, S, AMDGPUOperand::ImmTyEndpgm));
10511bool AMDGPUOperand::isEndpgm()
const {
return isImmTy(ImmTyEndpgm); }
10517bool 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
mir Rename Register Operands
Register const TargetRegisterInfo * TRI
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
MachineInstr unsigned OpIdx
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
Interface definition for SIInstrInfo.
unsigned unsigned DefaultVal
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
StringSet - A set-like wrapper for the StringMap.
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
static const char * getRegisterName(MCRegister Reg)
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createLit(LitModifier Lit, int64_t Value, MCContext &Ctx)
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
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.
Target independent representation for an assembler token.
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.
Base class for the full range of assembler expressions which are needed for parsing.
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.
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
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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)
unsigned getVGPREncodingGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI)
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
ArrayRef< GFXVersion > getGFXVersions()
constexpr unsigned COMPONENTS[]
bool isPackedFP32Inst(unsigned Opc)
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc, unsigned OpNo)
Get size of register operand.
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?
bool isDPALU_DPP(const MCInstrDesc &OpDesc, const MCSubtargetInfo &ST)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
bool hasMIMG_R128(const MCSubtargetInfo &STI)
bool hasG16(const MCSubtargetInfo &STI)
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
LLVM_READONLY int64_t getLitValue(const MCExpr *Expr)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isInlineValue(unsigned Reg)
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
bool isGFX10Plus(const MCSubtargetInfo &STI)
@ 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 hasGDS(const MCSubtargetInfo &STI)
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
bool isGFX9Plus(const MCSubtargetInfo &STI)
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
const int OPR_ID_DUPLICATE
bool isVOPD(unsigned Opc)
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isGFX1250(const MCSubtargetInfo &STI)
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
bool isVI(const MCSubtargetInfo &STI)
int64_t encode32BitLiteral(int64_t Imm, OperandType Type)
bool supportsScaleOffset(const MCInstrInfo &MII, unsigned Opcode)
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
bool supportsWGP(const MCSubtargetInfo &STI)
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
bool isCI(const MCSubtargetInfo &STI)
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
bool hasVOPD(const MCSubtargetInfo &STI)
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
bool isPermlane16(unsigned Opc)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ UNDEF
UNDEF - An undefined node.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
StringMapEntry< Value * > ValueName
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
testing::Matcher< const detail::ErrorHolder & > Failed()
void PrintError(const Twine &Msg)
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
FunctionAddr VTableAddr uintptr_t uintptr_t DataSize
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Target & getTheR600Target()
The target for R600 GPUs.
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.
int popcount(T Value) noexcept
Count the number of set bits in a value.
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
static LLVM_ABI const fltSemantics & IEEEsingle() LLVM_READNONE
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI const fltSemantics & IEEEdouble() LLVM_READNONE
static LLVM_ABI const fltSemantics & IEEEhalf() LLVM_READNONE
static LLVM_ABI const fltSemantics & BFloat() LLVM_READNONE
opStatus
IEEE-754R 7: Default exception handling.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
uint32_t group_segment_fixed_size
uint32_t private_segment_fixed_size