1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (c) 2017 Lima Project
3bf215546Sopenharmony_ci * Copyright (c) 2013 Connor Abbott
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy
6bf215546Sopenharmony_ci * of this software and associated documentation files (the "Software"), to deal
7bf215546Sopenharmony_ci * in the Software without restriction, including without limitation the rights
8bf215546Sopenharmony_ci * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9bf215546Sopenharmony_ci * copies of the Software, and to permit persons to whom the Software is
10bf215546Sopenharmony_ci * furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
13bf215546Sopenharmony_ci * all copies or substantial portions of the Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18bf215546Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21bf215546Sopenharmony_ci * THE SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci#ifndef LIMA_IR_GP_GPIR_H
26bf215546Sopenharmony_ci#define LIMA_IR_GP_GPIR_H
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "util/list.h"
29bf215546Sopenharmony_ci#include "util/u_math.h"
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci#include "ir/lima_ir.h"
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci/* list of operations that a node can do. */
34bf215546Sopenharmony_citypedef enum {
35bf215546Sopenharmony_ci   gpir_op_unsupported = 0,
36bf215546Sopenharmony_ci   gpir_op_mov,
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci   /* mul ops */
39bf215546Sopenharmony_ci   gpir_op_mul,
40bf215546Sopenharmony_ci   gpir_op_select,
41bf215546Sopenharmony_ci   gpir_op_complex1,
42bf215546Sopenharmony_ci   gpir_op_complex2,
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_ci   /* add ops */
45bf215546Sopenharmony_ci   gpir_op_add,
46bf215546Sopenharmony_ci   gpir_op_floor,
47bf215546Sopenharmony_ci   gpir_op_sign,
48bf215546Sopenharmony_ci   gpir_op_ge,
49bf215546Sopenharmony_ci   gpir_op_lt,
50bf215546Sopenharmony_ci   gpir_op_min,
51bf215546Sopenharmony_ci   gpir_op_max,
52bf215546Sopenharmony_ci   gpir_op_abs,
53bf215546Sopenharmony_ci   gpir_op_not,
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   /* mul/add ops */
56bf215546Sopenharmony_ci   gpir_op_neg,
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci   /* passthrough ops */
59bf215546Sopenharmony_ci   gpir_op_clamp_const,
60bf215546Sopenharmony_ci   gpir_op_preexp2,
61bf215546Sopenharmony_ci   gpir_op_postlog2,
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci   /* complex ops */
64bf215546Sopenharmony_ci   gpir_op_exp2_impl,
65bf215546Sopenharmony_ci   gpir_op_log2_impl,
66bf215546Sopenharmony_ci   gpir_op_rcp_impl,
67bf215546Sopenharmony_ci   gpir_op_rsqrt_impl,
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_ci   /* load/store ops */
70bf215546Sopenharmony_ci   gpir_op_load_uniform,
71bf215546Sopenharmony_ci   gpir_op_load_temp,
72bf215546Sopenharmony_ci   gpir_op_load_attribute,
73bf215546Sopenharmony_ci   gpir_op_load_reg,
74bf215546Sopenharmony_ci   gpir_op_store_temp,
75bf215546Sopenharmony_ci   gpir_op_store_reg,
76bf215546Sopenharmony_ci   gpir_op_store_varying,
77bf215546Sopenharmony_ci   gpir_op_store_temp_load_off0,
78bf215546Sopenharmony_ci   gpir_op_store_temp_load_off1,
79bf215546Sopenharmony_ci   gpir_op_store_temp_load_off2,
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci   /* branch */
82bf215546Sopenharmony_ci   gpir_op_branch_cond,
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci   /* const (emulated) */
85bf215546Sopenharmony_ci   gpir_op_const,
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci   /* emulated ops */
88bf215546Sopenharmony_ci   gpir_op_exp2,
89bf215546Sopenharmony_ci   gpir_op_log2,
90bf215546Sopenharmony_ci   gpir_op_rcp,
91bf215546Sopenharmony_ci   gpir_op_rsqrt,
92bf215546Sopenharmony_ci   gpir_op_ceil,
93bf215546Sopenharmony_ci   gpir_op_exp,
94bf215546Sopenharmony_ci   gpir_op_log,
95bf215546Sopenharmony_ci   gpir_op_sin,
96bf215546Sopenharmony_ci   gpir_op_cos,
97bf215546Sopenharmony_ci   gpir_op_tan,
98bf215546Sopenharmony_ci   gpir_op_branch_uncond,
99bf215546Sopenharmony_ci   gpir_op_eq,
100bf215546Sopenharmony_ci   gpir_op_ne,
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci   /* auxiliary ops */
103bf215546Sopenharmony_ci   gpir_op_dummy_f,
104bf215546Sopenharmony_ci   gpir_op_dummy_m,
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   gpir_op_num,
107bf215546Sopenharmony_ci} gpir_op;
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_citypedef enum {
110bf215546Sopenharmony_ci   gpir_node_type_alu,
111bf215546Sopenharmony_ci   gpir_node_type_const,
112bf215546Sopenharmony_ci   gpir_node_type_load,
113bf215546Sopenharmony_ci   gpir_node_type_store,
114bf215546Sopenharmony_ci   gpir_node_type_branch,
115bf215546Sopenharmony_ci} gpir_node_type;
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_citypedef struct {
118bf215546Sopenharmony_ci   char *name;
119bf215546Sopenharmony_ci   bool dest_neg;
120bf215546Sopenharmony_ci   bool src_neg[4];
121bf215546Sopenharmony_ci   int *slots;
122bf215546Sopenharmony_ci   gpir_node_type type;
123bf215546Sopenharmony_ci   bool spillless;
124bf215546Sopenharmony_ci   bool schedule_first;
125bf215546Sopenharmony_ci   bool may_consume_two_slots;
126bf215546Sopenharmony_ci} gpir_op_info;
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ciextern const gpir_op_info gpir_op_infos[];
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_citypedef struct {
131bf215546Sopenharmony_ci   enum {
132bf215546Sopenharmony_ci      GPIR_DEP_INPUT,     /* def is the input of use */
133bf215546Sopenharmony_ci      GPIR_DEP_OFFSET,    /* def is the offset of use (i.e. temp store) */
134bf215546Sopenharmony_ci      GPIR_DEP_READ_AFTER_WRITE,
135bf215546Sopenharmony_ci      GPIR_DEP_WRITE_AFTER_READ,
136bf215546Sopenharmony_ci   } type;
137bf215546Sopenharmony_ci
138bf215546Sopenharmony_ci   /* node execute before succ */
139bf215546Sopenharmony_ci   struct gpir_node *pred;
140bf215546Sopenharmony_ci   /* node execute after pred */
141bf215546Sopenharmony_ci   struct gpir_node *succ;
142bf215546Sopenharmony_ci
143bf215546Sopenharmony_ci   /* for node pred_list */
144bf215546Sopenharmony_ci   struct list_head pred_link;
145bf215546Sopenharmony_ci   /* for ndoe succ_list */
146bf215546Sopenharmony_ci   struct list_head succ_link;
147bf215546Sopenharmony_ci} gpir_dep;
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_cistruct gpir_instr;
150bf215546Sopenharmony_cistruct gpir_store_node;
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_citypedef struct gpir_node {
153bf215546Sopenharmony_ci   struct list_head list;
154bf215546Sopenharmony_ci   gpir_op op;
155bf215546Sopenharmony_ci   gpir_node_type type;
156bf215546Sopenharmony_ci   int index;
157bf215546Sopenharmony_ci   char name[16];
158bf215546Sopenharmony_ci   bool printed;
159bf215546Sopenharmony_ci   struct gpir_block *block;
160bf215546Sopenharmony_ci
161bf215546Sopenharmony_ci   /* for nodes relationship */
162bf215546Sopenharmony_ci   /* for node who uses this node (successor) */
163bf215546Sopenharmony_ci   struct list_head succ_list;
164bf215546Sopenharmony_ci   /* for node this node uses (predecessor) */
165bf215546Sopenharmony_ci   struct list_head pred_list;
166bf215546Sopenharmony_ci
167bf215546Sopenharmony_ci   /* for scheduler and regalloc */
168bf215546Sopenharmony_ci   int value_reg;
169bf215546Sopenharmony_ci   union {
170bf215546Sopenharmony_ci      struct {
171bf215546Sopenharmony_ci         struct gpir_instr *instr;
172bf215546Sopenharmony_ci         struct gpir_store_node *physreg_store;
173bf215546Sopenharmony_ci         int pos;
174bf215546Sopenharmony_ci         int dist;
175bf215546Sopenharmony_ci         int index;
176bf215546Sopenharmony_ci         bool ready;
177bf215546Sopenharmony_ci         bool inserted;
178bf215546Sopenharmony_ci         bool max_node, next_max_node;
179bf215546Sopenharmony_ci         bool complex_allowed;
180bf215546Sopenharmony_ci      } sched;
181bf215546Sopenharmony_ci      struct {
182bf215546Sopenharmony_ci         int parent_index;
183bf215546Sopenharmony_ci         float reg_pressure;
184bf215546Sopenharmony_ci         int est;
185bf215546Sopenharmony_ci         bool scheduled;
186bf215546Sopenharmony_ci      } rsched;
187bf215546Sopenharmony_ci      struct {
188bf215546Sopenharmony_ci         float index;
189bf215546Sopenharmony_ci         struct gpir_node *last;
190bf215546Sopenharmony_ci      } vreg;
191bf215546Sopenharmony_ci      struct {
192bf215546Sopenharmony_ci         int index;
193bf215546Sopenharmony_ci      } preg;
194bf215546Sopenharmony_ci   };
195bf215546Sopenharmony_ci} gpir_node;
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_citypedef struct {
198bf215546Sopenharmony_ci   gpir_node node;
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci   gpir_node *children[3];
201bf215546Sopenharmony_ci   bool children_negate[3];
202bf215546Sopenharmony_ci   int num_child;
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci   bool dest_negate;
205bf215546Sopenharmony_ci} gpir_alu_node;
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_citypedef struct {
208bf215546Sopenharmony_ci   gpir_node node;
209bf215546Sopenharmony_ci   union fi value;
210bf215546Sopenharmony_ci} gpir_const_node;
211bf215546Sopenharmony_ci
212bf215546Sopenharmony_citypedef struct {
213bf215546Sopenharmony_ci   int index;
214bf215546Sopenharmony_ci   struct list_head list;
215bf215546Sopenharmony_ci} gpir_reg;
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_citypedef struct {
218bf215546Sopenharmony_ci   gpir_node node;
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci   unsigned index;
221bf215546Sopenharmony_ci   unsigned component;
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci   gpir_reg *reg;
224bf215546Sopenharmony_ci   struct list_head reg_link;
225bf215546Sopenharmony_ci} gpir_load_node;
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_citypedef struct gpir_store_node {
228bf215546Sopenharmony_ci   gpir_node node;
229bf215546Sopenharmony_ci
230bf215546Sopenharmony_ci   unsigned index;
231bf215546Sopenharmony_ci   unsigned component;
232bf215546Sopenharmony_ci   gpir_node *child;
233bf215546Sopenharmony_ci
234bf215546Sopenharmony_ci   gpir_reg *reg;
235bf215546Sopenharmony_ci} gpir_store_node;
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_cienum gpir_instr_slot {
238bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_MUL0,
239bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_MUL1,
240bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_ADD0,
241bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_ADD1,
242bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_PASS,
243bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_COMPLEX,
244bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_REG0_LOAD0,
245bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_REG0_LOAD1,
246bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_REG0_LOAD2,
247bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_REG0_LOAD3,
248bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_REG1_LOAD0,
249bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_REG1_LOAD1,
250bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_REG1_LOAD2,
251bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_REG1_LOAD3,
252bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_MEM_LOAD0,
253bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_MEM_LOAD1,
254bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_MEM_LOAD2,
255bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_MEM_LOAD3,
256bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_STORE0,
257bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_STORE1,
258bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_STORE2,
259bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_STORE3,
260bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_NUM,
261bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_END,
262bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_ALU_BEGIN      = GPIR_INSTR_SLOT_MUL0,
263bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_ALU_END        = GPIR_INSTR_SLOT_COMPLEX,
264bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_DIST_TWO_BEGIN = GPIR_INSTR_SLOT_MUL0,
265bf215546Sopenharmony_ci   GPIR_INSTR_SLOT_DIST_TWO_END   = GPIR_INSTR_SLOT_PASS,
266bf215546Sopenharmony_ci};
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_citypedef struct gpir_instr {
269bf215546Sopenharmony_ci   int index;
270bf215546Sopenharmony_ci   struct list_head list;
271bf215546Sopenharmony_ci
272bf215546Sopenharmony_ci   gpir_node *slots[GPIR_INSTR_SLOT_NUM];
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_ci   /* The number of ALU slots free for moves. */
275bf215546Sopenharmony_ci   int alu_num_slot_free;
276bf215546Sopenharmony_ci
277bf215546Sopenharmony_ci   /* The number of ALU slots free for moves, except for the complex slot. */
278bf215546Sopenharmony_ci   int alu_non_cplx_slot_free;
279bf215546Sopenharmony_ci
280bf215546Sopenharmony_ci   /* We need to make sure that we can insert moves in the following cases:
281bf215546Sopenharmony_ci    * (1) There was a use of a value two cycles ago.
282bf215546Sopenharmony_ci    * (2) There were more than 5 uses of a value 1 cycle ago (or else we can't
283bf215546Sopenharmony_ci    *     possibly satisfy (1) for the next cycle).
284bf215546Sopenharmony_ci    * (3) There is a store instruction scheduled, but not its child.
285bf215546Sopenharmony_ci    *
286bf215546Sopenharmony_ci    * The complex slot cannot be used for a move in case (1), since it only
287bf215546Sopenharmony_ci    * has a FIFO depth of 1, but it can be used for (2) as well as (3) as long
288bf215546Sopenharmony_ci    * as the uses aren't in certain slots. It turns out that we don't have to
289bf215546Sopenharmony_ci    * worry about nodes that can't use the complex slot for (2), since there
290bf215546Sopenharmony_ci    * are at most 4 uses 1 cycle ago that can't use the complex slot, but we
291bf215546Sopenharmony_ci    * do have to worry about (3). This means tracking stores whose children
292bf215546Sopenharmony_ci    * cannot be in the complex slot. In order to ensure that we have enough
293bf215546Sopenharmony_ci    * space for all three, we maintain the following invariants:
294bf215546Sopenharmony_ci    *
295bf215546Sopenharmony_ci    * (1) alu_num_slot_free >= alu_num_slot_needed_by_store +
296bf215546Sopenharmony_ci    *       alu_num_slot_needed_by_max +
297bf215546Sopenharmony_ci    *       max(alu_num_unscheduled_next_max - alu_max_allowed_next_max, 0)
298bf215546Sopenharmony_ci    * (2) alu_non_cplx_slot_free >= alu_num_slot_needed_by_max +
299bf215546Sopenharmony_ci    *       alu_num_slot_needed_by_non_cplx_store
300bf215546Sopenharmony_ci    *
301bf215546Sopenharmony_ci    * alu_max_allowed_next_max is normally 5 (since there can be at most 5 max
302bf215546Sopenharmony_ci    * nodes for the next instruction) but when there is a complex1 node in
303bf215546Sopenharmony_ci    * this instruction it reduces to 4 to reserve a slot for complex2 in the
304bf215546Sopenharmony_ci    * next instruction.
305bf215546Sopenharmony_ci    */
306bf215546Sopenharmony_ci   int alu_num_slot_needed_by_store;
307bf215546Sopenharmony_ci   int alu_num_slot_needed_by_non_cplx_store;
308bf215546Sopenharmony_ci   int alu_num_slot_needed_by_max;
309bf215546Sopenharmony_ci   int alu_num_unscheduled_next_max;
310bf215546Sopenharmony_ci   int alu_max_allowed_next_max;
311bf215546Sopenharmony_ci
312bf215546Sopenharmony_ci   /* Used to communicate to the scheduler how many slots need to be cleared
313bf215546Sopenharmony_ci    * up in order to satisfy the invariants.
314bf215546Sopenharmony_ci    */
315bf215546Sopenharmony_ci   int slot_difference;
316bf215546Sopenharmony_ci   int non_cplx_slot_difference;
317bf215546Sopenharmony_ci
318bf215546Sopenharmony_ci   int reg0_use_count;
319bf215546Sopenharmony_ci   bool reg0_is_attr;
320bf215546Sopenharmony_ci   int reg0_index;
321bf215546Sopenharmony_ci
322bf215546Sopenharmony_ci   int reg1_use_count;
323bf215546Sopenharmony_ci   int reg1_index;
324bf215546Sopenharmony_ci
325bf215546Sopenharmony_ci   int mem_use_count;
326bf215546Sopenharmony_ci   bool mem_is_temp;
327bf215546Sopenharmony_ci   int mem_index;
328bf215546Sopenharmony_ci
329bf215546Sopenharmony_ci   enum {
330bf215546Sopenharmony_ci      GPIR_INSTR_STORE_NONE,
331bf215546Sopenharmony_ci      GPIR_INSTR_STORE_VARYING,
332bf215546Sopenharmony_ci      GPIR_INSTR_STORE_REG,
333bf215546Sopenharmony_ci      GPIR_INSTR_STORE_TEMP,
334bf215546Sopenharmony_ci   } store_content[2];
335bf215546Sopenharmony_ci   int store_index[2];
336bf215546Sopenharmony_ci} gpir_instr;
337bf215546Sopenharmony_ci
338bf215546Sopenharmony_citypedef struct gpir_block {
339bf215546Sopenharmony_ci   struct list_head list;
340bf215546Sopenharmony_ci   struct list_head node_list;
341bf215546Sopenharmony_ci   struct list_head instr_list;
342bf215546Sopenharmony_ci   struct gpir_compiler *comp;
343bf215546Sopenharmony_ci
344bf215546Sopenharmony_ci   struct gpir_block *successors[2];
345bf215546Sopenharmony_ci   struct list_head predecessors;
346bf215546Sopenharmony_ci   struct list_head predecessors_node;
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_ci   /* for regalloc */
349bf215546Sopenharmony_ci
350bf215546Sopenharmony_ci   /* The set of live registers, i.e. registers whose value may be used
351bf215546Sopenharmony_ci    * eventually, at the beginning of the block.
352bf215546Sopenharmony_ci    */
353bf215546Sopenharmony_ci   BITSET_WORD *live_in;
354bf215546Sopenharmony_ci
355bf215546Sopenharmony_ci   /* Set of live registers at the end of the block. */
356bf215546Sopenharmony_ci   BITSET_WORD *live_out;
357bf215546Sopenharmony_ci
358bf215546Sopenharmony_ci   /* Set of registers that may have a value defined at the end of the
359bf215546Sopenharmony_ci    * block.
360bf215546Sopenharmony_ci    */
361bf215546Sopenharmony_ci   BITSET_WORD *def_out;
362bf215546Sopenharmony_ci
363bf215546Sopenharmony_ci   /* After register allocation, the set of live physical registers at the end
364bf215546Sopenharmony_ci    * of the block. Needed for scheduling.
365bf215546Sopenharmony_ci    */
366bf215546Sopenharmony_ci   uint64_t live_out_phys;
367bf215546Sopenharmony_ci
368bf215546Sopenharmony_ci   /* For codegen, the offset in the final program. */
369bf215546Sopenharmony_ci   unsigned instr_offset;
370bf215546Sopenharmony_ci
371bf215546Sopenharmony_ci   /* for scheduler */
372bf215546Sopenharmony_ci   union {
373bf215546Sopenharmony_ci      struct {
374bf215546Sopenharmony_ci         int instr_index;
375bf215546Sopenharmony_ci      } sched;
376bf215546Sopenharmony_ci      struct {
377bf215546Sopenharmony_ci         int node_index;
378bf215546Sopenharmony_ci      } rsched;
379bf215546Sopenharmony_ci   };
380bf215546Sopenharmony_ci} gpir_block;
381bf215546Sopenharmony_ci
382bf215546Sopenharmony_citypedef struct {
383bf215546Sopenharmony_ci   gpir_node node;
384bf215546Sopenharmony_ci   gpir_block *dest;
385bf215546Sopenharmony_ci   gpir_node *cond;
386bf215546Sopenharmony_ci} gpir_branch_node;
387bf215546Sopenharmony_ci
388bf215546Sopenharmony_cistruct lima_vs_compiled_shader;
389bf215546Sopenharmony_ci
390bf215546Sopenharmony_ci#define GPIR_VECTOR_SSA_VIEWPORT_SCALE  0
391bf215546Sopenharmony_ci#define GPIR_VECTOR_SSA_VIEWPORT_OFFSET 1
392bf215546Sopenharmony_ci#define GPIR_VECTOR_SSA_NUM 2
393bf215546Sopenharmony_ci
394bf215546Sopenharmony_citypedef struct gpir_compiler {
395bf215546Sopenharmony_ci   struct list_head block_list;
396bf215546Sopenharmony_ci   int cur_index;
397bf215546Sopenharmony_ci
398bf215546Sopenharmony_ci   /* Find the gpir node for a given NIR SSA def. */
399bf215546Sopenharmony_ci   gpir_node **node_for_ssa;
400bf215546Sopenharmony_ci
401bf215546Sopenharmony_ci   /* Find the gpir node for a given NIR register. */
402bf215546Sopenharmony_ci   gpir_node **node_for_reg;
403bf215546Sopenharmony_ci
404bf215546Sopenharmony_ci   /* Find the gpir register for a given NIR SSA def. */
405bf215546Sopenharmony_ci   gpir_reg **reg_for_ssa;
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci   /* Find the gpir register for a given NIR register. */
408bf215546Sopenharmony_ci   gpir_reg **reg_for_reg;
409bf215546Sopenharmony_ci
410bf215546Sopenharmony_ci   /* gpir block for NIR block. */
411bf215546Sopenharmony_ci   gpir_block **blocks;
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_ci   /* for physical reg */
414bf215546Sopenharmony_ci   struct list_head reg_list;
415bf215546Sopenharmony_ci   int cur_reg;
416bf215546Sopenharmony_ci
417bf215546Sopenharmony_ci   /* lookup for vector ssa */
418bf215546Sopenharmony_ci   struct {
419bf215546Sopenharmony_ci      int ssa;
420bf215546Sopenharmony_ci      gpir_node *nodes[4];
421bf215546Sopenharmony_ci   } vector_ssa[GPIR_VECTOR_SSA_NUM];
422bf215546Sopenharmony_ci
423bf215546Sopenharmony_ci   struct lima_vs_compiled_shader *prog;
424bf215546Sopenharmony_ci   int constant_base;
425bf215546Sopenharmony_ci
426bf215546Sopenharmony_ci   /* shaderdb */
427bf215546Sopenharmony_ci   int num_instr;
428bf215546Sopenharmony_ci   int num_loops;
429bf215546Sopenharmony_ci   int num_spills;
430bf215546Sopenharmony_ci   int num_fills;
431bf215546Sopenharmony_ci} gpir_compiler;
432bf215546Sopenharmony_ci
433bf215546Sopenharmony_ci#define GPIR_VALUE_REG_NUM 11
434bf215546Sopenharmony_ci#define GPIR_PHYSICAL_REG_NUM 64
435bf215546Sopenharmony_ci
436bf215546Sopenharmony_civoid *gpir_node_create(gpir_block *block, gpir_op op);
437bf215546Sopenharmony_cigpir_dep *gpir_node_add_dep(gpir_node *succ, gpir_node *pred, int type);
438bf215546Sopenharmony_civoid gpir_node_remove_dep(gpir_node *succ, gpir_node *pred);
439bf215546Sopenharmony_civoid gpir_node_replace_succ(gpir_node *dst, gpir_node *src);
440bf215546Sopenharmony_civoid gpir_node_replace_pred(gpir_dep *dep, gpir_node *new_pred);
441bf215546Sopenharmony_civoid gpir_node_replace_child(gpir_node *parent, gpir_node *old_child, gpir_node *new_child);
442bf215546Sopenharmony_civoid gpir_node_insert_child(gpir_node *parent, gpir_node *child, gpir_node *insert_child);
443bf215546Sopenharmony_civoid gpir_node_delete(gpir_node *node);
444bf215546Sopenharmony_civoid gpir_node_print_prog_dep(gpir_compiler *comp);
445bf215546Sopenharmony_civoid gpir_node_print_prog_seq(gpir_compiler *comp);
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci#define gpir_node_foreach_succ(node, dep) \
448bf215546Sopenharmony_ci   list_for_each_entry(gpir_dep, dep, &node->succ_list, succ_link)
449bf215546Sopenharmony_ci#define gpir_node_foreach_succ_safe(node, dep) \
450bf215546Sopenharmony_ci   list_for_each_entry_safe(gpir_dep, dep, &node->succ_list, succ_link)
451bf215546Sopenharmony_ci#define gpir_node_foreach_pred(node, dep) \
452bf215546Sopenharmony_ci   list_for_each_entry(gpir_dep, dep, &node->pred_list, pred_link)
453bf215546Sopenharmony_ci#define gpir_node_foreach_pred_safe(node, dep) \
454bf215546Sopenharmony_ci   list_for_each_entry_safe(gpir_dep, dep, &node->pred_list, pred_link)
455bf215546Sopenharmony_ci
456bf215546Sopenharmony_cistatic inline bool gpir_node_is_root(gpir_node *node)
457bf215546Sopenharmony_ci{
458bf215546Sopenharmony_ci   return list_is_empty(&node->succ_list);
459bf215546Sopenharmony_ci}
460bf215546Sopenharmony_ci
461bf215546Sopenharmony_cistatic inline bool gpir_node_is_leaf(gpir_node *node)
462bf215546Sopenharmony_ci{
463bf215546Sopenharmony_ci   return list_is_empty(&node->pred_list);
464bf215546Sopenharmony_ci}
465bf215546Sopenharmony_ci
466bf215546Sopenharmony_ci#define gpir_node_to_alu(node) ((gpir_alu_node *)(node))
467bf215546Sopenharmony_ci#define gpir_node_to_const(node) ((gpir_const_node *)(node))
468bf215546Sopenharmony_ci#define gpir_node_to_load(node) ((gpir_load_node *)(node))
469bf215546Sopenharmony_ci#define gpir_node_to_store(node) ((gpir_store_node *)(node))
470bf215546Sopenharmony_ci#define gpir_node_to_branch(node) ((gpir_branch_node *)(node))
471bf215546Sopenharmony_ci
472bf215546Sopenharmony_cigpir_instr *gpir_instr_create(gpir_block *block);
473bf215546Sopenharmony_cibool gpir_instr_try_insert_node(gpir_instr *instr, gpir_node *node);
474bf215546Sopenharmony_civoid gpir_instr_remove_node(gpir_instr *instr, gpir_node *node);
475bf215546Sopenharmony_civoid gpir_instr_print_prog(gpir_compiler *comp);
476bf215546Sopenharmony_ci
477bf215546Sopenharmony_cibool gpir_codegen_acc_same_op(gpir_op op1, gpir_op op2);
478bf215546Sopenharmony_ci
479bf215546Sopenharmony_cibool gpir_optimize(gpir_compiler *comp);
480bf215546Sopenharmony_cibool gpir_pre_rsched_lower_prog(gpir_compiler *comp);
481bf215546Sopenharmony_cibool gpir_reduce_reg_pressure_schedule_prog(gpir_compiler *comp);
482bf215546Sopenharmony_cibool gpir_regalloc_prog(gpir_compiler *comp);
483bf215546Sopenharmony_cibool gpir_schedule_prog(gpir_compiler *comp);
484bf215546Sopenharmony_cibool gpir_codegen_prog(gpir_compiler *comp);
485bf215546Sopenharmony_ci
486bf215546Sopenharmony_cigpir_reg *gpir_create_reg(gpir_compiler *comp);
487bf215546Sopenharmony_ci
488bf215546Sopenharmony_ci#endif
489