xref: /aosp_15_r20/external/mesa3d/src/imagination/rogue/rogue.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2022 Imagination Technologies Ltd.
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
5*61046927SAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to deal
6*61046927SAndroid Build Coastguard Worker  * in the Software without restriction, including without limitation the rights
7*61046927SAndroid Build Coastguard Worker  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8*61046927SAndroid Build Coastguard Worker  * copies of the Software, and to permit persons to whom the Software is
9*61046927SAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18*61046927SAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20*61046927SAndroid Build Coastguard Worker  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21*61046927SAndroid Build Coastguard Worker  * SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #ifndef ROGUE_H
25*61046927SAndroid Build Coastguard Worker #define ROGUE_H
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker /**
28*61046927SAndroid Build Coastguard Worker  * \file rogue.h
29*61046927SAndroid Build Coastguard Worker  *
30*61046927SAndroid Build Coastguard Worker  * \brief Main header.
31*61046927SAndroid Build Coastguard Worker  */
32*61046927SAndroid Build Coastguard Worker 
33*61046927SAndroid Build Coastguard Worker #define __pvr_address_type pvr_dev_addr_t
34*61046927SAndroid Build Coastguard Worker #define __pvr_get_address(pvr_dev_addr) (pvr_dev_addr).addr
35*61046927SAndroid Build Coastguard Worker /* clang-format off */
36*61046927SAndroid Build Coastguard Worker #define __pvr_make_address(addr_u64) PVR_DEV_ADDR(addr_u64)
37*61046927SAndroid Build Coastguard Worker /* clang-format on */
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker #include "pvr_types.h"
40*61046927SAndroid Build Coastguard Worker #include "csbgen/rogue_hwdefs.h"
41*61046927SAndroid Build Coastguard Worker #include "vulkan/pvr_limits.h"
42*61046927SAndroid Build Coastguard Worker #include "vulkan/pvr_common.h"
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker #include "compiler/nir/nir.h"
45*61046927SAndroid Build Coastguard Worker #include "compiler/shader_enums.h"
46*61046927SAndroid Build Coastguard Worker #include "compiler/spirv/nir_spirv.h"
47*61046927SAndroid Build Coastguard Worker #include "rogue_isa.h"
48*61046927SAndroid Build Coastguard Worker #include "util/bitscan.h"
49*61046927SAndroid Build Coastguard Worker #include "util/bitset.h"
50*61046927SAndroid Build Coastguard Worker #include "util/compiler.h"
51*61046927SAndroid Build Coastguard Worker #include "util/list.h"
52*61046927SAndroid Build Coastguard Worker #include "util/sparse_array.h"
53*61046927SAndroid Build Coastguard Worker #include "util/ralloc.h"
54*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h"
55*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
56*61046927SAndroid Build Coastguard Worker 
57*61046927SAndroid Build Coastguard Worker #include <limits.h>
58*61046927SAndroid Build Coastguard Worker #include <stdarg.h>
59*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
60*61046927SAndroid Build Coastguard Worker #include <stdint.h>
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker /* Coefficient registers are typically used in groups of 4. */
63*61046927SAndroid Build Coastguard Worker #define ROGUE_COEFF_ALIGN 4
64*61046927SAndroid Build Coastguard Worker 
65*61046927SAndroid Build Coastguard Worker #define ROGUE_REG_UNUSED ~0
66*61046927SAndroid Build Coastguard Worker 
67*61046927SAndroid Build Coastguard Worker /* All registers are 32-bit in size. */
68*61046927SAndroid Build Coastguard Worker #define ROGUE_REG_SIZE_BYTES 4
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker /** Rogue register classes. */
71*61046927SAndroid Build Coastguard Worker enum rogue_reg_class {
72*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_INVALID = 0,
73*61046927SAndroid Build Coastguard Worker 
74*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_SSA, /** SSA register. */
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_TEMP, /** Temp register. */
77*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_COEFF, /** Coefficient register. */
78*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_SHARED, /** Shared register. */
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_SPECIAL, /** Special register. */
81*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_INTERNAL, /** Internal register. */
82*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_CONST, /** Constant register. */
83*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_PIXOUT, /** Pixel output register. */
84*61046927SAndroid Build Coastguard Worker 
85*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_VTXIN, /** Vertex input register. */
86*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_VTXOUT, /** Vertex output register. */
87*61046927SAndroid Build Coastguard Worker 
88*61046927SAndroid Build Coastguard Worker    ROGUE_REG_CLASS_COUNT,
89*61046927SAndroid Build Coastguard Worker } PACKED;
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker typedef struct rogue_reg_info {
92*61046927SAndroid Build Coastguard Worker    const char *name; /** Human-readable name. */
93*61046927SAndroid Build Coastguard Worker    const char *str; /** Register prefix. */
94*61046927SAndroid Build Coastguard Worker    unsigned num; /** Number of hardware registers available. */
95*61046927SAndroid Build Coastguard Worker    uint64_t supported_io_srcs;
96*61046927SAndroid Build Coastguard Worker } rogue_reg_info;
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker extern const rogue_reg_info rogue_reg_infos[ROGUE_REG_CLASS_COUNT];
99*61046927SAndroid Build Coastguard Worker 
rogue_reg_bank_encoding(enum rogue_reg_class class)100*61046927SAndroid Build Coastguard Worker static inline enum reg_bank rogue_reg_bank_encoding(enum rogue_reg_class class)
101*61046927SAndroid Build Coastguard Worker {
102*61046927SAndroid Build Coastguard Worker    switch (class) {
103*61046927SAndroid Build Coastguard Worker    case ROGUE_REG_CLASS_TEMP:
104*61046927SAndroid Build Coastguard Worker       return BANK_TEMP;
105*61046927SAndroid Build Coastguard Worker    case ROGUE_REG_CLASS_COEFF:
106*61046927SAndroid Build Coastguard Worker       return BANK_COEFF;
107*61046927SAndroid Build Coastguard Worker    case ROGUE_REG_CLASS_SHARED:
108*61046927SAndroid Build Coastguard Worker       return BANK_SHARED;
109*61046927SAndroid Build Coastguard Worker    case ROGUE_REG_CLASS_SPECIAL:
110*61046927SAndroid Build Coastguard Worker       return BANK_SPECIAL;
111*61046927SAndroid Build Coastguard Worker    case ROGUE_REG_CLASS_VTXIN:
112*61046927SAndroid Build Coastguard Worker       return BANK_VTXIN;
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    default:
115*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported register class.");
116*61046927SAndroid Build Coastguard Worker    }
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker /* TODO: Do this dynamically by iterating
120*61046927SAndroid Build Coastguard Worker  * through regarrays and matching sizes.
121*61046927SAndroid Build Coastguard Worker  */
122*61046927SAndroid Build Coastguard Worker enum rogue_regalloc_class {
123*61046927SAndroid Build Coastguard Worker    ROGUE_REGALLOC_CLASS_TEMP_1,
124*61046927SAndroid Build Coastguard Worker    ROGUE_REGALLOC_CLASS_TEMP_2,
125*61046927SAndroid Build Coastguard Worker    ROGUE_REGALLOC_CLASS_TEMP_4,
126*61046927SAndroid Build Coastguard Worker 
127*61046927SAndroid Build Coastguard Worker    ROGUE_REGALLOC_CLASS_COUNT,
128*61046927SAndroid Build Coastguard Worker };
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker typedef struct rogue_regalloc_info {
131*61046927SAndroid Build Coastguard Worker    enum rogue_reg_class class;
132*61046927SAndroid Build Coastguard Worker    unsigned stride;
133*61046927SAndroid Build Coastguard Worker } rogue_regalloc_info;
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker extern const rogue_regalloc_info regalloc_info[ROGUE_REGALLOC_CLASS_COUNT];
136*61046927SAndroid Build Coastguard Worker 
137*61046927SAndroid Build Coastguard Worker #define ROGUE_ISA_DSTS 2
138*61046927SAndroid Build Coastguard Worker #define ROGUE_ISA_SRCS 6
139*61046927SAndroid Build Coastguard Worker #define ROGUE_ISA_ISSS 6
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker #define ROGUE_ISA_ICACHE_ALIGN 8
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker typedef struct rogue_reg_dst_info {
144*61046927SAndroid Build Coastguard Worker    unsigned num_dsts;
145*61046927SAndroid Build Coastguard Worker    unsigned bank_bits[ROGUE_ISA_DSTS];
146*61046927SAndroid Build Coastguard Worker    unsigned index_bits[ROGUE_ISA_DSTS];
147*61046927SAndroid Build Coastguard Worker    unsigned bytes;
148*61046927SAndroid Build Coastguard Worker } rogue_reg_dst_info;
149*61046927SAndroid Build Coastguard Worker 
150*61046927SAndroid Build Coastguard Worker #define ROGUE_REG_DST_VARIANTS 5
151*61046927SAndroid Build Coastguard Worker extern const rogue_reg_dst_info rogue_reg_dst_infos[ROGUE_REG_DST_VARIANTS];
152*61046927SAndroid Build Coastguard Worker 
153*61046927SAndroid Build Coastguard Worker typedef struct rogue_reg_src_info {
154*61046927SAndroid Build Coastguard Worker    unsigned num_srcs;
155*61046927SAndroid Build Coastguard Worker    unsigned mux_bits;
156*61046927SAndroid Build Coastguard Worker    unsigned bank_bits[ROGUE_ISA_SRCS / 2];
157*61046927SAndroid Build Coastguard Worker    unsigned index_bits[ROGUE_ISA_SRCS / 2];
158*61046927SAndroid Build Coastguard Worker    unsigned bytes;
159*61046927SAndroid Build Coastguard Worker } rogue_reg_src_info;
160*61046927SAndroid Build Coastguard Worker 
161*61046927SAndroid Build Coastguard Worker #define ROGUE_REG_SRC_VARIANTS 8
162*61046927SAndroid Build Coastguard Worker extern const rogue_reg_src_info
163*61046927SAndroid Build Coastguard Worker    rogue_reg_lower_src_infos[ROGUE_REG_SRC_VARIANTS];
164*61046927SAndroid Build Coastguard Worker extern const rogue_reg_src_info
165*61046927SAndroid Build Coastguard Worker    rogue_reg_upper_src_infos[ROGUE_REG_SRC_VARIANTS];
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker typedef struct rogue_shader rogue_shader;
168*61046927SAndroid Build Coastguard Worker typedef struct rogue_reg rogue_reg;
169*61046927SAndroid Build Coastguard Worker typedef struct rogue_regarray rogue_regarray;
170*61046927SAndroid Build Coastguard Worker 
171*61046927SAndroid Build Coastguard Worker /** Rogue register. */
172*61046927SAndroid Build Coastguard Worker typedef struct rogue_reg {
173*61046927SAndroid Build Coastguard Worker    rogue_shader *shader; /** Pointer back to shader. */
174*61046927SAndroid Build Coastguard Worker    enum rogue_reg_class class; /** Register class. */
175*61046927SAndroid Build Coastguard Worker 
176*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_shader::regs. */
177*61046927SAndroid Build Coastguard Worker    struct list_head writes; /** List of all writes to this register. */
178*61046927SAndroid Build Coastguard Worker    struct list_head uses; /** List of all register uses. */
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    rogue_regarray *regarray;
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker    bool dirty;
183*61046927SAndroid Build Coastguard Worker    uint32_t index; /** Register index. */
184*61046927SAndroid Build Coastguard Worker 
185*61046927SAndroid Build Coastguard Worker    rogue_reg **cached;
186*61046927SAndroid Build Coastguard Worker } rogue_reg;
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker #define rogue_foreach_reg(reg, shader, class) \
189*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_reg, reg, &(shader)->regs[class], link)
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker #define rogue_foreach_reg_safe(reg, shader, class) \
192*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_reg, reg, &(shader)->regs[class], link)
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker #define REG_CACHE_KEY_COMPONENT_BITS 3
195*61046927SAndroid Build Coastguard Worker #define REG_CACHE_KEY_INDEX_BITS 28
196*61046927SAndroid Build Coastguard Worker #define REG_CACHE_KEY_VEC_BITS 1
197*61046927SAndroid Build Coastguard Worker 
198*61046927SAndroid Build Coastguard Worker struct rogue_reg_cache_key {
199*61046927SAndroid Build Coastguard Worker    union {
200*61046927SAndroid Build Coastguard Worker       struct {
201*61046927SAndroid Build Coastguard Worker          uint32_t component : REG_CACHE_KEY_COMPONENT_BITS;
202*61046927SAndroid Build Coastguard Worker          uint32_t index : REG_CACHE_KEY_INDEX_BITS;
203*61046927SAndroid Build Coastguard Worker          uint32_t vec : REG_CACHE_KEY_VEC_BITS;
204*61046927SAndroid Build Coastguard Worker       } PACKED;
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker       uint32_t val;
207*61046927SAndroid Build Coastguard Worker    } PACKED;
208*61046927SAndroid Build Coastguard Worker } PACKED;
209*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct rogue_reg_cache_key) == sizeof(uint32_t),
210*61046927SAndroid Build Coastguard Worker               "sizeof(struct rogue_reg_cache_key) != sizeof(uint32_t)");
211*61046927SAndroid Build Coastguard Worker 
212*61046927SAndroid Build Coastguard Worker static inline uint32_t
rogue_reg_cache_key(unsigned index,bool vec,unsigned component)213*61046927SAndroid Build Coastguard Worker rogue_reg_cache_key(unsigned index, bool vec, unsigned component)
214*61046927SAndroid Build Coastguard Worker {
215*61046927SAndroid Build Coastguard Worker    assert(util_last_bit(component) <= REG_CACHE_KEY_COMPONENT_BITS);
216*61046927SAndroid Build Coastguard Worker    assert(!vec || util_last_bit(index) <= REG_CACHE_KEY_INDEX_BITS);
217*61046927SAndroid Build Coastguard Worker    assert(vec || util_last_bit(index) <= 32);
218*61046927SAndroid Build Coastguard Worker    assert(util_last_bit(vec) <= REG_CACHE_KEY_VEC_BITS);
219*61046927SAndroid Build Coastguard Worker 
220*61046927SAndroid Build Coastguard Worker    if (!vec)
221*61046927SAndroid Build Coastguard Worker       return index;
222*61046927SAndroid Build Coastguard Worker 
223*61046927SAndroid Build Coastguard Worker    return (struct rogue_reg_cache_key){ .component = component,
224*61046927SAndroid Build Coastguard Worker                                         .index = index,
225*61046927SAndroid Build Coastguard Worker                                         .vec = vec }
226*61046927SAndroid Build Coastguard Worker       .val;
227*61046927SAndroid Build Coastguard Worker }
228*61046927SAndroid Build Coastguard Worker 
rogue_reg_is_unused(rogue_reg * reg)229*61046927SAndroid Build Coastguard Worker static inline bool rogue_reg_is_unused(rogue_reg *reg)
230*61046927SAndroid Build Coastguard Worker {
231*61046927SAndroid Build Coastguard Worker    return list_is_empty(&reg->uses) && list_is_empty(&reg->writes);
232*61046927SAndroid Build Coastguard Worker }
233*61046927SAndroid Build Coastguard Worker 
234*61046927SAndroid Build Coastguard Worker struct rogue_regarray_cache_key {
235*61046927SAndroid Build Coastguard Worker    union {
236*61046927SAndroid Build Coastguard Worker       struct {
237*61046927SAndroid Build Coastguard Worker          uint32_t start_index;
238*61046927SAndroid Build Coastguard Worker          enum rogue_reg_class class;
239*61046927SAndroid Build Coastguard Worker          uint16_t size;
240*61046927SAndroid Build Coastguard Worker          uint8_t __pad;
241*61046927SAndroid Build Coastguard Worker       } PACKED;
242*61046927SAndroid Build Coastguard Worker 
243*61046927SAndroid Build Coastguard Worker       uint64_t val;
244*61046927SAndroid Build Coastguard Worker    } PACKED;
245*61046927SAndroid Build Coastguard Worker } PACKED;
246*61046927SAndroid Build Coastguard Worker static_assert(sizeof(struct rogue_regarray_cache_key) == sizeof(uint64_t),
247*61046927SAndroid Build Coastguard Worker               "sizeof(struct rogue_regarray_cache_key) != sizeof(uint64_t)");
248*61046927SAndroid Build Coastguard Worker 
rogue_regarray_cache_key(unsigned size,enum rogue_reg_class class,uint32_t start_index,bool vec,uint8_t component)249*61046927SAndroid Build Coastguard Worker static inline uint64_t rogue_regarray_cache_key(unsigned size,
250*61046927SAndroid Build Coastguard Worker                                                 enum rogue_reg_class class,
251*61046927SAndroid Build Coastguard Worker                                                 uint32_t start_index,
252*61046927SAndroid Build Coastguard Worker                                                 bool vec,
253*61046927SAndroid Build Coastguard Worker                                                 uint8_t component)
254*61046927SAndroid Build Coastguard Worker {
255*61046927SAndroid Build Coastguard Worker    uint32_t reg_cache_key = rogue_reg_cache_key(start_index, vec, component);
256*61046927SAndroid Build Coastguard Worker    return (struct rogue_regarray_cache_key){ .start_index = reg_cache_key,
257*61046927SAndroid Build Coastguard Worker                                              .class = class,
258*61046927SAndroid Build Coastguard Worker                                              .size = size }
259*61046927SAndroid Build Coastguard Worker       .val;
260*61046927SAndroid Build Coastguard Worker }
261*61046927SAndroid Build Coastguard Worker 
262*61046927SAndroid Build Coastguard Worker typedef struct rogue_regarray {
263*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_shader::regarrays. */
264*61046927SAndroid Build Coastguard Worker    unsigned size; /** Number of registers in the array. */
265*61046927SAndroid Build Coastguard Worker    rogue_regarray *parent;
266*61046927SAndroid Build Coastguard Worker    struct list_head children; /** List of subarrays with this regarray as their
267*61046927SAndroid Build Coastguard Worker                                  parent. */
268*61046927SAndroid Build Coastguard Worker    struct list_head child_link; /** Link in rogue_regarray::children. */
269*61046927SAndroid Build Coastguard Worker    rogue_reg **regs; /** Registers (allocated array if this is a parent, else
270*61046927SAndroid Build Coastguard Worker                         pointer to inside parent regarray->regs). */
271*61046927SAndroid Build Coastguard Worker    rogue_regarray **cached;
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker    struct list_head writes; /** List of all writes to this register array. */
274*61046927SAndroid Build Coastguard Worker    struct list_head uses; /** List of all register array uses. */
275*61046927SAndroid Build Coastguard Worker } rogue_regarray;
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker #define rogue_foreach_regarray(regarray, shader) \
278*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_regarray, regarray, &(shader)->regarrays, link)
279*61046927SAndroid Build Coastguard Worker 
280*61046927SAndroid Build Coastguard Worker #define rogue_foreach_regarray_safe(regarray, shader) \
281*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_regarray,          \
282*61046927SAndroid Build Coastguard Worker                              regarray,                \
283*61046927SAndroid Build Coastguard Worker                              &(shader)->regarrays,    \
284*61046927SAndroid Build Coastguard Worker                              link)
285*61046927SAndroid Build Coastguard Worker 
286*61046927SAndroid Build Coastguard Worker #define rogue_foreach_subarray(subarray, regarray) \
287*61046927SAndroid Build Coastguard Worker    assert(!regarray->parent);                      \
288*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_regarray,            \
289*61046927SAndroid Build Coastguard Worker                         subarray,                  \
290*61046927SAndroid Build Coastguard Worker                         &(regarray)->children,     \
291*61046927SAndroid Build Coastguard Worker                         child_link)
292*61046927SAndroid Build Coastguard Worker 
293*61046927SAndroid Build Coastguard Worker #define rogue_foreach_subarray_safe(subarray, regarray) \
294*61046927SAndroid Build Coastguard Worker    assert(!regarray->parent);                           \
295*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_regarray,            \
296*61046927SAndroid Build Coastguard Worker                              subarray,                  \
297*61046927SAndroid Build Coastguard Worker                              &(regarray)->children,     \
298*61046927SAndroid Build Coastguard Worker                              child_link)
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker typedef struct rogue_instr rogue_instr;
301*61046927SAndroid Build Coastguard Worker 
302*61046927SAndroid Build Coastguard Worker typedef struct rogue_regarray_write {
303*61046927SAndroid Build Coastguard Worker    rogue_instr *instr;
304*61046927SAndroid Build Coastguard Worker    unsigned dst_index;
305*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_regarray::writes. */
306*61046927SAndroid Build Coastguard Worker } rogue_regarray_write;
307*61046927SAndroid Build Coastguard Worker 
308*61046927SAndroid Build Coastguard Worker #define rogue_foreach_regarray_write(write, regarray) \
309*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_regarray_write, write, &(regarray)->writes, link)
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker #define rogue_foreach_regarray_write_safe(write, regarray) \
312*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_regarray_write,         \
313*61046927SAndroid Build Coastguard Worker                              write,                        \
314*61046927SAndroid Build Coastguard Worker                              &(regarray)->writes,          \
315*61046927SAndroid Build Coastguard Worker                              link)
316*61046927SAndroid Build Coastguard Worker 
317*61046927SAndroid Build Coastguard Worker typedef struct rogue_regarray_use {
318*61046927SAndroid Build Coastguard Worker    rogue_instr *instr;
319*61046927SAndroid Build Coastguard Worker    unsigned src_index;
320*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_regarray::uses. */
321*61046927SAndroid Build Coastguard Worker } rogue_regarray_use;
322*61046927SAndroid Build Coastguard Worker 
323*61046927SAndroid Build Coastguard Worker #define rogue_foreach_regarray_use(use, regarray) \
324*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_regarray_use, use, &(regarray)->uses, link)
325*61046927SAndroid Build Coastguard Worker 
326*61046927SAndroid Build Coastguard Worker #define rogue_foreach_regarray_use_safe(use, regarray) \
327*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_regarray_use, use, &(regarray)->uses, link)
328*61046927SAndroid Build Coastguard Worker 
329*61046927SAndroid Build Coastguard Worker /** Instruction phases, used in bitset. */
330*61046927SAndroid Build Coastguard Worker enum rogue_instr_phase {
331*61046927SAndroid Build Coastguard Worker    /** Main/ALU (and backend) instructions. */
332*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_0,
333*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_1,
334*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_2_PCK,
335*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_2_TST,
336*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_2_MOV,
337*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_BACKEND,
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_COUNT,
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker    /** Control instructions (no co-issuing). */
342*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_CTRL = ROGUE_INSTR_PHASE_0,
343*61046927SAndroid Build Coastguard Worker 
344*61046927SAndroid Build Coastguard Worker    /** Bitwise instructions. */
345*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_0_BITMASK = ROGUE_INSTR_PHASE_0,
346*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_0_SHIFT1 = ROGUE_INSTR_PHASE_1,
347*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_0_COUNT = ROGUE_INSTR_PHASE_2_PCK,
348*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_1_LOGICAL = ROGUE_INSTR_PHASE_2_TST,
349*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_2_SHIFT2 = ROGUE_INSTR_PHASE_2_MOV,
350*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_2_TEST = ROGUE_INSTR_PHASE_BACKEND,
351*61046927SAndroid Build Coastguard Worker 
352*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_PHASE_INVALID = ~0,
353*61046927SAndroid Build Coastguard Worker };
354*61046927SAndroid Build Coastguard Worker 
355*61046927SAndroid Build Coastguard Worker /* TODO: put into bitscan.h */
356*61046927SAndroid Build Coastguard Worker #define u_foreach_bit64_rev(b, dword)                  \
357*61046927SAndroid Build Coastguard Worker    for (uint64_t __dword = (dword), b;                 \
358*61046927SAndroid Build Coastguard Worker         ((b) = util_last_bit64(__dword) - 1, __dword); \
359*61046927SAndroid Build Coastguard Worker         __dword &= ~(1ull << (b)))
360*61046927SAndroid Build Coastguard Worker 
361*61046927SAndroid Build Coastguard Worker #define rogue_foreach_phase_in_set(p, phases) u_foreach_bit64(p, phases)
362*61046927SAndroid Build Coastguard Worker #define rogue_foreach_phase_in_set_rev(p, phases) u_foreach_bit64_rev(p, phases)
363*61046927SAndroid Build Coastguard Worker 
364*61046927SAndroid Build Coastguard Worker #define rogue_foreach_mod_in_set(m, mods) u_foreach_bit64(m, mods)
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker /** Rogue basic block. */
367*61046927SAndroid Build Coastguard Worker typedef struct rogue_block {
368*61046927SAndroid Build Coastguard Worker    rogue_shader *shader; /** Shader containing this block. */
369*61046927SAndroid Build Coastguard Worker    struct list_head instrs; /** Basic block instruction list. */
370*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_shader::blocks. */
371*61046927SAndroid Build Coastguard Worker 
372*61046927SAndroid Build Coastguard Worker    struct list_head uses; /** List of all block uses. */
373*61046927SAndroid Build Coastguard Worker 
374*61046927SAndroid Build Coastguard Worker    unsigned index; /** Block index. */
375*61046927SAndroid Build Coastguard Worker    const char *label; /** Block label. */
376*61046927SAndroid Build Coastguard Worker } rogue_block;
377*61046927SAndroid Build Coastguard Worker 
378*61046927SAndroid Build Coastguard Worker #define rogue_foreach_block(block, shader) \
379*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_block, block, &(shader)->blocks, link)
380*61046927SAndroid Build Coastguard Worker 
381*61046927SAndroid Build Coastguard Worker #define rogue_foreach_block_safe(block, shader) \
382*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_block, block, &(shader)->blocks, link)
383*61046927SAndroid Build Coastguard Worker 
384*61046927SAndroid Build Coastguard Worker #define rogue_foreach_block_rev(block, shader) \
385*61046927SAndroid Build Coastguard Worker    list_for_each_entry_rev (rogue_block, block, &(shader)->blocks, link)
386*61046927SAndroid Build Coastguard Worker 
387*61046927SAndroid Build Coastguard Worker #define rogue_foreach_block_safe_rev(block, shader) \
388*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe_rev (rogue_block, block, &(shader)->blocks, link)
389*61046927SAndroid Build Coastguard Worker 
390*61046927SAndroid Build Coastguard Worker /** Rogue execution conditions. */
391*61046927SAndroid Build Coastguard Worker enum rogue_exec_cond {
392*61046927SAndroid Build Coastguard Worker    ROGUE_EXEC_COND_INVALID = 0,
393*61046927SAndroid Build Coastguard Worker 
394*61046927SAndroid Build Coastguard Worker    ROGUE_EXEC_COND_PE_TRUE,
395*61046927SAndroid Build Coastguard Worker    ROGUE_EXEC_COND_P0_TRUE,
396*61046927SAndroid Build Coastguard Worker    ROGUE_EXEC_COND_PE_ANY,
397*61046927SAndroid Build Coastguard Worker    ROGUE_EXEC_COND_P0_FALSE,
398*61046927SAndroid Build Coastguard Worker 
399*61046927SAndroid Build Coastguard Worker    ROGUE_EXEC_COND_COUNT,
400*61046927SAndroid Build Coastguard Worker };
401*61046927SAndroid Build Coastguard Worker 
402*61046927SAndroid Build Coastguard Worker extern const char *rogue_exec_cond_str[ROGUE_EXEC_COND_COUNT];
403*61046927SAndroid Build Coastguard Worker 
404*61046927SAndroid Build Coastguard Worker /** Rogue instruction type. */
405*61046927SAndroid Build Coastguard Worker enum rogue_instr_type {
406*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_TYPE_INVALID = 0,
407*61046927SAndroid Build Coastguard Worker 
408*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_TYPE_ALU, /** ALU instruction. */
409*61046927SAndroid Build Coastguard Worker    /* ROGUE_INSTR_TYPE_CMPLX, */ /** TODO: Complex/trig instruction (these take
410*61046927SAndroid Build Coastguard Worker                                     up the whole pipeline). */
411*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_TYPE_BACKEND, /** Backend instruction. */
412*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_TYPE_CTRL, /** Control instruction. */
413*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_TYPE_BITWISE, /** Bitwise instruction. */
414*61046927SAndroid Build Coastguard Worker    /* ROGUE_INSTR_TYPE_F16SOP, */ /** TODO: F16 sum-of-products instruction. */
415*61046927SAndroid Build Coastguard Worker 
416*61046927SAndroid Build Coastguard Worker    ROGUE_INSTR_TYPE_COUNT,
417*61046927SAndroid Build Coastguard Worker };
418*61046927SAndroid Build Coastguard Worker 
419*61046927SAndroid Build Coastguard Worker extern const char *rogue_instr_type_str[ROGUE_INSTR_TYPE_COUNT];
420*61046927SAndroid Build Coastguard Worker 
421*61046927SAndroid Build Coastguard Worker enum rogue_alu {
422*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_INVALID = 0,
423*61046927SAndroid Build Coastguard Worker 
424*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_MAIN,
425*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_BITWISE,
426*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_CONTROL,
427*61046927SAndroid Build Coastguard Worker 
428*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_COUNT,
429*61046927SAndroid Build Coastguard Worker };
430*61046927SAndroid Build Coastguard Worker 
431*61046927SAndroid Build Coastguard Worker extern const char *const rogue_alu_str[ROGUE_ALU_COUNT];
432*61046927SAndroid Build Coastguard Worker 
433*61046927SAndroid Build Coastguard Worker extern const char
434*61046927SAndroid Build Coastguard Worker    *const rogue_instr_phase_str[ROGUE_ALU_COUNT][ROGUE_INSTR_PHASE_COUNT];
435*61046927SAndroid Build Coastguard Worker 
436*61046927SAndroid Build Coastguard Worker typedef struct rogue_instr_group rogue_instr_group;
437*61046927SAndroid Build Coastguard Worker 
438*61046927SAndroid Build Coastguard Worker /** Rogue instruction. */
439*61046927SAndroid Build Coastguard Worker typedef struct rogue_instr {
440*61046927SAndroid Build Coastguard Worker    enum rogue_instr_type type; /** Instruction type. */
441*61046927SAndroid Build Coastguard Worker 
442*61046927SAndroid Build Coastguard Worker    enum rogue_exec_cond exec_cond;
443*61046927SAndroid Build Coastguard Worker    unsigned repeat;
444*61046927SAndroid Build Coastguard Worker    bool end;
445*61046927SAndroid Build Coastguard Worker 
446*61046927SAndroid Build Coastguard Worker    union {
447*61046927SAndroid Build Coastguard Worker       struct list_head link; /** Link in rogue_block::instrs. */
448*61046927SAndroid Build Coastguard Worker       rogue_instr_group *group; /** Instruction group containing this
449*61046927SAndroid Build Coastguard Worker                                    instruction. */
450*61046927SAndroid Build Coastguard Worker    };
451*61046927SAndroid Build Coastguard Worker 
452*61046927SAndroid Build Coastguard Worker    rogue_block *block; /** Basic block containing this instruction. */
453*61046927SAndroid Build Coastguard Worker 
454*61046927SAndroid Build Coastguard Worker    bool group_next; /** Group next instruction with this one. */
455*61046927SAndroid Build Coastguard Worker    unsigned index; /** Instruction index. */
456*61046927SAndroid Build Coastguard Worker    char *comment; /** Comment string. */
457*61046927SAndroid Build Coastguard Worker } rogue_instr;
458*61046927SAndroid Build Coastguard Worker 
rogue_set_instr_group_next(rogue_instr * instr,bool group_next)459*61046927SAndroid Build Coastguard Worker static inline void rogue_set_instr_group_next(rogue_instr *instr,
460*61046927SAndroid Build Coastguard Worker                                               bool group_next)
461*61046927SAndroid Build Coastguard Worker {
462*61046927SAndroid Build Coastguard Worker    instr->group_next = group_next;
463*61046927SAndroid Build Coastguard Worker }
464*61046927SAndroid Build Coastguard Worker 
465*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_in_block(instr, block) \
466*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_instr, instr, &(block)->instrs, link)
467*61046927SAndroid Build Coastguard Worker 
468*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_in_block_safe(instr, block) \
469*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_instr, instr, &(block)->instrs, link)
470*61046927SAndroid Build Coastguard Worker 
471*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_in_block_rev(instr, block) \
472*61046927SAndroid Build Coastguard Worker    list_for_each_entry_rev (rogue_instr, instr, &(block)->instrs, link)
473*61046927SAndroid Build Coastguard Worker 
474*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_in_block_safe_rev(instr, block) \
475*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe_rev (rogue_instr, instr, &(block)->instrs, link)
476*61046927SAndroid Build Coastguard Worker 
477*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_in_shader(instr, shader) \
478*61046927SAndroid Build Coastguard Worker    rogue_foreach_block (_block, (shader))            \
479*61046927SAndroid Build Coastguard Worker       rogue_foreach_instr_in_block ((instr), _block)
480*61046927SAndroid Build Coastguard Worker 
481*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_in_shader_safe(instr, shader) \
482*61046927SAndroid Build Coastguard Worker    rogue_foreach_block_safe (_block, (shader))            \
483*61046927SAndroid Build Coastguard Worker       rogue_foreach_instr_in_block_safe ((instr), _block)
484*61046927SAndroid Build Coastguard Worker 
485*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_in_shader_rev(instr, shader) \
486*61046927SAndroid Build Coastguard Worker    rogue_foreach_block_rev (_block, (shader))            \
487*61046927SAndroid Build Coastguard Worker       rogue_foreach_instr_in_block_rev ((instr), _block)
488*61046927SAndroid Build Coastguard Worker 
489*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_in_shader_safe_rev(instr, shader) \
490*61046927SAndroid Build Coastguard Worker    rogue_foreach_block_safe_rev (_block, (shader))            \
491*61046927SAndroid Build Coastguard Worker       rogue_foreach_instr_in_block_safe_rev ((instr), _block)
492*61046927SAndroid Build Coastguard Worker 
rogue_set_instr_exec_cond(rogue_instr * instr,enum rogue_exec_cond exec_cond)493*61046927SAndroid Build Coastguard Worker static inline void rogue_set_instr_exec_cond(rogue_instr *instr,
494*61046927SAndroid Build Coastguard Worker                                              enum rogue_exec_cond exec_cond)
495*61046927SAndroid Build Coastguard Worker {
496*61046927SAndroid Build Coastguard Worker    instr->exec_cond = exec_cond;
497*61046927SAndroid Build Coastguard Worker }
498*61046927SAndroid Build Coastguard Worker 
rogue_set_instr_repeat(rogue_instr * instr,unsigned repeat)499*61046927SAndroid Build Coastguard Worker static inline void rogue_set_instr_repeat(rogue_instr *instr, unsigned repeat)
500*61046927SAndroid Build Coastguard Worker {
501*61046927SAndroid Build Coastguard Worker    instr->repeat = repeat;
502*61046927SAndroid Build Coastguard Worker }
503*61046927SAndroid Build Coastguard Worker 
rogue_add_instr_comment(rogue_instr * instr,const char * comment)504*61046927SAndroid Build Coastguard Worker static inline void rogue_add_instr_comment(rogue_instr *instr,
505*61046927SAndroid Build Coastguard Worker                                            const char *comment)
506*61046927SAndroid Build Coastguard Worker {
507*61046927SAndroid Build Coastguard Worker    if (!instr->comment)
508*61046927SAndroid Build Coastguard Worker       instr->comment = ralloc_strdup(instr, comment);
509*61046927SAndroid Build Coastguard Worker    else
510*61046927SAndroid Build Coastguard Worker       ralloc_asprintf_append(&instr->comment, ", %s", comment);
511*61046927SAndroid Build Coastguard Worker }
512*61046927SAndroid Build Coastguard Worker 
rogue_copy_instr_comment(rogue_instr * to,const rogue_instr * from)513*61046927SAndroid Build Coastguard Worker static inline void rogue_copy_instr_comment(rogue_instr *to,
514*61046927SAndroid Build Coastguard Worker                                             const rogue_instr *from)
515*61046927SAndroid Build Coastguard Worker {
516*61046927SAndroid Build Coastguard Worker    if (!from->comment)
517*61046927SAndroid Build Coastguard Worker       return;
518*61046927SAndroid Build Coastguard Worker 
519*61046927SAndroid Build Coastguard Worker    rogue_add_instr_comment(to, from->comment);
520*61046927SAndroid Build Coastguard Worker }
521*61046927SAndroid Build Coastguard Worker 
rogue_merge_instr_comment(rogue_instr * to,const rogue_instr * from,const char * comment)522*61046927SAndroid Build Coastguard Worker static inline void rogue_merge_instr_comment(rogue_instr *to,
523*61046927SAndroid Build Coastguard Worker                                              const rogue_instr *from,
524*61046927SAndroid Build Coastguard Worker                                              const char *comment)
525*61046927SAndroid Build Coastguard Worker {
526*61046927SAndroid Build Coastguard Worker    rogue_copy_instr_comment(to, from);
527*61046927SAndroid Build Coastguard Worker    rogue_add_instr_comment(to, comment);
528*61046927SAndroid Build Coastguard Worker }
529*61046927SAndroid Build Coastguard Worker 
530*61046927SAndroid Build Coastguard Worker typedef union rogue_imm_t {
531*61046927SAndroid Build Coastguard Worker    float f32;
532*61046927SAndroid Build Coastguard Worker    int32_t s32;
533*61046927SAndroid Build Coastguard Worker    uint32_t u32;
534*61046927SAndroid Build Coastguard Worker } rogue_imm_t;
535*61046927SAndroid Build Coastguard Worker 
536*61046927SAndroid Build Coastguard Worker enum rogue_io {
537*61046927SAndroid Build Coastguard Worker    ROGUE_IO_INVALID = 0,
538*61046927SAndroid Build Coastguard Worker 
539*61046927SAndroid Build Coastguard Worker    /* Lower sources. */
540*61046927SAndroid Build Coastguard Worker    ROGUE_IO_S0,
541*61046927SAndroid Build Coastguard Worker    ROGUE_IO_S1,
542*61046927SAndroid Build Coastguard Worker    ROGUE_IO_S2,
543*61046927SAndroid Build Coastguard Worker 
544*61046927SAndroid Build Coastguard Worker    /* Upper sources. */
545*61046927SAndroid Build Coastguard Worker    ROGUE_IO_S3,
546*61046927SAndroid Build Coastguard Worker    ROGUE_IO_S4,
547*61046927SAndroid Build Coastguard Worker    ROGUE_IO_S5,
548*61046927SAndroid Build Coastguard Worker 
549*61046927SAndroid Build Coastguard Worker    /* Destinations. */
550*61046927SAndroid Build Coastguard Worker    ROGUE_IO_W0,
551*61046927SAndroid Build Coastguard Worker    ROGUE_IO_W1,
552*61046927SAndroid Build Coastguard Worker 
553*61046927SAndroid Build Coastguard Worker    /* Internal selectors. */
554*61046927SAndroid Build Coastguard Worker    ROGUE_IO_IS0,
555*61046927SAndroid Build Coastguard Worker    ROGUE_IO_IS1,
556*61046927SAndroid Build Coastguard Worker    ROGUE_IO_IS2,
557*61046927SAndroid Build Coastguard Worker    ROGUE_IO_IS3,
558*61046927SAndroid Build Coastguard Worker    ROGUE_IO_IS4,
559*61046927SAndroid Build Coastguard Worker    ROGUE_IO_IS5,
560*61046927SAndroid Build Coastguard Worker 
561*61046927SAndroid Build Coastguard Worker    /* Feedthroughs. */
562*61046927SAndroid Build Coastguard Worker    ROGUE_IO_FT0,
563*61046927SAndroid Build Coastguard Worker    ROGUE_IO_FT1,
564*61046927SAndroid Build Coastguard Worker    ROGUE_IO_FT2,
565*61046927SAndroid Build Coastguard Worker    ROGUE_IO_FTE,
566*61046927SAndroid Build Coastguard Worker 
567*61046927SAndroid Build Coastguard Worker    /* Only used for bitwise instructions. */
568*61046927SAndroid Build Coastguard Worker    ROGUE_IO_FT3,
569*61046927SAndroid Build Coastguard Worker    ROGUE_IO_FT4,
570*61046927SAndroid Build Coastguard Worker    ROGUE_IO_FT5,
571*61046927SAndroid Build Coastguard Worker 
572*61046927SAndroid Build Coastguard Worker    /* Test output feedthrough. */
573*61046927SAndroid Build Coastguard Worker    ROGUE_IO_FTT,
574*61046927SAndroid Build Coastguard Worker 
575*61046927SAndroid Build Coastguard Worker    /* Predicate register. */
576*61046927SAndroid Build Coastguard Worker    ROGUE_IO_P0,
577*61046927SAndroid Build Coastguard Worker 
578*61046927SAndroid Build Coastguard Worker    /* For optional instruction arguments. */
579*61046927SAndroid Build Coastguard Worker    ROGUE_IO_NONE,
580*61046927SAndroid Build Coastguard Worker 
581*61046927SAndroid Build Coastguard Worker    ROGUE_IO_COUNT,
582*61046927SAndroid Build Coastguard Worker };
583*61046927SAndroid Build Coastguard Worker 
rogue_io_is_src(enum rogue_io io)584*61046927SAndroid Build Coastguard Worker static inline bool rogue_io_is_src(enum rogue_io io)
585*61046927SAndroid Build Coastguard Worker {
586*61046927SAndroid Build Coastguard Worker    return (io >= ROGUE_IO_S0 && io <= ROGUE_IO_S5);
587*61046927SAndroid Build Coastguard Worker }
588*61046927SAndroid Build Coastguard Worker 
rogue_io_is_dst(enum rogue_io io)589*61046927SAndroid Build Coastguard Worker static inline bool rogue_io_is_dst(enum rogue_io io)
590*61046927SAndroid Build Coastguard Worker {
591*61046927SAndroid Build Coastguard Worker    return (io >= ROGUE_IO_W0 && io <= ROGUE_IO_W1);
592*61046927SAndroid Build Coastguard Worker }
593*61046927SAndroid Build Coastguard Worker 
rogue_io_is_iss(enum rogue_io io)594*61046927SAndroid Build Coastguard Worker static inline bool rogue_io_is_iss(enum rogue_io io)
595*61046927SAndroid Build Coastguard Worker {
596*61046927SAndroid Build Coastguard Worker    return (io >= ROGUE_IO_IS0 && io <= ROGUE_IO_IS5);
597*61046927SAndroid Build Coastguard Worker }
598*61046927SAndroid Build Coastguard Worker 
rogue_io_is_ft(enum rogue_io io)599*61046927SAndroid Build Coastguard Worker static inline bool rogue_io_is_ft(enum rogue_io io)
600*61046927SAndroid Build Coastguard Worker {
601*61046927SAndroid Build Coastguard Worker    return (io >= ROGUE_IO_FT0 && io <= ROGUE_IO_FTE);
602*61046927SAndroid Build Coastguard Worker }
603*61046927SAndroid Build Coastguard Worker 
rogue_io_is_none(enum rogue_io io)604*61046927SAndroid Build Coastguard Worker static inline bool rogue_io_is_none(enum rogue_io io)
605*61046927SAndroid Build Coastguard Worker {
606*61046927SAndroid Build Coastguard Worker    return io == ROGUE_IO_NONE;
607*61046927SAndroid Build Coastguard Worker }
608*61046927SAndroid Build Coastguard Worker 
609*61046927SAndroid Build Coastguard Worker typedef struct rogue_io_info {
610*61046927SAndroid Build Coastguard Worker    const char *str;
611*61046927SAndroid Build Coastguard Worker } rogue_io_info;
612*61046927SAndroid Build Coastguard Worker 
613*61046927SAndroid Build Coastguard Worker extern const rogue_io_info rogue_io_infos[ROGUE_IO_COUNT];
614*61046927SAndroid Build Coastguard Worker 
rogue_io_supported(enum rogue_io io,uint64_t supported_ios)615*61046927SAndroid Build Coastguard Worker static inline bool rogue_io_supported(enum rogue_io io, uint64_t supported_ios)
616*61046927SAndroid Build Coastguard Worker {
617*61046927SAndroid Build Coastguard Worker    return !!(BITFIELD64_BIT(io - 1) & supported_ios);
618*61046927SAndroid Build Coastguard Worker }
619*61046927SAndroid Build Coastguard Worker 
620*61046927SAndroid Build Coastguard Worker #define ROGUE_DRCS 2
621*61046927SAndroid Build Coastguard Worker 
622*61046927SAndroid Build Coastguard Worker typedef struct rogue_drc_trxn {
623*61046927SAndroid Build Coastguard Worker    rogue_instr *acquire;
624*61046927SAndroid Build Coastguard Worker    rogue_instr *release;
625*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_shader::drc_trxns[0/1]. */
626*61046927SAndroid Build Coastguard Worker } rogue_drc_trxn;
627*61046927SAndroid Build Coastguard Worker 
628*61046927SAndroid Build Coastguard Worker #define rogue_foreach_drc_trxn(drc_trxn, shader, index) \
629*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_drc_trxn,                 \
630*61046927SAndroid Build Coastguard Worker                         drc_trxn,                       \
631*61046927SAndroid Build Coastguard Worker                         &(shader)->drc_trxns[index],    \
632*61046927SAndroid Build Coastguard Worker                         link)
633*61046927SAndroid Build Coastguard Worker 
634*61046927SAndroid Build Coastguard Worker #define rogue_foreach_drc_trxn_safe(drc_trxn, shader, index) \
635*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_drc_trxn,                 \
636*61046927SAndroid Build Coastguard Worker                              drc_trxn,                       \
637*61046927SAndroid Build Coastguard Worker                              &(shader)->drc_trxns[index],    \
638*61046927SAndroid Build Coastguard Worker                              link)
639*61046927SAndroid Build Coastguard Worker 
640*61046927SAndroid Build Coastguard Worker enum rogue_ref_type {
641*61046927SAndroid Build Coastguard Worker    ROGUE_REF_TYPE_INVALID = 0,
642*61046927SAndroid Build Coastguard Worker 
643*61046927SAndroid Build Coastguard Worker    ROGUE_REF_TYPE_VAL, /* Immediate that is not going to be replaced with a
644*61046927SAndroid Build Coastguard Worker                           register reference. */
645*61046927SAndroid Build Coastguard Worker 
646*61046927SAndroid Build Coastguard Worker    ROGUE_REF_TYPE_REG,
647*61046927SAndroid Build Coastguard Worker    ROGUE_REF_TYPE_REGARRAY,
648*61046927SAndroid Build Coastguard Worker 
649*61046927SAndroid Build Coastguard Worker    ROGUE_REF_TYPE_IMM, /* Immediate that is going to be replaced with a register
650*61046927SAndroid Build Coastguard Worker                           reference. */
651*61046927SAndroid Build Coastguard Worker 
652*61046927SAndroid Build Coastguard Worker    ROGUE_REF_TYPE_IO,
653*61046927SAndroid Build Coastguard Worker 
654*61046927SAndroid Build Coastguard Worker    ROGUE_REF_TYPE_DRC,
655*61046927SAndroid Build Coastguard Worker 
656*61046927SAndroid Build Coastguard Worker    ROGUE_REF_TYPE_COUNT,
657*61046927SAndroid Build Coastguard Worker };
658*61046927SAndroid Build Coastguard Worker 
659*61046927SAndroid Build Coastguard Worker typedef struct rogue_drc {
660*61046927SAndroid Build Coastguard Worker    unsigned index;
661*61046927SAndroid Build Coastguard Worker    union {
662*61046927SAndroid Build Coastguard Worker       rogue_drc_trxn trxn;
663*61046927SAndroid Build Coastguard Worker       rogue_drc_trxn *trxn_ptr;
664*61046927SAndroid Build Coastguard Worker    };
665*61046927SAndroid Build Coastguard Worker } rogue_drc;
666*61046927SAndroid Build Coastguard Worker 
667*61046927SAndroid Build Coastguard Worker typedef struct rogue_imm_use {
668*61046927SAndroid Build Coastguard Worker    rogue_instr *instr;
669*61046927SAndroid Build Coastguard Worker    unsigned src_index;
670*61046927SAndroid Build Coastguard Worker    rogue_imm_t *imm;
671*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_shader::imm_uses. */
672*61046927SAndroid Build Coastguard Worker } rogue_imm_use;
673*61046927SAndroid Build Coastguard Worker 
674*61046927SAndroid Build Coastguard Worker #define rogue_foreach_imm_use(imm_use, shader) \
675*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_imm_use, imm_use, &(shader)->imm_uses, link)
676*61046927SAndroid Build Coastguard Worker 
677*61046927SAndroid Build Coastguard Worker #define rogue_foreach_imm_use_safe(imm_use, shader) \
678*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_imm_use, imm_use, &(shader)->imm_uses, link)
679*61046927SAndroid Build Coastguard Worker 
680*61046927SAndroid Build Coastguard Worker typedef struct rogue_imm {
681*61046927SAndroid Build Coastguard Worker    rogue_imm_t imm;
682*61046927SAndroid Build Coastguard Worker    rogue_imm_use use;
683*61046927SAndroid Build Coastguard Worker } rogue_imm;
684*61046927SAndroid Build Coastguard Worker 
685*61046927SAndroid Build Coastguard Worker typedef struct rogue_ref {
686*61046927SAndroid Build Coastguard Worker    enum rogue_ref_type type;
687*61046927SAndroid Build Coastguard Worker 
688*61046927SAndroid Build Coastguard Worker    union {
689*61046927SAndroid Build Coastguard Worker       unsigned val;
690*61046927SAndroid Build Coastguard Worker       rogue_imm imm;
691*61046927SAndroid Build Coastguard Worker       rogue_reg *reg;
692*61046927SAndroid Build Coastguard Worker       rogue_regarray *regarray;
693*61046927SAndroid Build Coastguard Worker       enum rogue_io io;
694*61046927SAndroid Build Coastguard Worker       rogue_drc drc;
695*61046927SAndroid Build Coastguard Worker    };
696*61046927SAndroid Build Coastguard Worker } rogue_ref;
697*61046927SAndroid Build Coastguard Worker 
rogue_ref_type_supported(enum rogue_ref_type type,uint64_t supported_types)698*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_type_supported(enum rogue_ref_type type,
699*61046927SAndroid Build Coastguard Worker                                             uint64_t supported_types)
700*61046927SAndroid Build Coastguard Worker {
701*61046927SAndroid Build Coastguard Worker    return !!(BITFIELD64_BIT(type - 1) & supported_types);
702*61046927SAndroid Build Coastguard Worker }
703*61046927SAndroid Build Coastguard Worker 
704*61046927SAndroid Build Coastguard Worker /**
705*61046927SAndroid Build Coastguard Worker  * \brief Returns a reference to a value.
706*61046927SAndroid Build Coastguard Worker  *
707*61046927SAndroid Build Coastguard Worker  * \param[in] val The value.
708*61046927SAndroid Build Coastguard Worker  * \return The reference.
709*61046927SAndroid Build Coastguard Worker  */
rogue_ref_val(unsigned val)710*61046927SAndroid Build Coastguard Worker static inline rogue_ref rogue_ref_val(unsigned val)
711*61046927SAndroid Build Coastguard Worker {
712*61046927SAndroid Build Coastguard Worker    return (rogue_ref){
713*61046927SAndroid Build Coastguard Worker       .type = ROGUE_REF_TYPE_VAL,
714*61046927SAndroid Build Coastguard Worker       .val = val,
715*61046927SAndroid Build Coastguard Worker    };
716*61046927SAndroid Build Coastguard Worker }
717*61046927SAndroid Build Coastguard Worker 
718*61046927SAndroid Build Coastguard Worker /**
719*61046927SAndroid Build Coastguard Worker  * \brief Returns a reference to a register.
720*61046927SAndroid Build Coastguard Worker  *
721*61046927SAndroid Build Coastguard Worker  * \param[in] reg The register.
722*61046927SAndroid Build Coastguard Worker  * \return The reference.
723*61046927SAndroid Build Coastguard Worker  */
rogue_ref_reg(rogue_reg * reg)724*61046927SAndroid Build Coastguard Worker static inline rogue_ref rogue_ref_reg(rogue_reg *reg)
725*61046927SAndroid Build Coastguard Worker {
726*61046927SAndroid Build Coastguard Worker    return (rogue_ref){
727*61046927SAndroid Build Coastguard Worker       .type = ROGUE_REF_TYPE_REG,
728*61046927SAndroid Build Coastguard Worker       .reg = reg,
729*61046927SAndroid Build Coastguard Worker    };
730*61046927SAndroid Build Coastguard Worker }
731*61046927SAndroid Build Coastguard Worker 
732*61046927SAndroid Build Coastguard Worker /**
733*61046927SAndroid Build Coastguard Worker  * \brief Returns a reference to a register array.
734*61046927SAndroid Build Coastguard Worker  *
735*61046927SAndroid Build Coastguard Worker  * \param[in] regarray The register array.
736*61046927SAndroid Build Coastguard Worker  * \return The reference.
737*61046927SAndroid Build Coastguard Worker  */
rogue_ref_regarray(rogue_regarray * regarray)738*61046927SAndroid Build Coastguard Worker static inline rogue_ref rogue_ref_regarray(rogue_regarray *regarray)
739*61046927SAndroid Build Coastguard Worker {
740*61046927SAndroid Build Coastguard Worker    return (rogue_ref){
741*61046927SAndroid Build Coastguard Worker       .type = ROGUE_REF_TYPE_REGARRAY,
742*61046927SAndroid Build Coastguard Worker       .regarray = regarray,
743*61046927SAndroid Build Coastguard Worker    };
744*61046927SAndroid Build Coastguard Worker }
745*61046927SAndroid Build Coastguard Worker 
rogue_ref_imm(uint32_t imm)746*61046927SAndroid Build Coastguard Worker static inline rogue_ref rogue_ref_imm(uint32_t imm)
747*61046927SAndroid Build Coastguard Worker {
748*61046927SAndroid Build Coastguard Worker    return (rogue_ref){
749*61046927SAndroid Build Coastguard Worker       .type = ROGUE_REF_TYPE_IMM,
750*61046927SAndroid Build Coastguard Worker       .imm.imm.u32 = imm,
751*61046927SAndroid Build Coastguard Worker    };
752*61046927SAndroid Build Coastguard Worker }
753*61046927SAndroid Build Coastguard Worker 
rogue_ref_io(enum rogue_io io)754*61046927SAndroid Build Coastguard Worker static inline rogue_ref rogue_ref_io(enum rogue_io io)
755*61046927SAndroid Build Coastguard Worker {
756*61046927SAndroid Build Coastguard Worker    return (rogue_ref){
757*61046927SAndroid Build Coastguard Worker       .type = ROGUE_REF_TYPE_IO,
758*61046927SAndroid Build Coastguard Worker       .io = io,
759*61046927SAndroid Build Coastguard Worker    };
760*61046927SAndroid Build Coastguard Worker }
761*61046927SAndroid Build Coastguard Worker 
rogue_ref_drc(unsigned index)762*61046927SAndroid Build Coastguard Worker static inline rogue_ref rogue_ref_drc(unsigned index)
763*61046927SAndroid Build Coastguard Worker {
764*61046927SAndroid Build Coastguard Worker    return (rogue_ref){
765*61046927SAndroid Build Coastguard Worker       .type = ROGUE_REF_TYPE_DRC,
766*61046927SAndroid Build Coastguard Worker       .drc.index = index,
767*61046927SAndroid Build Coastguard Worker    };
768*61046927SAndroid Build Coastguard Worker }
769*61046927SAndroid Build Coastguard Worker 
rogue_ref_drc_trxn(unsigned index,rogue_drc_trxn * drc_trxn)770*61046927SAndroid Build Coastguard Worker static inline rogue_ref rogue_ref_drc_trxn(unsigned index,
771*61046927SAndroid Build Coastguard Worker                                            rogue_drc_trxn *drc_trxn)
772*61046927SAndroid Build Coastguard Worker {
773*61046927SAndroid Build Coastguard Worker    return (rogue_ref){
774*61046927SAndroid Build Coastguard Worker       .type = ROGUE_REF_TYPE_DRC,
775*61046927SAndroid Build Coastguard Worker       .drc.index = index,
776*61046927SAndroid Build Coastguard Worker       .drc.trxn_ptr = drc_trxn,
777*61046927SAndroid Build Coastguard Worker    };
778*61046927SAndroid Build Coastguard Worker }
779*61046927SAndroid Build Coastguard Worker 
rogue_ref_null(void)780*61046927SAndroid Build Coastguard Worker static inline rogue_ref rogue_ref_null(void)
781*61046927SAndroid Build Coastguard Worker {
782*61046927SAndroid Build Coastguard Worker    return (rogue_ref){};
783*61046927SAndroid Build Coastguard Worker }
784*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_imm(const rogue_ref * ref)785*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_imm(const rogue_ref *ref)
786*61046927SAndroid Build Coastguard Worker {
787*61046927SAndroid Build Coastguard Worker    return ref->type == ROGUE_REF_TYPE_IMM;
788*61046927SAndroid Build Coastguard Worker }
789*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_val(const rogue_ref * ref)790*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_val(const rogue_ref *ref)
791*61046927SAndroid Build Coastguard Worker {
792*61046927SAndroid Build Coastguard Worker    return ref->type == ROGUE_REF_TYPE_VAL;
793*61046927SAndroid Build Coastguard Worker }
794*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_reg(const rogue_ref * ref)795*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_reg(const rogue_ref *ref)
796*61046927SAndroid Build Coastguard Worker {
797*61046927SAndroid Build Coastguard Worker    return ref->type == ROGUE_REF_TYPE_REG;
798*61046927SAndroid Build Coastguard Worker }
799*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_special_reg(const rogue_ref * ref)800*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_special_reg(const rogue_ref *ref)
801*61046927SAndroid Build Coastguard Worker {
802*61046927SAndroid Build Coastguard Worker    return rogue_ref_is_reg(ref) && ref->reg->class == ROGUE_REG_CLASS_SPECIAL;
803*61046927SAndroid Build Coastguard Worker }
804*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_regarray(const rogue_ref * ref)805*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_regarray(const rogue_ref *ref)
806*61046927SAndroid Build Coastguard Worker {
807*61046927SAndroid Build Coastguard Worker    return ref->type == ROGUE_REF_TYPE_REGARRAY;
808*61046927SAndroid Build Coastguard Worker }
809*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_reg_or_regarray(const rogue_ref * ref)810*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_reg_or_regarray(const rogue_ref *ref)
811*61046927SAndroid Build Coastguard Worker {
812*61046927SAndroid Build Coastguard Worker    return rogue_ref_is_reg(ref) || rogue_ref_is_regarray(ref);
813*61046927SAndroid Build Coastguard Worker }
814*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_io(const rogue_ref * ref)815*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_io(const rogue_ref *ref)
816*61046927SAndroid Build Coastguard Worker {
817*61046927SAndroid Build Coastguard Worker    return ref->type == ROGUE_REF_TYPE_IO;
818*61046927SAndroid Build Coastguard Worker }
819*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_drc(const rogue_ref * ref)820*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_drc(const rogue_ref *ref)
821*61046927SAndroid Build Coastguard Worker {
822*61046927SAndroid Build Coastguard Worker    return ref->type == ROGUE_REF_TYPE_DRC;
823*61046927SAndroid Build Coastguard Worker }
824*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_null(const rogue_ref * ref)825*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_null(const rogue_ref *ref)
826*61046927SAndroid Build Coastguard Worker {
827*61046927SAndroid Build Coastguard Worker    return ref->type == ROGUE_REF_TYPE_INVALID;
828*61046927SAndroid Build Coastguard Worker }
829*61046927SAndroid Build Coastguard Worker 
rogue_ref_get_reg_class(const rogue_ref * ref)830*61046927SAndroid Build Coastguard Worker static inline enum rogue_reg_class rogue_ref_get_reg_class(const rogue_ref *ref)
831*61046927SAndroid Build Coastguard Worker {
832*61046927SAndroid Build Coastguard Worker    if (rogue_ref_is_regarray(ref))
833*61046927SAndroid Build Coastguard Worker       return ref->regarray->regs[0]->class;
834*61046927SAndroid Build Coastguard Worker    else if (rogue_ref_is_reg(ref))
835*61046927SAndroid Build Coastguard Worker       return ref->reg->class;
836*61046927SAndroid Build Coastguard Worker    unreachable("Ref is not a reg/regarray.");
837*61046927SAndroid Build Coastguard Worker }
838*61046927SAndroid Build Coastguard Worker 
rogue_ref_get_reg_index(const rogue_ref * ref)839*61046927SAndroid Build Coastguard Worker static inline unsigned rogue_ref_get_reg_index(const rogue_ref *ref)
840*61046927SAndroid Build Coastguard Worker {
841*61046927SAndroid Build Coastguard Worker    if (rogue_ref_is_regarray(ref))
842*61046927SAndroid Build Coastguard Worker       return ref->regarray->regs[0]->index;
843*61046927SAndroid Build Coastguard Worker    else if (rogue_ref_is_reg(ref))
844*61046927SAndroid Build Coastguard Worker       return ref->reg->index;
845*61046927SAndroid Build Coastguard Worker    unreachable("Ref is not a reg/regarray.");
846*61046927SAndroid Build Coastguard Worker }
847*61046927SAndroid Build Coastguard Worker 
rogue_ref_get_regarray_size(const rogue_ref * ref)848*61046927SAndroid Build Coastguard Worker static inline unsigned rogue_ref_get_regarray_size(const rogue_ref *ref)
849*61046927SAndroid Build Coastguard Worker {
850*61046927SAndroid Build Coastguard Worker    if (rogue_ref_is_regarray(ref))
851*61046927SAndroid Build Coastguard Worker       return ref->regarray->size;
852*61046927SAndroid Build Coastguard Worker    unreachable("Ref is not a regarray.");
853*61046927SAndroid Build Coastguard Worker }
854*61046927SAndroid Build Coastguard Worker 
855*61046927SAndroid Build Coastguard Worker #define ROGUE_INTERNAL0_OFFSET 36
856*61046927SAndroid Build Coastguard Worker #define ROGUE_INTERNAL_GROUP 8
857*61046927SAndroid Build Coastguard Worker 
858*61046927SAndroid Build Coastguard Worker #define ROGUE_PIXOUT0_OFFSET 32
859*61046927SAndroid Build Coastguard Worker #define ROGUE_PIXOUT4_OFFSET 164
860*61046927SAndroid Build Coastguard Worker #define ROGUE_PIXOUT_GROUP 4
861*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_pixout(rogue_ref * ref)862*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_pixout(rogue_ref *ref)
863*61046927SAndroid Build Coastguard Worker {
864*61046927SAndroid Build Coastguard Worker    enum rogue_reg_class class;
865*61046927SAndroid Build Coastguard Worker    unsigned index;
866*61046927SAndroid Build Coastguard Worker 
867*61046927SAndroid Build Coastguard Worker    if (!rogue_ref_is_reg(ref) && !rogue_ref_is_regarray(ref))
868*61046927SAndroid Build Coastguard Worker       return false;
869*61046927SAndroid Build Coastguard Worker 
870*61046927SAndroid Build Coastguard Worker    class = rogue_ref_get_reg_class(ref);
871*61046927SAndroid Build Coastguard Worker 
872*61046927SAndroid Build Coastguard Worker    if (class == ROGUE_REG_CLASS_PIXOUT)
873*61046927SAndroid Build Coastguard Worker       return true;
874*61046927SAndroid Build Coastguard Worker    else if (class != ROGUE_REG_CLASS_SPECIAL)
875*61046927SAndroid Build Coastguard Worker       return false;
876*61046927SAndroid Build Coastguard Worker 
877*61046927SAndroid Build Coastguard Worker    index = rogue_ref_get_reg_index(ref);
878*61046927SAndroid Build Coastguard Worker 
879*61046927SAndroid Build Coastguard Worker    return (index >= ROGUE_PIXOUT0_OFFSET &&
880*61046927SAndroid Build Coastguard Worker            index < (ROGUE_PIXOUT0_OFFSET + ROGUE_PIXOUT_GROUP)) ||
881*61046927SAndroid Build Coastguard Worker           (index >= ROGUE_PIXOUT4_OFFSET &&
882*61046927SAndroid Build Coastguard Worker            index < (ROGUE_PIXOUT4_OFFSET + ROGUE_PIXOUT_GROUP));
883*61046927SAndroid Build Coastguard Worker }
884*61046927SAndroid Build Coastguard Worker 
rogue_ref_get_io(const rogue_ref * ref)885*61046927SAndroid Build Coastguard Worker static inline enum rogue_io rogue_ref_get_io(const rogue_ref *ref)
886*61046927SAndroid Build Coastguard Worker {
887*61046927SAndroid Build Coastguard Worker    assert(rogue_ref_is_io(ref));
888*61046927SAndroid Build Coastguard Worker    return ref->io;
889*61046927SAndroid Build Coastguard Worker }
890*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_io_p0(const rogue_ref * ref)891*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_io_p0(const rogue_ref *ref)
892*61046927SAndroid Build Coastguard Worker {
893*61046927SAndroid Build Coastguard Worker    return rogue_ref_get_io(ref) == ROGUE_IO_P0;
894*61046927SAndroid Build Coastguard Worker }
895*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_io_ftt(const rogue_ref * ref)896*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_io_ftt(const rogue_ref *ref)
897*61046927SAndroid Build Coastguard Worker {
898*61046927SAndroid Build Coastguard Worker    return rogue_ref_get_io(ref) == ROGUE_IO_FTT;
899*61046927SAndroid Build Coastguard Worker }
900*61046927SAndroid Build Coastguard Worker 
rogue_ref_is_io_none(const rogue_ref * ref)901*61046927SAndroid Build Coastguard Worker static inline bool rogue_ref_is_io_none(const rogue_ref *ref)
902*61046927SAndroid Build Coastguard Worker {
903*61046927SAndroid Build Coastguard Worker    /* Special case - never assert. */
904*61046927SAndroid Build Coastguard Worker    if (!rogue_ref_is_io(ref))
905*61046927SAndroid Build Coastguard Worker       return false;
906*61046927SAndroid Build Coastguard Worker 
907*61046927SAndroid Build Coastguard Worker    return rogue_ref_get_io(ref) == ROGUE_IO_NONE;
908*61046927SAndroid Build Coastguard Worker }
909*61046927SAndroid Build Coastguard Worker 
rogue_ref_get_io_src_index(const rogue_ref * ref)910*61046927SAndroid Build Coastguard Worker static inline unsigned rogue_ref_get_io_src_index(const rogue_ref *ref)
911*61046927SAndroid Build Coastguard Worker {
912*61046927SAndroid Build Coastguard Worker    return rogue_ref_get_io(ref) - ROGUE_IO_S0;
913*61046927SAndroid Build Coastguard Worker }
914*61046927SAndroid Build Coastguard Worker 
rogue_ref_get_drc_index(const rogue_ref * ref)915*61046927SAndroid Build Coastguard Worker static inline unsigned rogue_ref_get_drc_index(const rogue_ref *ref)
916*61046927SAndroid Build Coastguard Worker {
917*61046927SAndroid Build Coastguard Worker    assert(rogue_ref_is_drc(ref));
918*61046927SAndroid Build Coastguard Worker    return ref->drc.index;
919*61046927SAndroid Build Coastguard Worker }
920*61046927SAndroid Build Coastguard Worker 
rogue_ref_get_drc(rogue_ref * ref)921*61046927SAndroid Build Coastguard Worker static inline rogue_drc *rogue_ref_get_drc(rogue_ref *ref)
922*61046927SAndroid Build Coastguard Worker {
923*61046927SAndroid Build Coastguard Worker    assert(rogue_ref_is_drc(ref));
924*61046927SAndroid Build Coastguard Worker    return &ref->drc;
925*61046927SAndroid Build Coastguard Worker }
926*61046927SAndroid Build Coastguard Worker 
rogue_ref_get_val(const rogue_ref * ref)927*61046927SAndroid Build Coastguard Worker static inline unsigned rogue_ref_get_val(const rogue_ref *ref)
928*61046927SAndroid Build Coastguard Worker {
929*61046927SAndroid Build Coastguard Worker    assert(rogue_ref_is_val(ref));
930*61046927SAndroid Build Coastguard Worker    return ref->val;
931*61046927SAndroid Build Coastguard Worker }
932*61046927SAndroid Build Coastguard Worker 
rogue_ref_get_imm(rogue_ref * ref)933*61046927SAndroid Build Coastguard Worker static inline rogue_imm *rogue_ref_get_imm(rogue_ref *ref)
934*61046927SAndroid Build Coastguard Worker {
935*61046927SAndroid Build Coastguard Worker    assert(rogue_ref_is_imm(ref));
936*61046927SAndroid Build Coastguard Worker    return &ref->imm;
937*61046927SAndroid Build Coastguard Worker }
938*61046927SAndroid Build Coastguard Worker 
rogue_refs_equal(rogue_ref * a,rogue_ref * b)939*61046927SAndroid Build Coastguard Worker static inline bool rogue_refs_equal(rogue_ref *a, rogue_ref *b)
940*61046927SAndroid Build Coastguard Worker {
941*61046927SAndroid Build Coastguard Worker    if (a->type != b->type)
942*61046927SAndroid Build Coastguard Worker       return false;
943*61046927SAndroid Build Coastguard Worker 
944*61046927SAndroid Build Coastguard Worker    switch (a->type) {
945*61046927SAndroid Build Coastguard Worker    case ROGUE_REF_TYPE_VAL:
946*61046927SAndroid Build Coastguard Worker       return a->val == b->val;
947*61046927SAndroid Build Coastguard Worker 
948*61046927SAndroid Build Coastguard Worker    case ROGUE_REF_TYPE_REG:
949*61046927SAndroid Build Coastguard Worker       return a->reg == b->reg;
950*61046927SAndroid Build Coastguard Worker 
951*61046927SAndroid Build Coastguard Worker    case ROGUE_REF_TYPE_REGARRAY:
952*61046927SAndroid Build Coastguard Worker       return a->regarray == b->regarray;
953*61046927SAndroid Build Coastguard Worker 
954*61046927SAndroid Build Coastguard Worker    case ROGUE_REF_TYPE_IMM:
955*61046927SAndroid Build Coastguard Worker       return a->imm.imm.u32 == b->imm.imm.u32;
956*61046927SAndroid Build Coastguard Worker 
957*61046927SAndroid Build Coastguard Worker    case ROGUE_REF_TYPE_IO:
958*61046927SAndroid Build Coastguard Worker       return a->io == b->io;
959*61046927SAndroid Build Coastguard Worker 
960*61046927SAndroid Build Coastguard Worker    case ROGUE_REF_TYPE_DRC:
961*61046927SAndroid Build Coastguard Worker       return a->drc.index == b->drc.index;
962*61046927SAndroid Build Coastguard Worker 
963*61046927SAndroid Build Coastguard Worker    default:
964*61046927SAndroid Build Coastguard Worker       break;
965*61046927SAndroid Build Coastguard Worker    }
966*61046927SAndroid Build Coastguard Worker 
967*61046927SAndroid Build Coastguard Worker    return false;
968*61046927SAndroid Build Coastguard Worker }
969*61046927SAndroid Build Coastguard Worker 
970*61046927SAndroid Build Coastguard Worker typedef struct rogue_instr_dst {
971*61046927SAndroid Build Coastguard Worker    rogue_ref ref;
972*61046927SAndroid Build Coastguard Worker    uint64_t mod;
973*61046927SAndroid Build Coastguard Worker    unsigned index;
974*61046927SAndroid Build Coastguard Worker } rogue_instr_dst;
975*61046927SAndroid Build Coastguard Worker 
976*61046927SAndroid Build Coastguard Worker typedef struct rogue_instr_src {
977*61046927SAndroid Build Coastguard Worker    rogue_ref ref;
978*61046927SAndroid Build Coastguard Worker    uint64_t mod;
979*61046927SAndroid Build Coastguard Worker    unsigned index;
980*61046927SAndroid Build Coastguard Worker } rogue_instr_src;
981*61046927SAndroid Build Coastguard Worker 
rogue_instr_dst_src_equal(rogue_instr_dst * dst,rogue_instr_src * src)982*61046927SAndroid Build Coastguard Worker static inline bool rogue_instr_dst_src_equal(rogue_instr_dst *dst,
983*61046927SAndroid Build Coastguard Worker                                              rogue_instr_src *src)
984*61046927SAndroid Build Coastguard Worker {
985*61046927SAndroid Build Coastguard Worker    /* TODO: Take modifiers into account. */
986*61046927SAndroid Build Coastguard Worker    if (dst->mod || src->mod)
987*61046927SAndroid Build Coastguard Worker       return false;
988*61046927SAndroid Build Coastguard Worker 
989*61046927SAndroid Build Coastguard Worker    return rogue_refs_equal(&dst->ref, &src->ref);
990*61046927SAndroid Build Coastguard Worker }
991*61046927SAndroid Build Coastguard Worker 
992*61046927SAndroid Build Coastguard Worker typedef struct rogue_reg_write {
993*61046927SAndroid Build Coastguard Worker    rogue_instr *instr;
994*61046927SAndroid Build Coastguard Worker    unsigned dst_index;
995*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_reg::writes. */
996*61046927SAndroid Build Coastguard Worker } rogue_reg_write;
997*61046927SAndroid Build Coastguard Worker 
998*61046927SAndroid Build Coastguard Worker #define rogue_foreach_reg_write(write, reg) \
999*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_reg_write, write, &(reg)->writes, link)
1000*61046927SAndroid Build Coastguard Worker 
1001*61046927SAndroid Build Coastguard Worker #define rogue_foreach_reg_write_safe(write, reg) \
1002*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_reg_write, write, &(reg)->writes, link)
1003*61046927SAndroid Build Coastguard Worker 
1004*61046927SAndroid Build Coastguard Worker typedef struct rogue_reg_use {
1005*61046927SAndroid Build Coastguard Worker    rogue_instr *instr;
1006*61046927SAndroid Build Coastguard Worker    unsigned src_index;
1007*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_reg::uses. */
1008*61046927SAndroid Build Coastguard Worker } rogue_reg_use;
1009*61046927SAndroid Build Coastguard Worker 
1010*61046927SAndroid Build Coastguard Worker #define rogue_foreach_reg_use(use, reg) \
1011*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_reg_use, use, &(reg)->uses, link)
1012*61046927SAndroid Build Coastguard Worker 
1013*61046927SAndroid Build Coastguard Worker #define rogue_foreach_reg_use_safe(use, reg) \
1014*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_reg_use, use, &(reg)->uses, link)
1015*61046927SAndroid Build Coastguard Worker 
1016*61046927SAndroid Build Coastguard Worker typedef union rogue_dst_write {
1017*61046927SAndroid Build Coastguard Worker    rogue_reg_write reg;
1018*61046927SAndroid Build Coastguard Worker    rogue_regarray_write regarray;
1019*61046927SAndroid Build Coastguard Worker } rogue_dst_write;
1020*61046927SAndroid Build Coastguard Worker 
1021*61046927SAndroid Build Coastguard Worker typedef union rogue_src_use {
1022*61046927SAndroid Build Coastguard Worker    rogue_reg_use reg;
1023*61046927SAndroid Build Coastguard Worker    rogue_regarray_use regarray;
1024*61046927SAndroid Build Coastguard Worker } rogue_src_use;
1025*61046927SAndroid Build Coastguard Worker 
1026*61046927SAndroid Build Coastguard Worker typedef struct rogue_block_use {
1027*61046927SAndroid Build Coastguard Worker    rogue_instr *instr;
1028*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_block::uses. */
1029*61046927SAndroid Build Coastguard Worker } rogue_block_use;
1030*61046927SAndroid Build Coastguard Worker 
1031*61046927SAndroid Build Coastguard Worker #define rogue_foreach_block_use(use, block) \
1032*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_block_use, use, &(block)->uses, link)
1033*61046927SAndroid Build Coastguard Worker 
1034*61046927SAndroid Build Coastguard Worker #define rogue_foreach_block_use_safe(use, block) \
1035*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_block_use, use, &(block)->uses, link)
1036*61046927SAndroid Build Coastguard Worker 
1037*61046927SAndroid Build Coastguard Worker /** Rogue ALU instruction operations. */
1038*61046927SAndroid Build Coastguard Worker enum rogue_alu_op {
1039*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_INVALID = 0,
1040*61046927SAndroid Build Coastguard Worker 
1041*61046927SAndroid Build Coastguard Worker    /* Real instructions. */
1042*61046927SAndroid Build Coastguard Worker 
1043*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MBYP,
1044*61046927SAndroid Build Coastguard Worker 
1045*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_FADD,
1046*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_FMUL,
1047*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_FMAD,
1048*61046927SAndroid Build Coastguard Worker 
1049*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_ADD64,
1050*61046927SAndroid Build Coastguard Worker 
1051*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_TST,
1052*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOVC,
1053*61046927SAndroid Build Coastguard Worker 
1054*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_PCK_U8888,
1055*61046927SAndroid Build Coastguard Worker 
1056*61046927SAndroid Build Coastguard Worker    /* Pseudo-instructions. */
1057*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_PSEUDO,
1058*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOV = ROGUE_ALU_OP_PSEUDO,
1059*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_CMOV, /** Conditional move. */
1060*61046927SAndroid Build Coastguard Worker 
1061*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_FABS,
1062*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_FNEG,
1063*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_FNABS,
1064*61046927SAndroid Build Coastguard Worker 
1065*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_FMAX,
1066*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_FMIN,
1067*61046927SAndroid Build Coastguard Worker 
1068*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_COUNT,
1069*61046927SAndroid Build Coastguard Worker };
1070*61046927SAndroid Build Coastguard Worker 
1071*61046927SAndroid Build Coastguard Worker enum rogue_alu_op_mod {
1072*61046927SAndroid Build Coastguard Worker    /* In order of priority */
1073*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_LP, /* Low-precision modifier (force 13 lsbs of all sources
1074*61046927SAndroid Build Coastguard Worker                            to zero before op, and of result after op). */
1075*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_SAT, /* Saturate output. */
1076*61046927SAndroid Build Coastguard Worker 
1077*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_SCALE, /* Scale to [0, 1]. */
1078*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_ROUNDZERO, /* Round to zero. */
1079*61046927SAndroid Build Coastguard Worker 
1080*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_Z, /** Test == 0. */
1081*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_GZ, /** Test > 0. */
1082*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_GEZ, /** Test >= 0. */
1083*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_C, /** Test integer carry-out. */
1084*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_E, /** Test a == b. */
1085*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_G, /** Test a > b. */
1086*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_GE, /** Test a >= b. */
1087*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_NE, /** Test a != b. */
1088*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_L, /** Test a < b. */
1089*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_LE, /** Test a <= b. */
1090*61046927SAndroid Build Coastguard Worker 
1091*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_F32,
1092*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_U16,
1093*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_S16,
1094*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_U8,
1095*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_S8,
1096*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_U32,
1097*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_S32,
1098*61046927SAndroid Build Coastguard Worker 
1099*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_OP_MOD_COUNT,
1100*61046927SAndroid Build Coastguard Worker };
1101*61046927SAndroid Build Coastguard Worker 
1102*61046927SAndroid Build Coastguard Worker typedef struct rogue_alu_op_mod_info {
1103*61046927SAndroid Build Coastguard Worker    const char *str;
1104*61046927SAndroid Build Coastguard Worker    uint64_t exclude; /* Can't use this op mod with any of these. */
1105*61046927SAndroid Build Coastguard Worker    uint64_t require; /* Required op mods for this to be used (OR). */
1106*61046927SAndroid Build Coastguard Worker } rogue_alu_op_mod_info;
1107*61046927SAndroid Build Coastguard Worker 
1108*61046927SAndroid Build Coastguard Worker extern const rogue_alu_op_mod_info
1109*61046927SAndroid Build Coastguard Worker    rogue_alu_op_mod_infos[ROGUE_ALU_OP_MOD_COUNT];
1110*61046927SAndroid Build Coastguard Worker 
rogue_mods_supported(uint64_t mods,uint64_t supported_mods)1111*61046927SAndroid Build Coastguard Worker static inline bool rogue_mods_supported(uint64_t mods, uint64_t supported_mods)
1112*61046927SAndroid Build Coastguard Worker {
1113*61046927SAndroid Build Coastguard Worker    return !(mods & ~supported_mods);
1114*61046927SAndroid Build Coastguard Worker }
1115*61046927SAndroid Build Coastguard Worker 
1116*61046927SAndroid Build Coastguard Worker enum rogue_alu_dst_mod {
1117*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_DST_MOD_E0,
1118*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_DST_MOD_E1,
1119*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_DST_MOD_E2,
1120*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_DST_MOD_E3,
1121*61046927SAndroid Build Coastguard Worker 
1122*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_DST_MOD_COUNT,
1123*61046927SAndroid Build Coastguard Worker };
1124*61046927SAndroid Build Coastguard Worker 
1125*61046927SAndroid Build Coastguard Worker typedef struct rogue_alu_dst_mod_info {
1126*61046927SAndroid Build Coastguard Worker    const char *str;
1127*61046927SAndroid Build Coastguard Worker } rogue_alu_dst_mod_info;
1128*61046927SAndroid Build Coastguard Worker 
1129*61046927SAndroid Build Coastguard Worker extern const rogue_alu_dst_mod_info
1130*61046927SAndroid Build Coastguard Worker    rogue_alu_dst_mod_infos[ROGUE_ALU_DST_MOD_COUNT];
1131*61046927SAndroid Build Coastguard Worker 
1132*61046927SAndroid Build Coastguard Worker enum rogue_alu_src_mod {
1133*61046927SAndroid Build Coastguard Worker    /* In order of priority, i.e. if all NEG, ABS, and FLR are all set, FLR will
1134*61046927SAndroid Build Coastguard Worker       happen first, then ABS, then NEG. */
1135*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_SRC_MOD_FLR,
1136*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_SRC_MOD_ABS,
1137*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_SRC_MOD_NEG,
1138*61046927SAndroid Build Coastguard Worker 
1139*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_SRC_MOD_E0,
1140*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_SRC_MOD_E1,
1141*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_SRC_MOD_E2,
1142*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_SRC_MOD_E3,
1143*61046927SAndroid Build Coastguard Worker 
1144*61046927SAndroid Build Coastguard Worker    ROGUE_ALU_SRC_MOD_COUNT,
1145*61046927SAndroid Build Coastguard Worker };
1146*61046927SAndroid Build Coastguard Worker 
1147*61046927SAndroid Build Coastguard Worker typedef struct rogue_alu_src_mod_info {
1148*61046927SAndroid Build Coastguard Worker    const char *str;
1149*61046927SAndroid Build Coastguard Worker } rogue_alu_src_mod_info;
1150*61046927SAndroid Build Coastguard Worker 
1151*61046927SAndroid Build Coastguard Worker extern const rogue_alu_src_mod_info
1152*61046927SAndroid Build Coastguard Worker    rogue_alu_src_mod_infos[ROGUE_ALU_SRC_MOD_COUNT];
1153*61046927SAndroid Build Coastguard Worker 
1154*61046927SAndroid Build Coastguard Worker enum rogue_ctrl_op {
1155*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_INVALID = 0,
1156*61046927SAndroid Build Coastguard Worker 
1157*61046927SAndroid Build Coastguard Worker    /* Real instructions. */
1158*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_NOP,
1159*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_WOP,
1160*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_BR, /* Branch: relative (to block). */
1161*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_BA, /* Branch: absolute (to address). */
1162*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_WDF,
1163*61046927SAndroid Build Coastguard Worker 
1164*61046927SAndroid Build Coastguard Worker    /* Pseudo-instructions. */
1165*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_PSEUDO,
1166*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_END = ROGUE_CTRL_OP_PSEUDO,
1167*61046927SAndroid Build Coastguard Worker 
1168*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_COUNT,
1169*61046927SAndroid Build Coastguard Worker };
1170*61046927SAndroid Build Coastguard Worker 
1171*61046927SAndroid Build Coastguard Worker enum rogue_ctrl_op_mod {
1172*61046927SAndroid Build Coastguard Worker    /* In order of priority */
1173*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_MOD_LINK,
1174*61046927SAndroid Build Coastguard Worker 
1175*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_MOD_ALLINST,
1176*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_MOD_ANYINST,
1177*61046927SAndroid Build Coastguard Worker 
1178*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_MOD_END,
1179*61046927SAndroid Build Coastguard Worker 
1180*61046927SAndroid Build Coastguard Worker    ROGUE_CTRL_OP_MOD_COUNT,
1181*61046927SAndroid Build Coastguard Worker };
1182*61046927SAndroid Build Coastguard Worker 
1183*61046927SAndroid Build Coastguard Worker typedef struct rogue_ctrl_op_mod_info {
1184*61046927SAndroid Build Coastguard Worker    const char *str;
1185*61046927SAndroid Build Coastguard Worker    uint64_t exclude; /* Can't use this op mod with any of these. */
1186*61046927SAndroid Build Coastguard Worker    uint64_t require; /* Required op mods for this to be used (OR). */
1187*61046927SAndroid Build Coastguard Worker } rogue_ctrl_op_mod_info;
1188*61046927SAndroid Build Coastguard Worker 
1189*61046927SAndroid Build Coastguard Worker extern const rogue_ctrl_op_mod_info
1190*61046927SAndroid Build Coastguard Worker    rogue_ctrl_op_mod_infos[ROGUE_CTRL_OP_MOD_COUNT];
1191*61046927SAndroid Build Coastguard Worker 
1192*61046927SAndroid Build Coastguard Worker #define ROGUE_CTRL_OP_MAX_SRCS 7
1193*61046927SAndroid Build Coastguard Worker #define ROGUE_CTRL_OP_MAX_DSTS 2
1194*61046927SAndroid Build Coastguard Worker 
1195*61046927SAndroid Build Coastguard Worker typedef struct rogue_ctrl_op_info {
1196*61046927SAndroid Build Coastguard Worker    const char *str;
1197*61046927SAndroid Build Coastguard Worker 
1198*61046927SAndroid Build Coastguard Worker    bool has_target; /* Has a block as a target. */
1199*61046927SAndroid Build Coastguard Worker    bool ends_block; /* Can be the instruction at the end of a block. */
1200*61046927SAndroid Build Coastguard Worker    bool has_srcs; /* Has encodable sources. */
1201*61046927SAndroid Build Coastguard Worker    bool has_dsts; /* Has encodable destinations. */
1202*61046927SAndroid Build Coastguard Worker 
1203*61046927SAndroid Build Coastguard Worker    unsigned num_dsts;
1204*61046927SAndroid Build Coastguard Worker    unsigned num_srcs;
1205*61046927SAndroid Build Coastguard Worker 
1206*61046927SAndroid Build Coastguard Worker    uint64_t supported_op_mods;
1207*61046927SAndroid Build Coastguard Worker    uint64_t supported_dst_mods[ROGUE_CTRL_OP_MAX_DSTS];
1208*61046927SAndroid Build Coastguard Worker    uint64_t supported_src_mods[ROGUE_CTRL_OP_MAX_SRCS];
1209*61046927SAndroid Build Coastguard Worker 
1210*61046927SAndroid Build Coastguard Worker    uint64_t supported_dst_types[ROGUE_CTRL_OP_MAX_DSTS];
1211*61046927SAndroid Build Coastguard Worker    uint64_t supported_src_types[ROGUE_CTRL_OP_MAX_SRCS];
1212*61046927SAndroid Build Coastguard Worker 
1213*61046927SAndroid Build Coastguard Worker    unsigned dst_stride[ROGUE_CTRL_OP_MAX_DSTS];
1214*61046927SAndroid Build Coastguard Worker    unsigned src_stride[ROGUE_CTRL_OP_MAX_SRCS];
1215*61046927SAndroid Build Coastguard Worker 
1216*61046927SAndroid Build Coastguard Worker    uint64_t dst_repeat_mask;
1217*61046927SAndroid Build Coastguard Worker    uint64_t src_repeat_mask;
1218*61046927SAndroid Build Coastguard Worker } rogue_ctrl_op_info;
1219*61046927SAndroid Build Coastguard Worker 
1220*61046927SAndroid Build Coastguard Worker extern const rogue_ctrl_op_info rogue_ctrl_op_infos[ROGUE_CTRL_OP_COUNT];
1221*61046927SAndroid Build Coastguard Worker 
rogue_ctrl_op_has_srcs(enum rogue_ctrl_op op)1222*61046927SAndroid Build Coastguard Worker static inline bool rogue_ctrl_op_has_srcs(enum rogue_ctrl_op op)
1223*61046927SAndroid Build Coastguard Worker {
1224*61046927SAndroid Build Coastguard Worker    const rogue_ctrl_op_info *info = &rogue_ctrl_op_infos[op];
1225*61046927SAndroid Build Coastguard Worker    return info->has_srcs;
1226*61046927SAndroid Build Coastguard Worker }
1227*61046927SAndroid Build Coastguard Worker 
rogue_ctrl_op_has_dsts(enum rogue_ctrl_op op)1228*61046927SAndroid Build Coastguard Worker static inline bool rogue_ctrl_op_has_dsts(enum rogue_ctrl_op op)
1229*61046927SAndroid Build Coastguard Worker {
1230*61046927SAndroid Build Coastguard Worker    const rogue_ctrl_op_info *info = &rogue_ctrl_op_infos[op];
1231*61046927SAndroid Build Coastguard Worker    return info->has_dsts;
1232*61046927SAndroid Build Coastguard Worker }
1233*61046927SAndroid Build Coastguard Worker 
1234*61046927SAndroid Build Coastguard Worker /* ALU instructions have at most 5 sources. */
1235*61046927SAndroid Build Coastguard Worker #define ROGUE_ALU_OP_MAX_SRCS 5
1236*61046927SAndroid Build Coastguard Worker #define ROGUE_ALU_OP_MAX_DSTS 3
1237*61046927SAndroid Build Coastguard Worker 
1238*61046927SAndroid Build Coastguard Worker typedef struct rogue_alu_io_info {
1239*61046927SAndroid Build Coastguard Worker    enum rogue_io dst[ROGUE_ALU_OP_MAX_DSTS];
1240*61046927SAndroid Build Coastguard Worker    enum rogue_io src[ROGUE_ALU_OP_MAX_SRCS];
1241*61046927SAndroid Build Coastguard Worker } rogue_alu_io_info;
1242*61046927SAndroid Build Coastguard Worker 
1243*61046927SAndroid Build Coastguard Worker /** Rogue ALU instruction operation info. */
1244*61046927SAndroid Build Coastguard Worker typedef struct rogue_alu_op_info {
1245*61046927SAndroid Build Coastguard Worker    const char *str;
1246*61046927SAndroid Build Coastguard Worker 
1247*61046927SAndroid Build Coastguard Worker    unsigned num_dsts;
1248*61046927SAndroid Build Coastguard Worker    unsigned num_srcs;
1249*61046927SAndroid Build Coastguard Worker 
1250*61046927SAndroid Build Coastguard Worker    uint64_t supported_phases;
1251*61046927SAndroid Build Coastguard Worker    rogue_alu_io_info phase_io[ROGUE_INSTR_PHASE_COUNT];
1252*61046927SAndroid Build Coastguard Worker 
1253*61046927SAndroid Build Coastguard Worker    uint64_t supported_op_mods;
1254*61046927SAndroid Build Coastguard Worker    uint64_t supported_dst_mods[ROGUE_ALU_OP_MAX_DSTS];
1255*61046927SAndroid Build Coastguard Worker    uint64_t supported_src_mods[ROGUE_ALU_OP_MAX_SRCS];
1256*61046927SAndroid Build Coastguard Worker 
1257*61046927SAndroid Build Coastguard Worker    uint64_t supported_dst_types[ROGUE_ALU_OP_MAX_DSTS];
1258*61046927SAndroid Build Coastguard Worker    uint64_t supported_src_types[ROGUE_ALU_OP_MAX_SRCS];
1259*61046927SAndroid Build Coastguard Worker 
1260*61046927SAndroid Build Coastguard Worker    unsigned dst_stride[ROGUE_CTRL_OP_MAX_DSTS];
1261*61046927SAndroid Build Coastguard Worker    unsigned src_stride[ROGUE_CTRL_OP_MAX_SRCS];
1262*61046927SAndroid Build Coastguard Worker 
1263*61046927SAndroid Build Coastguard Worker    uint64_t dst_repeat_mask;
1264*61046927SAndroid Build Coastguard Worker    uint64_t src_repeat_mask;
1265*61046927SAndroid Build Coastguard Worker } rogue_alu_op_info;
1266*61046927SAndroid Build Coastguard Worker 
1267*61046927SAndroid Build Coastguard Worker extern const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT];
1268*61046927SAndroid Build Coastguard Worker 
1269*61046927SAndroid Build Coastguard Worker /** Rogue ALU instruction. */
1270*61046927SAndroid Build Coastguard Worker typedef struct rogue_alu_instr {
1271*61046927SAndroid Build Coastguard Worker    rogue_instr instr;
1272*61046927SAndroid Build Coastguard Worker 
1273*61046927SAndroid Build Coastguard Worker    enum rogue_alu_op op;
1274*61046927SAndroid Build Coastguard Worker 
1275*61046927SAndroid Build Coastguard Worker    uint64_t mod;
1276*61046927SAndroid Build Coastguard Worker 
1277*61046927SAndroid Build Coastguard Worker    rogue_instr_dst dst[ROGUE_ALU_OP_MAX_DSTS];
1278*61046927SAndroid Build Coastguard Worker    rogue_dst_write dst_write[ROGUE_ALU_OP_MAX_DSTS];
1279*61046927SAndroid Build Coastguard Worker 
1280*61046927SAndroid Build Coastguard Worker    rogue_instr_src src[ROGUE_ALU_OP_MAX_SRCS];
1281*61046927SAndroid Build Coastguard Worker    rogue_src_use src_use[ROGUE_ALU_OP_MAX_SRCS];
1282*61046927SAndroid Build Coastguard Worker } rogue_alu_instr;
1283*61046927SAndroid Build Coastguard Worker 
rogue_set_alu_op_mod(rogue_alu_instr * alu,enum rogue_alu_op_mod mod)1284*61046927SAndroid Build Coastguard Worker static inline void rogue_set_alu_op_mod(rogue_alu_instr *alu,
1285*61046927SAndroid Build Coastguard Worker                                         enum rogue_alu_op_mod mod)
1286*61046927SAndroid Build Coastguard Worker {
1287*61046927SAndroid Build Coastguard Worker    alu->mod |= BITFIELD64_BIT(mod);
1288*61046927SAndroid Build Coastguard Worker }
1289*61046927SAndroid Build Coastguard Worker 
rogue_alu_op_mod_is_set(const rogue_alu_instr * alu,enum rogue_alu_op_mod mod)1290*61046927SAndroid Build Coastguard Worker static inline bool rogue_alu_op_mod_is_set(const rogue_alu_instr *alu,
1291*61046927SAndroid Build Coastguard Worker                                            enum rogue_alu_op_mod mod)
1292*61046927SAndroid Build Coastguard Worker {
1293*61046927SAndroid Build Coastguard Worker    return !!(alu->mod & BITFIELD64_BIT(mod));
1294*61046927SAndroid Build Coastguard Worker }
1295*61046927SAndroid Build Coastguard Worker 
rogue_set_alu_dst_mod(rogue_alu_instr * alu,unsigned dst_index,enum rogue_alu_dst_mod mod)1296*61046927SAndroid Build Coastguard Worker static inline void rogue_set_alu_dst_mod(rogue_alu_instr *alu,
1297*61046927SAndroid Build Coastguard Worker                                          unsigned dst_index,
1298*61046927SAndroid Build Coastguard Worker                                          enum rogue_alu_dst_mod mod)
1299*61046927SAndroid Build Coastguard Worker {
1300*61046927SAndroid Build Coastguard Worker    alu->dst[dst_index].mod |= BITFIELD64_BIT(mod);
1301*61046927SAndroid Build Coastguard Worker }
1302*61046927SAndroid Build Coastguard Worker 
rogue_alu_dst_mod_is_set(const rogue_alu_instr * alu,unsigned dst_index,enum rogue_alu_dst_mod mod)1303*61046927SAndroid Build Coastguard Worker static inline bool rogue_alu_dst_mod_is_set(const rogue_alu_instr *alu,
1304*61046927SAndroid Build Coastguard Worker                                             unsigned dst_index,
1305*61046927SAndroid Build Coastguard Worker                                             enum rogue_alu_dst_mod mod)
1306*61046927SAndroid Build Coastguard Worker {
1307*61046927SAndroid Build Coastguard Worker    return !!(alu->dst[dst_index].mod & BITFIELD64_BIT(mod));
1308*61046927SAndroid Build Coastguard Worker }
1309*61046927SAndroid Build Coastguard Worker 
rogue_set_alu_src_mod(rogue_alu_instr * alu,unsigned src_index,enum rogue_alu_src_mod mod)1310*61046927SAndroid Build Coastguard Worker static inline void rogue_set_alu_src_mod(rogue_alu_instr *alu,
1311*61046927SAndroid Build Coastguard Worker                                          unsigned src_index,
1312*61046927SAndroid Build Coastguard Worker                                          enum rogue_alu_src_mod mod)
1313*61046927SAndroid Build Coastguard Worker {
1314*61046927SAndroid Build Coastguard Worker    alu->src[src_index].mod |= BITFIELD64_BIT(mod);
1315*61046927SAndroid Build Coastguard Worker }
1316*61046927SAndroid Build Coastguard Worker 
rogue_alu_src_mod_is_set(const rogue_alu_instr * alu,unsigned src_index,enum rogue_alu_src_mod mod)1317*61046927SAndroid Build Coastguard Worker static inline bool rogue_alu_src_mod_is_set(const rogue_alu_instr *alu,
1318*61046927SAndroid Build Coastguard Worker                                             unsigned src_index,
1319*61046927SAndroid Build Coastguard Worker                                             enum rogue_alu_src_mod mod)
1320*61046927SAndroid Build Coastguard Worker {
1321*61046927SAndroid Build Coastguard Worker    return !!(alu->src[src_index].mod & BITFIELD64_BIT(mod));
1322*61046927SAndroid Build Coastguard Worker }
1323*61046927SAndroid Build Coastguard Worker 
1324*61046927SAndroid Build Coastguard Worker /**
1325*61046927SAndroid Build Coastguard Worker  * \brief Allocates and initializes a new ALU instruction.
1326*61046927SAndroid Build Coastguard Worker  *
1327*61046927SAndroid Build Coastguard Worker  * \param[in] block The block which will contain the instruction.
1328*61046927SAndroid Build Coastguard Worker  * \param[in] op The ALU instruction operation.
1329*61046927SAndroid Build Coastguard Worker  * \return The new instruction.
1330*61046927SAndroid Build Coastguard Worker  */
1331*61046927SAndroid Build Coastguard Worker rogue_alu_instr *rogue_alu_instr_create(rogue_block *block,
1332*61046927SAndroid Build Coastguard Worker                                         enum rogue_alu_op op);
1333*61046927SAndroid Build Coastguard Worker 
1334*61046927SAndroid Build Coastguard Worker #define ROGUE_BACKEND_OP_MAX_SRCS 6
1335*61046927SAndroid Build Coastguard Worker #define ROGUE_BACKEND_OP_MAX_DSTS 2
1336*61046927SAndroid Build Coastguard Worker 
1337*61046927SAndroid Build Coastguard Worker enum rogue_backend_op {
1338*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_INVALID = 0,
1339*61046927SAndroid Build Coastguard Worker 
1340*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_UVSW_WRITE,
1341*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_UVSW_EMIT,
1342*61046927SAndroid Build Coastguard Worker    /* ROGUE_BACKEND_OP_UVSW_CUT, */
1343*61046927SAndroid Build Coastguard Worker    /* ROGUE_BACKEND_OP_UVSW_EMITTHENCUT, */
1344*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_UVSW_ENDTASK,
1345*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_UVSW_EMITTHENENDTASK,
1346*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_UVSW_WRITETHENEMITTHENENDTASK,
1347*61046927SAndroid Build Coastguard Worker 
1348*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_IDF,
1349*61046927SAndroid Build Coastguard Worker 
1350*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_EMITPIX,
1351*61046927SAndroid Build Coastguard Worker 
1352*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_LD,
1353*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_ST,
1354*61046927SAndroid Build Coastguard Worker 
1355*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_FITR_PIXEL,
1356*61046927SAndroid Build Coastguard Worker    /* ROGUE_BACKEND_OP_SAMPLE, */
1357*61046927SAndroid Build Coastguard Worker    /* ROGUE_BACKEND_OP_CENTROID, */
1358*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_FITRP_PIXEL,
1359*61046927SAndroid Build Coastguard Worker    /* ROGUE_BACKEND_OP_FITRP_SAMPLE, */
1360*61046927SAndroid Build Coastguard Worker    /* ROGUE_BACKEND_OP_FITRP_CENTROID, */
1361*61046927SAndroid Build Coastguard Worker 
1362*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_SMP1D,
1363*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_SMP2D,
1364*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_SMP3D,
1365*61046927SAndroid Build Coastguard Worker 
1366*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_PSEUDO,
1367*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_COUNT = ROGUE_BACKEND_OP_PSEUDO,
1368*61046927SAndroid Build Coastguard Worker };
1369*61046927SAndroid Build Coastguard Worker 
1370*61046927SAndroid Build Coastguard Worker typedef struct rogue_backend_io_info {
1371*61046927SAndroid Build Coastguard Worker    enum rogue_io dst[ROGUE_BACKEND_OP_MAX_DSTS];
1372*61046927SAndroid Build Coastguard Worker    enum rogue_io src[ROGUE_BACKEND_OP_MAX_SRCS];
1373*61046927SAndroid Build Coastguard Worker } rogue_backend_io_info;
1374*61046927SAndroid Build Coastguard Worker 
1375*61046927SAndroid Build Coastguard Worker typedef struct rogue_backend_op_info {
1376*61046927SAndroid Build Coastguard Worker    const char *str;
1377*61046927SAndroid Build Coastguard Worker 
1378*61046927SAndroid Build Coastguard Worker    unsigned num_dsts;
1379*61046927SAndroid Build Coastguard Worker    unsigned num_srcs;
1380*61046927SAndroid Build Coastguard Worker 
1381*61046927SAndroid Build Coastguard Worker    /* supported_phases not needed as it's always going to be in the backend
1382*61046927SAndroid Build Coastguard Worker     * phase. */
1383*61046927SAndroid Build Coastguard Worker    rogue_backend_io_info phase_io;
1384*61046927SAndroid Build Coastguard Worker 
1385*61046927SAndroid Build Coastguard Worker    uint64_t supported_op_mods;
1386*61046927SAndroid Build Coastguard Worker    uint64_t supported_dst_mods[ROGUE_BACKEND_OP_MAX_DSTS];
1387*61046927SAndroid Build Coastguard Worker    uint64_t supported_src_mods[ROGUE_BACKEND_OP_MAX_SRCS];
1388*61046927SAndroid Build Coastguard Worker 
1389*61046927SAndroid Build Coastguard Worker    uint64_t supported_dst_types[ROGUE_BACKEND_OP_MAX_DSTS];
1390*61046927SAndroid Build Coastguard Worker    uint64_t supported_src_types[ROGUE_BACKEND_OP_MAX_SRCS];
1391*61046927SAndroid Build Coastguard Worker 
1392*61046927SAndroid Build Coastguard Worker    unsigned dst_stride[ROGUE_CTRL_OP_MAX_DSTS];
1393*61046927SAndroid Build Coastguard Worker    unsigned src_stride[ROGUE_CTRL_OP_MAX_SRCS];
1394*61046927SAndroid Build Coastguard Worker 
1395*61046927SAndroid Build Coastguard Worker    uint64_t dst_repeat_mask;
1396*61046927SAndroid Build Coastguard Worker    uint64_t src_repeat_mask;
1397*61046927SAndroid Build Coastguard Worker } rogue_backend_op_info;
1398*61046927SAndroid Build Coastguard Worker 
1399*61046927SAndroid Build Coastguard Worker extern const rogue_backend_op_info
1400*61046927SAndroid Build Coastguard Worker    rogue_backend_op_infos[ROGUE_BACKEND_OP_COUNT];
1401*61046927SAndroid Build Coastguard Worker 
1402*61046927SAndroid Build Coastguard Worker enum rogue_backend_op_mod {
1403*61046927SAndroid Build Coastguard Worker    /* In order of priority */
1404*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_PROJ, /* Projection (send T co-ordinate). */
1405*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_FCNORM, /* Fixed-point texture data (convert to float).
1406*61046927SAndroid Build Coastguard Worker                                  */
1407*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_NNCOORDS, /* Non-normalised co-ordinates. */
1408*61046927SAndroid Build Coastguard Worker 
1409*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_BIAS, /* LOD mode: bias. */
1410*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_REPLACE, /* LOD mode: replace. */
1411*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_GRADIENT, /* LOD mode: gradient. */
1412*61046927SAndroid Build Coastguard Worker 
1413*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_PPLOD, /* Per-pixel LOD. */
1414*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_TAO, /* Texture address override. */
1415*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_SOO, /* Sample offset supplied. */
1416*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_SNO, /* Sample number supplied. */
1417*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_WRT, /* SMP write. */
1418*61046927SAndroid Build Coastguard Worker 
1419*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_DATA, /* Sample bypass mode: data. */
1420*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_INFO, /* Sample bypass mode: info. */
1421*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_BOTH, /* Sample bypass mode: both. */
1422*61046927SAndroid Build Coastguard Worker 
1423*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_TILED, /* Tiled LD/ST. */
1424*61046927SAndroid Build Coastguard Worker 
1425*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_BYPASS, /* MCU cache mode (read): bypass. */
1426*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_FORCELINEFILL, /* MCU cache mode (read): force line
1427*61046927SAndroid Build Coastguard Worker                                         * fill.
1428*61046927SAndroid Build Coastguard Worker                                         */
1429*61046927SAndroid Build Coastguard Worker 
1430*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_WRITETHROUGH, /* MCU cache mode (write): write through
1431*61046927SAndroid Build Coastguard Worker                                        * L1 & SLC.
1432*61046927SAndroid Build Coastguard Worker                                        */
1433*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_WRITEBACK, /* MCU cache mode (write): write back. */
1434*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_LAZYWRITEBACK, /* MCU cache mode (write): lazy write
1435*61046927SAndroid Build Coastguard Worker                                         * back.
1436*61046927SAndroid Build Coastguard Worker                                         */
1437*61046927SAndroid Build Coastguard Worker 
1438*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_SLCBYPASS, /* SLC cache mode: bypass.*/
1439*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_SLCWRITEBACK, /* SLC cache mode: write back */
1440*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_SLCWRITETHROUGH, /* SLC cache mode: write through. */
1441*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_SLCNOALLOC, /* SLC cache mode: cached reads/no
1442*61046927SAndroid Build Coastguard Worker                                      * allocation on miss.
1443*61046927SAndroid Build Coastguard Worker                                      */
1444*61046927SAndroid Build Coastguard Worker 
1445*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_ARRAY, /* Sample data contains array index/texture
1446*61046927SAndroid Build Coastguard Worker                                 * arrays enabled.
1447*61046927SAndroid Build Coastguard Worker                                 */
1448*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_INTEGER, /* Integer co-ordinates and sample data. */
1449*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_SCHEDSWAP, /* Deschedule slot after instruction. */
1450*61046927SAndroid Build Coastguard Worker 
1451*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_F16, /* Return packed F16 data. */
1452*61046927SAndroid Build Coastguard Worker 
1453*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_SAT, /* Saturate output. */
1454*61046927SAndroid Build Coastguard Worker 
1455*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_FREEP, /* Free partition. */
1456*61046927SAndroid Build Coastguard Worker 
1457*61046927SAndroid Build Coastguard Worker    ROGUE_BACKEND_OP_MOD_COUNT,
1458*61046927SAndroid Build Coastguard Worker };
1459*61046927SAndroid Build Coastguard Worker 
1460*61046927SAndroid Build Coastguard Worker typedef struct rogue_backend_op_mod_info {
1461*61046927SAndroid Build Coastguard Worker    const char *str;
1462*61046927SAndroid Build Coastguard Worker    uint64_t exclude; /* Can't use this op mod with any of these. */
1463*61046927SAndroid Build Coastguard Worker    uint64_t require; /* Required op mods for this to be used (OR). */
1464*61046927SAndroid Build Coastguard Worker } rogue_backend_op_mod_info;
1465*61046927SAndroid Build Coastguard Worker 
1466*61046927SAndroid Build Coastguard Worker extern const rogue_backend_op_mod_info
1467*61046927SAndroid Build Coastguard Worker    rogue_backend_op_mod_infos[ROGUE_BACKEND_OP_MOD_COUNT];
1468*61046927SAndroid Build Coastguard Worker 
1469*61046927SAndroid Build Coastguard Worker typedef struct rogue_backend_instr {
1470*61046927SAndroid Build Coastguard Worker    rogue_instr instr;
1471*61046927SAndroid Build Coastguard Worker 
1472*61046927SAndroid Build Coastguard Worker    enum rogue_backend_op op;
1473*61046927SAndroid Build Coastguard Worker 
1474*61046927SAndroid Build Coastguard Worker    uint64_t mod;
1475*61046927SAndroid Build Coastguard Worker 
1476*61046927SAndroid Build Coastguard Worker    /* Backend instructions don't have source/dest modifiers. */
1477*61046927SAndroid Build Coastguard Worker 
1478*61046927SAndroid Build Coastguard Worker    rogue_instr_dst dst[ROGUE_BACKEND_OP_MAX_DSTS];
1479*61046927SAndroid Build Coastguard Worker    rogue_dst_write dst_write[ROGUE_BACKEND_OP_MAX_DSTS];
1480*61046927SAndroid Build Coastguard Worker 
1481*61046927SAndroid Build Coastguard Worker    rogue_instr_src src[ROGUE_BACKEND_OP_MAX_SRCS];
1482*61046927SAndroid Build Coastguard Worker    rogue_src_use src_use[ROGUE_BACKEND_OP_MAX_SRCS];
1483*61046927SAndroid Build Coastguard Worker } rogue_backend_instr;
1484*61046927SAndroid Build Coastguard Worker 
rogue_set_backend_op_mod(rogue_backend_instr * backend,enum rogue_backend_op_mod mod)1485*61046927SAndroid Build Coastguard Worker static inline void rogue_set_backend_op_mod(rogue_backend_instr *backend,
1486*61046927SAndroid Build Coastguard Worker                                             enum rogue_backend_op_mod mod)
1487*61046927SAndroid Build Coastguard Worker {
1488*61046927SAndroid Build Coastguard Worker    backend->mod |= BITFIELD64_BIT(mod);
1489*61046927SAndroid Build Coastguard Worker }
1490*61046927SAndroid Build Coastguard Worker 
1491*61046927SAndroid Build Coastguard Worker static inline bool
rogue_backend_op_mod_is_set(const rogue_backend_instr * backend,enum rogue_backend_op_mod mod)1492*61046927SAndroid Build Coastguard Worker rogue_backend_op_mod_is_set(const rogue_backend_instr *backend,
1493*61046927SAndroid Build Coastguard Worker                             enum rogue_backend_op_mod mod)
1494*61046927SAndroid Build Coastguard Worker {
1495*61046927SAndroid Build Coastguard Worker    return !!(backend->mod & BITFIELD64_BIT(mod));
1496*61046927SAndroid Build Coastguard Worker }
1497*61046927SAndroid Build Coastguard Worker 
1498*61046927SAndroid Build Coastguard Worker rogue_backend_instr *rogue_backend_instr_create(rogue_block *block,
1499*61046927SAndroid Build Coastguard Worker                                                 enum rogue_backend_op op);
1500*61046927SAndroid Build Coastguard Worker 
1501*61046927SAndroid Build Coastguard Worker typedef struct rogue_ctrl_instr {
1502*61046927SAndroid Build Coastguard Worker    rogue_instr instr;
1503*61046927SAndroid Build Coastguard Worker 
1504*61046927SAndroid Build Coastguard Worker    enum rogue_ctrl_op op;
1505*61046927SAndroid Build Coastguard Worker 
1506*61046927SAndroid Build Coastguard Worker    uint64_t mod;
1507*61046927SAndroid Build Coastguard Worker 
1508*61046927SAndroid Build Coastguard Worker    /* Control instructions don't have source/dest modifiers. */
1509*61046927SAndroid Build Coastguard Worker 
1510*61046927SAndroid Build Coastguard Worker    rogue_instr_dst dst[ROGUE_CTRL_OP_MAX_DSTS];
1511*61046927SAndroid Build Coastguard Worker    rogue_dst_write dst_write[ROGUE_CTRL_OP_MAX_DSTS];
1512*61046927SAndroid Build Coastguard Worker 
1513*61046927SAndroid Build Coastguard Worker    rogue_instr_src src[ROGUE_CTRL_OP_MAX_SRCS];
1514*61046927SAndroid Build Coastguard Worker    rogue_src_use src_use[ROGUE_CTRL_OP_MAX_SRCS];
1515*61046927SAndroid Build Coastguard Worker 
1516*61046927SAndroid Build Coastguard Worker    rogue_block *target_block;
1517*61046927SAndroid Build Coastguard Worker    rogue_block_use block_use;
1518*61046927SAndroid Build Coastguard Worker } rogue_ctrl_instr;
1519*61046927SAndroid Build Coastguard Worker 
rogue_set_ctrl_op_mod(rogue_ctrl_instr * ctrl,enum rogue_ctrl_op_mod mod)1520*61046927SAndroid Build Coastguard Worker static inline void rogue_set_ctrl_op_mod(rogue_ctrl_instr *ctrl,
1521*61046927SAndroid Build Coastguard Worker                                          enum rogue_ctrl_op_mod mod)
1522*61046927SAndroid Build Coastguard Worker {
1523*61046927SAndroid Build Coastguard Worker    ctrl->mod |= BITFIELD64_BIT(mod);
1524*61046927SAndroid Build Coastguard Worker }
1525*61046927SAndroid Build Coastguard Worker 
rogue_ctrl_op_mod_is_set(const rogue_ctrl_instr * ctrl,enum rogue_ctrl_op_mod mod)1526*61046927SAndroid Build Coastguard Worker static inline bool rogue_ctrl_op_mod_is_set(const rogue_ctrl_instr *ctrl,
1527*61046927SAndroid Build Coastguard Worker                                             enum rogue_ctrl_op_mod mod)
1528*61046927SAndroid Build Coastguard Worker {
1529*61046927SAndroid Build Coastguard Worker    return !!(ctrl->mod & BITFIELD64_BIT(mod));
1530*61046927SAndroid Build Coastguard Worker }
1531*61046927SAndroid Build Coastguard Worker 
1532*61046927SAndroid Build Coastguard Worker /**
1533*61046927SAndroid Build Coastguard Worker  * \brief Allocates and initializes a new control instruction.
1534*61046927SAndroid Build Coastguard Worker  *
1535*61046927SAndroid Build Coastguard Worker  * \param[in] block The block which will contain the instruction.
1536*61046927SAndroid Build Coastguard Worker  * \param[in] op The ALU instruction operation.
1537*61046927SAndroid Build Coastguard Worker  * \return The new instruction.
1538*61046927SAndroid Build Coastguard Worker  */
1539*61046927SAndroid Build Coastguard Worker rogue_ctrl_instr *rogue_ctrl_instr_create(rogue_block *block,
1540*61046927SAndroid Build Coastguard Worker                                           enum rogue_ctrl_op op);
1541*61046927SAndroid Build Coastguard Worker 
1542*61046927SAndroid Build Coastguard Worker enum rogue_bitwise_op {
1543*61046927SAndroid Build Coastguard Worker    ROGUE_BITWISE_OP_INVALID = 0,
1544*61046927SAndroid Build Coastguard Worker 
1545*61046927SAndroid Build Coastguard Worker    /* Real instructions. */
1546*61046927SAndroid Build Coastguard Worker    ROGUE_BITWISE_OP_BYP0,
1547*61046927SAndroid Build Coastguard Worker 
1548*61046927SAndroid Build Coastguard Worker    /* Pseudo-instructions. */
1549*61046927SAndroid Build Coastguard Worker    ROGUE_BITWISE_OP_PSEUDO,
1550*61046927SAndroid Build Coastguard Worker    ROGUE_BITWISE_OP_ = ROGUE_BITWISE_OP_PSEUDO,
1551*61046927SAndroid Build Coastguard Worker 
1552*61046927SAndroid Build Coastguard Worker    ROGUE_BITWISE_OP_COUNT,
1553*61046927SAndroid Build Coastguard Worker };
1554*61046927SAndroid Build Coastguard Worker 
1555*61046927SAndroid Build Coastguard Worker enum rogue_bitwise_op_mod {
1556*61046927SAndroid Build Coastguard Worker    /* In order of priority */
1557*61046927SAndroid Build Coastguard Worker    ROGUE_BITWISE_OP_MOD_TWB, /* Top word break. */
1558*61046927SAndroid Build Coastguard Worker    ROGUE_BITWISE_OP_MOD_PWB, /* Partial word break. */
1559*61046927SAndroid Build Coastguard Worker    ROGUE_BITWISE_OP_MOD_MTB, /* Mask top break. */
1560*61046927SAndroid Build Coastguard Worker    ROGUE_BITWISE_OP_MOD_FTB, /* Find top break. */
1561*61046927SAndroid Build Coastguard Worker 
1562*61046927SAndroid Build Coastguard Worker    ROGUE_BITWISE_OP_MOD_COUNT,
1563*61046927SAndroid Build Coastguard Worker };
1564*61046927SAndroid Build Coastguard Worker 
1565*61046927SAndroid Build Coastguard Worker typedef struct rogue_bitwise_op_mod_info {
1566*61046927SAndroid Build Coastguard Worker    const char *str;
1567*61046927SAndroid Build Coastguard Worker    uint64_t exclude; /* Can't use this op mod with any of these. */
1568*61046927SAndroid Build Coastguard Worker    uint64_t require; /* Required op mods for this to be used (OR). */
1569*61046927SAndroid Build Coastguard Worker } rogue_bitwise_op_mod_info;
1570*61046927SAndroid Build Coastguard Worker 
1571*61046927SAndroid Build Coastguard Worker extern const rogue_bitwise_op_mod_info
1572*61046927SAndroid Build Coastguard Worker    rogue_bitwise_op_mod_infos[ROGUE_BITWISE_OP_MOD_COUNT];
1573*61046927SAndroid Build Coastguard Worker 
1574*61046927SAndroid Build Coastguard Worker #define ROGUE_BITWISE_OP_MAX_SRCS 7
1575*61046927SAndroid Build Coastguard Worker #define ROGUE_BITWISE_OP_MAX_DSTS 2
1576*61046927SAndroid Build Coastguard Worker 
1577*61046927SAndroid Build Coastguard Worker typedef struct rogue_bitwise_op_info {
1578*61046927SAndroid Build Coastguard Worker    const char *str;
1579*61046927SAndroid Build Coastguard Worker 
1580*61046927SAndroid Build Coastguard Worker    unsigned num_dsts;
1581*61046927SAndroid Build Coastguard Worker    unsigned num_srcs;
1582*61046927SAndroid Build Coastguard Worker 
1583*61046927SAndroid Build Coastguard Worker    uint64_t supported_phases;
1584*61046927SAndroid Build Coastguard Worker    rogue_alu_io_info phase_io[ROGUE_INSTR_PHASE_COUNT];
1585*61046927SAndroid Build Coastguard Worker 
1586*61046927SAndroid Build Coastguard Worker    uint64_t supported_op_mods;
1587*61046927SAndroid Build Coastguard Worker    uint64_t supported_dst_mods[ROGUE_BITWISE_OP_MAX_DSTS];
1588*61046927SAndroid Build Coastguard Worker    uint64_t supported_src_mods[ROGUE_BITWISE_OP_MAX_SRCS];
1589*61046927SAndroid Build Coastguard Worker 
1590*61046927SAndroid Build Coastguard Worker    uint64_t supported_dst_types[ROGUE_BITWISE_OP_MAX_DSTS];
1591*61046927SAndroid Build Coastguard Worker    uint64_t supported_src_types[ROGUE_BITWISE_OP_MAX_SRCS];
1592*61046927SAndroid Build Coastguard Worker 
1593*61046927SAndroid Build Coastguard Worker    unsigned dst_stride[ROGUE_CTRL_OP_MAX_DSTS];
1594*61046927SAndroid Build Coastguard Worker    unsigned src_stride[ROGUE_CTRL_OP_MAX_SRCS];
1595*61046927SAndroid Build Coastguard Worker 
1596*61046927SAndroid Build Coastguard Worker    uint64_t dst_repeat_mask;
1597*61046927SAndroid Build Coastguard Worker    uint64_t src_repeat_mask;
1598*61046927SAndroid Build Coastguard Worker } rogue_bitwise_op_info;
1599*61046927SAndroid Build Coastguard Worker 
1600*61046927SAndroid Build Coastguard Worker extern const rogue_bitwise_op_info
1601*61046927SAndroid Build Coastguard Worker    rogue_bitwise_op_infos[ROGUE_BITWISE_OP_COUNT];
1602*61046927SAndroid Build Coastguard Worker 
1603*61046927SAndroid Build Coastguard Worker typedef struct rogue_bitwise_dst {
1604*61046927SAndroid Build Coastguard Worker    rogue_ref ref;
1605*61046927SAndroid Build Coastguard Worker    unsigned index;
1606*61046927SAndroid Build Coastguard Worker } rogue_bitwise_dst;
1607*61046927SAndroid Build Coastguard Worker 
1608*61046927SAndroid Build Coastguard Worker typedef struct rogue_bitwise_src {
1609*61046927SAndroid Build Coastguard Worker    rogue_ref ref;
1610*61046927SAndroid Build Coastguard Worker    unsigned index;
1611*61046927SAndroid Build Coastguard Worker } rogue_bitwise_src;
1612*61046927SAndroid Build Coastguard Worker 
1613*61046927SAndroid Build Coastguard Worker typedef struct rogue_bitwise_instr {
1614*61046927SAndroid Build Coastguard Worker    rogue_instr instr;
1615*61046927SAndroid Build Coastguard Worker 
1616*61046927SAndroid Build Coastguard Worker    enum rogue_bitwise_op op;
1617*61046927SAndroid Build Coastguard Worker 
1618*61046927SAndroid Build Coastguard Worker    uint64_t mod;
1619*61046927SAndroid Build Coastguard Worker 
1620*61046927SAndroid Build Coastguard Worker    /* TODO NEXT: source/dest modifiers */
1621*61046927SAndroid Build Coastguard Worker 
1622*61046927SAndroid Build Coastguard Worker    rogue_instr_dst dst[ROGUE_BITWISE_OP_MAX_DSTS];
1623*61046927SAndroid Build Coastguard Worker    rogue_dst_write dst_write[ROGUE_BITWISE_OP_MAX_DSTS];
1624*61046927SAndroid Build Coastguard Worker 
1625*61046927SAndroid Build Coastguard Worker    rogue_instr_src src[ROGUE_BITWISE_OP_MAX_SRCS];
1626*61046927SAndroid Build Coastguard Worker    rogue_src_use src_use[ROGUE_BITWISE_OP_MAX_SRCS];
1627*61046927SAndroid Build Coastguard Worker } rogue_bitwise_instr;
1628*61046927SAndroid Build Coastguard Worker 
rogue_set_bitwise_op_mod(rogue_bitwise_instr * bitwise,enum rogue_bitwise_op_mod mod)1629*61046927SAndroid Build Coastguard Worker static inline void rogue_set_bitwise_op_mod(rogue_bitwise_instr *bitwise,
1630*61046927SAndroid Build Coastguard Worker                                             enum rogue_bitwise_op_mod mod)
1631*61046927SAndroid Build Coastguard Worker {
1632*61046927SAndroid Build Coastguard Worker    bitwise->mod |= BITFIELD64_BIT(mod);
1633*61046927SAndroid Build Coastguard Worker }
1634*61046927SAndroid Build Coastguard Worker 
1635*61046927SAndroid Build Coastguard Worker static inline bool
rogue_bitwise_op_mod_is_set(const rogue_bitwise_instr * bitwise,enum rogue_bitwise_op_mod mod)1636*61046927SAndroid Build Coastguard Worker rogue_bitwise_op_mod_is_set(const rogue_bitwise_instr *bitwise,
1637*61046927SAndroid Build Coastguard Worker                             enum rogue_bitwise_op_mod mod)
1638*61046927SAndroid Build Coastguard Worker {
1639*61046927SAndroid Build Coastguard Worker    return !!(bitwise->mod & BITFIELD64_BIT(mod));
1640*61046927SAndroid Build Coastguard Worker }
1641*61046927SAndroid Build Coastguard Worker 
1642*61046927SAndroid Build Coastguard Worker /**
1643*61046927SAndroid Build Coastguard Worker  * \brief Allocates and initializes a new bitwise instruction.
1644*61046927SAndroid Build Coastguard Worker  *
1645*61046927SAndroid Build Coastguard Worker  * \param[in] op The ALU instruction operation.
1646*61046927SAndroid Build Coastguard Worker  * \return The new instruction.
1647*61046927SAndroid Build Coastguard Worker  */
1648*61046927SAndroid Build Coastguard Worker rogue_bitwise_instr *rogue_bitwise_instr_create(rogue_block *block,
1649*61046927SAndroid Build Coastguard Worker                                                 enum rogue_bitwise_op op);
1650*61046927SAndroid Build Coastguard Worker 
1651*61046927SAndroid Build Coastguard Worker /** Defines a cast function
1652*61046927SAndroid Build Coastguard Worker  *
1653*61046927SAndroid Build Coastguard Worker  * This macro defines a cast function from in_type to out_type where
1654*61046927SAndroid Build Coastguard Worker  * out_type is some structure type that contains a field of type out_type.
1655*61046927SAndroid Build Coastguard Worker  *
1656*61046927SAndroid Build Coastguard Worker  * Note that you have to be a bit careful as the generated cast function
1657*61046927SAndroid Build Coastguard Worker  * destroys constness.
1658*61046927SAndroid Build Coastguard Worker  */
1659*61046927SAndroid Build Coastguard Worker #define ROGUE_DEFINE_CAST(name,                           \
1660*61046927SAndroid Build Coastguard Worker                           in_type,                        \
1661*61046927SAndroid Build Coastguard Worker                           out_type,                       \
1662*61046927SAndroid Build Coastguard Worker                           field,                          \
1663*61046927SAndroid Build Coastguard Worker                           type_field,                     \
1664*61046927SAndroid Build Coastguard Worker                           type_value)                     \
1665*61046927SAndroid Build Coastguard Worker    static inline out_type *name(const in_type *parent)    \
1666*61046927SAndroid Build Coastguard Worker    {                                                      \
1667*61046927SAndroid Build Coastguard Worker       assert(parent && parent->type_field == type_value); \
1668*61046927SAndroid Build Coastguard Worker       return list_entry(parent, out_type, field);         \
1669*61046927SAndroid Build Coastguard Worker    }
1670*61046927SAndroid Build Coastguard Worker 
ROGUE_DEFINE_CAST(rogue_instr_as_alu,rogue_instr,rogue_alu_instr,instr,type,ROGUE_INSTR_TYPE_ALU)1671*61046927SAndroid Build Coastguard Worker ROGUE_DEFINE_CAST(rogue_instr_as_alu,
1672*61046927SAndroid Build Coastguard Worker                   rogue_instr,
1673*61046927SAndroid Build Coastguard Worker                   rogue_alu_instr,
1674*61046927SAndroid Build Coastguard Worker                   instr,
1675*61046927SAndroid Build Coastguard Worker                   type,
1676*61046927SAndroid Build Coastguard Worker                   ROGUE_INSTR_TYPE_ALU)
1677*61046927SAndroid Build Coastguard Worker ROGUE_DEFINE_CAST(rogue_instr_as_backend,
1678*61046927SAndroid Build Coastguard Worker                   rogue_instr,
1679*61046927SAndroid Build Coastguard Worker                   rogue_backend_instr,
1680*61046927SAndroid Build Coastguard Worker                   instr,
1681*61046927SAndroid Build Coastguard Worker                   type,
1682*61046927SAndroid Build Coastguard Worker                   ROGUE_INSTR_TYPE_BACKEND)
1683*61046927SAndroid Build Coastguard Worker ROGUE_DEFINE_CAST(rogue_instr_as_ctrl,
1684*61046927SAndroid Build Coastguard Worker                   rogue_instr,
1685*61046927SAndroid Build Coastguard Worker                   rogue_ctrl_instr,
1686*61046927SAndroid Build Coastguard Worker                   instr,
1687*61046927SAndroid Build Coastguard Worker                   type,
1688*61046927SAndroid Build Coastguard Worker                   ROGUE_INSTR_TYPE_CTRL)
1689*61046927SAndroid Build Coastguard Worker ROGUE_DEFINE_CAST(rogue_instr_as_bitwise,
1690*61046927SAndroid Build Coastguard Worker                   rogue_instr,
1691*61046927SAndroid Build Coastguard Worker                   rogue_bitwise_instr,
1692*61046927SAndroid Build Coastguard Worker                   instr,
1693*61046927SAndroid Build Coastguard Worker                   type,
1694*61046927SAndroid Build Coastguard Worker                   ROGUE_INSTR_TYPE_BITWISE)
1695*61046927SAndroid Build Coastguard Worker 
1696*61046927SAndroid Build Coastguard Worker static inline enum rogue_io rogue_instr_src_io_src(const rogue_instr *instr,
1697*61046927SAndroid Build Coastguard Worker                                                    enum rogue_instr_phase phase,
1698*61046927SAndroid Build Coastguard Worker                                                    unsigned src_index)
1699*61046927SAndroid Build Coastguard Worker {
1700*61046927SAndroid Build Coastguard Worker    switch (instr->type) {
1701*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_ALU: {
1702*61046927SAndroid Build Coastguard Worker       const rogue_alu_instr *alu = rogue_instr_as_alu(instr);
1703*61046927SAndroid Build Coastguard Worker       const rogue_alu_op_info *info = &rogue_alu_op_infos[alu->op];
1704*61046927SAndroid Build Coastguard Worker       return info->phase_io[phase].src[src_index];
1705*61046927SAndroid Build Coastguard Worker    }
1706*61046927SAndroid Build Coastguard Worker 
1707*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_BACKEND: {
1708*61046927SAndroid Build Coastguard Worker       const rogue_backend_instr *backend = rogue_instr_as_backend(instr);
1709*61046927SAndroid Build Coastguard Worker       const rogue_backend_op_info *info = &rogue_backend_op_infos[backend->op];
1710*61046927SAndroid Build Coastguard Worker       return info->phase_io.src[src_index];
1711*61046927SAndroid Build Coastguard Worker    }
1712*61046927SAndroid Build Coastguard Worker 
1713*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_CTRL: {
1714*61046927SAndroid Build Coastguard Worker       /* TODO after phase_io is added to relevant control instructions as well.
1715*61046927SAndroid Build Coastguard Worker        */
1716*61046927SAndroid Build Coastguard Worker       break;
1717*61046927SAndroid Build Coastguard Worker    }
1718*61046927SAndroid Build Coastguard Worker 
1719*61046927SAndroid Build Coastguard Worker    default:
1720*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported instruction type.");
1721*61046927SAndroid Build Coastguard Worker       break;
1722*61046927SAndroid Build Coastguard Worker    }
1723*61046927SAndroid Build Coastguard Worker 
1724*61046927SAndroid Build Coastguard Worker    return ROGUE_IO_INVALID;
1725*61046927SAndroid Build Coastguard Worker }
1726*61046927SAndroid Build Coastguard Worker 
1727*61046927SAndroid Build Coastguard Worker /* Maps sources and destinations ("inputs"/"outputs") to registers. */
1728*61046927SAndroid Build Coastguard Worker typedef struct rogue_instr_group_io_sel {
1729*61046927SAndroid Build Coastguard Worker    rogue_ref srcs[ROGUE_ISA_SRCS]; /** Upper + lower sources. */
1730*61046927SAndroid Build Coastguard Worker    rogue_ref dsts[ROGUE_ISA_DSTS]; /** Destinations. */
1731*61046927SAndroid Build Coastguard Worker    rogue_ref iss[ROGUE_ISA_ISSS]; /** Internal source selector (includes
1732*61046927SAndroid Build Coastguard Worker                                      IS0/MUX). */
1733*61046927SAndroid Build Coastguard Worker } rogue_instr_group_io_sel;
1734*61046927SAndroid Build Coastguard Worker 
1735*61046927SAndroid Build Coastguard Worker static inline rogue_ref *
rogue_instr_group_io_sel_ref(rogue_instr_group_io_sel * map,enum rogue_io io)1736*61046927SAndroid Build Coastguard Worker rogue_instr_group_io_sel_ref(rogue_instr_group_io_sel *map, enum rogue_io io)
1737*61046927SAndroid Build Coastguard Worker {
1738*61046927SAndroid Build Coastguard Worker    if (rogue_io_is_src(io))
1739*61046927SAndroid Build Coastguard Worker       return &map->srcs[io - ROGUE_IO_S0];
1740*61046927SAndroid Build Coastguard Worker    else if (rogue_io_is_dst(io))
1741*61046927SAndroid Build Coastguard Worker       return &map->dsts[io - ROGUE_IO_W0];
1742*61046927SAndroid Build Coastguard Worker    else if (rogue_io_is_iss(io))
1743*61046927SAndroid Build Coastguard Worker       return &map->iss[io - ROGUE_IO_IS0];
1744*61046927SAndroid Build Coastguard Worker    unreachable("Unsupported io.");
1745*61046927SAndroid Build Coastguard Worker }
1746*61046927SAndroid Build Coastguard Worker 
1747*61046927SAndroid Build Coastguard Worker /** Rogue instruction group. */
1748*61046927SAndroid Build Coastguard Worker typedef struct rogue_instr_group {
1749*61046927SAndroid Build Coastguard Worker    rogue_block *block;
1750*61046927SAndroid Build Coastguard Worker    struct list_head link; /** Link in rogue_block::instrs. */
1751*61046927SAndroid Build Coastguard Worker 
1752*61046927SAndroid Build Coastguard Worker    rogue_instr *instrs[ROGUE_INSTR_PHASE_COUNT]; /** Instructions in group. */
1753*61046927SAndroid Build Coastguard Worker    rogue_instr_group_io_sel io_sel; /** Source, destination, internal source
1754*61046927SAndroid Build Coastguard Worker                                        selector maps. */
1755*61046927SAndroid Build Coastguard Worker 
1756*61046927SAndroid Build Coastguard Worker    struct {
1757*61046927SAndroid Build Coastguard Worker       uint64_t phases; /** Instructions phases present. */
1758*61046927SAndroid Build Coastguard Worker 
1759*61046927SAndroid Build Coastguard Worker       enum rogue_exec_cond exec_cond;
1760*61046927SAndroid Build Coastguard Worker       enum rogue_alu alu;
1761*61046927SAndroid Build Coastguard Worker 
1762*61046927SAndroid Build Coastguard Worker       bool end; /** Shader end flag. */
1763*61046927SAndroid Build Coastguard Worker       unsigned repeat;
1764*61046927SAndroid Build Coastguard Worker    } header;
1765*61046927SAndroid Build Coastguard Worker 
1766*61046927SAndroid Build Coastguard Worker    struct {
1767*61046927SAndroid Build Coastguard Worker       unsigned header;
1768*61046927SAndroid Build Coastguard Worker       unsigned instrs[ROGUE_INSTR_PHASE_COUNT];
1769*61046927SAndroid Build Coastguard Worker       unsigned lower_srcs;
1770*61046927SAndroid Build Coastguard Worker       unsigned upper_srcs;
1771*61046927SAndroid Build Coastguard Worker       unsigned iss;
1772*61046927SAndroid Build Coastguard Worker       unsigned dsts;
1773*61046927SAndroid Build Coastguard Worker       unsigned word_padding; /* Padding to make total size a word (% 2 == 0) */
1774*61046927SAndroid Build Coastguard Worker       unsigned align_padding; /* Padding to align instruction position in memory
1775*61046927SAndroid Build Coastguard Worker                                */
1776*61046927SAndroid Build Coastguard Worker       unsigned total;
1777*61046927SAndroid Build Coastguard Worker 
1778*61046927SAndroid Build Coastguard Worker       unsigned offset;
1779*61046927SAndroid Build Coastguard Worker    } size;
1780*61046927SAndroid Build Coastguard Worker 
1781*61046927SAndroid Build Coastguard Worker    struct {
1782*61046927SAndroid Build Coastguard Worker       unsigned lower_src_index;
1783*61046927SAndroid Build Coastguard Worker       unsigned upper_src_index;
1784*61046927SAndroid Build Coastguard Worker       unsigned dst_index;
1785*61046927SAndroid Build Coastguard Worker    } encode_info;
1786*61046927SAndroid Build Coastguard Worker 
1787*61046927SAndroid Build Coastguard Worker    unsigned index; /** For debug purposes. */
1788*61046927SAndroid Build Coastguard Worker } rogue_instr_group;
1789*61046927SAndroid Build Coastguard Worker 
1790*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_group_in_block(group, block) \
1791*61046927SAndroid Build Coastguard Worker    list_for_each_entry (rogue_instr_group, group, &(block)->instrs, link)
1792*61046927SAndroid Build Coastguard Worker 
1793*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_group_in_block_safe(group, block) \
1794*61046927SAndroid Build Coastguard Worker    list_for_each_entry_safe (rogue_instr_group, group, &(block)->instrs, link)
1795*61046927SAndroid Build Coastguard Worker 
1796*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_group_in_shader(group, shader) \
1797*61046927SAndroid Build Coastguard Worker    rogue_foreach_block (_block, (shader))                  \
1798*61046927SAndroid Build Coastguard Worker       rogue_foreach_instr_group_in_block ((group), _block)
1799*61046927SAndroid Build Coastguard Worker 
1800*61046927SAndroid Build Coastguard Worker #define rogue_foreach_instr_group_in_shader_safe(group, shader) \
1801*61046927SAndroid Build Coastguard Worker    rogue_foreach_block_safe (_block, (shader))                  \
1802*61046927SAndroid Build Coastguard Worker       rogue_foreach_instr_group_in_block_safe ((group), _block)
1803*61046927SAndroid Build Coastguard Worker 
rogue_instr_group_create(rogue_block * block,enum rogue_alu alu)1804*61046927SAndroid Build Coastguard Worker static inline rogue_instr_group *rogue_instr_group_create(rogue_block *block,
1805*61046927SAndroid Build Coastguard Worker                                                           enum rogue_alu alu)
1806*61046927SAndroid Build Coastguard Worker {
1807*61046927SAndroid Build Coastguard Worker    rogue_instr_group *group = rzalloc_size(block, sizeof(*group));
1808*61046927SAndroid Build Coastguard Worker    group->header.alu = alu;
1809*61046927SAndroid Build Coastguard Worker    group->block = block;
1810*61046927SAndroid Build Coastguard Worker    return group;
1811*61046927SAndroid Build Coastguard Worker }
1812*61046927SAndroid Build Coastguard Worker 
1813*61046927SAndroid Build Coastguard Worker typedef struct rogue_build_ctx rogue_build_ctx;
1814*61046927SAndroid Build Coastguard Worker 
1815*61046927SAndroid Build Coastguard Worker /** Rogue shader object. */
1816*61046927SAndroid Build Coastguard Worker typedef struct rogue_shader {
1817*61046927SAndroid Build Coastguard Worker    gl_shader_stage stage; /** Shader stage. */
1818*61046927SAndroid Build Coastguard Worker 
1819*61046927SAndroid Build Coastguard Worker    rogue_build_ctx *ctx; /** Build context. */
1820*61046927SAndroid Build Coastguard Worker 
1821*61046927SAndroid Build Coastguard Worker    unsigned next_instr; /** Next instruction index. */
1822*61046927SAndroid Build Coastguard Worker    unsigned next_block; /** Next block index. */
1823*61046927SAndroid Build Coastguard Worker 
1824*61046927SAndroid Build Coastguard Worker    struct list_head blocks; /** List of basic blocks. */
1825*61046927SAndroid Build Coastguard Worker    struct list_head regs[ROGUE_REG_CLASS_COUNT]; /** List of registers used by
1826*61046927SAndroid Build Coastguard Worker                                                     the shader. */
1827*61046927SAndroid Build Coastguard Worker    BITSET_WORD *regs_used[ROGUE_REG_CLASS_COUNT]; /** Bitset of register numbers
1828*61046927SAndroid Build Coastguard Worker                                                      used. */
1829*61046927SAndroid Build Coastguard Worker    struct util_sparse_array reg_cache[ROGUE_REG_CLASS_COUNT];
1830*61046927SAndroid Build Coastguard Worker 
1831*61046927SAndroid Build Coastguard Worker    struct list_head regarrays; /** List of register arrays used by the shader.
1832*61046927SAndroid Build Coastguard Worker                                 */
1833*61046927SAndroid Build Coastguard Worker    struct util_sparse_array regarray_cache;
1834*61046927SAndroid Build Coastguard Worker 
1835*61046927SAndroid Build Coastguard Worker    struct list_head drc_trxns[ROGUE_DRCS]; /** List of drc transactions. */
1836*61046927SAndroid Build Coastguard Worker 
1837*61046927SAndroid Build Coastguard Worker    struct list_head imm_uses; /** List of immediate value uses. */
1838*61046927SAndroid Build Coastguard Worker 
1839*61046927SAndroid Build Coastguard Worker    bool is_grouped; /** Whether the instructions are grouped. */
1840*61046927SAndroid Build Coastguard Worker 
1841*61046927SAndroid Build Coastguard Worker    const char *name; /** Shader name. */
1842*61046927SAndroid Build Coastguard Worker } rogue_shader;
1843*61046927SAndroid Build Coastguard Worker 
rogue_set_shader_name(rogue_shader * shader,const char * name)1844*61046927SAndroid Build Coastguard Worker static inline void rogue_set_shader_name(rogue_shader *shader, const char *name)
1845*61046927SAndroid Build Coastguard Worker {
1846*61046927SAndroid Build Coastguard Worker    shader->name = ralloc_strdup(shader, name);
1847*61046927SAndroid Build Coastguard Worker }
1848*61046927SAndroid Build Coastguard Worker 
rogue_reg_is_used(const rogue_shader * shader,enum rogue_reg_class class,unsigned index)1849*61046927SAndroid Build Coastguard Worker static inline bool rogue_reg_is_used(const rogue_shader *shader,
1850*61046927SAndroid Build Coastguard Worker                                      enum rogue_reg_class class,
1851*61046927SAndroid Build Coastguard Worker                                      unsigned index)
1852*61046927SAndroid Build Coastguard Worker {
1853*61046927SAndroid Build Coastguard Worker    return BITSET_TEST(shader->regs_used[class], index);
1854*61046927SAndroid Build Coastguard Worker }
1855*61046927SAndroid Build Coastguard Worker 
rogue_set_reg_use(rogue_shader * shader,enum rogue_reg_class class,unsigned index)1856*61046927SAndroid Build Coastguard Worker static inline void rogue_set_reg_use(rogue_shader *shader,
1857*61046927SAndroid Build Coastguard Worker                                      enum rogue_reg_class class,
1858*61046927SAndroid Build Coastguard Worker                                      unsigned index)
1859*61046927SAndroid Build Coastguard Worker {
1860*61046927SAndroid Build Coastguard Worker    BITSET_SET(shader->regs_used[class], index);
1861*61046927SAndroid Build Coastguard Worker }
1862*61046927SAndroid Build Coastguard Worker 
rogue_clear_reg_use(rogue_shader * shader,enum rogue_reg_class class,unsigned index)1863*61046927SAndroid Build Coastguard Worker static inline void rogue_clear_reg_use(rogue_shader *shader,
1864*61046927SAndroid Build Coastguard Worker                                        enum rogue_reg_class class,
1865*61046927SAndroid Build Coastguard Worker                                        unsigned index)
1866*61046927SAndroid Build Coastguard Worker {
1867*61046927SAndroid Build Coastguard Worker    BITSET_CLEAR(shader->regs_used[class], index);
1868*61046927SAndroid Build Coastguard Worker }
1869*61046927SAndroid Build Coastguard Worker 
1870*61046927SAndroid Build Coastguard Worker /**
1871*61046927SAndroid Build Coastguard Worker  * \brief Allocates and initializes a new rogue_shader object.
1872*61046927SAndroid Build Coastguard Worker  *
1873*61046927SAndroid Build Coastguard Worker  * \param[in] mem_ctx The parent memory context.
1874*61046927SAndroid Build Coastguard Worker  * \param[in] stage The shader stage.
1875*61046927SAndroid Build Coastguard Worker  * \return The new shader.
1876*61046927SAndroid Build Coastguard Worker  */
1877*61046927SAndroid Build Coastguard Worker rogue_shader *rogue_shader_create(void *mem_ctx, gl_shader_stage stage);
1878*61046927SAndroid Build Coastguard Worker 
1879*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_ssa_reg(rogue_shader *shader, unsigned index);
1880*61046927SAndroid Build Coastguard Worker 
1881*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_temp_reg(rogue_shader *shader, unsigned index);
1882*61046927SAndroid Build Coastguard Worker 
1883*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_coeff_reg(rogue_shader *shader, unsigned index);
1884*61046927SAndroid Build Coastguard Worker 
1885*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_shared_reg(rogue_shader *shader, unsigned index);
1886*61046927SAndroid Build Coastguard Worker 
1887*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_const_reg(rogue_shader *shader, unsigned index);
1888*61046927SAndroid Build Coastguard Worker 
1889*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_pixout_reg(rogue_shader *shader, unsigned index);
1890*61046927SAndroid Build Coastguard Worker 
1891*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_special_reg(rogue_shader *shader, unsigned index);
1892*61046927SAndroid Build Coastguard Worker 
1893*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_vtxin_reg(rogue_shader *shader, unsigned index);
1894*61046927SAndroid Build Coastguard Worker 
1895*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_vtxout_reg(rogue_shader *shader, unsigned index);
1896*61046927SAndroid Build Coastguard Worker 
1897*61046927SAndroid Build Coastguard Worker rogue_reg *
1898*61046927SAndroid Build Coastguard Worker rogue_ssa_vec_reg(rogue_shader *shader, unsigned index, unsigned component);
1899*61046927SAndroid Build Coastguard Worker 
1900*61046927SAndroid Build Coastguard Worker void rogue_reg_delete(rogue_reg *reg);
1901*61046927SAndroid Build Coastguard Worker 
1902*61046927SAndroid Build Coastguard Worker rogue_regarray *
1903*61046927SAndroid Build Coastguard Worker rogue_ssa_regarray(rogue_shader *shader, unsigned size, unsigned start_index);
1904*61046927SAndroid Build Coastguard Worker 
1905*61046927SAndroid Build Coastguard Worker rogue_regarray *
1906*61046927SAndroid Build Coastguard Worker rogue_temp_regarray(rogue_shader *shader, unsigned size, unsigned start_index);
1907*61046927SAndroid Build Coastguard Worker 
1908*61046927SAndroid Build Coastguard Worker rogue_regarray *
1909*61046927SAndroid Build Coastguard Worker rogue_coeff_regarray(rogue_shader *shader, unsigned size, unsigned start_index);
1910*61046927SAndroid Build Coastguard Worker 
1911*61046927SAndroid Build Coastguard Worker rogue_regarray *rogue_shared_regarray(rogue_shader *shader,
1912*61046927SAndroid Build Coastguard Worker                                       unsigned size,
1913*61046927SAndroid Build Coastguard Worker                                       unsigned start_index);
1914*61046927SAndroid Build Coastguard Worker 
1915*61046927SAndroid Build Coastguard Worker rogue_regarray *rogue_ssa_vec_regarray(rogue_shader *shader,
1916*61046927SAndroid Build Coastguard Worker                                        unsigned size,
1917*61046927SAndroid Build Coastguard Worker                                        unsigned start_index,
1918*61046927SAndroid Build Coastguard Worker                                        unsigned component);
1919*61046927SAndroid Build Coastguard Worker 
1920*61046927SAndroid Build Coastguard Worker rogue_regarray *rogue_regarray_cached(rogue_shader *shader,
1921*61046927SAndroid Build Coastguard Worker                                       unsigned size,
1922*61046927SAndroid Build Coastguard Worker                                       enum rogue_reg_class class,
1923*61046927SAndroid Build Coastguard Worker                                       uint32_t start_index);
1924*61046927SAndroid Build Coastguard Worker 
1925*61046927SAndroid Build Coastguard Worker rogue_regarray *rogue_vec_regarray_cached(rogue_shader *shader,
1926*61046927SAndroid Build Coastguard Worker                                           unsigned size,
1927*61046927SAndroid Build Coastguard Worker                                           enum rogue_reg_class class,
1928*61046927SAndroid Build Coastguard Worker                                           uint32_t start_index,
1929*61046927SAndroid Build Coastguard Worker                                           uint8_t component);
1930*61046927SAndroid Build Coastguard Worker 
rogue_regarray_is_unused(rogue_regarray * regarray)1931*61046927SAndroid Build Coastguard Worker static inline bool rogue_regarray_is_unused(rogue_regarray *regarray)
1932*61046927SAndroid Build Coastguard Worker {
1933*61046927SAndroid Build Coastguard Worker    return list_is_empty(&regarray->uses) && list_is_empty(&regarray->writes);
1934*61046927SAndroid Build Coastguard Worker }
1935*61046927SAndroid Build Coastguard Worker 
rogue_regarray_delete(rogue_regarray * regarray)1936*61046927SAndroid Build Coastguard Worker static void rogue_regarray_delete(rogue_regarray *regarray)
1937*61046927SAndroid Build Coastguard Worker {
1938*61046927SAndroid Build Coastguard Worker    assert(rogue_regarray_is_unused(regarray));
1939*61046927SAndroid Build Coastguard Worker 
1940*61046927SAndroid Build Coastguard Worker    if (!regarray->parent) {
1941*61046927SAndroid Build Coastguard Worker       for (unsigned u = 0; u < regarray->size; ++u)
1942*61046927SAndroid Build Coastguard Worker          rogue_reg_delete(regarray->regs[u]);
1943*61046927SAndroid Build Coastguard Worker    }
1944*61046927SAndroid Build Coastguard Worker 
1945*61046927SAndroid Build Coastguard Worker    if (regarray->cached && *regarray->cached == regarray)
1946*61046927SAndroid Build Coastguard Worker       *regarray->cached = NULL;
1947*61046927SAndroid Build Coastguard Worker 
1948*61046927SAndroid Build Coastguard Worker    list_del(&regarray->link);
1949*61046927SAndroid Build Coastguard Worker    if (regarray->parent)
1950*61046927SAndroid Build Coastguard Worker       list_del(&regarray->child_link);
1951*61046927SAndroid Build Coastguard Worker    ralloc_free(regarray);
1952*61046927SAndroid Build Coastguard Worker }
1953*61046927SAndroid Build Coastguard Worker 
rogue_reset_reg_usage(rogue_shader * shader,enum rogue_reg_class class)1954*61046927SAndroid Build Coastguard Worker static inline void rogue_reset_reg_usage(rogue_shader *shader,
1955*61046927SAndroid Build Coastguard Worker                                          enum rogue_reg_class class)
1956*61046927SAndroid Build Coastguard Worker {
1957*61046927SAndroid Build Coastguard Worker    const rogue_reg_info *info = &rogue_reg_infos[class];
1958*61046927SAndroid Build Coastguard Worker 
1959*61046927SAndroid Build Coastguard Worker    if (info->num) {
1960*61046927SAndroid Build Coastguard Worker       memset(shader->regs_used[class],
1961*61046927SAndroid Build Coastguard Worker              0,
1962*61046927SAndroid Build Coastguard Worker              sizeof(*shader->regs_used[class]) * BITSET_WORDS(info->num));
1963*61046927SAndroid Build Coastguard Worker    }
1964*61046927SAndroid Build Coastguard Worker 
1965*61046927SAndroid Build Coastguard Worker    rogue_foreach_reg (reg, shader, class) {
1966*61046927SAndroid Build Coastguard Worker       reg->dirty = false;
1967*61046927SAndroid Build Coastguard Worker    }
1968*61046927SAndroid Build Coastguard Worker }
1969*61046927SAndroid Build Coastguard Worker 
1970*61046927SAndroid Build Coastguard Worker bool rogue_reg_set(rogue_shader *shader,
1971*61046927SAndroid Build Coastguard Worker                    rogue_reg *reg,
1972*61046927SAndroid Build Coastguard Worker                    enum rogue_reg_class class,
1973*61046927SAndroid Build Coastguard Worker                    unsigned index);
1974*61046927SAndroid Build Coastguard Worker 
1975*61046927SAndroid Build Coastguard Worker bool rogue_reg_rewrite(rogue_shader *shader,
1976*61046927SAndroid Build Coastguard Worker                        rogue_reg *reg,
1977*61046927SAndroid Build Coastguard Worker                        enum rogue_reg_class class,
1978*61046927SAndroid Build Coastguard Worker                        unsigned index);
1979*61046927SAndroid Build Coastguard Worker 
1980*61046927SAndroid Build Coastguard Worker bool rogue_regarray_set(rogue_shader *shader,
1981*61046927SAndroid Build Coastguard Worker                         rogue_regarray *regarray,
1982*61046927SAndroid Build Coastguard Worker                         enum rogue_reg_class class,
1983*61046927SAndroid Build Coastguard Worker                         unsigned base_index,
1984*61046927SAndroid Build Coastguard Worker                         bool set_regs);
1985*61046927SAndroid Build Coastguard Worker 
1986*61046927SAndroid Build Coastguard Worker bool rogue_regarray_rewrite(rogue_shader *shader,
1987*61046927SAndroid Build Coastguard Worker                             rogue_regarray *regarray,
1988*61046927SAndroid Build Coastguard Worker                             enum rogue_reg_class class,
1989*61046927SAndroid Build Coastguard Worker                             unsigned base_index);
1990*61046927SAndroid Build Coastguard Worker 
1991*61046927SAndroid Build Coastguard Worker /** Cursor for Rogue instructions/groups and basic blocks. */
1992*61046927SAndroid Build Coastguard Worker typedef struct rogue_cursor {
1993*61046927SAndroid Build Coastguard Worker    bool block;
1994*61046927SAndroid Build Coastguard Worker    struct list_head *prev; /** Linked-list pointer to before the object. */
1995*61046927SAndroid Build Coastguard Worker    bool first; /** Whether the cursor is pointing to the first element. */
1996*61046927SAndroid Build Coastguard Worker } rogue_cursor;
1997*61046927SAndroid Build Coastguard Worker 
1998*61046927SAndroid Build Coastguard Worker /**
1999*61046927SAndroid Build Coastguard Worker  * \brief Returns a cursor set to the beginning of the shader.
2000*61046927SAndroid Build Coastguard Worker  *
2001*61046927SAndroid Build Coastguard Worker  * \param[in] shader The shader.
2002*61046927SAndroid Build Coastguard Worker  * \return The cursor.
2003*61046927SAndroid Build Coastguard Worker  */
rogue_cursor_before_shader(rogue_shader * shader)2004*61046927SAndroid Build Coastguard Worker static inline rogue_cursor rogue_cursor_before_shader(rogue_shader *shader)
2005*61046927SAndroid Build Coastguard Worker {
2006*61046927SAndroid Build Coastguard Worker    return (rogue_cursor){
2007*61046927SAndroid Build Coastguard Worker       .block = true,
2008*61046927SAndroid Build Coastguard Worker       .prev = &shader->blocks,
2009*61046927SAndroid Build Coastguard Worker       .first = true,
2010*61046927SAndroid Build Coastguard Worker    };
2011*61046927SAndroid Build Coastguard Worker }
2012*61046927SAndroid Build Coastguard Worker 
2013*61046927SAndroid Build Coastguard Worker /**
2014*61046927SAndroid Build Coastguard Worker  * \brief Returns a cursor set to before a block.
2015*61046927SAndroid Build Coastguard Worker  *
2016*61046927SAndroid Build Coastguard Worker  * \param[in] block The block.
2017*61046927SAndroid Build Coastguard Worker  * \return The cursor.
2018*61046927SAndroid Build Coastguard Worker  */
rogue_cursor_before_block(rogue_block * block)2019*61046927SAndroid Build Coastguard Worker static inline rogue_cursor rogue_cursor_before_block(rogue_block *block)
2020*61046927SAndroid Build Coastguard Worker {
2021*61046927SAndroid Build Coastguard Worker    return (rogue_cursor){
2022*61046927SAndroid Build Coastguard Worker       .block = true,
2023*61046927SAndroid Build Coastguard Worker       .prev = block->link.prev,
2024*61046927SAndroid Build Coastguard Worker       .first = (block->link.prev == &block->shader->blocks),
2025*61046927SAndroid Build Coastguard Worker    };
2026*61046927SAndroid Build Coastguard Worker }
2027*61046927SAndroid Build Coastguard Worker 
2028*61046927SAndroid Build Coastguard Worker /**
2029*61046927SAndroid Build Coastguard Worker  * \brief Returns a cursor set to after a block.
2030*61046927SAndroid Build Coastguard Worker  *
2031*61046927SAndroid Build Coastguard Worker  * \param[in] block The block.
2032*61046927SAndroid Build Coastguard Worker  * \return The cursor.
2033*61046927SAndroid Build Coastguard Worker  */
rogue_cursor_after_block(rogue_block * block)2034*61046927SAndroid Build Coastguard Worker static inline rogue_cursor rogue_cursor_after_block(rogue_block *block)
2035*61046927SAndroid Build Coastguard Worker {
2036*61046927SAndroid Build Coastguard Worker    return (rogue_cursor){
2037*61046927SAndroid Build Coastguard Worker       .block = true,
2038*61046927SAndroid Build Coastguard Worker       .prev = &block->link,
2039*61046927SAndroid Build Coastguard Worker    };
2040*61046927SAndroid Build Coastguard Worker }
2041*61046927SAndroid Build Coastguard Worker 
2042*61046927SAndroid Build Coastguard Worker /**
2043*61046927SAndroid Build Coastguard Worker  * \brief Returns a cursor set to before an instruction.
2044*61046927SAndroid Build Coastguard Worker  *
2045*61046927SAndroid Build Coastguard Worker  * \param[in] instr The instruction.
2046*61046927SAndroid Build Coastguard Worker  * \return The cursor.
2047*61046927SAndroid Build Coastguard Worker  */
rogue_cursor_before_instr(rogue_instr * instr)2048*61046927SAndroid Build Coastguard Worker static inline rogue_cursor rogue_cursor_before_instr(rogue_instr *instr)
2049*61046927SAndroid Build Coastguard Worker {
2050*61046927SAndroid Build Coastguard Worker    return (rogue_cursor){
2051*61046927SAndroid Build Coastguard Worker       .block = false,
2052*61046927SAndroid Build Coastguard Worker       .prev = instr->link.prev,
2053*61046927SAndroid Build Coastguard Worker       .first = (instr->link.prev == &instr->block->instrs),
2054*61046927SAndroid Build Coastguard Worker    };
2055*61046927SAndroid Build Coastguard Worker }
2056*61046927SAndroid Build Coastguard Worker 
2057*61046927SAndroid Build Coastguard Worker /**
2058*61046927SAndroid Build Coastguard Worker  * \brief Returns a cursor set to after an instruction.
2059*61046927SAndroid Build Coastguard Worker  *
2060*61046927SAndroid Build Coastguard Worker  * \param[in] instr The instruction.
2061*61046927SAndroid Build Coastguard Worker  * \return The cursor.
2062*61046927SAndroid Build Coastguard Worker  */
rogue_cursor_after_instr(rogue_instr * instr)2063*61046927SAndroid Build Coastguard Worker static inline rogue_cursor rogue_cursor_after_instr(rogue_instr *instr)
2064*61046927SAndroid Build Coastguard Worker {
2065*61046927SAndroid Build Coastguard Worker    return (rogue_cursor){
2066*61046927SAndroid Build Coastguard Worker       .block = false,
2067*61046927SAndroid Build Coastguard Worker       .prev = &instr->link,
2068*61046927SAndroid Build Coastguard Worker    };
2069*61046927SAndroid Build Coastguard Worker }
2070*61046927SAndroid Build Coastguard Worker 
2071*61046927SAndroid Build Coastguard Worker /**
2072*61046927SAndroid Build Coastguard Worker  * \brief Allocates and initializes a new rogue_block object.
2073*61046927SAndroid Build Coastguard Worker  *
2074*61046927SAndroid Build Coastguard Worker  * \param[in] shader The shader which will contain the block.
2075*61046927SAndroid Build Coastguard Worker  * \param[in] label The (optional) block label.
2076*61046927SAndroid Build Coastguard Worker  * \return The new block.
2077*61046927SAndroid Build Coastguard Worker  */
2078*61046927SAndroid Build Coastguard Worker rogue_block *rogue_block_create(rogue_shader *shader, const char *label);
2079*61046927SAndroid Build Coastguard Worker 
2080*61046927SAndroid Build Coastguard Worker /**
2081*61046927SAndroid Build Coastguard Worker  * \brief Returns the block currently being pointed to by the cursor.
2082*61046927SAndroid Build Coastguard Worker  *
2083*61046927SAndroid Build Coastguard Worker  * If the cursor is currently pointing to a block, this function will
2084*61046927SAndroid Build Coastguard Worker  * directly return said block. If it is pointing to an instruction, it
2085*61046927SAndroid Build Coastguard Worker  * will return the block that said instruction is a part of.
2086*61046927SAndroid Build Coastguard Worker  *
2087*61046927SAndroid Build Coastguard Worker  * \param[in] cursor A cursor.
2088*61046927SAndroid Build Coastguard Worker  * \return The the block being pointed to.
2089*61046927SAndroid Build Coastguard Worker  */
rogue_cursor_block(rogue_cursor cursor)2090*61046927SAndroid Build Coastguard Worker static inline rogue_block *rogue_cursor_block(rogue_cursor cursor)
2091*61046927SAndroid Build Coastguard Worker {
2092*61046927SAndroid Build Coastguard Worker    rogue_block *block = NULL;
2093*61046927SAndroid Build Coastguard Worker 
2094*61046927SAndroid Build Coastguard Worker    if (cursor.block) {
2095*61046927SAndroid Build Coastguard Worker       assert(!cursor.first && "Cursor is not pointing at a block.");
2096*61046927SAndroid Build Coastguard Worker       block = list_entry(cursor.prev, rogue_block, link);
2097*61046927SAndroid Build Coastguard Worker    } else {
2098*61046927SAndroid Build Coastguard Worker       block = cursor.first ? list_entry(cursor.prev, rogue_block, instrs)
2099*61046927SAndroid Build Coastguard Worker                            : list_entry(cursor.prev, rogue_instr, link)->block;
2100*61046927SAndroid Build Coastguard Worker    }
2101*61046927SAndroid Build Coastguard Worker 
2102*61046927SAndroid Build Coastguard Worker    return block;
2103*61046927SAndroid Build Coastguard Worker }
2104*61046927SAndroid Build Coastguard Worker 
2105*61046927SAndroid Build Coastguard Worker /**
2106*61046927SAndroid Build Coastguard Worker  * \brief Inserts a basic block at the specified cursor position.
2107*61046927SAndroid Build Coastguard Worker  *
2108*61046927SAndroid Build Coastguard Worker  * \param[in] block The basic block to insert.
2109*61046927SAndroid Build Coastguard Worker  * \param[in] cursor The cursor.
2110*61046927SAndroid Build Coastguard Worker  */
rogue_block_insert(rogue_block * block,rogue_cursor cursor)2111*61046927SAndroid Build Coastguard Worker static inline void rogue_block_insert(rogue_block *block, rogue_cursor cursor)
2112*61046927SAndroid Build Coastguard Worker {
2113*61046927SAndroid Build Coastguard Worker    struct list_head *list = cursor.prev;
2114*61046927SAndroid Build Coastguard Worker 
2115*61046927SAndroid Build Coastguard Worker    /* If the cursor is pointing at an instruction, the block
2116*61046927SAndroid Build Coastguard Worker     * is always going to be inserted *after* the block
2117*61046927SAndroid Build Coastguard Worker     * that the instruction is in.
2118*61046927SAndroid Build Coastguard Worker     */
2119*61046927SAndroid Build Coastguard Worker    if (!cursor.block)
2120*61046927SAndroid Build Coastguard Worker       list = &rogue_cursor_block(cursor)->link;
2121*61046927SAndroid Build Coastguard Worker 
2122*61046927SAndroid Build Coastguard Worker    list_add(&block->link, list);
2123*61046927SAndroid Build Coastguard Worker }
2124*61046927SAndroid Build Coastguard Worker 
2125*61046927SAndroid Build Coastguard Worker void rogue_link_instr_write(rogue_instr *instr);
2126*61046927SAndroid Build Coastguard Worker 
2127*61046927SAndroid Build Coastguard Worker void rogue_link_instr_use(rogue_instr *instr);
2128*61046927SAndroid Build Coastguard Worker 
2129*61046927SAndroid Build Coastguard Worker void rogue_unlink_instr_write(rogue_instr *instr);
2130*61046927SAndroid Build Coastguard Worker 
2131*61046927SAndroid Build Coastguard Worker void rogue_unlink_instr_use(rogue_instr *instr);
2132*61046927SAndroid Build Coastguard Worker 
2133*61046927SAndroid Build Coastguard Worker /**
2134*61046927SAndroid Build Coastguard Worker  * \brief Inserts an instruction at the specified cursor position.
2135*61046927SAndroid Build Coastguard Worker  *
2136*61046927SAndroid Build Coastguard Worker  * \param[in] instr The instruction to insert.
2137*61046927SAndroid Build Coastguard Worker  * \param[in] cursor The cursor.
2138*61046927SAndroid Build Coastguard Worker  */
rogue_instr_insert(rogue_instr * instr,rogue_cursor cursor)2139*61046927SAndroid Build Coastguard Worker static inline void rogue_instr_insert(rogue_instr *instr, rogue_cursor cursor)
2140*61046927SAndroid Build Coastguard Worker {
2141*61046927SAndroid Build Coastguard Worker    struct list_head *list = cursor.prev;
2142*61046927SAndroid Build Coastguard Worker 
2143*61046927SAndroid Build Coastguard Worker    /* If the cursor is pointing at block, the instruction
2144*61046927SAndroid Build Coastguard Worker     * is always going to be inserted at the end of any other
2145*61046927SAndroid Build Coastguard Worker     * instructions in the block.
2146*61046927SAndroid Build Coastguard Worker     */
2147*61046927SAndroid Build Coastguard Worker    if (cursor.block)
2148*61046927SAndroid Build Coastguard Worker       list = rogue_cursor_block(cursor)->instrs.prev;
2149*61046927SAndroid Build Coastguard Worker 
2150*61046927SAndroid Build Coastguard Worker    list_add(&instr->link, list);
2151*61046927SAndroid Build Coastguard Worker 
2152*61046927SAndroid Build Coastguard Worker    rogue_link_instr_write(instr);
2153*61046927SAndroid Build Coastguard Worker    rogue_link_instr_use(instr);
2154*61046927SAndroid Build Coastguard Worker }
2155*61046927SAndroid Build Coastguard Worker 
rogue_instr_delete(rogue_instr * instr)2156*61046927SAndroid Build Coastguard Worker static inline void rogue_instr_delete(rogue_instr *instr)
2157*61046927SAndroid Build Coastguard Worker {
2158*61046927SAndroid Build Coastguard Worker    rogue_unlink_instr_use(instr);
2159*61046927SAndroid Build Coastguard Worker    rogue_unlink_instr_write(instr);
2160*61046927SAndroid Build Coastguard Worker 
2161*61046927SAndroid Build Coastguard Worker    list_del(&instr->link);
2162*61046927SAndroid Build Coastguard Worker 
2163*61046927SAndroid Build Coastguard Worker    ralloc_free(instr);
2164*61046927SAndroid Build Coastguard Worker }
2165*61046927SAndroid Build Coastguard Worker 
2166*61046927SAndroid Build Coastguard Worker static inline void
rogue_link_drc_trxn(rogue_shader * shader,rogue_instr * instr,rogue_drc * drc)2167*61046927SAndroid Build Coastguard Worker rogue_link_drc_trxn(rogue_shader *shader, rogue_instr *instr, rogue_drc *drc)
2168*61046927SAndroid Build Coastguard Worker {
2169*61046927SAndroid Build Coastguard Worker    unsigned index = drc->index;
2170*61046927SAndroid Build Coastguard Worker    assert(index < ROGUE_DRCS);
2171*61046927SAndroid Build Coastguard Worker 
2172*61046927SAndroid Build Coastguard Worker    drc->trxn.acquire = instr;
2173*61046927SAndroid Build Coastguard Worker    list_addtail(&drc->trxn.link, &shader->drc_trxns[index]);
2174*61046927SAndroid Build Coastguard Worker }
2175*61046927SAndroid Build Coastguard Worker 
2176*61046927SAndroid Build Coastguard Worker static inline void
rogue_unlink_drc_trxn(rogue_shader * shader,rogue_instr * instr,rogue_drc * drc)2177*61046927SAndroid Build Coastguard Worker rogue_unlink_drc_trxn(rogue_shader *shader, rogue_instr *instr, rogue_drc *drc)
2178*61046927SAndroid Build Coastguard Worker {
2179*61046927SAndroid Build Coastguard Worker    ASSERTED unsigned index = drc->index;
2180*61046927SAndroid Build Coastguard Worker    assert(index < ROGUE_DRCS);
2181*61046927SAndroid Build Coastguard Worker    assert(drc->trxn.acquire == instr);
2182*61046927SAndroid Build Coastguard Worker 
2183*61046927SAndroid Build Coastguard Worker    if (drc->trxn.release)
2184*61046927SAndroid Build Coastguard Worker       rogue_instr_delete(drc->trxn.release);
2185*61046927SAndroid Build Coastguard Worker 
2186*61046927SAndroid Build Coastguard Worker    list_del(&drc->trxn.link);
2187*61046927SAndroid Build Coastguard Worker }
2188*61046927SAndroid Build Coastguard Worker 
rogue_link_imm_use(rogue_shader * shader,rogue_instr * instr,unsigned src_index,rogue_imm * imm)2189*61046927SAndroid Build Coastguard Worker static inline void rogue_link_imm_use(rogue_shader *shader,
2190*61046927SAndroid Build Coastguard Worker                                       rogue_instr *instr,
2191*61046927SAndroid Build Coastguard Worker                                       unsigned src_index,
2192*61046927SAndroid Build Coastguard Worker                                       rogue_imm *imm)
2193*61046927SAndroid Build Coastguard Worker {
2194*61046927SAndroid Build Coastguard Worker    rogue_imm_use *imm_use = &imm->use;
2195*61046927SAndroid Build Coastguard Worker 
2196*61046927SAndroid Build Coastguard Worker    imm_use->instr = instr;
2197*61046927SAndroid Build Coastguard Worker    imm_use->src_index = src_index;
2198*61046927SAndroid Build Coastguard Worker    imm_use->imm = &imm->imm;
2199*61046927SAndroid Build Coastguard Worker 
2200*61046927SAndroid Build Coastguard Worker    list_addtail(&imm_use->link, &shader->imm_uses);
2201*61046927SAndroid Build Coastguard Worker }
2202*61046927SAndroid Build Coastguard Worker 
rogue_unlink_imm_use(rogue_instr * instr,rogue_imm_use * imm_use)2203*61046927SAndroid Build Coastguard Worker static inline void rogue_unlink_imm_use(rogue_instr *instr,
2204*61046927SAndroid Build Coastguard Worker                                         rogue_imm_use *imm_use)
2205*61046927SAndroid Build Coastguard Worker {
2206*61046927SAndroid Build Coastguard Worker    assert(imm_use->instr == instr);
2207*61046927SAndroid Build Coastguard Worker    list_del(&imm_use->link);
2208*61046927SAndroid Build Coastguard Worker }
2209*61046927SAndroid Build Coastguard Worker 
rogue_link_instr_write_reg(rogue_instr * instr,rogue_reg_write * write,rogue_reg * reg,unsigned dst_index)2210*61046927SAndroid Build Coastguard Worker static inline void rogue_link_instr_write_reg(rogue_instr *instr,
2211*61046927SAndroid Build Coastguard Worker                                               rogue_reg_write *write,
2212*61046927SAndroid Build Coastguard Worker                                               rogue_reg *reg,
2213*61046927SAndroid Build Coastguard Worker                                               unsigned dst_index)
2214*61046927SAndroid Build Coastguard Worker {
2215*61046927SAndroid Build Coastguard Worker    write->instr = instr;
2216*61046927SAndroid Build Coastguard Worker    write->dst_index = dst_index;
2217*61046927SAndroid Build Coastguard Worker    list_addtail(&write->link, &reg->writes);
2218*61046927SAndroid Build Coastguard Worker }
2219*61046927SAndroid Build Coastguard Worker 
rogue_unlink_instr_write_reg(rogue_instr * instr,rogue_reg_write * write)2220*61046927SAndroid Build Coastguard Worker static inline void rogue_unlink_instr_write_reg(rogue_instr *instr,
2221*61046927SAndroid Build Coastguard Worker                                                 rogue_reg_write *write)
2222*61046927SAndroid Build Coastguard Worker {
2223*61046927SAndroid Build Coastguard Worker    assert(write->instr == instr);
2224*61046927SAndroid Build Coastguard Worker    write->instr = NULL;
2225*61046927SAndroid Build Coastguard Worker    list_del(&write->link);
2226*61046927SAndroid Build Coastguard Worker }
2227*61046927SAndroid Build Coastguard Worker 
rogue_link_instr_write_regarray(rogue_instr * instr,rogue_regarray_write * write,rogue_regarray * regarray,unsigned dst_index)2228*61046927SAndroid Build Coastguard Worker static inline void rogue_link_instr_write_regarray(rogue_instr *instr,
2229*61046927SAndroid Build Coastguard Worker                                                    rogue_regarray_write *write,
2230*61046927SAndroid Build Coastguard Worker                                                    rogue_regarray *regarray,
2231*61046927SAndroid Build Coastguard Worker                                                    unsigned dst_index)
2232*61046927SAndroid Build Coastguard Worker {
2233*61046927SAndroid Build Coastguard Worker    write->instr = instr;
2234*61046927SAndroid Build Coastguard Worker    write->dst_index = dst_index;
2235*61046927SAndroid Build Coastguard Worker    list_addtail(&write->link, &regarray->writes);
2236*61046927SAndroid Build Coastguard Worker }
2237*61046927SAndroid Build Coastguard Worker 
2238*61046927SAndroid Build Coastguard Worker static inline void
rogue_unlink_instr_write_regarray(rogue_instr * instr,rogue_regarray_write * write)2239*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_write_regarray(rogue_instr *instr,
2240*61046927SAndroid Build Coastguard Worker                                   rogue_regarray_write *write)
2241*61046927SAndroid Build Coastguard Worker {
2242*61046927SAndroid Build Coastguard Worker    assert(write->instr == instr);
2243*61046927SAndroid Build Coastguard Worker    write->instr = NULL;
2244*61046927SAndroid Build Coastguard Worker    list_del(&write->link);
2245*61046927SAndroid Build Coastguard Worker }
2246*61046927SAndroid Build Coastguard Worker 
rogue_link_instr_use_reg(rogue_instr * instr,rogue_reg_use * use,rogue_reg * reg,unsigned src_index)2247*61046927SAndroid Build Coastguard Worker static inline void rogue_link_instr_use_reg(rogue_instr *instr,
2248*61046927SAndroid Build Coastguard Worker                                             rogue_reg_use *use,
2249*61046927SAndroid Build Coastguard Worker                                             rogue_reg *reg,
2250*61046927SAndroid Build Coastguard Worker                                             unsigned src_index)
2251*61046927SAndroid Build Coastguard Worker {
2252*61046927SAndroid Build Coastguard Worker    use->instr = instr;
2253*61046927SAndroid Build Coastguard Worker    use->src_index = src_index;
2254*61046927SAndroid Build Coastguard Worker    list_addtail(&use->link, &reg->uses);
2255*61046927SAndroid Build Coastguard Worker }
2256*61046927SAndroid Build Coastguard Worker 
rogue_unlink_instr_use_reg(rogue_instr * instr,rogue_reg_use * use)2257*61046927SAndroid Build Coastguard Worker static inline void rogue_unlink_instr_use_reg(rogue_instr *instr,
2258*61046927SAndroid Build Coastguard Worker                                               rogue_reg_use *use)
2259*61046927SAndroid Build Coastguard Worker {
2260*61046927SAndroid Build Coastguard Worker    assert(use->instr == instr);
2261*61046927SAndroid Build Coastguard Worker    use->instr = NULL;
2262*61046927SAndroid Build Coastguard Worker    list_del(&use->link);
2263*61046927SAndroid Build Coastguard Worker }
2264*61046927SAndroid Build Coastguard Worker 
rogue_link_instr_use_regarray(rogue_instr * instr,rogue_regarray_use * use,rogue_regarray * regarray,unsigned src_index)2265*61046927SAndroid Build Coastguard Worker static inline void rogue_link_instr_use_regarray(rogue_instr *instr,
2266*61046927SAndroid Build Coastguard Worker                                                  rogue_regarray_use *use,
2267*61046927SAndroid Build Coastguard Worker                                                  rogue_regarray *regarray,
2268*61046927SAndroid Build Coastguard Worker                                                  unsigned src_index)
2269*61046927SAndroid Build Coastguard Worker {
2270*61046927SAndroid Build Coastguard Worker    use->instr = instr;
2271*61046927SAndroid Build Coastguard Worker    use->src_index = src_index;
2272*61046927SAndroid Build Coastguard Worker    list_addtail(&use->link, &regarray->uses);
2273*61046927SAndroid Build Coastguard Worker }
2274*61046927SAndroid Build Coastguard Worker 
rogue_unlink_instr_use_regarray(rogue_instr * instr,rogue_regarray_use * use)2275*61046927SAndroid Build Coastguard Worker static inline void rogue_unlink_instr_use_regarray(rogue_instr *instr,
2276*61046927SAndroid Build Coastguard Worker                                                    rogue_regarray_use *use)
2277*61046927SAndroid Build Coastguard Worker {
2278*61046927SAndroid Build Coastguard Worker    assert(use->instr == instr);
2279*61046927SAndroid Build Coastguard Worker    use->instr = NULL;
2280*61046927SAndroid Build Coastguard Worker    list_del(&use->link);
2281*61046927SAndroid Build Coastguard Worker }
2282*61046927SAndroid Build Coastguard Worker 
rogue_link_instr_use_block(rogue_instr * instr,rogue_block_use * block_use,rogue_block * target_block)2283*61046927SAndroid Build Coastguard Worker static inline void rogue_link_instr_use_block(rogue_instr *instr,
2284*61046927SAndroid Build Coastguard Worker                                               rogue_block_use *block_use,
2285*61046927SAndroid Build Coastguard Worker                                               rogue_block *target_block)
2286*61046927SAndroid Build Coastguard Worker {
2287*61046927SAndroid Build Coastguard Worker    assert(!block_use->instr);
2288*61046927SAndroid Build Coastguard Worker    block_use->instr = instr;
2289*61046927SAndroid Build Coastguard Worker    list_addtail(&block_use->link, &target_block->uses);
2290*61046927SAndroid Build Coastguard Worker }
2291*61046927SAndroid Build Coastguard Worker 
rogue_unlink_instr_use_block(rogue_instr * instr,rogue_block_use * block_use)2292*61046927SAndroid Build Coastguard Worker static inline void rogue_unlink_instr_use_block(rogue_instr *instr,
2293*61046927SAndroid Build Coastguard Worker                                                 rogue_block_use *block_use)
2294*61046927SAndroid Build Coastguard Worker {
2295*61046927SAndroid Build Coastguard Worker    assert(block_use->instr == instr);
2296*61046927SAndroid Build Coastguard Worker    list_del(&block_use->link);
2297*61046927SAndroid Build Coastguard Worker }
2298*61046927SAndroid Build Coastguard Worker 
rogue_dst_reg_replace(rogue_reg_write * write,rogue_reg * new_reg)2299*61046927SAndroid Build Coastguard Worker static inline bool rogue_dst_reg_replace(rogue_reg_write *write,
2300*61046927SAndroid Build Coastguard Worker                                          rogue_reg *new_reg)
2301*61046927SAndroid Build Coastguard Worker {
2302*61046927SAndroid Build Coastguard Worker    unsigned dst_index = write->dst_index;
2303*61046927SAndroid Build Coastguard Worker    rogue_instr *instr = write->instr;
2304*61046927SAndroid Build Coastguard Worker    rogue_ref *ref;
2305*61046927SAndroid Build Coastguard Worker 
2306*61046927SAndroid Build Coastguard Worker    switch (instr->type) {
2307*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_ALU:
2308*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_alu(instr)->dst[dst_index].ref;
2309*61046927SAndroid Build Coastguard Worker       break;
2310*61046927SAndroid Build Coastguard Worker 
2311*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_BACKEND:
2312*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_backend(instr)->dst[dst_index].ref;
2313*61046927SAndroid Build Coastguard Worker       break;
2314*61046927SAndroid Build Coastguard Worker 
2315*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_CTRL:
2316*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_ctrl(instr)->dst[dst_index].ref;
2317*61046927SAndroid Build Coastguard Worker       break;
2318*61046927SAndroid Build Coastguard Worker 
2319*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_BITWISE:
2320*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_bitwise(instr)->dst[dst_index].ref;
2321*61046927SAndroid Build Coastguard Worker       break;
2322*61046927SAndroid Build Coastguard Worker 
2323*61046927SAndroid Build Coastguard Worker    default:
2324*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported instruction type.");
2325*61046927SAndroid Build Coastguard Worker       return false;
2326*61046927SAndroid Build Coastguard Worker    }
2327*61046927SAndroid Build Coastguard Worker 
2328*61046927SAndroid Build Coastguard Worker    /* We don't want to be modifying regarrays. */
2329*61046927SAndroid Build Coastguard Worker    assert(rogue_ref_is_reg(ref));
2330*61046927SAndroid Build Coastguard Worker 
2331*61046927SAndroid Build Coastguard Worker    if (ref->reg == new_reg)
2332*61046927SAndroid Build Coastguard Worker       return false;
2333*61046927SAndroid Build Coastguard Worker 
2334*61046927SAndroid Build Coastguard Worker    rogue_unlink_instr_write_reg(instr, write);
2335*61046927SAndroid Build Coastguard Worker    *ref = rogue_ref_reg(new_reg);
2336*61046927SAndroid Build Coastguard Worker    rogue_link_instr_write_reg(instr, write, new_reg, dst_index);
2337*61046927SAndroid Build Coastguard Worker 
2338*61046927SAndroid Build Coastguard Worker    return true;
2339*61046927SAndroid Build Coastguard Worker }
2340*61046927SAndroid Build Coastguard Worker 
rogue_src_reg_replace(rogue_reg_use * use,rogue_reg * new_reg)2341*61046927SAndroid Build Coastguard Worker static inline bool rogue_src_reg_replace(rogue_reg_use *use, rogue_reg *new_reg)
2342*61046927SAndroid Build Coastguard Worker {
2343*61046927SAndroid Build Coastguard Worker    unsigned src_index = use->src_index;
2344*61046927SAndroid Build Coastguard Worker    rogue_instr *instr = use->instr;
2345*61046927SAndroid Build Coastguard Worker    rogue_ref *ref;
2346*61046927SAndroid Build Coastguard Worker 
2347*61046927SAndroid Build Coastguard Worker    switch (instr->type) {
2348*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_ALU:
2349*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_alu(instr)->src[src_index].ref;
2350*61046927SAndroid Build Coastguard Worker       break;
2351*61046927SAndroid Build Coastguard Worker 
2352*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_BACKEND:
2353*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_backend(instr)->src[src_index].ref;
2354*61046927SAndroid Build Coastguard Worker       break;
2355*61046927SAndroid Build Coastguard Worker 
2356*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_CTRL:
2357*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_ctrl(instr)->src[src_index].ref;
2358*61046927SAndroid Build Coastguard Worker       break;
2359*61046927SAndroid Build Coastguard Worker 
2360*61046927SAndroid Build Coastguard Worker    default:
2361*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported instruction type.");
2362*61046927SAndroid Build Coastguard Worker       return false;
2363*61046927SAndroid Build Coastguard Worker    }
2364*61046927SAndroid Build Coastguard Worker 
2365*61046927SAndroid Build Coastguard Worker    /* We don't want to be modifying regarrays. */
2366*61046927SAndroid Build Coastguard Worker    assert(rogue_ref_is_reg(ref));
2367*61046927SAndroid Build Coastguard Worker 
2368*61046927SAndroid Build Coastguard Worker    if (ref->reg == new_reg)
2369*61046927SAndroid Build Coastguard Worker       return false;
2370*61046927SAndroid Build Coastguard Worker 
2371*61046927SAndroid Build Coastguard Worker    rogue_unlink_instr_use_reg(instr, use);
2372*61046927SAndroid Build Coastguard Worker    *ref = rogue_ref_reg(new_reg);
2373*61046927SAndroid Build Coastguard Worker    rogue_link_instr_use_reg(instr, use, new_reg, src_index);
2374*61046927SAndroid Build Coastguard Worker 
2375*61046927SAndroid Build Coastguard Worker    return true;
2376*61046927SAndroid Build Coastguard Worker }
2377*61046927SAndroid Build Coastguard Worker 
rogue_reg_replace(rogue_reg * old_reg,rogue_reg * new_reg)2378*61046927SAndroid Build Coastguard Worker static inline bool rogue_reg_replace(rogue_reg *old_reg, rogue_reg *new_reg)
2379*61046927SAndroid Build Coastguard Worker {
2380*61046927SAndroid Build Coastguard Worker    bool replaced = true;
2381*61046927SAndroid Build Coastguard Worker 
2382*61046927SAndroid Build Coastguard Worker    rogue_foreach_reg_write_safe (write, old_reg) {
2383*61046927SAndroid Build Coastguard Worker       replaced &= rogue_dst_reg_replace(write, new_reg);
2384*61046927SAndroid Build Coastguard Worker    }
2385*61046927SAndroid Build Coastguard Worker 
2386*61046927SAndroid Build Coastguard Worker    rogue_foreach_reg_use_safe (use, old_reg) {
2387*61046927SAndroid Build Coastguard Worker       replaced &= rogue_src_reg_replace(use, new_reg);
2388*61046927SAndroid Build Coastguard Worker    }
2389*61046927SAndroid Build Coastguard Worker 
2390*61046927SAndroid Build Coastguard Worker    if (replaced)
2391*61046927SAndroid Build Coastguard Worker       rogue_reg_delete(old_reg);
2392*61046927SAndroid Build Coastguard Worker 
2393*61046927SAndroid Build Coastguard Worker    return replaced;
2394*61046927SAndroid Build Coastguard Worker }
2395*61046927SAndroid Build Coastguard Worker 
2396*61046927SAndroid Build Coastguard Worker /* TODO: try and commonise this with the reg one! */
rogue_dst_regarray_replace(rogue_regarray_write * write,rogue_regarray * new_regarray)2397*61046927SAndroid Build Coastguard Worker static inline bool rogue_dst_regarray_replace(rogue_regarray_write *write,
2398*61046927SAndroid Build Coastguard Worker                                               rogue_regarray *new_regarray)
2399*61046927SAndroid Build Coastguard Worker {
2400*61046927SAndroid Build Coastguard Worker    unsigned dst_index = write->dst_index;
2401*61046927SAndroid Build Coastguard Worker    rogue_instr *instr = write->instr;
2402*61046927SAndroid Build Coastguard Worker    rogue_ref *ref;
2403*61046927SAndroid Build Coastguard Worker 
2404*61046927SAndroid Build Coastguard Worker    switch (instr->type) {
2405*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_ALU:
2406*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_alu(instr)->dst[dst_index].ref;
2407*61046927SAndroid Build Coastguard Worker       break;
2408*61046927SAndroid Build Coastguard Worker 
2409*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_BACKEND:
2410*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_backend(instr)->dst[dst_index].ref;
2411*61046927SAndroid Build Coastguard Worker       break;
2412*61046927SAndroid Build Coastguard Worker 
2413*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_CTRL:
2414*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_ctrl(instr)->dst[dst_index].ref;
2415*61046927SAndroid Build Coastguard Worker       break;
2416*61046927SAndroid Build Coastguard Worker 
2417*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_BITWISE:
2418*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_bitwise(instr)->dst[dst_index].ref;
2419*61046927SAndroid Build Coastguard Worker       break;
2420*61046927SAndroid Build Coastguard Worker 
2421*61046927SAndroid Build Coastguard Worker    default:
2422*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported instruction type.");
2423*61046927SAndroid Build Coastguard Worker       return false;
2424*61046927SAndroid Build Coastguard Worker    }
2425*61046927SAndroid Build Coastguard Worker 
2426*61046927SAndroid Build Coastguard Worker    /* We don't want to be modifying regs. */
2427*61046927SAndroid Build Coastguard Worker    assert(rogue_ref_is_regarray(ref));
2428*61046927SAndroid Build Coastguard Worker 
2429*61046927SAndroid Build Coastguard Worker    if (ref->regarray == new_regarray)
2430*61046927SAndroid Build Coastguard Worker       return false;
2431*61046927SAndroid Build Coastguard Worker 
2432*61046927SAndroid Build Coastguard Worker    rogue_unlink_instr_write_regarray(instr, write);
2433*61046927SAndroid Build Coastguard Worker    *ref = rogue_ref_regarray(new_regarray);
2434*61046927SAndroid Build Coastguard Worker    rogue_link_instr_write_regarray(instr, write, new_regarray, dst_index);
2435*61046927SAndroid Build Coastguard Worker 
2436*61046927SAndroid Build Coastguard Worker    return true;
2437*61046927SAndroid Build Coastguard Worker }
2438*61046927SAndroid Build Coastguard Worker 
rogue_src_regarray_replace(rogue_regarray_use * use,rogue_regarray * new_regarray)2439*61046927SAndroid Build Coastguard Worker static inline bool rogue_src_regarray_replace(rogue_regarray_use *use,
2440*61046927SAndroid Build Coastguard Worker                                               rogue_regarray *new_regarray)
2441*61046927SAndroid Build Coastguard Worker {
2442*61046927SAndroid Build Coastguard Worker    unsigned src_index = use->src_index;
2443*61046927SAndroid Build Coastguard Worker    rogue_instr *instr = use->instr;
2444*61046927SAndroid Build Coastguard Worker    rogue_ref *ref;
2445*61046927SAndroid Build Coastguard Worker 
2446*61046927SAndroid Build Coastguard Worker    switch (instr->type) {
2447*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_ALU:
2448*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_alu(instr)->src[src_index].ref;
2449*61046927SAndroid Build Coastguard Worker       break;
2450*61046927SAndroid Build Coastguard Worker 
2451*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_BACKEND:
2452*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_backend(instr)->src[src_index].ref;
2453*61046927SAndroid Build Coastguard Worker       break;
2454*61046927SAndroid Build Coastguard Worker 
2455*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_CTRL:
2456*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_ctrl(instr)->src[src_index].ref;
2457*61046927SAndroid Build Coastguard Worker       break;
2458*61046927SAndroid Build Coastguard Worker 
2459*61046927SAndroid Build Coastguard Worker    default:
2460*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported instruction type.");
2461*61046927SAndroid Build Coastguard Worker       return false;
2462*61046927SAndroid Build Coastguard Worker    }
2463*61046927SAndroid Build Coastguard Worker 
2464*61046927SAndroid Build Coastguard Worker    /* We don't want to be modifying reg. */
2465*61046927SAndroid Build Coastguard Worker    assert(rogue_ref_is_regarray(ref));
2466*61046927SAndroid Build Coastguard Worker 
2467*61046927SAndroid Build Coastguard Worker    if (ref->regarray == new_regarray)
2468*61046927SAndroid Build Coastguard Worker       return false;
2469*61046927SAndroid Build Coastguard Worker 
2470*61046927SAndroid Build Coastguard Worker    rogue_unlink_instr_use_regarray(instr, use);
2471*61046927SAndroid Build Coastguard Worker    *ref = rogue_ref_regarray(new_regarray);
2472*61046927SAndroid Build Coastguard Worker    rogue_link_instr_use_regarray(instr, use, new_regarray, src_index);
2473*61046927SAndroid Build Coastguard Worker 
2474*61046927SAndroid Build Coastguard Worker    return true;
2475*61046927SAndroid Build Coastguard Worker }
2476*61046927SAndroid Build Coastguard Worker 
rogue_regarray_replace(rogue_shader * shader,rogue_regarray * old_regarray,rogue_regarray * new_regarray)2477*61046927SAndroid Build Coastguard Worker static inline bool rogue_regarray_replace(rogue_shader *shader,
2478*61046927SAndroid Build Coastguard Worker                                           rogue_regarray *old_regarray,
2479*61046927SAndroid Build Coastguard Worker                                           rogue_regarray *new_regarray)
2480*61046927SAndroid Build Coastguard Worker {
2481*61046927SAndroid Build Coastguard Worker    bool replaced = true;
2482*61046927SAndroid Build Coastguard Worker 
2483*61046927SAndroid Build Coastguard Worker    assert(!old_regarray->parent);
2484*61046927SAndroid Build Coastguard Worker    assert(!new_regarray->parent);
2485*61046927SAndroid Build Coastguard Worker 
2486*61046927SAndroid Build Coastguard Worker    rogue_foreach_regarray_write_safe (write, old_regarray) {
2487*61046927SAndroid Build Coastguard Worker       replaced &= rogue_dst_regarray_replace(write, new_regarray);
2488*61046927SAndroid Build Coastguard Worker    }
2489*61046927SAndroid Build Coastguard Worker 
2490*61046927SAndroid Build Coastguard Worker    rogue_foreach_regarray_use_safe (use, old_regarray) {
2491*61046927SAndroid Build Coastguard Worker       replaced &= rogue_src_regarray_replace(use, new_regarray);
2492*61046927SAndroid Build Coastguard Worker    }
2493*61046927SAndroid Build Coastguard Worker 
2494*61046927SAndroid Build Coastguard Worker    enum rogue_reg_class new_class = new_regarray->regs[0]->class;
2495*61046927SAndroid Build Coastguard Worker    unsigned new_base_index = new_regarray->regs[0]->index;
2496*61046927SAndroid Build Coastguard Worker 
2497*61046927SAndroid Build Coastguard Worker    /* Replace subarrays. */
2498*61046927SAndroid Build Coastguard Worker    rogue_foreach_subarray_safe (old_subarray, old_regarray) {
2499*61046927SAndroid Build Coastguard Worker       unsigned idx_offset =
2500*61046927SAndroid Build Coastguard Worker          old_subarray->regs[0]->index - old_regarray->regs[0]->index;
2501*61046927SAndroid Build Coastguard Worker       rogue_regarray *new_subarray =
2502*61046927SAndroid Build Coastguard Worker          rogue_regarray_cached(shader,
2503*61046927SAndroid Build Coastguard Worker                                old_subarray->size,
2504*61046927SAndroid Build Coastguard Worker                                new_class,
2505*61046927SAndroid Build Coastguard Worker                                new_base_index + idx_offset);
2506*61046927SAndroid Build Coastguard Worker 
2507*61046927SAndroid Build Coastguard Worker       rogue_foreach_regarray_write_safe (write, old_subarray) {
2508*61046927SAndroid Build Coastguard Worker          replaced &= rogue_dst_regarray_replace(write, new_subarray);
2509*61046927SAndroid Build Coastguard Worker       }
2510*61046927SAndroid Build Coastguard Worker 
2511*61046927SAndroid Build Coastguard Worker       rogue_foreach_regarray_use_safe (use, old_subarray) {
2512*61046927SAndroid Build Coastguard Worker          replaced &= rogue_src_regarray_replace(use, new_subarray);
2513*61046927SAndroid Build Coastguard Worker       }
2514*61046927SAndroid Build Coastguard Worker 
2515*61046927SAndroid Build Coastguard Worker       rogue_regarray_delete(old_subarray);
2516*61046927SAndroid Build Coastguard Worker    }
2517*61046927SAndroid Build Coastguard Worker 
2518*61046927SAndroid Build Coastguard Worker    rogue_regarray_delete(old_regarray);
2519*61046927SAndroid Build Coastguard Worker 
2520*61046927SAndroid Build Coastguard Worker    return replaced;
2521*61046927SAndroid Build Coastguard Worker }
2522*61046927SAndroid Build Coastguard Worker 
rogue_src_imm_replace(rogue_imm_use * imm_use,rogue_reg * new_reg)2523*61046927SAndroid Build Coastguard Worker static inline bool rogue_src_imm_replace(rogue_imm_use *imm_use,
2524*61046927SAndroid Build Coastguard Worker                                          rogue_reg *new_reg)
2525*61046927SAndroid Build Coastguard Worker {
2526*61046927SAndroid Build Coastguard Worker    unsigned src_index = imm_use->src_index;
2527*61046927SAndroid Build Coastguard Worker    rogue_instr *instr = imm_use->instr;
2528*61046927SAndroid Build Coastguard Worker    rogue_ref *ref;
2529*61046927SAndroid Build Coastguard Worker    rogue_reg_use *reg_use;
2530*61046927SAndroid Build Coastguard Worker 
2531*61046927SAndroid Build Coastguard Worker    switch (instr->type) {
2532*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_ALU:
2533*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_alu(instr)->src[src_index].ref;
2534*61046927SAndroid Build Coastguard Worker       reg_use = &rogue_instr_as_alu(instr)->src_use[src_index].reg;
2535*61046927SAndroid Build Coastguard Worker       break;
2536*61046927SAndroid Build Coastguard Worker 
2537*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_BACKEND:
2538*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_backend(instr)->src[src_index].ref;
2539*61046927SAndroid Build Coastguard Worker       reg_use = &rogue_instr_as_backend(instr)->src_use[src_index].reg;
2540*61046927SAndroid Build Coastguard Worker       break;
2541*61046927SAndroid Build Coastguard Worker 
2542*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_CTRL:
2543*61046927SAndroid Build Coastguard Worker       ref = &rogue_instr_as_ctrl(instr)->src[src_index].ref;
2544*61046927SAndroid Build Coastguard Worker       reg_use = &rogue_instr_as_ctrl(instr)->src_use[src_index].reg;
2545*61046927SAndroid Build Coastguard Worker       break;
2546*61046927SAndroid Build Coastguard Worker 
2547*61046927SAndroid Build Coastguard Worker    default:
2548*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported instruction type.");
2549*61046927SAndroid Build Coastguard Worker       return false;
2550*61046927SAndroid Build Coastguard Worker    }
2551*61046927SAndroid Build Coastguard Worker 
2552*61046927SAndroid Build Coastguard Worker    assert(rogue_ref_is_imm(ref));
2553*61046927SAndroid Build Coastguard Worker 
2554*61046927SAndroid Build Coastguard Worker    rogue_unlink_imm_use(instr, imm_use);
2555*61046927SAndroid Build Coastguard Worker    *ref = rogue_ref_reg(new_reg);
2556*61046927SAndroid Build Coastguard Worker    rogue_link_instr_use_reg(instr, reg_use, new_reg, src_index);
2557*61046927SAndroid Build Coastguard Worker 
2558*61046927SAndroid Build Coastguard Worker    return true;
2559*61046927SAndroid Build Coastguard Worker }
2560*61046927SAndroid Build Coastguard Worker 
rogue_instr_is_nop_end(const rogue_instr * instr)2561*61046927SAndroid Build Coastguard Worker static inline bool rogue_instr_is_nop_end(const rogue_instr *instr)
2562*61046927SAndroid Build Coastguard Worker {
2563*61046927SAndroid Build Coastguard Worker    if (instr->type != ROGUE_INSTR_TYPE_CTRL)
2564*61046927SAndroid Build Coastguard Worker       return false;
2565*61046927SAndroid Build Coastguard Worker 
2566*61046927SAndroid Build Coastguard Worker    const rogue_ctrl_instr *ctrl = rogue_instr_as_ctrl(instr);
2567*61046927SAndroid Build Coastguard Worker 
2568*61046927SAndroid Build Coastguard Worker    if (ctrl->op != ROGUE_CTRL_OP_NOP)
2569*61046927SAndroid Build Coastguard Worker       return false;
2570*61046927SAndroid Build Coastguard Worker 
2571*61046927SAndroid Build Coastguard Worker    return rogue_ctrl_op_mod_is_set(ctrl, ROGUE_CTRL_OP_MOD_END);
2572*61046927SAndroid Build Coastguard Worker }
2573*61046927SAndroid Build Coastguard Worker 
rogue_instr_supported_phases(const rogue_instr * instr)2574*61046927SAndroid Build Coastguard Worker static inline unsigned rogue_instr_supported_phases(const rogue_instr *instr)
2575*61046927SAndroid Build Coastguard Worker {
2576*61046927SAndroid Build Coastguard Worker    uint64_t supported_phases = 0;
2577*61046927SAndroid Build Coastguard Worker 
2578*61046927SAndroid Build Coastguard Worker    switch (instr->type) {
2579*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_ALU: {
2580*61046927SAndroid Build Coastguard Worker       rogue_alu_instr *alu = rogue_instr_as_alu(instr);
2581*61046927SAndroid Build Coastguard Worker       if (alu->op >= ROGUE_ALU_OP_PSEUDO)
2582*61046927SAndroid Build Coastguard Worker          return 0;
2583*61046927SAndroid Build Coastguard Worker 
2584*61046927SAndroid Build Coastguard Worker       const rogue_alu_op_info *info = &rogue_alu_op_infos[alu->op];
2585*61046927SAndroid Build Coastguard Worker       supported_phases = info->supported_phases;
2586*61046927SAndroid Build Coastguard Worker       break;
2587*61046927SAndroid Build Coastguard Worker    }
2588*61046927SAndroid Build Coastguard Worker 
2589*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_BACKEND: {
2590*61046927SAndroid Build Coastguard Worker       rogue_backend_instr *backend = rogue_instr_as_backend(instr);
2591*61046927SAndroid Build Coastguard Worker       if (backend->op >= ROGUE_BACKEND_OP_PSEUDO)
2592*61046927SAndroid Build Coastguard Worker          return 0;
2593*61046927SAndroid Build Coastguard Worker 
2594*61046927SAndroid Build Coastguard Worker       supported_phases = BITFIELD_BIT(ROGUE_INSTR_PHASE_BACKEND);
2595*61046927SAndroid Build Coastguard Worker       break;
2596*61046927SAndroid Build Coastguard Worker    }
2597*61046927SAndroid Build Coastguard Worker 
2598*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_CTRL: {
2599*61046927SAndroid Build Coastguard Worker       /* Control instructions can't be co-issued; just make sure this isn't a
2600*61046927SAndroid Build Coastguard Worker        * pseudo-instruction. */
2601*61046927SAndroid Build Coastguard Worker       rogue_ctrl_instr *ctrl = rogue_instr_as_ctrl(instr);
2602*61046927SAndroid Build Coastguard Worker       if (ctrl->op >= ROGUE_CTRL_OP_PSEUDO)
2603*61046927SAndroid Build Coastguard Worker          return 0;
2604*61046927SAndroid Build Coastguard Worker 
2605*61046927SAndroid Build Coastguard Worker       supported_phases = BITFIELD_BIT(ROGUE_INSTR_PHASE_CTRL);
2606*61046927SAndroid Build Coastguard Worker       break;
2607*61046927SAndroid Build Coastguard Worker    }
2608*61046927SAndroid Build Coastguard Worker 
2609*61046927SAndroid Build Coastguard Worker    case ROGUE_INSTR_TYPE_BITWISE: {
2610*61046927SAndroid Build Coastguard Worker       rogue_bitwise_instr *bitwise = rogue_instr_as_bitwise(instr);
2611*61046927SAndroid Build Coastguard Worker       if (bitwise->op >= ROGUE_BITWISE_OP_PSEUDO)
2612*61046927SAndroid Build Coastguard Worker          return 0;
2613*61046927SAndroid Build Coastguard Worker 
2614*61046927SAndroid Build Coastguard Worker       const rogue_bitwise_op_info *info = &rogue_bitwise_op_infos[bitwise->op];
2615*61046927SAndroid Build Coastguard Worker       supported_phases = info->supported_phases;
2616*61046927SAndroid Build Coastguard Worker       break;
2617*61046927SAndroid Build Coastguard Worker    }
2618*61046927SAndroid Build Coastguard Worker 
2619*61046927SAndroid Build Coastguard Worker    default:
2620*61046927SAndroid Build Coastguard Worker       unreachable("Unsupported instruction type.");
2621*61046927SAndroid Build Coastguard Worker    }
2622*61046927SAndroid Build Coastguard Worker 
2623*61046927SAndroid Build Coastguard Worker    return supported_phases;
2624*61046927SAndroid Build Coastguard Worker }
2625*61046927SAndroid Build Coastguard Worker 
2626*61046927SAndroid Build Coastguard Worker /* Loop through and find first unused phase that's supported, then return its
2627*61046927SAndroid Build Coastguard Worker  * enum. */
2628*61046927SAndroid Build Coastguard Worker static inline enum rogue_instr_phase
rogue_get_supported_phase(uint64_t supported_phases,uint64_t occupied_phases)2629*61046927SAndroid Build Coastguard Worker rogue_get_supported_phase(uint64_t supported_phases, uint64_t occupied_phases)
2630*61046927SAndroid Build Coastguard Worker {
2631*61046927SAndroid Build Coastguard Worker    rogue_foreach_phase_in_set (p, supported_phases) {
2632*61046927SAndroid Build Coastguard Worker       if (!(BITFIELD_BIT(p) & occupied_phases))
2633*61046927SAndroid Build Coastguard Worker          return p;
2634*61046927SAndroid Build Coastguard Worker    }
2635*61046927SAndroid Build Coastguard Worker 
2636*61046927SAndroid Build Coastguard Worker    return ROGUE_INSTR_PHASE_INVALID;
2637*61046927SAndroid Build Coastguard Worker }
2638*61046927SAndroid Build Coastguard Worker 
rogue_phase_occupied(enum rogue_instr_phase phase,uint64_t occupied_phases)2639*61046927SAndroid Build Coastguard Worker static inline bool rogue_phase_occupied(enum rogue_instr_phase phase,
2640*61046927SAndroid Build Coastguard Worker                                         uint64_t occupied_phases)
2641*61046927SAndroid Build Coastguard Worker {
2642*61046927SAndroid Build Coastguard Worker    return !!(BITFIELD_BIT(phase) & occupied_phases);
2643*61046927SAndroid Build Coastguard Worker }
2644*61046927SAndroid Build Coastguard Worker 
rogue_can_replace_reg_use(rogue_reg_use * use,const rogue_reg * new_reg)2645*61046927SAndroid Build Coastguard Worker static inline bool rogue_can_replace_reg_use(rogue_reg_use *use,
2646*61046927SAndroid Build Coastguard Worker                                              const rogue_reg *new_reg)
2647*61046927SAndroid Build Coastguard Worker {
2648*61046927SAndroid Build Coastguard Worker    bool can_replace = false;
2649*61046927SAndroid Build Coastguard Worker    const rogue_reg_info *reg_info = &rogue_reg_infos[new_reg->class];
2650*61046927SAndroid Build Coastguard Worker    const rogue_instr *instr = use->instr;
2651*61046927SAndroid Build Coastguard Worker 
2652*61046927SAndroid Build Coastguard Worker    rogue_foreach_phase_in_set (p, rogue_instr_supported_phases(instr)) {
2653*61046927SAndroid Build Coastguard Worker       enum rogue_io io_src = rogue_instr_src_io_src(instr, p, use->src_index);
2654*61046927SAndroid Build Coastguard Worker       can_replace &= rogue_io_supported(io_src, reg_info->supported_io_srcs);
2655*61046927SAndroid Build Coastguard Worker    }
2656*61046927SAndroid Build Coastguard Worker 
2657*61046927SAndroid Build Coastguard Worker    return can_replace;
2658*61046927SAndroid Build Coastguard Worker }
2659*61046927SAndroid Build Coastguard Worker 
2660*61046927SAndroid Build Coastguard Worker #define ROGUE_NO_CONST_REG ~0
2661*61046927SAndroid Build Coastguard Worker 
2662*61046927SAndroid Build Coastguard Worker unsigned rogue_constreg_lookup(rogue_imm_t imm);
2663*61046927SAndroid Build Coastguard Worker 
2664*61046927SAndroid Build Coastguard Worker /* Printing */
2665*61046927SAndroid Build Coastguard Worker 
2666*61046927SAndroid Build Coastguard Worker void rogue_print_color(bool print_color);
2667*61046927SAndroid Build Coastguard Worker 
2668*61046927SAndroid Build Coastguard Worker /**
2669*61046927SAndroid Build Coastguard Worker  * \brief Prints a shader's Rogue IR/assembly.
2670*61046927SAndroid Build Coastguard Worker  *
2671*61046927SAndroid Build Coastguard Worker  * \param[in] fp The file pointer to use for printing.
2672*61046927SAndroid Build Coastguard Worker  * \param[in] shader The shader to print.
2673*61046927SAndroid Build Coastguard Worker  */
2674*61046927SAndroid Build Coastguard Worker void rogue_print_shader(FILE *fp, const rogue_shader *shader);
2675*61046927SAndroid Build Coastguard Worker 
2676*61046927SAndroid Build Coastguard Worker /**
2677*61046927SAndroid Build Coastguard Worker  * \brief Prints an instruction.
2678*61046927SAndroid Build Coastguard Worker  *
2679*61046927SAndroid Build Coastguard Worker  * \param[in] fp The file pointer to use for printing.
2680*61046927SAndroid Build Coastguard Worker  * \param[in] instr The instruction to print.
2681*61046927SAndroid Build Coastguard Worker  */
2682*61046927SAndroid Build Coastguard Worker void rogue_print_instr(FILE *fp, const rogue_instr *instr);
2683*61046927SAndroid Build Coastguard Worker 
2684*61046927SAndroid Build Coastguard Worker void rogue_print_reg_writes(FILE *fp, const rogue_shader *shader);
2685*61046927SAndroid Build Coastguard Worker 
2686*61046927SAndroid Build Coastguard Worker void rogue_print_reg_uses(FILE *fp, const rogue_shader *shader);
2687*61046927SAndroid Build Coastguard Worker 
2688*61046927SAndroid Build Coastguard Worker void rogue_print_block_uses(FILE *fp, const rogue_shader *shader);
2689*61046927SAndroid Build Coastguard Worker 
2690*61046927SAndroid Build Coastguard Worker void rogue_print_drc_trxns(FILE *fp, const rogue_shader *shader);
2691*61046927SAndroid Build Coastguard Worker 
2692*61046927SAndroid Build Coastguard Worker /* Validation */
2693*61046927SAndroid Build Coastguard Worker bool rogue_validate_shader(rogue_shader *shader, const char *when);
2694*61046927SAndroid Build Coastguard Worker 
2695*61046927SAndroid Build Coastguard Worker /* Debug. */
2696*61046927SAndroid Build Coastguard Worker enum rogue_debug {
2697*61046927SAndroid Build Coastguard Worker    ROGUE_DEBUG_NIR = BITFIELD_BIT(0),
2698*61046927SAndroid Build Coastguard Worker    ROGUE_DEBUG_NIR_PASSES = BITFIELD_BIT(1),
2699*61046927SAndroid Build Coastguard Worker    ROGUE_DEBUG_IR = BITFIELD_BIT(2),
2700*61046927SAndroid Build Coastguard Worker    ROGUE_DEBUG_IR_PASSES = BITFIELD_BIT(3),
2701*61046927SAndroid Build Coastguard Worker    ROGUE_DEBUG_IR_DETAILS = BITFIELD_BIT(4),
2702*61046927SAndroid Build Coastguard Worker    ROGUE_DEBUG_VLD_SKIP = BITFIELD_BIT(5),
2703*61046927SAndroid Build Coastguard Worker    ROGUE_DEBUG_VLD_NONFATAL = BITFIELD_BIT(6),
2704*61046927SAndroid Build Coastguard Worker };
2705*61046927SAndroid Build Coastguard Worker 
2706*61046927SAndroid Build Coastguard Worker extern unsigned long rogue_debug;
2707*61046927SAndroid Build Coastguard Worker 
2708*61046927SAndroid Build Coastguard Worker #define ROGUE_DEBUG(flag) unlikely(!!(rogue_debug & (ROGUE_DEBUG_##flag)))
2709*61046927SAndroid Build Coastguard Worker 
2710*61046927SAndroid Build Coastguard Worker extern bool rogue_color;
2711*61046927SAndroid Build Coastguard Worker 
2712*61046927SAndroid Build Coastguard Worker void rogue_debug_init(void);
2713*61046927SAndroid Build Coastguard Worker 
2714*61046927SAndroid Build Coastguard Worker static inline void
rogue_print_pass_debug(rogue_shader * shader,const char * pass,FILE * fp)2715*61046927SAndroid Build Coastguard Worker rogue_print_pass_debug(rogue_shader *shader, const char *pass, FILE *fp)
2716*61046927SAndroid Build Coastguard Worker {
2717*61046927SAndroid Build Coastguard Worker    fprintf(fp, "%s\n", pass);
2718*61046927SAndroid Build Coastguard Worker    rogue_print_shader(fp, shader);
2719*61046927SAndroid Build Coastguard Worker    if (ROGUE_DEBUG(IR_DETAILS)) {
2720*61046927SAndroid Build Coastguard Worker       rogue_print_reg_writes(fp, shader);
2721*61046927SAndroid Build Coastguard Worker       rogue_print_reg_uses(fp, shader);
2722*61046927SAndroid Build Coastguard Worker       rogue_print_block_uses(fp, shader);
2723*61046927SAndroid Build Coastguard Worker       rogue_print_drc_trxns(fp, shader);
2724*61046927SAndroid Build Coastguard Worker    }
2725*61046927SAndroid Build Coastguard Worker }
2726*61046927SAndroid Build Coastguard Worker 
2727*61046927SAndroid Build Coastguard Worker /* Passes */
2728*61046927SAndroid Build Coastguard Worker #define ROGUE_PASS(progress, shader, pass, ...)            \
2729*61046927SAndroid Build Coastguard Worker    do {                                                    \
2730*61046927SAndroid Build Coastguard Worker       if (pass((shader), ##__VA_ARGS__)) {                 \
2731*61046927SAndroid Build Coastguard Worker          if (ROGUE_DEBUG(IR_PASSES))                       \
2732*61046927SAndroid Build Coastguard Worker             rogue_print_pass_debug(shader, #pass, stdout); \
2733*61046927SAndroid Build Coastguard Worker          rogue_validate_shader(shader, #pass);             \
2734*61046927SAndroid Build Coastguard Worker          progress = true;                                  \
2735*61046927SAndroid Build Coastguard Worker       }                                                    \
2736*61046927SAndroid Build Coastguard Worker    } while (0)
2737*61046927SAndroid Build Coastguard Worker 
2738*61046927SAndroid Build Coastguard Worker #define ROGUE_PASS_V(shader, pass, ...)                    \
2739*61046927SAndroid Build Coastguard Worker    do {                                                    \
2740*61046927SAndroid Build Coastguard Worker       if (pass((shader), ##__VA_ARGS__)) {                 \
2741*61046927SAndroid Build Coastguard Worker          if (ROGUE_DEBUG(IR_PASSES))                       \
2742*61046927SAndroid Build Coastguard Worker             rogue_print_pass_debug(shader, #pass, stdout); \
2743*61046927SAndroid Build Coastguard Worker          rogue_validate_shader(shader, #pass);             \
2744*61046927SAndroid Build Coastguard Worker       }                                                    \
2745*61046927SAndroid Build Coastguard Worker    } while (0)
2746*61046927SAndroid Build Coastguard Worker 
2747*61046927SAndroid Build Coastguard Worker bool rogue_constreg(rogue_shader *shader);
2748*61046927SAndroid Build Coastguard Worker 
2749*61046927SAndroid Build Coastguard Worker bool rogue_copy_prop(rogue_shader *shader);
2750*61046927SAndroid Build Coastguard Worker 
2751*61046927SAndroid Build Coastguard Worker bool rogue_dce(rogue_shader *shader);
2752*61046927SAndroid Build Coastguard Worker 
2753*61046927SAndroid Build Coastguard Worker bool rogue_lower_late_ops(rogue_shader *shader);
2754*61046927SAndroid Build Coastguard Worker 
2755*61046927SAndroid Build Coastguard Worker bool rogue_lower_pseudo_ops(rogue_shader *shader);
2756*61046927SAndroid Build Coastguard Worker 
2757*61046927SAndroid Build Coastguard Worker bool rogue_regalloc(rogue_shader *shader);
2758*61046927SAndroid Build Coastguard Worker 
2759*61046927SAndroid Build Coastguard Worker bool rogue_schedule_instr_groups(rogue_shader *shader, bool multi_instr_groups);
2760*61046927SAndroid Build Coastguard Worker 
2761*61046927SAndroid Build Coastguard Worker bool rogue_schedule_uvsw(rogue_shader *shader, bool latency_hiding);
2762*61046927SAndroid Build Coastguard Worker 
2763*61046927SAndroid Build Coastguard Worker bool rogue_schedule_wdf(rogue_shader *shader, bool latency_hiding);
2764*61046927SAndroid Build Coastguard Worker 
2765*61046927SAndroid Build Coastguard Worker bool rogue_trim(rogue_shader *shader);
2766*61046927SAndroid Build Coastguard Worker 
2767*61046927SAndroid Build Coastguard Worker void rogue_shader_passes(rogue_shader *shader);
2768*61046927SAndroid Build Coastguard Worker 
2769*61046927SAndroid Build Coastguard Worker struct pvr_device_info;
2770*61046927SAndroid Build Coastguard Worker 
2771*61046927SAndroid Build Coastguard Worker /**
2772*61046927SAndroid Build Coastguard Worker  * \brief Compiler context.
2773*61046927SAndroid Build Coastguard Worker  */
2774*61046927SAndroid Build Coastguard Worker typedef struct rogue_compiler {
2775*61046927SAndroid Build Coastguard Worker    const struct pvr_device_info *dev_info;
2776*61046927SAndroid Build Coastguard Worker } rogue_compiler;
2777*61046927SAndroid Build Coastguard Worker 
2778*61046927SAndroid Build Coastguard Worker rogue_compiler *rogue_compiler_create(const struct pvr_device_info *dev_info);
2779*61046927SAndroid Build Coastguard Worker 
2780*61046927SAndroid Build Coastguard Worker /* Max number of I/O varying variables.
2781*61046927SAndroid Build Coastguard Worker  * Fragment shader: MAX_VARYING + 1 (W coefficient).
2782*61046927SAndroid Build Coastguard Worker  * Vertex shader: MAX_VARYING + 1 (position slot).
2783*61046927SAndroid Build Coastguard Worker  */
2784*61046927SAndroid Build Coastguard Worker #define ROGUE_MAX_IO_VARYING_VARS (MAX_VARYING + 1)
2785*61046927SAndroid Build Coastguard Worker 
2786*61046927SAndroid Build Coastguard Worker /* VERT_ATTRIB_GENERIC0-15 */
2787*61046927SAndroid Build Coastguard Worker #define ROGUE_MAX_IO_ATTRIB_VARS 16
2788*61046927SAndroid Build Coastguard Worker 
2789*61046927SAndroid Build Coastguard Worker /* Max buffers entries that can be used. */
2790*61046927SAndroid Build Coastguard Worker /* TODO: Currently UBOs are the only supported buffers. */
2791*61046927SAndroid Build Coastguard Worker #define ROGUE_MAX_BUFFERS 24
2792*61046927SAndroid Build Coastguard Worker 
2793*61046927SAndroid Build Coastguard Worker /**
2794*61046927SAndroid Build Coastguard Worker  * \brief UBO data.
2795*61046927SAndroid Build Coastguard Worker  */
2796*61046927SAndroid Build Coastguard Worker typedef struct rogue_ubo_data {
2797*61046927SAndroid Build Coastguard Worker    unsigned num_ubo_entries;
2798*61046927SAndroid Build Coastguard Worker    unsigned desc_set[ROGUE_MAX_BUFFERS];
2799*61046927SAndroid Build Coastguard Worker    unsigned binding[ROGUE_MAX_BUFFERS];
2800*61046927SAndroid Build Coastguard Worker    unsigned dest[ROGUE_MAX_BUFFERS];
2801*61046927SAndroid Build Coastguard Worker    unsigned size[ROGUE_MAX_BUFFERS];
2802*61046927SAndroid Build Coastguard Worker } rogue_ubo_data;
2803*61046927SAndroid Build Coastguard Worker 
2804*61046927SAndroid Build Coastguard Worker /**
2805*61046927SAndroid Build Coastguard Worker  * \brief Compile time constants that need uploading.
2806*61046927SAndroid Build Coastguard Worker  */
2807*61046927SAndroid Build Coastguard Worker typedef struct rogue_compile_time_consts_data {
2808*61046927SAndroid Build Coastguard Worker    /* TODO: Output these from the compiler. */
2809*61046927SAndroid Build Coastguard Worker    /* TODO: Add the other types. */
2810*61046927SAndroid Build Coastguard Worker    struct {
2811*61046927SAndroid Build Coastguard Worker       unsigned num;
2812*61046927SAndroid Build Coastguard Worker       unsigned dest;
2813*61046927SAndroid Build Coastguard Worker       /* TODO: This should probably be bigger. Big enough to account for all
2814*61046927SAndroid Build Coastguard Worker        * available writable special constant regs.
2815*61046927SAndroid Build Coastguard Worker        */
2816*61046927SAndroid Build Coastguard Worker       uint32_t value[ROGUE_MAX_BUFFERS];
2817*61046927SAndroid Build Coastguard Worker    } static_consts;
2818*61046927SAndroid Build Coastguard Worker } rogue_compile_time_consts_data;
2819*61046927SAndroid Build Coastguard Worker 
2820*61046927SAndroid Build Coastguard Worker /**
2821*61046927SAndroid Build Coastguard Worker  * \brief Per-stage common build data.
2822*61046927SAndroid Build Coastguard Worker  */
2823*61046927SAndroid Build Coastguard Worker typedef struct rogue_common_build_data {
2824*61046927SAndroid Build Coastguard Worker    unsigned temps;
2825*61046927SAndroid Build Coastguard Worker    unsigned internals;
2826*61046927SAndroid Build Coastguard Worker    unsigned coeffs;
2827*61046927SAndroid Build Coastguard Worker    unsigned shareds;
2828*61046927SAndroid Build Coastguard Worker 
2829*61046927SAndroid Build Coastguard Worker    rogue_ubo_data ubo_data;
2830*61046927SAndroid Build Coastguard Worker    rogue_compile_time_consts_data compile_time_consts_data;
2831*61046927SAndroid Build Coastguard Worker } rogue_common_build_data;
2832*61046927SAndroid Build Coastguard Worker 
2833*61046927SAndroid Build Coastguard Worker /**
2834*61046927SAndroid Build Coastguard Worker  * \brief Arguments for the FPU iterator(s)
2835*61046927SAndroid Build Coastguard Worker  * (produces varyings for the fragment shader).
2836*61046927SAndroid Build Coastguard Worker  */
2837*61046927SAndroid Build Coastguard Worker typedef struct rogue_iterator_args {
2838*61046927SAndroid Build Coastguard Worker    uint32_t num_fpu_iterators;
2839*61046927SAndroid Build Coastguard Worker    uint32_t fpu_iterators[ROGUE_MAX_IO_VARYING_VARS];
2840*61046927SAndroid Build Coastguard Worker    uint32_t destination[ROGUE_MAX_IO_VARYING_VARS];
2841*61046927SAndroid Build Coastguard Worker    unsigned base[ROGUE_MAX_IO_VARYING_VARS];
2842*61046927SAndroid Build Coastguard Worker    unsigned components[ROGUE_MAX_IO_VARYING_VARS];
2843*61046927SAndroid Build Coastguard Worker } rogue_iterator_args;
2844*61046927SAndroid Build Coastguard Worker 
2845*61046927SAndroid Build Coastguard Worker /**
2846*61046927SAndroid Build Coastguard Worker  * \brief Vertex input register allocations.
2847*61046927SAndroid Build Coastguard Worker  */
2848*61046927SAndroid Build Coastguard Worker typedef struct rogue_vertex_inputs {
2849*61046927SAndroid Build Coastguard Worker    unsigned num_input_vars;
2850*61046927SAndroid Build Coastguard Worker    unsigned base[ROGUE_MAX_IO_ATTRIB_VARS];
2851*61046927SAndroid Build Coastguard Worker    unsigned components[ROGUE_MAX_IO_ATTRIB_VARS];
2852*61046927SAndroid Build Coastguard Worker } rogue_vertex_inputs;
2853*61046927SAndroid Build Coastguard Worker 
2854*61046927SAndroid Build Coastguard Worker /**
2855*61046927SAndroid Build Coastguard Worker  * \brief Vertex output allocations.
2856*61046927SAndroid Build Coastguard Worker  */
2857*61046927SAndroid Build Coastguard Worker typedef struct rogue_vertex_outputs {
2858*61046927SAndroid Build Coastguard Worker    unsigned num_output_vars;
2859*61046927SAndroid Build Coastguard Worker    unsigned base[ROGUE_MAX_IO_VARYING_VARS];
2860*61046927SAndroid Build Coastguard Worker    unsigned components[ROGUE_MAX_IO_VARYING_VARS];
2861*61046927SAndroid Build Coastguard Worker } rogue_vertex_outputs;
2862*61046927SAndroid Build Coastguard Worker 
2863*61046927SAndroid Build Coastguard Worker enum rogue_msaa_mode {
2864*61046927SAndroid Build Coastguard Worker    ROGUE_MSAA_MODE_UNDEF = 0, /* explicitly treat 0 as undefined */
2865*61046927SAndroid Build Coastguard Worker    /* One task for all samples. */
2866*61046927SAndroid Build Coastguard Worker    ROGUE_MSAA_MODE_PIXEL,
2867*61046927SAndroid Build Coastguard Worker    /* For on-edge pixels only: separate tasks for each sample. */
2868*61046927SAndroid Build Coastguard Worker    ROGUE_MSAA_MODE_SELECTIVE,
2869*61046927SAndroid Build Coastguard Worker    /* For all pixels: separate tasks for each sample. */
2870*61046927SAndroid Build Coastguard Worker    ROGUE_MSAA_MODE_FULL,
2871*61046927SAndroid Build Coastguard Worker };
2872*61046927SAndroid Build Coastguard Worker 
2873*61046927SAndroid Build Coastguard Worker /**
2874*61046927SAndroid Build Coastguard Worker  * \brief Stage-specific build data.
2875*61046927SAndroid Build Coastguard Worker  */
2876*61046927SAndroid Build Coastguard Worker typedef struct rogue_build_data {
2877*61046927SAndroid Build Coastguard Worker    struct rogue_fs_build_data {
2878*61046927SAndroid Build Coastguard Worker       rogue_iterator_args iterator_args;
2879*61046927SAndroid Build Coastguard Worker       enum rogue_msaa_mode msaa_mode;
2880*61046927SAndroid Build Coastguard Worker       bool phas; /* Indicates the presence of PHAS instruction. */
2881*61046927SAndroid Build Coastguard Worker    } fs;
2882*61046927SAndroid Build Coastguard Worker    struct rogue_vs_build_data {
2883*61046927SAndroid Build Coastguard Worker       /* TODO: Should these be removed since the driver allocates the vertex
2884*61046927SAndroid Build Coastguard Worker        * inputs?
2885*61046927SAndroid Build Coastguard Worker        */
2886*61046927SAndroid Build Coastguard Worker       rogue_vertex_inputs inputs;
2887*61046927SAndroid Build Coastguard Worker       unsigned num_vertex_input_regs; /* Final number of inputs. */
2888*61046927SAndroid Build Coastguard Worker 
2889*61046927SAndroid Build Coastguard Worker       rogue_vertex_outputs outputs;
2890*61046927SAndroid Build Coastguard Worker       unsigned num_vertex_outputs; /* Final number of outputs. */
2891*61046927SAndroid Build Coastguard Worker 
2892*61046927SAndroid Build Coastguard Worker       unsigned num_varyings; /* Final number of varyings. */
2893*61046927SAndroid Build Coastguard Worker    } vs;
2894*61046927SAndroid Build Coastguard Worker } rogue_build_data;
2895*61046927SAndroid Build Coastguard Worker 
2896*61046927SAndroid Build Coastguard Worker /**
2897*61046927SAndroid Build Coastguard Worker  * \brief Shared multi-stage build context.
2898*61046927SAndroid Build Coastguard Worker  */
2899*61046927SAndroid Build Coastguard Worker typedef struct rogue_build_ctx {
2900*61046927SAndroid Build Coastguard Worker    rogue_compiler *compiler;
2901*61046927SAndroid Build Coastguard Worker 
2902*61046927SAndroid Build Coastguard Worker    /* Shaders in various stages of compilations. */
2903*61046927SAndroid Build Coastguard Worker    nir_shader *nir[MESA_SHADER_FRAGMENT + 1];
2904*61046927SAndroid Build Coastguard Worker    rogue_shader *rogue[MESA_SHADER_FRAGMENT + 1];
2905*61046927SAndroid Build Coastguard Worker    struct util_dynarray binary[MESA_SHADER_FRAGMENT + 1];
2906*61046927SAndroid Build Coastguard Worker 
2907*61046927SAndroid Build Coastguard Worker    rogue_common_build_data common_data[MESA_SHADER_FRAGMENT + 1];
2908*61046927SAndroid Build Coastguard Worker    rogue_build_data stage_data;
2909*61046927SAndroid Build Coastguard Worker    struct pvr_pipeline_layout *pipeline_layout;
2910*61046927SAndroid Build Coastguard Worker    unsigned next_ssa_idx;
2911*61046927SAndroid Build Coastguard Worker } rogue_build_ctx;
2912*61046927SAndroid Build Coastguard Worker 
2913*61046927SAndroid Build Coastguard Worker rogue_build_ctx *
2914*61046927SAndroid Build Coastguard Worker rogue_build_context_create(rogue_compiler *compiler,
2915*61046927SAndroid Build Coastguard Worker                            struct pvr_pipeline_layout *pipeline_layout);
2916*61046927SAndroid Build Coastguard Worker 
2917*61046927SAndroid Build Coastguard Worker void rogue_collect_io_data(rogue_build_ctx *ctx, nir_shader *nir);
2918*61046927SAndroid Build Coastguard Worker 
2919*61046927SAndroid Build Coastguard Worker unsigned rogue_count_used_regs(const rogue_shader *shader,
2920*61046927SAndroid Build Coastguard Worker                                enum rogue_reg_class class);
2921*61046927SAndroid Build Coastguard Worker 
2922*61046927SAndroid Build Coastguard Worker unsigned rogue_coeff_index_fs(rogue_iterator_args *args,
2923*61046927SAndroid Build Coastguard Worker                               gl_varying_slot location,
2924*61046927SAndroid Build Coastguard Worker                               unsigned component);
2925*61046927SAndroid Build Coastguard Worker 
2926*61046927SAndroid Build Coastguard Worker unsigned rogue_output_index_vs(rogue_vertex_outputs *outputs,
2927*61046927SAndroid Build Coastguard Worker                                gl_varying_slot location,
2928*61046927SAndroid Build Coastguard Worker                                unsigned component);
2929*61046927SAndroid Build Coastguard Worker 
2930*61046927SAndroid Build Coastguard Worker unsigned rogue_ubo_reg(rogue_ubo_data *ubo_data,
2931*61046927SAndroid Build Coastguard Worker                        unsigned desc_set,
2932*61046927SAndroid Build Coastguard Worker                        unsigned binding,
2933*61046927SAndroid Build Coastguard Worker                        unsigned offset_bytes);
2934*61046927SAndroid Build Coastguard Worker 
2935*61046927SAndroid Build Coastguard Worker nir_shader *rogue_spirv_to_nir(rogue_build_ctx *ctx,
2936*61046927SAndroid Build Coastguard Worker                                gl_shader_stage stage,
2937*61046927SAndroid Build Coastguard Worker                                const char *entry,
2938*61046927SAndroid Build Coastguard Worker                                unsigned spirv_size,
2939*61046927SAndroid Build Coastguard Worker                                const uint32_t *spirv_data,
2940*61046927SAndroid Build Coastguard Worker                                unsigned num_spec,
2941*61046927SAndroid Build Coastguard Worker                                struct nir_spirv_specialization *spec);
2942*61046927SAndroid Build Coastguard Worker 
2943*61046927SAndroid Build Coastguard Worker /* Custom NIR passes. */
2944*61046927SAndroid Build Coastguard Worker void rogue_nir_pfo(nir_shader *shader);
2945*61046927SAndroid Build Coastguard Worker 
2946*61046927SAndroid Build Coastguard Worker bool rogue_nir_lower_io(nir_shader *shader);
2947*61046927SAndroid Build Coastguard Worker 
2948*61046927SAndroid Build Coastguard Worker rogue_shader *rogue_nir_to_rogue(rogue_build_ctx *ctx, const nir_shader *nir);
2949*61046927SAndroid Build Coastguard Worker 
2950*61046927SAndroid Build Coastguard Worker /* Encode/decode */
2951*61046927SAndroid Build Coastguard Worker 
2952*61046927SAndroid Build Coastguard Worker void rogue_encode_shader(rogue_build_ctx *ctx,
2953*61046927SAndroid Build Coastguard Worker                          rogue_shader *shader,
2954*61046927SAndroid Build Coastguard Worker                          struct util_dynarray *binary);
2955*61046927SAndroid Build Coastguard Worker 
2956*61046927SAndroid Build Coastguard Worker #endif /* ROGUE_H */
2957