1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (c) 2017 Lima Project
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sub license,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
12bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
13bf215546Sopenharmony_ci * 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 NON-INFRINGEMENT. IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE 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
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci */
24bf215546Sopenharmony_ci
25bf215546Sopenharmony_ci#include "util/u_math.h"
26bf215546Sopenharmony_ci#include "util/ralloc.h"
27bf215546Sopenharmony_ci#include "util/bitscan.h"
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "ppir.h"
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ciconst ppir_op_info ppir_op_infos[] = {
32bf215546Sopenharmony_ci   [ppir_op_unsupported] = {
33bf215546Sopenharmony_ci      .name = "unsupported",
34bf215546Sopenharmony_ci   },
35bf215546Sopenharmony_ci   [ppir_op_mov] = {
36bf215546Sopenharmony_ci      .name = "mov",
37bf215546Sopenharmony_ci      .slots = (int []) {
38bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_SCL_MUL,
39bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_VEC_ADD, PPIR_INSTR_SLOT_ALU_VEC_MUL,
40bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
41bf215546Sopenharmony_ci      },
42bf215546Sopenharmony_ci   },
43bf215546Sopenharmony_ci   [ppir_op_abs] = {
44bf215546Sopenharmony_ci      .name = "abs",
45bf215546Sopenharmony_ci   },
46bf215546Sopenharmony_ci   [ppir_op_neg] = {
47bf215546Sopenharmony_ci      .name = "neg",
48bf215546Sopenharmony_ci   },
49bf215546Sopenharmony_ci   [ppir_op_sat] = {
50bf215546Sopenharmony_ci      .name = "sat",
51bf215546Sopenharmony_ci   },
52bf215546Sopenharmony_ci   [ppir_op_mul] = {
53bf215546Sopenharmony_ci      .name = "mul",
54bf215546Sopenharmony_ci      .slots = (int []) {
55bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_VEC_MUL,
56bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
57bf215546Sopenharmony_ci      },
58bf215546Sopenharmony_ci   },
59bf215546Sopenharmony_ci   [ppir_op_add] = {
60bf215546Sopenharmony_ci      .name = "add",
61bf215546Sopenharmony_ci      .slots = (int []) {
62bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
63bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
64bf215546Sopenharmony_ci      },
65bf215546Sopenharmony_ci   },
66bf215546Sopenharmony_ci   [ppir_op_sum3] = {
67bf215546Sopenharmony_ci      .name = "sum3",
68bf215546Sopenharmony_ci      .slots = (int []) {
69bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_VEC_ADD, PPIR_INSTR_SLOT_END
70bf215546Sopenharmony_ci      },
71bf215546Sopenharmony_ci   },
72bf215546Sopenharmony_ci   [ppir_op_sum4] = {
73bf215546Sopenharmony_ci      .name = "sum4",
74bf215546Sopenharmony_ci      .slots = (int []) {
75bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_VEC_ADD, PPIR_INSTR_SLOT_END
76bf215546Sopenharmony_ci      },
77bf215546Sopenharmony_ci   },
78bf215546Sopenharmony_ci   [ppir_op_rsqrt] = {
79bf215546Sopenharmony_ci      .name = "rsqrt",
80bf215546Sopenharmony_ci      .slots = (int []) {
81bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
82bf215546Sopenharmony_ci      },
83bf215546Sopenharmony_ci   },
84bf215546Sopenharmony_ci   [ppir_op_log2] = {
85bf215546Sopenharmony_ci      .name = "log2",
86bf215546Sopenharmony_ci      .slots = (int []) {
87bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
88bf215546Sopenharmony_ci      },
89bf215546Sopenharmony_ci   },
90bf215546Sopenharmony_ci   [ppir_op_exp2] = {
91bf215546Sopenharmony_ci      .name = "exp2",
92bf215546Sopenharmony_ci      .slots = (int []) {
93bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
94bf215546Sopenharmony_ci      },
95bf215546Sopenharmony_ci   },
96bf215546Sopenharmony_ci   [ppir_op_sqrt] = {
97bf215546Sopenharmony_ci      .name = "sqrt",
98bf215546Sopenharmony_ci      .slots = (int []) {
99bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
100bf215546Sopenharmony_ci      },
101bf215546Sopenharmony_ci   },
102bf215546Sopenharmony_ci   [ppir_op_sin] = {
103bf215546Sopenharmony_ci      .name = "sin",
104bf215546Sopenharmony_ci      .slots = (int []) {
105bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
106bf215546Sopenharmony_ci      },
107bf215546Sopenharmony_ci   },
108bf215546Sopenharmony_ci   [ppir_op_cos] = {
109bf215546Sopenharmony_ci      .name = "cos",
110bf215546Sopenharmony_ci      .slots = (int []) {
111bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
112bf215546Sopenharmony_ci      },
113bf215546Sopenharmony_ci   },
114bf215546Sopenharmony_ci   [ppir_op_max] = {
115bf215546Sopenharmony_ci      .name = "max",
116bf215546Sopenharmony_ci      .slots = (int []) {
117bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_SCL_MUL,
118bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_VEC_ADD, PPIR_INSTR_SLOT_ALU_VEC_MUL,
119bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
120bf215546Sopenharmony_ci      },
121bf215546Sopenharmony_ci   },
122bf215546Sopenharmony_ci   [ppir_op_min] = {
123bf215546Sopenharmony_ci      .name = "min",
124bf215546Sopenharmony_ci      .slots = (int []) {
125bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_SCL_MUL,
126bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_VEC_ADD, PPIR_INSTR_SLOT_ALU_VEC_MUL,
127bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
128bf215546Sopenharmony_ci      },
129bf215546Sopenharmony_ci   },
130bf215546Sopenharmony_ci   [ppir_op_floor] = {
131bf215546Sopenharmony_ci      .name = "floor",
132bf215546Sopenharmony_ci      .slots = (int []) {
133bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
134bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
135bf215546Sopenharmony_ci      },
136bf215546Sopenharmony_ci   },
137bf215546Sopenharmony_ci   [ppir_op_ceil] = {
138bf215546Sopenharmony_ci      .name = "ceil",
139bf215546Sopenharmony_ci      .slots = (int []) {
140bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
141bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
142bf215546Sopenharmony_ci      },
143bf215546Sopenharmony_ci   },
144bf215546Sopenharmony_ci   [ppir_op_fract] = {
145bf215546Sopenharmony_ci      .name = "fract",
146bf215546Sopenharmony_ci      .slots = (int []) {
147bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
148bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
149bf215546Sopenharmony_ci      },
150bf215546Sopenharmony_ci   },
151bf215546Sopenharmony_ci   [ppir_op_ddx] = {
152bf215546Sopenharmony_ci      .name = "ddx",
153bf215546Sopenharmony_ci      .slots = (int []) {
154bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
155bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
156bf215546Sopenharmony_ci      },
157bf215546Sopenharmony_ci   },
158bf215546Sopenharmony_ci   [ppir_op_ddy] = {
159bf215546Sopenharmony_ci      .name = "ddy",
160bf215546Sopenharmony_ci      .slots = (int []) {
161bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
162bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
163bf215546Sopenharmony_ci      },
164bf215546Sopenharmony_ci   },
165bf215546Sopenharmony_ci   [ppir_op_and] = {
166bf215546Sopenharmony_ci      .name = "and",
167bf215546Sopenharmony_ci      .slots = (int []) {
168bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_VEC_MUL,
169bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
170bf215546Sopenharmony_ci      },
171bf215546Sopenharmony_ci   },
172bf215546Sopenharmony_ci   [ppir_op_or] = {
173bf215546Sopenharmony_ci      .name = "or",
174bf215546Sopenharmony_ci      .slots = (int []) {
175bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_VEC_MUL,
176bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
177bf215546Sopenharmony_ci      },
178bf215546Sopenharmony_ci   },
179bf215546Sopenharmony_ci   [ppir_op_xor] = {
180bf215546Sopenharmony_ci      .name = "xor",
181bf215546Sopenharmony_ci      .slots = (int []) {
182bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_VEC_MUL,
183bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
184bf215546Sopenharmony_ci      },
185bf215546Sopenharmony_ci   },
186bf215546Sopenharmony_ci   [ppir_op_not] = {
187bf215546Sopenharmony_ci      .name = "not",
188bf215546Sopenharmony_ci      .slots = (int []) {
189bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_VEC_MUL,
190bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
191bf215546Sopenharmony_ci      },
192bf215546Sopenharmony_ci   },
193bf215546Sopenharmony_ci   [ppir_op_lt] = {
194bf215546Sopenharmony_ci      .name = "lt",
195bf215546Sopenharmony_ci   },
196bf215546Sopenharmony_ci   [ppir_op_le] = {
197bf215546Sopenharmony_ci      .name = "le",
198bf215546Sopenharmony_ci   },
199bf215546Sopenharmony_ci   [ppir_op_gt] = {
200bf215546Sopenharmony_ci      .name = "gt",
201bf215546Sopenharmony_ci      .slots = (int []) {
202bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_SCL_ADD,
203bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_VEC_MUL, PPIR_INSTR_SLOT_ALU_VEC_ADD,
204bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
205bf215546Sopenharmony_ci      },
206bf215546Sopenharmony_ci   },
207bf215546Sopenharmony_ci   [ppir_op_ge] = {
208bf215546Sopenharmony_ci      .name = "ge",
209bf215546Sopenharmony_ci      .slots = (int []) {
210bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_SCL_ADD,
211bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_VEC_MUL, PPIR_INSTR_SLOT_ALU_VEC_ADD,
212bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
213bf215546Sopenharmony_ci      },
214bf215546Sopenharmony_ci   },
215bf215546Sopenharmony_ci   [ppir_op_eq] = {
216bf215546Sopenharmony_ci      .name = "eq",
217bf215546Sopenharmony_ci      .slots = (int []) {
218bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_SCL_ADD,
219bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_VEC_MUL, PPIR_INSTR_SLOT_ALU_VEC_ADD,
220bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
221bf215546Sopenharmony_ci      },
222bf215546Sopenharmony_ci   },
223bf215546Sopenharmony_ci   [ppir_op_ne] = {
224bf215546Sopenharmony_ci      .name = "ne",
225bf215546Sopenharmony_ci      .slots = (int []) {
226bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_MUL, PPIR_INSTR_SLOT_ALU_SCL_ADD,
227bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_VEC_MUL, PPIR_INSTR_SLOT_ALU_VEC_ADD,
228bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
229bf215546Sopenharmony_ci      },
230bf215546Sopenharmony_ci   },
231bf215546Sopenharmony_ci   [ppir_op_select] = {
232bf215546Sopenharmony_ci      .name = "select",
233bf215546Sopenharmony_ci      .slots = (int []) {
234bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_SCL_ADD, PPIR_INSTR_SLOT_ALU_VEC_ADD,
235bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
236bf215546Sopenharmony_ci      },
237bf215546Sopenharmony_ci   },
238bf215546Sopenharmony_ci   [ppir_op_rcp] = {
239bf215546Sopenharmony_ci      .name = "rcp",
240bf215546Sopenharmony_ci      .slots = (int []) {
241bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_ALU_COMBINE, PPIR_INSTR_SLOT_END
242bf215546Sopenharmony_ci      },
243bf215546Sopenharmony_ci   },
244bf215546Sopenharmony_ci   [ppir_op_load_varying] = {
245bf215546Sopenharmony_ci      .name = "ld_var",
246bf215546Sopenharmony_ci      .type = ppir_node_type_load,
247bf215546Sopenharmony_ci      .slots = (int []) {
248bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
249bf215546Sopenharmony_ci      },
250bf215546Sopenharmony_ci   },
251bf215546Sopenharmony_ci   [ppir_op_load_coords] = {
252bf215546Sopenharmony_ci      .name = "ld_coords",
253bf215546Sopenharmony_ci      .type = ppir_node_type_load,
254bf215546Sopenharmony_ci      .slots = (int []) {
255bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
256bf215546Sopenharmony_ci      },
257bf215546Sopenharmony_ci   },
258bf215546Sopenharmony_ci   [ppir_op_load_coords_reg] = {
259bf215546Sopenharmony_ci      .name = "ld_coords_reg",
260bf215546Sopenharmony_ci      .type = ppir_node_type_load,
261bf215546Sopenharmony_ci      .slots = (int []) {
262bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
263bf215546Sopenharmony_ci      },
264bf215546Sopenharmony_ci   },
265bf215546Sopenharmony_ci   [ppir_op_load_fragcoord] = {
266bf215546Sopenharmony_ci      .name = "ld_fragcoord",
267bf215546Sopenharmony_ci      .type = ppir_node_type_load,
268bf215546Sopenharmony_ci      .slots = (int []) {
269bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
270bf215546Sopenharmony_ci      },
271bf215546Sopenharmony_ci   },
272bf215546Sopenharmony_ci   [ppir_op_load_pointcoord] = {
273bf215546Sopenharmony_ci      .name = "ld_pointcoord",
274bf215546Sopenharmony_ci      .type = ppir_node_type_load,
275bf215546Sopenharmony_ci      .slots = (int []) {
276bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
277bf215546Sopenharmony_ci      },
278bf215546Sopenharmony_ci   },
279bf215546Sopenharmony_ci   [ppir_op_load_frontface] = {
280bf215546Sopenharmony_ci      .name = "ld_frontface",
281bf215546Sopenharmony_ci      .type = ppir_node_type_load,
282bf215546Sopenharmony_ci      .slots = (int []) {
283bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END
284bf215546Sopenharmony_ci      },
285bf215546Sopenharmony_ci   },
286bf215546Sopenharmony_ci   [ppir_op_load_uniform] = {
287bf215546Sopenharmony_ci      .name = "ld_uni",
288bf215546Sopenharmony_ci      .type = ppir_node_type_load,
289bf215546Sopenharmony_ci      .slots = (int []) {
290bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_UNIFORM, PPIR_INSTR_SLOT_END
291bf215546Sopenharmony_ci      },
292bf215546Sopenharmony_ci   },
293bf215546Sopenharmony_ci   [ppir_op_load_texture] = {
294bf215546Sopenharmony_ci      .name = "ld_tex",
295bf215546Sopenharmony_ci      .type = ppir_node_type_load_texture,
296bf215546Sopenharmony_ci      .slots = (int []) {
297bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_TEXLD, PPIR_INSTR_SLOT_END
298bf215546Sopenharmony_ci      },
299bf215546Sopenharmony_ci   },
300bf215546Sopenharmony_ci   [ppir_op_load_temp] = {
301bf215546Sopenharmony_ci      .name = "ld_temp",
302bf215546Sopenharmony_ci      .type = ppir_node_type_load,
303bf215546Sopenharmony_ci      .slots = (int []) {
304bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_UNIFORM, PPIR_INSTR_SLOT_END
305bf215546Sopenharmony_ci      },
306bf215546Sopenharmony_ci   },
307bf215546Sopenharmony_ci   [ppir_op_const] = {
308bf215546Sopenharmony_ci      .name = "const",
309bf215546Sopenharmony_ci      .type = ppir_node_type_const,
310bf215546Sopenharmony_ci   },
311bf215546Sopenharmony_ci   [ppir_op_store_temp] = {
312bf215546Sopenharmony_ci      .name = "st_temp",
313bf215546Sopenharmony_ci      .type = ppir_node_type_store,
314bf215546Sopenharmony_ci      .slots = (int []) {
315bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_STORE_TEMP, PPIR_INSTR_SLOT_END
316bf215546Sopenharmony_ci      },
317bf215546Sopenharmony_ci   },
318bf215546Sopenharmony_ci   [ppir_op_discard] = {
319bf215546Sopenharmony_ci      .name = "discard",
320bf215546Sopenharmony_ci      .type = ppir_node_type_discard,
321bf215546Sopenharmony_ci      .slots = (int []) {
322bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_BRANCH, PPIR_INSTR_SLOT_END
323bf215546Sopenharmony_ci      },
324bf215546Sopenharmony_ci   },
325bf215546Sopenharmony_ci   [ppir_op_branch] = {
326bf215546Sopenharmony_ci      .name = "branch",
327bf215546Sopenharmony_ci      .type = ppir_node_type_branch,
328bf215546Sopenharmony_ci      .slots = (int []) {
329bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_BRANCH, PPIR_INSTR_SLOT_END
330bf215546Sopenharmony_ci      },
331bf215546Sopenharmony_ci   },
332bf215546Sopenharmony_ci   [ppir_op_undef] = {
333bf215546Sopenharmony_ci      .name = "undef",
334bf215546Sopenharmony_ci      .type = ppir_node_type_alu,
335bf215546Sopenharmony_ci      .slots = (int []) {
336bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
337bf215546Sopenharmony_ci      },
338bf215546Sopenharmony_ci   },
339bf215546Sopenharmony_ci   [ppir_op_dummy] = {
340bf215546Sopenharmony_ci      .name = "dummy",
341bf215546Sopenharmony_ci      .type = ppir_node_type_alu,
342bf215546Sopenharmony_ci      .slots = (int []) {
343bf215546Sopenharmony_ci         PPIR_INSTR_SLOT_END
344bf215546Sopenharmony_ci      },
345bf215546Sopenharmony_ci   },
346bf215546Sopenharmony_ci};
347bf215546Sopenharmony_ci
348bf215546Sopenharmony_civoid *ppir_node_create(ppir_block *block, ppir_op op, int index, unsigned mask)
349bf215546Sopenharmony_ci{
350bf215546Sopenharmony_ci   ppir_compiler *comp = block->comp;
351bf215546Sopenharmony_ci   static const int node_size[] = {
352bf215546Sopenharmony_ci      [ppir_node_type_alu] = sizeof(ppir_alu_node),
353bf215546Sopenharmony_ci      [ppir_node_type_const] = sizeof(ppir_const_node),
354bf215546Sopenharmony_ci      [ppir_node_type_load] = sizeof(ppir_load_node),
355bf215546Sopenharmony_ci      [ppir_node_type_store] = sizeof(ppir_store_node),
356bf215546Sopenharmony_ci      [ppir_node_type_load_texture] = sizeof(ppir_load_texture_node),
357bf215546Sopenharmony_ci      [ppir_node_type_discard] = sizeof(ppir_discard_node),
358bf215546Sopenharmony_ci      [ppir_node_type_branch] = sizeof(ppir_branch_node),
359bf215546Sopenharmony_ci   };
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_ci   ppir_node_type type = ppir_op_infos[op].type;
362bf215546Sopenharmony_ci   int size = node_size[type];
363bf215546Sopenharmony_ci   ppir_node *node = rzalloc_size(block, size);
364bf215546Sopenharmony_ci   if (!node)
365bf215546Sopenharmony_ci      return NULL;
366bf215546Sopenharmony_ci
367bf215546Sopenharmony_ci   list_inithead(&node->succ_list);
368bf215546Sopenharmony_ci   list_inithead(&node->pred_list);
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ci   if (index >= 0) {
371bf215546Sopenharmony_ci      if (mask) {
372bf215546Sopenharmony_ci         /* reg has 4 slots for each component write node */
373bf215546Sopenharmony_ci         while (mask)
374bf215546Sopenharmony_ci            comp->var_nodes[(index << 2) + comp->reg_base + u_bit_scan(&mask)] = node;
375bf215546Sopenharmony_ci         snprintf(node->name, sizeof(node->name), "reg%d", index);
376bf215546Sopenharmony_ci      } else {
377bf215546Sopenharmony_ci         comp->var_nodes[index] = node;
378bf215546Sopenharmony_ci         snprintf(node->name, sizeof(node->name), "ssa%d", index);
379bf215546Sopenharmony_ci      }
380bf215546Sopenharmony_ci   }
381bf215546Sopenharmony_ci   else
382bf215546Sopenharmony_ci      snprintf(node->name, sizeof(node->name), "new");
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ci   node->op = op;
385bf215546Sopenharmony_ci   node->type = type;
386bf215546Sopenharmony_ci   node->index = comp->cur_index++;
387bf215546Sopenharmony_ci   node->block = block;
388bf215546Sopenharmony_ci
389bf215546Sopenharmony_ci   return node;
390bf215546Sopenharmony_ci}
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_civoid ppir_node_add_dep(ppir_node *succ, ppir_node *pred,
393bf215546Sopenharmony_ci                       ppir_dep_type type)
394bf215546Sopenharmony_ci{
395bf215546Sopenharmony_ci   /* don't add dep for two nodes from different block */
396bf215546Sopenharmony_ci   if (succ->block != pred->block) {
397bf215546Sopenharmony_ci      pred->succ_different_block = true;
398bf215546Sopenharmony_ci      return;
399bf215546Sopenharmony_ci   }
400bf215546Sopenharmony_ci
401bf215546Sopenharmony_ci   /* don't add duplicated dep */
402bf215546Sopenharmony_ci   ppir_node_foreach_pred(succ, dep) {
403bf215546Sopenharmony_ci      if (dep->pred == pred)
404bf215546Sopenharmony_ci         return;
405bf215546Sopenharmony_ci   }
406bf215546Sopenharmony_ci
407bf215546Sopenharmony_ci   ppir_dep *dep = ralloc(succ, ppir_dep);
408bf215546Sopenharmony_ci   dep->pred = pred;
409bf215546Sopenharmony_ci   dep->succ = succ;
410bf215546Sopenharmony_ci   dep->type = type;
411bf215546Sopenharmony_ci   list_addtail(&dep->pred_link, &succ->pred_list);
412bf215546Sopenharmony_ci   list_addtail(&dep->succ_link, &pred->succ_list);
413bf215546Sopenharmony_ci}
414bf215546Sopenharmony_ci
415bf215546Sopenharmony_civoid ppir_node_remove_dep(ppir_dep *dep)
416bf215546Sopenharmony_ci{
417bf215546Sopenharmony_ci   list_del(&dep->succ_link);
418bf215546Sopenharmony_ci   list_del(&dep->pred_link);
419bf215546Sopenharmony_ci   ralloc_free(dep);
420bf215546Sopenharmony_ci}
421bf215546Sopenharmony_ci
422bf215546Sopenharmony_cistatic void _ppir_node_replace_child(ppir_src *src, ppir_node *old_child, ppir_node *new_child)
423bf215546Sopenharmony_ci{
424bf215546Sopenharmony_ci   ppir_dest *od = ppir_node_get_dest(old_child);
425bf215546Sopenharmony_ci   if (ppir_node_target_equal(src, od)) {
426bf215546Sopenharmony_ci      ppir_node_target_assign(src, new_child);
427bf215546Sopenharmony_ci   }
428bf215546Sopenharmony_ci}
429bf215546Sopenharmony_ci
430bf215546Sopenharmony_civoid ppir_node_replace_child(ppir_node *parent, ppir_node *old_child, ppir_node *new_child)
431bf215546Sopenharmony_ci{
432bf215546Sopenharmony_ci   switch (parent->type) {
433bf215546Sopenharmony_ci   case ppir_node_type_alu:
434bf215546Sopenharmony_ci   {
435bf215546Sopenharmony_ci      ppir_alu_node *alu = ppir_node_to_alu(parent);
436bf215546Sopenharmony_ci      for (int i = 0; i < alu->num_src; i++)
437bf215546Sopenharmony_ci         _ppir_node_replace_child(alu->src + i, old_child, new_child);
438bf215546Sopenharmony_ci      break;
439bf215546Sopenharmony_ci   }
440bf215546Sopenharmony_ci   case ppir_node_type_branch:
441bf215546Sopenharmony_ci   {
442bf215546Sopenharmony_ci      ppir_branch_node *branch = ppir_node_to_branch(parent);
443bf215546Sopenharmony_ci      for (int i = 0; i < 2; i++)
444bf215546Sopenharmony_ci         _ppir_node_replace_child(branch->src + i, old_child, new_child);
445bf215546Sopenharmony_ci      break;
446bf215546Sopenharmony_ci   }
447bf215546Sopenharmony_ci   case ppir_node_type_load:
448bf215546Sopenharmony_ci   {
449bf215546Sopenharmony_ci      ppir_load_node *load = ppir_node_to_load(parent);
450bf215546Sopenharmony_ci      _ppir_node_replace_child(&load->src, old_child, new_child);
451bf215546Sopenharmony_ci      break;
452bf215546Sopenharmony_ci   }
453bf215546Sopenharmony_ci   case ppir_node_type_load_texture:
454bf215546Sopenharmony_ci   {
455bf215546Sopenharmony_ci      ppir_load_texture_node *load_texture = ppir_node_to_load_texture(parent);
456bf215546Sopenharmony_ci      for (int i = 0; i < load_texture->num_src; i++)
457bf215546Sopenharmony_ci         _ppir_node_replace_child(ppir_node_get_src(parent, i), old_child, new_child);
458bf215546Sopenharmony_ci      break;
459bf215546Sopenharmony_ci   }
460bf215546Sopenharmony_ci   case ppir_node_type_store:
461bf215546Sopenharmony_ci   {
462bf215546Sopenharmony_ci      ppir_store_node *store = ppir_node_to_store(parent);
463bf215546Sopenharmony_ci      _ppir_node_replace_child(&store->src, old_child, new_child);
464bf215546Sopenharmony_ci      break;
465bf215546Sopenharmony_ci   }
466bf215546Sopenharmony_ci   default:
467bf215546Sopenharmony_ci      ppir_debug("unknown node type in %s\n", __func__);
468bf215546Sopenharmony_ci      break;
469bf215546Sopenharmony_ci   }
470bf215546Sopenharmony_ci}
471bf215546Sopenharmony_ci
472bf215546Sopenharmony_civoid ppir_node_replace_pred(ppir_dep *dep, ppir_node *new_pred)
473bf215546Sopenharmony_ci{
474bf215546Sopenharmony_ci   list_del(&dep->succ_link);
475bf215546Sopenharmony_ci   dep->pred = new_pred;
476bf215546Sopenharmony_ci   list_addtail(&dep->succ_link, &new_pred->succ_list);
477bf215546Sopenharmony_ci}
478bf215546Sopenharmony_ci
479bf215546Sopenharmony_cippir_dep *ppir_dep_for_pred(ppir_node *node, ppir_node *pred)
480bf215546Sopenharmony_ci{
481bf215546Sopenharmony_ci   if (!pred)
482bf215546Sopenharmony_ci      return NULL;
483bf215546Sopenharmony_ci
484bf215546Sopenharmony_ci   if (node->block != pred->block)
485bf215546Sopenharmony_ci      return NULL;
486bf215546Sopenharmony_ci
487bf215546Sopenharmony_ci   ppir_node_foreach_pred(node, dep) {
488bf215546Sopenharmony_ci      if (dep->pred == pred)
489bf215546Sopenharmony_ci         return dep;
490bf215546Sopenharmony_ci   }
491bf215546Sopenharmony_ci   return NULL;
492bf215546Sopenharmony_ci}
493bf215546Sopenharmony_ci
494bf215546Sopenharmony_civoid ppir_node_replace_all_succ(ppir_node *dst, ppir_node *src)
495bf215546Sopenharmony_ci{
496bf215546Sopenharmony_ci   ppir_node_foreach_succ_safe(src, dep) {
497bf215546Sopenharmony_ci      ppir_node_replace_pred(dep, dst);
498bf215546Sopenharmony_ci      ppir_node_replace_child(dep->succ, src, dst);
499bf215546Sopenharmony_ci   }
500bf215546Sopenharmony_ci}
501bf215546Sopenharmony_ci
502bf215546Sopenharmony_civoid ppir_node_delete(ppir_node *node)
503bf215546Sopenharmony_ci{
504bf215546Sopenharmony_ci   ppir_node_foreach_succ_safe(node, dep)
505bf215546Sopenharmony_ci      ppir_node_remove_dep(dep);
506bf215546Sopenharmony_ci
507bf215546Sopenharmony_ci   ppir_node_foreach_pred_safe(node, dep)
508bf215546Sopenharmony_ci      ppir_node_remove_dep(dep);
509bf215546Sopenharmony_ci
510bf215546Sopenharmony_ci   list_del(&node->list);
511bf215546Sopenharmony_ci   ralloc_free(node);
512bf215546Sopenharmony_ci}
513bf215546Sopenharmony_ci
514bf215546Sopenharmony_cistatic void ppir_node_print_dest(ppir_dest *dest)
515bf215546Sopenharmony_ci{
516bf215546Sopenharmony_ci   switch (dest->type) {
517bf215546Sopenharmony_ci   case ppir_target_ssa:
518bf215546Sopenharmony_ci      printf("ssa%d", dest->ssa.index);
519bf215546Sopenharmony_ci      break;
520bf215546Sopenharmony_ci   case ppir_target_pipeline:
521bf215546Sopenharmony_ci      printf("pipeline %d", dest->pipeline);
522bf215546Sopenharmony_ci      break;
523bf215546Sopenharmony_ci   case ppir_target_register:
524bf215546Sopenharmony_ci      printf("reg %d", dest->reg->index);
525bf215546Sopenharmony_ci      break;
526bf215546Sopenharmony_ci   }
527bf215546Sopenharmony_ci}
528bf215546Sopenharmony_ci
529bf215546Sopenharmony_cistatic void ppir_node_print_src(ppir_src *src)
530bf215546Sopenharmony_ci{
531bf215546Sopenharmony_ci   switch (src->type) {
532bf215546Sopenharmony_ci   case ppir_target_ssa: {
533bf215546Sopenharmony_ci      if (src->node)
534bf215546Sopenharmony_ci         printf("ssa node %d", src->node->index);
535bf215546Sopenharmony_ci      else
536bf215546Sopenharmony_ci         printf("ssa idx %d", src->ssa ? src->ssa->index : -1);
537bf215546Sopenharmony_ci      break;
538bf215546Sopenharmony_ci   }
539bf215546Sopenharmony_ci   case ppir_target_pipeline:
540bf215546Sopenharmony_ci      if (src->node)
541bf215546Sopenharmony_ci         printf("pipeline %d node %d", src->pipeline, src->node->index);
542bf215546Sopenharmony_ci      else
543bf215546Sopenharmony_ci         printf("pipeline %d", src->pipeline);
544bf215546Sopenharmony_ci      break;
545bf215546Sopenharmony_ci   case ppir_target_register:
546bf215546Sopenharmony_ci      printf("reg %d", src->reg->index);
547bf215546Sopenharmony_ci      break;
548bf215546Sopenharmony_ci   }
549bf215546Sopenharmony_ci}
550bf215546Sopenharmony_ci
551bf215546Sopenharmony_cistatic void ppir_node_print_node(ppir_node *node, int space)
552bf215546Sopenharmony_ci{
553bf215546Sopenharmony_ci   for (int i = 0; i < space; i++)
554bf215546Sopenharmony_ci      printf(" ");
555bf215546Sopenharmony_ci
556bf215546Sopenharmony_ci   printf("%s%d: %s %s: ", node->printed && !ppir_node_is_leaf(node) ? "+" : "",
557bf215546Sopenharmony_ci          node->index, ppir_op_infos[node->op].name, node->name);
558bf215546Sopenharmony_ci
559bf215546Sopenharmony_ci   ppir_dest *dest = ppir_node_get_dest(node);
560bf215546Sopenharmony_ci   if (dest) {
561bf215546Sopenharmony_ci      printf("dest: ");
562bf215546Sopenharmony_ci      ppir_node_print_dest(dest);
563bf215546Sopenharmony_ci   }
564bf215546Sopenharmony_ci
565bf215546Sopenharmony_ci   if (ppir_node_get_src_num(node) > 0) {
566bf215546Sopenharmony_ci      printf(" src: ");
567bf215546Sopenharmony_ci   }
568bf215546Sopenharmony_ci   for (int i = 0; i < ppir_node_get_src_num(node); i++) {
569bf215546Sopenharmony_ci      ppir_node_print_src(ppir_node_get_src(node, i));
570bf215546Sopenharmony_ci      if (i != (ppir_node_get_src_num(node) - 1))
571bf215546Sopenharmony_ci         printf(", ");
572bf215546Sopenharmony_ci   }
573bf215546Sopenharmony_ci   printf("\n");
574bf215546Sopenharmony_ci
575bf215546Sopenharmony_ci   if (!node->printed) {
576bf215546Sopenharmony_ci      ppir_node_foreach_pred(node, dep) {
577bf215546Sopenharmony_ci         ppir_node *pred = dep->pred;
578bf215546Sopenharmony_ci         ppir_node_print_node(pred, space + 2);
579bf215546Sopenharmony_ci      }
580bf215546Sopenharmony_ci
581bf215546Sopenharmony_ci      node->printed = true;
582bf215546Sopenharmony_ci   }
583bf215546Sopenharmony_ci}
584bf215546Sopenharmony_ci
585bf215546Sopenharmony_civoid ppir_node_print_prog(ppir_compiler *comp)
586bf215546Sopenharmony_ci{
587bf215546Sopenharmony_ci   if (!(lima_debug & LIMA_DEBUG_PP))
588bf215546Sopenharmony_ci      return;
589bf215546Sopenharmony_ci
590bf215546Sopenharmony_ci   list_for_each_entry(ppir_block, block, &comp->block_list, list) {
591bf215546Sopenharmony_ci      list_for_each_entry(ppir_node, node, &block->node_list, list) {
592bf215546Sopenharmony_ci         node->printed = false;
593bf215546Sopenharmony_ci      }
594bf215546Sopenharmony_ci   }
595bf215546Sopenharmony_ci
596bf215546Sopenharmony_ci   printf("========prog========\n");
597bf215546Sopenharmony_ci   list_for_each_entry(ppir_block, block, &comp->block_list, list) {
598bf215546Sopenharmony_ci      printf("-------block %3d-------\n", block->index);
599bf215546Sopenharmony_ci      list_for_each_entry(ppir_node, node, &block->node_list, list) {
600bf215546Sopenharmony_ci         if (ppir_node_is_root(node))
601bf215546Sopenharmony_ci            ppir_node_print_node(node, 0);
602bf215546Sopenharmony_ci      }
603bf215546Sopenharmony_ci   }
604bf215546Sopenharmony_ci   printf("====================\n");
605bf215546Sopenharmony_ci}
606bf215546Sopenharmony_ci
607bf215546Sopenharmony_cistatic ppir_node *ppir_node_insert_mov_local(ppir_node *node)
608bf215546Sopenharmony_ci{
609bf215546Sopenharmony_ci   ppir_node *move = ppir_node_create(node->block, ppir_op_mov, -1, 0);
610bf215546Sopenharmony_ci   if (unlikely(!move))
611bf215546Sopenharmony_ci      return NULL;
612bf215546Sopenharmony_ci
613bf215546Sopenharmony_ci   ppir_dest *dest = ppir_node_get_dest(node);
614bf215546Sopenharmony_ci   ppir_alu_node *alu = ppir_node_to_alu(move);
615bf215546Sopenharmony_ci   alu->dest = *dest;
616bf215546Sopenharmony_ci   alu->num_src = 1;
617bf215546Sopenharmony_ci   ppir_node_target_assign(alu->src, node);
618bf215546Sopenharmony_ci
619bf215546Sopenharmony_ci   for (int s = 0; s < 4; s++)
620bf215546Sopenharmony_ci      alu->src->swizzle[s] = s;
621bf215546Sopenharmony_ci
622bf215546Sopenharmony_ci   ppir_node_replace_all_succ(move, node);
623bf215546Sopenharmony_ci   ppir_node_add_dep(move, node, ppir_dep_src);
624bf215546Sopenharmony_ci   list_addtail(&move->list, &node->list);
625bf215546Sopenharmony_ci
626bf215546Sopenharmony_ci   if (node->is_out) {
627bf215546Sopenharmony_ci      node->is_out = false;
628bf215546Sopenharmony_ci      move->is_out = true;
629bf215546Sopenharmony_ci   }
630bf215546Sopenharmony_ci
631bf215546Sopenharmony_ci   return move;
632bf215546Sopenharmony_ci}
633bf215546Sopenharmony_ci
634bf215546Sopenharmony_cippir_node *ppir_node_insert_mov(ppir_node *old)
635bf215546Sopenharmony_ci{
636bf215546Sopenharmony_ci   ppir_node *move = ppir_node_insert_mov_local(old);
637bf215546Sopenharmony_ci   ppir_compiler *comp = old->block->comp;
638bf215546Sopenharmony_ci
639bf215546Sopenharmony_ci   list_for_each_entry(ppir_block, block, &comp->block_list, list) {
640bf215546Sopenharmony_ci      if (old->block == block)
641bf215546Sopenharmony_ci         continue;
642bf215546Sopenharmony_ci      list_for_each_entry_safe(ppir_node, node, &block->node_list, list) {
643bf215546Sopenharmony_ci         for (int i = 0; i < ppir_node_get_src_num(node); i++){
644bf215546Sopenharmony_ci            ppir_src *src = ppir_node_get_src(node, i);
645bf215546Sopenharmony_ci            if (!src)
646bf215546Sopenharmony_ci               continue;
647bf215546Sopenharmony_ci            if (src->node == old)
648bf215546Sopenharmony_ci               ppir_node_target_assign(src, move);
649bf215546Sopenharmony_ci         }
650bf215546Sopenharmony_ci      }
651bf215546Sopenharmony_ci   }
652bf215546Sopenharmony_ci
653bf215546Sopenharmony_ci   return move;
654bf215546Sopenharmony_ci}
655bf215546Sopenharmony_ci
656bf215546Sopenharmony_cibool ppir_node_has_single_src_succ(ppir_node *node)
657bf215546Sopenharmony_ci{
658bf215546Sopenharmony_ci   if (ppir_node_has_single_succ(node) &&
659bf215546Sopenharmony_ci       list_first_entry(&node->succ_list,
660bf215546Sopenharmony_ci                        ppir_dep, succ_link)->type == ppir_dep_src)
661bf215546Sopenharmony_ci      return true;
662bf215546Sopenharmony_ci
663bf215546Sopenharmony_ci   int cnt = 0;
664bf215546Sopenharmony_ci   ppir_node_foreach_succ(node, dep) {
665bf215546Sopenharmony_ci      if (dep->type != ppir_dep_src)
666bf215546Sopenharmony_ci         continue;
667bf215546Sopenharmony_ci      cnt++;
668bf215546Sopenharmony_ci   }
669bf215546Sopenharmony_ci
670bf215546Sopenharmony_ci   return cnt == 1;
671bf215546Sopenharmony_ci}
672