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(®->uses) && list_is_empty(®->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(®array->uses) && list_is_empty(®array->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(®array->link);
1949*61046927SAndroid Build Coastguard Worker if (regarray->parent)
1950*61046927SAndroid Build Coastguard Worker list_del(®array->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, ®->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, ®array->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, ®->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, ®array->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