62 using namespace llvm::AMDGPU;
66 class AMDGPUAsmParser;
68 enum RegisterKind { IS_UNKNOWN, IS_VGPR, IS_SGPR, IS_TTMP, IS_SPECIAL };
82 SMLoc StartLoc, EndLoc;
83 const AMDGPUAsmParser *AsmParser;
86 AMDGPUOperand(
enum KindTy Kind_,
const AMDGPUAsmParser *AsmParser_)
89 typedef std::unique_ptr<AMDGPUOperand>
Ptr;
96 bool hasFPModifiers()
const {
return Abs || Neg; }
97 bool hasIntModifiers()
const {
return Sext; }
98 bool hasModifiers()
const {
return hasFPModifiers() || hasIntModifiers(); }
100 int64_t getFPModifiersOperand()
const {
107 int64_t getIntModifiersOperand()
const {
113 int64_t getModifiersOperand()
const {
114 assert(!(hasFPModifiers() && hasIntModifiers())
115 &&
"fp and int modifiers should not be used simultaneously");
116 if (hasFPModifiers()) {
117 return getFPModifiersOperand();
118 }
else if (hasIntModifiers()) {
119 return getIntModifiersOperand();
191 bool isToken()
const override {
195 if (
Kind != Expression || !Expr)
202 return isa<MCSymbolRefExpr>(Expr);
205 bool isImm()
const override {
206 return Kind == Immediate;
209 bool isInlinableImm(
MVT type)
const;
210 bool isLiteralImm(
MVT type)
const;
212 bool isRegKind()
const {
216 bool isReg()
const override {
217 return isRegKind() && !hasModifiers();
221 return isRegKind() || isInlinableImm(type);
224 bool isRegOrImmWithInt16InputMods()
const {
228 bool isRegOrImmWithInt32InputMods()
const {
232 bool isRegOrImmWithInt64InputMods()
const {
236 bool isRegOrImmWithFP16InputMods()
const {
240 bool isRegOrImmWithFP32InputMods()
const {
244 bool isRegOrImmWithFP64InputMods()
const {
248 bool isVReg()
const {
249 return isRegClass(AMDGPU::VGPR_32RegClassID) ||
250 isRegClass(AMDGPU::VReg_64RegClassID) ||
251 isRegClass(AMDGPU::VReg_96RegClassID) ||
252 isRegClass(AMDGPU::VReg_128RegClassID) ||
253 isRegClass(AMDGPU::VReg_256RegClassID) ||
254 isRegClass(AMDGPU::VReg_512RegClassID);
257 bool isVReg32OrOff()
const {
258 return isOff() || isRegClass(AMDGPU::VGPR_32RegClassID);
261 bool isImmTy(ImmTy ImmT)
const {
262 return isImm() && Imm.Type == ImmT;
265 bool isImmModifier()
const {
266 return isImm() && Imm.Type != ImmTyNone;
269 bool isClampSI()
const {
return isImmTy(ImmTyClampSI); }
270 bool isOModSI()
const {
return isImmTy(ImmTyOModSI); }
271 bool isDMask()
const {
return isImmTy(ImmTyDMask); }
272 bool isUNorm()
const {
return isImmTy(ImmTyUNorm); }
273 bool isDA()
const {
return isImmTy(ImmTyDA); }
274 bool isR128()
const {
return isImmTy(ImmTyUNorm); }
275 bool isLWE()
const {
return isImmTy(ImmTyLWE); }
276 bool isOff()
const {
return isImmTy(ImmTyOff); }
277 bool isExpTgt()
const {
return isImmTy(ImmTyExpTgt); }
278 bool isExpVM()
const {
return isImmTy(ImmTyExpVM); }
279 bool isExpCompr()
const {
return isImmTy(ImmTyExpCompr); }
280 bool isOffen()
const {
return isImmTy(ImmTyOffen); }
281 bool isIdxen()
const {
return isImmTy(ImmTyIdxen); }
282 bool isAddr64()
const {
return isImmTy(ImmTyAddr64); }
283 bool isOffset()
const {
return isImmTy(ImmTyOffset) &&
isUInt<16>(getImm()); }
284 bool isOffset0()
const {
return isImmTy(ImmTyOffset0) &&
isUInt<16>(getImm()); }
285 bool isOffset1()
const {
return isImmTy(ImmTyOffset1) &&
isUInt<8>(getImm()); }
286 bool isGDS()
const {
return isImmTy(ImmTyGDS); }
287 bool isGLC()
const {
return isImmTy(ImmTyGLC); }
288 bool isSLC()
const {
return isImmTy(ImmTySLC); }
289 bool isTFE()
const {
return isImmTy(ImmTyTFE); }
290 bool isBankMask()
const {
return isImmTy(ImmTyDppBankMask); }
291 bool isRowMask()
const {
return isImmTy(ImmTyDppRowMask); }
292 bool isBoundCtrl()
const {
return isImmTy(ImmTyDppBoundCtrl); }
293 bool isSDWADstSel()
const {
return isImmTy(ImmTySdwaDstSel); }
294 bool isSDWASrc0Sel()
const {
return isImmTy(ImmTySdwaSrc0Sel); }
295 bool isSDWASrc1Sel()
const {
return isImmTy(ImmTySdwaSrc1Sel); }
296 bool isSDWADstUnused()
const {
return isImmTy(ImmTySdwaDstUnused); }
297 bool isInterpSlot()
const {
return isImmTy(ImmTyInterpSlot); }
298 bool isInterpAttr()
const {
return isImmTy(ImmTyInterpAttr); }
299 bool isAttrChan()
const {
return isImmTy(ImmTyAttrChan); }
302 return isClampSI() || isOModSI();
305 bool isRegOrImm()
const {
306 return isReg() || isImm();
309 bool isRegClass(
unsigned RCID)
const;
311 bool isRegOrInlineNoMods(
unsigned RCID,
MVT type)
const {
312 return (isRegClass(RCID) || isInlinableImm(type)) && !hasModifiers();
315 bool isSCSrcB16()
const {
316 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID,
MVT::i16);
319 bool isSCSrcB32()
const {
320 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID,
MVT::i32);
323 bool isSCSrcB64()
const {
324 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID,
MVT::i64);
327 bool isSCSrcF16()
const {
328 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID,
MVT::f16);
331 bool isSCSrcF32()
const {
332 return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID,
MVT::f32);
335 bool isSCSrcF64()
const {
336 return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID,
MVT::f64);
339 bool isSSrcB32()
const {
340 return isSCSrcB32() || isLiteralImm(
MVT::i32) || isExpr();
343 bool isSSrcB16()
const {
344 return isSCSrcB16() || isLiteralImm(
MVT::i16);
347 bool isSSrcB64()
const {
350 return isSCSrcB64() || isLiteralImm(
MVT::i64);
353 bool isSSrcF32()
const {
354 return isSCSrcB32() || isLiteralImm(
MVT::f32) || isExpr();
357 bool isSSrcF64()
const {
358 return isSCSrcB64() || isLiteralImm(
MVT::f64);
361 bool isSSrcF16()
const {
362 return isSCSrcB16() || isLiteralImm(
MVT::f16);
365 bool isVCSrcB32()
const {
366 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID,
MVT::i32);
369 bool isVCSrcB64()
const {
370 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID,
MVT::i64);
373 bool isVCSrcB16()
const {
374 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID,
MVT::i16);
377 bool isVCSrcF32()
const {
378 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID,
MVT::f32);
381 bool isVCSrcF64()
const {
382 return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID,
MVT::f64);
385 bool isVCSrcF16()
const {
386 return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID,
MVT::f16);
389 bool isVSrcB32()
const {
390 return isVCSrcF32() || isLiteralImm(
MVT::i32);
393 bool isVSrcB64()
const {
394 return isVCSrcF64() || isLiteralImm(
MVT::i64);
397 bool isVSrcB16()
const {
398 return isVCSrcF16() || isLiteralImm(
MVT::i16);
401 bool isVSrcF32()
const {
402 return isVCSrcF32() || isLiteralImm(
MVT::f32);
405 bool isVSrcF64()
const {
406 return isVCSrcF64() || isLiteralImm(
MVT::f64);
409 bool isVSrcF16()
const {
410 return isVCSrcF16() || isLiteralImm(
MVT::f16);
413 bool isKImmFP32()
const {
417 bool isKImmFP16()
const {
421 bool isMem()
const override {
425 bool isExpr()
const {
426 return Kind == Expression;
429 bool isSoppBrTarget()
const {
430 return isExpr() || isImm();
433 bool isSWaitCnt()
const;
434 bool isHwreg()
const;
435 bool isSendMsg()
const;
436 bool isSMRDOffset8()
const;
437 bool isSMRDOffset20()
const;
438 bool isSMRDLiteralOffset()
const;
439 bool isDPPCtrl()
const;
440 bool isGPRIdxMode()
const;
451 if (
Kind == Expression)
452 return getExpressionAsToken();
457 int64_t getImm()
const {
462 enum ImmTy getImmTy()
const {
467 unsigned getReg()
const override {
471 SMLoc getStartLoc()
const override {
475 SMLoc getEndLoc()
const override {
479 Modifiers getModifiers()
const {
480 assert(isRegKind() || isImmTy(ImmTyNone));
481 return isRegKind() ?
Reg.Mods : Imm.Mods;
484 void setModifiers(Modifiers Mods) {
485 assert(isRegKind() || isImmTy(ImmTyNone));
492 bool hasModifiers()
const {
493 return getModifiers().hasModifiers();
496 bool hasFPModifiers()
const {
497 return getModifiers().hasFPModifiers();
500 bool hasIntModifiers()
const {
501 return getModifiers().hasIntModifiers();
504 void addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers =
true)
const;
506 void addLiteralImmOperand(
MCInst &Inst, int64_t Val)
const;
508 template <
unsigned Bitw
idth>
509 void addKImmFPOperands(
MCInst &Inst,
unsigned N)
const;
511 void addKImmFP16Operands(
MCInst &Inst,
unsigned N)
const {
512 addKImmFPOperands<16>(Inst,
N);
515 void addKImmFP32Operands(
MCInst &Inst,
unsigned N)
const {
516 addKImmFPOperands<32>(Inst,
N);
519 void addRegOperands(
MCInst &Inst,
unsigned N)
const;
521 void addRegOrImmOperands(
MCInst &Inst,
unsigned N)
const {
523 addRegOperands(Inst, N);
527 addImmOperands(Inst, N);
530 void addRegOrImmWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
531 Modifiers Mods = getModifiers();
534 addRegOperands(Inst, N);
536 addImmOperands(Inst, N,
false);
540 void addRegOrImmWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
541 assert(!hasIntModifiers());
542 addRegOrImmWithInputModsOperands(Inst, N);
545 void addRegOrImmWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
546 assert(!hasFPModifiers());
547 addRegOrImmWithInputModsOperands(Inst, N);
550 void addRegWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
551 Modifiers Mods = getModifiers();
554 addRegOperands(Inst, N);
557 void addRegWithFPInputModsOperands(
MCInst &Inst,
unsigned N)
const {
558 assert(!hasIntModifiers());
559 addRegWithInputModsOperands(Inst, N);
562 void addRegWithIntInputModsOperands(
MCInst &Inst,
unsigned N)
const {
563 assert(!hasFPModifiers());
564 addRegWithInputModsOperands(Inst, N);
567 void addSoppBrTargetOperands(
MCInst &Inst,
unsigned N)
const {
569 addImmOperands(Inst, N);
578 case ImmTyNone: OS <<
"None";
break;
579 case ImmTyGDS: OS <<
"GDS";
break;
580 case ImmTyOffen: OS <<
"Offen";
break;
581 case ImmTyIdxen: OS <<
"Idxen";
break;
582 case ImmTyAddr64: OS <<
"Addr64";
break;
583 case ImmTyOffset: OS <<
"Offset";
break;
584 case ImmTyOffset0: OS <<
"Offset0";
break;
585 case ImmTyOffset1: OS <<
"Offset1";
break;
586 case ImmTyGLC: OS <<
"GLC";
break;
587 case ImmTySLC: OS <<
"SLC";
break;
588 case ImmTyTFE: OS <<
"TFE";
break;
589 case ImmTyClampSI: OS <<
"ClampSI";
break;
590 case ImmTyOModSI: OS <<
"OModSI";
break;
591 case ImmTyDppCtrl: OS <<
"DppCtrl";
break;
592 case ImmTyDppRowMask: OS <<
"DppRowMask";
break;
593 case ImmTyDppBankMask: OS <<
"DppBankMask";
break;
594 case ImmTyDppBoundCtrl: OS <<
"DppBoundCtrl";
break;
595 case ImmTySdwaDstSel: OS <<
"SdwaDstSel";
break;
596 case ImmTySdwaSrc0Sel: OS <<
"SdwaSrc0Sel";
break;
597 case ImmTySdwaSrc1Sel: OS <<
"SdwaSrc1Sel";
break;
598 case ImmTySdwaDstUnused: OS <<
"SdwaDstUnused";
break;
599 case ImmTyDMask: OS <<
"DMask";
break;
600 case ImmTyUNorm: OS <<
"UNorm";
break;
601 case ImmTyDA: OS <<
"DA";
break;
602 case ImmTyR128: OS <<
"R128";
break;
603 case ImmTyLWE: OS <<
"LWE";
break;
604 case ImmTyOff: OS <<
"Off";
break;
605 case ImmTyExpTgt: OS <<
"ExpTgt";
break;
606 case ImmTyExpCompr: OS <<
"ExpCompr";
break;
607 case ImmTyExpVM: OS <<
"ExpVM";
break;
608 case ImmTyHwreg: OS <<
"Hwreg";
break;
609 case ImmTySendMsg: OS <<
"SendMsg";
break;
610 case ImmTyInterpSlot: OS <<
"InterpSlot";
break;
611 case ImmTyInterpAttr: OS <<
"InterpAttr";
break;
612 case ImmTyAttrChan: OS <<
"AttrChan";
break;
619 OS <<
"<register " <<
getReg() <<
" mods: " <<
Reg.Mods <<
'>';
622 OS <<
'<' << getImm();
623 if (getImmTy() != ImmTyNone) {
624 OS <<
" type: "; printImmTy(OS, getImmTy());
626 OS <<
" mods: " << Imm.Mods <<
'>';
632 OS <<
"<expr " << *Expr << '>
';
637 static AMDGPUOperand::Ptr CreateImm(const AMDGPUAsmParser *AsmParser,
638 int64_t Val, SMLoc Loc,
639 enum ImmTy Type = ImmTyNone,
640 bool IsFPImm = false) {
641 auto Op = llvm::make_unique<AMDGPUOperand>(Immediate, AsmParser);
643 Op->Imm.IsFPImm = IsFPImm;
645 Op->Imm.Mods = Modifiers();
651 static AMDGPUOperand::Ptr CreateToken(const AMDGPUAsmParser *AsmParser,
652 StringRef Str, SMLoc Loc,
653 bool HasExplicitEncodingSize = true) {
654 auto Res = llvm::make_unique<AMDGPUOperand>(Token, AsmParser);
655 Res->Tok.Data = Str.data();
656 Res->Tok.Length = Str.size();
662 static AMDGPUOperand::Ptr CreateReg(const AMDGPUAsmParser *AsmParser,
663 unsigned RegNo, SMLoc S,
666 auto Op = llvm::make_unique<AMDGPUOperand>(Register, AsmParser);
667 Op->Reg.RegNo = RegNo;
668 Op->Reg.Mods = Modifiers();
669 Op->Reg.IsForcedVOP3 = ForceVOP3;
675 static AMDGPUOperand::Ptr CreateExpr(const AMDGPUAsmParser *AsmParser,
676 const class MCExpr *Expr, SMLoc S) {
677 auto Op = llvm::make_unique<AMDGPUOperand>(Expression, AsmParser);
685 raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods) {
686 OS << "abs:" << Mods.Abs << " neg: " << Mods.Neg << " sext:" << Mods.Sext;
690 //===----------------------------------------------------------------------===//
692 //===----------------------------------------------------------------------===//
694 // Holds info related to the current kernel, e.g. count of SGPRs used.
695 // Kernel scope begins at .amdgpu_hsa_kernel directive, ends at next
696 // .amdgpu_hsa_kernel or at EOF.
697 class KernelScopeInfo {
698 int SgprIndexUnusedMin;
699 int VgprIndexUnusedMin;
702 void usesSgprAt(int i) {
703 if (i >= SgprIndexUnusedMin) {
704 SgprIndexUnusedMin = ++i;
706 MCSymbol * const Sym = Ctx->getOrCreateSymbol(Twine(".kernel.sgpr_count"));
707 Sym->setVariableValue(MCConstantExpr::create(SgprIndexUnusedMin, *Ctx));
711 void usesVgprAt(int i) {
712 if (i >= VgprIndexUnusedMin) {
713 VgprIndexUnusedMin = ++i;
715 MCSymbol * const Sym = Ctx->getOrCreateSymbol(Twine(".kernel.vgpr_count"));
716 Sym->setVariableValue(MCConstantExpr::create(VgprIndexUnusedMin, *Ctx));
721 KernelScopeInfo() : SgprIndexUnusedMin(-1), VgprIndexUnusedMin(-1), Ctx(nullptr)
723 void initialize(MCContext &Context) {
725 usesSgprAt(SgprIndexUnusedMin = -1);
726 usesVgprAt(VgprIndexUnusedMin = -1);
728 void usesRegister(RegisterKind RegKind, unsigned DwordRegIndex, unsigned RegWidth) {
730 case IS_SGPR: usesSgprAt(DwordRegIndex + RegWidth - 1); break;
731 case IS_VGPR: usesVgprAt(DwordRegIndex + RegWidth - 1); break;
737 class AMDGPUAsmParser : public MCTargetAsmParser {
738 const MCInstrInfo &MII;
741 unsigned ForcedEncodingSize;
744 KernelScopeInfo KernelScope;
749 #define GET_ASSEMBLER_HEADER
750 #include "AMDGPUGenAsmMatcher.inc"
755 bool ParseAsAbsoluteExpression(uint32_t &Ret);
756 bool ParseDirectiveMajorMinor(uint32_t &Major, uint32_t &Minor);
757 bool ParseDirectiveHSACodeObjectVersion();
758 bool ParseDirectiveHSACodeObjectISA();
759 bool ParseDirectiveRuntimeMetadata();
760 bool ParseAMDKernelCodeTValue(StringRef ID, amd_kernel_code_t &Header);
761 bool ParseDirectiveAMDKernelCodeT();
762 bool ParseSectionDirectiveHSAText();
763 bool subtargetHasRegister(const MCRegisterInfo &MRI, unsigned RegNo) const;
764 bool ParseDirectiveAMDGPUHsaKernel();
765 bool ParseDirectiveAMDGPUHsaModuleGlobal();
766 bool ParseDirectiveAMDGPUHsaProgramGlobal();
767 bool ParseSectionDirectiveHSADataGlobalAgent();
768 bool ParseSectionDirectiveHSADataGlobalProgram();
769 bool ParseSectionDirectiveHSARodataReadonlyAgent();
770 bool AddNextRegisterToList(unsigned& Reg, unsigned& RegWidth, RegisterKind RegKind, unsigned Reg1, unsigned RegNum);
771 bool ParseAMDGPURegister(RegisterKind& RegKind, unsigned& Reg, unsigned& RegNum, unsigned& RegWidth, unsigned *DwordRegIndex);
772 void cvtMubufImpl(MCInst &Inst, const OperandVector &Operands, bool IsAtomic, bool IsAtomicReturn);
775 enum AMDGPUMatchResultTy {
776 Match_PreferE32 = FIRST_TARGET_MATCH_RESULT_TY
779 AMDGPUAsmParser(const MCSubtargetInfo &STI, MCAsmParser &_Parser,
780 const MCInstrInfo &MII,
781 const MCTargetOptions &Options)
782 : MCTargetAsmParser(Options, STI), MII(MII), Parser(_Parser),
783 ForcedEncodingSize(0),
786 MCAsmParserExtension::Initialize(Parser);
788 if (getSTI().getFeatureBits().none()) {
789 // Set default features.
790 copySTI().ToggleFeature("SOUTHERN_ISLANDS");
793 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
796 // TODO: make those pre-defined variables read-only.
797 // Currently there is none suitable machinery in the core llvm-mc for this.
798 // MCSymbol::isRedefinable is intended for another purpose, and
799 // AsmParser::parseDirectiveSet() cannot be specialized for specific target.
800 AMDGPU::IsaVersion Isa = AMDGPU::getIsaVersion(getSTI().getFeatureBits());
801 MCContext &Ctx = getContext();
802 MCSymbol *Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_major"));
803 Sym->setVariableValue(MCConstantExpr::create(Isa.Major, Ctx));
804 Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_minor"));
805 Sym->setVariableValue(MCConstantExpr::create(Isa.Minor, Ctx));
806 Sym = Ctx.getOrCreateSymbol(Twine(".option.machine_version_stepping"));
807 Sym->setVariableValue(MCConstantExpr::create(Isa.Stepping, Ctx));
809 KernelScope.initialize(getContext());
813 return AMDGPU::isSI(getSTI());
817 return AMDGPU::isCI(getSTI());
821 return AMDGPU::isVI(getSTI());
824 bool hasInv2PiInlineImm() const {
825 return getSTI().getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
828 bool hasSGPR102_SGPR103() const {
832 AMDGPUTargetStreamer &getTargetStreamer() {
833 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
834 return static_cast<AMDGPUTargetStreamer &>(TS);
837 const MCRegisterInfo *getMRI() const {
838 // We need this const_cast because for some reason getContext() is not const
840 return const_cast<AMDGPUAsmParser*>(this)->getContext().getRegisterInfo();
843 const MCInstrInfo *getMII() const {
847 void setForcedEncodingSize(unsigned Size) { ForcedEncodingSize = Size; }
848 void setForcedDPP(bool ForceDPP_) { ForcedDPP = ForceDPP_; }
849 void setForcedSDWA(bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
851 unsigned getForcedEncodingSize() const { return ForcedEncodingSize; }
852 bool isForcedVOP3() const { return ForcedEncodingSize == 64; }
853 bool isForcedDPP() const { return ForcedDPP; }
854 bool isForcedSDWA() const { return ForcedSDWA; }
855 ArrayRef<unsigned> getMatchedVariants() const;
857 std::unique_ptr<AMDGPUOperand> parseRegister();
858 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
859 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
860 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
861 unsigned Kind) override;
862 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
863 OperandVector &Operands, MCStreamer &Out,
865 bool MatchingInlineAsm) override;
866 bool ParseDirective(AsmToken DirectiveID) override;
867 OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Mnemonic);
868 StringRef parseMnemonicSuffix(StringRef Name);
869 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
870 SMLoc NameLoc, OperandVector &Operands) override;
871 //bool ProcessInstruction(MCInst &Inst);
873 OperandMatchResultTy parseIntWithPrefix(const char *Prefix, int64_t &Int);
875 parseIntWithPrefix(const char *Prefix, OperandVector &Operands,
876 enum AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
877 bool (*ConvertResult)(int64_t &) = nullptr);
879 parseNamedBit(const char *Name, OperandVector &Operands,
880 enum AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
881 OperandMatchResultTy parseStringWithPrefix(StringRef Prefix,
884 OperandMatchResultTy parseImm(OperandVector &Operands);
885 OperandMatchResultTy parseReg(OperandVector &Operands);
886 OperandMatchResultTy parseRegOrImm(OperandVector &Operands);
887 OperandMatchResultTy parseRegOrImmWithFPInputMods(OperandVector &Operands, bool AllowImm = true);
888 OperandMatchResultTy parseRegOrImmWithIntInputMods(OperandVector &Operands, bool AllowImm = true);
889 OperandMatchResultTy parseRegWithFPInputMods(OperandVector &Operands);
890 OperandMatchResultTy parseRegWithIntInputMods(OperandVector &Operands);
891 OperandMatchResultTy parseVReg32OrOff(OperandVector &Operands);
893 void cvtDSOffset01(MCInst &Inst, const OperandVector &Operands);
894 void cvtDS(MCInst &Inst, const OperandVector &Operands);
895 void cvtExp(MCInst &Inst, const OperandVector &Operands);
897 bool parseCnt(int64_t &IntVal);
898 OperandMatchResultTy parseSWaitCntOps(OperandVector &Operands);
899 OperandMatchResultTy parseHwreg(OperandVector &Operands);
902 struct OperandInfoTy {
905 OperandInfoTy(int64_t Id_) : Id(Id_), IsSymbolic(false) { }
908 bool parseSendMsgConstruct(OperandInfoTy &Msg, OperandInfoTy &Operation, int64_t &StreamId);
909 bool parseHwregConstruct(OperandInfoTy &HwReg, int64_t &Offset, int64_t &Width);
912 OperandMatchResultTy parseExpTgtImpl(StringRef Str, uint8_t &Val);
915 OperandMatchResultTy parseOptionalOperand(OperandVector &Operands);
917 OperandMatchResultTy parseExpTgt(OperandVector &Operands);
918 OperandMatchResultTy parseSendMsgOp(OperandVector &Operands);
919 OperandMatchResultTy parseInterpSlot(OperandVector &Operands);
920 OperandMatchResultTy parseInterpAttr(OperandVector &Operands);
921 OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands);
923 void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, false); }
924 void cvtMubufAtomic(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, false); }
925 void cvtMubufAtomicReturn(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, true); }
926 AMDGPUOperand::Ptr defaultGLC() const;
927 AMDGPUOperand::Ptr defaultSLC() const;
928 AMDGPUOperand::Ptr defaultTFE() const;
930 AMDGPUOperand::Ptr defaultDMask() const;
931 AMDGPUOperand::Ptr defaultUNorm() const;
932 AMDGPUOperand::Ptr defaultDA() const;
933 AMDGPUOperand::Ptr defaultR128() const;
934 AMDGPUOperand::Ptr defaultLWE() const;
935 AMDGPUOperand::Ptr defaultSMRDOffset8() const;
936 AMDGPUOperand::Ptr defaultSMRDOffset20() const;
937 AMDGPUOperand::Ptr defaultSMRDLiteralOffset() const;
939 OperandMatchResultTy parseOModOperand(OperandVector &Operands);
941 void cvtId(MCInst &Inst, const OperandVector &Operands);
942 void cvtVOP3_2_mod(MCInst &Inst, const OperandVector &Operands);
943 void cvtVOP3(MCInst &Inst, const OperandVector &Operands);
945 void cvtMIMG(MCInst &Inst, const OperandVector &Operands);
946 void cvtMIMGAtomic(MCInst &Inst, const OperandVector &Operands);
948 OperandMatchResultTy parseDPPCtrl(OperandVector &Operands);
949 AMDGPUOperand::Ptr defaultRowMask() const;
950 AMDGPUOperand::Ptr defaultBankMask() const;
951 AMDGPUOperand::Ptr defaultBoundCtrl() const;
952 void cvtDPP(MCInst &Inst, const OperandVector &Operands);
954 OperandMatchResultTy parseSDWASel(OperandVector &Operands, StringRef Prefix,
955 AMDGPUOperand::ImmTy Type);
956 OperandMatchResultTy parseSDWADstUnused(OperandVector &Operands);
957 void cvtSdwaVOP1(MCInst &Inst, const OperandVector &Operands);
958 void cvtSdwaVOP2(MCInst &Inst, const OperandVector &Operands);
959 void cvtSdwaVOPC(MCInst &Inst, const OperandVector &Operands);
960 void cvtSDWA(MCInst &Inst, const OperandVector &Operands,
961 uint64_t BasicInstType);
964 struct OptionalOperand {
966 AMDGPUOperand::ImmTy Type;
968 bool (*ConvertResult)(int64_t&);
971 } // end anonymous namespace
973 // May be called with integer type with equivalent bitwidth.
974 static const fltSemantics *getFltSemantics(unsigned Size) {
977 return &APFloat::IEEEsingle();
979 return &APFloat::IEEEdouble();
981 return &APFloat::IEEEhalf();
983 llvm_unreachable("unsupported fp type");
987 static const fltSemantics *getFltSemantics(MVT VT) {
988 return getFltSemantics(VT.getSizeInBits() / 8);
991 //===----------------------------------------------------------------------===//
993 //===----------------------------------------------------------------------===//
995 static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT) {
998 // Convert literal to single precision
999 APFloat::opStatus Status = FPLiteral.convert(*getFltSemantics(VT),
1000 APFloat::rmNearestTiesToEven,
1002 // We allow precision lost but not overflow or underflow
1003 if (Status != APFloat::opOK &&
1005 ((Status & APFloat::opOverflow) != 0 ||
1006 (Status & APFloat::opUnderflow) != 0)) {
1013 bool AMDGPUOperand::isInlinableImm(MVT type) const {
1014 if (!isImmTy(ImmTyNone)) {
1015 // Only plain immediates are inlinable (e.g. "clamp" attribute is not)
1018 // TODO: We should avoid using host float here. It would be better to
1019 // check the float bit values which is what a few other places do.
1020 // We've had bot failures before due to weird NaN support on mips hosts.
1027 AsmParser->hasInv2PiInlineImm());
1036 static_cast<int32_t>(FPLiteral.bitcastToAPInt().getZExtValue()),
1037 AsmParser->hasInv2PiInlineImm());
1044 AsmParser->hasInv2PiInlineImm());
1049 static_cast<int16_t>(
Literal.getLoBits(16).getSExtValue()),
1050 AsmParser->hasInv2PiInlineImm());
1054 static_cast<int32_t>(
Literal.getLoBits(32).getZExtValue()),
1055 AsmParser->hasInv2PiInlineImm());
1058 bool AMDGPUOperand::isLiteralImm(
MVT type)
const {
1060 if (!isImmTy(ImmTyNone)) {
1092 bool AMDGPUOperand::isRegClass(
unsigned RCID)
const {
1093 return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(
getReg());
1096 void AMDGPUOperand::addImmOperands(
MCInst &Inst,
unsigned N,
bool ApplyModifiers)
const {
1097 int64_t Val = Imm.Val;
1098 if (isImmTy(ImmTyNone) && ApplyModifiers && Imm.Mods.hasFPModifiers() && Imm.Mods.Neg) {
1103 Val =
F.bitcastToAPInt().getZExtValue();
1111 addLiteralImmOperand(Inst, Val);
1117 void AMDGPUOperand::addLiteralImmOperand(
MCInst &Inst, int64_t Val)
const {
1118 const auto& InstDesc = AsmParser->getMII()->get(Inst.
getOpcode());
1131 AsmParser->hasInv2PiInlineImm())) {
1139 if (
Literal.getLoBits(32) != 0) {
1140 const_cast<AMDGPUAsmParser *
>(AsmParser)->Warning(Inst.
getLoc(),
1141 "Can't encode literal as exact 64-bit floating-point operand. "
1142 "Low 32-bits will be set to zero");
1180 AsmParser->hasInv2PiInlineImm())) {
1190 AsmParser->hasInv2PiInlineImm())) {
1201 AsmParser->hasInv2PiInlineImm())) {
1214 template <
unsigned Bitw
idth>
1215 void AMDGPUOperand::addKImmFPOperands(
MCInst &Inst,
unsigned N)
const {
1231 void AMDGPUOperand::addRegOperands(
MCInst &Inst,
unsigned N)
const {
1240 if (Is == IS_VGPR) {
1243 case 1:
return AMDGPU::VGPR_32RegClassID;
1244 case 2:
return AMDGPU::VReg_64RegClassID;
1245 case 3:
return AMDGPU::VReg_96RegClassID;
1246 case 4:
return AMDGPU::VReg_128RegClassID;
1247 case 8:
return AMDGPU::VReg_256RegClassID;
1248 case 16:
return AMDGPU::VReg_512RegClassID;
1250 }
else if (Is == IS_TTMP) {
1253 case 1:
return AMDGPU::TTMP_32RegClassID;
1254 case 2:
return AMDGPU::TTMP_64RegClassID;
1255 case 4:
return AMDGPU::TTMP_128RegClassID;
1257 }
else if (Is == IS_SGPR) {
1260 case 1:
return AMDGPU::SGPR_32RegClassID;
1261 case 2:
return AMDGPU::SGPR_64RegClassID;
1262 case 4:
return AMDGPU::SGPR_128RegClassID;
1263 case 8:
return AMDGPU::SReg_256RegClassID;
1264 case 16:
return AMDGPU::SReg_512RegClassID;
1272 .Case(
"exec", AMDGPU::EXEC)
1273 .
Case(
"vcc", AMDGPU::VCC)
1274 .
Case(
"flat_scratch", AMDGPU::FLAT_SCR)
1275 .
Case(
"m0", AMDGPU::M0)
1276 .
Case(
"scc", AMDGPU::SCC)
1277 .
Case(
"tba", AMDGPU::TBA)
1278 .
Case(
"tma", AMDGPU::TMA)
1279 .
Case(
"flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
1280 .
Case(
"flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
1281 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
1282 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
1283 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
1284 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
1285 .
Case(
"tma_lo", AMDGPU::TMA_LO)
1286 .
Case(
"tma_hi", AMDGPU::TMA_HI)
1287 .
Case(
"tba_lo", AMDGPU::TBA_LO)
1288 .
Case(
"tba_hi", AMDGPU::TBA_HI)
1292 bool AMDGPUAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc) {
1293 auto R = parseRegister();
1294 if (!R)
return true;
1296 RegNo = R->getReg();
1297 StartLoc = R->getStartLoc();
1298 EndLoc = R->getEndLoc();
1302 bool AMDGPUAsmParser::AddNextRegisterToList(
unsigned&
Reg,
unsigned& RegWidth,
RegisterKind RegKind,
unsigned Reg1,
unsigned RegNum)
1306 if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) { Reg = AMDGPU::EXEC; RegWidth = 2;
return true; }
1307 if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) { Reg = AMDGPU::FLAT_SCR; RegWidth = 2;
return true; }
1308 if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) { Reg = AMDGPU::VCC; RegWidth = 2;
return true; }
1309 if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) { Reg = AMDGPU::TBA; RegWidth = 2;
return true; }
1310 if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) { Reg = AMDGPU::TMA; RegWidth = 2;
return true; }
1315 if (Reg1 != Reg + RegWidth) {
return false; }
1323 bool AMDGPUAsmParser::ParseAMDGPURegister(
RegisterKind& RegKind,
unsigned& Reg,
unsigned& RegNum,
unsigned& RegWidth,
unsigned *DwordRegIndex)
1325 if (DwordRegIndex) { *DwordRegIndex = 0; }
1328 StringRef RegName = Parser.getTok().getString();
1331 RegKind = IS_SPECIAL;
1333 unsigned RegNumIndex = 0;
1334 if (RegName[0] ==
'v') {
1337 }
else if (RegName[0] ==
's') {
1341 RegNumIndex = strlen(
"ttmp");
1346 if (RegName.
size() > RegNumIndex) {
1355 int64_t RegLo, RegHi;
1360 if (getParser().parseAbsoluteExpression(RegLo))
1371 if (getParser().parseAbsoluteExpression(RegHi))
1379 RegWidth = (RegHi - RegLo) + 1;
1385 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth,
nullptr))
1390 unsigned Reg1, RegNum1, RegWidth1;
1397 }
else if (ParseAMDGPURegister(RegKind1, Reg1, RegNum1, RegWidth1,
nullptr)) {
1398 if (RegWidth1 != 1) {
1401 if (RegKind1 != RegKind) {
1404 if (!AddNextRegisterToList(Reg, RegWidth, RegKind1, Reg1, RegNum1)) {
1424 if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
1428 if (RegNum % Size != 0)
1430 if (DwordRegIndex) { *DwordRegIndex = RegNum; }
1431 RegNum = RegNum / Size;
1446 if (!subtargetHasRegister(*TRI, Reg))
1451 std::unique_ptr<AMDGPUOperand> AMDGPUAsmParser::parseRegister() {
1452 const auto &Tok = Parser.getTok();
1453 SMLoc StartLoc = Tok.getLoc();
1454 SMLoc EndLoc = Tok.getEndLoc();
1456 unsigned Reg, RegNum, RegWidth, DwordRegIndex;
1458 if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, &DwordRegIndex)) {
1461 KernelScope.usesRegister(RegKind, DwordRegIndex, RegWidth);
1462 return AMDGPUOperand::CreateReg(
this, Reg, StartLoc, EndLoc,
false);
1474 SMLoc S = Parser.getTok().getLoc();
1475 switch(getLexer().getKind()) {
1478 if (getParser().parseAbsoluteExpression(IntVal))
1482 Operands.
push_back(AMDGPUOperand::CreateImm(
this, IntVal, S));
1487 if (getParser().parseAbsoluteExpression(IntVal))
1494 AMDGPUOperand::CreateImm(
this,
F.bitcastToAPInt().getZExtValue(), S,
1495 AMDGPUOperand::ImmTyNone,
true));
1505 if (
auto R = parseRegister()) {
1507 R->Reg.IsForcedVOP3 = isForcedVOP3();
1516 auto res = parseImm(Operands);
1521 return parseReg(Operands);
1525 AMDGPUAsmParser::parseRegOrImmWithFPInputMods(
OperandVector &Operands,
bool AllowImm) {
1529 bool Negate =
false, Abs =
false, Abs2 =
false;
1540 Error(Parser.getTok().getLoc(),
"expected left paren after abs");
1548 Error(Parser.getTok().getLoc(),
"expected register or immediate");
1557 Res = parseRegOrImm(Operands);
1559 Res = parseReg(Operands);
1565 AMDGPUOperand::Modifiers Mods;
1571 Error(Parser.getTok().getLoc(),
"expected vertical bar");
1579 Error(Parser.getTok().getLoc(),
"expected closing parentheses");
1586 if (Mods.hasFPModifiers()) {
1587 AMDGPUOperand &
Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
1588 Op.setModifiers(Mods);
1594 AMDGPUAsmParser::parseRegOrImmWithIntInputMods(
OperandVector &Operands,
bool AllowImm) {
1601 Error(Parser.getTok().getLoc(),
"expected left paren after sext");
1609 Res = parseRegOrImm(Operands);
1611 Res = parseReg(Operands);
1617 AMDGPUOperand::Modifiers Mods;
1620 Error(Parser.getTok().getLoc(),
"expected closing parentheses");
1627 if (Mods.hasIntModifiers()) {
1628 AMDGPUOperand &Op =
static_cast<AMDGPUOperand &
>(*Operands.
back());
1629 Op.setModifiers(Mods);
1636 AMDGPUAsmParser::parseRegWithFPInputMods(
OperandVector &Operands) {
1637 return parseRegOrImmWithFPInputMods(Operands,
false);
1641 AMDGPUAsmParser::parseRegWithIntInputMods(
OperandVector &Operands) {
1642 return parseRegOrImmWithIntInputMods(Operands,
false);
1646 std::unique_ptr<AMDGPUOperand> Reg = parseRegister();
1652 const AsmToken &Tok = Parser.getTok();
1655 AMDGPUOperand::ImmTyOff,
false));
1663 unsigned AMDGPUAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1665 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
1671 return Match_InvalidOperand;
1673 if ((TSFlags & SIInstrFlags::VOP3) &&
1675 getForcedEncodingSize() != 64)
1676 return Match_PreferE32;
1678 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
1679 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
1685 return Match_InvalidOperand;
1689 return Match_Success;
1694 if (getForcedEncodingSize() == 32) {
1699 if (isForcedVOP3()) {
1704 if (isForcedSDWA()) {
1709 if (isForcedDPP()) {
1714 static const unsigned Variants[] = {
1722 bool AMDGPUAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1726 bool MatchingInlineAsm) {
1728 unsigned Result = Match_Success;
1729 for (
auto Variant : getMatchedVariants()) {
1731 auto R = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
1736 if ((R == Match_Success) ||
1737 (R == Match_PreferE32) ||
1738 (R == Match_MissingFeature && Result != Match_PreferE32) ||
1739 (R == Match_InvalidOperand && Result != Match_MissingFeature
1740 && Result != Match_PreferE32) ||
1741 (R == Match_MnemonicFail && Result != Match_InvalidOperand
1742 && Result != Match_MissingFeature
1743 && Result != Match_PreferE32)) {
1747 if (R == Match_Success)
1758 case Match_MissingFeature:
1759 return Error(IDLoc,
"instruction not supported on this GPU");
1761 case Match_MnemonicFail:
1762 return Error(IDLoc,
"unrecognized instruction mnemonic");
1764 case Match_InvalidOperand: {
1765 SMLoc ErrorLoc = IDLoc;
1766 if (ErrorInfo != ~0ULL) {
1767 if (ErrorInfo >= Operands.
size()) {
1768 return Error(IDLoc,
"too few operands for instruction");
1770 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
1771 if (ErrorLoc ==
SMLoc())
1774 return Error(ErrorLoc,
"invalid operand for instruction");
1777 case Match_PreferE32:
1778 return Error(IDLoc,
"internal error: instruction without _e64 suffix "
1779 "should be encoded as e32");
1784 bool AMDGPUAsmParser::ParseAsAbsoluteExpression(
uint32_t &
Ret) {
1789 if (getParser().parseAbsoluteExpression(Tmp)) {
1797 bool AMDGPUAsmParser::ParseDirectiveMajorMinor(
uint32_t &Major,
1799 if (ParseAsAbsoluteExpression(Major))
1800 return TokError(
"invalid major version");
1803 return TokError(
"minor version number required, comma expected");
1806 if (ParseAsAbsoluteExpression(Minor))
1807 return TokError(
"invalid minor version");
1812 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectVersion() {
1817 if (ParseDirectiveMajorMinor(Major, Minor))
1820 getTargetStreamer().EmitDirectiveHSACodeObjectVersion(Major, Minor);
1824 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectISA() {
1835 getTargetStreamer().EmitDirectiveHSACodeObjectISA(Isa.Major, Isa.Minor,
1841 if (ParseDirectiveMajorMinor(Major, Minor))
1845 return TokError(
"stepping version number required, comma expected");
1848 if (ParseAsAbsoluteExpression(Stepping))
1849 return TokError(
"invalid stepping version");
1852 return TokError(
"vendor name required, comma expected");
1856 return TokError(
"invalid vendor name");
1858 VendorName = getLexer().getTok().getStringContents();
1862 return TokError(
"arch name required, comma expected");
1866 return TokError(
"invalid arch name");
1868 ArchName = getLexer().getTok().getStringContents();
1871 getTargetStreamer().EmitDirectiveHSACodeObjectISA(Major, Minor, Stepping,
1872 VendorName, ArchName);
1876 bool AMDGPUAsmParser::ParseDirectiveRuntimeMetadata() {
1880 getLexer().setSkipSpace(
false);
1882 bool FoundEnd =
false;
1890 StringRef ID = getLexer().getTok().getIdentifier();
1891 if (ID ==
".end_amdgpu_runtime_metadata") {
1898 MS << Parser.parseStringToEndOfStatement()
1899 << getContext().getAsmInfo()->getSeparatorString();
1901 Parser.eatToEndOfStatement();
1904 getLexer().setSkipSpace(
true);
1907 return TokError(
"expected directive .end_amdgpu_runtime_metadata not found");
1911 getTargetStreamer().EmitRuntimeMetadata(Metadata);
1916 bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(
StringRef ID,
1921 return TokError(Err.str());
1927 bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
1938 return TokError(
"expected value identifier or .end_amd_kernel_code_t");
1940 StringRef ID = getLexer().getTok().getIdentifier();
1943 if (ID ==
".end_amd_kernel_code_t")
1946 if (ParseAMDKernelCodeTValue(ID, Header))
1950 getTargetStreamer().EmitAMDKernelCodeT(Header);
1955 bool AMDGPUAsmParser::ParseSectionDirectiveHSAText() {
1956 getParser().getStreamer().SwitchSection(
1961 bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
1963 return TokError(
"expected symbol name");
1967 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
1970 KernelScope.initialize(getContext());
1974 bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaModuleGlobal() {
1976 return TokError(
"expected symbol name");
1978 StringRef GlobalName = Parser.getTok().getIdentifier();
1980 getTargetStreamer().EmitAMDGPUHsaModuleScopeGlobal(GlobalName);
1985 bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaProgramGlobal() {
1987 return TokError(
"expected symbol name");
1989 StringRef GlobalName = Parser.getTok().getIdentifier();
1991 getTargetStreamer().EmitAMDGPUHsaProgramScopeGlobal(GlobalName);
1996 bool AMDGPUAsmParser::ParseSectionDirectiveHSADataGlobalAgent() {
1997 getParser().getStreamer().SwitchSection(
2002 bool AMDGPUAsmParser::ParseSectionDirectiveHSADataGlobalProgram() {
2003 getParser().getStreamer().SwitchSection(
2008 bool AMDGPUAsmParser::ParseSectionDirectiveHSARodataReadonlyAgent() {
2009 getParser().getStreamer().SwitchSection(
2014 bool AMDGPUAsmParser::ParseDirective(
AsmToken DirectiveID) {
2017 if (IDVal ==
".hsa_code_object_version")
2018 return ParseDirectiveHSACodeObjectVersion();
2020 if (IDVal ==
".hsa_code_object_isa")
2021 return ParseDirectiveHSACodeObjectISA();
2023 if (IDVal ==
".amdgpu_runtime_metadata")
2024 return ParseDirectiveRuntimeMetadata();
2026 if (IDVal ==
".amd_kernel_code_t")
2027 return ParseDirectiveAMDKernelCodeT();
2029 if (IDVal ==
".hsatext")
2030 return ParseSectionDirectiveHSAText();
2032 if (IDVal ==
".amdgpu_hsa_kernel")
2033 return ParseDirectiveAMDGPUHsaKernel();
2035 if (IDVal ==
".amdgpu_hsa_module_global")
2036 return ParseDirectiveAMDGPUHsaModuleGlobal();
2038 if (IDVal ==
".amdgpu_hsa_program_global")
2039 return ParseDirectiveAMDGPUHsaProgramGlobal();
2041 if (IDVal ==
".hsadata_global_agent")
2042 return ParseSectionDirectiveHSADataGlobalAgent();
2044 if (IDVal ==
".hsadata_global_program")
2045 return ParseSectionDirectiveHSADataGlobalProgram();
2047 if (IDVal ==
".hsarodata_readonly_agent")
2048 return ParseSectionDirectiveHSARodataReadonlyAgent();
2054 unsigned RegNo)
const {
2061 case AMDGPU::FLAT_SCR:
2062 case AMDGPU::FLAT_SCR_LO:
2063 case AMDGPU::FLAT_SCR_HI:
2097 ResTy = parseRegOrImm(Operands);
2108 const auto &Tok = Parser.getTok();
2110 const MCExpr *Expr =
nullptr;
2111 if (!Parser.parseExpression(Expr)) {
2112 Operands.
push_back(AMDGPUOperand::CreateExpr(
this, Expr, S));
2125 setForcedEncodingSize(0);
2126 setForcedDPP(
false);
2127 setForcedSDWA(
false);
2130 setForcedEncodingSize(64);
2132 }
else if (Name.
endswith(
"_e32")) {
2133 setForcedEncodingSize(32);
2135 }
else if (Name.
endswith(
"_dpp")) {
2138 }
else if (Name.
endswith(
"_sdwa")) {
2139 setForcedSDWA(
true);
2149 Name = parseMnemonicSuffix(Name);
2150 Operands.
push_back(AMDGPUOperand::CreateToken(
this, Name, NameLoc));
2162 Error(getLexer().getLoc(),
"failed parsing operand.");
2168 Error(getLexer().getLoc(),
"not a valid operand.");
2184 AMDGPUAsmParser::parseIntWithPrefix(
const char *
Prefix, int64_t &Int) {
2185 switch(getLexer().getKind()) {
2188 StringRef Name = Parser.getTok().getString();
2189 if (!Name.
equals(Prefix)) {
2201 if (getParser().parseAbsoluteExpression(Int))
2210 AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
2211 enum AMDGPUOperand::ImmTy ImmTy,
2212 bool (*ConvertResult)(int64_t&)) {
2213 SMLoc S = Parser.getTok().getLoc();
2220 if (ConvertResult && !ConvertResult(Value)) {
2224 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Value, S, ImmTy));
2229 AMDGPUAsmParser::parseNamedBit(
const char *Name,
OperandVector &Operands,
2230 enum AMDGPUOperand::ImmTy ImmTy) {
2232 SMLoc S = Parser.getTok().getLoc();
2237 switch(getLexer().getKind()) {
2256 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Bit, S, ImmTy));
2263 OptionalImmIndexMap& OptionalIdx,
2264 enum AMDGPUOperand::ImmTy ImmT, int64_t Default = 0) {
2265 auto i = OptionalIdx.find(ImmT);
2266 if (
i != OptionalIdx.end()) {
2267 unsigned Idx =
i->second;
2268 ((AMDGPUOperand &)*Operands[Idx]).addImmOperands(Inst, 1);
2279 StringRef Tok = Parser.getTok().getString();
2280 if (Tok != Prefix) {
2294 Value = Parser.getTok().getString();
2302 void AMDGPUAsmParser::cvtDSOffset01(
MCInst &Inst,
2304 OptionalImmIndexMap OptionalIdx;
2306 for (
unsigned i = 1, e = Operands.
size();
i != e; ++
i) {
2307 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[
i]);
2311 Op.addRegOperands(Inst, 1);
2316 OptionalIdx[Op.getImmTy()] =
i;
2327 std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
2328 bool GDSOnly =
false;
2330 for (
unsigned i = 1, e = Operands.
size(); i != e; ++
i) {
2331 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
2335 Op.addRegOperands(Inst, 1);
2339 if (Op.isToken() && Op.getToken() ==
"gds") {
2345 OptionalIdx[Op.getImmTy()] =
i;
2358 OptionalImmIndexMap OptionalIdx;
2360 unsigned EnMask = 0;
2363 for (
unsigned i = 1, e = Operands.
size(); i != e; ++
i) {
2364 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
2368 EnMask |= (1 << SrcIdx);
2369 Op.addRegOperands(Inst, 1);
2380 if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
2381 Op.addImmOperands(Inst, 1);
2385 if (Op.isToken() && Op.getToken() ==
"done")
2389 OptionalIdx[Op.getImmTy()] =
i;
2402 bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
2403 StringRef CntName = Parser.getTok().getString();
2414 if (getParser().parseAbsoluteExpression(CntVal))
2425 if (CntName ==
"vmcnt")
2427 else if (CntName ==
"expcnt")
2429 else if (CntName ==
"lgkmcnt")
2438 AMDGPUAsmParser::parseSWaitCntOps(
OperandVector &Operands) {
2441 SMLoc S = Parser.getTok().getLoc();
2443 switch(getLexer().getKind()) {
2447 if (getParser().parseAbsoluteExpression(Waitcnt))
2453 if (parseCnt(Waitcnt))
2458 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Waitcnt, S));
2462 bool AMDGPUAsmParser::parseHwregConstruct(OperandInfoTy &HwReg, int64_t &
Offset, int64_t &Width) {
2463 using namespace llvm::AMDGPU::Hwreg;
2465 if (Parser.getTok().getString() !=
"hwreg")
2474 HwReg.IsSymbolic =
true;
2476 const StringRef tok = Parser.getTok().getString();
2485 HwReg.IsSymbolic =
false;
2488 if (getParser().parseAbsoluteExpression(HwReg.Id))
2504 if (getParser().parseAbsoluteExpression(Offset))
2513 if (getParser().parseAbsoluteExpression(Width))
2525 using namespace llvm::AMDGPU::Hwreg;
2527 int64_t Imm16Val = 0;
2528 SMLoc S = Parser.getTok().getLoc();
2530 switch(getLexer().getKind()) {
2534 if (getParser().parseAbsoluteExpression(Imm16Val))
2537 Error(S,
"invalid immediate: only 16-bit values are legal");
2547 if (parseHwregConstruct(HwReg, Offset, Width))
2549 if (HwReg.Id < 0 || !isUInt<ID_WIDTH_>(HwReg.Id)) {
2550 if (HwReg.IsSymbolic)
2551 Error(S,
"invalid symbolic name of hardware register");
2553 Error(S,
"invalid code of hardware register: only 6-bit values are legal");
2555 if (Offset < 0 || !isUInt<OFFSET_WIDTH_>(Offset))
2556 Error(S,
"invalid bit offset: only 5-bit values are legal");
2557 if ((Width-1) < 0 || !isUInt<WIDTH_M1_WIDTH_>(Width-1))
2558 Error(S,
"invalid bitfield width: only values from 1 to 32 are legal");
2563 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Imm16Val, S, AMDGPUOperand::ImmTyHwreg));
2567 bool AMDGPUOperand::isSWaitCnt()
const {
2571 bool AMDGPUOperand::isHwreg()
const {
2572 return isImmTy(ImmTyHwreg);
2575 bool AMDGPUAsmParser::parseSendMsgConstruct(OperandInfoTy &Msg, OperandInfoTy &Operation, int64_t &
StreamId) {
2576 using namespace llvm::AMDGPU::SendMsg;
2578 if (Parser.getTok().getString() !=
"sendmsg")
2587 Msg.IsSymbolic =
true;
2589 const std::string tok = Parser.getTok().getString();
2602 Msg.IsSymbolic =
false;
2605 if (getParser().parseAbsoluteExpression(Msg.Id))
2608 if (getParser().parseAbsoluteExpression(Msg.Id))
2628 Operation.IsSymbolic =
true;
2632 const StringRef Tok = Parser.getTok().getString();
2633 for (
int i = F; i <
L; ++
i) {
2641 Operation.IsSymbolic =
false;
2644 if (getParser().parseAbsoluteExpression(Operation.Id))
2661 if (getParser().parseAbsoluteExpression(StreamId))
2675 StringRef Str = Parser.getTok().getString();
2682 SMLoc S = Parser.getTok().getLoc();
2687 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Slot, S,
2688 AMDGPUOperand::ImmTyInterpSlot));
2696 StringRef Str = Parser.getTok().getString();
2716 SMLoc S = Parser.getTok().getLoc();
2719 Error(S,
"out of bounds attr");
2725 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Attr, S,
2726 AMDGPUOperand::ImmTyInterpAttr));
2727 Operands.
push_back(AMDGPUOperand::CreateImm(
this, AttrChan, SChan,
2728 AMDGPUOperand::ImmTyAttrChan));
2732 void AMDGPUAsmParser::errorExpTgt() {
2733 Error(Parser.getTok().getLoc(),
"invalid exp target");
2738 if (Str ==
"null") {
2797 StringRef Str = Parser.getTok().getString();
2799 auto Res = parseExpTgtImpl(Str, Val);
2803 SMLoc S = Parser.getTok().getLoc();
2806 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Val, S,
2807 AMDGPUOperand::ImmTyExpTgt));
2813 using namespace llvm::AMDGPU::SendMsg;
2815 int64_t Imm16Val = 0;
2816 SMLoc S = Parser.getTok().getLoc();
2818 switch(getLexer().getKind()) {
2823 if (getParser().parseAbsoluteExpression(Imm16Val))
2826 Error(S,
"invalid immediate: only 16-bit values are legal");
2835 if (parseSendMsgConstruct(Msg, Operation, StreamId))
2842 Error(S,
"invalid/unsupported symbolic name of message");
2844 Error(S,
"invalid/unsupported code of message");
2851 if (Operation.IsSymbolic)
2852 Error(S,
"invalid symbolic name of GS_OP");
2854 Error(S,
"invalid code of GS_OP: only 2-bit values are legal");
2859 Error(S,
"invalid GS_OP: NOP is for GS_DONE only");
2862 Imm16Val |= (Operation.Id <<
OP_SHIFT_);
2866 if (Operation.IsSymbolic)
2867 Error(S,
"invalid/unsupported symbolic name of SYSMSG_OP");
2869 Error(S,
"invalid/unsupported code of SYSMSG_OP");
2872 Imm16Val |= (Operation.Id <<
OP_SHIFT_);
2877 Error(S,
"invalid stream id: only 2-bit values are legal");
2886 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Imm16Val, S, AMDGPUOperand::ImmTySendMsg));
2890 bool AMDGPUOperand::isSendMsg()
const {
2891 return isImmTy(ImmTySendMsg);
2899 AMDGPUAsmParser::parseSOppBrTarget(
OperandVector &Operands) {
2900 SMLoc S = Parser.getTok().getLoc();
2902 switch (getLexer().getKind()) {
2906 if (getParser().parseAbsoluteExpression(Imm))
2908 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Imm, S));
2913 Operands.
push_back(AMDGPUOperand::CreateExpr(
this,
2915 Parser.getTok().getString()), getContext()), S));
2925 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultGLC()
const {
2926 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyGLC);
2929 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSLC()
const {
2930 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTySLC);
2933 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultTFE()
const {
2934 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyTFE);
2937 void AMDGPUAsmParser::cvtMubufImpl(
MCInst &Inst,
2939 bool IsAtomic,
bool IsAtomicReturn) {
2940 OptionalImmIndexMap OptionalIdx;
2941 assert(IsAtomicReturn ? IsAtomic :
true);
2943 for (
unsigned i = 1, e = Operands.
size(); i != e; ++
i) {
2944 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
2948 Op.addRegOperands(Inst, 1);
2953 if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
2954 Op.addImmOperands(Inst, 1);
2966 OptionalIdx[Op.getImmTy()] =
i;
2970 if (IsAtomicReturn) {
2990 for (
unsigned J = 0; J < Desc.
getNumDefs(); ++J) {
2991 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
2994 OptionalImmIndexMap OptionalIdx;
2996 for (
unsigned E = Operands.
size(); I !=
E; ++
I) {
2997 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
3000 if (Op.isRegOrImm()) {
3001 Op.addRegOrImmOperands(Inst, 1);
3003 }
else if (Op.isImmModifier()) {
3004 OptionalIdx[Op.getImmTy()] =
I;
3023 for (
unsigned J = 0; J < Desc.
getNumDefs(); ++J) {
3024 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
3028 ((AMDGPUOperand &)*Operands[I]).addRegOperands(Inst, 1);
3030 OptionalImmIndexMap OptionalIdx;
3032 for (
unsigned E = Operands.
size(); I !=
E; ++
I) {
3033 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
3036 if (Op.isRegOrImm()) {
3037 Op.addRegOrImmOperands(Inst, 1);
3039 }
else if (Op.isImmModifier()) {
3040 OptionalIdx[Op.getImmTy()] =
I;
3056 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultDMask()
const {
3057 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyDMask);
3060 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultUNorm()
const {
3061 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyUNorm);
3064 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultDA()
const {
3065 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyDA);
3068 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultR128()
const {
3069 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyR128);
3072 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultLWE()
const {
3073 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyLWE);
3080 bool AMDGPUOperand::isSMRDOffset8()
const {
3084 bool AMDGPUOperand::isSMRDOffset20()
const {
3085 return isImm() && isUInt<20>(getImm());
3088 bool AMDGPUOperand::isSMRDLiteralOffset()
const {
3094 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset8()
const {
3095 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyOffset);
3098 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDOffset20()
const {
3099 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyOffset);
3102 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSMRDLiteralOffset()
const {
3103 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyOffset);
3111 if (Mul != 1 && Mul != 2 && Mul != 4)
3133 if (BoundCtrl == 0) {
3138 if (BoundCtrl == -1) {
3148 {
"offen", AMDGPUOperand::ImmTyOffen,
true,
nullptr},
3149 {
"idxen", AMDGPUOperand::ImmTyIdxen,
true,
nullptr},
3150 {
"addr64", AMDGPUOperand::ImmTyAddr64,
true,
nullptr},
3151 {
"offset0", AMDGPUOperand::ImmTyOffset0,
false,
nullptr},
3152 {
"offset1", AMDGPUOperand::ImmTyOffset1,
false,
nullptr},
3153 {
"gds", AMDGPUOperand::ImmTyGDS,
true,
nullptr},
3154 {
"offset", AMDGPUOperand::ImmTyOffset,
false,
nullptr},
3155 {
"glc", AMDGPUOperand::ImmTyGLC,
true,
nullptr},
3156 {
"slc", AMDGPUOperand::ImmTySLC,
true,
nullptr},
3157 {
"tfe", AMDGPUOperand::ImmTyTFE,
true,
nullptr},
3158 {
"clamp", AMDGPUOperand::ImmTyClampSI,
true,
nullptr},
3160 {
"unorm", AMDGPUOperand::ImmTyUNorm,
true,
nullptr},
3161 {
"da", AMDGPUOperand::ImmTyDA,
true,
nullptr},
3162 {
"r128", AMDGPUOperand::ImmTyR128,
true,
nullptr},
3163 {
"lwe", AMDGPUOperand::ImmTyLWE,
true,
nullptr},
3164 {
"dmask", AMDGPUOperand::ImmTyDMask,
false,
nullptr},
3165 {
"row_mask", AMDGPUOperand::ImmTyDppRowMask,
false,
nullptr},
3166 {
"bank_mask", AMDGPUOperand::ImmTyDppBankMask,
false,
nullptr},
3168 {
"dst_sel", AMDGPUOperand::ImmTySdwaDstSel,
false,
nullptr},
3169 {
"src0_sel", AMDGPUOperand::ImmTySdwaSrc0Sel,
false,
nullptr},
3170 {
"src1_sel", AMDGPUOperand::ImmTySdwaSrc1Sel,
false,
nullptr},
3171 {
"dst_unused", AMDGPUOperand::ImmTySdwaDstUnused,
false,
nullptr},
3172 {
"vm", AMDGPUOperand::ImmTyExpVM,
true,
nullptr},
3177 for (
const OptionalOperand &Op : AMDGPUOptionalOperandTable) {
3180 res = parseNamedBit(Op.Name, Operands, Op.Type);
3181 }
else if (Op.Type == AMDGPUOperand::ImmTyOModSI) {
3182 res = parseOModOperand(Operands);
3183 }
else if (Op.Type == AMDGPUOperand::ImmTySdwaDstSel ||
3184 Op.Type == AMDGPUOperand::ImmTySdwaSrc0Sel ||
3185 Op.Type == AMDGPUOperand::ImmTySdwaSrc1Sel) {
3186 res = parseSDWASel(Operands, Op.Name, Op.Type);
3187 }
else if (Op.Type == AMDGPUOperand::ImmTySdwaDstUnused) {
3188 res = parseSDWADstUnused(Operands);
3190 res = parseIntWithPrefix(Op.Name, Operands, Op.Type, Op.ConvertResult);
3200 StringRef Name = Parser.getTok().getString();
3201 if (Name ==
"mul") {
3202 return parseIntWithPrefix(
"mul", Operands,
3206 if (Name ==
"div") {
3207 return parseIntWithPrefix(
"div", Operands,
3217 for (
unsigned J = 0; J < Desc.
getNumDefs(); ++J) {
3218 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
3220 for (
unsigned E = Operands.
size(); I !=
E; ++
I)
3221 ((AMDGPUOperand &)*Operands[
I]).addRegOrImmOperands(Inst, 1);
3225 uint64_t TSFlags = MII.get(Inst.
getOpcode()).TSFlags;
3226 if (TSFlags & SIInstrFlags::VOP3) {
3227 cvtVOP3(Inst, Operands);
3229 cvtId(Inst, Operands);
3245 OptionalImmIndexMap OptionalIdx;
3248 for (
unsigned J = 0; J < Desc.
getNumDefs(); ++J) {
3249 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
3252 for (
unsigned E = Operands.
size(); I !=
E; ++
I) {
3253 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
3255 Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
3256 }
else if (Op.isImm()) {
3257 OptionalIdx[Op.getImmTy()] =
I;
3270 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_e64_si ||
3271 Inst.
getOpcode() == AMDGPU::V_MAC_F32_e64_vi ||
3272 Inst.
getOpcode() == AMDGPU::V_MAC_F16_e64_vi) {
3273 auto it = Inst.
begin();
3277 AMDGPU::V_MAC_F16_e64 :
3278 AMDGPU::V_MAC_F32_e64,
3279 AMDGPU::OpName::src2_modifiers));
3290 bool AMDGPUOperand::isDPPCtrl()
const {
3291 bool result = isImm() && getImmTy() == ImmTyDppCtrl && isUInt<9>(getImm());
3293 int64_t Imm = getImm();
3294 return ((Imm >= 0x000) && (Imm <= 0x0ff)) ||
3295 ((Imm >= 0x101) && (Imm <= 0x10f)) ||
3296 ((Imm >= 0x111) && (Imm <= 0x11f)) ||
3297 ((Imm >= 0x121) && (Imm <= 0x12f)) ||
3310 bool AMDGPUOperand::isGPRIdxMode()
const {
3311 return isImm() && isUInt<4>(getImm());
3316 SMLoc S = Parser.getTok().getLoc();
3321 Prefix = Parser.getTok().getString();
3326 if (Prefix ==
"row_mirror") {
3329 }
else if (Prefix ==
"row_half_mirror") {
3334 if (Prefix !=
"quad_perm"
3335 && Prefix !=
"row_shl"
3336 && Prefix !=
"row_shr"
3337 && Prefix !=
"row_ror"
3338 && Prefix !=
"wave_shl"
3339 && Prefix !=
"wave_rol"
3340 && Prefix !=
"wave_shr"
3341 && Prefix !=
"wave_ror"
3342 && Prefix !=
"row_bcast") {
3350 if (Prefix ==
"quad_perm") {
3357 if (getParser().parseAbsoluteExpression(Int) || !(0 <= Int && Int <=3))
3360 for (
int i = 0; i < 3; ++
i) {
3366 if (getParser().parseAbsoluteExpression(Temp) || !(0 <= Temp && Temp <=3))
3368 const int shift = i*2 + 2;
3369 Int += (Temp << shift);
3379 if (getParser().parseAbsoluteExpression(Int))
3382 if (Prefix ==
"row_shl" && 1 <= Int && Int <= 15) {
3384 }
else if (Prefix ==
"row_shr" && 1 <= Int && Int <= 15) {
3386 }
else if (Prefix ==
"row_ror" && 1 <= Int && Int <= 15) {
3388 }
else if (Prefix ==
"wave_shl" && 1 == Int) {
3390 }
else if (Prefix ==
"wave_rol" && 1 == Int) {
3392 }
else if (Prefix ==
"wave_shr" && 1 == Int) {
3394 }
else if (Prefix ==
"wave_ror" && 1 == Int) {
3396 }
else if (Prefix ==
"row_bcast") {
3399 }
else if (Int == 31) {
3410 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Int, S, AMDGPUOperand::ImmTyDppCtrl));
3414 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultRowMask()
const {
3415 return AMDGPUOperand::CreateImm(
this, 0xf,
SMLoc(), AMDGPUOperand::ImmTyDppRowMask);
3418 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultBankMask()
const {
3419 return AMDGPUOperand::CreateImm(
this, 0xf,
SMLoc(), AMDGPUOperand::ImmTyDppBankMask);
3422 AMDGPUOperand::Ptr AMDGPUAsmParser::defaultBoundCtrl()
const {
3423 return AMDGPUOperand::CreateImm(
this, 0,
SMLoc(), AMDGPUOperand::ImmTyDppBoundCtrl);
3427 OptionalImmIndexMap OptionalIdx;
3431 for (
unsigned J = 0; J < Desc.
getNumDefs(); ++J) {
3432 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
3435 for (
unsigned E = Operands.
size(); I !=
E; ++
I) {
3436 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
3438 if (Op.isReg() && Op.Reg.RegNo == AMDGPU::VCC) {
3443 Op.addRegWithFPInputModsOperands(Inst, 2);
3444 }
else if (Op.isDPPCtrl()) {
3445 Op.addImmOperands(Inst, 1);
3446 }
else if (Op.isImm()) {
3448 OptionalIdx[Op.getImmTy()] =
I;
3460 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_dpp ||
3461 Inst.
getOpcode() == AMDGPU::V_MAC_F16_dpp) {
3462 auto it = Inst.
begin();
3475 AMDGPUOperand::ImmTy Type) {
3478 SMLoc S = Parser.getTok().getLoc();
3482 res = parseStringWithPrefix(Prefix, Value);
3499 if (Int == 0xffffffff) {
3503 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Int, S, Type));
3508 AMDGPUAsmParser::parseSDWADstUnused(
OperandVector &Operands) {
3511 SMLoc S = Parser.getTok().getLoc();
3515 res = parseStringWithPrefix(
"dst_unused", Value);
3528 if (Int == 0xffffffff) {
3532 Operands.
push_back(AMDGPUOperand::CreateImm(
this, Int, S, AMDGPUOperand::ImmTySdwaDstUnused));
3549 uint64_t BasicInstType) {
3550 OptionalImmIndexMap OptionalIdx;
3554 for (
unsigned J = 0; J < Desc.
getNumDefs(); ++J) {
3555 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
3558 for (
unsigned E = Operands.
size(); I !=
E; ++
I) {
3559 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
3564 Op.Reg.RegNo == AMDGPU::VCC) {
3569 Op.addRegWithInputModsOperands(Inst, 2);
3570 }
else if (Op.isImm()) {
3572 OptionalIdx[Op.getImmTy()] =
I;
3580 if (Inst.
getOpcode() != AMDGPU::V_NOP_sdwa_vi) {
3582 switch (BasicInstType) {
3602 llvm_unreachable(
"Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
3608 if (Inst.
getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3609 Inst.
getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3610 auto it = Inst.
begin();
3624 #define GET_REGISTER_MATCHER
3625 #define GET_MATCHER_IMPLEMENTATION
3626 #include "AMDGPUGenAsmMatcher.inc"
3636 AMDGPUOperand &Operand = (AMDGPUOperand&)Op;
3639 return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
3641 return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
3643 return Operand.isGLC() ? Match_Success : Match_InvalidOperand;
3645 return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
3647 return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
3655 return Operand.isSSrcB32() ? Match_Success : Match_InvalidOperand;
3657 return Operand.isSSrcF32() ? Match_Success : Match_InvalidOperand;
3658 case MCK_SoppBrTarget:
3659 return Operand.isSoppBrTarget() ? Match_Success : Match_InvalidOperand;
3660 case MCK_VReg32OrOff:
3661 return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
3662 case MCK_InterpSlot:
3663 return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
3665 return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
3667 return Operand.isAttrChan() ? Match_Success : Match_InvalidOperand;
3669 return Match_InvalidOperand;
static bool isReg(const MCInst &MI, unsigned OpNo)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr bool isUInt< 32 >(uint64_t x)
void push_back(const T &Elt)
Target & getTheGCNTarget()
The target for GCN GPUs.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef take_back(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
static MCOperand createExpr(const MCExpr *Val)
constexpr uint32_t Lo_32(uint64_t Value)
Lo_32 - This function returns the low 32 bits of a 64 bit value.
Target & getTheAMDGPUTarget()
The target which suports all AMD GPUs.
Describe properties that are true of each instruction in the target description file.
MachineInstrBuilder MachineInstrBuilder &DefMI const MCInstrDesc & Desc
unsigned getScalarSizeInBits() const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
static unsigned getSpecialRegForName(StringRef RegName)
unsigned getSizeInBits() const
MCSection * getHSATextSection(MCContext &Ctx)
A raw_ostream that writes to an SmallVector or SmallString.
constexpr bool isInt< 16 >(int64_t x)
MCSection * getHSARodataReadonlyAgentSection(MCContext &Ctx)
unsigned getWaitcntBitMask(IsaVersion Version)
static bool ConvertOmodDiv(int64_t &Div)
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
bool parseAmdKernelCodeField(StringRef ID, MCAsmParser &Parser, amd_kernel_code_t &C, raw_ostream &Err)
bool isInlinableLiteral16(int16_t Literal, bool HasInv2Pi)
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
static MCOperand createReg(unsigned Reg)
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
AMD Kernel Code Object (amd_kernel_code_t).
static void advance(T &it, size_t Val)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
static int getRegClass(RegisterKind Is, unsigned RegWidth)
Represent a reference to a symbol from inside an expression.
static bool isMem(const MachineInstr &MI, unsigned Op)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
This file implements a class to represent arbitrary precision integral constant values and operations...
unsigned encodeExpcnt(IsaVersion Version, unsigned Waitcnt, unsigned Expcnt)
uint8_t OperandType
Information about the type of the operand.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
MCRegisterClass - Base class of TargetRegisterClass.
iterator insert(iterator I, const MCOperand &Op)
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
Instances of this class represent a single low-level machine instruction.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
unsigned short NumOperands
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
MCSection * getHSADataGlobalAgentSection(MCContext &Ctx)
MCSection * getHSADataGlobalProgramSection(MCContext &Ctx)
A switch()-like statement whose cases are string literals.
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
Streaming machine code generation interface.
bool isSI(const MCSubtargetInfo &STI)
constexpr bool isUInt< 8 >(uint64_t x)
unsigned const MachineRegisterInfo * MRI
IsaVersion getIsaVersion(const FeatureBitset &Features)
MVT - Machine Value Type.
The instances of the Type class are immutable: once they are created, they are never changed...
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
const char *const IdSymbolic[]
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
unsigned encodeLgkmcnt(IsaVersion Version, unsigned Waitcnt, unsigned Lgkmcnt)
MCRegAliasIterator enumerates all registers aliasing Reg.
This file declares a class to represent arbitrary precision floating point values and provide a varie...
static const OptionalOperand AMDGPUOptionalOperandTable[]
void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, OptionalImmIndexMap &OptionalIdx, enum AMDGPUOperand::ImmTy ImmT, int64_t Default=0)
bool isIntN(unsigned N, int64_t x)
isIntN - Checks if an signed integer fits into the given (dynamic) bit width.
void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header, const FeatureBitset &Features)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specific constraint if it is set.
static bool ConvertBoundCtrl(int64_t &BoundCtrl)
constexpr bool isInt< 32 >(int64_t x)
Promote Memory to Register
static bool ConvertOmodMul(int64_t &Mul)
double BitsToDouble(uint64_t Bits)
BitsToDouble - This function takes a 64-bit integer and returns the bit equivalent double...
void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
unsigned encodeVmcnt(IsaVersion Version, unsigned Waitcnt, unsigned Vmcnt)
unsigned getOpcode() const
Class for arbitrary precision integers.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
const char *const OpSysSymbolic[]
Base class for user error types.
bool isCI(const MCSubtargetInfo &STI)
static const fltSemantics & IEEEdouble()
static SMLoc getFromPointer(const char *Ptr)
const char *const OpGsSymbolic[]
Provides AMDGPU specific target descriptions.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
StringRef getName() const
getName - Get the symbol name.
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
unsigned getNumOperands() const
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
constexpr bool isUInt< 16 >(uint64_t x)
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo)
Can this operand also contain immediate values?
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
LLVM Value Representation.
const MCOperandInfo * OpInfo
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg...
This class implements an extremely fast bulk output stream that can only output to a stream...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
static const fltSemantics * getFltSemantics(unsigned Size)
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
Represents a location in source code.
bool isUIntN(unsigned N, uint64_t x)
isUIntN - Checks if an unsigned integer fits into the given (dynamic) bit width.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
std::map< enum AMDGPUOperand::ImmTy, unsigned > OptionalImmIndexMap
static MCOperand createImm(int64_t Val)
const MCOperand & getOperand(unsigned i) const