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 #include "compiler/glsl_types.h"
25*61046927SAndroid Build Coastguard Worker #include "rogue.h"
26*61046927SAndroid Build Coastguard Worker #include "util/list.h"
27*61046927SAndroid Build Coastguard Worker #include "util/macros.h"
28*61046927SAndroid Build Coastguard Worker #include "util/ralloc.h"
29*61046927SAndroid Build Coastguard Worker #include "util/sparse_array.h"
30*61046927SAndroid Build Coastguard Worker
31*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker /**
34*61046927SAndroid Build Coastguard Worker * \file rogue.c
35*61046927SAndroid Build Coastguard Worker *
36*61046927SAndroid Build Coastguard Worker * \brief Contains general Rogue IR functions.
37*61046927SAndroid Build Coastguard Worker */
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker /* TODO: Tweak these? */
40*61046927SAndroid Build Coastguard Worker #define ROGUE_REG_CACHE_NODE_SIZE 512
41*61046927SAndroid Build Coastguard Worker #define ROGUE_REGARRAY_CACHE_NODE_SIZE 512
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard Worker /**
44*61046927SAndroid Build Coastguard Worker * \brief Sets an existing register to a (new) class and/or index.
45*61046927SAndroid Build Coastguard Worker *
46*61046927SAndroid Build Coastguard Worker * \param[in] shader The shader containing the register.
47*61046927SAndroid Build Coastguard Worker * \param[in] reg The register being changed.
48*61046927SAndroid Build Coastguard Worker * \param[in] class The new register class.
49*61046927SAndroid Build Coastguard Worker * \param[in] index The new register index.
50*61046927SAndroid Build Coastguard Worker * \return True if the register was updated, else false.
51*61046927SAndroid Build Coastguard Worker */
52*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_reg_set(rogue_shader * shader,rogue_reg * reg,enum rogue_reg_class class,unsigned index)53*61046927SAndroid Build Coastguard Worker bool rogue_reg_set(rogue_shader *shader,
54*61046927SAndroid Build Coastguard Worker rogue_reg *reg,
55*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
56*61046927SAndroid Build Coastguard Worker unsigned index)
57*61046927SAndroid Build Coastguard Worker {
58*61046927SAndroid Build Coastguard Worker bool changed = true;
59*61046927SAndroid Build Coastguard Worker
60*61046927SAndroid Build Coastguard Worker if (reg->class == class && reg->index == index)
61*61046927SAndroid Build Coastguard Worker changed = false;
62*61046927SAndroid Build Coastguard Worker
63*61046927SAndroid Build Coastguard Worker const rogue_reg_info *info = &rogue_reg_infos[class];
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker if (info->num) {
66*61046927SAndroid Build Coastguard Worker assert(index < info->num);
67*61046927SAndroid Build Coastguard Worker rogue_set_reg_use(shader, class, index);
68*61046927SAndroid Build Coastguard Worker }
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker if (reg->class != class) {
71*61046927SAndroid Build Coastguard Worker list_del(®->link);
72*61046927SAndroid Build Coastguard Worker list_addtail(®->link, &shader->regs[class]);
73*61046927SAndroid Build Coastguard Worker }
74*61046927SAndroid Build Coastguard Worker
75*61046927SAndroid Build Coastguard Worker reg->class = class;
76*61046927SAndroid Build Coastguard Worker reg->index = index;
77*61046927SAndroid Build Coastguard Worker reg->dirty = true;
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker /* Clear the old cache entry. */
80*61046927SAndroid Build Coastguard Worker if (reg->cached && *reg->cached == reg)
81*61046927SAndroid Build Coastguard Worker *reg->cached = NULL;
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Worker /* Set new cache entry. */
84*61046927SAndroid Build Coastguard Worker rogue_reg **reg_cached =
85*61046927SAndroid Build Coastguard Worker util_sparse_array_get(&shader->reg_cache[class], index);
86*61046927SAndroid Build Coastguard Worker *reg_cached = reg;
87*61046927SAndroid Build Coastguard Worker reg->cached = reg_cached;
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker return changed;
90*61046927SAndroid Build Coastguard Worker }
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker /**
93*61046927SAndroid Build Coastguard Worker * \brief Sets an existing register to a (new) class and/or index, and updates
94*61046927SAndroid Build Coastguard Worker * its usage bitset.
95*61046927SAndroid Build Coastguard Worker *
96*61046927SAndroid Build Coastguard Worker * \param[in] shader The shader containing the register.
97*61046927SAndroid Build Coastguard Worker * \param[in] reg The register being changed.
98*61046927SAndroid Build Coastguard Worker * \param[in] class The new register class.
99*61046927SAndroid Build Coastguard Worker * \param[in] index The new register index.
100*61046927SAndroid Build Coastguard Worker * \return True if the register was updated, else false.
101*61046927SAndroid Build Coastguard Worker */
102*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_reg_rewrite(rogue_shader * shader,rogue_reg * reg,enum rogue_reg_class class,unsigned index)103*61046927SAndroid Build Coastguard Worker bool rogue_reg_rewrite(rogue_shader *shader,
104*61046927SAndroid Build Coastguard Worker rogue_reg *reg,
105*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
106*61046927SAndroid Build Coastguard Worker unsigned index)
107*61046927SAndroid Build Coastguard Worker {
108*61046927SAndroid Build Coastguard Worker const rogue_reg_info *info = &rogue_reg_infos[reg->class];
109*61046927SAndroid Build Coastguard Worker if (info->num) {
110*61046927SAndroid Build Coastguard Worker assert(rogue_reg_is_used(shader, reg->class, reg->index) &&
111*61046927SAndroid Build Coastguard Worker "Register not in use!");
112*61046927SAndroid Build Coastguard Worker rogue_clear_reg_use(shader, reg->class, reg->index);
113*61046927SAndroid Build Coastguard Worker }
114*61046927SAndroid Build Coastguard Worker
115*61046927SAndroid Build Coastguard Worker return rogue_reg_set(shader, reg, class, index);
116*61046927SAndroid Build Coastguard Worker }
117*61046927SAndroid Build Coastguard Worker
118*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_regarray_set(rogue_shader * shader,rogue_regarray * regarray,enum rogue_reg_class class,unsigned base_index,bool set_regs)119*61046927SAndroid Build Coastguard Worker bool rogue_regarray_set(rogue_shader *shader,
120*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray,
121*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
122*61046927SAndroid Build Coastguard Worker unsigned base_index,
123*61046927SAndroid Build Coastguard Worker bool set_regs)
124*61046927SAndroid Build Coastguard Worker {
125*61046927SAndroid Build Coastguard Worker bool updated = true;
126*61046927SAndroid Build Coastguard Worker
127*61046927SAndroid Build Coastguard Worker if (set_regs) {
128*61046927SAndroid Build Coastguard Worker for (unsigned u = 0; u < regarray->size; ++u) {
129*61046927SAndroid Build Coastguard Worker updated &=
130*61046927SAndroid Build Coastguard Worker rogue_reg_set(shader, regarray->regs[u], class, base_index + u);
131*61046927SAndroid Build Coastguard Worker }
132*61046927SAndroid Build Coastguard Worker }
133*61046927SAndroid Build Coastguard Worker
134*61046927SAndroid Build Coastguard Worker if (regarray->cached && *regarray->cached == regarray)
135*61046927SAndroid Build Coastguard Worker *regarray->cached = NULL;
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker uint64_t key =
138*61046927SAndroid Build Coastguard Worker rogue_regarray_cache_key(regarray->size, class, base_index, false, 0);
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker rogue_regarray **regarray_cached =
141*61046927SAndroid Build Coastguard Worker util_sparse_array_get(&shader->regarray_cache, key);
142*61046927SAndroid Build Coastguard Worker assert(*regarray_cached == NULL);
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker *regarray_cached = regarray;
145*61046927SAndroid Build Coastguard Worker regarray->cached = regarray_cached;
146*61046927SAndroid Build Coastguard Worker
147*61046927SAndroid Build Coastguard Worker return updated;
148*61046927SAndroid Build Coastguard Worker }
149*61046927SAndroid Build Coastguard Worker
rogue_regarray_rewrite(rogue_shader * shader,rogue_regarray * regarray,enum rogue_reg_class class,unsigned base_index)150*61046927SAndroid Build Coastguard Worker bool rogue_regarray_rewrite(rogue_shader *shader,
151*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray,
152*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
153*61046927SAndroid Build Coastguard Worker unsigned base_index)
154*61046927SAndroid Build Coastguard Worker {
155*61046927SAndroid Build Coastguard Worker bool progress = true;
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker enum rogue_reg_class orig_class = regarray->regs[0]->class;
158*61046927SAndroid Build Coastguard Worker unsigned orig_base_index = regarray->regs[0]->index;
159*61046927SAndroid Build Coastguard Worker const rogue_reg_info *info = &rogue_reg_infos[orig_class];
160*61046927SAndroid Build Coastguard Worker
161*61046927SAndroid Build Coastguard Worker assert(!regarray->parent);
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker if (info->num) {
164*61046927SAndroid Build Coastguard Worker for (unsigned u = 0; u < regarray->size; ++u) {
165*61046927SAndroid Build Coastguard Worker assert(rogue_reg_is_used(shader, orig_class, orig_base_index) &&
166*61046927SAndroid Build Coastguard Worker "Register not in use!");
167*61046927SAndroid Build Coastguard Worker rogue_clear_reg_use(shader, orig_class, orig_base_index);
168*61046927SAndroid Build Coastguard Worker }
169*61046927SAndroid Build Coastguard Worker }
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker progress &= rogue_regarray_set(shader, regarray, class, base_index, true);
172*61046927SAndroid Build Coastguard Worker
173*61046927SAndroid Build Coastguard Worker rogue_foreach_subarray (subarray, regarray) {
174*61046927SAndroid Build Coastguard Worker unsigned idx_offset = subarray->regs[0]->index - regarray->regs[0]->index;
175*61046927SAndroid Build Coastguard Worker progress &= rogue_regarray_set(shader,
176*61046927SAndroid Build Coastguard Worker subarray,
177*61046927SAndroid Build Coastguard Worker class,
178*61046927SAndroid Build Coastguard Worker base_index + idx_offset,
179*61046927SAndroid Build Coastguard Worker false);
180*61046927SAndroid Build Coastguard Worker }
181*61046927SAndroid Build Coastguard Worker
182*61046927SAndroid Build Coastguard Worker assert(progress);
183*61046927SAndroid Build Coastguard Worker return progress;
184*61046927SAndroid Build Coastguard Worker }
185*61046927SAndroid Build Coastguard Worker
rogue_shader_destructor(void * ptr)186*61046927SAndroid Build Coastguard Worker static void rogue_shader_destructor(void *ptr)
187*61046927SAndroid Build Coastguard Worker {
188*61046927SAndroid Build Coastguard Worker rogue_shader *shader = ptr;
189*61046927SAndroid Build Coastguard Worker for (unsigned u = 0; u < ARRAY_SIZE(shader->reg_cache); ++u)
190*61046927SAndroid Build Coastguard Worker util_sparse_array_finish(&shader->reg_cache[u]);
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker util_sparse_array_finish(&shader->regarray_cache);
193*61046927SAndroid Build Coastguard Worker }
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker /**
196*61046927SAndroid Build Coastguard Worker * \brief Allocates and initializes a new rogue_shader object.
197*61046927SAndroid Build Coastguard Worker *
198*61046927SAndroid Build Coastguard Worker * \param[in] mem_ctx The new shader's memory context.
199*61046927SAndroid Build Coastguard Worker * \param[in] stage The new shader's stage.
200*61046927SAndroid Build Coastguard Worker * \return The new shader.
201*61046927SAndroid Build Coastguard Worker */
202*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_shader_create(void * mem_ctx,gl_shader_stage stage)203*61046927SAndroid Build Coastguard Worker rogue_shader *rogue_shader_create(void *mem_ctx, gl_shader_stage stage)
204*61046927SAndroid Build Coastguard Worker {
205*61046927SAndroid Build Coastguard Worker rogue_debug_init();
206*61046927SAndroid Build Coastguard Worker
207*61046927SAndroid Build Coastguard Worker rogue_shader *shader = rzalloc_size(mem_ctx, sizeof(*shader));
208*61046927SAndroid Build Coastguard Worker
209*61046927SAndroid Build Coastguard Worker shader->stage = stage;
210*61046927SAndroid Build Coastguard Worker
211*61046927SAndroid Build Coastguard Worker list_inithead(&shader->blocks);
212*61046927SAndroid Build Coastguard Worker
213*61046927SAndroid Build Coastguard Worker for (enum rogue_reg_class class = 0; class < ROGUE_REG_CLASS_COUNT;
214*61046927SAndroid Build Coastguard Worker ++class) {
215*61046927SAndroid Build Coastguard Worker list_inithead(&shader->regs[class]);
216*61046927SAndroid Build Coastguard Worker
217*61046927SAndroid Build Coastguard Worker const rogue_reg_info *info = &rogue_reg_infos[class];
218*61046927SAndroid Build Coastguard Worker if (info->num) {
219*61046927SAndroid Build Coastguard Worker unsigned bitset_size =
220*61046927SAndroid Build Coastguard Worker sizeof(*shader->regs_used[class]) * BITSET_WORDS(info->num);
221*61046927SAndroid Build Coastguard Worker shader->regs_used[class] = rzalloc_size(shader, bitset_size);
222*61046927SAndroid Build Coastguard Worker }
223*61046927SAndroid Build Coastguard Worker }
224*61046927SAndroid Build Coastguard Worker
225*61046927SAndroid Build Coastguard Worker for (unsigned u = 0; u < ARRAY_SIZE(shader->reg_cache); ++u)
226*61046927SAndroid Build Coastguard Worker util_sparse_array_init(&shader->reg_cache[u],
227*61046927SAndroid Build Coastguard Worker sizeof(rogue_reg *),
228*61046927SAndroid Build Coastguard Worker ROGUE_REG_CACHE_NODE_SIZE);
229*61046927SAndroid Build Coastguard Worker
230*61046927SAndroid Build Coastguard Worker list_inithead(&shader->regarrays);
231*61046927SAndroid Build Coastguard Worker
232*61046927SAndroid Build Coastguard Worker util_sparse_array_init(&shader->regarray_cache,
233*61046927SAndroid Build Coastguard Worker sizeof(rogue_regarray *),
234*61046927SAndroid Build Coastguard Worker ROGUE_REGARRAY_CACHE_NODE_SIZE);
235*61046927SAndroid Build Coastguard Worker
236*61046927SAndroid Build Coastguard Worker for (unsigned u = 0; u < ARRAY_SIZE(shader->drc_trxns); ++u)
237*61046927SAndroid Build Coastguard Worker list_inithead(&shader->drc_trxns[u]);
238*61046927SAndroid Build Coastguard Worker
239*61046927SAndroid Build Coastguard Worker list_inithead(&shader->imm_uses);
240*61046927SAndroid Build Coastguard Worker
241*61046927SAndroid Build Coastguard Worker ralloc_set_destructor(shader, rogue_shader_destructor);
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker return shader;
244*61046927SAndroid Build Coastguard Worker }
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker /**
247*61046927SAndroid Build Coastguard Worker * \brief Allocates and initializes a new rogue_reg object.
248*61046927SAndroid Build Coastguard Worker *
249*61046927SAndroid Build Coastguard Worker * \param[in] shader The shader which will contain the register.
250*61046927SAndroid Build Coastguard Worker * \param[in] class The register class.
251*61046927SAndroid Build Coastguard Worker * \param[in] index The register index.
252*61046927SAndroid Build Coastguard Worker * \param[in] reg_cached The shader register cache.
253*61046927SAndroid Build Coastguard Worker * \return The new register.
254*61046927SAndroid Build Coastguard Worker */
rogue_reg_create(rogue_shader * shader,enum rogue_reg_class class,uint32_t index,rogue_reg ** reg_cached)255*61046927SAndroid Build Coastguard Worker static rogue_reg *rogue_reg_create(rogue_shader *shader,
256*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
257*61046927SAndroid Build Coastguard Worker uint32_t index,
258*61046927SAndroid Build Coastguard Worker rogue_reg **reg_cached)
259*61046927SAndroid Build Coastguard Worker {
260*61046927SAndroid Build Coastguard Worker rogue_reg *reg = rzalloc_size(shader, sizeof(*reg));
261*61046927SAndroid Build Coastguard Worker
262*61046927SAndroid Build Coastguard Worker reg->shader = shader;
263*61046927SAndroid Build Coastguard Worker reg->class = class;
264*61046927SAndroid Build Coastguard Worker reg->index = index;
265*61046927SAndroid Build Coastguard Worker reg->cached = reg_cached;
266*61046927SAndroid Build Coastguard Worker
267*61046927SAndroid Build Coastguard Worker list_addtail(®->link, &shader->regs[class]);
268*61046927SAndroid Build Coastguard Worker list_inithead(®->writes);
269*61046927SAndroid Build Coastguard Worker list_inithead(®->uses);
270*61046927SAndroid Build Coastguard Worker
271*61046927SAndroid Build Coastguard Worker const rogue_reg_info *info = &rogue_reg_infos[class];
272*61046927SAndroid Build Coastguard Worker if (info->num) {
273*61046927SAndroid Build Coastguard Worker assert(index < info->num);
274*61046927SAndroid Build Coastguard Worker assert(!rogue_reg_is_used(shader, class, index) &&
275*61046927SAndroid Build Coastguard Worker "Register already in use!");
276*61046927SAndroid Build Coastguard Worker rogue_set_reg_use(shader, class, index);
277*61046927SAndroid Build Coastguard Worker }
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker return reg;
280*61046927SAndroid Build Coastguard Worker }
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker /**
283*61046927SAndroid Build Coastguard Worker * \brief Deletes and frees a Rogue register.
284*61046927SAndroid Build Coastguard Worker *
285*61046927SAndroid Build Coastguard Worker * \param[in] reg The register to delete.
286*61046927SAndroid Build Coastguard Worker */
287*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_reg_delete(rogue_reg * reg)288*61046927SAndroid Build Coastguard Worker void rogue_reg_delete(rogue_reg *reg)
289*61046927SAndroid Build Coastguard Worker {
290*61046927SAndroid Build Coastguard Worker assert(rogue_reg_is_unused(reg));
291*61046927SAndroid Build Coastguard Worker const rogue_reg_info *info = &rogue_reg_infos[reg->class];
292*61046927SAndroid Build Coastguard Worker if (info->num) {
293*61046927SAndroid Build Coastguard Worker assert(rogue_reg_is_used(reg->shader, reg->class, reg->index) &&
294*61046927SAndroid Build Coastguard Worker "Register not in use!");
295*61046927SAndroid Build Coastguard Worker rogue_clear_reg_use(reg->shader, reg->class, reg->index);
296*61046927SAndroid Build Coastguard Worker }
297*61046927SAndroid Build Coastguard Worker
298*61046927SAndroid Build Coastguard Worker if (reg->cached && *reg->cached == reg)
299*61046927SAndroid Build Coastguard Worker *reg->cached = NULL;
300*61046927SAndroid Build Coastguard Worker
301*61046927SAndroid Build Coastguard Worker list_del(®->link);
302*61046927SAndroid Build Coastguard Worker ralloc_free(reg);
303*61046927SAndroid Build Coastguard Worker }
304*61046927SAndroid Build Coastguard Worker
rogue_reg_cached_common(rogue_shader * shader,enum rogue_reg_class class,uint32_t index,uint8_t component,bool vec)305*61046927SAndroid Build Coastguard Worker static inline rogue_reg *rogue_reg_cached_common(rogue_shader *shader,
306*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
307*61046927SAndroid Build Coastguard Worker uint32_t index,
308*61046927SAndroid Build Coastguard Worker uint8_t component,
309*61046927SAndroid Build Coastguard Worker bool vec)
310*61046927SAndroid Build Coastguard Worker {
311*61046927SAndroid Build Coastguard Worker uint32_t key = rogue_reg_cache_key(index, vec, component);
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker rogue_reg **reg_cached =
314*61046927SAndroid Build Coastguard Worker util_sparse_array_get(&shader->reg_cache[class], key);
315*61046927SAndroid Build Coastguard Worker if (!*reg_cached)
316*61046927SAndroid Build Coastguard Worker *reg_cached = rogue_reg_create(shader, class, key, reg_cached);
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker return *reg_cached;
319*61046927SAndroid Build Coastguard Worker }
320*61046927SAndroid Build Coastguard Worker
rogue_reg_cached(rogue_shader * shader,enum rogue_reg_class class,uint32_t index)321*61046927SAndroid Build Coastguard Worker static inline rogue_reg *rogue_reg_cached(rogue_shader *shader,
322*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
323*61046927SAndroid Build Coastguard Worker uint32_t index)
324*61046927SAndroid Build Coastguard Worker {
325*61046927SAndroid Build Coastguard Worker return rogue_reg_cached_common(shader, class, index, 0, false);
326*61046927SAndroid Build Coastguard Worker }
327*61046927SAndroid Build Coastguard Worker
rogue_vec_reg_cached(rogue_shader * shader,enum rogue_reg_class class,unsigned index,unsigned component)328*61046927SAndroid Build Coastguard Worker static inline rogue_reg *rogue_vec_reg_cached(rogue_shader *shader,
329*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
330*61046927SAndroid Build Coastguard Worker unsigned index,
331*61046927SAndroid Build Coastguard Worker unsigned component)
332*61046927SAndroid Build Coastguard Worker {
333*61046927SAndroid Build Coastguard Worker return rogue_reg_cached_common(shader, class, index, component, true);
334*61046927SAndroid Build Coastguard Worker }
335*61046927SAndroid Build Coastguard Worker
336*61046927SAndroid Build Coastguard Worker /* TODO: Static inline in rogue.h? */
337*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_ssa_reg(rogue_shader * shader,unsigned index)338*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_ssa_reg(rogue_shader *shader, unsigned index)
339*61046927SAndroid Build Coastguard Worker {
340*61046927SAndroid Build Coastguard Worker return rogue_reg_cached(shader, ROGUE_REG_CLASS_SSA, index);
341*61046927SAndroid Build Coastguard Worker }
342*61046927SAndroid Build Coastguard Worker
343*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_temp_reg(rogue_shader * shader,unsigned index)344*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_temp_reg(rogue_shader *shader, unsigned index)
345*61046927SAndroid Build Coastguard Worker {
346*61046927SAndroid Build Coastguard Worker return rogue_reg_cached(shader, ROGUE_REG_CLASS_TEMP, index);
347*61046927SAndroid Build Coastguard Worker }
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_coeff_reg(rogue_shader * shader,unsigned index)350*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_coeff_reg(rogue_shader *shader, unsigned index)
351*61046927SAndroid Build Coastguard Worker {
352*61046927SAndroid Build Coastguard Worker return rogue_reg_cached(shader, ROGUE_REG_CLASS_COEFF, index);
353*61046927SAndroid Build Coastguard Worker }
354*61046927SAndroid Build Coastguard Worker
355*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_shared_reg(rogue_shader * shader,unsigned index)356*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_shared_reg(rogue_shader *shader, unsigned index)
357*61046927SAndroid Build Coastguard Worker {
358*61046927SAndroid Build Coastguard Worker return rogue_reg_cached(shader, ROGUE_REG_CLASS_SHARED, index);
359*61046927SAndroid Build Coastguard Worker }
360*61046927SAndroid Build Coastguard Worker
361*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_const_reg(rogue_shader * shader,unsigned index)362*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_const_reg(rogue_shader *shader, unsigned index)
363*61046927SAndroid Build Coastguard Worker {
364*61046927SAndroid Build Coastguard Worker return rogue_reg_cached(shader, ROGUE_REG_CLASS_CONST, index);
365*61046927SAndroid Build Coastguard Worker }
366*61046927SAndroid Build Coastguard Worker
367*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_pixout_reg(rogue_shader * shader,unsigned index)368*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_pixout_reg(rogue_shader *shader, unsigned index)
369*61046927SAndroid Build Coastguard Worker {
370*61046927SAndroid Build Coastguard Worker return rogue_reg_cached(shader, ROGUE_REG_CLASS_PIXOUT, index);
371*61046927SAndroid Build Coastguard Worker }
372*61046927SAndroid Build Coastguard Worker
373*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_special_reg(rogue_shader * shader,unsigned index)374*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_special_reg(rogue_shader *shader, unsigned index)
375*61046927SAndroid Build Coastguard Worker {
376*61046927SAndroid Build Coastguard Worker return rogue_reg_cached(shader, ROGUE_REG_CLASS_SPECIAL, index);
377*61046927SAndroid Build Coastguard Worker }
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_vtxin_reg(rogue_shader * shader,unsigned index)380*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_vtxin_reg(rogue_shader *shader, unsigned index)
381*61046927SAndroid Build Coastguard Worker {
382*61046927SAndroid Build Coastguard Worker return rogue_reg_cached(shader, ROGUE_REG_CLASS_VTXIN, index);
383*61046927SAndroid Build Coastguard Worker }
384*61046927SAndroid Build Coastguard Worker
385*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_vtxout_reg(rogue_shader * shader,unsigned index)386*61046927SAndroid Build Coastguard Worker rogue_reg *rogue_vtxout_reg(rogue_shader *shader, unsigned index)
387*61046927SAndroid Build Coastguard Worker {
388*61046927SAndroid Build Coastguard Worker return rogue_reg_cached(shader, ROGUE_REG_CLASS_VTXOUT, index);
389*61046927SAndroid Build Coastguard Worker }
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker PUBLIC
392*61046927SAndroid Build Coastguard Worker rogue_reg *
rogue_ssa_vec_reg(rogue_shader * shader,unsigned index,unsigned component)393*61046927SAndroid Build Coastguard Worker rogue_ssa_vec_reg(rogue_shader *shader, unsigned index, unsigned component)
394*61046927SAndroid Build Coastguard Worker {
395*61046927SAndroid Build Coastguard Worker return rogue_vec_reg_cached(shader, ROGUE_REG_CLASS_SSA, index, component);
396*61046927SAndroid Build Coastguard Worker }
397*61046927SAndroid Build Coastguard Worker
rogue_find_common_regarray(rogue_regarray * regarray,bool * is_parent,rogue_reg *** parent_regptr)398*61046927SAndroid Build Coastguard Worker static rogue_regarray *rogue_find_common_regarray(rogue_regarray *regarray,
399*61046927SAndroid Build Coastguard Worker bool *is_parent,
400*61046927SAndroid Build Coastguard Worker rogue_reg ***parent_regptr)
401*61046927SAndroid Build Coastguard Worker {
402*61046927SAndroid Build Coastguard Worker rogue_regarray *common_regarray = NULL;
403*61046927SAndroid Build Coastguard Worker
404*61046927SAndroid Build Coastguard Worker for (unsigned u = 0; u < regarray->size; ++u) {
405*61046927SAndroid Build Coastguard Worker if (regarray->regs[u]->regarray) {
406*61046927SAndroid Build Coastguard Worker if (common_regarray && regarray->regs[u]->regarray != common_regarray)
407*61046927SAndroid Build Coastguard Worker unreachable("Can't have overlapping regarrays.");
408*61046927SAndroid Build Coastguard Worker else if (!common_regarray)
409*61046927SAndroid Build Coastguard Worker common_regarray = regarray->regs[u]->regarray;
410*61046927SAndroid Build Coastguard Worker }
411*61046927SAndroid Build Coastguard Worker }
412*61046927SAndroid Build Coastguard Worker
413*61046927SAndroid Build Coastguard Worker if (common_regarray) {
414*61046927SAndroid Build Coastguard Worker unsigned min_index = regarray->regs[0]->index;
415*61046927SAndroid Build Coastguard Worker unsigned max_index = min_index + regarray->size - 1;
416*61046927SAndroid Build Coastguard Worker
417*61046927SAndroid Build Coastguard Worker unsigned min_common_index = common_regarray->regs[0]->index;
418*61046927SAndroid Build Coastguard Worker unsigned max_common_index = min_common_index + common_regarray->size - 1;
419*61046927SAndroid Build Coastguard Worker
420*61046927SAndroid Build Coastguard Worker /* TODO: Create a new parent array that encapsulates both ranges? */
421*61046927SAndroid Build Coastguard Worker /* Ensure that the new regarray doesn't occupy only part of its parent,
422*61046927SAndroid Build Coastguard Worker * and also registers *beyond* its parent. */
423*61046927SAndroid Build Coastguard Worker if ((min_index > min_common_index && max_index > max_common_index) ||
424*61046927SAndroid Build Coastguard Worker (min_index < min_common_index && max_index < max_common_index))
425*61046927SAndroid Build Coastguard Worker unreachable("Can't have overflowing partial regarrays.");
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker *is_parent = regarray->size > common_regarray->size;
428*61046927SAndroid Build Coastguard Worker const rogue_regarray *parent_regarray = *is_parent ? regarray
429*61046927SAndroid Build Coastguard Worker : common_regarray;
430*61046927SAndroid Build Coastguard Worker const rogue_regarray *child_regarray = *is_parent ? common_regarray
431*61046927SAndroid Build Coastguard Worker : regarray;
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker for (unsigned u = 0; u < parent_regarray->size; ++u) {
434*61046927SAndroid Build Coastguard Worker if (child_regarray->regs[0]->index ==
435*61046927SAndroid Build Coastguard Worker parent_regarray->regs[u]->index) {
436*61046927SAndroid Build Coastguard Worker *parent_regptr = &parent_regarray->regs[u];
437*61046927SAndroid Build Coastguard Worker break;
438*61046927SAndroid Build Coastguard Worker }
439*61046927SAndroid Build Coastguard Worker }
440*61046927SAndroid Build Coastguard Worker }
441*61046927SAndroid Build Coastguard Worker
442*61046927SAndroid Build Coastguard Worker return common_regarray;
443*61046927SAndroid Build Coastguard Worker }
444*61046927SAndroid Build Coastguard Worker
rogue_regarray_create(rogue_shader * shader,unsigned size,enum rogue_reg_class class,unsigned start_index,uint8_t component,bool vec,rogue_regarray ** regarray_cached)445*61046927SAndroid Build Coastguard Worker static rogue_regarray *rogue_regarray_create(rogue_shader *shader,
446*61046927SAndroid Build Coastguard Worker unsigned size,
447*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
448*61046927SAndroid Build Coastguard Worker unsigned start_index,
449*61046927SAndroid Build Coastguard Worker uint8_t component,
450*61046927SAndroid Build Coastguard Worker bool vec,
451*61046927SAndroid Build Coastguard Worker rogue_regarray **regarray_cached)
452*61046927SAndroid Build Coastguard Worker {
453*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray = rzalloc_size(shader, sizeof(*regarray));
454*61046927SAndroid Build Coastguard Worker regarray->regs = rzalloc_size(regarray, sizeof(*regarray->regs) * size);
455*61046927SAndroid Build Coastguard Worker regarray->size = size;
456*61046927SAndroid Build Coastguard Worker regarray->cached = regarray_cached;
457*61046927SAndroid Build Coastguard Worker list_inithead(®array->children);
458*61046927SAndroid Build Coastguard Worker list_inithead(®array->writes);
459*61046927SAndroid Build Coastguard Worker list_inithead(®array->uses);
460*61046927SAndroid Build Coastguard Worker
461*61046927SAndroid Build Coastguard Worker for (unsigned u = 0; u < size; ++u) {
462*61046927SAndroid Build Coastguard Worker regarray->regs[u] =
463*61046927SAndroid Build Coastguard Worker vec ? rogue_vec_reg_cached(shader, class, start_index, component + u)
464*61046927SAndroid Build Coastguard Worker : rogue_reg_cached(shader, class, start_index + u);
465*61046927SAndroid Build Coastguard Worker }
466*61046927SAndroid Build Coastguard Worker
467*61046927SAndroid Build Coastguard Worker bool is_parent = false;
468*61046927SAndroid Build Coastguard Worker rogue_reg **parent_regptr = NULL;
469*61046927SAndroid Build Coastguard Worker rogue_regarray *common_regarray =
470*61046927SAndroid Build Coastguard Worker rogue_find_common_regarray(regarray, &is_parent, &parent_regptr);
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker if (!common_regarray) {
473*61046927SAndroid Build Coastguard Worker /* We don't share any registers with another regarray. */
474*61046927SAndroid Build Coastguard Worker for (unsigned u = 0; u < size; ++u)
475*61046927SAndroid Build Coastguard Worker regarray->regs[u]->regarray = regarray;
476*61046927SAndroid Build Coastguard Worker } else {
477*61046927SAndroid Build Coastguard Worker if (is_parent) {
478*61046927SAndroid Build Coastguard Worker /* We share registers with another regarray, and it is a subset of us.
479*61046927SAndroid Build Coastguard Worker */
480*61046927SAndroid Build Coastguard Worker for (unsigned u = 0; u < common_regarray->size; ++u)
481*61046927SAndroid Build Coastguard Worker common_regarray->regs[u]->regarray = regarray;
482*61046927SAndroid Build Coastguard Worker
483*61046927SAndroid Build Coastguard Worker /* Steal its children. */
484*61046927SAndroid Build Coastguard Worker rogue_foreach_subarray_safe (subarray, common_regarray) {
485*61046927SAndroid Build Coastguard Worker unsigned parent_index = common_regarray->regs[0]->index;
486*61046927SAndroid Build Coastguard Worker unsigned child_index = subarray->regs[0]->index;
487*61046927SAndroid Build Coastguard Worker assert(child_index >= parent_index);
488*61046927SAndroid Build Coastguard Worker
489*61046927SAndroid Build Coastguard Worker subarray->parent = regarray;
490*61046927SAndroid Build Coastguard Worker subarray->regs = &parent_regptr[child_index - parent_index];
491*61046927SAndroid Build Coastguard Worker
492*61046927SAndroid Build Coastguard Worker list_del(&subarray->child_link);
493*61046927SAndroid Build Coastguard Worker list_addtail(&subarray->child_link, ®array->children);
494*61046927SAndroid Build Coastguard Worker }
495*61046927SAndroid Build Coastguard Worker
496*61046927SAndroid Build Coastguard Worker common_regarray->parent = regarray;
497*61046927SAndroid Build Coastguard Worker ralloc_free(common_regarray->regs);
498*61046927SAndroid Build Coastguard Worker common_regarray->regs = parent_regptr;
499*61046927SAndroid Build Coastguard Worker list_addtail(&common_regarray->child_link, ®array->children);
500*61046927SAndroid Build Coastguard Worker } else {
501*61046927SAndroid Build Coastguard Worker /* We share registers with another regarray, and we are a subset of it.
502*61046927SAndroid Build Coastguard Worker */
503*61046927SAndroid Build Coastguard Worker regarray->parent = common_regarray;
504*61046927SAndroid Build Coastguard Worker ralloc_free(regarray->regs);
505*61046927SAndroid Build Coastguard Worker regarray->regs = parent_regptr;
506*61046927SAndroid Build Coastguard Worker assert(list_is_empty(®array->children));
507*61046927SAndroid Build Coastguard Worker list_addtail(®array->child_link, &common_regarray->children);
508*61046927SAndroid Build Coastguard Worker }
509*61046927SAndroid Build Coastguard Worker }
510*61046927SAndroid Build Coastguard Worker
511*61046927SAndroid Build Coastguard Worker list_addtail(®array->link, &shader->regarrays);
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker return regarray;
514*61046927SAndroid Build Coastguard Worker }
515*61046927SAndroid Build Coastguard Worker
516*61046927SAndroid Build Coastguard Worker static inline rogue_regarray *
rogue_regarray_cached_common(rogue_shader * shader,unsigned size,enum rogue_reg_class class,uint32_t start_index,uint8_t component,bool vec)517*61046927SAndroid Build Coastguard Worker rogue_regarray_cached_common(rogue_shader *shader,
518*61046927SAndroid Build Coastguard Worker unsigned size,
519*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
520*61046927SAndroid Build Coastguard Worker uint32_t start_index,
521*61046927SAndroid Build Coastguard Worker uint8_t component,
522*61046927SAndroid Build Coastguard Worker bool vec)
523*61046927SAndroid Build Coastguard Worker {
524*61046927SAndroid Build Coastguard Worker uint64_t key =
525*61046927SAndroid Build Coastguard Worker rogue_regarray_cache_key(size, class, start_index, vec, component);
526*61046927SAndroid Build Coastguard Worker
527*61046927SAndroid Build Coastguard Worker rogue_regarray **regarray_cached =
528*61046927SAndroid Build Coastguard Worker util_sparse_array_get(&shader->regarray_cache, key);
529*61046927SAndroid Build Coastguard Worker if (!*regarray_cached)
530*61046927SAndroid Build Coastguard Worker *regarray_cached = rogue_regarray_create(shader,
531*61046927SAndroid Build Coastguard Worker size,
532*61046927SAndroid Build Coastguard Worker class,
533*61046927SAndroid Build Coastguard Worker start_index,
534*61046927SAndroid Build Coastguard Worker component,
535*61046927SAndroid Build Coastguard Worker vec,
536*61046927SAndroid Build Coastguard Worker regarray_cached);
537*61046927SAndroid Build Coastguard Worker
538*61046927SAndroid Build Coastguard Worker return *regarray_cached;
539*61046927SAndroid Build Coastguard Worker }
540*61046927SAndroid Build Coastguard Worker
541*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_regarray_cached(rogue_shader * shader,unsigned size,enum rogue_reg_class class,uint32_t start_index)542*61046927SAndroid Build Coastguard Worker rogue_regarray *rogue_regarray_cached(rogue_shader *shader,
543*61046927SAndroid Build Coastguard Worker unsigned size,
544*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
545*61046927SAndroid Build Coastguard Worker uint32_t start_index)
546*61046927SAndroid Build Coastguard Worker {
547*61046927SAndroid Build Coastguard Worker return rogue_regarray_cached_common(shader,
548*61046927SAndroid Build Coastguard Worker size,
549*61046927SAndroid Build Coastguard Worker class,
550*61046927SAndroid Build Coastguard Worker start_index,
551*61046927SAndroid Build Coastguard Worker 0,
552*61046927SAndroid Build Coastguard Worker false);
553*61046927SAndroid Build Coastguard Worker }
554*61046927SAndroid Build Coastguard Worker
555*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_vec_regarray_cached(rogue_shader * shader,unsigned size,enum rogue_reg_class class,uint32_t start_index,uint8_t component)556*61046927SAndroid Build Coastguard Worker rogue_regarray *rogue_vec_regarray_cached(rogue_shader *shader,
557*61046927SAndroid Build Coastguard Worker unsigned size,
558*61046927SAndroid Build Coastguard Worker enum rogue_reg_class class,
559*61046927SAndroid Build Coastguard Worker uint32_t start_index,
560*61046927SAndroid Build Coastguard Worker uint8_t component)
561*61046927SAndroid Build Coastguard Worker {
562*61046927SAndroid Build Coastguard Worker return rogue_regarray_cached_common(shader,
563*61046927SAndroid Build Coastguard Worker size,
564*61046927SAndroid Build Coastguard Worker class,
565*61046927SAndroid Build Coastguard Worker start_index,
566*61046927SAndroid Build Coastguard Worker component,
567*61046927SAndroid Build Coastguard Worker true);
568*61046927SAndroid Build Coastguard Worker }
569*61046927SAndroid Build Coastguard Worker
570*61046927SAndroid Build Coastguard Worker PUBLIC
571*61046927SAndroid Build Coastguard Worker rogue_regarray *
rogue_ssa_regarray(rogue_shader * shader,unsigned size,unsigned start_index)572*61046927SAndroid Build Coastguard Worker rogue_ssa_regarray(rogue_shader *shader, unsigned size, unsigned start_index)
573*61046927SAndroid Build Coastguard Worker {
574*61046927SAndroid Build Coastguard Worker return rogue_regarray_cached(shader, size, ROGUE_REG_CLASS_SSA, start_index);
575*61046927SAndroid Build Coastguard Worker }
576*61046927SAndroid Build Coastguard Worker
577*61046927SAndroid Build Coastguard Worker PUBLIC
578*61046927SAndroid Build Coastguard Worker rogue_regarray *
rogue_temp_regarray(rogue_shader * shader,unsigned size,unsigned start_index)579*61046927SAndroid Build Coastguard Worker rogue_temp_regarray(rogue_shader *shader, unsigned size, unsigned start_index)
580*61046927SAndroid Build Coastguard Worker {
581*61046927SAndroid Build Coastguard Worker return rogue_regarray_cached(shader, size, ROGUE_REG_CLASS_TEMP, start_index);
582*61046927SAndroid Build Coastguard Worker }
583*61046927SAndroid Build Coastguard Worker
584*61046927SAndroid Build Coastguard Worker PUBLIC
585*61046927SAndroid Build Coastguard Worker rogue_regarray *
rogue_coeff_regarray(rogue_shader * shader,unsigned size,unsigned start_index)586*61046927SAndroid Build Coastguard Worker rogue_coeff_regarray(rogue_shader *shader, unsigned size, unsigned start_index)
587*61046927SAndroid Build Coastguard Worker {
588*61046927SAndroid Build Coastguard Worker return rogue_regarray_cached(shader,
589*61046927SAndroid Build Coastguard Worker size,
590*61046927SAndroid Build Coastguard Worker ROGUE_REG_CLASS_COEFF,
591*61046927SAndroid Build Coastguard Worker start_index);
592*61046927SAndroid Build Coastguard Worker }
593*61046927SAndroid Build Coastguard Worker
594*61046927SAndroid Build Coastguard Worker PUBLIC
595*61046927SAndroid Build Coastguard Worker rogue_regarray *
rogue_shared_regarray(rogue_shader * shader,unsigned size,unsigned start_index)596*61046927SAndroid Build Coastguard Worker rogue_shared_regarray(rogue_shader *shader, unsigned size, unsigned start_index)
597*61046927SAndroid Build Coastguard Worker {
598*61046927SAndroid Build Coastguard Worker return rogue_regarray_cached(shader,
599*61046927SAndroid Build Coastguard Worker size,
600*61046927SAndroid Build Coastguard Worker ROGUE_REG_CLASS_SHARED,
601*61046927SAndroid Build Coastguard Worker start_index);
602*61046927SAndroid Build Coastguard Worker }
603*61046927SAndroid Build Coastguard Worker
604*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_ssa_vec_regarray(rogue_shader * shader,unsigned size,unsigned start_index,unsigned component)605*61046927SAndroid Build Coastguard Worker rogue_regarray *rogue_ssa_vec_regarray(rogue_shader *shader,
606*61046927SAndroid Build Coastguard Worker unsigned size,
607*61046927SAndroid Build Coastguard Worker unsigned start_index,
608*61046927SAndroid Build Coastguard Worker unsigned component)
609*61046927SAndroid Build Coastguard Worker {
610*61046927SAndroid Build Coastguard Worker return rogue_vec_regarray_cached(shader,
611*61046927SAndroid Build Coastguard Worker size,
612*61046927SAndroid Build Coastguard Worker ROGUE_REG_CLASS_SSA,
613*61046927SAndroid Build Coastguard Worker start_index,
614*61046927SAndroid Build Coastguard Worker component);
615*61046927SAndroid Build Coastguard Worker }
616*61046927SAndroid Build Coastguard Worker
617*61046927SAndroid Build Coastguard Worker /**
618*61046927SAndroid Build Coastguard Worker * \brief Allocates and initializes a new rogue_block object.
619*61046927SAndroid Build Coastguard Worker *
620*61046927SAndroid Build Coastguard Worker * \param[in] shader The shader that the new block belongs to.
621*61046927SAndroid Build Coastguard Worker * \param[in] label The (optional) block label.
622*61046927SAndroid Build Coastguard Worker * \return The new block.
623*61046927SAndroid Build Coastguard Worker */
624*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_block_create(rogue_shader * shader,const char * label)625*61046927SAndroid Build Coastguard Worker rogue_block *rogue_block_create(rogue_shader *shader, const char *label)
626*61046927SAndroid Build Coastguard Worker {
627*61046927SAndroid Build Coastguard Worker rogue_block *block = rzalloc_size(shader, sizeof(*block));
628*61046927SAndroid Build Coastguard Worker
629*61046927SAndroid Build Coastguard Worker block->shader = shader;
630*61046927SAndroid Build Coastguard Worker list_inithead(&block->instrs);
631*61046927SAndroid Build Coastguard Worker list_inithead(&block->uses);
632*61046927SAndroid Build Coastguard Worker block->index = shader->next_block++;
633*61046927SAndroid Build Coastguard Worker block->label = ralloc_strdup(block, label);
634*61046927SAndroid Build Coastguard Worker
635*61046927SAndroid Build Coastguard Worker return block;
636*61046927SAndroid Build Coastguard Worker }
637*61046927SAndroid Build Coastguard Worker
638*61046927SAndroid Build Coastguard Worker /**
639*61046927SAndroid Build Coastguard Worker * \brief Initialises a Rogue instruction.
640*61046927SAndroid Build Coastguard Worker *
641*61046927SAndroid Build Coastguard Worker * \param[in] instr The instruction to initialise.
642*61046927SAndroid Build Coastguard Worker * \param[in] type The instruction type.
643*61046927SAndroid Build Coastguard Worker * \param[in] block The block which will contain the instruction.
644*61046927SAndroid Build Coastguard Worker */
rogue_instr_init(rogue_instr * instr,enum rogue_instr_type type,rogue_block * block)645*61046927SAndroid Build Coastguard Worker static inline void rogue_instr_init(rogue_instr *instr,
646*61046927SAndroid Build Coastguard Worker enum rogue_instr_type type,
647*61046927SAndroid Build Coastguard Worker rogue_block *block)
648*61046927SAndroid Build Coastguard Worker {
649*61046927SAndroid Build Coastguard Worker instr->type = type;
650*61046927SAndroid Build Coastguard Worker instr->exec_cond = ROGUE_EXEC_COND_PE_TRUE;
651*61046927SAndroid Build Coastguard Worker instr->repeat = 1;
652*61046927SAndroid Build Coastguard Worker instr->index = block->shader->next_instr++;
653*61046927SAndroid Build Coastguard Worker instr->block = block;
654*61046927SAndroid Build Coastguard Worker }
655*61046927SAndroid Build Coastguard Worker
656*61046927SAndroid Build Coastguard Worker /**
657*61046927SAndroid Build Coastguard Worker * \brief Allocates and initializes a new rogue_alu_instr object.
658*61046927SAndroid Build Coastguard Worker *
659*61046927SAndroid Build Coastguard Worker * \param[in] block The block that the new ALU instruction belongs to.
660*61046927SAndroid Build Coastguard Worker * \param[in] op The ALU operation.
661*61046927SAndroid Build Coastguard Worker * \return The new ALU instruction.
662*61046927SAndroid Build Coastguard Worker */
663*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_alu_instr_create(rogue_block * block,enum rogue_alu_op op)664*61046927SAndroid Build Coastguard Worker rogue_alu_instr *rogue_alu_instr_create(rogue_block *block,
665*61046927SAndroid Build Coastguard Worker enum rogue_alu_op op)
666*61046927SAndroid Build Coastguard Worker {
667*61046927SAndroid Build Coastguard Worker rogue_alu_instr *alu = rzalloc_size(block, sizeof(*alu));
668*61046927SAndroid Build Coastguard Worker rogue_instr_init(&alu->instr, ROGUE_INSTR_TYPE_ALU, block);
669*61046927SAndroid Build Coastguard Worker alu->op = op;
670*61046927SAndroid Build Coastguard Worker
671*61046927SAndroid Build Coastguard Worker return alu;
672*61046927SAndroid Build Coastguard Worker }
673*61046927SAndroid Build Coastguard Worker
674*61046927SAndroid Build Coastguard Worker /**
675*61046927SAndroid Build Coastguard Worker * \brief Allocates and initializes a new rogue_backend_instr object.
676*61046927SAndroid Build Coastguard Worker *
677*61046927SAndroid Build Coastguard Worker * \param[in] block The block that the new backend instruction belongs to.
678*61046927SAndroid Build Coastguard Worker * \param[in] op The backend operation.
679*61046927SAndroid Build Coastguard Worker * \return The new backend instruction.
680*61046927SAndroid Build Coastguard Worker */
681*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_backend_instr_create(rogue_block * block,enum rogue_backend_op op)682*61046927SAndroid Build Coastguard Worker rogue_backend_instr *rogue_backend_instr_create(rogue_block *block,
683*61046927SAndroid Build Coastguard Worker enum rogue_backend_op op)
684*61046927SAndroid Build Coastguard Worker {
685*61046927SAndroid Build Coastguard Worker rogue_backend_instr *backend = rzalloc_size(block, sizeof(*backend));
686*61046927SAndroid Build Coastguard Worker rogue_instr_init(&backend->instr, ROGUE_INSTR_TYPE_BACKEND, block);
687*61046927SAndroid Build Coastguard Worker backend->op = op;
688*61046927SAndroid Build Coastguard Worker
689*61046927SAndroid Build Coastguard Worker return backend;
690*61046927SAndroid Build Coastguard Worker }
691*61046927SAndroid Build Coastguard Worker
692*61046927SAndroid Build Coastguard Worker /**
693*61046927SAndroid Build Coastguard Worker * \brief Allocates and initializes a new rogue_ctrl_instr object.
694*61046927SAndroid Build Coastguard Worker *
695*61046927SAndroid Build Coastguard Worker * \param[in] block The block that the new control instruction belongs to.
696*61046927SAndroid Build Coastguard Worker * \param[in] op The control operation.
697*61046927SAndroid Build Coastguard Worker * \return The new control instruction.
698*61046927SAndroid Build Coastguard Worker */
699*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_ctrl_instr_create(rogue_block * block,enum rogue_ctrl_op op)700*61046927SAndroid Build Coastguard Worker rogue_ctrl_instr *rogue_ctrl_instr_create(rogue_block *block,
701*61046927SAndroid Build Coastguard Worker enum rogue_ctrl_op op)
702*61046927SAndroid Build Coastguard Worker {
703*61046927SAndroid Build Coastguard Worker rogue_ctrl_instr *ctrl = rzalloc_size(block, sizeof(*ctrl));
704*61046927SAndroid Build Coastguard Worker rogue_instr_init(&ctrl->instr, ROGUE_INSTR_TYPE_CTRL, block);
705*61046927SAndroid Build Coastguard Worker ctrl->op = op;
706*61046927SAndroid Build Coastguard Worker
707*61046927SAndroid Build Coastguard Worker return ctrl;
708*61046927SAndroid Build Coastguard Worker }
709*61046927SAndroid Build Coastguard Worker
710*61046927SAndroid Build Coastguard Worker /**
711*61046927SAndroid Build Coastguard Worker * \brief Allocates and initializes a new rogue_bitwise_instr object.
712*61046927SAndroid Build Coastguard Worker *
713*61046927SAndroid Build Coastguard Worker * \param[in] block The block that the new bitwise instruction belongs to.
714*61046927SAndroid Build Coastguard Worker * \param[in] op The bitwise operation.
715*61046927SAndroid Build Coastguard Worker * \return The new bitwise instruction.
716*61046927SAndroid Build Coastguard Worker */
717*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_bitwise_instr_create(rogue_block * block,enum rogue_bitwise_op op)718*61046927SAndroid Build Coastguard Worker rogue_bitwise_instr *rogue_bitwise_instr_create(rogue_block *block,
719*61046927SAndroid Build Coastguard Worker enum rogue_bitwise_op op)
720*61046927SAndroid Build Coastguard Worker {
721*61046927SAndroid Build Coastguard Worker rogue_bitwise_instr *bitwise = rzalloc_size(block, sizeof(*bitwise));
722*61046927SAndroid Build Coastguard Worker rogue_instr_init(&bitwise->instr, ROGUE_INSTR_TYPE_BITWISE, block);
723*61046927SAndroid Build Coastguard Worker bitwise->op = op;
724*61046927SAndroid Build Coastguard Worker
725*61046927SAndroid Build Coastguard Worker return bitwise;
726*61046927SAndroid Build Coastguard Worker }
727*61046927SAndroid Build Coastguard Worker
728*61046927SAndroid Build Coastguard Worker /**
729*61046927SAndroid Build Coastguard Worker * \brief Tracks/links objects that are written to/modified by an instruction.
730*61046927SAndroid Build Coastguard Worker *
731*61046927SAndroid Build Coastguard Worker * \param[in] instr The instruction.
732*61046927SAndroid Build Coastguard Worker */
733*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_link_instr_write(rogue_instr * instr)734*61046927SAndroid Build Coastguard Worker void rogue_link_instr_write(rogue_instr *instr)
735*61046927SAndroid Build Coastguard Worker {
736*61046927SAndroid Build Coastguard Worker switch (instr->type) {
737*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_ALU: {
738*61046927SAndroid Build Coastguard Worker rogue_alu_instr *alu = rogue_instr_as_alu(instr);
739*61046927SAndroid Build Coastguard Worker const unsigned num_dsts = rogue_alu_op_infos[alu->op].num_dsts;
740*61046927SAndroid Build Coastguard Worker
741*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_dsts; ++i) {
742*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&alu->dst[i].ref)) {
743*61046927SAndroid Build Coastguard Worker rogue_reg_write *write = &alu->dst_write[i].reg;
744*61046927SAndroid Build Coastguard Worker rogue_reg *reg = alu->dst[i].ref.reg;
745*61046927SAndroid Build Coastguard Worker rogue_link_instr_write_reg(instr, write, reg, i);
746*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&alu->dst[i].ref)) {
747*61046927SAndroid Build Coastguard Worker rogue_regarray_write *write = &alu->dst_write[i].regarray;
748*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray = alu->dst[i].ref.regarray;
749*61046927SAndroid Build Coastguard Worker rogue_link_instr_write_regarray(instr, write, regarray, i);
750*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&alu->dst[i].ref)) { /* TODO: check WHICH IO
751*61046927SAndroid Build Coastguard Worker IT IS */
752*61046927SAndroid Build Coastguard Worker } else {
753*61046927SAndroid Build Coastguard Worker unreachable("Unsupported destination reference type.");
754*61046927SAndroid Build Coastguard Worker }
755*61046927SAndroid Build Coastguard Worker }
756*61046927SAndroid Build Coastguard Worker
757*61046927SAndroid Build Coastguard Worker break;
758*61046927SAndroid Build Coastguard Worker }
759*61046927SAndroid Build Coastguard Worker
760*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_BACKEND: {
761*61046927SAndroid Build Coastguard Worker rogue_backend_instr *backend = rogue_instr_as_backend(instr);
762*61046927SAndroid Build Coastguard Worker const unsigned num_dsts = rogue_backend_op_infos[backend->op].num_dsts;
763*61046927SAndroid Build Coastguard Worker
764*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_dsts; ++i) {
765*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&backend->dst[i].ref)) {
766*61046927SAndroid Build Coastguard Worker rogue_reg_write *write = &backend->dst_write[i].reg;
767*61046927SAndroid Build Coastguard Worker rogue_reg *reg = backend->dst[i].ref.reg;
768*61046927SAndroid Build Coastguard Worker rogue_link_instr_write_reg(instr, write, reg, i);
769*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&backend->dst[i].ref)) {
770*61046927SAndroid Build Coastguard Worker rogue_regarray_write *write = &backend->dst_write[i].regarray;
771*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray = backend->dst[i].ref.regarray;
772*61046927SAndroid Build Coastguard Worker rogue_link_instr_write_regarray(instr, write, regarray, i);
773*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&backend->dst[i].ref)) { /* TODO: check
774*61046927SAndroid Build Coastguard Worker WHICH IO IT IS
775*61046927SAndroid Build Coastguard Worker */
776*61046927SAndroid Build Coastguard Worker } else {
777*61046927SAndroid Build Coastguard Worker unreachable("Unsupported destination reference type.");
778*61046927SAndroid Build Coastguard Worker }
779*61046927SAndroid Build Coastguard Worker }
780*61046927SAndroid Build Coastguard Worker
781*61046927SAndroid Build Coastguard Worker break;
782*61046927SAndroid Build Coastguard Worker }
783*61046927SAndroid Build Coastguard Worker
784*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_CTRL: {
785*61046927SAndroid Build Coastguard Worker rogue_ctrl_instr *ctrl = rogue_instr_as_ctrl(instr);
786*61046927SAndroid Build Coastguard Worker const unsigned num_dsts = rogue_ctrl_op_infos[ctrl->op].num_dsts;
787*61046927SAndroid Build Coastguard Worker
788*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_dsts; ++i) {
789*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&ctrl->dst[i].ref)) {
790*61046927SAndroid Build Coastguard Worker rogue_reg_write *write = &ctrl->dst_write[i].reg;
791*61046927SAndroid Build Coastguard Worker rogue_reg *reg = ctrl->dst[i].ref.reg;
792*61046927SAndroid Build Coastguard Worker rogue_link_instr_write_reg(instr, write, reg, i);
793*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&ctrl->dst[i].ref)) {
794*61046927SAndroid Build Coastguard Worker rogue_regarray_write *write = &ctrl->dst_write[i].regarray;
795*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray = ctrl->dst[i].ref.regarray;
796*61046927SAndroid Build Coastguard Worker rogue_link_instr_write_regarray(instr, write, regarray, i);
797*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&ctrl->dst[i].ref)) { /* TODO: check WHICH
798*61046927SAndroid Build Coastguard Worker IO IT IS */
799*61046927SAndroid Build Coastguard Worker } else {
800*61046927SAndroid Build Coastguard Worker unreachable("Unsupported destination reference type.");
801*61046927SAndroid Build Coastguard Worker }
802*61046927SAndroid Build Coastguard Worker }
803*61046927SAndroid Build Coastguard Worker
804*61046927SAndroid Build Coastguard Worker break;
805*61046927SAndroid Build Coastguard Worker }
806*61046927SAndroid Build Coastguard Worker
807*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_BITWISE: {
808*61046927SAndroid Build Coastguard Worker rogue_bitwise_instr *bitwise = rogue_instr_as_bitwise(instr);
809*61046927SAndroid Build Coastguard Worker const unsigned num_dsts = rogue_bitwise_op_infos[bitwise->op].num_dsts;
810*61046927SAndroid Build Coastguard Worker
811*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_dsts; ++i) {
812*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&bitwise->dst[i].ref)) {
813*61046927SAndroid Build Coastguard Worker rogue_reg_write *write = &bitwise->dst_write[i].reg;
814*61046927SAndroid Build Coastguard Worker rogue_reg *reg = bitwise->dst[i].ref.reg;
815*61046927SAndroid Build Coastguard Worker rogue_link_instr_write_reg(instr, write, reg, i);
816*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&bitwise->dst[i].ref)) {
817*61046927SAndroid Build Coastguard Worker rogue_regarray_write *write = &bitwise->dst_write[i].regarray;
818*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray = bitwise->dst[i].ref.regarray;
819*61046927SAndroid Build Coastguard Worker rogue_link_instr_write_regarray(instr, write, regarray, i);
820*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&bitwise->dst[i].ref)) { /* TODO: check
821*61046927SAndroid Build Coastguard Worker WHICH IO IT IS
822*61046927SAndroid Build Coastguard Worker */
823*61046927SAndroid Build Coastguard Worker } else {
824*61046927SAndroid Build Coastguard Worker unreachable("Unsupported destination reference type.");
825*61046927SAndroid Build Coastguard Worker }
826*61046927SAndroid Build Coastguard Worker }
827*61046927SAndroid Build Coastguard Worker
828*61046927SAndroid Build Coastguard Worker break;
829*61046927SAndroid Build Coastguard Worker }
830*61046927SAndroid Build Coastguard Worker
831*61046927SAndroid Build Coastguard Worker default:
832*61046927SAndroid Build Coastguard Worker unreachable("Unsupported instruction type.");
833*61046927SAndroid Build Coastguard Worker }
834*61046927SAndroid Build Coastguard Worker }
835*61046927SAndroid Build Coastguard Worker
836*61046927SAndroid Build Coastguard Worker /**
837*61046927SAndroid Build Coastguard Worker * \brief Tracks/links objects that are used by/read from an instruction.
838*61046927SAndroid Build Coastguard Worker *
839*61046927SAndroid Build Coastguard Worker * \param[in] instr The instruction.
840*61046927SAndroid Build Coastguard Worker */
841*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_link_instr_use(rogue_instr * instr)842*61046927SAndroid Build Coastguard Worker void rogue_link_instr_use(rogue_instr *instr)
843*61046927SAndroid Build Coastguard Worker {
844*61046927SAndroid Build Coastguard Worker switch (instr->type) {
845*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_ALU: {
846*61046927SAndroid Build Coastguard Worker rogue_alu_instr *alu = rogue_instr_as_alu(instr);
847*61046927SAndroid Build Coastguard Worker const unsigned num_srcs = rogue_alu_op_infos[alu->op].num_srcs;
848*61046927SAndroid Build Coastguard Worker
849*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; ++i) {
850*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&alu->src[i].ref)) {
851*61046927SAndroid Build Coastguard Worker rogue_reg_use *use = &alu->src_use[i].reg;
852*61046927SAndroid Build Coastguard Worker rogue_reg *reg = alu->src[i].ref.reg;
853*61046927SAndroid Build Coastguard Worker rogue_link_instr_use_reg(instr, use, reg, i);
854*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&alu->src[i].ref)) {
855*61046927SAndroid Build Coastguard Worker rogue_regarray_use *use = &alu->src_use[i].regarray;
856*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray = alu->src[i].ref.regarray;
857*61046927SAndroid Build Coastguard Worker rogue_link_instr_use_regarray(instr, use, regarray, i);
858*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_imm(&alu->src[i].ref)) {
859*61046927SAndroid Build Coastguard Worker rogue_link_imm_use(instr->block->shader,
860*61046927SAndroid Build Coastguard Worker instr,
861*61046927SAndroid Build Coastguard Worker i,
862*61046927SAndroid Build Coastguard Worker rogue_ref_get_imm(&alu->src[i].ref));
863*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&alu->src[i].ref)) { /* TODO: check WHICH IO
864*61046927SAndroid Build Coastguard Worker IT IS */
865*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_val(&alu->src[i].ref)) {
866*61046927SAndroid Build Coastguard Worker } else {
867*61046927SAndroid Build Coastguard Worker unreachable("Unsupported source reference type.");
868*61046927SAndroid Build Coastguard Worker }
869*61046927SAndroid Build Coastguard Worker }
870*61046927SAndroid Build Coastguard Worker
871*61046927SAndroid Build Coastguard Worker break;
872*61046927SAndroid Build Coastguard Worker }
873*61046927SAndroid Build Coastguard Worker
874*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_BACKEND: {
875*61046927SAndroid Build Coastguard Worker rogue_backend_instr *backend = rogue_instr_as_backend(instr);
876*61046927SAndroid Build Coastguard Worker const unsigned num_srcs = rogue_backend_op_infos[backend->op].num_srcs;
877*61046927SAndroid Build Coastguard Worker
878*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; ++i) {
879*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&backend->src[i].ref)) {
880*61046927SAndroid Build Coastguard Worker rogue_reg_use *use = &backend->src_use[i].reg;
881*61046927SAndroid Build Coastguard Worker rogue_reg *reg = backend->src[i].ref.reg;
882*61046927SAndroid Build Coastguard Worker rogue_link_instr_use_reg(instr, use, reg, i);
883*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&backend->src[i].ref)) {
884*61046927SAndroid Build Coastguard Worker rogue_regarray_use *use = &backend->src_use[i].regarray;
885*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray = backend->src[i].ref.regarray;
886*61046927SAndroid Build Coastguard Worker rogue_link_instr_use_regarray(instr, use, regarray, i);
887*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_drc(&backend->src[i].ref)) {
888*61046927SAndroid Build Coastguard Worker rogue_link_drc_trxn(instr->block->shader,
889*61046927SAndroid Build Coastguard Worker instr,
890*61046927SAndroid Build Coastguard Worker rogue_ref_get_drc(&backend->src[i].ref));
891*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&backend->src[i].ref)) { /* TODO: check
892*61046927SAndroid Build Coastguard Worker WHICH IO IT IS
893*61046927SAndroid Build Coastguard Worker */
894*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_val(&backend->src[i].ref)) {
895*61046927SAndroid Build Coastguard Worker } else {
896*61046927SAndroid Build Coastguard Worker unreachable("Unsupported source reference type.");
897*61046927SAndroid Build Coastguard Worker }
898*61046927SAndroid Build Coastguard Worker }
899*61046927SAndroid Build Coastguard Worker
900*61046927SAndroid Build Coastguard Worker break;
901*61046927SAndroid Build Coastguard Worker }
902*61046927SAndroid Build Coastguard Worker
903*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_CTRL: {
904*61046927SAndroid Build Coastguard Worker rogue_ctrl_instr *ctrl = rogue_instr_as_ctrl(instr);
905*61046927SAndroid Build Coastguard Worker const unsigned num_srcs = rogue_ctrl_op_infos[ctrl->op].num_srcs;
906*61046927SAndroid Build Coastguard Worker
907*61046927SAndroid Build Coastguard Worker /* Branch instruction. */
908*61046927SAndroid Build Coastguard Worker if (!num_srcs && ctrl->target_block) {
909*61046927SAndroid Build Coastguard Worker rogue_link_instr_use_block(instr,
910*61046927SAndroid Build Coastguard Worker &ctrl->block_use,
911*61046927SAndroid Build Coastguard Worker ctrl->target_block);
912*61046927SAndroid Build Coastguard Worker break;
913*61046927SAndroid Build Coastguard Worker }
914*61046927SAndroid Build Coastguard Worker
915*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; ++i) {
916*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&ctrl->src[i].ref)) {
917*61046927SAndroid Build Coastguard Worker rogue_reg_use *use = &ctrl->src_use[i].reg;
918*61046927SAndroid Build Coastguard Worker rogue_reg *reg = ctrl->src[i].ref.reg;
919*61046927SAndroid Build Coastguard Worker rogue_link_instr_use_reg(instr, use, reg, i);
920*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&ctrl->src[i].ref)) {
921*61046927SAndroid Build Coastguard Worker rogue_regarray_use *use = &ctrl->src_use[i].regarray;
922*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray = ctrl->src[i].ref.regarray;
923*61046927SAndroid Build Coastguard Worker rogue_link_instr_use_regarray(instr, use, regarray, i);
924*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_drc(&ctrl->src[i].ref)) {
925*61046927SAndroid Build Coastguard Worker /* WDF instructions consume/release drcs, handled independently. */
926*61046927SAndroid Build Coastguard Worker if (ctrl->op != ROGUE_CTRL_OP_WDF)
927*61046927SAndroid Build Coastguard Worker rogue_link_drc_trxn(instr->block->shader,
928*61046927SAndroid Build Coastguard Worker instr,
929*61046927SAndroid Build Coastguard Worker rogue_ref_get_drc(&ctrl->src[i].ref));
930*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&ctrl->src[i].ref)) { /* TODO: check WHICH
931*61046927SAndroid Build Coastguard Worker IO IT IS */
932*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_val(&ctrl->src[i].ref)) {
933*61046927SAndroid Build Coastguard Worker } else {
934*61046927SAndroid Build Coastguard Worker unreachable("Unsupported source reference type.");
935*61046927SAndroid Build Coastguard Worker }
936*61046927SAndroid Build Coastguard Worker }
937*61046927SAndroid Build Coastguard Worker
938*61046927SAndroid Build Coastguard Worker break;
939*61046927SAndroid Build Coastguard Worker }
940*61046927SAndroid Build Coastguard Worker
941*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_BITWISE: {
942*61046927SAndroid Build Coastguard Worker rogue_bitwise_instr *bitwise = rogue_instr_as_bitwise(instr);
943*61046927SAndroid Build Coastguard Worker const unsigned num_srcs = rogue_bitwise_op_infos[bitwise->op].num_srcs;
944*61046927SAndroid Build Coastguard Worker
945*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; ++i) {
946*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&bitwise->src[i].ref)) {
947*61046927SAndroid Build Coastguard Worker rogue_reg_use *use = &bitwise->src_use[i].reg;
948*61046927SAndroid Build Coastguard Worker rogue_reg *reg = bitwise->src[i].ref.reg;
949*61046927SAndroid Build Coastguard Worker rogue_link_instr_use_reg(instr, use, reg, i);
950*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&bitwise->src[i].ref)) {
951*61046927SAndroid Build Coastguard Worker rogue_regarray_use *use = &bitwise->src_use[i].regarray;
952*61046927SAndroid Build Coastguard Worker rogue_regarray *regarray = bitwise->src[i].ref.regarray;
953*61046927SAndroid Build Coastguard Worker rogue_link_instr_use_regarray(instr, use, regarray, i);
954*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_drc(&bitwise->src[i].ref)) {
955*61046927SAndroid Build Coastguard Worker rogue_link_drc_trxn(instr->block->shader,
956*61046927SAndroid Build Coastguard Worker instr,
957*61046927SAndroid Build Coastguard Worker rogue_ref_get_drc(&bitwise->src[i].ref));
958*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&bitwise->src[i].ref)) { /* TODO: check
959*61046927SAndroid Build Coastguard Worker WHICH IO IT IS
960*61046927SAndroid Build Coastguard Worker */
961*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_val(&bitwise->src[i].ref)) {
962*61046927SAndroid Build Coastguard Worker } else {
963*61046927SAndroid Build Coastguard Worker unreachable("Unsupported source reference type.");
964*61046927SAndroid Build Coastguard Worker }
965*61046927SAndroid Build Coastguard Worker }
966*61046927SAndroid Build Coastguard Worker
967*61046927SAndroid Build Coastguard Worker break;
968*61046927SAndroid Build Coastguard Worker }
969*61046927SAndroid Build Coastguard Worker
970*61046927SAndroid Build Coastguard Worker default:
971*61046927SAndroid Build Coastguard Worker unreachable("Unsupported instruction type.");
972*61046927SAndroid Build Coastguard Worker }
973*61046927SAndroid Build Coastguard Worker }
974*61046927SAndroid Build Coastguard Worker
975*61046927SAndroid Build Coastguard Worker /**
976*61046927SAndroid Build Coastguard Worker * \brief Untracks/unlinks objects that are written to/modified by an
977*61046927SAndroid Build Coastguard Worker * instruction.
978*61046927SAndroid Build Coastguard Worker *
979*61046927SAndroid Build Coastguard Worker * \param[in] instr The instruction.
980*61046927SAndroid Build Coastguard Worker */
981*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_unlink_instr_write(rogue_instr * instr)982*61046927SAndroid Build Coastguard Worker void rogue_unlink_instr_write(rogue_instr *instr)
983*61046927SAndroid Build Coastguard Worker {
984*61046927SAndroid Build Coastguard Worker switch (instr->type) {
985*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_ALU: {
986*61046927SAndroid Build Coastguard Worker rogue_alu_instr *alu = rogue_instr_as_alu(instr);
987*61046927SAndroid Build Coastguard Worker const unsigned num_dsts = rogue_alu_op_infos[alu->op].num_dsts;
988*61046927SAndroid Build Coastguard Worker
989*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_dsts; ++i) {
990*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&alu->dst[i].ref)) {
991*61046927SAndroid Build Coastguard Worker rogue_reg_write *write = &alu->dst_write[i].reg;
992*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_write_reg(instr, write);
993*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&alu->dst[i].ref)) {
994*61046927SAndroid Build Coastguard Worker rogue_regarray_write *write = &alu->dst_write[i].regarray;
995*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_write_regarray(instr, write);
996*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&alu->dst[i].ref)) { /* TODO: check WHICH IO
997*61046927SAndroid Build Coastguard Worker IT IS */
998*61046927SAndroid Build Coastguard Worker } else {
999*61046927SAndroid Build Coastguard Worker unreachable("Unsupported destination reference type.");
1000*61046927SAndroid Build Coastguard Worker }
1001*61046927SAndroid Build Coastguard Worker }
1002*61046927SAndroid Build Coastguard Worker
1003*61046927SAndroid Build Coastguard Worker break;
1004*61046927SAndroid Build Coastguard Worker }
1005*61046927SAndroid Build Coastguard Worker
1006*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_BACKEND: {
1007*61046927SAndroid Build Coastguard Worker rogue_backend_instr *backend = rogue_instr_as_backend(instr);
1008*61046927SAndroid Build Coastguard Worker const unsigned num_dsts = rogue_backend_op_infos[backend->op].num_dsts;
1009*61046927SAndroid Build Coastguard Worker
1010*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_dsts; ++i) {
1011*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&backend->dst[i].ref)) {
1012*61046927SAndroid Build Coastguard Worker rogue_reg_write *write = &backend->dst_write[i].reg;
1013*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_write_reg(instr, write);
1014*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&backend->dst[i].ref)) {
1015*61046927SAndroid Build Coastguard Worker rogue_regarray_write *write = &backend->dst_write[i].regarray;
1016*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_write_regarray(instr, write);
1017*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&backend->dst[i].ref)) { /* TODO: check
1018*61046927SAndroid Build Coastguard Worker WHICH IO IT IS
1019*61046927SAndroid Build Coastguard Worker */
1020*61046927SAndroid Build Coastguard Worker } else {
1021*61046927SAndroid Build Coastguard Worker unreachable("Unsupported destination reference type.");
1022*61046927SAndroid Build Coastguard Worker }
1023*61046927SAndroid Build Coastguard Worker }
1024*61046927SAndroid Build Coastguard Worker
1025*61046927SAndroid Build Coastguard Worker break;
1026*61046927SAndroid Build Coastguard Worker }
1027*61046927SAndroid Build Coastguard Worker
1028*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_CTRL: {
1029*61046927SAndroid Build Coastguard Worker rogue_ctrl_instr *ctrl = rogue_instr_as_ctrl(instr);
1030*61046927SAndroid Build Coastguard Worker const unsigned num_dsts = rogue_ctrl_op_infos[ctrl->op].num_dsts;
1031*61046927SAndroid Build Coastguard Worker
1032*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_dsts; ++i) {
1033*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&ctrl->dst[i].ref)) {
1034*61046927SAndroid Build Coastguard Worker rogue_reg_write *write = &ctrl->dst_write[i].reg;
1035*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_write_reg(instr, write);
1036*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&ctrl->dst[i].ref)) {
1037*61046927SAndroid Build Coastguard Worker rogue_regarray_write *write = &ctrl->dst_write[i].regarray;
1038*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_write_regarray(instr, write);
1039*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&ctrl->dst[i].ref)) { /* TODO: check WHICH
1040*61046927SAndroid Build Coastguard Worker IO IT IS */
1041*61046927SAndroid Build Coastguard Worker } else {
1042*61046927SAndroid Build Coastguard Worker unreachable("Unsupported destination reference type.");
1043*61046927SAndroid Build Coastguard Worker }
1044*61046927SAndroid Build Coastguard Worker }
1045*61046927SAndroid Build Coastguard Worker
1046*61046927SAndroid Build Coastguard Worker break;
1047*61046927SAndroid Build Coastguard Worker }
1048*61046927SAndroid Build Coastguard Worker
1049*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_BITWISE: {
1050*61046927SAndroid Build Coastguard Worker rogue_bitwise_instr *bitwise = rogue_instr_as_bitwise(instr);
1051*61046927SAndroid Build Coastguard Worker const unsigned num_dsts = rogue_bitwise_op_infos[bitwise->op].num_dsts;
1052*61046927SAndroid Build Coastguard Worker
1053*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_dsts; ++i) {
1054*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&bitwise->dst[i].ref)) {
1055*61046927SAndroid Build Coastguard Worker rogue_reg_write *write = &bitwise->dst_write[i].reg;
1056*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_write_reg(instr, write);
1057*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&bitwise->dst[i].ref)) {
1058*61046927SAndroid Build Coastguard Worker rogue_regarray_write *write = &bitwise->dst_write[i].regarray;
1059*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_write_regarray(instr, write);
1060*61046927SAndroid Build Coastguard Worker } else {
1061*61046927SAndroid Build Coastguard Worker unreachable("Invalid destination reference type.");
1062*61046927SAndroid Build Coastguard Worker }
1063*61046927SAndroid Build Coastguard Worker }
1064*61046927SAndroid Build Coastguard Worker
1065*61046927SAndroid Build Coastguard Worker break;
1066*61046927SAndroid Build Coastguard Worker }
1067*61046927SAndroid Build Coastguard Worker
1068*61046927SAndroid Build Coastguard Worker default:
1069*61046927SAndroid Build Coastguard Worker unreachable("Unsupported instruction type.");
1070*61046927SAndroid Build Coastguard Worker }
1071*61046927SAndroid Build Coastguard Worker }
1072*61046927SAndroid Build Coastguard Worker
1073*61046927SAndroid Build Coastguard Worker /**
1074*61046927SAndroid Build Coastguard Worker * \brief Untracks/unlinks objects that are used by/read from an instruction.
1075*61046927SAndroid Build Coastguard Worker *
1076*61046927SAndroid Build Coastguard Worker * \param[in] instr The instruction.
1077*61046927SAndroid Build Coastguard Worker */
1078*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_unlink_instr_use(rogue_instr * instr)1079*61046927SAndroid Build Coastguard Worker void rogue_unlink_instr_use(rogue_instr *instr)
1080*61046927SAndroid Build Coastguard Worker {
1081*61046927SAndroid Build Coastguard Worker switch (instr->type) {
1082*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_ALU: {
1083*61046927SAndroid Build Coastguard Worker rogue_alu_instr *alu = rogue_instr_as_alu(instr);
1084*61046927SAndroid Build Coastguard Worker const unsigned num_srcs = rogue_alu_op_infos[alu->op].num_srcs;
1085*61046927SAndroid Build Coastguard Worker
1086*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; ++i) {
1087*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&alu->src[i].ref)) {
1088*61046927SAndroid Build Coastguard Worker rogue_reg_use *use = &alu->src_use[i].reg;
1089*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_use_reg(instr, use);
1090*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&alu->src[i].ref)) {
1091*61046927SAndroid Build Coastguard Worker rogue_regarray_use *use = &alu->src_use[i].regarray;
1092*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_use_regarray(instr, use);
1093*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_imm(&alu->src[i].ref)) {
1094*61046927SAndroid Build Coastguard Worker rogue_unlink_imm_use(instr,
1095*61046927SAndroid Build Coastguard Worker &rogue_ref_get_imm(&alu->src[i].ref)->use);
1096*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&alu->src[i].ref)) { /* TODO: check WHICH IO
1097*61046927SAndroid Build Coastguard Worker IT IS */
1098*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_val(&alu->src[i].ref)) {
1099*61046927SAndroid Build Coastguard Worker } else {
1100*61046927SAndroid Build Coastguard Worker unreachable("Unsupported source reference type.");
1101*61046927SAndroid Build Coastguard Worker }
1102*61046927SAndroid Build Coastguard Worker }
1103*61046927SAndroid Build Coastguard Worker
1104*61046927SAndroid Build Coastguard Worker break;
1105*61046927SAndroid Build Coastguard Worker }
1106*61046927SAndroid Build Coastguard Worker
1107*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_BACKEND: {
1108*61046927SAndroid Build Coastguard Worker rogue_backend_instr *backend = rogue_instr_as_backend(instr);
1109*61046927SAndroid Build Coastguard Worker const unsigned num_srcs = rogue_backend_op_infos[backend->op].num_srcs;
1110*61046927SAndroid Build Coastguard Worker
1111*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; ++i) {
1112*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&backend->src[i].ref)) {
1113*61046927SAndroid Build Coastguard Worker rogue_reg_use *use = &backend->src_use[i].reg;
1114*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_use_reg(instr, use);
1115*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&backend->src[i].ref)) {
1116*61046927SAndroid Build Coastguard Worker rogue_regarray_use *use = &backend->src_use[i].regarray;
1117*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_use_regarray(instr, use);
1118*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_drc(&backend->src[i].ref)) {
1119*61046927SAndroid Build Coastguard Worker rogue_unlink_drc_trxn(instr->block->shader,
1120*61046927SAndroid Build Coastguard Worker instr,
1121*61046927SAndroid Build Coastguard Worker rogue_ref_get_drc(&backend->src[i].ref));
1122*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&backend->src[i].ref)) { /* TODO: check
1123*61046927SAndroid Build Coastguard Worker WHICH IO IT IS
1124*61046927SAndroid Build Coastguard Worker */
1125*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_val(&backend->src[i].ref)) {
1126*61046927SAndroid Build Coastguard Worker } else {
1127*61046927SAndroid Build Coastguard Worker unreachable("Unsupported source reference type.");
1128*61046927SAndroid Build Coastguard Worker }
1129*61046927SAndroid Build Coastguard Worker }
1130*61046927SAndroid Build Coastguard Worker
1131*61046927SAndroid Build Coastguard Worker break;
1132*61046927SAndroid Build Coastguard Worker }
1133*61046927SAndroid Build Coastguard Worker
1134*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_CTRL: {
1135*61046927SAndroid Build Coastguard Worker rogue_ctrl_instr *ctrl = rogue_instr_as_ctrl(instr);
1136*61046927SAndroid Build Coastguard Worker const unsigned num_srcs = rogue_ctrl_op_infos[ctrl->op].num_srcs;
1137*61046927SAndroid Build Coastguard Worker
1138*61046927SAndroid Build Coastguard Worker /* Branch instruction. */
1139*61046927SAndroid Build Coastguard Worker if (!num_srcs && ctrl->target_block) {
1140*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_use_block(instr, &ctrl->block_use);
1141*61046927SAndroid Build Coastguard Worker break;
1142*61046927SAndroid Build Coastguard Worker }
1143*61046927SAndroid Build Coastguard Worker
1144*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; ++i) {
1145*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&ctrl->src[i].ref)) {
1146*61046927SAndroid Build Coastguard Worker rogue_reg_use *use = &ctrl->src_use[i].reg;
1147*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_use_reg(instr, use);
1148*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&ctrl->src[i].ref)) {
1149*61046927SAndroid Build Coastguard Worker rogue_regarray_use *use = &ctrl->src_use[i].regarray;
1150*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_use_regarray(instr, use);
1151*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_drc(&ctrl->src[i].ref)) {
1152*61046927SAndroid Build Coastguard Worker /* WDF instructions consume/release drcs, handled independently. */
1153*61046927SAndroid Build Coastguard Worker if (ctrl->op != ROGUE_CTRL_OP_WDF)
1154*61046927SAndroid Build Coastguard Worker rogue_unlink_drc_trxn(instr->block->shader,
1155*61046927SAndroid Build Coastguard Worker instr,
1156*61046927SAndroid Build Coastguard Worker rogue_ref_get_drc(&ctrl->src[i].ref));
1157*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&ctrl->src[i].ref)) { /* TODO: check WHICH
1158*61046927SAndroid Build Coastguard Worker IO IT IS */
1159*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_val(&ctrl->src[i].ref)) {
1160*61046927SAndroid Build Coastguard Worker } else {
1161*61046927SAndroid Build Coastguard Worker unreachable("Unsupported source reference type.");
1162*61046927SAndroid Build Coastguard Worker }
1163*61046927SAndroid Build Coastguard Worker }
1164*61046927SAndroid Build Coastguard Worker
1165*61046927SAndroid Build Coastguard Worker break;
1166*61046927SAndroid Build Coastguard Worker }
1167*61046927SAndroid Build Coastguard Worker
1168*61046927SAndroid Build Coastguard Worker case ROGUE_INSTR_TYPE_BITWISE: {
1169*61046927SAndroid Build Coastguard Worker rogue_bitwise_instr *bitwise = rogue_instr_as_bitwise(instr);
1170*61046927SAndroid Build Coastguard Worker const unsigned num_srcs = rogue_bitwise_op_infos[bitwise->op].num_srcs;
1171*61046927SAndroid Build Coastguard Worker
1172*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_srcs; ++i) {
1173*61046927SAndroid Build Coastguard Worker if (rogue_ref_is_reg(&bitwise->src[i].ref)) {
1174*61046927SAndroid Build Coastguard Worker rogue_reg_use *use = &bitwise->src_use[i].reg;
1175*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_use_reg(instr, use);
1176*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_regarray(&bitwise->src[i].ref)) {
1177*61046927SAndroid Build Coastguard Worker rogue_regarray_use *use = &bitwise->src_use[i].regarray;
1178*61046927SAndroid Build Coastguard Worker rogue_unlink_instr_use_regarray(instr, use);
1179*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_drc(&bitwise->src[i].ref)) {
1180*61046927SAndroid Build Coastguard Worker rogue_unlink_drc_trxn(instr->block->shader,
1181*61046927SAndroid Build Coastguard Worker instr,
1182*61046927SAndroid Build Coastguard Worker rogue_ref_get_drc(&bitwise->src[i].ref));
1183*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_io(&bitwise->src[i].ref)) { /* TODO: check
1184*61046927SAndroid Build Coastguard Worker WHICH IO IT IS
1185*61046927SAndroid Build Coastguard Worker */
1186*61046927SAndroid Build Coastguard Worker } else if (rogue_ref_is_val(&bitwise->src[i].ref)) {
1187*61046927SAndroid Build Coastguard Worker } else {
1188*61046927SAndroid Build Coastguard Worker unreachable("Unsupported source reference type.");
1189*61046927SAndroid Build Coastguard Worker }
1190*61046927SAndroid Build Coastguard Worker }
1191*61046927SAndroid Build Coastguard Worker
1192*61046927SAndroid Build Coastguard Worker break;
1193*61046927SAndroid Build Coastguard Worker }
1194*61046927SAndroid Build Coastguard Worker
1195*61046927SAndroid Build Coastguard Worker default:
1196*61046927SAndroid Build Coastguard Worker unreachable("Unsupported instruction type.");
1197*61046927SAndroid Build Coastguard Worker }
1198*61046927SAndroid Build Coastguard Worker }
1199*61046927SAndroid Build Coastguard Worker
rogue_compiler_destructor(UNUSED void * ptr)1200*61046927SAndroid Build Coastguard Worker static void rogue_compiler_destructor(UNUSED void *ptr)
1201*61046927SAndroid Build Coastguard Worker {
1202*61046927SAndroid Build Coastguard Worker glsl_type_singleton_decref();
1203*61046927SAndroid Build Coastguard Worker }
1204*61046927SAndroid Build Coastguard Worker
1205*61046927SAndroid Build Coastguard Worker /**
1206*61046927SAndroid Build Coastguard Worker * \brief Creates and sets up a Rogue compiler context.
1207*61046927SAndroid Build Coastguard Worker *
1208*61046927SAndroid Build Coastguard Worker * \param[in] dev_info Device info pointer.
1209*61046927SAndroid Build Coastguard Worker * \return A pointer to the new compiler context, or NULL on failure.
1210*61046927SAndroid Build Coastguard Worker */
1211*61046927SAndroid Build Coastguard Worker PUBLIC
rogue_compiler_create(const struct pvr_device_info * dev_info)1212*61046927SAndroid Build Coastguard Worker rogue_compiler *rogue_compiler_create(const struct pvr_device_info *dev_info)
1213*61046927SAndroid Build Coastguard Worker {
1214*61046927SAndroid Build Coastguard Worker rogue_compiler *compiler;
1215*61046927SAndroid Build Coastguard Worker
1216*61046927SAndroid Build Coastguard Worker rogue_debug_init();
1217*61046927SAndroid Build Coastguard Worker
1218*61046927SAndroid Build Coastguard Worker compiler = rzalloc_size(NULL, sizeof(*compiler));
1219*61046927SAndroid Build Coastguard Worker if (!compiler)
1220*61046927SAndroid Build Coastguard Worker return NULL;
1221*61046927SAndroid Build Coastguard Worker
1222*61046927SAndroid Build Coastguard Worker compiler->dev_info = dev_info;
1223*61046927SAndroid Build Coastguard Worker
1224*61046927SAndroid Build Coastguard Worker /* TODO: Additional compiler setup (e.g. number of internal registers, BRNs,
1225*61046927SAndroid Build Coastguard Worker * and other hw-specific info). */
1226*61046927SAndroid Build Coastguard Worker
1227*61046927SAndroid Build Coastguard Worker glsl_type_singleton_init_or_ref();
1228*61046927SAndroid Build Coastguard Worker
1229*61046927SAndroid Build Coastguard Worker ralloc_set_destructor(compiler, rogue_compiler_destructor);
1230*61046927SAndroid Build Coastguard Worker
1231*61046927SAndroid Build Coastguard Worker return compiler;
1232*61046927SAndroid Build Coastguard Worker }
1233*61046927SAndroid Build Coastguard Worker
1234*61046927SAndroid Build Coastguard Worker /**
1235*61046927SAndroid Build Coastguard Worker * \brief Creates and sets up a shared multi-stage build context.
1236*61046927SAndroid Build Coastguard Worker *
1237*61046927SAndroid Build Coastguard Worker * \param[in] compiler The compiler context.
1238*61046927SAndroid Build Coastguard Worker * \return A pointer to the new build context, or NULL on failure.
1239*61046927SAndroid Build Coastguard Worker */
1240*61046927SAndroid Build Coastguard Worker PUBLIC
1241*61046927SAndroid Build Coastguard Worker rogue_build_ctx *
rogue_build_context_create(rogue_compiler * compiler,struct pvr_pipeline_layout * pipeline_layout)1242*61046927SAndroid Build Coastguard Worker rogue_build_context_create(rogue_compiler *compiler,
1243*61046927SAndroid Build Coastguard Worker struct pvr_pipeline_layout *pipeline_layout)
1244*61046927SAndroid Build Coastguard Worker {
1245*61046927SAndroid Build Coastguard Worker rogue_build_ctx *ctx;
1246*61046927SAndroid Build Coastguard Worker
1247*61046927SAndroid Build Coastguard Worker ctx = rzalloc_size(NULL, sizeof(*ctx));
1248*61046927SAndroid Build Coastguard Worker if (!ctx)
1249*61046927SAndroid Build Coastguard Worker return NULL;
1250*61046927SAndroid Build Coastguard Worker
1251*61046927SAndroid Build Coastguard Worker ctx->compiler = compiler;
1252*61046927SAndroid Build Coastguard Worker ctx->pipeline_layout = pipeline_layout;
1253*61046927SAndroid Build Coastguard Worker
1254*61046927SAndroid Build Coastguard Worker /* nir/rogue/binary shaders need to be default-zeroed;
1255*61046927SAndroid Build Coastguard Worker * this is taken care of by rzalloc_size.
1256*61046927SAndroid Build Coastguard Worker */
1257*61046927SAndroid Build Coastguard Worker
1258*61046927SAndroid Build Coastguard Worker /* Setup non-zero defaults. */
1259*61046927SAndroid Build Coastguard Worker ctx->stage_data.fs.msaa_mode = ROGUE_MSAA_MODE_PIXEL;
1260*61046927SAndroid Build Coastguard Worker
1261*61046927SAndroid Build Coastguard Worker return ctx;
1262*61046927SAndroid Build Coastguard Worker }
1263