1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright (C) 2019-2020 Collabora, Ltd.
3*61046927SAndroid Build Coastguard Worker * Copyright (C) 2019 Alyssa Rosenzweig <[email protected]>
4*61046927SAndroid Build Coastguard Worker *
5*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
6*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
7*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
8*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
10*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
11*61046927SAndroid Build Coastguard Worker *
12*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
13*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
14*61046927SAndroid Build Coastguard Worker * Software.
15*61046927SAndroid Build Coastguard Worker *
16*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21*61046927SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*61046927SAndroid Build Coastguard Worker * SOFTWARE.
23*61046927SAndroid Build Coastguard Worker */
24*61046927SAndroid Build Coastguard Worker
25*61046927SAndroid Build Coastguard Worker #ifndef _MDG_COMPILER_H
26*61046927SAndroid Build Coastguard Worker #define _MDG_COMPILER_H
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker #include "helpers.h"
29*61046927SAndroid Build Coastguard Worker #include "midgard.h"
30*61046927SAndroid Build Coastguard Worker #include "midgard_compile.h"
31*61046927SAndroid Build Coastguard Worker #include "midgard_ops.h"
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
34*61046927SAndroid Build Coastguard Worker #include "util/list.h"
35*61046927SAndroid Build Coastguard Worker #include "util/set.h"
36*61046927SAndroid Build Coastguard Worker #include "util/u_dynarray.h"
37*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker #include "compiler/glsl_types.h"
40*61046927SAndroid Build Coastguard Worker #include "compiler/nir/nir.h"
41*61046927SAndroid Build Coastguard Worker #include "panfrost/util/lcra.h"
42*61046927SAndroid Build Coastguard Worker #include "panfrost/util/pan_ir.h"
43*61046927SAndroid Build Coastguard Worker
44*61046927SAndroid Build Coastguard Worker /* Forward declare */
45*61046927SAndroid Build Coastguard Worker struct midgard_block;
46*61046927SAndroid Build Coastguard Worker
47*61046927SAndroid Build Coastguard Worker /* Target types. Defaults to TARGET_GOTO (the type corresponding directly to
48*61046927SAndroid Build Coastguard Worker * the hardware), hence why that must be zero. TARGET_DISCARD signals this
49*61046927SAndroid Build Coastguard Worker * instruction is actually a discard op. */
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker #define TARGET_GOTO 0
52*61046927SAndroid Build Coastguard Worker #define TARGET_BREAK 1
53*61046927SAndroid Build Coastguard Worker #define TARGET_CONTINUE 2
54*61046927SAndroid Build Coastguard Worker #define TARGET_DISCARD 3
55*61046927SAndroid Build Coastguard Worker #define TARGET_TILEBUF_WAIT 4
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker typedef struct midgard_branch {
58*61046927SAndroid Build Coastguard Worker /* If conditional, the condition is specified in r31.w */
59*61046927SAndroid Build Coastguard Worker bool conditional;
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker /* For conditionals, if this is true, we branch on FALSE. If false, we branch
62*61046927SAndroid Build Coastguard Worker * on TRUE. */
63*61046927SAndroid Build Coastguard Worker bool invert_conditional;
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker /* Branch targets: the start of a block, the start of a loop (continue), the
66*61046927SAndroid Build Coastguard Worker * end of a loop (break). Value is one of TARGET_ */
67*61046927SAndroid Build Coastguard Worker unsigned target_type;
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker /* The actual target */
70*61046927SAndroid Build Coastguard Worker union {
71*61046927SAndroid Build Coastguard Worker int target_block;
72*61046927SAndroid Build Coastguard Worker int target_break;
73*61046927SAndroid Build Coastguard Worker int target_continue;
74*61046927SAndroid Build Coastguard Worker };
75*61046927SAndroid Build Coastguard Worker } midgard_branch;
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker /* Generic in-memory data type repesenting a single logical instruction, rather
78*61046927SAndroid Build Coastguard Worker * than a single instruction group. This is the preferred form for code gen.
79*61046927SAndroid Build Coastguard Worker * Multiple midgard_insturctions will later be combined during scheduling,
80*61046927SAndroid Build Coastguard Worker * though this is not represented in this structure. Its format bridges
81*61046927SAndroid Build Coastguard Worker * the low-level binary representation with the higher level semantic meaning.
82*61046927SAndroid Build Coastguard Worker *
83*61046927SAndroid Build Coastguard Worker * Notably, it allows registers to be specified as block local SSA, for code
84*61046927SAndroid Build Coastguard Worker * emitted before the register allocation pass.
85*61046927SAndroid Build Coastguard Worker */
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker #define MIR_SRC_COUNT 4
88*61046927SAndroid Build Coastguard Worker #define MIR_VEC_COMPONENTS 16
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard Worker typedef struct midgard_instruction {
91*61046927SAndroid Build Coastguard Worker /* Must be first for casting */
92*61046927SAndroid Build Coastguard Worker struct list_head link;
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker unsigned type; /* ALU, load/store, texture */
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker /* Instruction arguments represented as block-local SSA
97*61046927SAndroid Build Coastguard Worker * indices, rather than registers. ~0 means unused. */
98*61046927SAndroid Build Coastguard Worker unsigned src[MIR_SRC_COUNT];
99*61046927SAndroid Build Coastguard Worker unsigned dest;
100*61046927SAndroid Build Coastguard Worker
101*61046927SAndroid Build Coastguard Worker /* vec16 swizzle, unpacked, per source */
102*61046927SAndroid Build Coastguard Worker unsigned swizzle[MIR_SRC_COUNT][MIR_VEC_COMPONENTS];
103*61046927SAndroid Build Coastguard Worker
104*61046927SAndroid Build Coastguard Worker /* Types! */
105*61046927SAndroid Build Coastguard Worker nir_alu_type src_types[MIR_SRC_COUNT];
106*61046927SAndroid Build Coastguard Worker nir_alu_type dest_type;
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker /* Packing ops have non-32-bit dest types even though they functionally
109*61046927SAndroid Build Coastguard Worker * work at the 32-bit level, use this as a signal to disable copyprop.
110*61046927SAndroid Build Coastguard Worker * We maybe need synthetic pack ops instead. */
111*61046927SAndroid Build Coastguard Worker bool is_pack;
112*61046927SAndroid Build Coastguard Worker
113*61046927SAndroid Build Coastguard Worker /* Modifiers, depending on type */
114*61046927SAndroid Build Coastguard Worker union {
115*61046927SAndroid Build Coastguard Worker struct {
116*61046927SAndroid Build Coastguard Worker bool src_abs[MIR_SRC_COUNT];
117*61046927SAndroid Build Coastguard Worker bool src_neg[MIR_SRC_COUNT];
118*61046927SAndroid Build Coastguard Worker };
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker struct {
121*61046927SAndroid Build Coastguard Worker bool src_shift[MIR_SRC_COUNT];
122*61046927SAndroid Build Coastguard Worker };
123*61046927SAndroid Build Coastguard Worker };
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker /* Out of the union for csel (could maybe be fixed..) */
126*61046927SAndroid Build Coastguard Worker bool src_invert[MIR_SRC_COUNT];
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Worker /* If the op supports it */
129*61046927SAndroid Build Coastguard Worker enum midgard_roundmode roundmode;
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Worker /* For textures: should helpers execute this instruction (instead of
132*61046927SAndroid Build Coastguard Worker * just helping with derivatives)? Should helpers terminate after? */
133*61046927SAndroid Build Coastguard Worker bool helper_terminate;
134*61046927SAndroid Build Coastguard Worker bool helper_execute;
135*61046927SAndroid Build Coastguard Worker
136*61046927SAndroid Build Coastguard Worker /* I.e. (1 << alu_bit) */
137*61046927SAndroid Build Coastguard Worker int unit;
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker bool has_constants;
140*61046927SAndroid Build Coastguard Worker midgard_constants constants;
141*61046927SAndroid Build Coastguard Worker uint16_t inline_constant;
142*61046927SAndroid Build Coastguard Worker bool has_inline_constant;
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker bool compact_branch;
145*61046927SAndroid Build Coastguard Worker uint8_t writeout;
146*61046927SAndroid Build Coastguard Worker bool last_writeout;
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker /* Masks in a saneish format. One bit per channel, not packed fancy.
149*61046927SAndroid Build Coastguard Worker * Use this instead of the op specific ones, and switch over at emit
150*61046927SAndroid Build Coastguard Worker * time */
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker uint16_t mask;
153*61046927SAndroid Build Coastguard Worker
154*61046927SAndroid Build Coastguard Worker /* Hint for the register allocator not to spill the destination written
155*61046927SAndroid Build Coastguard Worker * from this instruction (because it is a spill/unspill node itself).
156*61046927SAndroid Build Coastguard Worker * Bitmask of spilled classes */
157*61046927SAndroid Build Coastguard Worker
158*61046927SAndroid Build Coastguard Worker unsigned no_spill;
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker /* Generic hint for intra-pass use */
161*61046927SAndroid Build Coastguard Worker bool hint;
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker /* During scheduling, the backwards dependency graph
164*61046927SAndroid Build Coastguard Worker * (DAG). nr_dependencies is the number of unscheduled
165*61046927SAndroid Build Coastguard Worker * instructions that must still be scheduled after
166*61046927SAndroid Build Coastguard Worker * (before) this instruction. dependents are which
167*61046927SAndroid Build Coastguard Worker * instructions need to be scheduled before (after) this
168*61046927SAndroid Build Coastguard Worker * instruction. */
169*61046927SAndroid Build Coastguard Worker
170*61046927SAndroid Build Coastguard Worker unsigned nr_dependencies;
171*61046927SAndroid Build Coastguard Worker BITSET_WORD *dependents;
172*61046927SAndroid Build Coastguard Worker
173*61046927SAndroid Build Coastguard Worker /* Use this in conjunction with `type` */
174*61046927SAndroid Build Coastguard Worker unsigned op;
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker /* This refers to midgard_outmod_float or midgard_outmod_int.
177*61046927SAndroid Build Coastguard Worker * In case of a ALU op, use midgard_is_integer_out_op() to know which
178*61046927SAndroid Build Coastguard Worker * one is used.
179*61046927SAndroid Build Coastguard Worker * If it's a texture op, it's always midgard_outmod_float. */
180*61046927SAndroid Build Coastguard Worker unsigned outmod;
181*61046927SAndroid Build Coastguard Worker
182*61046927SAndroid Build Coastguard Worker union {
183*61046927SAndroid Build Coastguard Worker midgard_load_store_word load_store;
184*61046927SAndroid Build Coastguard Worker midgard_texture_word texture;
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker midgard_branch branch;
187*61046927SAndroid Build Coastguard Worker };
188*61046927SAndroid Build Coastguard Worker
189*61046927SAndroid Build Coastguard Worker unsigned bundle_id;
190*61046927SAndroid Build Coastguard Worker } midgard_instruction;
191*61046927SAndroid Build Coastguard Worker
192*61046927SAndroid Build Coastguard Worker typedef struct midgard_block {
193*61046927SAndroid Build Coastguard Worker pan_block base;
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker bool scheduled;
196*61046927SAndroid Build Coastguard Worker
197*61046927SAndroid Build Coastguard Worker /* List of midgard_bundles emitted (after the scheduler has run) */
198*61046927SAndroid Build Coastguard Worker struct util_dynarray bundles;
199*61046927SAndroid Build Coastguard Worker
200*61046927SAndroid Build Coastguard Worker /* Number of quadwords _actually_ emitted, as determined after scheduling */
201*61046927SAndroid Build Coastguard Worker unsigned quadword_count;
202*61046927SAndroid Build Coastguard Worker
203*61046927SAndroid Build Coastguard Worker /* Indicates this is a fixed-function fragment epilogue block */
204*61046927SAndroid Build Coastguard Worker bool epilogue;
205*61046927SAndroid Build Coastguard Worker
206*61046927SAndroid Build Coastguard Worker /* Are helper invocations required by this block? */
207*61046927SAndroid Build Coastguard Worker bool helpers_in;
208*61046927SAndroid Build Coastguard Worker } midgard_block;
209*61046927SAndroid Build Coastguard Worker
210*61046927SAndroid Build Coastguard Worker typedef struct midgard_bundle {
211*61046927SAndroid Build Coastguard Worker /* Tag for the overall bundle */
212*61046927SAndroid Build Coastguard Worker int tag;
213*61046927SAndroid Build Coastguard Worker
214*61046927SAndroid Build Coastguard Worker /* Instructions contained by the bundle. instruction_count <= 6 (vmul,
215*61046927SAndroid Build Coastguard Worker * sadd, vadd, smul, vlut, branch) */
216*61046927SAndroid Build Coastguard Worker int instruction_count;
217*61046927SAndroid Build Coastguard Worker midgard_instruction *instructions[6];
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker /* Bundle-wide ALU configuration */
220*61046927SAndroid Build Coastguard Worker int padding;
221*61046927SAndroid Build Coastguard Worker int control;
222*61046927SAndroid Build Coastguard Worker bool has_embedded_constants;
223*61046927SAndroid Build Coastguard Worker midgard_constants constants;
224*61046927SAndroid Build Coastguard Worker bool last_writeout;
225*61046927SAndroid Build Coastguard Worker } midgard_bundle;
226*61046927SAndroid Build Coastguard Worker
227*61046927SAndroid Build Coastguard Worker enum midgard_rt_id {
228*61046927SAndroid Build Coastguard Worker MIDGARD_COLOR_RT0 = 0,
229*61046927SAndroid Build Coastguard Worker MIDGARD_COLOR_RT1,
230*61046927SAndroid Build Coastguard Worker MIDGARD_COLOR_RT2,
231*61046927SAndroid Build Coastguard Worker MIDGARD_COLOR_RT3,
232*61046927SAndroid Build Coastguard Worker MIDGARD_COLOR_RT4,
233*61046927SAndroid Build Coastguard Worker MIDGARD_COLOR_RT5,
234*61046927SAndroid Build Coastguard Worker MIDGARD_COLOR_RT6,
235*61046927SAndroid Build Coastguard Worker MIDGARD_COLOR_RT7,
236*61046927SAndroid Build Coastguard Worker MIDGARD_ZS_RT,
237*61046927SAndroid Build Coastguard Worker MIDGARD_NUM_RTS,
238*61046927SAndroid Build Coastguard Worker };
239*61046927SAndroid Build Coastguard Worker
240*61046927SAndroid Build Coastguard Worker #define MIDGARD_MAX_SAMPLE_ITER 16
241*61046927SAndroid Build Coastguard Worker
242*61046927SAndroid Build Coastguard Worker typedef struct compiler_context {
243*61046927SAndroid Build Coastguard Worker const struct panfrost_compile_inputs *inputs;
244*61046927SAndroid Build Coastguard Worker nir_shader *nir;
245*61046927SAndroid Build Coastguard Worker struct pan_shader_info *info;
246*61046927SAndroid Build Coastguard Worker gl_shader_stage stage;
247*61046927SAndroid Build Coastguard Worker
248*61046927SAndroid Build Coastguard Worker /* Index to precolour to r0 for an input blend colour */
249*61046927SAndroid Build Coastguard Worker unsigned blend_input;
250*61046927SAndroid Build Coastguard Worker
251*61046927SAndroid Build Coastguard Worker /* Index to precolour to r2 for a dual-source blend colour */
252*61046927SAndroid Build Coastguard Worker unsigned blend_src1;
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker /* Count of spills and fills for shaderdb */
255*61046927SAndroid Build Coastguard Worker unsigned spills;
256*61046927SAndroid Build Coastguard Worker unsigned fills;
257*61046927SAndroid Build Coastguard Worker
258*61046927SAndroid Build Coastguard Worker /* Current NIR function */
259*61046927SAndroid Build Coastguard Worker nir_function *func;
260*61046927SAndroid Build Coastguard Worker
261*61046927SAndroid Build Coastguard Worker /* Allocated compiler temporary counter */
262*61046927SAndroid Build Coastguard Worker unsigned temp_alloc;
263*61046927SAndroid Build Coastguard Worker
264*61046927SAndroid Build Coastguard Worker /* Unordered list of midgard_blocks */
265*61046927SAndroid Build Coastguard Worker int block_count;
266*61046927SAndroid Build Coastguard Worker struct list_head blocks;
267*61046927SAndroid Build Coastguard Worker
268*61046927SAndroid Build Coastguard Worker /* TODO merge with block_count? */
269*61046927SAndroid Build Coastguard Worker unsigned block_source_count;
270*61046927SAndroid Build Coastguard Worker
271*61046927SAndroid Build Coastguard Worker /* List of midgard_instructions emitted for the current block */
272*61046927SAndroid Build Coastguard Worker midgard_block *current_block;
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker /* If there is a preset after block, use this, otherwise emit_block will
275*61046927SAndroid Build Coastguard Worker * create one if NULL */
276*61046927SAndroid Build Coastguard Worker midgard_block *after_block;
277*61046927SAndroid Build Coastguard Worker
278*61046927SAndroid Build Coastguard Worker /* The current "depth" of the loop, for disambiguating breaks/continues
279*61046927SAndroid Build Coastguard Worker * when using nested loops */
280*61046927SAndroid Build Coastguard Worker int current_loop_depth;
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker /* Total number of loops for shader-db */
283*61046927SAndroid Build Coastguard Worker unsigned loop_count;
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker /* Constants which have been loaded, for later inlining */
286*61046927SAndroid Build Coastguard Worker struct hash_table_u64 *ssa_constants;
287*61046927SAndroid Build Coastguard Worker
288*61046927SAndroid Build Coastguard Worker int temp_count;
289*61046927SAndroid Build Coastguard Worker int max_hash;
290*61046927SAndroid Build Coastguard Worker
291*61046927SAndroid Build Coastguard Worker /* Count of instructions emitted from NIR overall, across all blocks */
292*61046927SAndroid Build Coastguard Worker int instruction_count;
293*61046927SAndroid Build Coastguard Worker
294*61046927SAndroid Build Coastguard Worker unsigned quadword_count;
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker /* Bitmask of valid metadata */
297*61046927SAndroid Build Coastguard Worker unsigned metadata;
298*61046927SAndroid Build Coastguard Worker
299*61046927SAndroid Build Coastguard Worker /* Model-specific quirk set */
300*61046927SAndroid Build Coastguard Worker uint32_t quirks;
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker /* Writeout instructions for each render target */
303*61046927SAndroid Build Coastguard Worker midgard_instruction
304*61046927SAndroid Build Coastguard Worker *writeout_branch[MIDGARD_NUM_RTS][MIDGARD_MAX_SAMPLE_ITER];
305*61046927SAndroid Build Coastguard Worker
306*61046927SAndroid Build Coastguard Worker /* Mask of UBOs that need to be uploaded */
307*61046927SAndroid Build Coastguard Worker uint32_t ubo_mask;
308*61046927SAndroid Build Coastguard Worker } compiler_context;
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker /* Per-block live_in/live_out */
311*61046927SAndroid Build Coastguard Worker #define MIDGARD_METADATA_LIVENESS (1 << 0)
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker /* Helpers for manipulating the above structures (forming the driver IR) */
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker /* Append instruction to end of current block */
316*61046927SAndroid Build Coastguard Worker
317*61046927SAndroid Build Coastguard Worker static inline midgard_instruction *
mir_upload_ins(struct compiler_context * ctx,struct midgard_instruction ins)318*61046927SAndroid Build Coastguard Worker mir_upload_ins(struct compiler_context *ctx, struct midgard_instruction ins)
319*61046927SAndroid Build Coastguard Worker {
320*61046927SAndroid Build Coastguard Worker midgard_instruction *heap = ralloc(ctx, struct midgard_instruction);
321*61046927SAndroid Build Coastguard Worker memcpy(heap, &ins, sizeof(ins));
322*61046927SAndroid Build Coastguard Worker return heap;
323*61046927SAndroid Build Coastguard Worker }
324*61046927SAndroid Build Coastguard Worker
325*61046927SAndroid Build Coastguard Worker static inline midgard_instruction *
emit_mir_instruction(struct compiler_context * ctx,struct midgard_instruction ins)326*61046927SAndroid Build Coastguard Worker emit_mir_instruction(struct compiler_context *ctx,
327*61046927SAndroid Build Coastguard Worker struct midgard_instruction ins)
328*61046927SAndroid Build Coastguard Worker {
329*61046927SAndroid Build Coastguard Worker midgard_instruction *u = mir_upload_ins(ctx, ins);
330*61046927SAndroid Build Coastguard Worker list_addtail(&u->link, &ctx->current_block->base.instructions);
331*61046927SAndroid Build Coastguard Worker return u;
332*61046927SAndroid Build Coastguard Worker }
333*61046927SAndroid Build Coastguard Worker
334*61046927SAndroid Build Coastguard Worker static inline struct midgard_instruction *
mir_insert_instruction_before(struct compiler_context * ctx,struct midgard_instruction * tag,struct midgard_instruction ins)335*61046927SAndroid Build Coastguard Worker mir_insert_instruction_before(struct compiler_context *ctx,
336*61046927SAndroid Build Coastguard Worker struct midgard_instruction *tag,
337*61046927SAndroid Build Coastguard Worker struct midgard_instruction ins)
338*61046927SAndroid Build Coastguard Worker {
339*61046927SAndroid Build Coastguard Worker struct midgard_instruction *u = mir_upload_ins(ctx, ins);
340*61046927SAndroid Build Coastguard Worker list_addtail(&u->link, &tag->link);
341*61046927SAndroid Build Coastguard Worker return u;
342*61046927SAndroid Build Coastguard Worker }
343*61046927SAndroid Build Coastguard Worker
344*61046927SAndroid Build Coastguard Worker static inline void
mir_remove_instruction(struct midgard_instruction * ins)345*61046927SAndroid Build Coastguard Worker mir_remove_instruction(struct midgard_instruction *ins)
346*61046927SAndroid Build Coastguard Worker {
347*61046927SAndroid Build Coastguard Worker list_del(&ins->link);
348*61046927SAndroid Build Coastguard Worker }
349*61046927SAndroid Build Coastguard Worker
350*61046927SAndroid Build Coastguard Worker static inline midgard_instruction *
mir_prev_op(struct midgard_instruction * ins)351*61046927SAndroid Build Coastguard Worker mir_prev_op(struct midgard_instruction *ins)
352*61046927SAndroid Build Coastguard Worker {
353*61046927SAndroid Build Coastguard Worker return list_last_entry(&(ins->link), midgard_instruction, link);
354*61046927SAndroid Build Coastguard Worker }
355*61046927SAndroid Build Coastguard Worker
356*61046927SAndroid Build Coastguard Worker static inline midgard_instruction *
mir_next_op(struct midgard_instruction * ins)357*61046927SAndroid Build Coastguard Worker mir_next_op(struct midgard_instruction *ins)
358*61046927SAndroid Build Coastguard Worker {
359*61046927SAndroid Build Coastguard Worker return list_first_entry(&(ins->link), midgard_instruction, link);
360*61046927SAndroid Build Coastguard Worker }
361*61046927SAndroid Build Coastguard Worker
362*61046927SAndroid Build Coastguard Worker #define mir_foreach_block(ctx, v) \
363*61046927SAndroid Build Coastguard Worker list_for_each_entry(pan_block, v, &ctx->blocks, link)
364*61046927SAndroid Build Coastguard Worker
365*61046927SAndroid Build Coastguard Worker #define mir_foreach_block_from(ctx, from, v) \
366*61046927SAndroid Build Coastguard Worker list_for_each_entry_from(pan_block, v, &from->base, &ctx->blocks, link)
367*61046927SAndroid Build Coastguard Worker
368*61046927SAndroid Build Coastguard Worker #define mir_foreach_instr_in_block(block, v) \
369*61046927SAndroid Build Coastguard Worker list_for_each_entry(struct midgard_instruction, v, \
370*61046927SAndroid Build Coastguard Worker &block->base.instructions, link)
371*61046927SAndroid Build Coastguard Worker #define mir_foreach_instr_in_block_rev(block, v) \
372*61046927SAndroid Build Coastguard Worker list_for_each_entry_rev(struct midgard_instruction, v, \
373*61046927SAndroid Build Coastguard Worker &block->base.instructions, link)
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker #define mir_foreach_instr_in_block_safe(block, v) \
376*61046927SAndroid Build Coastguard Worker list_for_each_entry_safe(struct midgard_instruction, v, \
377*61046927SAndroid Build Coastguard Worker &block->base.instructions, link)
378*61046927SAndroid Build Coastguard Worker
379*61046927SAndroid Build Coastguard Worker #define mir_foreach_instr_in_block_safe_rev(block, v) \
380*61046927SAndroid Build Coastguard Worker list_for_each_entry_safe_rev(struct midgard_instruction, v, \
381*61046927SAndroid Build Coastguard Worker &block->base.instructions, link)
382*61046927SAndroid Build Coastguard Worker
383*61046927SAndroid Build Coastguard Worker #define mir_foreach_instr_in_block_from(block, v, from) \
384*61046927SAndroid Build Coastguard Worker list_for_each_entry_from(struct midgard_instruction, v, from, \
385*61046927SAndroid Build Coastguard Worker &block->base.instructions, link)
386*61046927SAndroid Build Coastguard Worker
387*61046927SAndroid Build Coastguard Worker #define mir_foreach_instr_in_block_from_rev(block, v, from) \
388*61046927SAndroid Build Coastguard Worker list_for_each_entry_from_rev(struct midgard_instruction, v, from, \
389*61046927SAndroid Build Coastguard Worker &block->base.instructions, link)
390*61046927SAndroid Build Coastguard Worker
391*61046927SAndroid Build Coastguard Worker #define mir_foreach_bundle_in_block(block, v) \
392*61046927SAndroid Build Coastguard Worker util_dynarray_foreach(&block->bundles, midgard_bundle, v)
393*61046927SAndroid Build Coastguard Worker
394*61046927SAndroid Build Coastguard Worker #define mir_foreach_bundle_in_block_rev(block, v) \
395*61046927SAndroid Build Coastguard Worker util_dynarray_foreach_reverse(&block->bundles, midgard_bundle, v)
396*61046927SAndroid Build Coastguard Worker
397*61046927SAndroid Build Coastguard Worker #define mir_foreach_instr_in_block_scheduled_rev(block, v) \
398*61046927SAndroid Build Coastguard Worker midgard_instruction *v; \
399*61046927SAndroid Build Coastguard Worker signed i = 0; \
400*61046927SAndroid Build Coastguard Worker mir_foreach_bundle_in_block_rev(block, _bundle) \
401*61046927SAndroid Build Coastguard Worker for (i = (_bundle->instruction_count - 1), v = _bundle->instructions[i]; \
402*61046927SAndroid Build Coastguard Worker i >= 0; --i, v = (i >= 0) ? _bundle->instructions[i] : NULL)
403*61046927SAndroid Build Coastguard Worker
404*61046927SAndroid Build Coastguard Worker #define mir_foreach_instr_global(ctx, v) \
405*61046927SAndroid Build Coastguard Worker mir_foreach_block(ctx, v_block) \
406*61046927SAndroid Build Coastguard Worker mir_foreach_instr_in_block(((midgard_block *)v_block), v)
407*61046927SAndroid Build Coastguard Worker
408*61046927SAndroid Build Coastguard Worker #define mir_foreach_instr_global_safe(ctx, v) \
409*61046927SAndroid Build Coastguard Worker mir_foreach_block(ctx, v_block) \
410*61046927SAndroid Build Coastguard Worker mir_foreach_instr_in_block_safe(((midgard_block *)v_block), v)
411*61046927SAndroid Build Coastguard Worker
412*61046927SAndroid Build Coastguard Worker /* Based on set_foreach, expanded with automatic type casts */
413*61046927SAndroid Build Coastguard Worker
414*61046927SAndroid Build Coastguard Worker #define mir_foreach_predecessor(blk, v) \
415*61046927SAndroid Build Coastguard Worker struct set_entry *_entry_##v; \
416*61046927SAndroid Build Coastguard Worker struct midgard_block *v; \
417*61046927SAndroid Build Coastguard Worker for (_entry_##v = _mesa_set_next_entry(blk->base.predecessors, NULL), \
418*61046927SAndroid Build Coastguard Worker v = (struct midgard_block *)(_entry_##v ? _entry_##v->key : NULL); \
419*61046927SAndroid Build Coastguard Worker _entry_##v != NULL; \
420*61046927SAndroid Build Coastguard Worker _entry_##v = _mesa_set_next_entry(blk->base.predecessors, _entry_##v), \
421*61046927SAndroid Build Coastguard Worker v = (struct midgard_block *)(_entry_##v ? _entry_##v->key : NULL))
422*61046927SAndroid Build Coastguard Worker
423*61046927SAndroid Build Coastguard Worker #define mir_foreach_src(ins, v) \
424*61046927SAndroid Build Coastguard Worker for (unsigned v = 0; v < ARRAY_SIZE(ins->src); ++v)
425*61046927SAndroid Build Coastguard Worker
426*61046927SAndroid Build Coastguard Worker static inline midgard_instruction *
mir_last_in_block(struct midgard_block * block)427*61046927SAndroid Build Coastguard Worker mir_last_in_block(struct midgard_block *block)
428*61046927SAndroid Build Coastguard Worker {
429*61046927SAndroid Build Coastguard Worker return list_last_entry(&block->base.instructions, struct midgard_instruction,
430*61046927SAndroid Build Coastguard Worker link);
431*61046927SAndroid Build Coastguard Worker }
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker static inline midgard_block *
mir_get_block(compiler_context * ctx,int idx)434*61046927SAndroid Build Coastguard Worker mir_get_block(compiler_context *ctx, int idx)
435*61046927SAndroid Build Coastguard Worker {
436*61046927SAndroid Build Coastguard Worker struct list_head *lst = &ctx->blocks;
437*61046927SAndroid Build Coastguard Worker
438*61046927SAndroid Build Coastguard Worker while ((idx--) + 1)
439*61046927SAndroid Build Coastguard Worker lst = lst->next;
440*61046927SAndroid Build Coastguard Worker
441*61046927SAndroid Build Coastguard Worker return (struct midgard_block *)lst;
442*61046927SAndroid Build Coastguard Worker }
443*61046927SAndroid Build Coastguard Worker
444*61046927SAndroid Build Coastguard Worker static inline bool
mir_is_alu_bundle(midgard_bundle * bundle)445*61046927SAndroid Build Coastguard Worker mir_is_alu_bundle(midgard_bundle *bundle)
446*61046927SAndroid Build Coastguard Worker {
447*61046927SAndroid Build Coastguard Worker return IS_ALU(bundle->tag);
448*61046927SAndroid Build Coastguard Worker }
449*61046927SAndroid Build Coastguard Worker
450*61046927SAndroid Build Coastguard Worker static inline unsigned
make_compiler_temp(compiler_context * ctx)451*61046927SAndroid Build Coastguard Worker make_compiler_temp(compiler_context *ctx)
452*61046927SAndroid Build Coastguard Worker {
453*61046927SAndroid Build Coastguard Worker return (ctx->func->impl->ssa_alloc + ctx->temp_alloc++) << 1;
454*61046927SAndroid Build Coastguard Worker }
455*61046927SAndroid Build Coastguard Worker
456*61046927SAndroid Build Coastguard Worker static inline unsigned
make_compiler_temp_reg(compiler_context * ctx)457*61046927SAndroid Build Coastguard Worker make_compiler_temp_reg(compiler_context *ctx)
458*61046927SAndroid Build Coastguard Worker {
459*61046927SAndroid Build Coastguard Worker return ((ctx->func->impl->ssa_alloc + ctx->temp_alloc++) << 1) | PAN_IS_REG;
460*61046927SAndroid Build Coastguard Worker }
461*61046927SAndroid Build Coastguard Worker
462*61046927SAndroid Build Coastguard Worker static inline bool
mir_is_ssa(unsigned index)463*61046927SAndroid Build Coastguard Worker mir_is_ssa(unsigned index)
464*61046927SAndroid Build Coastguard Worker {
465*61046927SAndroid Build Coastguard Worker return (index < SSA_FIXED_MINIMUM) && !(index & PAN_IS_REG);
466*61046927SAndroid Build Coastguard Worker }
467*61046927SAndroid Build Coastguard Worker
468*61046927SAndroid Build Coastguard Worker static inline unsigned
nir_ssa_index(nir_def * ssa)469*61046927SAndroid Build Coastguard Worker nir_ssa_index(nir_def *ssa)
470*61046927SAndroid Build Coastguard Worker {
471*61046927SAndroid Build Coastguard Worker return (ssa->index << 1) | 0;
472*61046927SAndroid Build Coastguard Worker }
473*61046927SAndroid Build Coastguard Worker
474*61046927SAndroid Build Coastguard Worker static inline unsigned
nir_reg_index(nir_def * handle)475*61046927SAndroid Build Coastguard Worker nir_reg_index(nir_def *handle)
476*61046927SAndroid Build Coastguard Worker {
477*61046927SAndroid Build Coastguard Worker return (handle->index << 1) | PAN_IS_REG;
478*61046927SAndroid Build Coastguard Worker }
479*61046927SAndroid Build Coastguard Worker
480*61046927SAndroid Build Coastguard Worker static inline unsigned
nir_src_index(compiler_context * ctx,nir_src * src)481*61046927SAndroid Build Coastguard Worker nir_src_index(compiler_context *ctx, nir_src *src)
482*61046927SAndroid Build Coastguard Worker {
483*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *load = nir_load_reg_for_def(src->ssa);
484*61046927SAndroid Build Coastguard Worker
485*61046927SAndroid Build Coastguard Worker if (load)
486*61046927SAndroid Build Coastguard Worker return nir_reg_index(load->src[0].ssa);
487*61046927SAndroid Build Coastguard Worker else
488*61046927SAndroid Build Coastguard Worker return nir_ssa_index(src->ssa);
489*61046927SAndroid Build Coastguard Worker }
490*61046927SAndroid Build Coastguard Worker
491*61046927SAndroid Build Coastguard Worker static inline unsigned
nir_def_index_with_mask(nir_def * def,uint16_t * write_mask)492*61046927SAndroid Build Coastguard Worker nir_def_index_with_mask(nir_def *def, uint16_t *write_mask)
493*61046927SAndroid Build Coastguard Worker {
494*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *store = nir_store_reg_for_def(def);
495*61046927SAndroid Build Coastguard Worker
496*61046927SAndroid Build Coastguard Worker if (store) {
497*61046927SAndroid Build Coastguard Worker *write_mask = nir_intrinsic_write_mask(store);
498*61046927SAndroid Build Coastguard Worker return nir_reg_index(store->src[1].ssa);
499*61046927SAndroid Build Coastguard Worker } else {
500*61046927SAndroid Build Coastguard Worker *write_mask = (uint16_t)BITFIELD_MASK(def->num_components);
501*61046927SAndroid Build Coastguard Worker return nir_ssa_index(def);
502*61046927SAndroid Build Coastguard Worker }
503*61046927SAndroid Build Coastguard Worker }
504*61046927SAndroid Build Coastguard Worker
505*61046927SAndroid Build Coastguard Worker static inline unsigned
nir_def_index(nir_def * def)506*61046927SAndroid Build Coastguard Worker nir_def_index(nir_def *def)
507*61046927SAndroid Build Coastguard Worker {
508*61046927SAndroid Build Coastguard Worker uint16_t write_mask = 0;
509*61046927SAndroid Build Coastguard Worker return nir_def_index_with_mask(def, &write_mask);
510*61046927SAndroid Build Coastguard Worker }
511*61046927SAndroid Build Coastguard Worker
512*61046927SAndroid Build Coastguard Worker /* MIR manipulation */
513*61046927SAndroid Build Coastguard Worker
514*61046927SAndroid Build Coastguard Worker void mir_rewrite_index(compiler_context *ctx, unsigned old, unsigned new);
515*61046927SAndroid Build Coastguard Worker void mir_rewrite_index_src(compiler_context *ctx, unsigned old, unsigned new);
516*61046927SAndroid Build Coastguard Worker void mir_rewrite_index_dst(compiler_context *ctx, unsigned old, unsigned new);
517*61046927SAndroid Build Coastguard Worker void mir_rewrite_index_dst_single(midgard_instruction *ins, unsigned old,
518*61046927SAndroid Build Coastguard Worker unsigned new);
519*61046927SAndroid Build Coastguard Worker void mir_rewrite_index_src_single(midgard_instruction *ins, unsigned old,
520*61046927SAndroid Build Coastguard Worker unsigned new);
521*61046927SAndroid Build Coastguard Worker void mir_rewrite_index_src_swizzle(compiler_context *ctx, unsigned old,
522*61046927SAndroid Build Coastguard Worker unsigned new, unsigned *swizzle);
523*61046927SAndroid Build Coastguard Worker bool mir_single_use(compiler_context *ctx, unsigned value);
524*61046927SAndroid Build Coastguard Worker unsigned mir_use_count(compiler_context *ctx, unsigned value);
525*61046927SAndroid Build Coastguard Worker uint16_t mir_bytemask_of_read_components(midgard_instruction *ins,
526*61046927SAndroid Build Coastguard Worker unsigned node);
527*61046927SAndroid Build Coastguard Worker uint16_t mir_bytemask_of_read_components_index(midgard_instruction *ins,
528*61046927SAndroid Build Coastguard Worker unsigned i);
529*61046927SAndroid Build Coastguard Worker uint16_t mir_from_bytemask(uint16_t bytemask, unsigned bits);
530*61046927SAndroid Build Coastguard Worker uint16_t mir_bytemask(midgard_instruction *ins);
531*61046927SAndroid Build Coastguard Worker uint16_t mir_round_bytemask_up(uint16_t mask, unsigned bits);
532*61046927SAndroid Build Coastguard Worker void mir_set_bytemask(midgard_instruction *ins, uint16_t bytemask);
533*61046927SAndroid Build Coastguard Worker signed mir_upper_override(midgard_instruction *ins, unsigned inst_size);
534*61046927SAndroid Build Coastguard Worker unsigned mir_components_for_type(nir_alu_type T);
535*61046927SAndroid Build Coastguard Worker unsigned max_bitsize_for_alu(midgard_instruction *ins);
536*61046927SAndroid Build Coastguard Worker midgard_reg_mode reg_mode_for_bitsize(unsigned bitsize);
537*61046927SAndroid Build Coastguard Worker
538*61046927SAndroid Build Coastguard Worker /* MIR printing */
539*61046927SAndroid Build Coastguard Worker
540*61046927SAndroid Build Coastguard Worker void mir_print_instruction(midgard_instruction *ins);
541*61046927SAndroid Build Coastguard Worker void mir_print_bundle(midgard_bundle *ctx);
542*61046927SAndroid Build Coastguard Worker void mir_print_block(midgard_block *block);
543*61046927SAndroid Build Coastguard Worker void mir_print_shader(compiler_context *ctx);
544*61046927SAndroid Build Coastguard Worker bool mir_nontrivial_mod(midgard_instruction *ins, unsigned i,
545*61046927SAndroid Build Coastguard Worker bool check_swizzle);
546*61046927SAndroid Build Coastguard Worker bool mir_nontrivial_outmod(midgard_instruction *ins);
547*61046927SAndroid Build Coastguard Worker
548*61046927SAndroid Build Coastguard Worker midgard_instruction *mir_insert_instruction_before_scheduled(
549*61046927SAndroid Build Coastguard Worker compiler_context *ctx, midgard_block *block, midgard_instruction *tag,
550*61046927SAndroid Build Coastguard Worker midgard_instruction ins);
551*61046927SAndroid Build Coastguard Worker midgard_instruction *mir_insert_instruction_after_scheduled(
552*61046927SAndroid Build Coastguard Worker compiler_context *ctx, midgard_block *block, midgard_instruction *tag,
553*61046927SAndroid Build Coastguard Worker midgard_instruction ins);
554*61046927SAndroid Build Coastguard Worker void mir_flip(midgard_instruction *ins);
555*61046927SAndroid Build Coastguard Worker void mir_compute_temp_count(compiler_context *ctx);
556*61046927SAndroid Build Coastguard Worker
557*61046927SAndroid Build Coastguard Worker #define LDST_GLOBAL (REGISTER_LDST_ZERO << 2)
558*61046927SAndroid Build Coastguard Worker #define LDST_SHARED ((REGISTER_LDST_LOCAL_STORAGE_PTR << 2) | COMPONENT_Z)
559*61046927SAndroid Build Coastguard Worker #define LDST_SCRATCH ((REGISTER_LDST_PC_SP << 2) | COMPONENT_Z)
560*61046927SAndroid Build Coastguard Worker
561*61046927SAndroid Build Coastguard Worker void mir_set_offset(compiler_context *ctx, midgard_instruction *ins,
562*61046927SAndroid Build Coastguard Worker nir_src *offset, unsigned seg);
563*61046927SAndroid Build Coastguard Worker void mir_set_ubo_offset(midgard_instruction *ins, nir_src *src, unsigned bias);
564*61046927SAndroid Build Coastguard Worker
565*61046927SAndroid Build Coastguard Worker /* 'Intrinsic' move for aliasing */
566*61046927SAndroid Build Coastguard Worker
567*61046927SAndroid Build Coastguard Worker static inline midgard_instruction
v_mov(unsigned src,unsigned dest)568*61046927SAndroid Build Coastguard Worker v_mov(unsigned src, unsigned dest)
569*61046927SAndroid Build Coastguard Worker {
570*61046927SAndroid Build Coastguard Worker midgard_instruction ins = {
571*61046927SAndroid Build Coastguard Worker .type = TAG_ALU_4,
572*61046927SAndroid Build Coastguard Worker .mask = 0xF,
573*61046927SAndroid Build Coastguard Worker .src = {~0, src, ~0, ~0},
574*61046927SAndroid Build Coastguard Worker .src_types = {0, nir_type_uint32},
575*61046927SAndroid Build Coastguard Worker .swizzle = SWIZZLE_IDENTITY,
576*61046927SAndroid Build Coastguard Worker .dest = dest,
577*61046927SAndroid Build Coastguard Worker .dest_type = nir_type_uint32,
578*61046927SAndroid Build Coastguard Worker .op = midgard_alu_op_imov,
579*61046927SAndroid Build Coastguard Worker .outmod = midgard_outmod_keeplo,
580*61046927SAndroid Build Coastguard Worker };
581*61046927SAndroid Build Coastguard Worker
582*61046927SAndroid Build Coastguard Worker return ins;
583*61046927SAndroid Build Coastguard Worker }
584*61046927SAndroid Build Coastguard Worker
585*61046927SAndroid Build Coastguard Worker /* Broad types of register classes so we can handle special
586*61046927SAndroid Build Coastguard Worker * registers */
587*61046927SAndroid Build Coastguard Worker
588*61046927SAndroid Build Coastguard Worker #define REG_CLASS_WORK 0
589*61046927SAndroid Build Coastguard Worker #define REG_CLASS_LDST 1
590*61046927SAndroid Build Coastguard Worker #define REG_CLASS_TEXR 3
591*61046927SAndroid Build Coastguard Worker #define REG_CLASS_TEXW 4
592*61046927SAndroid Build Coastguard Worker
593*61046927SAndroid Build Coastguard Worker /* Like a move, but to thread local storage! */
594*61046927SAndroid Build Coastguard Worker
595*61046927SAndroid Build Coastguard Worker static inline midgard_instruction
v_load_store_scratch(unsigned srcdest,unsigned index,bool is_store,unsigned mask)596*61046927SAndroid Build Coastguard Worker v_load_store_scratch(unsigned srcdest, unsigned index, bool is_store,
597*61046927SAndroid Build Coastguard Worker unsigned mask)
598*61046927SAndroid Build Coastguard Worker {
599*61046927SAndroid Build Coastguard Worker /* We index by 32-bit vec4s */
600*61046927SAndroid Build Coastguard Worker unsigned byte = (index * 4 * 4);
601*61046927SAndroid Build Coastguard Worker
602*61046927SAndroid Build Coastguard Worker midgard_instruction ins = {
603*61046927SAndroid Build Coastguard Worker .type = TAG_LOAD_STORE_4,
604*61046927SAndroid Build Coastguard Worker .mask = mask,
605*61046927SAndroid Build Coastguard Worker .dest_type = nir_type_uint32,
606*61046927SAndroid Build Coastguard Worker .dest = ~0,
607*61046927SAndroid Build Coastguard Worker .src = {~0, ~0, ~0, ~0},
608*61046927SAndroid Build Coastguard Worker .swizzle = SWIZZLE_IDENTITY_4,
609*61046927SAndroid Build Coastguard Worker .op = is_store ? midgard_op_st_128 : midgard_op_ld_128,
610*61046927SAndroid Build Coastguard Worker .load_store =
611*61046927SAndroid Build Coastguard Worker {
612*61046927SAndroid Build Coastguard Worker /* For register spilling - to thread local storage */
613*61046927SAndroid Build Coastguard Worker .arg_reg = REGISTER_LDST_LOCAL_STORAGE_PTR,
614*61046927SAndroid Build Coastguard Worker .arg_comp = COMPONENT_X,
615*61046927SAndroid Build Coastguard Worker .bitsize_toggle = true,
616*61046927SAndroid Build Coastguard Worker .index_format = midgard_index_address_u32,
617*61046927SAndroid Build Coastguard Worker .index_reg = REGISTER_LDST_ZERO,
618*61046927SAndroid Build Coastguard Worker },
619*61046927SAndroid Build Coastguard Worker
620*61046927SAndroid Build Coastguard Worker /* If we spill an unspill, RA goes into an infinite loop */
621*61046927SAndroid Build Coastguard Worker .no_spill = (1 << REG_CLASS_WORK),
622*61046927SAndroid Build Coastguard Worker };
623*61046927SAndroid Build Coastguard Worker
624*61046927SAndroid Build Coastguard Worker ins.constants.u32[0] = byte;
625*61046927SAndroid Build Coastguard Worker
626*61046927SAndroid Build Coastguard Worker if (is_store) {
627*61046927SAndroid Build Coastguard Worker ins.src[0] = srcdest;
628*61046927SAndroid Build Coastguard Worker ins.src_types[0] = nir_type_uint32;
629*61046927SAndroid Build Coastguard Worker
630*61046927SAndroid Build Coastguard Worker /* Ensure we are tightly swizzled so liveness analysis is
631*61046927SAndroid Build Coastguard Worker * correct */
632*61046927SAndroid Build Coastguard Worker
633*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < 4; ++i) {
634*61046927SAndroid Build Coastguard Worker if (!(mask & (1 << i)))
635*61046927SAndroid Build Coastguard Worker ins.swizzle[0][i] = COMPONENT_X;
636*61046927SAndroid Build Coastguard Worker }
637*61046927SAndroid Build Coastguard Worker } else
638*61046927SAndroid Build Coastguard Worker ins.dest = srcdest;
639*61046927SAndroid Build Coastguard Worker
640*61046927SAndroid Build Coastguard Worker return ins;
641*61046927SAndroid Build Coastguard Worker }
642*61046927SAndroid Build Coastguard Worker
643*61046927SAndroid Build Coastguard Worker static inline bool
mir_has_arg(midgard_instruction * ins,unsigned arg)644*61046927SAndroid Build Coastguard Worker mir_has_arg(midgard_instruction *ins, unsigned arg)
645*61046927SAndroid Build Coastguard Worker {
646*61046927SAndroid Build Coastguard Worker if (!ins)
647*61046927SAndroid Build Coastguard Worker return false;
648*61046927SAndroid Build Coastguard Worker
649*61046927SAndroid Build Coastguard Worker mir_foreach_src(ins, i) {
650*61046927SAndroid Build Coastguard Worker if (ins->src[i] == arg)
651*61046927SAndroid Build Coastguard Worker return true;
652*61046927SAndroid Build Coastguard Worker }
653*61046927SAndroid Build Coastguard Worker
654*61046927SAndroid Build Coastguard Worker return false;
655*61046927SAndroid Build Coastguard Worker }
656*61046927SAndroid Build Coastguard Worker
657*61046927SAndroid Build Coastguard Worker /* Scheduling */
658*61046927SAndroid Build Coastguard Worker
659*61046927SAndroid Build Coastguard Worker void midgard_schedule_program(compiler_context *ctx);
660*61046927SAndroid Build Coastguard Worker
661*61046927SAndroid Build Coastguard Worker void mir_ra(compiler_context *ctx);
662*61046927SAndroid Build Coastguard Worker void mir_squeeze_index(compiler_context *ctx);
663*61046927SAndroid Build Coastguard Worker void mir_lower_special_reads(compiler_context *ctx);
664*61046927SAndroid Build Coastguard Worker void mir_liveness_ins_update(uint16_t *live, midgard_instruction *ins,
665*61046927SAndroid Build Coastguard Worker unsigned max);
666*61046927SAndroid Build Coastguard Worker void mir_compute_liveness(compiler_context *ctx);
667*61046927SAndroid Build Coastguard Worker void mir_invalidate_liveness(compiler_context *ctx);
668*61046927SAndroid Build Coastguard Worker bool mir_is_live_after(compiler_context *ctx, midgard_block *block,
669*61046927SAndroid Build Coastguard Worker midgard_instruction *start, int src);
670*61046927SAndroid Build Coastguard Worker
671*61046927SAndroid Build Coastguard Worker void mir_create_pipeline_registers(compiler_context *ctx);
672*61046927SAndroid Build Coastguard Worker void midgard_promote_uniforms(compiler_context *ctx);
673*61046927SAndroid Build Coastguard Worker
674*61046927SAndroid Build Coastguard Worker void midgard_emit_derivatives(compiler_context *ctx,
675*61046927SAndroid Build Coastguard Worker nir_intrinsic_instr *instr);
676*61046927SAndroid Build Coastguard Worker
677*61046927SAndroid Build Coastguard Worker void midgard_lower_derivatives(compiler_context *ctx, midgard_block *block);
678*61046927SAndroid Build Coastguard Worker
679*61046927SAndroid Build Coastguard Worker bool mir_op_computes_derivatives(gl_shader_stage stage, unsigned op);
680*61046927SAndroid Build Coastguard Worker
681*61046927SAndroid Build Coastguard Worker void mir_analyze_helper_terminate(compiler_context *ctx);
682*61046927SAndroid Build Coastguard Worker void mir_analyze_helper_requirements(compiler_context *ctx);
683*61046927SAndroid Build Coastguard Worker
684*61046927SAndroid Build Coastguard Worker /* Final emission */
685*61046927SAndroid Build Coastguard Worker
686*61046927SAndroid Build Coastguard Worker void emit_binary_bundle(compiler_context *ctx, midgard_block *block,
687*61046927SAndroid Build Coastguard Worker midgard_bundle *bundle, struct util_dynarray *emission,
688*61046927SAndroid Build Coastguard Worker int next_tag);
689*61046927SAndroid Build Coastguard Worker
690*61046927SAndroid Build Coastguard Worker bool nir_fuse_io_16(nir_shader *shader);
691*61046927SAndroid Build Coastguard Worker
692*61046927SAndroid Build Coastguard Worker bool midgard_nir_lod_errata(nir_shader *shader);
693*61046927SAndroid Build Coastguard Worker
694*61046927SAndroid Build Coastguard Worker unsigned midgard_get_first_tag_from_block(compiler_context *ctx,
695*61046927SAndroid Build Coastguard Worker unsigned block_idx);
696*61046927SAndroid Build Coastguard Worker
697*61046927SAndroid Build Coastguard Worker /* Optimizations */
698*61046927SAndroid Build Coastguard Worker
699*61046927SAndroid Build Coastguard Worker bool midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block);
700*61046927SAndroid Build Coastguard Worker bool midgard_opt_prop(compiler_context *ctx);
701*61046927SAndroid Build Coastguard Worker bool midgard_opt_combine_projection(compiler_context *ctx,
702*61046927SAndroid Build Coastguard Worker midgard_block *block);
703*61046927SAndroid Build Coastguard Worker bool midgard_opt_varying_projection(compiler_context *ctx,
704*61046927SAndroid Build Coastguard Worker midgard_block *block);
705*61046927SAndroid Build Coastguard Worker bool midgard_opt_dead_code_eliminate(compiler_context *ctx);
706*61046927SAndroid Build Coastguard Worker bool midgard_opt_dead_move_eliminate(compiler_context *ctx,
707*61046927SAndroid Build Coastguard Worker midgard_block *block);
708*61046927SAndroid Build Coastguard Worker
709*61046927SAndroid Build Coastguard Worker #endif
710