47 class AMDGPUAsmParser;
49 enum RegisterKind { IS_UNKNOWN,
IS_VGPR, IS_SGPR, IS_AGPR, IS_TTMP, IS_SPECIAL };
63 SMLoc StartLoc, EndLoc;
64 const AMDGPUAsmParser *AsmParser;
67 AMDGPUOperand(KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
68 :
Kind(Kind_), AsmParser(AsmParser_) {}
70 using Ptr = std::unique_ptr<AMDGPUOperand>;
77 bool hasFPModifiers()
const {
return Abs || Neg; }
78 bool hasIntModifiers()
const {
return Sext; }
79 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
81 int64_t getFPModifiersOperand()
const {
88 int64_t getIntModifiersOperand()
const {
94 int64_t getModifiersOperand()
const {
95 assert(!(hasFPModifiers() && hasIntModifiers())
96 &&
"fp and int modifiers should not be used simultaneously");
97 if (hasFPModifiers()) {
98 return getFPModifiersOperand();
99 }
else if (hasIntModifiers()) {
100 return getIntModifiersOperand();
184 mutable ImmKindTy
Kind;
201 bool isToken()
const override {
209 return isSymbolRefExpr();
212 bool isSymbolRefExpr()
const {
213 return isExpr() && Expr && isa<MCSymbolRefExpr>(Expr);
216 bool isImm()
const override {
217 return Kind == Immediate;
220 void setImmKindNone()
const {
222 Imm.Kind = ImmKindTyNone;
225 void setImmKindLiteral()
const {
227 Imm.Kind = ImmKindTyLiteral;
230 void setImmKindConst()
const {
232 Imm.Kind = ImmKindTyConst;
235 bool IsImmKindLiteral()
const {
236 return isImm() &&
Imm.Kind == ImmKindTyLiteral;
239 bool isImmKindConst()
const {
240 return isImm() &&
Imm.Kind == ImmKindTyConst;
243 bool isInlinableImm(
MVT type)
const;
244 bool isLiteralImm(
MVT type)
const;
246 bool isRegKind()
const {
250 bool isReg()
const override {
251 return isRegKind() && !hasModifiers();
254 bool isRegOrInline(
unsigned RCID,
MVT type)
const {
255 return isRegClass(RCID) || isInlinableImm(
type);
259 return isRegOrInline(RCID,
type) || isLiteralImm(
type);
262 bool isRegOrImmWithInt16InputMods()
const {
266 bool isRegOrImmWithInt32InputMods()
const {
270 bool isRegOrImmWithInt64InputMods()
const {
274 bool isRegOrImmWithFP16InputMods()
const {
278 bool isRegOrImmWithFP32InputMods()
const {
282 bool isRegOrImmWithFP64InputMods()
const {
286 bool isVReg()
const {
287 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
288 isRegClass(AMDGPU::VReg_64RegClassID) ||
289 isRegClass(AMDGPU::VReg_96RegClassID) ||
290 isRegClass(AMDGPU::VReg_128RegClassID) ||
291 isRegClass(AMDGPU::VReg_160RegClassID) ||
292 isRegClass(AMDGPU::VReg_192RegClassID) ||
293 isRegClass(AMDGPU::VReg_256RegClassID) ||
294 isRegClass(AMDGPU::VReg_512RegClassID) ||
295 isRegClass(AMDGPU::VReg_1024RegClassID);
298 bool isVReg32()
const {
299 return isRegClass(AMDGPU::VGPR_32RegClassID);
302 bool isVReg32OrOff()
const {
303 return isOff() || isVReg32();
306 bool isNull()
const {
307 return isRegKind() &&
getReg() == AMDGPU::SGPR_NULL;
310 bool isVRegWithInputMods()
const;
312 bool isSDWAOperand(
MVT type)
const;
313 bool isSDWAFP16Operand()
const;
314 bool isSDWAFP32Operand()
const;
315 bool isSDWAInt16Operand()
const;
316 bool isSDWAInt32Operand()
const;
318 bool isImmTy(ImmTy ImmT)
const {
322 bool isImmModifier()
const {
323 return isImm() &&
Imm.Type != ImmTyNone;
326 bool isClampSI()
const {
return isImmTy(ImmTyClampSI); }
327 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
328 bool isDMask()
const {
return isImmTy(ImmTyDMask); }
329 bool isDim()
const {
return isImmTy(ImmTyDim); }
330 bool isUNorm()
const {
return isImmTy(ImmTyUNorm); }
331 bool isDA()
const {
return isImmTy(ImmTyDA); }
332 bool isR128A16()
const {
return isImmTy(ImmTyR128A16); }
333 bool isGFX10A16()
const {
return isImmTy(ImmTyA16); }
334 bool isLWE()
const {
return isImmTy(ImmTyLWE); }
335 bool isOff()
const {
return isImmTy(ImmTyOff); }
336 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
337 bool isExpVM()
const {
return isImmTy(ImmTyExpVM); }
338 bool isExpCompr()
const {
return isImmTy(ImmTyExpCompr); }
339 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
340 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
341 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
342 bool isOffset()
const {
return isImmTy(ImmTyOffset) &&
isUInt<16>(getImm()); }
343 bool isOffset0()
const {
return isImmTy(ImmTyOffset0) &&
isUInt<8>(getImm()); }
344 bool isOffset1()
const {
return isImmTy(ImmTyOffset1) &&
isUInt<8>(getImm()); }
346 bool isFlatOffset()
const {
return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
347 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
348 bool isLDS()
const {
return isImmTy(ImmTyLDS); }
349 bool isCPol()
const {
return isImmTy(ImmTyCPol); }
350 bool isSWZ()
const {
return isImmTy(ImmTySWZ); }
351 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
352 bool isD16()
const {
return isImmTy(ImmTyD16); }
353 bool isFORMAT()
const {
return isImmTy(ImmTyFORMAT) && isUInt<7>(getImm()); }
354 bool isBankMask()
const {
return isImmTy(ImmTyDppBankMask); }
355 bool isRowMask()
const {
return isImmTy(ImmTyDppRowMask); }
356 bool isBoundCtrl()
const {
return isImmTy(ImmTyDppBoundCtrl); }
357 bool isFI()
const {
return isImmTy(ImmTyDppFi); }
358 bool isSDWADstSel()
const {
return isImmTy(ImmTySdwaDstSel); }
359 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySdwaSrc0Sel); }
360 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySdwaSrc1Sel); }
361 bool isSDWADstUnused()
const {
return isImmTy(ImmTySdwaDstUnused); }
362 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
363 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
364 bool isAttrChan()
const {
return isImmTy(ImmTyAttrChan); }
365 bool isOpSel()
const {
return isImmTy(ImmTyOpSel); }
366 bool isOpSelHi()
const {
return isImmTy(ImmTyOpSelHi); }
367 bool isNegLo()
const {
return isImmTy(ImmTyNegLo); }
368 bool isNegHi()
const {
return isImmTy(ImmTyNegHi); }
369 bool isHigh()
const {
return isImmTy(ImmTyHigh); }
372 return isClampSI() || isOModSI();
375 bool isRegOrImm()
const {
379 bool isRegClass(
unsigned RCID)
const;
383 bool isRegOrInlineNoMods(
unsigned RCID,
MVT type)
const {
384 return isRegOrInline(RCID,
type) && !hasModifiers();
387 bool isSCSrcB16()
const {
388 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID,
MVT::i16);
391 bool isSCSrcV2B16()
const {
395 bool isSCSrcB32()
const {
396 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID,
MVT::i32);
399 bool isSCSrcB64()
const {
400 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID,
MVT::i64);
403 bool isBoolReg()
const;
405 bool isSCSrcF16()
const {
406 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID,
MVT::f16);
409 bool isSCSrcV2F16()
const {
413 bool isSCSrcF32()
const {
414 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID,
MVT::f32);
417 bool isSCSrcF64()
const {
418 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID,
MVT::f64);
421 bool isSSrcB32()
const {
422 return isSCSrcB32() || isLiteralImm(
MVT::i32) || isExpr();
425 bool isSSrcB16()
const {
426 return isSCSrcB16() || isLiteralImm(
MVT::i16);
429 bool isSSrcV2B16()
const {
434 bool isSSrcB64()
const {
437 return isSCSrcB64() || isLiteralImm(
MVT::i64);
440 bool isSSrcF32()
const {
441 return isSCSrcB32() || isLiteralImm(
MVT::f32) || isExpr();
444 bool isSSrcF64()
const {
445 return isSCSrcB64() || isLiteralImm(
MVT::f64);
448 bool isSSrcF16()
const {
449 return isSCSrcB16() || isLiteralImm(
MVT::f16);
452 bool isSSrcV2F16()
const {
457 bool isSSrcV2FP32()
const {
462 bool isSCSrcV2FP32()
const {
467 bool isSSrcV2INT32()
const {
472 bool isSCSrcV2INT32()
const {
477 bool isSSrcOrLdsB32()
const {
478 return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID,
MVT::i32) ||
482 bool isVCSrcB32()
const {
483 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID,
MVT::i32);
486 bool isVCSrcB64()
const {
487 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID,
MVT::i64);
490 bool isVCSrcB16()
const {
491 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID,
MVT::i16);
494 bool isVCSrcV2B16()
const {
498 bool isVCSrcF32()
const {
499 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID,
MVT::f32);
502 bool isVCSrcF64()
const {
503 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID,
MVT::f64);
506 bool isVCSrcF16()
const {
507 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID,
MVT::f16);
510 bool isVCSrcV2F16()
const {
514 bool isVSrcB32()
const {
515 return isVCSrcF32() || isLiteralImm(
MVT::i32) || isExpr();
518 bool isVSrcB64()
const {
519 return isVCSrcF64() || isLiteralImm(
MVT::i64);
522 bool isVSrcB16()
const {
523 return isVCSrcB16() || isLiteralImm(
MVT::i16);
526 bool isVSrcV2B16()
const {
527 return isVSrcB16() || isLiteralImm(
MVT::v2i16);
530 bool isVCSrcV2FP32()
const {
534 bool isVSrcV2FP32()
const {
535 return isVSrcF64() || isLiteralImm(
MVT::v2f32);
538 bool isVCSrcV2INT32()
const {
542 bool isVSrcV2INT32()
const {
543 return isVSrcB64() || isLiteralImm(
MVT::v2i32);
546 bool isVSrcF32()
const {
547 return isVCSrcF32() || isLiteralImm(
MVT::f32) || isExpr();
550 bool isVSrcF64()
const {
551 return isVCSrcF64() || isLiteralImm(
MVT::f64);
554 bool isVSrcF16()
const {
555 return isVCSrcF16() || isLiteralImm(
MVT::f16);
558 bool isVSrcV2F16()
const {
559 return isVSrcF16() || isLiteralImm(
MVT::v2f16);
562 bool isVISrcB32()
const {
563 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID,
MVT::i32);
566 bool isVISrcB16()
const {
567 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID,
MVT::i16);
570 bool isVISrcV2B16()
const {
574 bool isVISrcF32()
const {
575 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID,
MVT::f32);
578 bool isVISrcF16()
const {
579 return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID,
MVT::f16);
582 bool isVISrcV2F16()
const {
583 return isVISrcF16() || isVISrcB32();
586 bool isVISrc_64B64()
const {
587 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID,
MVT::i64);
590 bool isVISrc_64F64()
const {
591 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID,
MVT::f64);
594 bool isVISrc_64V2FP32()
const {
595 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID,
MVT::f32);
598 bool isVISrc_64V2INT32()
const {
599 return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID,
MVT::i32);
602 bool isVISrc_256B64()
const {
603 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID,
MVT::i64);
606 bool isVISrc_256F64()
const {
607 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID,
MVT::f64);
610 bool isVISrc_128B16()
const {
611 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID,
MVT::i16);
614 bool isVISrc_128V2B16()
const {
615 return isVISrc_128B16();
618 bool isVISrc_128B32()
const {
619 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID,
MVT::i32);
622 bool isVISrc_128F32()
const {
623 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID,
MVT::f32);
626 bool isVISrc_256V2FP32()
const {
627 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID,
MVT::f32);
630 bool isVISrc_256V2INT32()
const {
631 return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID,
MVT::i32);
634 bool isVISrc_512B32()
const {
635 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID,
MVT::i32);
638 bool isVISrc_512B16()
const {
639 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID,
MVT::i16);
642 bool isVISrc_512V2B16()
const {
643 return isVISrc_512B16();
646 bool isVISrc_512F32()
const {
647 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID,
MVT::f32);
650 bool isVISrc_512F16()
const {
651 return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID,
MVT::f16);
654 bool isVISrc_512V2F16()
const {
655 return isVISrc_512F16() || isVISrc_512B32();
658 bool isVISrc_1024B32()
const {
659 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID,
MVT::i32);
662 bool isVISrc_1024B16()
const {
663 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID,
MVT::i16);
666 bool isVISrc_1024V2B16()
const {
667 return isVISrc_1024B16();
670 bool isVISrc_1024F32()
const {
671 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID,
MVT::f32);
674 bool isVISrc_1024F16()
const {
675 return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID,
MVT::f16);
678 bool isVISrc_1024V2F16()
const {
679 return isVISrc_1024F16() || isVISrc_1024B32();
682 bool isAISrcB32()
const {
683 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID,
MVT::i32);
686 bool isAISrcB16()
const {
687 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID,
MVT::i16);
690 bool isAISrcV2B16()
const {
694 bool isAISrcF32()
const {
695 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID,
MVT::f32);
698 bool isAISrcF16()
const {
699 return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID,
MVT::f16);
702 bool isAISrcV2F16()
const {
703 return isAISrcF16() || isAISrcB32();
706 bool isAISrc_64B64()
const {
707 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID,
MVT::i64);
710 bool isAISrc_64F64()
const {
711 return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID,
MVT::f64);
714 bool isAISrc_128B32()
const {
715 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID,
MVT::i32);
718 bool isAISrc_128B16()
const {
719 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID,
MVT::i16);
722 bool isAISrc_128V2B16()
const {
723 return isAISrc_128B16();
726 bool isAISrc_128F32()
const {
727 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID,
MVT::f32);
730 bool isAISrc_128F16()
const {
731 return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID,
MVT::f16);
734 bool isAISrc_128V2F16()
const {
735 return isAISrc_128F16() || isAISrc_128B32();
738 bool isVISrc_128F16()
const {
739 return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID,
MVT::f16);
742 bool isVISrc_128V2F16()
const {
743 return isVISrc_128F16() || isVISrc_128B32();
746 bool isAISrc_256B64()
const {
747 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID,
MVT::i64);
750 bool isAISrc_256F64()
const {
751 return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID,
MVT::f64);
754 bool isAISrc_512B32()
const {
755 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID,
MVT::i32);
758 bool isAISrc_512B16()
const {
759 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID,
MVT::i16);
762 bool isAISrc_512V2B16()
const {
763 return isAISrc_512B16();
766 bool isAISrc_512F32()
const {
767 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID,
MVT::f32);
770 bool isAISrc_512F16()
const {
771 return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID,
MVT::f16);
774 bool isAISrc_512V2F16()
const {
775 return isAISrc_512F16() || isAISrc_512B32();
778 bool isAISrc_1024B32()
const {
779 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID,
MVT::i32);
782 bool isAISrc_1024B16()
const {
783 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID,
MVT::i16);
786 bool isAISrc_1024V2B16()
const {
787 return isAISrc_1024B16();
790 bool isAISrc_1024F32()
const {
791 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID,
MVT::f32);
794 bool isAISrc_1024F16()
const {
795 return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID,
MVT::f16);
798 bool isAISrc_1024V2F16()
const {
799 return isAISrc_1024F16() || isAISrc_1024B32();
802 bool isKImmFP32()
const {
806 bool isKImmFP16()
const {
810 bool isMem()
const override {
814 bool isExpr()
const {
818 bool isSoppBrTarget()
const {
819 return isExpr() ||
isImm();
822 bool isSWaitCnt()
const;
823 bool isDepCtr()
const;
824 bool isSDelayAlu()
const;
825 bool isHwreg()
const;
826 bool isSendMsg()
const;
827 bool isSwizzle()
const;
828 bool isSMRDOffset8()
const;
829 bool isSMEMOffset()
const;
830 bool isSMRDLiteralOffset()
const;
832 bool isDPPCtrl()
const;
836 bool isGPRIdxMode()
const;
837 bool isS16Imm()
const;
838 bool isU16Imm()
const;
839 bool isEndpgm()
const;
840 bool isWaitVDST()
const;
841 bool isWaitEXP()
const;
846 return S->getSymbol().getName();
853 return getExpressionAsToken();
858 int64_t getImm()
const {
863 void setImm(int64_t Val) {
868 ImmTy getImmTy()
const {
873 unsigned getReg()
const override {
878 SMLoc getStartLoc()
const override {
882 SMLoc getEndLoc()
const override {
887 return SMRange(StartLoc, EndLoc);
890 Modifiers getModifiers()
const {
891 assert(isRegKind() || isImmTy(ImmTyNone));
892 return isRegKind() ?
Reg.Mods :
Imm.Mods;
895 void setModifiers(Modifiers Mods) {
896 assert(isRegKind() || isImmTy(ImmTyNone));
903 bool hasModifiers()
const {
904 return getModifiers().hasModifiers();
907 bool hasFPModifiers()
const {
908 return getModifiers().hasFPModifiers();
911 bool hasIntModifiers()
const {
912 return getModifiers().hasIntModifiers();
917 void addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
919 void addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const;
921 template <
unsigned Bitw
idth>
922 void addKImmFPOperands(
MCInst &Inst,
unsigned N)
const;
924 void addKImmFP16Operands(
MCInst &Inst,
unsigned N)
const {
925 addKImmFPOperands<16>(Inst,
N);
928 void addKImmFP32Operands(
MCInst &Inst,
unsigned N)
const {
929 addKImmFPOperands<32>(Inst,
N);
932 void addRegOperands(
MCInst &Inst,
unsigned N)
const;
934 void addBoolRegOperands(
MCInst &Inst,
unsigned N)
const {
935 addRegOperands(Inst,
N);
938 void addRegOrImmOperands(
MCInst &Inst,
unsigned N)
const {
940 addRegOperands(Inst,
N);
944 addImmOperands(Inst,
N);
947 void addRegOrImmWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
948 Modifiers Mods = getModifiers();
951 addRegOperands(Inst,
N);
953 addImmOperands(Inst,
N,
false);
957 void addRegOrImmWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
958 assert(!hasIntModifiers());
959 addRegOrImmWithInputModsOperands(Inst,
N);
962 void addRegOrImmWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
963 assert(!hasFPModifiers());
964 addRegOrImmWithInputModsOperands(Inst,
N);
967 void addRegWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
968 Modifiers Mods = getModifiers();
971 addRegOperands(Inst,
N);
974 void addRegWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
975 assert(!hasIntModifiers());
976 addRegWithInputModsOperands(Inst,
N);
979 void addRegWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
980 assert(!hasFPModifiers());
981 addRegWithInputModsOperands(Inst,
N);
984 void addSoppBrTargetOperands(
MCInst &Inst,
unsigned N)
const {
986 addImmOperands(Inst,
N);
995 case ImmTyNone: OS <<
"None";
break;
996 case ImmTyGDS: OS <<
"GDS";
break;
997 case ImmTyLDS: OS <<
"LDS";
break;
998 case ImmTyOffen: OS <<
"Offen";
break;
999 case ImmTyIdxen: OS <<
"Idxen";
break;
1000 case ImmTyAddr64: OS <<
"Addr64";
break;
1001 case ImmTyOffset: OS <<
"Offset";
break;
1002 case ImmTyInstOffset: OS <<
"InstOffset";
break;
1003 case ImmTyOffset0: OS <<
"Offset0";
break;
1004 case ImmTyOffset1: OS <<
"Offset1";
break;
1005 case ImmTyCPol: OS <<
"CPol";
break;
1006 case ImmTySWZ: OS <<
"SWZ";
break;
1007 case ImmTyTFE: OS <<
"TFE";
break;
1008 case ImmTyD16: OS <<
"D16";
break;
1009 case ImmTyFORMAT: OS <<
"FORMAT";
break;
1010 case ImmTyClampSI: OS <<
"ClampSI";
break;
1011 case ImmTyOModSI: OS <<
"OModSI";
break;
1012 case ImmTyDPP8: OS <<
"DPP8";
break;
1013 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
1014 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
1015 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
1016 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
1017 case ImmTyDppFi: OS <<
"FI";
break;
1018 case ImmTySdwaDstSel: OS <<
"SdwaDstSel";
break;
1019 case ImmTySdwaSrc0Sel: OS <<
"SdwaSrc0Sel";
break;
1020 case ImmTySdwaSrc1Sel: OS <<
"SdwaSrc1Sel";
break;
1021 case ImmTySdwaDstUnused: OS <<
"SdwaDstUnused";
break;
1022 case ImmTyDMask: OS <<
"DMask";
break;
1023 case ImmTyDim: OS <<
"Dim";
break;
1024 case ImmTyUNorm: OS <<
"UNorm";
break;
1025 case ImmTyDA: OS <<
"DA";
break;
1026 case ImmTyR128A16: OS <<
"R128A16";
break;
1027 case ImmTyA16: OS <<
"A16";
break;
1028 case ImmTyLWE: OS <<
"LWE";
break;
1029 case ImmTyOff: OS <<
"Off";
break;
1030 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
1031 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
1032 case ImmTyExpVM: OS <<
"ExpVM";
break;
1033 case ImmTyHwreg: OS <<
"Hwreg";
break;
1034 case ImmTySendMsg: OS <<
"SendMsg";
break;
1035 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
1036 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
1037 case ImmTyAttrChan: OS <<
"AttrChan";
break;
1038 case ImmTyOpSel: OS <<
"OpSel";
break;
1039 case ImmTyOpSelHi: OS <<
"OpSelHi";
break;
1040 case ImmTyNegLo: OS <<
"NegLo";
break;
1041 case ImmTyNegHi: OS <<
"NegHi";
break;
1042 case ImmTySwizzle: OS <<
"Swizzle";
break;
1043 case ImmTyGprIdxMode: OS <<
"GprIdxMode";
break;
1044 case ImmTyHigh: OS <<
"High";
break;
1045 case ImmTyBLGP: OS <<
"BLGP";
break;
1046 case ImmTyCBSZ: OS <<
"CBSZ";
break;
1047 case ImmTyABID: OS <<
"ABID";
break;
1048 case ImmTyEndpgm: OS <<
"Endpgm";
break;
1049 case ImmTyWaitVDST: OS <<
"WaitVDST";
break;
1050 case ImmTyWaitEXP: OS <<
"WaitEXP";
break;
1057 OS <<
"<register " <<
getReg() <<
" mods: " <<
Reg.Mods <<
'>';
1060 OS <<
'<' << getImm();
1061 if (getImmTy() != ImmTyNone) {
1062 OS <<
" type: "; printImmTy(OS, getImmTy());
1064 OS <<
" mods: " <<
Imm.Mods <<
'>';
1067 OS <<
'\'' << getToken() <<
'\'';
1070 OS <<
"<expr " << *Expr << '>
';
1075 static AMDGPUOperand::Ptr CreateImm(const AMDGPUAsmParser *AsmParser,
1076 int64_t Val, SMLoc Loc,
1077 ImmTy Type = ImmTyNone,
1078 bool IsFPImm = false) {
1079 auto Op = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1081 Op->Imm.IsFPImm = IsFPImm;
1082 Op->Imm.Kind = ImmKindTyNone;
1083 Op->Imm.Type = Type;
1084 Op->Imm.Mods = Modifiers();
1090 static AMDGPUOperand::Ptr CreateToken(const AMDGPUAsmParser *AsmParser,
1091 StringRef Str, SMLoc Loc,
1092 bool HasExplicitEncodingSize = true) {
1093 auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1094 Res->Tok.Data = Str.data();
1095 Res->Tok.Length = Str.size();
1096 Res->StartLoc = Loc;
1101 static AMDGPUOperand::Ptr CreateReg(const AMDGPUAsmParser *AsmParser,
1102 unsigned RegNo, SMLoc S,
1104 auto Op = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1105 Op->Reg.RegNo = RegNo;
1106 Op->Reg.Mods = Modifiers();
1112 static AMDGPUOperand::Ptr CreateExpr(const AMDGPUAsmParser *AsmParser,
1113 const class MCExpr *Expr, SMLoc S) {
1114 auto Op = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1122 raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods) {
1123 OS << "abs:" << Mods.Abs << " neg: " << Mods.Neg << " sext:" << Mods.Sext;
1127 //===----------------------------------------------------------------------===//
1129 //===----------------------------------------------------------------------===//
1131 // Holds info related to the current kernel, e.g. count of SGPRs used.
1132 // Kernel scope begins at .amdgpu_hsa_kernel directive, ends at next
1133 // .amdgpu_hsa_kernel or at EOF.
1134 class KernelScopeInfo {
1135 int SgprIndexUnusedMin = -1;
1136 int VgprIndexUnusedMin = -1;
1137 int AgprIndexUnusedMin = -1;
1138 MCContext *Ctx = nullptr;
1139 MCSubtargetInfo const *MSTI = nullptr;
1141 void usesSgprAt(int i) {
1142 if (i >= SgprIndexUnusedMin) {
1143 SgprIndexUnusedMin = ++i;
1145 MCSymbol* const Sym =
1146 Ctx->getOrCreateSymbol(Twine(".kernel.sgpr_count"));
1147 Sym->setVariableValue(MCConstantExpr::create(SgprIndexUnusedMin, *Ctx));
1152 void usesVgprAt(int i) {
1153 if (i >= VgprIndexUnusedMin) {
1154 VgprIndexUnusedMin = ++i;
1156 MCSymbol* const Sym =
1157 Ctx->getOrCreateSymbol(Twine(".kernel.vgpr_count"));
1158 int totalVGPR = getTotalNumVGPRs(isGFX90A(*MSTI), AgprIndexUnusedMin,
1159 VgprIndexUnusedMin);
1160 Sym->setVariableValue(MCConstantExpr::create(totalVGPR, *Ctx));
1165 void usesAgprAt(int i) {
1166 // Instruction will error in AMDGPUAsmParser::MatchAndEmitInstruction
1167 if (!hasMAIInsts(*MSTI))
1170 if (i >= AgprIndexUnusedMin) {
1171 AgprIndexUnusedMin = ++i;
1173 MCSymbol* const Sym =
1174 Ctx->getOrCreateSymbol(Twine(".kernel.agpr_count"));
1175 Sym->setVariableValue(MCConstantExpr::create(AgprIndexUnusedMin, *Ctx));
1177 // Also update vgpr_count (dependent on agpr_count for gfx908/gfx90a)
1178 MCSymbol* const vSym =
1179 Ctx->getOrCreateSymbol(Twine(".kernel.vgpr_count"));
1180 int totalVGPR = getTotalNumVGPRs(isGFX90A(*MSTI), AgprIndexUnusedMin,
1181 VgprIndexUnusedMin);
1182 vSym->setVariableValue(MCConstantExpr::create(totalVGPR, *Ctx));
1188 KernelScopeInfo() = default;
1190 void initialize(MCContext &Context) {
1192 MSTI = Ctx->getSubtargetInfo();
1194 usesSgprAt(SgprIndexUnusedMin = -1);
1195 usesVgprAt(VgprIndexUnusedMin = -1);
1196 if (hasMAIInsts(*MSTI)) {
1197 usesAgprAt(AgprIndexUnusedMin = -1);
1201 void usesRegister(RegisterKind RegKind, unsigned DwordRegIndex,
1202 unsigned RegWidth) {
1205 usesSgprAt(DwordRegIndex + divideCeil(RegWidth, 32) - 1);
1208 usesAgprAt(DwordRegIndex + divideCeil(RegWidth, 32) - 1);
1211 usesVgprAt(DwordRegIndex + divideCeil(RegWidth, 32) - 1);
1219 class AMDGPUAsmParser : public MCTargetAsmParser {
1220 MCAsmParser &Parser;
1222 // Number of extra operands parsed after the first optional operand.
1223 // This may be necessary to skip hardcoded mandatory operands.
1224 static const unsigned MAX_OPR_LOOKAHEAD = 8;
1226 unsigned ForcedEncodingSize = 0;
1227 bool ForcedDPP = false;
1228 bool ForcedSDWA = false;
1229 KernelScopeInfo KernelScope;
1235 #define GET_ASSEMBLER_HEADER
1236 #include "AMDGPUGenAsmMatcher.inc"
1241 bool ParseAsAbsoluteExpression(uint32_t &Ret);
1242 bool OutOfRangeError(SMRange Range);
1258 bool calculateGPRBlocks(const FeatureBitset &Features, bool VCCUsed,
1259 bool FlatScrUsed, bool XNACKUsed,
1260 Optional<bool> EnableWavefrontSize32, unsigned NextFreeVGPR,
1261 SMRange VGPRRange, unsigned NextFreeSGPR,
1262 SMRange SGPRRange, unsigned &VGPRBlocks,
1263 unsigned &SGPRBlocks);
1264 bool ParseDirectiveAMDGCNTarget();
1265 bool ParseDirectiveAMDHSAKernel();
1266 bool ParseDirectiveMajorMinor(uint32_t &Major, uint32_t &Minor);
1267 bool ParseDirectiveHSACodeObjectVersion();
1268 bool ParseDirectiveHSACodeObjectISA();
1269 bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header);
1270 bool ParseDirectiveAMDKernelCodeT();
1271 // TODO: Possibly make subtargetHasRegister const.
1272 bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo);
1273 bool ParseDirectiveAMDGPUHsaKernel();
1275 bool ParseDirectiveISAVersion();
1276 bool ParseDirectiveHSAMetadata();
1277 bool ParseDirectivePALMetadataBegin();
1278 bool ParseDirectivePALMetadata();
1279 bool ParseDirectiveAMDGPULDS();
1283 bool ParseToEndDirective(const char *AssemblerDirectiveBegin,
1284 const char *AssemblerDirectiveEnd,
1285 std::string &CollectString);
1287 bool AddNextRegisterToList(unsigned& Reg, unsigned& RegWidth,
1288 RegisterKind RegKind, unsigned Reg1, SMLoc Loc);
1289 bool ParseAMDGPURegister(RegisterKind &RegKind, unsigned &Reg,
1290 unsigned &RegNum, unsigned &RegWidth,
1291 bool RestoreOnFailure = false);
1292 bool ParseAMDGPURegister(RegisterKind &RegKind, unsigned &Reg,
1293 unsigned &RegNum, unsigned &RegWidth,
1294 SmallVectorImpl<AsmToken> &Tokens);
1295 unsigned ParseRegularReg(RegisterKind &RegKind, unsigned &RegNum,
1297 SmallVectorImpl<AsmToken> &Tokens);
1298 unsigned ParseSpecialReg(RegisterKind &RegKind, unsigned &RegNum,
1300 SmallVectorImpl<AsmToken> &Tokens);
1301 unsigned ParseRegList(RegisterKind &RegKind, unsigned &RegNum,
1302 unsigned &RegWidth, SmallVectorImpl<AsmToken> &Tokens);
1303 bool ParseRegRange(unsigned& Num, unsigned& Width);
1304 unsigned getRegularReg(RegisterKind RegKind,
1310 bool isRegister(const AsmToken &Token, const AsmToken &NextToken) const;
1311 Optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1312 void initializeGprCountSymbol(RegisterKind RegKind);
1313 bool updateGprCountSymbols(RegisterKind RegKind, unsigned DwordRegIndex,
1315 void cvtMubufImpl(MCInst &Inst, const OperandVector &Operands,
1316 bool IsAtomic, bool IsLds = false);
1317 void cvtDSImpl(MCInst &Inst, const OperandVector &Operands,
1318 bool IsGdsHardcoded);
1321 enum AMDGPUMatchResultTy {
1322 Match_PreferE32 = FIRST_TARGET_MATCH_RESULT_TY
1325 OperandMode_Default,
1329 using OptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1331 AMDGPUAsmParser(const MCSubtargetInfo &STI, MCAsmParser &_Parser,
1332 const MCInstrInfo &MII,
1333 const MCTargetOptions &Options)
1334 : MCTargetAsmParser(Options, STI, MII), Parser(_Parser) {
1335 MCAsmParserExtension::Initialize(Parser);
1337 if (getFeatureBits().none()) {
1338 // Set default features.
1339 copySTI().ToggleFeature("southern-islands");
1342 setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1345 // TODO: make those pre-defined variables read-only.
1346 // Currently there is none suitable machinery in the core llvm-mc for this.
1347 // MCSymbol::isRedefinable is intended for another purpose, and
1348 // AsmParser::parseDirectiveSet() cannot be specialized for specific target.
1349 AMDGPU::IsaVersion ISA = AMDGPU::getIsaVersion(getSTI().getCPU());
1350 MCContext &Ctx = getContext();
1351 if (ISA.Major >= 6 && isHsaAbiVersion3AndAbove(&getSTI())) {
1353 Ctx.getOrCreateSymbol(Twine(".amdgcn.gfx_generation_number"));
1354 Sym->setVariableValue(MCConstantExpr::create(ISA.Major, Ctx));
1355 Sym = Ctx.getOrCreateSymbol(Twine(".amdgcn.gfx_generation_minor"));
1356 Sym->setVariableValue(MCConstantExpr::create(ISA.Minor, Ctx));
1357 Sym = Ctx.getOrCreateSymbol(Twine(".amdgcn.gfx_generation_stepping"));
1358 Sym->setVariableValue(MCConstantExpr::create(ISA.Stepping, Ctx));
1361 Ctx.getOrCreateSymbol(Twine(".option.machine_version_major"));
1362 Sym->setVariableValue(MCConstantExpr::create(ISA.Major, Ctx));
1363 Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_minor"));
1364 Sym->setVariableValue(MCConstantExpr::create(ISA.Minor, Ctx));
1365 Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_stepping"));
1366 Sym->setVariableValue(MCConstantExpr::create(ISA.Stepping, Ctx));
1368 if (ISA.Major >= 6 && isHsaAbiVersion3AndAbove(&getSTI())) {
1369 initializeGprCountSymbol(IS_VGPR);
1370 initializeGprCountSymbol(IS_SGPR);
1372 KernelScope.initialize(getContext());
1376 bool hasMIMG_R128() const {
1377 return AMDGPU::hasMIMG_R128(getSTI());
1380 bool hasPackedD16() const {
1381 return AMDGPU::hasPackedD16(getSTI());
1384 bool hasGFX10A16() const {
1385 return AMDGPU::hasGFX10A16(getSTI());
1388 bool hasG16() const { return AMDGPU::hasG16(getSTI()); }
1391 return AMDGPU::isSI(getSTI());
1395 return AMDGPU::isCI(getSTI());
1399 return AMDGPU::isVI(getSTI());
1402 bool isGFX9() const {
1403 return AMDGPU::isGFX9(getSTI());
1406 // TODO: isGFX90A is also true for GFX940. We need to clean it.
1407 bool isGFX90A() const {
1408 return AMDGPU::isGFX90A(getSTI());
1411 bool isGFX940() const {
1412 return AMDGPU::isGFX940(getSTI());
1415 bool isGFX9Plus() const {
1416 return AMDGPU::isGFX9Plus(getSTI());
1419 bool isGFX10() const {
1420 return AMDGPU::isGFX10(getSTI());
1423 bool isGFX10Plus() const { return AMDGPU::isGFX10Plus(getSTI()); }
1425 bool isGFX11() const {
1426 return AMDGPU::isGFX11(getSTI());
1429 bool isGFX11Plus() const {
1430 return AMDGPU::isGFX11Plus(getSTI());
1433 bool isGFX10_BEncoding() const {
1434 return AMDGPU::isGFX10_BEncoding(getSTI());
1437 bool hasInv2PiInlineImm() const {
1438 return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1441 bool hasFlatOffsets() const {
1442 return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1445 bool hasArchitectedFlatScratch() const {
1446 return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1449 bool hasSGPR102_SGPR103() const {
1450 return !isVI() && !isGFX9();
1453 bool hasSGPR104_SGPR105() const { return isGFX10Plus(); }
1455 bool hasIntClamp() const {
1456 return getFeatureBits()[AMDGPU::FeatureIntClamp];
1459 AMDGPUTargetStreamer &getTargetStreamer() {
1460 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1461 return static_cast<AMDGPUTargetStreamer &>(TS);
1464 const MCRegisterInfo *getMRI() const {
1465 // We need this const_cast because for some reason getContext() is not const
1467 return const_cast<AMDGPUAsmParser*>(this)->getContext().getRegisterInfo();
1470 const MCInstrInfo *getMII() const {
1474 const FeatureBitset &getFeatureBits() const {
1475 return getSTI().getFeatureBits();
1478 void setForcedEncodingSize(unsigned Size) { ForcedEncodingSize = Size; }
1479 void setForcedDPP(bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1480 void setForcedSDWA(bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1482 unsigned getForcedEncodingSize() const { return ForcedEncodingSize; }
1483 bool isForcedVOP3() const { return ForcedEncodingSize == 64; }
1484 bool isForcedDPP() const { return ForcedDPP; }
1485 bool isForcedSDWA() const { return ForcedSDWA; }
1486 ArrayRef<unsigned> getMatchedVariants() const;
1487 StringRef getMatchedVariantName() const;
1489 std::unique_ptr<AMDGPUOperand> parseRegister(bool RestoreOnFailure = false);
1490 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc,
1491 bool RestoreOnFailure);
1492 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
1493 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1494 SMLoc &EndLoc) override;
1495 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
1496 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
1497 unsigned Kind) override;
1498 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1499 OperandVector &Operands, MCStreamer &Out,
1500 uint64_t &ErrorInfo,
1501 bool MatchingInlineAsm) override;
1502 bool ParseDirective(AsmToken DirectiveID) override;
1503 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Mnemonic,
1504 OperandMode Mode = OperandMode_Default);
1505 StringRef parseMnemonicSuffix(StringRef Name);
1506 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1507 SMLoc NameLoc, OperandVector &Operands) override;
1508 //bool ProcessInstruction(MCInst &Inst);
1510 OperandMatchResultTy parseIntWithPrefix(const char *Prefix, int64_t &Int);
1512 OperandMatchResultTy
1513 parseIntWithPrefix(const char *Prefix, OperandVector &Operands,
1514 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1515 bool (*ConvertResult)(int64_t &) = nullptr);
1517 OperandMatchResultTy
1518 parseOperandArrayWithPrefix(const char *Prefix,
1519 OperandVector &Operands,
1520 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1521 bool (*ConvertResult)(int64_t&) = nullptr);
1523 OperandMatchResultTy
1524 parseNamedBit(StringRef Name, OperandVector &Operands,
1525 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1526 OperandMatchResultTy parseCPol(OperandVector &Operands);
1527 OperandMatchResultTy parseStringWithPrefix(StringRef Prefix,
1532 bool isOperandModifier(const AsmToken &Token, const AsmToken &NextToken) const;
1533 bool isRegOrOperandModifier(const AsmToken &Token, const AsmToken &NextToken) const;
1534 bool isNamedOperandModifier(const AsmToken &Token, const AsmToken &NextToken) const;
1535 bool isOpcodeModifierWithVal(const AsmToken &Token, const AsmToken &NextToken) const;
1536 bool parseSP3NegModifier();
1537 OperandMatchResultTy parseImm(OperandVector &Operands, bool HasSP3AbsModifier = false);
1538 OperandMatchResultTy parseReg(OperandVector &Operands);
1539 OperandMatchResultTy parseRegOrImm(OperandVector &Operands, bool HasSP3AbsMod = false);
1540 OperandMatchResultTy parseRegOrImmWithFPInputMods(OperandVector &Operands, bool AllowImm = true);
1541 OperandMatchResultTy parseRegOrImmWithIntInputMods(OperandVector &Operands, bool AllowImm = true);
1542 OperandMatchResultTy parseRegWithFPInputMods(OperandVector &Operands);
1543 OperandMatchResultTy parseRegWithIntInputMods(OperandVector &Operands);
1544 OperandMatchResultTy parseVReg32OrOff(OperandVector &Operands);
1545 OperandMatchResultTy parseDfmtNfmt(int64_t &Format);
1546 OperandMatchResultTy parseUfmt(int64_t &Format);
1547 OperandMatchResultTy parseSymbolicSplitFormat(StringRef FormatStr, SMLoc Loc, int64_t &Format);
1548 OperandMatchResultTy parseSymbolicUnifiedFormat(StringRef FormatStr, SMLoc Loc, int64_t &Format);
1549 OperandMatchResultTy parseFORMAT(OperandVector &Operands);
1550 OperandMatchResultTy parseSymbolicOrNumericFormat(int64_t &Format);
1551 OperandMatchResultTy parseNumericFormat(int64_t &Format);
1552 bool tryParseFmt(const char *Pref, int64_t MaxVal, int64_t &Val);
1553 bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt, StringRef FormatStr, SMLoc Loc);
1555 void cvtDSOffset01(MCInst &Inst, const OperandVector &Operands);
1556 void cvtDS(MCInst &Inst, const OperandVector &Operands) { cvtDSImpl(Inst, Operands, false); }
1557 void cvtDSGds(MCInst &Inst, const OperandVector &Operands) { cvtDSImpl(Inst, Operands, true); }
1558 void cvtExp(MCInst &Inst, const OperandVector &Operands);
1560 bool parseCnt(int64_t &IntVal);
1561 OperandMatchResultTy parseSWaitCntOps(OperandVector &Operands);
1563 bool parseDepCtr(int64_t &IntVal, unsigned &Mask);
1564 void depCtrError(SMLoc Loc, int ErrorId, StringRef DepCtrName);
1565 OperandMatchResultTy parseDepCtrOps(OperandVector &Operands);
1567 bool parseDelay(int64_t &Delay);
1568 OperandMatchResultTy parseSDelayAluOps(OperandVector &Operands);
1570 OperandMatchResultTy parseHwreg(OperandVector &Operands);
1573 struct OperandInfoTy {
1576 bool IsSymbolic = false;
1577 bool IsDefined = false;
1579 OperandInfoTy(int64_t Id_) : Id(Id_) {}
1582 bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &Op, OperandInfoTy &Stream);
1583 bool validateSendMsg(const OperandInfoTy &Msg,
1584 const OperandInfoTy &Op,
1585 const OperandInfoTy &Stream);
1587 bool parseHwregBody(OperandInfoTy &HwReg,
1588 OperandInfoTy &Offset,
1589 OperandInfoTy &Width);
1590 bool validateHwreg(const OperandInfoTy &HwReg,
1591 const OperandInfoTy &Offset,
1592 const OperandInfoTy &Width);
1594 SMLoc getFlatOffsetLoc(const OperandVector &Operands) const;
1595 SMLoc getSMEMOffsetLoc(const OperandVector &Operands) const;
1596 SMLoc getBLGPLoc(const OperandVector &Operands) const;
1598 SMLoc getOperandLoc(std::function<bool(const AMDGPUOperand&)> Test,
1599 const OperandVector &Operands) const;
1600 SMLoc getImmLoc(AMDGPUOperand::ImmTy Type, const OperandVector &Operands) const;
1601 SMLoc getRegLoc(unsigned Reg, const OperandVector &Operands) const;
1602 SMLoc getLitLoc(const OperandVector &Operands) const;
1603 SMLoc getConstLoc(const OperandVector &Operands) const;
1605 bool validateInstruction(const MCInst &Inst, const SMLoc &IDLoc, const OperandVector &Operands);
1606 bool validateFlatOffset(const MCInst &Inst, const OperandVector &Operands);
1607 bool validateSMEMOffset(const MCInst &Inst, const OperandVector &Operands);
1608 bool validateSOPLiteral(const MCInst &Inst) const;
1609 bool validateConstantBusLimitations(const MCInst &Inst, const OperandVector &Operands);
1610 bool validateEarlyClobberLimitations(const MCInst &Inst, const OperandVector &Operands);
1611 bool validateIntClampSupported(const MCInst &Inst);
1612 bool validateMIMGAtomicDMask(const MCInst &Inst);
1613 bool validateMIMGGatherDMask(const MCInst &Inst);
1614 bool validateMovrels(const MCInst &Inst, const OperandVector &Operands);
1615 Optional<StringRef> validateMIMGDataSize(const MCInst &Inst);
1616 bool validateMIMGAddrSize(const MCInst &Inst);
1617 bool validateMIMGD16(const MCInst &Inst);
1618 bool validateMIMGDim(const MCInst &Inst);
1619 bool validateMIMGMSAA(const MCInst &Inst);
1620 bool validateOpSel(const MCInst &Inst);
1621 bool validateDPP(const MCInst &Inst, const OperandVector &Operands);
1622 bool validateVccOperand(unsigned Reg) const;
1623 bool validateVOPLiteral(const MCInst &Inst, const OperandVector &Operands);
1624 bool validateMAIAccWrite(const MCInst &Inst, const OperandVector &Operands);
1625 bool validateMFMA(const MCInst &Inst, const OperandVector &Operands);
1626 bool validateAGPRLdSt(const MCInst &Inst) const;
1627 bool validateVGPRAlign(const MCInst &Inst) const;
1628 bool validateBLGP(const MCInst &Inst, const OperandVector &Operands);
1629 bool validateGWS(const MCInst &Inst, const OperandVector &Operands);
1630 bool validateDivScale(const MCInst &Inst);
1631 bool validateCoherencyBits(const MCInst &Inst, const OperandVector &Operands,
1632 const SMLoc &IDLoc);
1633 bool validateFlatLdsDMA(const MCInst &Inst, const OperandVector &Operands,
1634 const SMLoc &IDLoc);
1635 Optional<StringRef> validateLdsDirect(const MCInst &Inst);
1636 unsigned getConstantBusLimit(unsigned Opcode) const;
1637 bool usesConstantBus(const MCInst &Inst, unsigned OpIdx);
1638 bool isInlineConstant(const MCInst &Inst, unsigned OpIdx) const;
1639 unsigned findImplicitSGPRReadInVOP(const MCInst &Inst) const;
1641 bool isSupportedMnemo(StringRef Mnemo,
1642 const FeatureBitset &FBS);
1643 bool isSupportedMnemo(StringRef Mnemo,
1644 const FeatureBitset &FBS,
1645 ArrayRef<unsigned> Variants);
1646 bool checkUnsupportedInstruction(StringRef Name, const SMLoc &IDLoc);
1648 bool isId(const StringRef Id) const;
1649 bool isId(const AsmToken &Token, const StringRef Id) const;
1650 bool isToken(const AsmToken::TokenKind Kind) const;
1651 bool trySkipId(const StringRef Id);
1652 bool trySkipId(const StringRef Pref, const StringRef Id);
1653 bool trySkipId(const StringRef Id, const AsmToken::TokenKind Kind);
1654 bool trySkipToken(const AsmToken::TokenKind Kind);
1655 bool skipToken(const AsmToken::TokenKind Kind, const StringRef ErrMsg);
1656 bool parseString(StringRef &Val, const StringRef ErrMsg = "expected a string");
1657 bool parseId(StringRef &Val, const StringRef ErrMsg = "");
1659 void peekTokens(MutableArrayRef<AsmToken> Tokens);
1660 AsmToken::TokenKind getTokenKind() const;
1661 bool parseExpr(int64_t &Imm, StringRef Expected = "");
1662 bool parseExpr(OperandVector &Operands);
1663 StringRef getTokenStr() const;
1664 AsmToken peekToken();
1665 AsmToken getToken() const;
1666 SMLoc getLoc() const;
1670 void onBeginOfFile() override;
1672 OperandMatchResultTy parseOptionalOperand(OperandVector &Operands);
1673 OperandMatchResultTy parseOptionalOpr(OperandVector &Operands);
1675 OperandMatchResultTy parseExpTgt(OperandVector &Operands);
1676 OperandMatchResultTy parseSendMsgOp(OperandVector &Operands);
1677 OperandMatchResultTy parseInterpSlot(OperandVector &Operands);
1678 OperandMatchResultTy parseInterpAttr(OperandVector &Operands);
1679 OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands);
1680 OperandMatchResultTy parseBoolReg(OperandVector &Operands);
1682 bool parseSwizzleOperand(int64_t &Op,
1683 const unsigned MinVal,
1684 const unsigned MaxVal,
1685 const StringRef ErrMsg,
1687 bool parseSwizzleOperands(const unsigned OpNum, int64_t* Op,
1688 const unsigned MinVal,
1689 const unsigned MaxVal,
1690 const StringRef ErrMsg);
1691 OperandMatchResultTy parseSwizzleOp(OperandVector &Operands);
1692 bool parseSwizzleOffset(int64_t &Imm);
1693 bool parseSwizzleMacro(int64_t &Imm);
1694 bool parseSwizzleQuadPerm(int64_t &Imm);
1695 bool parseSwizzleBitmaskPerm(int64_t &Imm);
1696 bool parseSwizzleBroadcast(int64_t &Imm);
1697 bool parseSwizzleSwap(int64_t &Imm);
1698 bool parseSwizzleReverse(int64_t &Imm);
1700 OperandMatchResultTy parseGPRIdxMode(OperandVector &Operands);
1701 int64_t parseGPRIdxMacro();
1703 void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false); }
1704 void cvtMubufAtomic(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true); }
1705 void cvtMubufLds(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, true); }
1706 void cvtMtbuf(MCInst &Inst, const OperandVector &Operands);
1708 AMDGPUOperand::Ptr defaultCPol() const;
1710 AMDGPUOperand::Ptr defaultSMRDOffset8() const;
1711 AMDGPUOperand::Ptr defaultSMEMOffset() const;
1712 AMDGPUOperand::Ptr defaultSMRDLiteralOffset() const;
1713 AMDGPUOperand::Ptr defaultFlatOffset() const;
1715 OperandMatchResultTy parseOModOperand(OperandVector &Operands);
1717 void cvtVOP3(MCInst &Inst, const OperandVector &Operands,
1718 OptionalImmIndexMap &OptionalIdx);
1719 void cvtVOP3OpSel(MCInst &Inst, const OperandVector &Operands);
1720 void cvtVOP3(MCInst &Inst, const OperandVector &Operands);
1721 void cvtVOP3P(MCInst &Inst, const OperandVector &Operands);
1722 void cvtVOP3P(MCInst &Inst, const OperandVector &Operands,
1723 OptionalImmIndexMap &OptionalIdx);
1725 void cvtVOP3Interp(MCInst &Inst, const OperandVector &Operands);
1726 void cvtVINTERP(MCInst &Inst, const OperandVector &Operands);
1728 void cvtMIMG(MCInst &Inst, const OperandVector &Operands,
1729 bool IsAtomic = false);
1730 void cvtMIMGAtomic(MCInst &Inst, const OperandVector &Operands);
1731 void cvtIntersectRay(MCInst &Inst, const OperandVector &Operands);
1733 void cvtSMEMAtomic(MCInst &Inst, const OperandVector &Operands);
1735 bool parseDimId(unsigned &Encoding);
1736 OperandMatchResultTy parseDim(OperandVector &Operands);
1737 OperandMatchResultTy parseDPP8(OperandVector &Operands);
1738 OperandMatchResultTy parseDPPCtrl(OperandVector &Operands);
1739 bool isSupportedDPPCtrl(StringRef Ctrl, const OperandVector &Operands);
1740 int64_t parseDPPCtrlSel(StringRef Ctrl);
1741 int64_t parseDPPCtrlPerm();
1742 AMDGPUOperand::Ptr defaultRowMask() const;
1743 AMDGPUOperand::Ptr defaultBankMask() const;
1744 AMDGPUOperand::Ptr defaultBoundCtrl() const;
1745 AMDGPUOperand::Ptr defaultFI() const;
1746 void cvtDPP(MCInst &Inst, const OperandVector &Operands, bool IsDPP8 = false);
1747 void cvtDPP8(MCInst &Inst, const OperandVector &Operands) { cvtDPP(Inst, Operands, true); }
1749 OperandMatchResultTy parseSDWASel(OperandVector &Operands, StringRef Prefix,
1750 AMDGPUOperand::ImmTy Type);
1751 OperandMatchResultTy parseSDWADstUnused(OperandVector &Operands);
1752 void cvtSdwaVOP1(MCInst &Inst, const OperandVector &Operands);
1753 void cvtSdwaVOP2(MCInst &Inst, const OperandVector &Operands);
1754 void cvtSdwaVOP2b(MCInst &Inst, const OperandVector &Operands);
1755 void cvtSdwaVOP2e(MCInst &Inst, const OperandVector &Operands);
1756 void cvtSdwaVOPC(MCInst &Inst, const OperandVector &Operands);
1757 void cvtSDWA(MCInst &Inst, const OperandVector &Operands,
1758 uint64_t BasicInstType,
1759 bool SkipDstVcc = false,
1760 bool SkipSrcVcc = false);
1762 AMDGPUOperand::Ptr defaultBLGP() const;
1763 AMDGPUOperand::Ptr defaultCBSZ() const;
1764 AMDGPUOperand::Ptr defaultABID() const;
1766 OperandMatchResultTy parseEndpgmOp(OperandVector &Operands);
1767 AMDGPUOperand::Ptr defaultEndpgmImmOperands() const;
1769 AMDGPUOperand::Ptr defaultWaitVDST() const;
1770 AMDGPUOperand::Ptr defaultWaitEXP() const;
1773 struct OptionalOperand {
1775 AMDGPUOperand::ImmTy Type;
1777 bool (*ConvertResult)(int64_t&);
1780 } // end anonymous namespace
1782 // May be called with integer type with equivalent bitwidth.
1783 static const fltSemantics *getFltSemantics(unsigned Size) {
1786 return &APFloat::IEEEsingle();
1788 return &APFloat::IEEEdouble();
1790 return &APFloat::IEEEhalf();
1792 llvm_unreachable("unsupported fp type");
1796 static const fltSemantics *getFltSemantics(MVT VT) {
1797 return getFltSemantics(VT.getSizeInBits() / 8);
1800 static const fltSemantics *getOpFltSemantics(uint8_t OperandType) {
1801 switch (OperandType) {
1802 case AMDGPU::OPERAND_REG_IMM_INT32:
1803 case AMDGPU::OPERAND_REG_IMM_FP32:
1804 case AMDGPU::OPERAND_REG_IMM_FP32_DEFERRED:
1805 case AMDGPU::OPERAND_REG_INLINE_C_INT32:
1806 case AMDGPU::OPERAND_REG_INLINE_C_FP32:
1807 case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
1808 case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
1809 case AMDGPU::OPERAND_REG_INLINE_C_V2FP32:
1810 case AMDGPU::OPERAND_REG_IMM_V2FP32:
1811 case AMDGPU::OPERAND_REG_INLINE_C_V2INT32:
1812 case AMDGPU::OPERAND_REG_IMM_V2INT32:
1813 case AMDGPU::OPERAND_KIMM32:
1814 return &APFloat::IEEEsingle();
1815 case AMDGPU::OPERAND_REG_IMM_INT64:
1816 case AMDGPU::OPERAND_REG_IMM_FP64:
1817 case AMDGPU::OPERAND_REG_INLINE_C_INT64:
1818 case AMDGPU::OPERAND_REG_INLINE_C_FP64:
1819 case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
1820 return &APFloat::IEEEdouble();
1821 case AMDGPU::OPERAND_REG_IMM_INT16:
1822 case AMDGPU::OPERAND_REG_IMM_FP16:
1823 case AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED:
1824 case AMDGPU::OPERAND_REG_INLINE_C_INT16:
1825 case AMDGPU::OPERAND_REG_INLINE_C_FP16:
1826 case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
1827 case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
1828 case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
1829 case AMDGPU::OPERAND_REG_INLINE_AC_FP16:
1830 case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
1831 case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
1832 case AMDGPU::OPERAND_REG_IMM_V2INT16:
1833 case AMDGPU::OPERAND_REG_IMM_V2FP16:
1834 case AMDGPU::OPERAND_KIMM16:
1835 return &APFloat::IEEEhalf();
1837 llvm_unreachable("unsupported fp type");
1841 //===----------------------------------------------------------------------===//
1843 //===----------------------------------------------------------------------===//
1845 static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT) {
1848 // Convert literal to single precision
1849 APFloat::opStatus Status = FPLiteral.convert(*getFltSemantics(VT),
1850 APFloat::rmNearestTiesToEven,
1852 // We allow precision lost but not overflow or underflow
1853 if (Status != APFloat::opOK &&
1855 ((Status & APFloat::opOverflow) != 0 ||
1856 (Status & APFloat::opUnderflow) != 0)) {
1863 static bool isSafeTruncation(int64_t Val, unsigned Size) {
1864 return isUIntN(Size, Val) || isIntN(Size, Val);
1867 static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi) {
1868 if (VT.getScalarType() == MVT::i16) {
1869 // FP immediate values are broken.
1870 return isInlinableIntLiteral(Val);
1873 // f16/v2f16 operands work correctly for all values.
1874 return AMDGPU::isInlinableLiteral16(Val, HasInv2Pi);
1877 bool AMDGPUOperand::isInlinableImm(MVT type) const {
1879 // This is a hack to enable named inline values like
1880 // shared_base with both 32-bit and 64-bit operands.
1881 // Note that these values are defined as
1882 // 32-bit operands only.
1883 if (isInlineValue()) {
1887 if (!isImmTy(ImmTyNone)) {
1888 // Only plain immediates are inlinable (e.g. "clamp" attribute is not)
1891 // TODO: We should avoid using host float here. It would be better to
1892 // check the float bit values which is what a few other places do.
1893 // We've had bot failures before due
to weird NaN
support on mips hosts.
1900 AsmParser->hasInv2PiInlineImm());
1907 if (
type.getScalarSizeInBits() == 16) {
1909 static_cast<int16_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
1910 type, AsmParser->hasInv2PiInlineImm());
1915 static_cast<int32_t
>(FPLiteral.bitcastToAPInt().getZExtValue()),
1916 AsmParser->hasInv2PiInlineImm());
1922 AsmParser->hasInv2PiInlineImm());
1929 if (
type.getScalarSizeInBits() == 16) {
1931 static_cast<int16_t
>(
Literal.getLoBits(16).getSExtValue()),
1932 type, AsmParser->hasInv2PiInlineImm());
1936 static_cast<int32_t
>(
Literal.getLoBits(32).getZExtValue()),
1937 AsmParser->hasInv2PiInlineImm());
1940 bool AMDGPUOperand::isLiteralImm(
MVT type)
const {
1942 if (!isImmTy(ImmTyNone)) {
1956 unsigned Size =
type.getSizeInBits();
1988 bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
1989 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
1992 bool AMDGPUOperand::isVRegWithInputMods()
const {
1993 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
1995 (isRegClass(AMDGPU::VReg_64RegClassID) &&
1996 AsmParser->getFeatureBits()[AMDGPU::Feature64BitDPP]);
1999 bool AMDGPUOperand::isSDWAOperand(
MVT type)
const {
2000 if (AsmParser->isVI())
2002 else if (AsmParser->isGFX9Plus())
2003 return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(
type);
2008 bool AMDGPUOperand::isSDWAFP16Operand()
const {
2012 bool AMDGPUOperand::isSDWAFP32Operand()
const {
2016 bool AMDGPUOperand::isSDWAInt16Operand()
const {
2020 bool AMDGPUOperand::isSDWAInt32Operand()
const {
2024 bool AMDGPUOperand::isBoolReg()
const {
2025 auto FB = AsmParser->getFeatureBits();
2026 return isReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrcB64()) ||
2027 (FB[AMDGPU::FeatureWavefrontSize32] && isSCSrcB32()));
2030 uint64_t AMDGPUOperand::applyInputFPModifiers(
uint64_t Val,
unsigned Size)
const
2032 assert(isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2033 assert(Size == 2 || Size == 4 || Size == 8);
2047 void AMDGPUOperand::addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
2050 addLiteralImmOperand(Inst,
Imm.Val,
2052 isImmTy(ImmTyNone) &&
Imm.Mods.hasFPModifiers());
2054 assert(!isImmTy(ImmTyNone) || !hasModifiers());
2060 void AMDGPUOperand::addLiteralImmOperand(
MCInst &Inst, int64_t Val,
bool ApplyModifiers)
const {
2061 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
2066 if (ApplyModifiers) {
2069 Val = applyInputFPModifiers(Val, Size);
2073 uint8_t OpTy = InstDesc.OpInfo[OpNum].OperandType;
2083 AsmParser->hasInv2PiInlineImm())) {
2092 if (
Literal.getLoBits(32) != 0) {
2093 const_cast<AMDGPUAsmParser *
>(AsmParser)->
Warning(Inst.
getLoc(),
2094 "Can't encode literal as exact 64-bit floating-point operand. "
2095 "Low 32-bits will be set to zero");
2099 setImmKindLiteral();
2142 uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2144 setImmKindLiteral();
2172 AsmParser->hasInv2PiInlineImm())) {
2179 setImmKindLiteral();
2194 setImmKindLiteral();
2206 AsmParser->hasInv2PiInlineImm())) {
2213 setImmKindLiteral();
2222 AsmParser->hasInv2PiInlineImm()));
2240 template <
unsigned Bitw
idth>
2241 void AMDGPUOperand::addKImmFPOperands(
MCInst &Inst,
unsigned N)
const {
2258 void AMDGPUOperand::addRegOperands(
MCInst &Inst,
unsigned N)
const {
2264 case AMDGPU::SRC_SHARED_BASE:
2265 case AMDGPU::SRC_SHARED_LIMIT:
2266 case AMDGPU::SRC_PRIVATE_BASE:
2267 case AMDGPU::SRC_PRIVATE_LIMIT:
2268 case AMDGPU::SRC_POPS_EXITING_WAVE_ID:
2270 case AMDGPU::SRC_VCCZ:
2271 case AMDGPU::SRC_EXECZ:
2272 case AMDGPU::SRC_SCC:
2274 case AMDGPU::SGPR_NULL:
2294 return AMDGPU::VGPR_32RegClassID;
2296 return AMDGPU::VReg_64RegClassID;
2298 return AMDGPU::VReg_96RegClassID;
2300 return AMDGPU::VReg_128RegClassID;
2302 return AMDGPU::VReg_160RegClassID;
2304 return AMDGPU::VReg_192RegClassID;
2306 return AMDGPU::VReg_224RegClassID;
2308 return AMDGPU::VReg_256RegClassID;
2310 return AMDGPU::VReg_512RegClassID;
2312 return AMDGPU::VReg_1024RegClassID;
2314 }
else if (Is == IS_TTMP) {
2318 return AMDGPU::TTMP_32RegClassID;
2320 return AMDGPU::TTMP_64RegClassID;
2322 return AMDGPU::TTMP_128RegClassID;
2324 return AMDGPU::TTMP_256RegClassID;
2326 return AMDGPU::TTMP_512RegClassID;
2328 }
else if (Is == IS_SGPR) {
2332 return AMDGPU::SGPR_32RegClassID;
2334 return AMDGPU::SGPR_64RegClassID;
2336 return AMDGPU::SGPR_96RegClassID;
2338 return AMDGPU::SGPR_128RegClassID;
2340 return AMDGPU::SGPR_160RegClassID;
2342 return AMDGPU::SGPR_192RegClassID;
2344 return AMDGPU::SGPR_224RegClassID;
2346 return AMDGPU::SGPR_256RegClassID;
2348 return AMDGPU::SGPR_512RegClassID;
2350 }
else if (Is == IS_AGPR) {
2354 return AMDGPU::AGPR_32RegClassID;
2356 return AMDGPU::AReg_64RegClassID;
2358 return AMDGPU::AReg_96RegClassID;
2360 return AMDGPU::AReg_128RegClassID;
2362 return AMDGPU::AReg_160RegClassID;
2364 return AMDGPU::AReg_192RegClassID;
2366 return AMDGPU::AReg_224RegClassID;
2368 return AMDGPU::AReg_256RegClassID;
2370 return AMDGPU::AReg_512RegClassID;
2372 return AMDGPU::AReg_1024RegClassID;
2380 .
Case(
"exec", AMDGPU::EXEC)
2381 .
Case(
"vcc", AMDGPU::VCC)
2382 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
2383 .
Case(
"xnack_mask", AMDGPU::XNACK_MASK)
2384 .
Case(
"shared_base", AMDGPU::SRC_SHARED_BASE)
2385 .
Case(
"src_shared_base", AMDGPU::SRC_SHARED_BASE)
2386 .
Case(
"shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2387 .
Case(
"src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2388 .
Case(
"private_base", AMDGPU::SRC_PRIVATE_BASE)
2389 .
Case(
"src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2390 .
Case(
"private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2391 .
Case(
"src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2392 .
Case(
"pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2393 .
Case(
"src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2394 .
Case(
"lds_direct", AMDGPU::LDS_DIRECT)
2395 .
Case(
"src_lds_direct", AMDGPU::LDS_DIRECT)
2397 .
Case(
"vccz", AMDGPU::SRC_VCCZ)
2398 .
Case(
"src_vccz", AMDGPU::SRC_VCCZ)
2399 .
Case(
"execz", AMDGPU::SRC_EXECZ)
2400 .
Case(
"src_execz", AMDGPU::SRC_EXECZ)
2401 .
Case(
"scc", AMDGPU::SRC_SCC)
2402 .
Case(
"src_scc", AMDGPU::SRC_SCC)
2403 .
Case(
"tba", AMDGPU::TBA)
2404 .
Case(
"tma", AMDGPU::TMA)
2405 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2406 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2407 .
Case(
"xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2408 .
Case(
"xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2409 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
2410 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
2411 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
2412 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
2413 .
Case(
"tma_lo", AMDGPU::TMA_LO)
2414 .
Case(
"tma_hi", AMDGPU::TMA_HI)
2415 .
Case(
"tba_lo", AMDGPU::TBA_LO)
2416 .
Case(
"tba_hi", AMDGPU::TBA_HI)
2417 .
Case(
"pc", AMDGPU::PC_REG)
2418 .
Case(
"null", AMDGPU::SGPR_NULL)
2422 bool AMDGPUAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
2423 SMLoc &EndLoc,
bool RestoreOnFailure) {
2424 auto R = parseRegister();
2425 if (!R)
return true;
2427 RegNo =
R->getReg();
2428 StartLoc =
R->getStartLoc();
2429 EndLoc =
R->getEndLoc();
2433 bool AMDGPUAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
2435 return ParseRegister(RegNo, StartLoc, EndLoc,
false);
2442 ParseRegister(RegNo, StartLoc, EndLoc,
true);
2443 bool PendingErrors = getParser().hasPendingError();
2444 getParser().clearPendingErrors();
2452 bool AMDGPUAsmParser::AddNextRegisterToList(
unsigned &
Reg,
unsigned &RegWidth,
2453 RegisterKind RegKind,
unsigned Reg1,
2457 if (
Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2462 if (
Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2463 Reg = AMDGPU::FLAT_SCR;
2467 if (
Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2468 Reg = AMDGPU::XNACK_MASK;
2472 if (
Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2477 if (
Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2482 if (
Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2487 Error(Loc,
"register does not fit in the list");
2493 if (Reg1 !=
Reg + RegWidth / 32) {
2494 Error(Loc,
"registers in a list must have consecutive indices");
2512 {{
"ttmp"}, IS_TTMP},
2526 if (Str.startswith(
Reg.Name))
2532 return !Str.getAsInteger(10, Num);
2536 AMDGPUAsmParser::isRegister(
const AsmToken &Token,
2553 if (!RegSuffix.
empty()) {
2569 AMDGPUAsmParser::isRegister()
2571 return isRegister(getToken(), peekToken());
2575 AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,
2582 unsigned AlignSize = 1;
2583 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2586 AlignSize =
std::min(RegWidth / 32, 4u);
2589 if (RegNum % AlignSize != 0) {
2590 Error(Loc,
"invalid register alignment");
2591 return AMDGPU::NoRegister;
2594 unsigned RegIdx = RegNum / AlignSize;
2597 Error(Loc,
"invalid or unsupported register size");
2598 return AMDGPU::NoRegister;
2604 Error(Loc,
"register index is out of range");
2605 return AMDGPU::NoRegister;
2611 bool AMDGPUAsmParser::ParseRegRange(
unsigned &Num,
unsigned &RegWidth) {
2612 int64_t RegLo, RegHi;
2616 SMLoc FirstIdxLoc = getLoc();
2619 if (!parseExpr(RegLo))
2623 SecondIdxLoc = getLoc();
2624 if (!parseExpr(RegHi))
2634 Error(FirstIdxLoc,
"invalid register index");
2639 Error(SecondIdxLoc,
"invalid register index");
2643 if (RegLo > RegHi) {
2644 Error(FirstIdxLoc,
"first register index should not exceed second index");
2648 Num =
static_cast<unsigned>(RegLo);
2649 RegWidth = 32 * ((RegHi - RegLo) + 1);
2653 unsigned AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2654 unsigned &RegNum,
unsigned &RegWidth,
2661 RegKind = IS_SPECIAL;
2662 Tokens.push_back(getToken());
2668 unsigned AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2669 unsigned &RegNum,
unsigned &RegWidth,
2673 auto Loc = getLoc();
2677 Error(Loc,
"invalid register name");
2678 return AMDGPU::NoRegister;
2681 Tokens.push_back(getToken());
2686 if (!RegSuffix.
empty()) {
2689 Error(Loc,
"invalid register index");
2690 return AMDGPU::NoRegister;
2695 if (!ParseRegRange(RegNum, RegWidth))
2696 return AMDGPU::NoRegister;
2699 return getRegularReg(RegKind, RegNum, RegWidth, Loc);
2702 unsigned AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
unsigned &RegNum,
2705 unsigned Reg = AMDGPU::NoRegister;
2706 auto ListLoc = getLoc();
2709 "expected a register or a list of registers")) {
2710 return AMDGPU::NoRegister;
2715 auto Loc = getLoc();
2716 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth))
2717 return AMDGPU::NoRegister;
2718 if (RegWidth != 32) {
2719 Error(Loc,
"expected a single 32-bit register");
2720 return AMDGPU::NoRegister;
2724 RegisterKind NextRegKind;
2725 unsigned NextReg, NextRegNum, NextRegWidth;
2728 if (!ParseAMDGPURegister(NextRegKind, NextReg,
2729 NextRegNum, NextRegWidth,
2731 return AMDGPU::NoRegister;
2733 if (NextRegWidth != 32) {
2734 Error(Loc,
"expected a single 32-bit register");
2735 return AMDGPU::NoRegister;
2737 if (NextRegKind != RegKind) {
2738 Error(Loc,
"registers in a list must be of the same kind");
2739 return AMDGPU::NoRegister;
2741 if (!AddNextRegisterToList(
Reg, RegWidth, RegKind, NextReg, Loc))
2742 return AMDGPU::NoRegister;
2746 "expected a comma or a closing square bracket")) {
2747 return AMDGPU::NoRegister;
2751 Reg = getRegularReg(RegKind, RegNum, RegWidth, ListLoc);
2756 bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &
Reg,
2757 unsigned &RegNum,
unsigned &RegWidth,
2759 auto Loc = getLoc();
2760 Reg = AMDGPU::NoRegister;
2763 Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
2764 if (
Reg == AMDGPU::NoRegister)
2765 Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
2767 Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
2771 if (
Reg == AMDGPU::NoRegister) {
2772 assert(Parser.hasPendingError());
2776 if (!subtargetHasRegister(*
TRI,
Reg)) {
2777 if (
Reg == AMDGPU::SGPR_NULL) {
2778 Error(Loc,
"'null' operand is not supported on this GPU");
2780 Error(Loc,
"register not available on this GPU");
2788 bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
unsigned &
Reg,
2789 unsigned &RegNum,
unsigned &RegWidth,
2790 bool RestoreOnFailure ) {
2791 Reg = AMDGPU::NoRegister;
2794 if (ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth, Tokens)) {
2795 if (RestoreOnFailure) {
2796 while (!Tokens.empty()) {
2806 AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
2809 return StringRef(
".amdgcn.next_free_vgpr");
2811 return StringRef(
".amdgcn.next_free_sgpr");
2817 void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
2818 auto SymbolName = getGprCountSymbolName(RegKind);
2824 bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
2825 unsigned DwordRegIndex,
2826 unsigned RegWidth) {
2831 auto SymbolName = getGprCountSymbolName(RegKind);
2836 int64_t NewMax = DwordRegIndex +
divideCeil(RegWidth, 32) - 1;
2840 return !
Error(getLoc(),
2841 ".amdgcn.next_free_{v,s}gpr symbols must be variable");
2845 ".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
2847 if (OldCount <= NewMax)
2853 std::unique_ptr<AMDGPUOperand>
2854 AMDGPUAsmParser::parseRegister(
bool RestoreOnFailure) {
2855 const auto &Tok = getToken();
2856 SMLoc StartLoc = Tok.getLoc();
2857 SMLoc EndLoc = Tok.getEndLoc();
2858 RegisterKind RegKind;
2859 unsigned Reg, RegNum, RegWidth;
2861 if (!ParseAMDGPURegister(RegKind,
Reg, RegNum, RegWidth)) {
2865 if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
2868 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
2869 return AMDGPUOperand::CreateReg(
this,
Reg, StartLoc, EndLoc);
2879 const auto& Tok = getToken();
2880 const auto& NextTok = peekToken();
2883 bool Negate =
false;
2901 if (
errorToBool(RealVal.convertFromString(Num, roundMode).takeError())) {
2905 RealVal.changeSign();
2908 AMDGPUOperand::CreateImm(
this, RealVal.bitcastToAPInt().getZExtValue(),
S,
2909 AMDGPUOperand::ImmTyNone,
true));
2918 if (HasSP3AbsModifier) {
2927 if (getParser().parsePrimaryExpr(Expr, EndLoc,
nullptr))
2930 if (Parser.parseExpression(Expr))
2934 if (Expr->evaluateAsAbsolute(
IntVal)) {
2937 Operands.push_back(AMDGPUOperand::CreateExpr(
this, Expr,
S));
2951 if (
auto R = parseRegister()) {
2964 }
else if (isModifier()) {
2967 return parseImm(
Operands, HasSP3AbsMod);
2972 AMDGPUAsmParser::isNamedOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
2975 return str ==
"abs" || str ==
"neg" || str ==
"sext";
2981 AMDGPUAsmParser::isOpcodeModifierWithVal(
const AsmToken &Token,
const AsmToken &NextToken)
const {
2986 AMDGPUAsmParser::isOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
2987 return isNamedOperandModifier(Token, NextToken) || Token.
is(
AsmToken::Pipe);
2991 AMDGPUAsmParser::isRegOrOperandModifier(
const AsmToken &Token,
const AsmToken &NextToken)
const {
2992 return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3011 AMDGPUAsmParser::isModifier() {
3015 peekTokens(NextToken);
3017 return isOperandModifier(Tok, NextToken[0]) ||
3018 (Tok.
is(
AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3019 isOpcodeModifierWithVal(Tok, NextToken[0]);
3045 AMDGPUAsmParser::parseSP3NegModifier() {
3048 peekTokens(NextToken);
3051 (isRegister(NextToken[0], NextToken[1]) ||
3053 isId(NextToken[0],
"abs"))) {
3070 Error(getLoc(),
"invalid syntax, expected 'neg' modifier");
3074 SP3Neg = parseSP3NegModifier();
3077 Neg = trySkipId(
"neg");
3078 if (Neg && SP3Neg) {
3079 Error(Loc,
"expected register or immediate");
3085 Abs = trySkipId(
"abs");
3091 if (Abs && SP3Abs) {
3092 Error(Loc,
"expected register or immediate");
3098 Res = parseRegOrImm(
Operands, SP3Abs);
3106 if (SP3Abs && !skipToken(
AsmToken::Pipe,
"expected vertical bar"))
3113 AMDGPUOperand::Modifiers Mods;
3114 Mods.Abs = Abs || SP3Abs;
3115 Mods.Neg = Neg || SP3Neg;
3117 if (Mods.hasFPModifiers()) {
3118 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3120 Error(
Op.getStartLoc(),
"expected an absolute expression");
3123 Op.setModifiers(Mods);
3131 bool Sext = trySkipId(
"sext");
3132 if (Sext && !skipToken(
AsmToken::LParen,
"expected left paren after sext"))
3148 AMDGPUOperand::Modifiers Mods;
3151 if (Mods.hasIntModifiers()) {
3152 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*
Operands.back());
3154 Error(
Op.getStartLoc(),
"expected an absolute expression");
3157 Op.setModifiers(Mods);
3165 return parseRegOrImmWithFPInputMods(
Operands,
false);
3170 return parseRegOrImmWithIntInputMods(
Operands,
false);
3174 auto Loc = getLoc();
3175 if (trySkipId(
"off")) {
3176 Operands.push_back(AMDGPUOperand::CreateImm(
this, 0, Loc,
3177 AMDGPUOperand::ImmTyOff,
false));
3184 std::unique_ptr<AMDGPUOperand>
Reg = parseRegister();
3194 unsigned AMDGPUAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
3201 return Match_InvalidOperand;
3205 getForcedEncodingSize() != 64)
3206 return Match_PreferE32;
3208 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3209 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3215 return Match_InvalidOperand;
3219 return Match_Success;
3223 static const unsigned Variants[] = {
3233 if (getForcedEncodingSize() == 32) {
3238 if (isForcedVOP3()) {
3243 if (isForcedSDWA()) {
3249 if (isForcedDPP()) {
3257 StringRef AMDGPUAsmParser::getMatchedVariantName()
const {
3258 if (getForcedEncodingSize() == 32)
3273 unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(
const MCInst &Inst)
const {
3276 for (
unsigned i = 0;
i < Num; ++
i) {
3279 case AMDGPU::FLAT_SCR:
3281 case AMDGPU::VCC_LO:
3282 case AMDGPU::VCC_HI:
3289 return AMDGPU::NoRegister;
3296 bool AMDGPUAsmParser::isInlineConstant(
const MCInst &Inst,
3297 unsigned OpIdx)
const {
3306 int64_t Val = MO.
getImm();
3338 unsigned AMDGPUAsmParser::getConstantBusLimit(
unsigned Opcode)
const {
3344 case AMDGPU::V_LSHLREV_B64_e64:
3345 case AMDGPU::V_LSHLREV_B64_gfx10:
3346 case AMDGPU::V_LSHRREV_B64_e64:
3347 case AMDGPU::V_LSHRREV_B64_gfx10:
3348 case AMDGPU::V_ASHRREV_I64_e64:
3349 case AMDGPU::V_ASHRREV_I64_gfx10:
3350 case AMDGPU::V_LSHL_B64_e64:
3351 case AMDGPU::V_LSHR_B64_e64:
3352 case AMDGPU::V_ASHR_I64_e64:
3359 bool AMDGPUAsmParser::usesConstantBus(
const MCInst &Inst,
unsigned OpIdx) {
3362 return !isInlineConstant(Inst, OpIdx);
3363 }
else if (MO.
isReg()) {
3367 return isSGPR(PReg,
TRI) && PReg != SGPR_NULL;
3374 AMDGPUAsmParser::validateConstantBusLimitations(
const MCInst &Inst,
3376 const unsigned Opcode = Inst.
getOpcode();
3378 unsigned LastSGPR = AMDGPU::NoRegister;
3379 unsigned ConstantBusUseCount = 0;
3380 unsigned NumLiterals = 0;
3381 unsigned LiteralSize;
3395 unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3396 if (SGPRUsed != AMDGPU::NoRegister) {
3397 SGPRsUsed.
insert(SGPRUsed);
3398 ++ConstantBusUseCount;
3405 const int OpIndices[] = { Src0Idx, Src1Idx, Src2Idx };
3407 for (
int OpIdx : OpIndices) {
3408 if (OpIdx == -1)
break;
3411 if (usesConstantBus(Inst, OpIdx)) {
3420 if (!SGPRsUsed.
count(LastSGPR)) {
3421 SGPRsUsed.
insert(LastSGPR);
3422 ++ConstantBusUseCount;
3439 if (Size < 4)
Size = 4;
3441 if (NumLiterals == 0) {
3444 }
else if (LiteralSize != Size) {
3451 ConstantBusUseCount += NumLiterals;
3453 if (ConstantBusUseCount <= getConstantBusLimit(Opcode))
3459 Error(Loc,
"invalid operand (violates constant bus restrictions)");
3464 AMDGPUAsmParser::validateEarlyClobberLimitations(
const MCInst &Inst,
3466 const unsigned Opcode = Inst.
getOpcode();
3485 const int SrcIndices[] = { Src0Idx, Src1Idx, Src2Idx };
3487 for (
int SrcIdx : SrcIndices) {
3488 if (SrcIdx == -1)
break;
3494 "destination must be different than all sources");
3503 bool AMDGPUAsmParser::validateIntClampSupported(
const MCInst &Inst) {
3531 if (DMaskIdx == -1 || TFEIdx == -1)
3535 unsigned TFESize = (TFEIdx != -1 && Inst.
getOperand(TFEIdx).
getImm()) ? 1 : 0;
3540 bool isPackedD16 =
false;
3545 isPackedD16 = D16Idx >= 0;
3547 DataSize = (DataSize + 1) / 2;
3550 if ((VDataSize / 4) == DataSize + TFESize)
3554 ?
"image data size does not match dmask, d16 and tfe"
3555 :
"image data size does not match dmask and tfe");
3558 bool AMDGPUAsmParser::validateMIMGAddrSize(
const MCInst &Inst) {
3567 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
3576 assert(SrsrcIdx > VAddr0Idx);
3583 bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
3584 unsigned ActualAddrSize =
3585 IsNSA ? SrsrcIdx - VAddr0Idx
3589 unsigned ExpectedAddrSize =
3593 if (ExpectedAddrSize > 8)
3594 ExpectedAddrSize = 16;
3599 if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
3603 return ActualAddrSize == ExpectedAddrSize;
3606 bool AMDGPUAsmParser::validateMIMGAtomicDMask(
const MCInst &Inst) {
3623 return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
3626 bool AMDGPUAsmParser::validateMIMGGatherDMask(
const MCInst &Inst) {
3642 return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
3645 bool AMDGPUAsmParser::validateMIMGMSAA(
const MCInst &Inst) {
3653 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
3656 if (!BaseOpcode->MSAA)
3665 return DimInfo->MSAA;
3671 case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
3672 case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
3673 case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
3683 bool AMDGPUAsmParser::validateMovrels(
const MCInst &Inst,
3707 Error(ErrLoc,
"source operand must be a VGPR");
3711 bool AMDGPUAsmParser::validateMAIAccWrite(
const MCInst &Inst,
3716 if (Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
3730 "source operand must be either a VGPR or an inline constant");
3737 bool AMDGPUAsmParser::validateMFMA(
const MCInst &Inst,
3755 if (Src2Reg == DstReg)
3764 "source 2 operand must not partially overlap with dst");
3771 bool AMDGPUAsmParser::validateDivScale(
const MCInst &Inst) {
3775 case V_DIV_SCALE_F32_gfx6_gfx7:
3776 case V_DIV_SCALE_F32_vi:
3777 case V_DIV_SCALE_F32_gfx10:
3778 case V_DIV_SCALE_F64_gfx6_gfx7:
3779 case V_DIV_SCALE_F64_vi:
3780 case V_DIV_SCALE_F64_gfx10:
3786 for (
auto Name : {AMDGPU::OpName::src0_modifiers,
3787 AMDGPU::OpName::src2_modifiers,
3788 AMDGPU::OpName::src2_modifiers}) {
3799 bool AMDGPUAsmParser::validateMIMGD16(
const MCInst &Inst) {
3816 bool AMDGPUAsmParser::validateMIMGDim(
const MCInst &Inst) {
3828 if (Imm < 0 || Imm >= 8)
3837 case AMDGPU::V_SUBREV_F32_e32:
3838 case AMDGPU::V_SUBREV_F32_e64:
3839 case AMDGPU::V_SUBREV_F32_e32_gfx10:
3840 case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
3841 case AMDGPU::V_SUBREV_F32_e32_vi:
3842 case AMDGPU::V_SUBREV_F32_e64_gfx10:
3843 case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
3844 case AMDGPU::V_SUBREV_F32_e64_vi:
3846 case AMDGPU::V_SUBREV_CO_U32_e32:
3847 case AMDGPU::V_SUBREV_CO_U32_e64:
3848 case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
3849 case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
3851 case AMDGPU::V_SUBBREV_U32_e32:
3852 case AMDGPU::V_SUBBREV_U32_e64:
3853 case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
3854 case AMDGPU::V_SUBBREV_U32_e32_vi:
3855 case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
3856 case AMDGPU::V_SUBBREV_U32_e64_vi:
3858 case AMDGPU::V_SUBREV_U32_e32:
3859 case AMDGPU::V_SUBREV_U32_e64:
3860 case AMDGPU::V_SUBREV_U32_e32_gfx9:
3861 case AMDGPU::V_SUBREV_U32_e32_vi:
3862 case AMDGPU::V_SUBREV_U32_e64_gfx9:
3863 case AMDGPU::V_SUBREV_U32_e64_vi:
3865 case AMDGPU::V_SUBREV_F16_e32:
3866 case AMDGPU::V_SUBREV_F16_e64:
3867 case AMDGPU::V_SUBREV_F16_e32_gfx10:
3868 case AMDGPU::V_SUBREV_F16_e32_vi:
3869 case AMDGPU::V_SUBREV_F16_e64_gfx10:
3870 case AMDGPU::V_SUBREV_F16_e64_vi:
3872 case AMDGPU::V_SUBREV_U16_e32:
3873 case AMDGPU::V_SUBREV_U16_e64:
3874 case AMDGPU::V_SUBREV_U16_e32_vi:
3875 case AMDGPU::V_SUBREV_U16_e64_vi:
3877 case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
3878 case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
3879 case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
3881 case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
3882 case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
3884 case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
3885 case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
3887 case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
3888 case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
3890 case AMDGPU::V_LSHRREV_B32_e32:
3891 case AMDGPU::V_LSHRREV_B32_e64:
3892 case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
3893 case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
3894 case AMDGPU::V_LSHRREV_B32_e32_vi:
3895 case AMDGPU::V_LSHRREV_B32_e64_vi:
3896 case AMDGPU::V_LSHRREV_B32_e32_gfx10:
3897 case AMDGPU::V_LSHRREV_B32_e64_gfx10:
3899 case AMDGPU::V_ASHRREV_I32_e32:
3900 case AMDGPU::V_ASHRREV_I32_e64:
3901 case AMDGPU::V_ASHRREV_I32_e32_gfx10:
3902 case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
3903 case AMDGPU::V_ASHRREV_I32_e32_vi:
3904 case AMDGPU::V_ASHRREV_I32_e64_gfx10:
3905 case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
3906 case AMDGPU::V_ASHRREV_I32_e64_vi:
3908 case AMDGPU::V_LSHLREV_B32_e32:
3909 case AMDGPU::V_LSHLREV_B32_e64:
3910 case AMDGPU::V_LSHLREV_B32_e32_gfx10:
3911 case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
3912 case AMDGPU::V_LSHLREV_B32_e32_vi:
3913 case AMDGPU::V_LSHLREV_B32_e64_gfx10:
3914 case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
3915 case AMDGPU::V_LSHLREV_B32_e64_vi:
3917 case AMDGPU::V_LSHLREV_B16_e32:
3918 case AMDGPU::V_LSHLREV_B16_e64:
3919 case AMDGPU::V_LSHLREV_B16_e32_vi:
3920 case AMDGPU::V_LSHLREV_B16_e64_vi:
3921 case AMDGPU::V_LSHLREV_B16_gfx10:
3923 case AMDGPU::V_LSHRREV_B16_e32:
3924 case AMDGPU::V_LSHRREV_B16_e64:
3925 case AMDGPU::V_LSHRREV_B16_e32_vi:
3926 case AMDGPU::V_LSHRREV_B16_e64_vi:
3927 case AMDGPU::V_LSHRREV_B16_gfx10:
3929 case AMDGPU::V_ASHRREV_I16_e32:
3930 case AMDGPU::V_ASHRREV_I16_e64:
3931 case AMDGPU::V_ASHRREV_I16_e32_vi:
3932 case AMDGPU::V_ASHRREV_I16_e64_vi:
3933 case AMDGPU::V_ASHRREV_I16_gfx10:
3935 case AMDGPU::V_LSHLREV_B64_e64:
3936 case AMDGPU::V_LSHLREV_B64_gfx10:
3937 case AMDGPU::V_LSHLREV_B64_vi:
3939 case AMDGPU::V_LSHRREV_B64_e64:
3940 case AMDGPU::V_LSHRREV_B64_gfx10:
3941 case AMDGPU::V_LSHRREV_B64_vi:
3943 case AMDGPU::V_ASHRREV_I64_e64:
3944 case AMDGPU::V_ASHRREV_I64_gfx10:
3945 case AMDGPU::V_ASHRREV_I64_vi:
3947 case AMDGPU::V_PK_LSHLREV_B16:
3948 case AMDGPU::V_PK_LSHLREV_B16_gfx10:
3949 case AMDGPU::V_PK_LSHLREV_B16_vi:
3951 case AMDGPU::V_PK_LSHRREV_B16:
3952 case AMDGPU::V_PK_LSHRREV_B16_gfx10:
3953 case AMDGPU::V_PK_LSHRREV_B16_vi:
3954 case AMDGPU::V_PK_ASHRREV_I16:
3955 case AMDGPU::V_PK_ASHRREV_I16_gfx10:
3956 case AMDGPU::V_PK_ASHRREV_I16_vi:
3965 using namespace SIInstrFlags;
3966 const unsigned Opcode = Inst.
getOpcode();
3972 if ((Desc.
TSFlags & Enc) == 0)
3975 for (
auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
3980 if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
3983 return StringRef(
"lds_direct is not supported on this GPU");
3986 return StringRef(
"lds_direct cannot be used with this instruction");
3988 if (SrcName != OpName::src0)
3989 return StringRef(
"lds_direct may be used as src0 only");
3998 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
i]);
3999 if (
Op.isFlatOffset())
4000 return Op.getStartLoc();
4005 bool AMDGPUAsmParser::validateFlatOffset(
const MCInst &Inst,
4016 if (!hasFlatOffsets() &&
Op.getImm() != 0) {
4018 "flat offset modifier is not supported on this GPU");
4026 if (!
isIntN(OffsetSize,
Op.getImm())) {
4028 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit signed offset");
4033 if (!
isUIntN(OffsetSize,
Op.getImm())) {
4035 Twine(
"expected a ") +
Twine(OffsetSize) +
"-bit unsigned offset");
4046 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
i]);
4047 if (
Op.isSMEMOffset())
4048 return Op.getStartLoc();
4053 bool AMDGPUAsmParser::validateSMEMOffset(
const MCInst &Inst,
4078 (
isVI() || IsBuffer) ?
"expected a 20-bit unsigned offset" :
4079 "expected a 21-bit signed offset");
4084 bool AMDGPUAsmParser::validateSOPLiteral(
const MCInst &Inst)
const {
4093 const int OpIndices[] = { Src0Idx, Src1Idx };
4095 unsigned NumExprs = 0;
4096 unsigned NumLiterals = 0;
4099 for (
int OpIdx : OpIndices) {
4100 if (OpIdx == -1)
break;
4105 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4107 if (NumLiterals == 0 || LiteralValue !=
Value) {
4111 }
else if (MO.
isExpr()) {
4117 return NumLiterals + NumExprs <= 1;
4120 bool AMDGPUAsmParser::validateOpSel(
const MCInst &Inst) {
4122 if (Opc == AMDGPU::V_PERMLANE16_B32_gfx10 ||
4123 Opc == AMDGPU::V_PERMLANEX16_B32_gfx10) {
4133 if (OpSelIdx != -1) {
4138 if (OpSelHiIdx != -1) {
4147 bool AMDGPUAsmParser::validateDPP(
const MCInst &Inst,
4161 Error(
S,
"64 bit dpp only supports row_newbcast");
4170 bool AMDGPUAsmParser::validateVccOperand(
unsigned Reg)
const {
4171 auto FB = getFeatureBits();
4172 return (FB[AMDGPU::FeatureWavefrontSize64] &&
Reg == AMDGPU::VCC) ||
4173 (FB[AMDGPU::FeatureWavefrontSize32] &&
Reg == AMDGPU::VCC_LO);
4177 bool AMDGPUAsmParser::validateVOPLiteral(
const MCInst &Inst,
4190 const int OpIndices[] = {Src0Idx, Src1Idx, Src2Idx, ImmIdx};
4192 unsigned NumExprs = 0;
4193 unsigned NumLiterals = 0;
4196 for (
int OpIdx : OpIndices) {
4207 getFeatureBits()[AMDGPU::FeatureMFMAInlineLiteralBug]) {
4209 "inline constants are not allowed for this operand");
4213 if (MO.
isImm() && !isInlineConstant(Inst, OpIdx)) {
4215 if (NumLiterals == 0 || LiteralValue !=
Value) {
4219 }
else if (MO.
isExpr()) {
4223 NumLiterals += NumExprs;
4228 if (ImmIdx == -1 && !getFeatureBits()[AMDGPU::FeatureVOP3Literal]) {
4229 Error(getLitLoc(
Operands),
"literal operands are not supported");
4233 if (NumLiterals > 1) {
4234 Error(getLitLoc(
Operands),
"only one literal operand is allowed");
4252 unsigned Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
4253 auto Reg = Sub ? Sub :
Op.getReg();
4258 bool AMDGPUAsmParser::validateAGPRLdSt(
const MCInst &Inst)
const {
4266 : AMDGPU::OpName::vdata;
4274 if (Data2Areg >= 0 && Data2Areg != DataAreg)
4278 auto FB = getFeatureBits();
4279 if (FB[AMDGPU::FeatureGFX90AInsts]) {
4280 if (DataAreg < 0 || DstAreg < 0)
4282 return DstAreg == DataAreg;
4285 return DstAreg < 1 && DataAreg < 1;
4288 bool AMDGPUAsmParser::validateVGPRAlign(
const MCInst &Inst)
const {
4289 auto FB = getFeatureBits();
4290 if (!FB[AMDGPU::FeatureGFX90AInsts])
4301 unsigned Sub =
MRI->getSubReg(
Op.getReg(), AMDGPU::sub0);
4305 if (VGPR32.
contains(Sub) && ((Sub - AMDGPU::VGPR0) & 1))
4307 if (AGPR32.
contains(Sub) && ((Sub - AMDGPU::AGPR0) & 1))
4316 AMDGPUOperand &
Op = ((AMDGPUOperand &)*
Operands[
i]);
4318 return Op.getStartLoc();
4323 bool AMDGPUAsmParser::validateBLGP(
const MCInst &Inst,
4333 auto FB = getFeatureBits();
4334 bool UsesNeg =
false;
4335 if (FB[AMDGPU::FeatureGFX940Insts]) {
4337 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
4338 case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
4339 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
4340 case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
4345 if (IsNeg == UsesNeg)
4349 UsesNeg ?
"invalid modifier: blgp is not supported"
4350 :
"invalid modifier: neg is not supported");
4357 bool AMDGPUAsmParser::validateGWS(
const MCInst &Inst,
4359 if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
4363 if (Opc != AMDGPU::DS_GWS_INIT_vi && Opc != AMDGPU::DS_GWS_BARRIER_vi &&
4364 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
4373 auto RegIdx =
Reg - (VGPR32.
contains(
Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
4376 Error(RegLoc,
"vgpr must be even aligned");
4383 bool AMDGPUAsmParser::validateCoherencyBits(
const MCInst &Inst,
4385 const SMLoc &IDLoc) {
4387 AMDGPU::OpName::cpol);
4397 Error(
S,
"cache policy is not supported for SMRD instructions");
4401 Error(IDLoc,
"invalid cache policy for SMEM instruction");
4410 Error(
S,
"scc is not supported on this GPU");
4420 :
"instruction must use glc");
4428 &CStr.data()[CStr.find(
isGFX940() ?
"sc0" :
"glc")]);
4430 :
"instruction must not use glc");
4438 bool AMDGPUAsmParser::validateFlatLdsDMA(
const MCInst &Inst,
4440 const SMLoc &IDLoc) {
4452 if (!CStr.startswith(
"lds")) {
4456 Error(IDLoc,
"invalid operands for instruction");
4463 bool AMDGPUAsmParser::validateInstruction(
const MCInst &Inst,
4466 if (
auto ErrMsg = validateLdsDirect(Inst)) {
4470 if (!validateSOPLiteral(Inst)) {
4472 "only one literal operand is allowed");
4475 if (!validateVOPLiteral(Inst,
Operands)) {
4478 if (!validateConstantBusLimitations(Inst,
Operands)) {
4481 if (!validateEarlyClobberLimitations(Inst,
Operands)) {
4484 if (!validateIntClampSupported(Inst)) {
4486 "integer clamping is not supported on this GPU");
4489 if (!validateOpSel(Inst)) {
4491 "invalid op_sel operand");
4494 if (!validateDPP(Inst,
Operands)) {
4498 if (!validateMIMGD16(Inst)) {
4500 "d16 modifier is not supported on this GPU");
4503 if (!validateMIMGDim(Inst)) {
4504 Error(IDLoc,
"dim modifier is required on this GPU");
4507 if (!validateMIMGMSAA(Inst)) {
4509 "invalid dim; must be MSAA type");
4512 if (
auto ErrMsg = validateMIMGDataSize(Inst)) {
4513 Error(IDLoc, *ErrMsg);
4516 if (!validateMIMGAddrSize(Inst)) {
4518 "image address size does not match dim and a16");
4521 if (!validateMIMGAtomicDMask(Inst)) {
4523 "invalid atomic image dmask");
4526 if (!validateMIMGGatherDMask(Inst)) {
4528 "invalid image_gather dmask: only one bit must be set");
4531 if (!validateMovrels(Inst,
Operands)) {
4534 if (!validateFlatOffset(Inst,
Operands)) {
4537 if (!validateSMEMOffset(Inst,
Operands)) {
4540 if (!validateMAIAccWrite(Inst,
Operands)) {
4543 if (!validateMFMA(Inst,
Operands)) {
4546 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
4550 if (!validateAGPRLdSt(Inst)) {
4551 Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
4552 ?
"invalid register class: data and dst should be all VGPR or AGPR"
4553 :
"invalid register class: agpr loads and stores not supported on this GPU"
4557 if (!validateVGPRAlign(Inst)) {
4559 "invalid register class: vgpr tuples must be 64 bit aligned");
4562 if (!validateGWS(Inst,
Operands)) {
4566 if (!validateBLGP(Inst,
Operands)) {
4570 if (!validateDivScale(Inst)) {
4571 Error(IDLoc,
"ABS not allowed in VOP3B instructions");
4574 if (!validateCoherencyBits(Inst,
Operands, IDLoc)) {
4578 if (!validateFlatLdsDMA(Inst,
Operands, IDLoc)) {
4587 unsigned VariantID = 0);
4591 unsigned VariantID);
4593 bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
4598 bool AMDGPUAsmParser::isSupportedMnemo(
StringRef Mnemo,
4601 for (
auto Variant : Variants) {
4609 bool AMDGPUAsmParser::checkUnsupportedInstruction(
StringRef Mnemo,
4610 const SMLoc &IDLoc) {
4611 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
4614 if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
4619 getParser().clearPendingErrors();
4623 StringRef VariantName = getMatchedVariantName();
4624 if (!VariantName.
empty() && isSupportedMnemo(Mnemo, FBS)) {
4627 " variant of this instruction is not supported"));
4632 return Error(IDLoc,
"instruction not supported on this GPU");
4637 return Error(IDLoc,
"invalid instruction" + Suggestion);
4640 bool AMDGPUAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
4644 bool MatchingInlineAsm) {
4646 unsigned Result = Match_Success;
4647 for (
auto Variant : getMatchedVariants()) {
4649 auto R = MatchInstructionImpl(
Operands, Inst, EI, MatchingInlineAsm,
4654 if ((R == Match_Success) ||
4655 (R == Match_PreferE32) ||
4656 (R == Match_MissingFeature && Result != Match_PreferE32) ||
4657 (R == Match_InvalidOperand && Result != Match_MissingFeature
4658 && Result != Match_PreferE32) ||
4659 (R == Match_MnemonicFail && Result != Match_InvalidOperand
4660 && Result != Match_MissingFeature
4661 && Result != Match_PreferE32)) {
4665 if (R == Match_Success)
4669 if (Result == Match_Success) {
4670 if (!validateInstruction(Inst, IDLoc,
Operands)) {
4679 if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
4685 case Match_MissingFeature:
4689 return Error(IDLoc,
"operands are not valid for this GPU or mode");
4691 case Match_InvalidOperand: {
4692 SMLoc ErrorLoc = IDLoc;
4695 return Error(IDLoc,
"too few operands for instruction");
4698 if (ErrorLoc ==
SMLoc())
4701 return Error(ErrorLoc,
"invalid operand for instruction");
4704 case Match_PreferE32:
4705 return Error(IDLoc,
"internal error: instruction without _e64 suffix "
4706 "should be encoded as e32");
4707 case Match_MnemonicFail:
4713 bool AMDGPUAsmParser::ParseAsAbsoluteExpression(
uint32_t &
Ret) {
4718 if (getParser().parseAbsoluteExpression(Tmp)) {
4725 bool AMDGPUAsmParser::ParseDirectiveMajorMinor(
uint32_t &Major,
4727 if (ParseAsAbsoluteExpression(Major))
4728 return TokError(
"invalid major version");
4731 return TokError(
"minor version number required, comma expected");
4733 if (ParseAsAbsoluteExpression(Minor))
4734 return TokError(
"invalid minor version");
4739 bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
4741 return TokError(
"directive only supported for amdgcn architecture");
4743 std::string TargetIDDirective;
4744 SMLoc TargetStart = getTok().getLoc();
4745 if (getParser().parseEscapedString(TargetIDDirective))
4749 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
4750 return getParser().Error(TargetRange.
Start,
4751 (
Twine(
".amdgcn_target directive's target id ") +
4752 Twine(TargetIDDirective) +
4753 Twine(
" does not match the specified target id ") +
4754 Twine(getTargetStreamer().getTargetID()->
toString())).str());
4759 bool AMDGPUAsmParser::OutOfRangeError(
SMRange Range) {
4760 return Error(Range.
Start,
"value out of range", Range);
4763 bool AMDGPUAsmParser::calculateGPRBlocks(
4764 const FeatureBitset &Features,
bool VCCUsed,
bool FlatScrUsed,
4765 bool XNACKUsed,
Optional<bool> EnableWavefrontSize32,
unsigned NextFreeVGPR,
4767 unsigned &VGPRBlocks,
unsigned &SGPRBlocks) {
4778 unsigned MaxAddressableNumSGPRs =
4781 if (
Version.Major >= 8 && !Features.
test(FeatureSGPRInitBug) &&
4783 return OutOfRangeError(SGPRRange);
4788 if ((
Version.Major <= 7 || Features.
test(FeatureSGPRInitBug)) &&
4790 return OutOfRangeError(SGPRRange);
4792 if (Features.
test(FeatureSGPRInitBug))
4803 bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
4805 return TokError(
"directive only supported for amdgcn architecture");
4808 return TokError(
"directive only supported for amdhsa OS");
4811 if (getParser().parseIdentifier(KernelName))
4828 unsigned ImpliedUserSGPRCount = 0;
4833 bool ReserveVCC =
true;
4834 bool ReserveFlatScr =
true;
4841 SMRange IDRange = getTok().getLocRange();
4842 if (!parseId(
ID,
"expected .amdhsa_ directive or .end_amdhsa_kernel"))
4845 if (
ID ==
".end_amdhsa_kernel")
4849 return TokError(
".amdhsa_ directives cannot be repeated");
4852 SMLoc ValStart = getLoc();
4854 if (getParser().parseAbsoluteExpression(IVal))
4856 SMLoc ValEnd = getLoc();
4860 return OutOfRangeError(ValRange);
4864 #define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
4865 if (!isUInt<ENTRY##_WIDTH>(VALUE)) \
4866 return OutOfRangeError(RANGE); \
4867 AMDHSA_BITS_SET(FIELD, ENTRY, VALUE);
4869 if (
ID ==
".amdhsa_group_segment_fixed_size") {
4871 return OutOfRangeError(ValRange);
4873 }
else if (
ID ==
".amdhsa_private_segment_fixed_size") {
4875 return OutOfRangeError(ValRange);
4877 }
else if (
ID ==
".amdhsa_kernarg_size") {
4879 return OutOfRangeError(ValRange);
4881 }
else if (
ID ==
".amdhsa_user_sgpr_count") {
4882 ExplicitUserSGPRCount = Val;
4883 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_buffer") {
4886 "directive is not supported with architected flat scratch",
4889 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
4892 ImpliedUserSGPRCount += 4;
4893 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_ptr") {
4895 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, Val,
4898 ImpliedUserSGPRCount += 2;
4899 }
else if (
ID ==
".amdhsa_user_sgpr_queue_ptr") {
4901 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, Val,
4904 ImpliedUserSGPRCount += 2;
4905 }
else if (
ID ==
".amdhsa_user_sgpr_kernarg_segment_ptr") {
4907 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
4910 ImpliedUserSGPRCount += 2;
4911 }
else if (
ID ==
".amdhsa_user_sgpr_dispatch_id") {
4913 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, Val,
4916 ImpliedUserSGPRCount += 2;
4917 }
else if (
ID ==
".amdhsa_user_sgpr_flat_scratch_init") {
4920 "directive is not supported with architected flat scratch",
4923 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT, Val,
4926 ImpliedUserSGPRCount += 2;
4927 }
else if (
ID ==
".amdhsa_user_sgpr_private_segment_size") {
4929 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
4932 ImpliedUserSGPRCount += 1;
4933 }
else if (
ID ==
".amdhsa_wavefront_size32") {
4934 if (IVersion.
Major < 10)
4935 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
4936 EnableWavefrontSize32 = Val;
4938 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32,
4940 }
else if (
ID ==
".amdhsa_system_sgpr_private_segment_wavefront_offset") {
4943 "directive is not supported with architected flat scratch",
4946 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, Val, ValRange);
4947 }
else if (
ID ==
".amdhsa_enable_private_segment") {
4951 "directive is not supported without architected flat scratch",
4954 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, Val, ValRange);
4955 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_x") {
4957 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, Val,
4959 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_y") {
4961 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, Val,
4963 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_id_z") {
4965 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, Val,
4967 }
else if (
ID ==
".amdhsa_system_sgpr_workgroup_info") {
4969 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, Val,
4971 }
else if (
ID ==
".amdhsa_system_vgpr_workitem_id") {
4973 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, Val,
4975 }
else if (
ID ==
".amdhsa_next_free_vgpr") {
4976 VGPRRange = ValRange;
4978 }
else if (
ID ==
".amdhsa_next_free_sgpr") {
4979 SGPRRange = ValRange;
4981 }
else if (
ID ==
".amdhsa_accum_offset") {
4983 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
4985 }
else if (
ID ==
".amdhsa_reserve_vcc") {
4986 if (!isUInt<1>(Val))
4987 return OutOfRangeError(ValRange);
4989 }
else if (
ID ==
".amdhsa_reserve_flat_scratch") {
4990 if (IVersion.
Major < 7)
4991 return Error(IDRange.
Start,
"directive requires gfx7+", IDRange);
4994 "directive is not supported with architected flat scratch",
4996 if (!isUInt<1>(Val))
4997 return OutOfRangeError(ValRange);
4998 ReserveFlatScr = Val;
4999 }
else if (
ID ==
".amdhsa_reserve_xnack_mask") {
5000 if (IVersion.
Major < 8)
5001 return Error(IDRange.
Start,
"directive requires gfx8+", IDRange);
5002 if (!isUInt<1>(Val))
5003 return OutOfRangeError(ValRange);
5004 if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
5005 return getParser().Error(IDRange.
Start,
".amdhsa_reserve_xnack_mask does not match target id",
5007 }
else if (
ID ==
".amdhsa_float_round_mode_32") {
5009 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, Val, ValRange);
5010 }
else if (
ID ==
".amdhsa_float_round_mode_16_64") {
5012 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, Val, ValRange);
5013 }
else if (
ID ==
".amdhsa_float_denorm_mode_32") {
5015 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, Val, ValRange);
5016 }
else if (
ID ==
".amdhsa_float_denorm_mode_16_64") {
5018 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, Val,
5020 }
else if (
ID ==
".amdhsa_dx10_clamp") {
5022 COMPUTE_PGM_RSRC1_ENABLE_DX10_CLAMP, Val, ValRange);
5023 }
else if (
ID ==
".amdhsa_ieee_mode") {
5026 }
else if (
ID ==
".amdhsa_fp16_overflow") {
5027 if (IVersion.
Major < 9)
5028 return Error(IDRange.
Start,
"directive requires gfx9+", IDRange);
5031 }
else if (
ID ==
".amdhsa_tg_split") {
5033 return Error(IDRange.
Start,
"directive requires gfx90a+", IDRange);
5036 }
else if (
ID ==
".amdhsa_workgroup_processor_mode") {
5037 if (IVersion.
Major < 10)
5038 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5041 }
else if (
ID ==
".amdhsa_memory_ordered") {
5042 if (IVersion.
Major < 10)
5043 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5046 }
else if (
ID ==
".amdhsa_forward_progress") {
5047 if (IVersion.
Major < 10)
5048 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5051 }
else if (
ID ==
".amdhsa_shared_vgpr_count") {
5052 if (IVersion.
Major < 10)
5053 return Error(IDRange.
Start,
"directive requires gfx10+", IDRange);
5054 SharedVGPRCount = Val;
5056 COMPUTE_PGM_RSRC3_GFX10_SHARED_VGPR_COUNT, Val,
5058 }
else if (
ID ==
".amdhsa_exception_fp_ieee_invalid_op") {
5061 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION, Val,
5063 }
else if (
ID ==
".amdhsa_exception_fp_denorm_src") {
5065 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
5067 }
else if (
ID ==
".amdhsa_exception_fp_ieee_div_zero") {
5070 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO, Val,
5072 }
else if (
ID ==
".amdhsa_exception_fp_ieee_overflow") {
5074 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
5076 }
else if (
ID ==
".amdhsa_exception_fp_ieee_underflow") {
5078 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
5080 }
else if (
ID ==
".amdhsa_exception_fp_ieee_inexact") {
5082 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
5084 }
else if (
ID ==
".amdhsa_exception_int_div_zero") {
5086 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
5089 return Error(IDRange.
Start,
"unknown .amdhsa_kernel directive", IDRange);
5092 #undef PARSE_BITS_ENTRY
5095 if (Seen.
find(
".amdhsa_next_free_vgpr") == Seen.
end())
5096 return TokError(
".amdhsa_next_free_vgpr directive is required");
5098 if (Seen.
find(
".amdhsa_next_free_sgpr") == Seen.
end())
5099 return TokError(
".amdhsa_next_free_sgpr directive is required");
5101 unsigned VGPRBlocks;
5102 unsigned SGPRBlocks;
5103 if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
5104 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
5105 EnableWavefrontSize32, NextFreeVGPR,
5106 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
5110 if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_WIDTH>(
5112 return OutOfRangeError(VGPRRange);
5114 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT, VGPRBlocks);
5116 if (!isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_WIDTH>(
5118 return OutOfRangeError(SGPRRange);
5120 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT,
5123 if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
5124 return TokError(
"amdgpu_user_sgpr_count smaller than than implied by "
5125 "enabled user SGPRs");
5127 unsigned UserSGPRCount =
5128 ExplicitUserSGPRCount ? *ExplicitUserSGPRCount : ImpliedUserSGPRCount;
5130 if (!isUInt<COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_WIDTH>(UserSGPRCount))
5131 return TokError(
"too many user SGPRs enabled");
5136 if (Seen.
find(
".amdhsa_accum_offset") == Seen.
end())
5137 return TokError(
".amdhsa_accum_offset directive is required");
5138 if (AccumOffset < 4 || AccumOffset > 256 || (AccumOffset & 3))
5139 return TokError(
"accum_offset should be in range [4..256] in "
5142 return TokError(
"accum_offset exceeds total VGPR allocation");
5144 (AccumOffset / 4 - 1));
5147 if (IVersion.
Major == 10) {
5149 if (SharedVGPRCount && EnableWavefrontSize32) {
5150 return TokError(
"shared_vgpr_count directive not valid on "
5151 "wavefront size 32");
5153 if (SharedVGPRCount * 2 + VGPRBlocks > 63) {
5154 return TokError(
"shared_vgpr_count*2 + "
5155 "compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
5160 getTargetStreamer().EmitAmdhsaKernelDescriptor(
5161 getSTI(), KernelName, KD, NextFreeVGPR, NextFreeSGPR, ReserveVCC,
5166 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectVersion() {
5170 if (ParseDirectiveMajorMinor(Major, Minor))
5173 getTargetStreamer().EmitDirectiveHSACodeObjectVersion(Major, Minor);
5177 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectISA() {
5188 getTargetStreamer().EmitDirectiveHSACodeObjectISAV2(
ISA.Major,
ISA.Minor,
5194 if (ParseDirectiveMajorMinor(Major, Minor))
5198 return TokError(
"stepping version number required, comma expected");
5200 if (ParseAsAbsoluteExpression(Stepping))
5201 return TokError(
"invalid stepping version");
5204 return TokError(
"vendor name required, comma expected");
5206 if (!parseString(VendorName,
"invalid vendor name"))
5210 return TokError(
"arch name required, comma expected");
5212 if (!parseString(ArchName,
"invalid arch name"))
5215 getTargetStreamer().EmitDirectiveHSACodeObjectISAV2(Major, Minor, Stepping,
5216 VendorName, ArchName);
5220 bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(
StringRef ID,
5224 if (
ID ==
"max_scratch_backing_memory_byte_size") {
5225 Parser.eatToEndOfStatement();
5232 return TokError(Err.str());
5236 if (
ID ==
"enable_wavefront_size32") {
5239 return TokError(
"enable_wavefront_size32=1 is only allowed on GFX10+");
5240 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5241 return TokError(
"enable_wavefront_size32=1 requires +WavefrontSize32");
5243 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5244 return TokError(
"enable_wavefront_size32=0 requires +WavefrontSize64");
5248 if (
ID ==
"wavefront_size") {
5251 return TokError(
"wavefront_size=5 is only allowed on GFX10+");
5252 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
5253 return TokError(
"wavefront_size=5 requires +WavefrontSize32");
5255 if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
5256 return TokError(
"wavefront_size=6 requires +WavefrontSize64");
5260 if (
ID ==
"enable_wgp_mode") {
5263 return TokError(
"enable_wgp_mode=1 is only allowed on GFX10+");
5266 if (
ID ==
"enable_mem_ordered") {
5269 return TokError(
"enable_mem_ordered=1 is only allowed on GFX10+");
5272 if (
ID ==
"enable_fwd_progress") {
5275 return TokError(
"enable_fwd_progress=1 is only allowed on GFX10+");
5281 bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
5291 if (!parseId(
ID,
"expected value identifier or .end_amd_kernel_code_t"))
5294 if (
ID ==
".end_amd_kernel_code_t")
5297 if (ParseAMDKernelCodeTValue(
ID, Header))
5301 getTargetStreamer().EmitAMDKernelCodeT(Header);
5306 bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
5308 if (!parseId(KernelName,
"expected symbol name"))
5311 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
5314 KernelScope.initialize(getContext());
5318 bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
5320 return Error(getLoc(),
5321 ".amd_amdgpu_isa directive is not available on non-amdgcn "
5325 auto TargetIDDirective = getLexer().getTok().getStringContents();
5326 if (getTargetStreamer().getTargetID()->
toString() != TargetIDDirective)
5327 return Error(getParser().getTok().getLoc(),
"target id must match options");
5329 getTargetStreamer().EmitISAVersion();
5335 bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
5346 return Error(getLoc(),
5348 "not available on non-amdhsa OSes")).str());
5351 std::string HSAMetadataString;
5357 if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
5358 return Error(getLoc(),
"invalid HSA metadata");
5360 if (!getTargetStreamer().EmitHSAMetadataV2(HSAMetadataString))
5361 return Error(getLoc(),
"invalid HSA metadata");
5371 std::string &CollectString) {
5375 getLexer().setSkipSpace(
false);
5377 bool FoundEnd =
false;
5380 CollectStream << getTokenStr();
5389 CollectStream << Parser.parseStringToEndOfStatement()
5390 << getContext().getAsmInfo()->getSeparatorString();
5392 Parser.eatToEndOfStatement();
5395 getLexer().setSkipSpace(
true);
5398 return TokError(
Twine(
"expected directive ") +
5402 CollectStream.flush();
5407 bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
5413 auto PALMetadata = getTargetStreamer().getPALMetadata();
5414 if (!PALMetadata->setFromString(String))
5415 return Error(getLoc(),
"invalid PAL metadata");
5420 bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
5422 return Error(getLoc(),
5424 "not available on non-amdpal OSes")).str());
5427 auto PALMetadata = getTargetStreamer().getPALMetadata();
5428 PALMetadata->setLegacy();
5431 if (ParseAsAbsoluteExpression(
Key)) {
5432 return TokError(
Twine(
"invalid value in ") +
5436 return TokError(
Twine(
"expected an even number of values in ") +
5439 if (ParseAsAbsoluteExpression(
Value)) {
5440 return TokError(
Twine(
"invalid value in ") +
5443 PALMetadata->setRegister(
Key,
Value);
5452 bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
5453 if (getParser().checkForValidSection())
5457 SMLoc NameLoc = getLoc();
5458 if (getParser().parseIdentifier(
Name))
5459 return TokError(
"expected identifier in directive");
5468 SMLoc SizeLoc = getLoc();
5469 if (getParser().parseAbsoluteExpression(Size))
5472 return Error(SizeLoc,
"size must be non-negative");
5473 if (Size > LocalMemorySize)
5474 return Error(SizeLoc,
"size is too large");
5478 SMLoc AlignLoc = getLoc();
5479 if (getParser().parseAbsoluteExpression(Alignment))
5482 return Error(AlignLoc,
"alignment must be a power of two");
5487 if (Alignment >= 1u << 31)
5488 return Error(AlignLoc,
"alignment is too large");
5492 "unexpected token in '.amdgpu_lds' directive"))
5495 Symbol->redefineIfPossible();
5496 if (!
Symbol->isUndefined())
5497 return Error(NameLoc,
"invalid symbol redefinition");
5499 getTargetStreamer().emitAMDGPULDS(
Symbol, Size,
Align(Alignment));
5503 bool AMDGPUAsmParser::ParseDirective(
AsmToken DirectiveID) {
5507 if (IDVal ==
".amdhsa_kernel")
5508 return ParseDirectiveAMDHSAKernel();
5512 return ParseDirectiveHSAMetadata();
5514 if (IDVal ==
".hsa_code_object_version")
5515 return ParseDirectiveHSACodeObjectVersion();
5517 if (IDVal ==
".hsa_code_object_isa")
5518 return ParseDirectiveHSACodeObjectISA();
5520 if (IDVal ==
".amd_kernel_code_t")
5521 return ParseDirectiveAMDKernelCodeT();
5523 if (IDVal ==
".amdgpu_hsa_kernel")
5524 return ParseDirectiveAMDGPUHsaKernel();
5526 if (IDVal ==
".amd_amdgpu_isa")
5527 return ParseDirectiveISAVersion();
5530 return ParseDirectiveHSAMetadata();
5533 if (IDVal ==
".amdgcn_target")
5534 return ParseDirectiveAMDGCNTarget();
5536 if (IDVal ==
".amdgpu_lds")
5537 return ParseDirectiveAMDGPULDS();
5540 return ParseDirectivePALMetadataBegin();
5543 return ParseDirectivePALMetadata();
5551 if (
MRI.regsOverlap(AMDGPU::TTMP12_TTMP13_TTMP14_TTMP15, RegNo))
5555 if (
MRI.regsOverlap(AMDGPU::SGPR104_SGPR105, RegNo))
5556 return hasSGPR104_SGPR105();
5559 case AMDGPU::SRC_SHARED_BASE:
5560 case AMDGPU::SRC_SHARED_LIMIT:
5561 case AMDGPU::SRC_PRIVATE_BASE:
5562 case AMDGPU::SRC_PRIVATE_LIMIT:
5563 case AMDGPU::SRC_POPS_EXITING_WAVE_ID:
5566 case AMDGPU::TBA_LO:
5567 case AMDGPU::TBA_HI:
5569 case AMDGPU::TMA_LO:
5570 case AMDGPU::TMA_HI:
5572 case AMDGPU::XNACK_MASK:
5573 case AMDGPU::XNACK_MASK_LO:
5574 case AMDGPU::XNACK_MASK_HI:
5575 return (
isVI() ||
isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
5576 case AMDGPU::SGPR_NULL:
5590 case AMDGPU::FLAT_SCR:
5591 case AMDGPU::FLAT_SCR_LO:
5592 case AMDGPU::FLAT_SCR_HI:
5601 if (
MRI.regsOverlap(AMDGPU::SGPR102_SGPR103, RegNo))
5602 return hasSGPR102_SGPR103();
5624 SMLoc LBraceLoc = getLoc();
5629 auto Loc = getLoc();
5632 Error(Loc,
"expected a register");
5636 RBraceLoc = getLoc();
5641 "expected a comma or a closing square bracket")) {
5648 AMDGPUOperand::CreateToken(
this,
"[", LBraceLoc));
5649 Operands.push_back(AMDGPUOperand::CreateToken(
this,
"]", RBraceLoc));
5660 setForcedEncodingSize(0);
5661 setForcedDPP(
false);
5662 setForcedSDWA(
false);
5664 if (
Name.endswith(
"_e64")) {
5665 setForcedEncodingSize(64);
5666 return Name.substr(0,
Name.size() - 4);
5667 }
else if (
Name.endswith(
"_e32")) {
5668 setForcedEncodingSize(32);
5669 return Name.substr(0,
Name.size() - 4);
5670 }
else if (
Name.endswith(
"_dpp")) {
5672 return Name.substr(0,
Name.size() - 4);
5673 }
else if (
Name.endswith(
"_sdwa")) {
5674 setForcedSDWA(
true);
5675 return Name.substr(0,
Name.size() - 5);
5682 unsigned VariantID);
5694 Operands.push_back(AMDGPUOperand::CreateToken(
this,
Name, NameLoc));
5696 bool IsMIMG =
Name.startswith(
"image_");
5699 OperandMode
Mode = OperandMode_Default;
5701 Mode = OperandMode_NSA;
5706 checkUnsupportedInstruction(
Name, NameLoc);
5707 if (!Parser.hasPendingError()) {
5711 "not a valid operand.";
5732 AMDGPUAsmParser::parseIntWithPrefix(
const char *
Prefix, int64_t &
IntVal) {
5742 AMDGPUOperand::ImmTy ImmTy,
5743 bool (*ConvertResult)(int64_t&)) {
5751 if (ConvertResult && !ConvertResult(
Value)) {
5755 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Value,
S, ImmTy));
5760 AMDGPUAsmParser::parseOperandArrayWithPrefix(
const char *
Prefix,
5762 AMDGPUOperand::ImmTy ImmTy,
5763 bool (*ConvertResult)(int64_t&)) {
5772 const unsigned MaxSize = 4;
5776 for (
int I = 0; ; ++
I) {
5778 SMLoc Loc = getLoc();
5782 if (
Op != 0 &&
Op != 1) {
5792 if (
I + 1 == MaxSize) {
5793 Error(getLoc(),
"expected a closing square bracket");
5801 Operands.push_back(AMDGPUOperand::CreateImm(
this, Val,
S, ImmTy));
5807 AMDGPUOperand::ImmTy ImmTy) {
5811 if (trySkipId(
Name)) {
5813 }
else if (trySkipId(
"no",
Name)) {
5820 Error(
S,
"r128 modifier is not supported on this GPU");
5824 Error(
S,
"a16 modifier is not supported on this GPU");
5828 if (
isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
5829 ImmTy = AMDGPUOperand::ImmTyR128A16;
5831 Operands.push_back(AMDGPUOperand::CreateImm(
this,
Bit,
S, ImmTy));
5837 unsigned CPolOn = 0;
5838 unsigned CPolOff = 0;
5843 if (trySkipId(
"sc0"))
5845 else if (trySkipId(
"nosc0"))
5847 else if (trySkipId(
"nt"))
5849 else if (trySkipId(
"nont"))
5851 else if (trySkipId(
"sc1"))
5853 else if (trySkipId(
"nosc1"))
5858 else if (trySkipId(
"glc"))
5860 else if (trySkipId(
"noglc"))
5862 else if (trySkipId(
"slc"))
5864 else if (trySkipId(
"noslc"))
5866 else if (trySkipId(
"dlc"