xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- AMDGPUBaseInfo.h - Top level definitions for AMDGPU ------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_UTILS_AMDGPUBASEINFO_H
100b57cec5SDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_UTILS_AMDGPUBASEINFO_H
110b57cec5SDimitry Andric 
12*0fca6ea1SDimitry Andric #include "AMDGPUSubtarget.h"
130b57cec5SDimitry Andric #include "SIDefines.h"
140b57cec5SDimitry Andric #include "llvm/IR/CallingConv.h"
1506c3fb27SDimitry Andric #include "llvm/IR/InstrTypes.h"
1606c3fb27SDimitry Andric #include "llvm/IR/Module.h"
175ffd83dbSDimitry Andric #include "llvm/Support/Alignment.h"
18bdd1243dSDimitry Andric #include <array>
19bdd1243dSDimitry Andric #include <functional>
20bdd1243dSDimitry Andric #include <utility>
21e8d8bef9SDimitry Andric 
22e8d8bef9SDimitry Andric struct amd_kernel_code_t;
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric namespace llvm {
250b57cec5SDimitry Andric 
26e8d8bef9SDimitry Andric struct Align;
270b57cec5SDimitry Andric class Argument;
280b57cec5SDimitry Andric class Function;
290b57cec5SDimitry Andric class GlobalValue;
30bdd1243dSDimitry Andric class MCInstrInfo;
310b57cec5SDimitry Andric class MCRegisterClass;
320b57cec5SDimitry Andric class MCRegisterInfo;
330b57cec5SDimitry Andric class MCSubtargetInfo;
345ffd83dbSDimitry Andric class StringRef;
350b57cec5SDimitry Andric class Triple;
36bdd1243dSDimitry Andric class raw_ostream;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric namespace AMDGPU {
390b57cec5SDimitry Andric 
40*0fca6ea1SDimitry Andric struct AMDGPUMCKernelCodeT;
41e8d8bef9SDimitry Andric struct IsaVersion;
42e8d8bef9SDimitry Andric 
43*0fca6ea1SDimitry Andric /// Generic target versions emitted by this version of LLVM.
44*0fca6ea1SDimitry Andric ///
45*0fca6ea1SDimitry Andric /// These numbers are incremented every time a codegen breaking change occurs
46*0fca6ea1SDimitry Andric /// within a generic family.
47*0fca6ea1SDimitry Andric namespace GenericVersion {
48*0fca6ea1SDimitry Andric static constexpr unsigned GFX9 = 1;
49*0fca6ea1SDimitry Andric static constexpr unsigned GFX10_1 = 1;
50*0fca6ea1SDimitry Andric static constexpr unsigned GFX10_3 = 1;
51*0fca6ea1SDimitry Andric static constexpr unsigned GFX11 = 1;
52*0fca6ea1SDimitry Andric static constexpr unsigned GFX12 = 1;
53*0fca6ea1SDimitry Andric } // namespace GenericVersion
54*0fca6ea1SDimitry Andric 
55*0fca6ea1SDimitry Andric enum { AMDHSA_COV4 = 4, AMDHSA_COV5 = 5, AMDHSA_COV6 = 6 };
5606c3fb27SDimitry Andric 
575f757f3fSDimitry Andric /// \returns True if \p STI is AMDHSA.
585f757f3fSDimitry Andric bool isHsaAbi(const MCSubtargetInfo &STI);
597a6dacacSDimitry Andric 
607a6dacacSDimitry Andric /// \returns Code object version from the IR module flag.
617a6dacacSDimitry Andric unsigned getAMDHSACodeObjectVersion(const Module &M);
627a6dacacSDimitry Andric 
63*0fca6ea1SDimitry Andric /// \returns Code object version from ELF's e_ident[EI_ABIVERSION].
64*0fca6ea1SDimitry Andric unsigned getAMDHSACodeObjectVersion(unsigned ABIVersion);
65*0fca6ea1SDimitry Andric 
667a6dacacSDimitry Andric /// \returns The default HSA code object version. This should only be used when
677a6dacacSDimitry Andric /// we lack a more accurate CodeObjectVersion value (e.g. from the IR module
687a6dacacSDimitry Andric /// flag or a .amdhsa_code_object_version directive)
697a6dacacSDimitry Andric unsigned getDefaultAMDHSACodeObjectVersion();
707a6dacacSDimitry Andric 
71*0fca6ea1SDimitry Andric /// \returns ABIVersion suitable for use in ELF's e_ident[EI_ABIVERSION]. \param
727a6dacacSDimitry Andric /// CodeObjectVersion is a value returned by getAMDHSACodeObjectVersion().
737a6dacacSDimitry Andric uint8_t getELFABIVersion(const Triple &OS, unsigned CodeObjectVersion);
74e8d8bef9SDimitry Andric 
7581ad6265SDimitry Andric /// \returns The offset of the multigrid_sync_arg argument from implicitarg_ptr
7606c3fb27SDimitry Andric unsigned getMultigridSyncArgImplicitArgPosition(unsigned COV);
7781ad6265SDimitry Andric 
7881ad6265SDimitry Andric /// \returns The offset of the hostcall pointer argument from implicitarg_ptr
7906c3fb27SDimitry Andric unsigned getHostcallImplicitArgPosition(unsigned COV);
8081ad6265SDimitry Andric 
8106c3fb27SDimitry Andric unsigned getDefaultQueueImplicitArgPosition(unsigned COV);
8206c3fb27SDimitry Andric unsigned getCompletionActionImplicitArgPosition(unsigned COV);
83bdd1243dSDimitry Andric 
84480093f4SDimitry Andric struct GcnBufferFormatInfo {
85480093f4SDimitry Andric   unsigned Format;
86480093f4SDimitry Andric   unsigned BitsPerComp;
87480093f4SDimitry Andric   unsigned NumComponents;
88480093f4SDimitry Andric   unsigned NumFormat;
89480093f4SDimitry Andric   unsigned DataFormat;
90480093f4SDimitry Andric };
91480093f4SDimitry Andric 
9281ad6265SDimitry Andric struct MAIInstInfo {
9381ad6265SDimitry Andric   uint16_t Opcode;
9481ad6265SDimitry Andric   bool is_dgemm;
9581ad6265SDimitry Andric   bool is_gfx940_xdl;
9681ad6265SDimitry Andric };
9781ad6265SDimitry Andric 
980b57cec5SDimitry Andric #define GET_MIMGBaseOpcode_DECL
990b57cec5SDimitry Andric #define GET_MIMGDim_DECL
1000b57cec5SDimitry Andric #define GET_MIMGEncoding_DECL
1010b57cec5SDimitry Andric #define GET_MIMGLZMapping_DECL
1020b57cec5SDimitry Andric #define GET_MIMGMIPMapping_DECL
10304eeddc0SDimitry Andric #define GET_MIMGBiASMapping_DECL
10481ad6265SDimitry Andric #define GET_MAIInstInfoTable_DECL
1050b57cec5SDimitry Andric #include "AMDGPUGenSearchableTables.inc"
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric namespace IsaInfo {
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric enum {
1100b57cec5SDimitry Andric   // The closed Vulkan driver sets 96, which limits the wave count to 8 but
1110b57cec5SDimitry Andric   // doesn't spill SGPRs as much as when 80 is set.
1120b57cec5SDimitry Andric   FIXED_NUM_SGPRS_FOR_INIT_BUG = 96,
1130b57cec5SDimitry Andric   TRAP_NUM_SGPRS = 16
1140b57cec5SDimitry Andric };
1150b57cec5SDimitry Andric 
116e8d8bef9SDimitry Andric enum class TargetIDSetting {
117e8d8bef9SDimitry Andric   Unsupported,
118e8d8bef9SDimitry Andric   Any,
119e8d8bef9SDimitry Andric   Off,
120e8d8bef9SDimitry Andric   On
121e8d8bef9SDimitry Andric };
122e8d8bef9SDimitry Andric 
123e8d8bef9SDimitry Andric class AMDGPUTargetID {
124e8d8bef9SDimitry Andric private:
125fe6060f1SDimitry Andric   const MCSubtargetInfo &STI;
126e8d8bef9SDimitry Andric   TargetIDSetting XnackSetting;
127e8d8bef9SDimitry Andric   TargetIDSetting SramEccSetting;
128e8d8bef9SDimitry Andric 
129e8d8bef9SDimitry Andric public:
130e8d8bef9SDimitry Andric   explicit AMDGPUTargetID(const MCSubtargetInfo &STI);
131e8d8bef9SDimitry Andric   ~AMDGPUTargetID() = default;
132e8d8bef9SDimitry Andric 
133e8d8bef9SDimitry Andric   /// \return True if the current xnack setting is not "Unsupported".
134e8d8bef9SDimitry Andric   bool isXnackSupported() const {
135e8d8bef9SDimitry Andric     return XnackSetting != TargetIDSetting::Unsupported;
136e8d8bef9SDimitry Andric   }
137e8d8bef9SDimitry Andric 
138e8d8bef9SDimitry Andric   /// \returns True if the current xnack setting is "On" or "Any".
139e8d8bef9SDimitry Andric   bool isXnackOnOrAny() const {
140e8d8bef9SDimitry Andric     return XnackSetting == TargetIDSetting::On ||
141e8d8bef9SDimitry Andric         XnackSetting == TargetIDSetting::Any;
142e8d8bef9SDimitry Andric   }
143e8d8bef9SDimitry Andric 
144e8d8bef9SDimitry Andric   /// \returns True if current xnack setting is "On" or "Off",
145e8d8bef9SDimitry Andric   /// false otherwise.
146e8d8bef9SDimitry Andric   bool isXnackOnOrOff() const {
147e8d8bef9SDimitry Andric     return getXnackSetting() == TargetIDSetting::On ||
148e8d8bef9SDimitry Andric         getXnackSetting() == TargetIDSetting::Off;
149e8d8bef9SDimitry Andric   }
150e8d8bef9SDimitry Andric 
151e8d8bef9SDimitry Andric   /// \returns The current xnack TargetIDSetting, possible options are
152e8d8bef9SDimitry Andric   /// "Unsupported", "Any", "Off", and "On".
153e8d8bef9SDimitry Andric   TargetIDSetting getXnackSetting() const {
154e8d8bef9SDimitry Andric     return XnackSetting;
155e8d8bef9SDimitry Andric   }
156e8d8bef9SDimitry Andric 
157e8d8bef9SDimitry Andric   /// Sets xnack setting to \p NewXnackSetting.
158e8d8bef9SDimitry Andric   void setXnackSetting(TargetIDSetting NewXnackSetting) {
159e8d8bef9SDimitry Andric     XnackSetting = NewXnackSetting;
160e8d8bef9SDimitry Andric   }
161e8d8bef9SDimitry Andric 
162e8d8bef9SDimitry Andric   /// \return True if the current sramecc setting is not "Unsupported".
163e8d8bef9SDimitry Andric   bool isSramEccSupported() const {
164e8d8bef9SDimitry Andric     return SramEccSetting != TargetIDSetting::Unsupported;
165e8d8bef9SDimitry Andric   }
166e8d8bef9SDimitry Andric 
167e8d8bef9SDimitry Andric   /// \returns True if the current sramecc setting is "On" or "Any".
168e8d8bef9SDimitry Andric   bool isSramEccOnOrAny() const {
169e8d8bef9SDimitry Andric   return SramEccSetting == TargetIDSetting::On ||
170e8d8bef9SDimitry Andric       SramEccSetting == TargetIDSetting::Any;
171e8d8bef9SDimitry Andric   }
172e8d8bef9SDimitry Andric 
173e8d8bef9SDimitry Andric   /// \returns True if current sramecc setting is "On" or "Off",
174e8d8bef9SDimitry Andric   /// false otherwise.
175e8d8bef9SDimitry Andric   bool isSramEccOnOrOff() const {
176e8d8bef9SDimitry Andric     return getSramEccSetting() == TargetIDSetting::On ||
177e8d8bef9SDimitry Andric         getSramEccSetting() == TargetIDSetting::Off;
178e8d8bef9SDimitry Andric   }
179e8d8bef9SDimitry Andric 
180e8d8bef9SDimitry Andric   /// \returns The current sramecc TargetIDSetting, possible options are
181e8d8bef9SDimitry Andric   /// "Unsupported", "Any", "Off", and "On".
182e8d8bef9SDimitry Andric   TargetIDSetting getSramEccSetting() const {
183e8d8bef9SDimitry Andric     return SramEccSetting;
184e8d8bef9SDimitry Andric   }
185e8d8bef9SDimitry Andric 
186e8d8bef9SDimitry Andric   /// Sets sramecc setting to \p NewSramEccSetting.
187e8d8bef9SDimitry Andric   void setSramEccSetting(TargetIDSetting NewSramEccSetting) {
188e8d8bef9SDimitry Andric     SramEccSetting = NewSramEccSetting;
189e8d8bef9SDimitry Andric   }
190e8d8bef9SDimitry Andric 
191e8d8bef9SDimitry Andric   void setTargetIDFromFeaturesString(StringRef FS);
192e8d8bef9SDimitry Andric   void setTargetIDFromTargetIDStream(StringRef TargetID);
193e8d8bef9SDimitry Andric 
194fe6060f1SDimitry Andric   /// \returns String representation of an object.
195fe6060f1SDimitry Andric   std::string toString() const;
196fe6060f1SDimitry Andric };
1970b57cec5SDimitry Andric 
1980b57cec5SDimitry Andric /// \returns Wavefront size for given subtarget \p STI.
1990b57cec5SDimitry Andric unsigned getWavefrontSize(const MCSubtargetInfo *STI);
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric /// \returns Local memory size in bytes for given subtarget \p STI.
2020b57cec5SDimitry Andric unsigned getLocalMemorySize(const MCSubtargetInfo *STI);
2030b57cec5SDimitry Andric 
204bdd1243dSDimitry Andric /// \returns Maximum addressable local memory size in bytes for given subtarget
205bdd1243dSDimitry Andric /// \p STI.
206bdd1243dSDimitry Andric unsigned getAddressableLocalMemorySize(const MCSubtargetInfo *STI);
207bdd1243dSDimitry Andric 
2080b57cec5SDimitry Andric /// \returns Number of execution units per compute unit for given subtarget \p
2090b57cec5SDimitry Andric /// STI.
2100b57cec5SDimitry Andric unsigned getEUsPerCU(const MCSubtargetInfo *STI);
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric /// \returns Maximum number of work groups per compute unit for given subtarget
2130b57cec5SDimitry Andric /// \p STI and limited by given \p FlatWorkGroupSize.
2140b57cec5SDimitry Andric unsigned getMaxWorkGroupsPerCU(const MCSubtargetInfo *STI,
2150b57cec5SDimitry Andric                                unsigned FlatWorkGroupSize);
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric /// \returns Minimum number of waves per execution unit for given subtarget \p
2180b57cec5SDimitry Andric /// STI.
2190b57cec5SDimitry Andric unsigned getMinWavesPerEU(const MCSubtargetInfo *STI);
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric /// \returns Maximum number of waves per execution unit for given subtarget \p
2220b57cec5SDimitry Andric /// STI without any kind of limitation.
2238bcb0991SDimitry Andric unsigned getMaxWavesPerEU(const MCSubtargetInfo *STI);
2240b57cec5SDimitry Andric 
2255ffd83dbSDimitry Andric /// \returns Number of waves per execution unit required to support the given \p
2265ffd83dbSDimitry Andric /// FlatWorkGroupSize.
2275ffd83dbSDimitry Andric unsigned getWavesPerEUForWorkGroup(const MCSubtargetInfo *STI,
2280b57cec5SDimitry Andric                                    unsigned FlatWorkGroupSize);
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric /// \returns Minimum flat work group size for given subtarget \p STI.
2310b57cec5SDimitry Andric unsigned getMinFlatWorkGroupSize(const MCSubtargetInfo *STI);
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric /// \returns Maximum flat work group size for given subtarget \p STI.
2340b57cec5SDimitry Andric unsigned getMaxFlatWorkGroupSize(const MCSubtargetInfo *STI);
2350b57cec5SDimitry Andric 
2360b57cec5SDimitry Andric /// \returns Number of waves per work group for given subtarget \p STI and
2375ffd83dbSDimitry Andric /// \p FlatWorkGroupSize.
2380b57cec5SDimitry Andric unsigned getWavesPerWorkGroup(const MCSubtargetInfo *STI,
2390b57cec5SDimitry Andric                               unsigned FlatWorkGroupSize);
2400b57cec5SDimitry Andric 
2410b57cec5SDimitry Andric /// \returns SGPR allocation granularity for given subtarget \p STI.
2420b57cec5SDimitry Andric unsigned getSGPRAllocGranule(const MCSubtargetInfo *STI);
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric /// \returns SGPR encoding granularity for given subtarget \p STI.
2450b57cec5SDimitry Andric unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI);
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric /// \returns Total number of SGPRs for given subtarget \p STI.
2480b57cec5SDimitry Andric unsigned getTotalNumSGPRs(const MCSubtargetInfo *STI);
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric /// \returns Addressable number of SGPRs for given subtarget \p STI.
2510b57cec5SDimitry Andric unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI);
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric /// \returns Minimum number of SGPRs that meets the given number of waves per
2540b57cec5SDimitry Andric /// execution unit requirement for given subtarget \p STI.
2550b57cec5SDimitry Andric unsigned getMinNumSGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU);
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric /// \returns Maximum number of SGPRs that meets the given number of waves per
2580b57cec5SDimitry Andric /// execution unit requirement for given subtarget \p STI.
2590b57cec5SDimitry Andric unsigned getMaxNumSGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU,
2600b57cec5SDimitry Andric                         bool Addressable);
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric /// \returns Number of extra SGPRs implicitly required by given subtarget \p
2630b57cec5SDimitry Andric /// STI when the given special registers are used.
2640b57cec5SDimitry Andric unsigned getNumExtraSGPRs(const MCSubtargetInfo *STI, bool VCCUsed,
2650b57cec5SDimitry Andric                           bool FlatScrUsed, bool XNACKUsed);
2660b57cec5SDimitry Andric 
2670b57cec5SDimitry Andric /// \returns Number of extra SGPRs implicitly required by given subtarget \p
2680b57cec5SDimitry Andric /// STI when the given special registers are used. XNACK is inferred from
2690b57cec5SDimitry Andric /// \p STI.
2700b57cec5SDimitry Andric unsigned getNumExtraSGPRs(const MCSubtargetInfo *STI, bool VCCUsed,
2710b57cec5SDimitry Andric                           bool FlatScrUsed);
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric /// \returns Number of SGPR blocks needed for given subtarget \p STI when
2740b57cec5SDimitry Andric /// \p NumSGPRs are used. \p NumSGPRs should already include any special
2750b57cec5SDimitry Andric /// register counts.
2760b57cec5SDimitry Andric unsigned getNumSGPRBlocks(const MCSubtargetInfo *STI, unsigned NumSGPRs);
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric /// \returns VGPR allocation granularity for given subtarget \p STI.
2790b57cec5SDimitry Andric ///
2800b57cec5SDimitry Andric /// For subtargets which support it, \p EnableWavefrontSize32 should match
2810b57cec5SDimitry Andric /// the ENABLE_WAVEFRONT_SIZE32 kernel descriptor field.
282bdd1243dSDimitry Andric unsigned
283bdd1243dSDimitry Andric getVGPRAllocGranule(const MCSubtargetInfo *STI,
284bdd1243dSDimitry Andric                     std::optional<bool> EnableWavefrontSize32 = std::nullopt);
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric /// \returns VGPR encoding granularity for given subtarget \p STI.
2870b57cec5SDimitry Andric ///
2880b57cec5SDimitry Andric /// For subtargets which support it, \p EnableWavefrontSize32 should match
2890b57cec5SDimitry Andric /// the ENABLE_WAVEFRONT_SIZE32 kernel descriptor field.
290bdd1243dSDimitry Andric unsigned getVGPREncodingGranule(
291bdd1243dSDimitry Andric     const MCSubtargetInfo *STI,
292bdd1243dSDimitry Andric     std::optional<bool> EnableWavefrontSize32 = std::nullopt);
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric /// \returns Total number of VGPRs for given subtarget \p STI.
2950b57cec5SDimitry Andric unsigned getTotalNumVGPRs(const MCSubtargetInfo *STI);
2960b57cec5SDimitry Andric 
297*0fca6ea1SDimitry Andric /// \returns Addressable number of architectural VGPRs for a given subtarget \p
298*0fca6ea1SDimitry Andric /// STI.
299*0fca6ea1SDimitry Andric unsigned getAddressableNumArchVGPRs(const MCSubtargetInfo *STI);
300*0fca6ea1SDimitry Andric 
3010b57cec5SDimitry Andric /// \returns Addressable number of VGPRs for given subtarget \p STI.
3020b57cec5SDimitry Andric unsigned getAddressableNumVGPRs(const MCSubtargetInfo *STI);
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric /// \returns Minimum number of VGPRs that meets given number of waves per
3050b57cec5SDimitry Andric /// execution unit requirement for given subtarget \p STI.
3060b57cec5SDimitry Andric unsigned getMinNumVGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU);
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric /// \returns Maximum number of VGPRs that meets given number of waves per
3090b57cec5SDimitry Andric /// execution unit requirement for given subtarget \p STI.
3100b57cec5SDimitry Andric unsigned getMaxNumVGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU);
3110b57cec5SDimitry Andric 
312bdd1243dSDimitry Andric /// \returns Number of waves reachable for a given \p NumVGPRs usage for given
313bdd1243dSDimitry Andric /// subtarget \p STI.
314bdd1243dSDimitry Andric unsigned getNumWavesPerEUWithNumVGPRs(const MCSubtargetInfo *STI,
315bdd1243dSDimitry Andric                                       unsigned NumVGPRs);
316bdd1243dSDimitry Andric 
317*0fca6ea1SDimitry Andric /// \returns Number of waves reachable for a given \p NumVGPRs usage, \p Granule
318*0fca6ea1SDimitry Andric /// size, \p MaxWaves possible, and \p TotalNumVGPRs available.
319*0fca6ea1SDimitry Andric unsigned getNumWavesPerEUWithNumVGPRs(unsigned NumVGPRs, unsigned Granule,
320*0fca6ea1SDimitry Andric                                       unsigned MaxWaves,
321*0fca6ea1SDimitry Andric                                       unsigned TotalNumVGPRs);
322*0fca6ea1SDimitry Andric 
323*0fca6ea1SDimitry Andric /// \returns Occupancy for a given \p SGPRs usage, \p MaxWaves possible, and \p
324*0fca6ea1SDimitry Andric /// Gen.
325*0fca6ea1SDimitry Andric unsigned getOccupancyWithNumSGPRs(unsigned SGPRs, unsigned MaxWaves,
326*0fca6ea1SDimitry Andric                                   AMDGPUSubtarget::Generation Gen);
327*0fca6ea1SDimitry Andric 
3280b57cec5SDimitry Andric /// \returns Number of VGPR blocks needed for given subtarget \p STI when
329*0fca6ea1SDimitry Andric /// \p NumVGPRs are used. We actually return the number of blocks -1, since
330*0fca6ea1SDimitry Andric /// that's what we encode.
3310b57cec5SDimitry Andric ///
3320b57cec5SDimitry Andric /// For subtargets which support it, \p EnableWavefrontSize32 should match the
3330b57cec5SDimitry Andric /// ENABLE_WAVEFRONT_SIZE32 kernel descriptor field.
334*0fca6ea1SDimitry Andric unsigned getEncodedNumVGPRBlocks(
335*0fca6ea1SDimitry Andric     const MCSubtargetInfo *STI, unsigned NumVGPRs,
336*0fca6ea1SDimitry Andric     std::optional<bool> EnableWavefrontSize32 = std::nullopt);
337*0fca6ea1SDimitry Andric 
338*0fca6ea1SDimitry Andric /// \returns Number of VGPR blocks that need to be allocated for the given
339*0fca6ea1SDimitry Andric /// subtarget \p STI when \p NumVGPRs are used.
340*0fca6ea1SDimitry Andric unsigned getAllocatedNumVGPRBlocks(
341*0fca6ea1SDimitry Andric     const MCSubtargetInfo *STI, unsigned NumVGPRs,
342bdd1243dSDimitry Andric     std::optional<bool> EnableWavefrontSize32 = std::nullopt);
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric } // end namespace IsaInfo
3450b57cec5SDimitry Andric 
346*0fca6ea1SDimitry Andric // Represents a field in an encoded value.
347*0fca6ea1SDimitry Andric template <unsigned HighBit, unsigned LowBit, unsigned D = 0>
348*0fca6ea1SDimitry Andric struct EncodingField {
349*0fca6ea1SDimitry Andric   static_assert(HighBit >= LowBit, "Invalid bit range!");
350*0fca6ea1SDimitry Andric   static constexpr unsigned Offset = LowBit;
351*0fca6ea1SDimitry Andric   static constexpr unsigned Width = HighBit - LowBit + 1;
352*0fca6ea1SDimitry Andric 
353*0fca6ea1SDimitry Andric   using ValueType = unsigned;
354*0fca6ea1SDimitry Andric   static constexpr ValueType Default = D;
355*0fca6ea1SDimitry Andric 
356*0fca6ea1SDimitry Andric   ValueType Value;
357*0fca6ea1SDimitry Andric   constexpr EncodingField(ValueType Value) : Value(Value) {}
358*0fca6ea1SDimitry Andric 
359*0fca6ea1SDimitry Andric   constexpr uint64_t encode() const { return Value; }
360*0fca6ea1SDimitry Andric   static ValueType decode(uint64_t Encoded) { return Encoded; }
361*0fca6ea1SDimitry Andric };
362*0fca6ea1SDimitry Andric 
363*0fca6ea1SDimitry Andric // Represents a single bit in an encoded value.
364*0fca6ea1SDimitry Andric template <unsigned Bit, unsigned D = 0>
365*0fca6ea1SDimitry Andric using EncodingBit = EncodingField<Bit, Bit, D>;
366*0fca6ea1SDimitry Andric 
367*0fca6ea1SDimitry Andric // A helper for encoding and decoding multiple fields.
368*0fca6ea1SDimitry Andric template <typename... Fields> struct EncodingFields {
369*0fca6ea1SDimitry Andric   static constexpr uint64_t encode(Fields... Values) {
370*0fca6ea1SDimitry Andric     return ((Values.encode() << Values.Offset) | ...);
371*0fca6ea1SDimitry Andric   }
372*0fca6ea1SDimitry Andric 
373*0fca6ea1SDimitry Andric   static std::tuple<typename Fields::ValueType...> decode(uint64_t Encoded) {
374*0fca6ea1SDimitry Andric     return {Fields::decode((Encoded >> Fields::Offset) &
375*0fca6ea1SDimitry Andric                            maxUIntN(Fields::Width))...};
376*0fca6ea1SDimitry Andric   }
377*0fca6ea1SDimitry Andric };
378*0fca6ea1SDimitry Andric 
3790b57cec5SDimitry Andric LLVM_READONLY
3800b57cec5SDimitry Andric int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx);
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric LLVM_READONLY
383bdd1243dSDimitry Andric inline bool hasNamedOperand(uint64_t Opcode, uint64_t NamedIdx) {
384bdd1243dSDimitry Andric   return getNamedOperandIdx(Opcode, NamedIdx) != -1;
385bdd1243dSDimitry Andric }
386bdd1243dSDimitry Andric 
387bdd1243dSDimitry Andric LLVM_READONLY
3880b57cec5SDimitry Andric int getSOPPWithRelaxation(uint16_t Opcode);
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric struct MIMGBaseOpcodeInfo {
3910b57cec5SDimitry Andric   MIMGBaseOpcode BaseOpcode;
3920b57cec5SDimitry Andric   bool Store;
3930b57cec5SDimitry Andric   bool Atomic;
3940b57cec5SDimitry Andric   bool AtomicX2;
3950b57cec5SDimitry Andric   bool Sampler;
3960b57cec5SDimitry Andric   bool Gather4;
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric   uint8_t NumExtraArgs;
3990b57cec5SDimitry Andric   bool Gradients;
4005ffd83dbSDimitry Andric   bool G16;
4010b57cec5SDimitry Andric   bool Coordinates;
4020b57cec5SDimitry Andric   bool LodOrClampOrMip;
4030b57cec5SDimitry Andric   bool HasD16;
404fe6060f1SDimitry Andric   bool MSAA;
405349cc55cSDimitry Andric   bool BVH;
40606c3fb27SDimitry Andric   bool A16;
407*0fca6ea1SDimitry Andric   bool NoReturn;
4080b57cec5SDimitry Andric };
4090b57cec5SDimitry Andric 
4100b57cec5SDimitry Andric LLVM_READONLY
411349cc55cSDimitry Andric const MIMGBaseOpcodeInfo *getMIMGBaseOpcode(unsigned Opc);
412349cc55cSDimitry Andric 
413349cc55cSDimitry Andric LLVM_READONLY
4140b57cec5SDimitry Andric const MIMGBaseOpcodeInfo *getMIMGBaseOpcodeInfo(unsigned BaseOpcode);
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric struct MIMGDimInfo {
4170b57cec5SDimitry Andric   MIMGDim Dim;
4180b57cec5SDimitry Andric   uint8_t NumCoords;
4190b57cec5SDimitry Andric   uint8_t NumGradients;
420fe6060f1SDimitry Andric   bool MSAA;
4210b57cec5SDimitry Andric   bool DA;
4220b57cec5SDimitry Andric   uint8_t Encoding;
4230b57cec5SDimitry Andric   const char *AsmSuffix;
4240b57cec5SDimitry Andric };
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric LLVM_READONLY
4270b57cec5SDimitry Andric const MIMGDimInfo *getMIMGDimInfo(unsigned DimEnum);
4280b57cec5SDimitry Andric 
4290b57cec5SDimitry Andric LLVM_READONLY
4300b57cec5SDimitry Andric const MIMGDimInfo *getMIMGDimInfoByEncoding(uint8_t DimEnc);
4310b57cec5SDimitry Andric 
4320b57cec5SDimitry Andric LLVM_READONLY
4330b57cec5SDimitry Andric const MIMGDimInfo *getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix);
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric struct MIMGLZMappingInfo {
4360b57cec5SDimitry Andric   MIMGBaseOpcode L;
4370b57cec5SDimitry Andric   MIMGBaseOpcode LZ;
4380b57cec5SDimitry Andric };
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric struct MIMGMIPMappingInfo {
4410b57cec5SDimitry Andric   MIMGBaseOpcode MIP;
4420b57cec5SDimitry Andric   MIMGBaseOpcode NONMIP;
4430b57cec5SDimitry Andric };
4440b57cec5SDimitry Andric 
44504eeddc0SDimitry Andric struct MIMGBiasMappingInfo {
44604eeddc0SDimitry Andric   MIMGBaseOpcode Bias;
44704eeddc0SDimitry Andric   MIMGBaseOpcode NoBias;
44804eeddc0SDimitry Andric };
44904eeddc0SDimitry Andric 
45004eeddc0SDimitry Andric struct MIMGOffsetMappingInfo {
45104eeddc0SDimitry Andric   MIMGBaseOpcode Offset;
45204eeddc0SDimitry Andric   MIMGBaseOpcode NoOffset;
45304eeddc0SDimitry Andric };
45404eeddc0SDimitry Andric 
4555ffd83dbSDimitry Andric struct MIMGG16MappingInfo {
4565ffd83dbSDimitry Andric   MIMGBaseOpcode G;
4575ffd83dbSDimitry Andric   MIMGBaseOpcode G16;
4585ffd83dbSDimitry Andric };
4595ffd83dbSDimitry Andric 
4600b57cec5SDimitry Andric LLVM_READONLY
4610b57cec5SDimitry Andric const MIMGLZMappingInfo *getMIMGLZMappingInfo(unsigned L);
4620b57cec5SDimitry Andric 
46381ad6265SDimitry Andric struct WMMAOpcodeMappingInfo {
46481ad6265SDimitry Andric   unsigned Opcode2Addr;
46581ad6265SDimitry Andric   unsigned Opcode3Addr;
46681ad6265SDimitry Andric };
46781ad6265SDimitry Andric 
4680b57cec5SDimitry Andric LLVM_READONLY
4695ffd83dbSDimitry Andric const MIMGMIPMappingInfo *getMIMGMIPMappingInfo(unsigned MIP);
4705ffd83dbSDimitry Andric 
4715ffd83dbSDimitry Andric LLVM_READONLY
47204eeddc0SDimitry Andric const MIMGBiasMappingInfo *getMIMGBiasMappingInfo(unsigned Bias);
47304eeddc0SDimitry Andric 
47404eeddc0SDimitry Andric LLVM_READONLY
47504eeddc0SDimitry Andric const MIMGOffsetMappingInfo *getMIMGOffsetMappingInfo(unsigned Offset);
47604eeddc0SDimitry Andric 
47704eeddc0SDimitry Andric LLVM_READONLY
4785ffd83dbSDimitry Andric const MIMGG16MappingInfo *getMIMGG16MappingInfo(unsigned G);
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric LLVM_READONLY
4810b57cec5SDimitry Andric int getMIMGOpcode(unsigned BaseOpcode, unsigned MIMGEncoding,
4820b57cec5SDimitry Andric                   unsigned VDataDwords, unsigned VAddrDwords);
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric LLVM_READONLY
4850b57cec5SDimitry Andric int getMaskedMIMGOp(unsigned Opc, unsigned NewChannels);
4860b57cec5SDimitry Andric 
487fe6060f1SDimitry Andric LLVM_READONLY
488fe6060f1SDimitry Andric unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode,
489fe6060f1SDimitry Andric                            const MIMGDimInfo *Dim, bool IsA16,
490fe6060f1SDimitry Andric                            bool IsG16Supported);
491fe6060f1SDimitry Andric 
4920b57cec5SDimitry Andric struct MIMGInfo {
4930b57cec5SDimitry Andric   uint16_t Opcode;
4940b57cec5SDimitry Andric   uint16_t BaseOpcode;
4950b57cec5SDimitry Andric   uint8_t MIMGEncoding;
4960b57cec5SDimitry Andric   uint8_t VDataDwords;
4970b57cec5SDimitry Andric   uint8_t VAddrDwords;
49881ad6265SDimitry Andric   uint8_t VAddrOperands;
4990b57cec5SDimitry Andric };
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric LLVM_READONLY
5020b57cec5SDimitry Andric const MIMGInfo *getMIMGInfo(unsigned Opc);
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric LLVM_READONLY
5058bcb0991SDimitry Andric int getMTBUFBaseOpcode(unsigned Opc);
5068bcb0991SDimitry Andric 
5078bcb0991SDimitry Andric LLVM_READONLY
5088bcb0991SDimitry Andric int getMTBUFOpcode(unsigned BaseOpc, unsigned Elements);
5098bcb0991SDimitry Andric 
5108bcb0991SDimitry Andric LLVM_READONLY
5118bcb0991SDimitry Andric int getMTBUFElements(unsigned Opc);
5128bcb0991SDimitry Andric 
5138bcb0991SDimitry Andric LLVM_READONLY
5148bcb0991SDimitry Andric bool getMTBUFHasVAddr(unsigned Opc);
5158bcb0991SDimitry Andric 
5168bcb0991SDimitry Andric LLVM_READONLY
5178bcb0991SDimitry Andric bool getMTBUFHasSrsrc(unsigned Opc);
5188bcb0991SDimitry Andric 
5198bcb0991SDimitry Andric LLVM_READONLY
5208bcb0991SDimitry Andric bool getMTBUFHasSoffset(unsigned Opc);
5218bcb0991SDimitry Andric 
5228bcb0991SDimitry Andric LLVM_READONLY
5230b57cec5SDimitry Andric int getMUBUFBaseOpcode(unsigned Opc);
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric LLVM_READONLY
5268bcb0991SDimitry Andric int getMUBUFOpcode(unsigned BaseOpc, unsigned Elements);
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric LLVM_READONLY
5298bcb0991SDimitry Andric int getMUBUFElements(unsigned Opc);
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric LLVM_READONLY
5320b57cec5SDimitry Andric bool getMUBUFHasVAddr(unsigned Opc);
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric LLVM_READONLY
5350b57cec5SDimitry Andric bool getMUBUFHasSrsrc(unsigned Opc);
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric LLVM_READONLY
5380b57cec5SDimitry Andric bool getMUBUFHasSoffset(unsigned Opc);
5390b57cec5SDimitry Andric 
5400b57cec5SDimitry Andric LLVM_READONLY
541fe6060f1SDimitry Andric bool getMUBUFIsBufferInv(unsigned Opc);
542fe6060f1SDimitry Andric 
543fe6060f1SDimitry Andric LLVM_READONLY
544*0fca6ea1SDimitry Andric bool getMUBUFTfe(unsigned Opc);
545*0fca6ea1SDimitry Andric 
546*0fca6ea1SDimitry Andric LLVM_READONLY
5475ffd83dbSDimitry Andric bool getSMEMIsBuffer(unsigned Opc);
5485ffd83dbSDimitry Andric 
5495ffd83dbSDimitry Andric LLVM_READONLY
550fe6060f1SDimitry Andric bool getVOP1IsSingle(unsigned Opc);
551fe6060f1SDimitry Andric 
552fe6060f1SDimitry Andric LLVM_READONLY
553fe6060f1SDimitry Andric bool getVOP2IsSingle(unsigned Opc);
554fe6060f1SDimitry Andric 
555fe6060f1SDimitry Andric LLVM_READONLY
556fe6060f1SDimitry Andric bool getVOP3IsSingle(unsigned Opc);
557fe6060f1SDimitry Andric 
558fe6060f1SDimitry Andric LLVM_READONLY
55981ad6265SDimitry Andric bool isVOPC64DPP(unsigned Opc);
56081ad6265SDimitry Andric 
561*0fca6ea1SDimitry Andric LLVM_READONLY
562*0fca6ea1SDimitry Andric bool isVOPCAsmOnly(unsigned Opc);
563*0fca6ea1SDimitry Andric 
56481ad6265SDimitry Andric /// Returns true if MAI operation is a double precision GEMM.
56581ad6265SDimitry Andric LLVM_READONLY
56681ad6265SDimitry Andric bool getMAIIsDGEMM(unsigned Opc);
56781ad6265SDimitry Andric 
56881ad6265SDimitry Andric LLVM_READONLY
56981ad6265SDimitry Andric bool getMAIIsGFX940XDL(unsigned Opc);
57081ad6265SDimitry Andric 
571753f127fSDimitry Andric struct CanBeVOPD {
572753f127fSDimitry Andric   bool X;
573753f127fSDimitry Andric   bool Y;
574753f127fSDimitry Andric };
575753f127fSDimitry Andric 
5765f757f3fSDimitry Andric /// \returns SIEncodingFamily used for VOPD encoding on a \p ST.
5775f757f3fSDimitry Andric LLVM_READONLY
5785f757f3fSDimitry Andric unsigned getVOPDEncodingFamily(const MCSubtargetInfo &ST);
5795f757f3fSDimitry Andric 
580753f127fSDimitry Andric LLVM_READONLY
581753f127fSDimitry Andric CanBeVOPD getCanBeVOPD(unsigned Opc);
582753f127fSDimitry Andric 
58381ad6265SDimitry Andric LLVM_READONLY
584480093f4SDimitry Andric const GcnBufferFormatInfo *getGcnBufferFormatInfo(uint8_t BitsPerComp,
585480093f4SDimitry Andric                                                   uint8_t NumComponents,
586480093f4SDimitry Andric                                                   uint8_t NumFormat,
587480093f4SDimitry Andric                                                   const MCSubtargetInfo &STI);
588480093f4SDimitry Andric LLVM_READONLY
589480093f4SDimitry Andric const GcnBufferFormatInfo *getGcnBufferFormatInfo(uint8_t Format,
590480093f4SDimitry Andric                                                   const MCSubtargetInfo &STI);
591480093f4SDimitry Andric 
592480093f4SDimitry Andric LLVM_READONLY
5930b57cec5SDimitry Andric int getMCOpcode(uint16_t Opcode, unsigned Gen);
5940b57cec5SDimitry Andric 
59581ad6265SDimitry Andric LLVM_READONLY
596753f127fSDimitry Andric unsigned getVOPDOpcode(unsigned Opc);
597753f127fSDimitry Andric 
598753f127fSDimitry Andric LLVM_READONLY
5995f757f3fSDimitry Andric int getVOPDFull(unsigned OpX, unsigned OpY, unsigned EncodingFamily);
600753f127fSDimitry Andric 
601753f127fSDimitry Andric LLVM_READONLY
602bdd1243dSDimitry Andric bool isVOPD(unsigned Opc);
603bdd1243dSDimitry Andric 
604bdd1243dSDimitry Andric LLVM_READNONE
605bdd1243dSDimitry Andric bool isMAC(unsigned Opc);
606bdd1243dSDimitry Andric 
607bdd1243dSDimitry Andric LLVM_READNONE
608bdd1243dSDimitry Andric bool isPermlane16(unsigned Opc);
609bdd1243dSDimitry Andric 
6105f757f3fSDimitry Andric LLVM_READNONE
6115f757f3fSDimitry Andric bool isGenericAtomic(unsigned Opc);
6125f757f3fSDimitry Andric 
613b3edf446SDimitry Andric LLVM_READNONE
614b3edf446SDimitry Andric bool isCvt_F32_Fp8_Bf8_e64(unsigned Opc);
615b3edf446SDimitry Andric 
616bdd1243dSDimitry Andric namespace VOPD {
617bdd1243dSDimitry Andric 
618bdd1243dSDimitry Andric enum Component : unsigned {
619bdd1243dSDimitry Andric   DST = 0,
620bdd1243dSDimitry Andric   SRC0,
621bdd1243dSDimitry Andric   SRC1,
622bdd1243dSDimitry Andric   SRC2,
623bdd1243dSDimitry Andric 
624bdd1243dSDimitry Andric   DST_NUM = 1,
625bdd1243dSDimitry Andric   MAX_SRC_NUM = 3,
626bdd1243dSDimitry Andric   MAX_OPR_NUM = DST_NUM + MAX_SRC_NUM
627bdd1243dSDimitry Andric };
628bdd1243dSDimitry Andric 
62906c3fb27SDimitry Andric // LSB mask for VGPR banks per VOPD component operand.
63006c3fb27SDimitry Andric // 4 banks result in a mask 3, setting 2 lower bits.
63106c3fb27SDimitry Andric constexpr unsigned VOPD_VGPR_BANK_MASKS[] = {1, 3, 3, 1};
632bdd1243dSDimitry Andric 
633bdd1243dSDimitry Andric enum ComponentIndex : unsigned { X = 0, Y = 1 };
634bdd1243dSDimitry Andric constexpr unsigned COMPONENTS[] = {ComponentIndex::X, ComponentIndex::Y};
635bdd1243dSDimitry Andric constexpr unsigned COMPONENTS_NUM = 2;
636bdd1243dSDimitry Andric 
637bdd1243dSDimitry Andric // Properties of VOPD components.
638bdd1243dSDimitry Andric class ComponentProps {
639bdd1243dSDimitry Andric private:
640bdd1243dSDimitry Andric   unsigned SrcOperandsNum = 0;
64106c3fb27SDimitry Andric   unsigned MandatoryLiteralIdx = ~0u;
642bdd1243dSDimitry Andric   bool HasSrc2Acc = false;
643bdd1243dSDimitry Andric 
644bdd1243dSDimitry Andric public:
645bdd1243dSDimitry Andric   ComponentProps() = default;
646bdd1243dSDimitry Andric   ComponentProps(const MCInstrDesc &OpDesc);
647bdd1243dSDimitry Andric 
648bdd1243dSDimitry Andric   // Return the total number of src operands this component has.
649bdd1243dSDimitry Andric   unsigned getCompSrcOperandsNum() const { return SrcOperandsNum; }
650bdd1243dSDimitry Andric 
651bdd1243dSDimitry Andric   // Return the number of src operands of this component visible to the parser.
652bdd1243dSDimitry Andric   unsigned getCompParsedSrcOperandsNum() const {
653bdd1243dSDimitry Andric     return SrcOperandsNum - HasSrc2Acc;
654bdd1243dSDimitry Andric   }
655bdd1243dSDimitry Andric 
656bdd1243dSDimitry Andric   // Return true iif this component has a mandatory literal.
65706c3fb27SDimitry Andric   bool hasMandatoryLiteral() const { return MandatoryLiteralIdx != ~0u; }
658bdd1243dSDimitry Andric 
659bdd1243dSDimitry Andric   // If this component has a mandatory literal, return component operand
660bdd1243dSDimitry Andric   // index of this literal (i.e. either Component::SRC1 or Component::SRC2).
661bdd1243dSDimitry Andric   unsigned getMandatoryLiteralCompOperandIndex() const {
662bdd1243dSDimitry Andric     assert(hasMandatoryLiteral());
66306c3fb27SDimitry Andric     return MandatoryLiteralIdx;
664bdd1243dSDimitry Andric   }
665bdd1243dSDimitry Andric 
666bdd1243dSDimitry Andric   // Return true iif this component has operand
667bdd1243dSDimitry Andric   // with component index CompSrcIdx and this operand may be a register.
668bdd1243dSDimitry Andric   bool hasRegSrcOperand(unsigned CompSrcIdx) const {
669bdd1243dSDimitry Andric     assert(CompSrcIdx < Component::MAX_SRC_NUM);
670bdd1243dSDimitry Andric     return SrcOperandsNum > CompSrcIdx && !hasMandatoryLiteralAt(CompSrcIdx);
671bdd1243dSDimitry Andric   }
672bdd1243dSDimitry Andric 
673bdd1243dSDimitry Andric   // Return true iif this component has tied src2.
674bdd1243dSDimitry Andric   bool hasSrc2Acc() const { return HasSrc2Acc; }
675bdd1243dSDimitry Andric 
676bdd1243dSDimitry Andric private:
677bdd1243dSDimitry Andric   bool hasMandatoryLiteralAt(unsigned CompSrcIdx) const {
678bdd1243dSDimitry Andric     assert(CompSrcIdx < Component::MAX_SRC_NUM);
67906c3fb27SDimitry Andric     return MandatoryLiteralIdx == Component::DST_NUM + CompSrcIdx;
680bdd1243dSDimitry Andric   }
681bdd1243dSDimitry Andric };
682bdd1243dSDimitry Andric 
683bdd1243dSDimitry Andric enum ComponentKind : unsigned {
684bdd1243dSDimitry Andric   SINGLE = 0,  // A single VOP1 or VOP2 instruction which may be used in VOPD.
685bdd1243dSDimitry Andric   COMPONENT_X, // A VOPD instruction, X component.
686bdd1243dSDimitry Andric   COMPONENT_Y, // A VOPD instruction, Y component.
687bdd1243dSDimitry Andric   MAX = COMPONENT_Y
688bdd1243dSDimitry Andric };
689bdd1243dSDimitry Andric 
690bdd1243dSDimitry Andric // Interface functions of this class map VOPD component operand indices
691bdd1243dSDimitry Andric // to indices of operands in MachineInstr/MCInst or parsed operands array.
692bdd1243dSDimitry Andric //
693bdd1243dSDimitry Andric // Note that this class operates with 3 kinds of indices:
694bdd1243dSDimitry Andric // - VOPD component operand indices (Component::DST, Component::SRC0, etc.);
695bdd1243dSDimitry Andric // - MC operand indices (they refer operands in a MachineInstr/MCInst);
696bdd1243dSDimitry Andric // - parsed operand indices (they refer operands in parsed operands array).
697bdd1243dSDimitry Andric //
698bdd1243dSDimitry Andric // For SINGLE components mapping between these indices is trivial.
699bdd1243dSDimitry Andric // But things get more complicated for COMPONENT_X and
700bdd1243dSDimitry Andric // COMPONENT_Y because these components share the same
701bdd1243dSDimitry Andric // MachineInstr/MCInst and the same parsed operands array.
702bdd1243dSDimitry Andric // Below is an example of component operand to parsed operand
703bdd1243dSDimitry Andric // mapping for the following instruction:
704bdd1243dSDimitry Andric //
705bdd1243dSDimitry Andric //   v_dual_add_f32 v255, v4, v5 :: v_dual_mov_b32 v6, v1
706bdd1243dSDimitry Andric //
707bdd1243dSDimitry Andric //                          PARSED        COMPONENT         PARSED
708bdd1243dSDimitry Andric // COMPONENT               OPERANDS     OPERAND INDEX    OPERAND INDEX
709bdd1243dSDimitry Andric // -------------------------------------------------------------------
710bdd1243dSDimitry Andric //                     "v_dual_add_f32"                        0
711bdd1243dSDimitry Andric // v_dual_add_f32            v255          0 (DST)    -->      1
712bdd1243dSDimitry Andric //                           v4            1 (SRC0)   -->      2
713bdd1243dSDimitry Andric //                           v5            2 (SRC1)   -->      3
714bdd1243dSDimitry Andric //                          "::"                               4
715bdd1243dSDimitry Andric //                     "v_dual_mov_b32"                        5
716bdd1243dSDimitry Andric // v_dual_mov_b32            v6            0 (DST)    -->      6
717bdd1243dSDimitry Andric //                           v1            1 (SRC0)   -->      7
718bdd1243dSDimitry Andric // -------------------------------------------------------------------
719bdd1243dSDimitry Andric //
720bdd1243dSDimitry Andric class ComponentLayout {
721bdd1243dSDimitry Andric private:
722bdd1243dSDimitry Andric   // Regular MachineInstr/MCInst operands are ordered as follows:
723bdd1243dSDimitry Andric   //   dst, src0 [, other src operands]
724bdd1243dSDimitry Andric   // VOPD MachineInstr/MCInst operands are ordered as follows:
725bdd1243dSDimitry Andric   //   dstX, dstY, src0X [, other OpX operands], src0Y [, other OpY operands]
726bdd1243dSDimitry Andric   // Each ComponentKind has operand indices defined below.
727bdd1243dSDimitry Andric   static constexpr unsigned MC_DST_IDX[] = {0, 0, 1};
728bdd1243dSDimitry Andric   static constexpr unsigned FIRST_MC_SRC_IDX[] = {1, 2, 2 /* + OpX.MCSrcNum */};
729bdd1243dSDimitry Andric 
730bdd1243dSDimitry Andric   // Parsed operands of regular instructions are ordered as follows:
731bdd1243dSDimitry Andric   //   Mnemo dst src0 [vsrc1 ...]
732bdd1243dSDimitry Andric   // Parsed VOPD operands are ordered as follows:
733bdd1243dSDimitry Andric   //   OpXMnemo dstX src0X [vsrc1X|imm vsrc1X|vsrc1X imm] '::'
734bdd1243dSDimitry Andric   //   OpYMnemo dstY src0Y [vsrc1Y|imm vsrc1Y|vsrc1Y imm]
735bdd1243dSDimitry Andric   // Each ComponentKind has operand indices defined below.
736bdd1243dSDimitry Andric   static constexpr unsigned PARSED_DST_IDX[] = {1, 1,
737bdd1243dSDimitry Andric                                                 4 /* + OpX.ParsedSrcNum */};
738bdd1243dSDimitry Andric   static constexpr unsigned FIRST_PARSED_SRC_IDX[] = {
739bdd1243dSDimitry Andric       2, 2, 5 /* + OpX.ParsedSrcNum */};
740bdd1243dSDimitry Andric 
741bdd1243dSDimitry Andric private:
742bdd1243dSDimitry Andric   const ComponentKind Kind;
743bdd1243dSDimitry Andric   const ComponentProps PrevComp;
744bdd1243dSDimitry Andric 
745bdd1243dSDimitry Andric public:
746bdd1243dSDimitry Andric   // Create layout for COMPONENT_X or SINGLE component.
747bdd1243dSDimitry Andric   ComponentLayout(ComponentKind Kind) : Kind(Kind) {
748bdd1243dSDimitry Andric     assert(Kind == ComponentKind::SINGLE || Kind == ComponentKind::COMPONENT_X);
749bdd1243dSDimitry Andric   }
750bdd1243dSDimitry Andric 
751bdd1243dSDimitry Andric   // Create layout for COMPONENT_Y which depends on COMPONENT_X layout.
752bdd1243dSDimitry Andric   ComponentLayout(const ComponentProps &OpXProps)
753bdd1243dSDimitry Andric       : Kind(ComponentKind::COMPONENT_Y), PrevComp(OpXProps) {}
754bdd1243dSDimitry Andric 
755bdd1243dSDimitry Andric public:
756bdd1243dSDimitry Andric   // Return the index of dst operand in MCInst operands.
757bdd1243dSDimitry Andric   unsigned getIndexOfDstInMCOperands() const { return MC_DST_IDX[Kind]; }
758bdd1243dSDimitry Andric 
759bdd1243dSDimitry Andric   // Return the index of the specified src operand in MCInst operands.
760bdd1243dSDimitry Andric   unsigned getIndexOfSrcInMCOperands(unsigned CompSrcIdx) const {
761bdd1243dSDimitry Andric     assert(CompSrcIdx < Component::MAX_SRC_NUM);
762bdd1243dSDimitry Andric     return FIRST_MC_SRC_IDX[Kind] + getPrevCompSrcNum() + CompSrcIdx;
763bdd1243dSDimitry Andric   }
764bdd1243dSDimitry Andric 
765bdd1243dSDimitry Andric   // Return the index of dst operand in the parsed operands array.
766bdd1243dSDimitry Andric   unsigned getIndexOfDstInParsedOperands() const {
767bdd1243dSDimitry Andric     return PARSED_DST_IDX[Kind] + getPrevCompParsedSrcNum();
768bdd1243dSDimitry Andric   }
769bdd1243dSDimitry Andric 
770bdd1243dSDimitry Andric   // Return the index of the specified src operand in the parsed operands array.
771bdd1243dSDimitry Andric   unsigned getIndexOfSrcInParsedOperands(unsigned CompSrcIdx) const {
772bdd1243dSDimitry Andric     assert(CompSrcIdx < Component::MAX_SRC_NUM);
773bdd1243dSDimitry Andric     return FIRST_PARSED_SRC_IDX[Kind] + getPrevCompParsedSrcNum() + CompSrcIdx;
774bdd1243dSDimitry Andric   }
775bdd1243dSDimitry Andric 
776bdd1243dSDimitry Andric private:
777bdd1243dSDimitry Andric   unsigned getPrevCompSrcNum() const {
778bdd1243dSDimitry Andric     return PrevComp.getCompSrcOperandsNum();
779bdd1243dSDimitry Andric   }
780bdd1243dSDimitry Andric   unsigned getPrevCompParsedSrcNum() const {
781bdd1243dSDimitry Andric     return PrevComp.getCompParsedSrcOperandsNum();
782bdd1243dSDimitry Andric   }
783bdd1243dSDimitry Andric };
784bdd1243dSDimitry Andric 
785bdd1243dSDimitry Andric // Layout and properties of VOPD components.
786bdd1243dSDimitry Andric class ComponentInfo : public ComponentLayout, public ComponentProps {
787bdd1243dSDimitry Andric public:
788bdd1243dSDimitry Andric   // Create ComponentInfo for COMPONENT_X or SINGLE component.
789bdd1243dSDimitry Andric   ComponentInfo(const MCInstrDesc &OpDesc,
790bdd1243dSDimitry Andric                 ComponentKind Kind = ComponentKind::SINGLE)
791bdd1243dSDimitry Andric       : ComponentLayout(Kind), ComponentProps(OpDesc) {}
792bdd1243dSDimitry Andric 
793bdd1243dSDimitry Andric   // Create ComponentInfo for COMPONENT_Y which depends on COMPONENT_X layout.
794bdd1243dSDimitry Andric   ComponentInfo(const MCInstrDesc &OpDesc, const ComponentProps &OpXProps)
795bdd1243dSDimitry Andric       : ComponentLayout(OpXProps), ComponentProps(OpDesc) {}
796bdd1243dSDimitry Andric 
797bdd1243dSDimitry Andric   // Map component operand index to parsed operand index.
798bdd1243dSDimitry Andric   // Return 0 if the specified operand does not exist.
799bdd1243dSDimitry Andric   unsigned getIndexInParsedOperands(unsigned CompOprIdx) const;
800bdd1243dSDimitry Andric };
801bdd1243dSDimitry Andric 
802bdd1243dSDimitry Andric // Properties of VOPD instructions.
803bdd1243dSDimitry Andric class InstInfo {
804bdd1243dSDimitry Andric private:
805bdd1243dSDimitry Andric   const ComponentInfo CompInfo[COMPONENTS_NUM];
806bdd1243dSDimitry Andric 
807bdd1243dSDimitry Andric public:
808bdd1243dSDimitry Andric   using RegIndices = std::array<unsigned, Component::MAX_OPR_NUM>;
809bdd1243dSDimitry Andric 
810bdd1243dSDimitry Andric   InstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
811bdd1243dSDimitry Andric       : CompInfo{OpX, OpY} {}
812bdd1243dSDimitry Andric 
813bdd1243dSDimitry Andric   InstInfo(const ComponentInfo &OprInfoX, const ComponentInfo &OprInfoY)
814bdd1243dSDimitry Andric       : CompInfo{OprInfoX, OprInfoY} {}
815bdd1243dSDimitry Andric 
816bdd1243dSDimitry Andric   const ComponentInfo &operator[](size_t ComponentIdx) const {
817bdd1243dSDimitry Andric     assert(ComponentIdx < COMPONENTS_NUM);
818bdd1243dSDimitry Andric     return CompInfo[ComponentIdx];
819bdd1243dSDimitry Andric   }
820bdd1243dSDimitry Andric 
821bdd1243dSDimitry Andric   // Check VOPD operands constraints.
822bdd1243dSDimitry Andric   // GetRegIdx(Component, MCOperandIdx) must return a VGPR register index
823bdd1243dSDimitry Andric   // for the specified component and MC operand. The callback must return 0
824bdd1243dSDimitry Andric   // if the operand is not a register or not a VGPR.
8255f757f3fSDimitry Andric   // If \p SkipSrc is set to true then constraints for source operands are not
8265f757f3fSDimitry Andric   // checked.
8275f757f3fSDimitry Andric   bool hasInvalidOperand(std::function<unsigned(unsigned, unsigned)> GetRegIdx,
8285f757f3fSDimitry Andric                          bool SkipSrc = false) const {
8295f757f3fSDimitry Andric     return getInvalidCompOperandIndex(GetRegIdx, SkipSrc).has_value();
830bdd1243dSDimitry Andric   }
831bdd1243dSDimitry Andric 
832bdd1243dSDimitry Andric   // Check VOPD operands constraints.
833bdd1243dSDimitry Andric   // Return the index of an invalid component operand, if any.
8345f757f3fSDimitry Andric   // If \p SkipSrc is set to true then constraints for source operands are not
8355f757f3fSDimitry Andric   // checked.
836bdd1243dSDimitry Andric   std::optional<unsigned> getInvalidCompOperandIndex(
8375f757f3fSDimitry Andric       std::function<unsigned(unsigned, unsigned)> GetRegIdx,
8385f757f3fSDimitry Andric       bool SkipSrc = false) const;
839bdd1243dSDimitry Andric 
840bdd1243dSDimitry Andric private:
841bdd1243dSDimitry Andric   RegIndices
842bdd1243dSDimitry Andric   getRegIndices(unsigned ComponentIdx,
843bdd1243dSDimitry Andric                 std::function<unsigned(unsigned, unsigned)> GetRegIdx) const;
844bdd1243dSDimitry Andric };
845bdd1243dSDimitry Andric 
846bdd1243dSDimitry Andric } // namespace VOPD
847bdd1243dSDimitry Andric 
848bdd1243dSDimitry Andric LLVM_READONLY
849bdd1243dSDimitry Andric std::pair<unsigned, unsigned> getVOPDComponents(unsigned VOPDOpcode);
850bdd1243dSDimitry Andric 
851bdd1243dSDimitry Andric LLVM_READONLY
852bdd1243dSDimitry Andric // Get properties of 2 single VOP1/VOP2 instructions
853bdd1243dSDimitry Andric // used as components to create a VOPD instruction.
854bdd1243dSDimitry Andric VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY);
855bdd1243dSDimitry Andric 
856bdd1243dSDimitry Andric LLVM_READONLY
857bdd1243dSDimitry Andric // Get properties of VOPD X and Y components.
858bdd1243dSDimitry Andric VOPD::InstInfo
859bdd1243dSDimitry Andric getVOPDInstInfo(unsigned VOPDOpcode, const MCInstrInfo *InstrInfo);
860bdd1243dSDimitry Andric 
861bdd1243dSDimitry Andric LLVM_READONLY
862bdd1243dSDimitry Andric bool isTrue16Inst(unsigned Opc);
863bdd1243dSDimitry Andric 
864bdd1243dSDimitry Andric LLVM_READONLY
865*0fca6ea1SDimitry Andric bool isInvalidSingleUseConsumerInst(unsigned Opc);
866*0fca6ea1SDimitry Andric 
867*0fca6ea1SDimitry Andric LLVM_READONLY
868*0fca6ea1SDimitry Andric bool isInvalidSingleUseProducerInst(unsigned Opc);
869*0fca6ea1SDimitry Andric 
870*0fca6ea1SDimitry Andric LLVM_READONLY
87181ad6265SDimitry Andric unsigned mapWMMA2AddrTo3AddrOpcode(unsigned Opc);
87281ad6265SDimitry Andric 
87381ad6265SDimitry Andric LLVM_READONLY
87481ad6265SDimitry Andric unsigned mapWMMA3AddrTo2AddrOpcode(unsigned Opc);
87581ad6265SDimitry Andric 
876*0fca6ea1SDimitry Andric void initDefaultAMDKernelCodeT(AMDGPUMCKernelCodeT &Header,
8770b57cec5SDimitry Andric                                const MCSubtargetInfo *STI);
8780b57cec5SDimitry Andric 
8790b57cec5SDimitry Andric bool isGroupSegment(const GlobalValue *GV);
8800b57cec5SDimitry Andric bool isGlobalSegment(const GlobalValue *GV);
8810b57cec5SDimitry Andric bool isReadOnlySegment(const GlobalValue *GV);
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric /// \returns True if constants should be emitted to .text section for given
8840b57cec5SDimitry Andric /// target triple \p TT, false otherwise.
8850b57cec5SDimitry Andric bool shouldEmitConstantsToTextSection(const Triple &TT);
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric /// \returns Integer value requested using \p F's \p Name attribute.
8880b57cec5SDimitry Andric ///
8890b57cec5SDimitry Andric /// \returns \p Default if attribute is not present.
8900b57cec5SDimitry Andric ///
8910b57cec5SDimitry Andric /// \returns \p Default and emits error if requested value cannot be converted
8920b57cec5SDimitry Andric /// to integer.
8930b57cec5SDimitry Andric int getIntegerAttribute(const Function &F, StringRef Name, int Default);
8940b57cec5SDimitry Andric 
8950b57cec5SDimitry Andric /// \returns A pair of integer values requested using \p F's \p Name attribute
8960b57cec5SDimitry Andric /// in "first[,second]" format ("second" is optional unless \p OnlyFirstRequired
8970b57cec5SDimitry Andric /// is false).
8980b57cec5SDimitry Andric ///
8990b57cec5SDimitry Andric /// \returns \p Default if attribute is not present.
9000b57cec5SDimitry Andric ///
9010b57cec5SDimitry Andric /// \returns \p Default and emits error if one of the requested values cannot be
9020b57cec5SDimitry Andric /// converted to integer, or \p OnlyFirstRequired is false and "second" value is
9030b57cec5SDimitry Andric /// not present.
90406c3fb27SDimitry Andric std::pair<unsigned, unsigned>
90506c3fb27SDimitry Andric getIntegerPairAttribute(const Function &F, StringRef Name,
90606c3fb27SDimitry Andric                         std::pair<unsigned, unsigned> Default,
9070b57cec5SDimitry Andric                         bool OnlyFirstRequired = false);
9080b57cec5SDimitry Andric 
909*0fca6ea1SDimitry Andric /// \returns Generate a vector of integer values requested using \p F's \p Name
910*0fca6ea1SDimitry Andric /// attribute.
911*0fca6ea1SDimitry Andric ///
912*0fca6ea1SDimitry Andric /// \returns true if exactly Size (>2) number of integers are found in the
913*0fca6ea1SDimitry Andric /// attribute.
914*0fca6ea1SDimitry Andric ///
915*0fca6ea1SDimitry Andric /// \returns false if any error occurs.
916*0fca6ea1SDimitry Andric SmallVector<unsigned> getIntegerVecAttribute(const Function &F, StringRef Name,
917*0fca6ea1SDimitry Andric                                              unsigned Size);
918*0fca6ea1SDimitry Andric 
9190b57cec5SDimitry Andric /// Represents the counter values to wait for in an s_waitcnt instruction.
9200b57cec5SDimitry Andric ///
9210b57cec5SDimitry Andric /// Large values (including the maximum possible integer) can be used to
9220b57cec5SDimitry Andric /// represent "don't care" waits.
9230b57cec5SDimitry Andric struct Waitcnt {
9247a6dacacSDimitry Andric   unsigned LoadCnt = ~0u; // Corresponds to Vmcnt prior to gfx12.
9250b57cec5SDimitry Andric   unsigned ExpCnt = ~0u;
9267a6dacacSDimitry Andric   unsigned DsCnt = ~0u;     // Corresponds to LGKMcnt prior to gfx12.
9277a6dacacSDimitry Andric   unsigned StoreCnt = ~0u;  // Corresponds to VScnt on gfx10/gfx11.
9287a6dacacSDimitry Andric   unsigned SampleCnt = ~0u; // gfx12+ only.
9297a6dacacSDimitry Andric   unsigned BvhCnt = ~0u;    // gfx12+ only.
9307a6dacacSDimitry Andric   unsigned KmCnt = ~0u;     // gfx12+ only.
9310b57cec5SDimitry Andric 
93281ad6265SDimitry Andric   Waitcnt() = default;
9337a6dacacSDimitry Andric   // Pre-gfx12 constructor.
9340b57cec5SDimitry Andric   Waitcnt(unsigned VmCnt, unsigned ExpCnt, unsigned LgkmCnt, unsigned VsCnt)
9357a6dacacSDimitry Andric       : LoadCnt(VmCnt), ExpCnt(ExpCnt), DsCnt(LgkmCnt), StoreCnt(VsCnt),
9367a6dacacSDimitry Andric         SampleCnt(~0u), BvhCnt(~0u), KmCnt(~0u) {}
9370b57cec5SDimitry Andric 
9387a6dacacSDimitry Andric   // gfx12+ constructor.
9397a6dacacSDimitry Andric   Waitcnt(unsigned LoadCnt, unsigned ExpCnt, unsigned DsCnt, unsigned StoreCnt,
9407a6dacacSDimitry Andric           unsigned SampleCnt, unsigned BvhCnt, unsigned KmCnt)
9417a6dacacSDimitry Andric       : LoadCnt(LoadCnt), ExpCnt(ExpCnt), DsCnt(DsCnt), StoreCnt(StoreCnt),
9427a6dacacSDimitry Andric         SampleCnt(SampleCnt), BvhCnt(BvhCnt), KmCnt(KmCnt) {}
9430b57cec5SDimitry Andric 
9447a6dacacSDimitry Andric   bool hasWait() const { return StoreCnt != ~0u || hasWaitExceptStoreCnt(); }
9457a6dacacSDimitry Andric 
9467a6dacacSDimitry Andric   bool hasWaitExceptStoreCnt() const {
9477a6dacacSDimitry Andric     return LoadCnt != ~0u || ExpCnt != ~0u || DsCnt != ~0u ||
9487a6dacacSDimitry Andric            SampleCnt != ~0u || BvhCnt != ~0u || KmCnt != ~0u;
949fe6060f1SDimitry Andric   }
950fe6060f1SDimitry Andric 
9517a6dacacSDimitry Andric   bool hasWaitStoreCnt() const { return StoreCnt != ~0u; }
9527a6dacacSDimitry Andric 
9530b57cec5SDimitry Andric   Waitcnt combined(const Waitcnt &Other) const {
9547a6dacacSDimitry Andric     // Does the right thing provided self and Other are either both pre-gfx12
9557a6dacacSDimitry Andric     // or both gfx12+.
9567a6dacacSDimitry Andric     return Waitcnt(
9577a6dacacSDimitry Andric         std::min(LoadCnt, Other.LoadCnt), std::min(ExpCnt, Other.ExpCnt),
9587a6dacacSDimitry Andric         std::min(DsCnt, Other.DsCnt), std::min(StoreCnt, Other.StoreCnt),
9597a6dacacSDimitry Andric         std::min(SampleCnt, Other.SampleCnt), std::min(BvhCnt, Other.BvhCnt),
9607a6dacacSDimitry Andric         std::min(KmCnt, Other.KmCnt));
9610b57cec5SDimitry Andric   }
9620b57cec5SDimitry Andric };
9630b57cec5SDimitry Andric 
9647a6dacacSDimitry Andric // The following methods are only meaningful on targets that support
9657a6dacacSDimitry Andric // S_WAITCNT.
9667a6dacacSDimitry Andric 
9670b57cec5SDimitry Andric /// \returns Vmcnt bit mask for given isa \p Version.
9680b57cec5SDimitry Andric unsigned getVmcntBitMask(const IsaVersion &Version);
9690b57cec5SDimitry Andric 
9700b57cec5SDimitry Andric /// \returns Expcnt bit mask for given isa \p Version.
9710b57cec5SDimitry Andric unsigned getExpcntBitMask(const IsaVersion &Version);
9720b57cec5SDimitry Andric 
9730b57cec5SDimitry Andric /// \returns Lgkmcnt bit mask for given isa \p Version.
9740b57cec5SDimitry Andric unsigned getLgkmcntBitMask(const IsaVersion &Version);
9750b57cec5SDimitry Andric 
9760b57cec5SDimitry Andric /// \returns Waitcnt bit mask for given isa \p Version.
9770b57cec5SDimitry Andric unsigned getWaitcntBitMask(const IsaVersion &Version);
9780b57cec5SDimitry Andric 
9790b57cec5SDimitry Andric /// \returns Decoded Vmcnt from given \p Waitcnt for given isa \p Version.
9800b57cec5SDimitry Andric unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt);
9810b57cec5SDimitry Andric 
9820b57cec5SDimitry Andric /// \returns Decoded Expcnt from given \p Waitcnt for given isa \p Version.
9830b57cec5SDimitry Andric unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt);
9840b57cec5SDimitry Andric 
9850b57cec5SDimitry Andric /// \returns Decoded Lgkmcnt from given \p Waitcnt for given isa \p Version.
9860b57cec5SDimitry Andric unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt);
9870b57cec5SDimitry Andric 
9880b57cec5SDimitry Andric /// Decodes Vmcnt, Expcnt and Lgkmcnt from given \p Waitcnt for given isa
9890b57cec5SDimitry Andric /// \p Version, and writes decoded values into \p Vmcnt, \p Expcnt and
9907a6dacacSDimitry Andric /// \p Lgkmcnt respectively. Should not be used on gfx12+, the instruction
9917a6dacacSDimitry Andric /// which needs it is deprecated
9920b57cec5SDimitry Andric ///
9930b57cec5SDimitry Andric /// \details \p Vmcnt, \p Expcnt and \p Lgkmcnt are decoded as follows:
99481ad6265SDimitry Andric ///     \p Vmcnt = \p Waitcnt[3:0]        (pre-gfx9)
99581ad6265SDimitry Andric ///     \p Vmcnt = \p Waitcnt[15:14,3:0]  (gfx9,10)
9967a6dacacSDimitry Andric ///     \p Vmcnt = \p Waitcnt[15:10]      (gfx11)
99781ad6265SDimitry Andric ///     \p Expcnt = \p Waitcnt[6:4]       (pre-gfx11)
9987a6dacacSDimitry Andric ///     \p Expcnt = \p Waitcnt[2:0]       (gfx11)
99981ad6265SDimitry Andric ///     \p Lgkmcnt = \p Waitcnt[11:8]     (pre-gfx10)
100081ad6265SDimitry Andric ///     \p Lgkmcnt = \p Waitcnt[13:8]     (gfx10)
10017a6dacacSDimitry Andric ///     \p Lgkmcnt = \p Waitcnt[9:4]      (gfx11)
10027a6dacacSDimitry Andric ///
10030b57cec5SDimitry Andric void decodeWaitcnt(const IsaVersion &Version, unsigned Waitcnt,
10040b57cec5SDimitry Andric                    unsigned &Vmcnt, unsigned &Expcnt, unsigned &Lgkmcnt);
10050b57cec5SDimitry Andric 
10060b57cec5SDimitry Andric Waitcnt decodeWaitcnt(const IsaVersion &Version, unsigned Encoded);
10070b57cec5SDimitry Andric 
10080b57cec5SDimitry Andric /// \returns \p Waitcnt with encoded \p Vmcnt for given isa \p Version.
10090b57cec5SDimitry Andric unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt,
10100b57cec5SDimitry Andric                      unsigned Vmcnt);
10110b57cec5SDimitry Andric 
10120b57cec5SDimitry Andric /// \returns \p Waitcnt with encoded \p Expcnt for given isa \p Version.
10130b57cec5SDimitry Andric unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt,
10140b57cec5SDimitry Andric                       unsigned Expcnt);
10150b57cec5SDimitry Andric 
10160b57cec5SDimitry Andric /// \returns \p Waitcnt with encoded \p Lgkmcnt for given isa \p Version.
10170b57cec5SDimitry Andric unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt,
10180b57cec5SDimitry Andric                        unsigned Lgkmcnt);
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric /// Encodes \p Vmcnt, \p Expcnt and \p Lgkmcnt into Waitcnt for given isa
10217a6dacacSDimitry Andric /// \p Version. Should not be used on gfx12+, the instruction which needs
10227a6dacacSDimitry Andric /// it is deprecated
10230b57cec5SDimitry Andric ///
10240b57cec5SDimitry Andric /// \details \p Vmcnt, \p Expcnt and \p Lgkmcnt are encoded as follows:
102581ad6265SDimitry Andric ///     Waitcnt[2:0]   = \p Expcnt      (gfx11+)
102681ad6265SDimitry Andric ///     Waitcnt[3:0]   = \p Vmcnt       (pre-gfx9)
102781ad6265SDimitry Andric ///     Waitcnt[3:0]   = \p Vmcnt[3:0]  (gfx9,10)
102881ad6265SDimitry Andric ///     Waitcnt[6:4]   = \p Expcnt      (pre-gfx11)
10297a6dacacSDimitry Andric ///     Waitcnt[9:4]   = \p Lgkmcnt     (gfx11)
103081ad6265SDimitry Andric ///     Waitcnt[11:8]  = \p Lgkmcnt     (pre-gfx10)
103181ad6265SDimitry Andric ///     Waitcnt[13:8]  = \p Lgkmcnt     (gfx10)
10327a6dacacSDimitry Andric ///     Waitcnt[15:10] = \p Vmcnt       (gfx11)
103381ad6265SDimitry Andric ///     Waitcnt[15:14] = \p Vmcnt[5:4]  (gfx9,10)
10340b57cec5SDimitry Andric ///
10350b57cec5SDimitry Andric /// \returns Waitcnt with encoded \p Vmcnt, \p Expcnt and \p Lgkmcnt for given
10360b57cec5SDimitry Andric /// isa \p Version.
10377a6dacacSDimitry Andric ///
10380b57cec5SDimitry Andric unsigned encodeWaitcnt(const IsaVersion &Version,
10390b57cec5SDimitry Andric                        unsigned Vmcnt, unsigned Expcnt, unsigned Lgkmcnt);
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric unsigned encodeWaitcnt(const IsaVersion &Version, const Waitcnt &Decoded);
10420b57cec5SDimitry Andric 
10437a6dacacSDimitry Andric // The following methods are only meaningful on targets that support
10447a6dacacSDimitry Andric // S_WAIT_*CNT, introduced with gfx12.
10457a6dacacSDimitry Andric 
10467a6dacacSDimitry Andric /// \returns Loadcnt bit mask for given isa \p Version.
10477a6dacacSDimitry Andric /// Returns 0 for versions that do not support LOADcnt
10487a6dacacSDimitry Andric unsigned getLoadcntBitMask(const IsaVersion &Version);
10497a6dacacSDimitry Andric 
10507a6dacacSDimitry Andric /// \returns Samplecnt bit mask for given isa \p Version.
10517a6dacacSDimitry Andric /// Returns 0 for versions that do not support SAMPLEcnt
10527a6dacacSDimitry Andric unsigned getSamplecntBitMask(const IsaVersion &Version);
10537a6dacacSDimitry Andric 
10547a6dacacSDimitry Andric /// \returns Bvhcnt bit mask for given isa \p Version.
10557a6dacacSDimitry Andric /// Returns 0 for versions that do not support BVHcnt
10567a6dacacSDimitry Andric unsigned getBvhcntBitMask(const IsaVersion &Version);
10577a6dacacSDimitry Andric 
10587a6dacacSDimitry Andric /// \returns Dscnt bit mask for given isa \p Version.
10597a6dacacSDimitry Andric /// Returns 0 for versions that do not support DScnt
10607a6dacacSDimitry Andric unsigned getDscntBitMask(const IsaVersion &Version);
10617a6dacacSDimitry Andric 
10627a6dacacSDimitry Andric /// \returns Dscnt bit mask for given isa \p Version.
10637a6dacacSDimitry Andric /// Returns 0 for versions that do not support KMcnt
10647a6dacacSDimitry Andric unsigned getKmcntBitMask(const IsaVersion &Version);
10657a6dacacSDimitry Andric 
10667a6dacacSDimitry Andric /// \return STOREcnt or VScnt bit mask for given isa \p Version.
10677a6dacacSDimitry Andric /// returns 0 for versions that do not support STOREcnt or VScnt.
10687a6dacacSDimitry Andric /// STOREcnt and VScnt are the same counter, the name used
10697a6dacacSDimitry Andric /// depends on the ISA version.
10707a6dacacSDimitry Andric unsigned getStorecntBitMask(const IsaVersion &Version);
10717a6dacacSDimitry Andric 
10727a6dacacSDimitry Andric // The following are only meaningful on targets that support
10737a6dacacSDimitry Andric // S_WAIT_LOADCNT_DSCNT and S_WAIT_STORECNT_DSCNT.
10747a6dacacSDimitry Andric 
10757a6dacacSDimitry Andric /// \returns Decoded Waitcnt structure from given \p LoadcntDscnt for given
10767a6dacacSDimitry Andric /// isa \p Version.
10777a6dacacSDimitry Andric Waitcnt decodeLoadcntDscnt(const IsaVersion &Version, unsigned LoadcntDscnt);
10787a6dacacSDimitry Andric 
10797a6dacacSDimitry Andric /// \returns Decoded Waitcnt structure from given \p StorecntDscnt for given
10807a6dacacSDimitry Andric /// isa \p Version.
10817a6dacacSDimitry Andric Waitcnt decodeStorecntDscnt(const IsaVersion &Version, unsigned StorecntDscnt);
10827a6dacacSDimitry Andric 
10837a6dacacSDimitry Andric /// \returns \p Loadcnt and \p Dscnt components of \p Decoded  encoded as an
10847a6dacacSDimitry Andric /// immediate that can be used with S_WAIT_LOADCNT_DSCNT for given isa
10857a6dacacSDimitry Andric /// \p Version.
10867a6dacacSDimitry Andric unsigned encodeLoadcntDscnt(const IsaVersion &Version, const Waitcnt &Decoded);
10877a6dacacSDimitry Andric 
10887a6dacacSDimitry Andric /// \returns \p Storecnt and \p Dscnt components of \p Decoded  encoded as an
10897a6dacacSDimitry Andric /// immediate that can be used with S_WAIT_STORECNT_DSCNT for given isa
10907a6dacacSDimitry Andric /// \p Version.
10917a6dacacSDimitry Andric unsigned encodeStorecntDscnt(const IsaVersion &Version, const Waitcnt &Decoded);
10927a6dacacSDimitry Andric 
10930b57cec5SDimitry Andric namespace Hwreg {
10940b57cec5SDimitry Andric 
1095*0fca6ea1SDimitry Andric using HwregId = EncodingField<5, 0>;
1096*0fca6ea1SDimitry Andric using HwregOffset = EncodingField<10, 6>;
10970b57cec5SDimitry Andric 
1098*0fca6ea1SDimitry Andric struct HwregSize : EncodingField<15, 11, 32> {
1099*0fca6ea1SDimitry Andric   using EncodingField::EncodingField;
1100*0fca6ea1SDimitry Andric   constexpr uint64_t encode() const { return Value - 1; }
1101*0fca6ea1SDimitry Andric   static ValueType decode(uint64_t Encoded) { return Encoded + 1; }
1102*0fca6ea1SDimitry Andric };
11030b57cec5SDimitry Andric 
1104*0fca6ea1SDimitry Andric using HwregEncoding = EncodingFields<HwregId, HwregOffset, HwregSize>;
11050b57cec5SDimitry Andric 
11060b57cec5SDimitry Andric } // namespace Hwreg
11070b57cec5SDimitry Andric 
110881ad6265SDimitry Andric namespace DepCtr {
110981ad6265SDimitry Andric 
111081ad6265SDimitry Andric int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI);
111181ad6265SDimitry Andric int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask,
111281ad6265SDimitry Andric                  const MCSubtargetInfo &STI);
111381ad6265SDimitry Andric bool isSymbolicDepCtrEncoding(unsigned Code, bool &HasNonDefaultVal,
111481ad6265SDimitry Andric                               const MCSubtargetInfo &STI);
111581ad6265SDimitry Andric bool decodeDepCtr(unsigned Code, int &Id, StringRef &Name, unsigned &Val,
111681ad6265SDimitry Andric                   bool &IsDefault, const MCSubtargetInfo &STI);
111781ad6265SDimitry Andric 
111806c3fb27SDimitry Andric /// \returns Decoded VaVdst from given immediate \p Encoded.
111906c3fb27SDimitry Andric unsigned decodeFieldVaVdst(unsigned Encoded);
112006c3fb27SDimitry Andric 
112106c3fb27SDimitry Andric /// \returns Decoded VmVsrc from given immediate \p Encoded.
112206c3fb27SDimitry Andric unsigned decodeFieldVmVsrc(unsigned Encoded);
112306c3fb27SDimitry Andric 
112406c3fb27SDimitry Andric /// \returns Decoded SaSdst from given immediate \p Encoded.
112506c3fb27SDimitry Andric unsigned decodeFieldSaSdst(unsigned Encoded);
112606c3fb27SDimitry Andric 
112706c3fb27SDimitry Andric /// \returns \p VmVsrc as an encoded Depctr immediate.
112806c3fb27SDimitry Andric unsigned encodeFieldVmVsrc(unsigned VmVsrc);
112906c3fb27SDimitry Andric 
113006c3fb27SDimitry Andric /// \returns \p Encoded combined with encoded \p VmVsrc.
113106c3fb27SDimitry Andric unsigned encodeFieldVmVsrc(unsigned Encoded, unsigned VmVsrc);
113206c3fb27SDimitry Andric 
113306c3fb27SDimitry Andric /// \returns \p VaVdst as an encoded Depctr immediate.
113406c3fb27SDimitry Andric unsigned encodeFieldVaVdst(unsigned VaVdst);
113506c3fb27SDimitry Andric 
113606c3fb27SDimitry Andric /// \returns \p Encoded combined with encoded \p VaVdst.
113706c3fb27SDimitry Andric unsigned encodeFieldVaVdst(unsigned Encoded, unsigned VaVdst);
113806c3fb27SDimitry Andric 
113906c3fb27SDimitry Andric /// \returns \p SaSdst as an encoded Depctr immediate.
114006c3fb27SDimitry Andric unsigned encodeFieldSaSdst(unsigned SaSdst);
114106c3fb27SDimitry Andric 
114206c3fb27SDimitry Andric /// \returns \p Encoded combined with encoded \p SaSdst.
114306c3fb27SDimitry Andric unsigned encodeFieldSaSdst(unsigned Encoded, unsigned SaSdst);
114406c3fb27SDimitry Andric 
114581ad6265SDimitry Andric } // namespace DepCtr
114681ad6265SDimitry Andric 
1147e8d8bef9SDimitry Andric namespace Exp {
1148e8d8bef9SDimitry Andric 
1149e8d8bef9SDimitry Andric bool getTgtName(unsigned Id, StringRef &Name, int &Index);
1150e8d8bef9SDimitry Andric 
1151e8d8bef9SDimitry Andric LLVM_READONLY
1152e8d8bef9SDimitry Andric unsigned getTgtId(const StringRef Name);
1153e8d8bef9SDimitry Andric 
1154e8d8bef9SDimitry Andric LLVM_READNONE
1155e8d8bef9SDimitry Andric bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI);
1156e8d8bef9SDimitry Andric 
1157e8d8bef9SDimitry Andric } // namespace Exp
1158e8d8bef9SDimitry Andric 
1159e8d8bef9SDimitry Andric namespace MTBUFFormat {
1160e8d8bef9SDimitry Andric 
1161e8d8bef9SDimitry Andric LLVM_READNONE
1162e8d8bef9SDimitry Andric int64_t encodeDfmtNfmt(unsigned Dfmt, unsigned Nfmt);
1163e8d8bef9SDimitry Andric 
1164e8d8bef9SDimitry Andric void decodeDfmtNfmt(unsigned Format, unsigned &Dfmt, unsigned &Nfmt);
1165e8d8bef9SDimitry Andric 
1166e8d8bef9SDimitry Andric int64_t getDfmt(const StringRef Name);
1167e8d8bef9SDimitry Andric 
1168e8d8bef9SDimitry Andric StringRef getDfmtName(unsigned Id);
1169e8d8bef9SDimitry Andric 
1170e8d8bef9SDimitry Andric int64_t getNfmt(const StringRef Name, const MCSubtargetInfo &STI);
1171e8d8bef9SDimitry Andric 
1172e8d8bef9SDimitry Andric StringRef getNfmtName(unsigned Id, const MCSubtargetInfo &STI);
1173e8d8bef9SDimitry Andric 
1174e8d8bef9SDimitry Andric bool isValidDfmtNfmt(unsigned Val, const MCSubtargetInfo &STI);
1175e8d8bef9SDimitry Andric 
1176e8d8bef9SDimitry Andric bool isValidNfmt(unsigned Val, const MCSubtargetInfo &STI);
1177e8d8bef9SDimitry Andric 
117881ad6265SDimitry Andric int64_t getUnifiedFormat(const StringRef Name, const MCSubtargetInfo &STI);
1179e8d8bef9SDimitry Andric 
118081ad6265SDimitry Andric StringRef getUnifiedFormatName(unsigned Id, const MCSubtargetInfo &STI);
1181e8d8bef9SDimitry Andric 
118281ad6265SDimitry Andric bool isValidUnifiedFormat(unsigned Val, const MCSubtargetInfo &STI);
1183e8d8bef9SDimitry Andric 
118481ad6265SDimitry Andric int64_t convertDfmtNfmt2Ufmt(unsigned Dfmt, unsigned Nfmt,
118581ad6265SDimitry Andric                              const MCSubtargetInfo &STI);
1186e8d8bef9SDimitry Andric 
1187e8d8bef9SDimitry Andric bool isValidFormatEncoding(unsigned Val, const MCSubtargetInfo &STI);
1188e8d8bef9SDimitry Andric 
1189e8d8bef9SDimitry Andric unsigned getDefaultFormatEncoding(const MCSubtargetInfo &STI);
1190e8d8bef9SDimitry Andric 
1191e8d8bef9SDimitry Andric } // namespace MTBUFFormat
1192e8d8bef9SDimitry Andric 
11930b57cec5SDimitry Andric namespace SendMsg {
11940b57cec5SDimitry Andric 
11950b57cec5SDimitry Andric LLVM_READNONE
119681ad6265SDimitry Andric bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI);
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric LLVM_READNONE
1199fe6060f1SDimitry Andric bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI,
1200fe6060f1SDimitry Andric                   bool Strict = true);
12010b57cec5SDimitry Andric 
12020b57cec5SDimitry Andric LLVM_READNONE
1203fe6060f1SDimitry Andric bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId,
1204fe6060f1SDimitry Andric                       const MCSubtargetInfo &STI, bool Strict = true);
12050b57cec5SDimitry Andric 
12060b57cec5SDimitry Andric LLVM_READNONE
120781ad6265SDimitry Andric bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI);
12080b57cec5SDimitry Andric 
12090b57cec5SDimitry Andric LLVM_READNONE
121081ad6265SDimitry Andric bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI);
12110b57cec5SDimitry Andric 
121281ad6265SDimitry Andric void decodeMsg(unsigned Val, uint16_t &MsgId, uint16_t &OpId,
121381ad6265SDimitry Andric                uint16_t &StreamId, const MCSubtargetInfo &STI);
12140b57cec5SDimitry Andric 
12150b57cec5SDimitry Andric LLVM_READNONE
12160b57cec5SDimitry Andric uint64_t encodeMsg(uint64_t MsgId,
12170b57cec5SDimitry Andric                    uint64_t OpId,
12180b57cec5SDimitry Andric                    uint64_t StreamId);
12190b57cec5SDimitry Andric 
12200b57cec5SDimitry Andric } // namespace SendMsg
12210b57cec5SDimitry Andric 
12220b57cec5SDimitry Andric 
12230b57cec5SDimitry Andric unsigned getInitialPSInputAddr(const Function &F);
12240b57cec5SDimitry Andric 
1225fe6060f1SDimitry Andric bool getHasColorExport(const Function &F);
1226fe6060f1SDimitry Andric 
1227fe6060f1SDimitry Andric bool getHasDepthExport(const Function &F);
1228fe6060f1SDimitry Andric 
12290b57cec5SDimitry Andric LLVM_READNONE
12300b57cec5SDimitry Andric bool isShader(CallingConv::ID CC);
12310b57cec5SDimitry Andric 
12320b57cec5SDimitry Andric LLVM_READNONE
1233e8d8bef9SDimitry Andric bool isGraphics(CallingConv::ID CC);
1234e8d8bef9SDimitry Andric 
1235e8d8bef9SDimitry Andric LLVM_READNONE
12360b57cec5SDimitry Andric bool isCompute(CallingConv::ID CC);
12370b57cec5SDimitry Andric 
12380b57cec5SDimitry Andric LLVM_READNONE
12390b57cec5SDimitry Andric bool isEntryFunctionCC(CallingConv::ID CC);
12400b57cec5SDimitry Andric 
1241e8d8bef9SDimitry Andric // These functions are considered entrypoints into the current module, i.e. they
1242e8d8bef9SDimitry Andric // are allowed to be called from outside the current module. This is different
1243e8d8bef9SDimitry Andric // from isEntryFunctionCC, which is only true for functions that are entered by
1244e8d8bef9SDimitry Andric // the hardware. Module entry points include all entry functions but also
1245e8d8bef9SDimitry Andric // include functions that can be called from other functions inside or outside
1246e8d8bef9SDimitry Andric // the current module. Module entry functions are allowed to allocate LDS.
1247e8d8bef9SDimitry Andric LLVM_READNONE
1248e8d8bef9SDimitry Andric bool isModuleEntryFunctionCC(CallingConv::ID CC);
1249e8d8bef9SDimitry Andric 
12505f757f3fSDimitry Andric LLVM_READNONE
12515f757f3fSDimitry Andric bool isChainCC(CallingConv::ID CC);
12525f757f3fSDimitry Andric 
125381ad6265SDimitry Andric bool isKernelCC(const Function *Func);
125481ad6265SDimitry Andric 
12550b57cec5SDimitry Andric // FIXME: Remove this when calling conventions cleaned up
12560b57cec5SDimitry Andric LLVM_READNONE
12570b57cec5SDimitry Andric inline bool isKernel(CallingConv::ID CC) {
12580b57cec5SDimitry Andric   switch (CC) {
12590b57cec5SDimitry Andric   case CallingConv::AMDGPU_KERNEL:
12600b57cec5SDimitry Andric   case CallingConv::SPIR_KERNEL:
12610b57cec5SDimitry Andric     return true;
12620b57cec5SDimitry Andric   default:
12630b57cec5SDimitry Andric     return false;
12640b57cec5SDimitry Andric   }
12650b57cec5SDimitry Andric }
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric bool hasXNACK(const MCSubtargetInfo &STI);
12680b57cec5SDimitry Andric bool hasSRAMECC(const MCSubtargetInfo &STI);
12690b57cec5SDimitry Andric bool hasMIMG_R128(const MCSubtargetInfo &STI);
1270bdd1243dSDimitry Andric bool hasA16(const MCSubtargetInfo &STI);
12715ffd83dbSDimitry Andric bool hasG16(const MCSubtargetInfo &STI);
12720b57cec5SDimitry Andric bool hasPackedD16(const MCSubtargetInfo &STI);
12735f757f3fSDimitry Andric bool hasGDS(const MCSubtargetInfo &STI);
12745f757f3fSDimitry Andric unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler = false);
12755f757f3fSDimitry Andric unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI);
12760b57cec5SDimitry Andric 
12770b57cec5SDimitry Andric bool isSI(const MCSubtargetInfo &STI);
12780b57cec5SDimitry Andric bool isCI(const MCSubtargetInfo &STI);
12790b57cec5SDimitry Andric bool isVI(const MCSubtargetInfo &STI);
12800b57cec5SDimitry Andric bool isGFX9(const MCSubtargetInfo &STI);
128181ad6265SDimitry Andric bool isGFX9_GFX10(const MCSubtargetInfo &STI);
12825f757f3fSDimitry Andric bool isGFX9_GFX10_GFX11(const MCSubtargetInfo &STI);
128381ad6265SDimitry Andric bool isGFX8_GFX9_GFX10(const MCSubtargetInfo &STI);
128481ad6265SDimitry Andric bool isGFX8Plus(const MCSubtargetInfo &STI);
1285e8d8bef9SDimitry Andric bool isGFX9Plus(const MCSubtargetInfo &STI);
1286*0fca6ea1SDimitry Andric bool isNotGFX9Plus(const MCSubtargetInfo &STI);
12870b57cec5SDimitry Andric bool isGFX10(const MCSubtargetInfo &STI);
12885f757f3fSDimitry Andric bool isGFX10_GFX11(const MCSubtargetInfo &STI);
1289e8d8bef9SDimitry Andric bool isGFX10Plus(const MCSubtargetInfo &STI);
129081ad6265SDimitry Andric bool isNotGFX10Plus(const MCSubtargetInfo &STI);
129181ad6265SDimitry Andric bool isGFX10Before1030(const MCSubtargetInfo &STI);
129281ad6265SDimitry Andric bool isGFX11(const MCSubtargetInfo &STI);
129381ad6265SDimitry Andric bool isGFX11Plus(const MCSubtargetInfo &STI);
12945f757f3fSDimitry Andric bool isGFX12(const MCSubtargetInfo &STI);
12955f757f3fSDimitry Andric bool isGFX12Plus(const MCSubtargetInfo &STI);
12965f757f3fSDimitry Andric bool isNotGFX12Plus(const MCSubtargetInfo &STI);
129781ad6265SDimitry Andric bool isNotGFX11Plus(const MCSubtargetInfo &STI);
12985ffd83dbSDimitry Andric bool isGCN3Encoding(const MCSubtargetInfo &STI);
1299fe6060f1SDimitry Andric bool isGFX10_AEncoding(const MCSubtargetInfo &STI);
13005ffd83dbSDimitry Andric bool isGFX10_BEncoding(const MCSubtargetInfo &STI);
13015ffd83dbSDimitry Andric bool hasGFX10_3Insts(const MCSubtargetInfo &STI);
13025f757f3fSDimitry Andric bool isGFX10_3_GFX11(const MCSubtargetInfo &STI);
1303fe6060f1SDimitry Andric bool isGFX90A(const MCSubtargetInfo &STI);
130481ad6265SDimitry Andric bool isGFX940(const MCSubtargetInfo &STI);
1305fe6060f1SDimitry Andric bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI);
130681ad6265SDimitry Andric bool hasMAIInsts(const MCSubtargetInfo &STI);
130781ad6265SDimitry Andric bool hasVOPD(const MCSubtargetInfo &STI);
13085f757f3fSDimitry Andric bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI);
130981ad6265SDimitry Andric int getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR);
13105f757f3fSDimitry Andric unsigned hasKernargPreload(const MCSubtargetInfo &STI);
1311*0fca6ea1SDimitry Andric bool hasSMRDSignedImmOffset(const MCSubtargetInfo &ST);
13120b57cec5SDimitry Andric 
13130b57cec5SDimitry Andric /// Is Reg - scalar register
13140b57cec5SDimitry Andric bool isSGPR(unsigned Reg, const MCRegisterInfo* TRI);
13150b57cec5SDimitry Andric 
13165f757f3fSDimitry Andric /// \returns if \p Reg occupies the high 16-bits of a 32-bit register.
13175f757f3fSDimitry Andric /// The bit indicating isHi is the LSB of the encoding.
13185f757f3fSDimitry Andric bool isHi(unsigned Reg, const MCRegisterInfo &MRI);
13195f757f3fSDimitry Andric 
13200b57cec5SDimitry Andric /// If \p Reg is a pseudo reg, return the correct hardware register given
13210b57cec5SDimitry Andric /// \p STI otherwise return \p Reg.
13220b57cec5SDimitry Andric unsigned getMCReg(unsigned Reg, const MCSubtargetInfo &STI);
13230b57cec5SDimitry Andric 
13240b57cec5SDimitry Andric /// Convert hardware register \p Reg to a pseudo register
13250b57cec5SDimitry Andric LLVM_READNONE
13260b57cec5SDimitry Andric unsigned mc2PseudoReg(unsigned Reg);
13270b57cec5SDimitry Andric 
1328bdd1243dSDimitry Andric LLVM_READNONE
1329bdd1243dSDimitry Andric bool isInlineValue(unsigned Reg);
1330bdd1243dSDimitry Andric 
1331bdd1243dSDimitry Andric /// Is this an AMDGPU specific source operand? These include registers,
1332bdd1243dSDimitry Andric /// inline constants, literals and mandatory literals (KImm).
13330b57cec5SDimitry Andric bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo);
13340b57cec5SDimitry Andric 
1335bdd1243dSDimitry Andric /// Is this a KImm operand?
1336bdd1243dSDimitry Andric bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo);
1337bdd1243dSDimitry Andric 
13380b57cec5SDimitry Andric /// Is this floating-point operand?
13390b57cec5SDimitry Andric bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo);
13400b57cec5SDimitry Andric 
1341349cc55cSDimitry Andric /// Does this operand support only inlinable literals?
13420b57cec5SDimitry Andric bool isSISrcInlinableOperand(const MCInstrDesc &Desc, unsigned OpNo);
13430b57cec5SDimitry Andric 
13440b57cec5SDimitry Andric /// Get the size in bits of a register from the register class \p RC.
13450b57cec5SDimitry Andric unsigned getRegBitWidth(unsigned RCID);
13460b57cec5SDimitry Andric 
13470b57cec5SDimitry Andric /// Get the size in bits of a register from the register class \p RC.
13480b57cec5SDimitry Andric unsigned getRegBitWidth(const MCRegisterClass &RC);
13490b57cec5SDimitry Andric 
13500b57cec5SDimitry Andric /// Get size of register operand
13510b57cec5SDimitry Andric unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc,
13520b57cec5SDimitry Andric                            unsigned OpNo);
13530b57cec5SDimitry Andric 
13540b57cec5SDimitry Andric LLVM_READNONE
13550b57cec5SDimitry Andric inline unsigned getOperandSize(const MCOperandInfo &OpInfo) {
13560b57cec5SDimitry Andric   switch (OpInfo.OperandType) {
13570b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_INT32:
13580b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_FP32:
1359349cc55cSDimitry Andric   case AMDGPU::OPERAND_REG_IMM_FP32_DEFERRED:
13600b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_INT32:
13610b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_FP32:
13620b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_INT32:
13630b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_FP32:
1364fe6060f1SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_V2INT32:
1365fe6060f1SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_V2FP32:
1366fe6060f1SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_V2INT32:
1367fe6060f1SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_V2FP32:
1368349cc55cSDimitry Andric   case AMDGPU::OPERAND_KIMM32:
1369349cc55cSDimitry Andric   case AMDGPU::OPERAND_KIMM16: // mandatory literal is always size 4
13705f757f3fSDimitry Andric   case AMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32:
13710b57cec5SDimitry Andric     return 4;
13720b57cec5SDimitry Andric 
13730b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_INT64:
13740b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_FP64:
13750b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_INT64:
13760b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_FP64:
1377fe6060f1SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
13780b57cec5SDimitry Andric     return 8;
13790b57cec5SDimitry Andric 
13800b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_INT16:
1381*0fca6ea1SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_BF16:
13820b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_FP16:
1383*0fca6ea1SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_BF16_DEFERRED:
1384349cc55cSDimitry Andric   case AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED:
13850b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_INT16:
1386*0fca6ea1SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_BF16:
13870b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_FP16:
13880b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_V2INT16:
1389*0fca6ea1SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_V2BF16:
13900b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_C_V2FP16:
13910b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_INT16:
1392*0fca6ea1SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_BF16:
13930b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_FP16:
13940b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
1395*0fca6ea1SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_V2BF16:
13960b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
13970b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_V2INT16:
1398*0fca6ea1SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_V2BF16:
13990b57cec5SDimitry Andric   case AMDGPU::OPERAND_REG_IMM_V2FP16:
14000b57cec5SDimitry Andric     return 2;
14010b57cec5SDimitry Andric 
14020b57cec5SDimitry Andric   default:
14030b57cec5SDimitry Andric     llvm_unreachable("unhandled operand type");
14040b57cec5SDimitry Andric   }
14050b57cec5SDimitry Andric }
14060b57cec5SDimitry Andric 
14070b57cec5SDimitry Andric LLVM_READNONE
14080b57cec5SDimitry Andric inline unsigned getOperandSize(const MCInstrDesc &Desc, unsigned OpNo) {
1409bdd1243dSDimitry Andric   return getOperandSize(Desc.operands()[OpNo]);
14100b57cec5SDimitry Andric }
14110b57cec5SDimitry Andric 
14125ffd83dbSDimitry Andric /// Is this literal inlinable, and not one of the values intended for floating
14135ffd83dbSDimitry Andric /// point values.
14145ffd83dbSDimitry Andric LLVM_READNONE
14155ffd83dbSDimitry Andric inline bool isInlinableIntLiteral(int64_t Literal) {
14165ffd83dbSDimitry Andric   return Literal >= -16 && Literal <= 64;
14175ffd83dbSDimitry Andric }
14185ffd83dbSDimitry Andric 
14190b57cec5SDimitry Andric /// Is this literal inlinable
14200b57cec5SDimitry Andric LLVM_READNONE
14210b57cec5SDimitry Andric bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi);
14220b57cec5SDimitry Andric 
14230b57cec5SDimitry Andric LLVM_READNONE
14240b57cec5SDimitry Andric bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi);
14250b57cec5SDimitry Andric 
14260b57cec5SDimitry Andric LLVM_READNONE
1427*0fca6ea1SDimitry Andric bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi);
1428*0fca6ea1SDimitry Andric 
1429*0fca6ea1SDimitry Andric LLVM_READNONE
1430*0fca6ea1SDimitry Andric bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi);
1431*0fca6ea1SDimitry Andric 
1432*0fca6ea1SDimitry Andric LLVM_READNONE
1433*0fca6ea1SDimitry Andric bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi);
1434*0fca6ea1SDimitry Andric 
1435*0fca6ea1SDimitry Andric LLVM_READNONE
1436*0fca6ea1SDimitry Andric bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi);
14370b57cec5SDimitry Andric 
14380b57cec5SDimitry Andric LLVM_READNONE
14391db9f3b2SDimitry Andric std::optional<unsigned> getInlineEncodingV2I16(uint32_t Literal);
14400b57cec5SDimitry Andric 
14415ffd83dbSDimitry Andric LLVM_READNONE
1442*0fca6ea1SDimitry Andric std::optional<unsigned> getInlineEncodingV2BF16(uint32_t Literal);
1443*0fca6ea1SDimitry Andric 
1444*0fca6ea1SDimitry Andric LLVM_READNONE
14451db9f3b2SDimitry Andric std::optional<unsigned> getInlineEncodingV2F16(uint32_t Literal);
14465ffd83dbSDimitry Andric 
144716d6b3b3SDimitry Andric LLVM_READNONE
14481db9f3b2SDimitry Andric bool isInlinableLiteralV216(uint32_t Literal, uint8_t OpType);
14495f757f3fSDimitry Andric 
14505f757f3fSDimitry Andric LLVM_READNONE
14511db9f3b2SDimitry Andric bool isInlinableLiteralV2I16(uint32_t Literal);
14521db9f3b2SDimitry Andric 
14531db9f3b2SDimitry Andric LLVM_READNONE
1454*0fca6ea1SDimitry Andric bool isInlinableLiteralV2BF16(uint32_t Literal);
1455*0fca6ea1SDimitry Andric 
1456*0fca6ea1SDimitry Andric LLVM_READNONE
14571db9f3b2SDimitry Andric bool isInlinableLiteralV2F16(uint32_t Literal);
145816d6b3b3SDimitry Andric 
14595f757f3fSDimitry Andric LLVM_READNONE
14605f757f3fSDimitry Andric bool isValid32BitLiteral(uint64_t Val, bool IsFP64);
14615f757f3fSDimitry Andric 
14620b57cec5SDimitry Andric bool isArgPassedInSGPR(const Argument *Arg);
14630b57cec5SDimitry Andric 
146406c3fb27SDimitry Andric bool isArgPassedInSGPR(const CallBase *CB, unsigned ArgNo);
146506c3fb27SDimitry Andric 
14665ffd83dbSDimitry Andric LLVM_READONLY
14675ffd83dbSDimitry Andric bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST,
14685ffd83dbSDimitry Andric                                       int64_t EncodedOffset);
14695ffd83dbSDimitry Andric 
14705ffd83dbSDimitry Andric LLVM_READONLY
14715ffd83dbSDimitry Andric bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST,
14725ffd83dbSDimitry Andric                                     int64_t EncodedOffset,
14735ffd83dbSDimitry Andric                                     bool IsBuffer);
14745ffd83dbSDimitry Andric 
14755ffd83dbSDimitry Andric /// Convert \p ByteOffset to dwords if the subtarget uses dword SMRD immediate
14765ffd83dbSDimitry Andric /// offsets.
14775ffd83dbSDimitry Andric uint64_t convertSMRDOffsetUnits(const MCSubtargetInfo &ST, uint64_t ByteOffset);
14785ffd83dbSDimitry Andric 
14795ffd83dbSDimitry Andric /// \returns The encoding that will be used for \p ByteOffset in the
1480bdd1243dSDimitry Andric /// SMRD offset field, or std::nullopt if it won't fit. On GFX9 and GFX10
14815ffd83dbSDimitry Andric /// S_LOAD instructions have a signed offset, on other subtargets it is
14825ffd83dbSDimitry Andric /// unsigned. S_BUFFER has an unsigned offset for all subtargets.
1483bdd1243dSDimitry Andric std::optional<int64_t> getSMRDEncodedOffset(const MCSubtargetInfo &ST,
1484*0fca6ea1SDimitry Andric                                             int64_t ByteOffset, bool IsBuffer,
1485*0fca6ea1SDimitry Andric                                             bool HasSOffset = false);
14865ffd83dbSDimitry Andric 
14875ffd83dbSDimitry Andric /// \return The encoding that can be used for a 32-bit literal offset in an SMRD
14885ffd83dbSDimitry Andric /// instruction. This is only useful on CI.s
1489bdd1243dSDimitry Andric std::optional<int64_t> getSMRDEncodedLiteralOffset32(const MCSubtargetInfo &ST,
14905ffd83dbSDimitry Andric                                                      int64_t ByteOffset);
14910b57cec5SDimitry Andric 
14925f757f3fSDimitry Andric /// For pre-GFX12 FLAT instructions the offset must be positive;
1493e8d8bef9SDimitry Andric /// MSB is ignored and forced to zero.
1494e8d8bef9SDimitry Andric ///
1495bdd1243dSDimitry Andric /// \return The number of bits available for the signed offset field in flat
1496bdd1243dSDimitry Andric /// instructions. Note that some forms of the instruction disallow negative
1497bdd1243dSDimitry Andric /// offsets.
1498bdd1243dSDimitry Andric unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST);
1499e8d8bef9SDimitry Andric 
15000b57cec5SDimitry Andric /// \returns true if this offset is small enough to fit in the SMRD
15010b57cec5SDimitry Andric /// offset field.  \p ByteOffset should be the offset in bytes and
15020b57cec5SDimitry Andric /// not the encoded offset.
15030b57cec5SDimitry Andric bool isLegalSMRDImmOffset(const MCSubtargetInfo &ST, int64_t ByteOffset);
15040b57cec5SDimitry Andric 
1505fe6060f1SDimitry Andric LLVM_READNONE
15065f757f3fSDimitry Andric inline bool isLegalDPALU_DPPControl(unsigned DC) {
1507fe6060f1SDimitry Andric   return DC >= DPP::ROW_NEWBCAST_FIRST && DC <= DPP::ROW_NEWBCAST_LAST;
1508fe6060f1SDimitry Andric }
1509fe6060f1SDimitry Andric 
15105f757f3fSDimitry Andric /// \returns true if an instruction may have a 64-bit VGPR operand.
15115f757f3fSDimitry Andric bool hasAny64BitVGPROperands(const MCInstrDesc &OpDesc);
15125f757f3fSDimitry Andric 
15135f757f3fSDimitry Andric /// \returns true if an instruction is a DP ALU DPP.
15145f757f3fSDimitry Andric bool isDPALU_DPP(const MCInstrDesc &OpDesc);
15155f757f3fSDimitry Andric 
15160b57cec5SDimitry Andric /// \returns true if the intrinsic is divergent
15170b57cec5SDimitry Andric bool isIntrinsicSourceOfDivergence(unsigned IntrID);
15180b57cec5SDimitry Andric 
151906c3fb27SDimitry Andric /// \returns true if the intrinsic is uniform
152006c3fb27SDimitry Andric bool isIntrinsicAlwaysUniform(unsigned IntrID);
15210b57cec5SDimitry Andric 
1522*0fca6ea1SDimitry Andric /// \returns lds block size in terms of dwords. \p
1523*0fca6ea1SDimitry Andric /// This is used to calculate the lds size encoded for PAL metadata 3.0+ which
1524*0fca6ea1SDimitry Andric /// must be defined in terms of bytes.
1525*0fca6ea1SDimitry Andric unsigned getLdsDwGranularity(const MCSubtargetInfo &ST);
1526*0fca6ea1SDimitry Andric 
15270b57cec5SDimitry Andric } // end namespace AMDGPU
1528e8d8bef9SDimitry Andric 
1529e8d8bef9SDimitry Andric raw_ostream &operator<<(raw_ostream &OS,
1530e8d8bef9SDimitry Andric                         const AMDGPU::IsaInfo::TargetIDSetting S);
1531e8d8bef9SDimitry Andric 
15320b57cec5SDimitry Andric } // end namespace llvm
15330b57cec5SDimitry Andric 
15340b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_AMDGPU_UTILS_AMDGPUBASEINFO_H
1535