• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017 Lima Project
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sub license,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the
12  * next paragraph) shall be included in all copies or substantial portions
13  * of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  *
23  */
24 
25 #include "util/ralloc.h"
26 
27 #include "gpir.h"
28 #include "codegen.h"
29 #include "lima_context.h"
30 
gpir_get_alu_input(gpir_node * parent,gpir_node * child)31 static gpir_codegen_src gpir_get_alu_input(gpir_node *parent, gpir_node *child)
32 {
33    static const int slot_to_src[GPIR_INSTR_SLOT_NUM][3] = {
34       [GPIR_INSTR_SLOT_MUL0] = {
35          gpir_codegen_src_unused, gpir_codegen_src_p1_mul_0, gpir_codegen_src_p2_mul_0 },
36       [GPIR_INSTR_SLOT_MUL1] = {
37          gpir_codegen_src_unused, gpir_codegen_src_p1_mul_1, gpir_codegen_src_p2_mul_1 },
38 
39       [GPIR_INSTR_SLOT_ADD0] = {
40          gpir_codegen_src_unused, gpir_codegen_src_p1_acc_0, gpir_codegen_src_p2_acc_0 },
41       [GPIR_INSTR_SLOT_ADD1] = {
42          gpir_codegen_src_unused, gpir_codegen_src_p1_acc_1, gpir_codegen_src_p2_acc_1 },
43 
44       [GPIR_INSTR_SLOT_COMPLEX] = {
45          gpir_codegen_src_unused, gpir_codegen_src_p1_complex, gpir_codegen_src_unused },
46       [GPIR_INSTR_SLOT_PASS] = {
47          gpir_codegen_src_unused, gpir_codegen_src_p1_pass, gpir_codegen_src_p2_pass },
48 
49       [GPIR_INSTR_SLOT_REG0_LOAD0] = {
50          gpir_codegen_src_attrib_x, gpir_codegen_src_p1_attrib_x, gpir_codegen_src_unused },
51       [GPIR_INSTR_SLOT_REG0_LOAD1] = {
52          gpir_codegen_src_attrib_y, gpir_codegen_src_p1_attrib_y, gpir_codegen_src_unused },
53       [GPIR_INSTR_SLOT_REG0_LOAD2] = {
54          gpir_codegen_src_attrib_z, gpir_codegen_src_p1_attrib_z, gpir_codegen_src_unused },
55       [GPIR_INSTR_SLOT_REG0_LOAD3] = {
56          gpir_codegen_src_attrib_w, gpir_codegen_src_p1_attrib_w, gpir_codegen_src_unused },
57 
58       [GPIR_INSTR_SLOT_REG1_LOAD0] = {
59          gpir_codegen_src_register_x, gpir_codegen_src_unused, gpir_codegen_src_unused},
60       [GPIR_INSTR_SLOT_REG1_LOAD1] = {
61          gpir_codegen_src_register_y, gpir_codegen_src_unused, gpir_codegen_src_unused},
62       [GPIR_INSTR_SLOT_REG1_LOAD2] = {
63          gpir_codegen_src_register_z, gpir_codegen_src_unused, gpir_codegen_src_unused},
64       [GPIR_INSTR_SLOT_REG1_LOAD3] = {
65          gpir_codegen_src_register_w, gpir_codegen_src_unused, gpir_codegen_src_unused},
66 
67       [GPIR_INSTR_SLOT_MEM_LOAD0] = {
68          gpir_codegen_src_load_x, gpir_codegen_src_unused, gpir_codegen_src_unused },
69       [GPIR_INSTR_SLOT_MEM_LOAD1] = {
70          gpir_codegen_src_load_y, gpir_codegen_src_unused, gpir_codegen_src_unused },
71       [GPIR_INSTR_SLOT_MEM_LOAD2] = {
72          gpir_codegen_src_load_z, gpir_codegen_src_unused, gpir_codegen_src_unused },
73       [GPIR_INSTR_SLOT_MEM_LOAD3] = {
74          gpir_codegen_src_load_w, gpir_codegen_src_unused, gpir_codegen_src_unused },
75    };
76 
77    int diff = child->sched.instr->index - parent->sched.instr->index;
78    assert(diff < 3);
79    assert(diff >= 0);
80 
81    int src = slot_to_src[child->sched.pos][diff];
82    assert(src != gpir_codegen_src_unused);
83    return src;
84 }
85 
gpir_codegen_mul0_slot(gpir_codegen_instr * code,gpir_instr * instr)86 static void gpir_codegen_mul0_slot(gpir_codegen_instr *code, gpir_instr *instr)
87 {
88    gpir_node *node = instr->slots[GPIR_INSTR_SLOT_MUL0];
89 
90    if (!node) {
91       code->mul0_src0 = gpir_codegen_src_unused;
92       code->mul0_src1 = gpir_codegen_src_unused;
93       return;
94    }
95 
96    gpir_alu_node *alu = gpir_node_to_alu(node);
97 
98    switch (node->op) {
99    case gpir_op_mul:
100       code->mul0_src0 = gpir_get_alu_input(node, alu->children[0]);
101       code->mul0_src1 = gpir_get_alu_input(node, alu->children[1]);
102       if (code->mul0_src1 == gpir_codegen_src_p1_complex) {
103          /* Will get confused with gpir_codegen_src_ident, so need to swap inputs */
104          code->mul0_src1 = code->mul0_src0;
105          code->mul0_src0 = gpir_codegen_src_p1_complex;
106       }
107 
108       code->mul0_neg = alu->dest_negate;
109       if (alu->children_negate[0])
110          code->mul0_neg = !code->mul0_neg;
111       if (alu->children_negate[1])
112          code->mul0_neg = !code->mul0_neg;
113       break;
114 
115    case gpir_op_neg:
116       code->mul0_neg = true;
117       FALLTHROUGH;
118    case gpir_op_mov:
119       code->mul0_src0 = gpir_get_alu_input(node, alu->children[0]);
120       code->mul0_src1 = gpir_codegen_src_ident;
121       break;
122 
123    case gpir_op_complex1:
124       code->mul0_src0 = gpir_get_alu_input(node, alu->children[0]);
125       code->mul0_src1 = gpir_get_alu_input(node, alu->children[1]);
126       code->mul_op = gpir_codegen_mul_op_complex1;
127       break;
128 
129    case gpir_op_complex2:
130       code->mul0_src0 = gpir_get_alu_input(node, alu->children[0]);
131       code->mul0_src1 = code->mul0_src0;
132       code->mul_op = gpir_codegen_mul_op_complex2;
133       break;
134 
135    case gpir_op_select:
136       code->mul0_src0 = gpir_get_alu_input(node, alu->children[2]);
137       code->mul0_src1 = gpir_get_alu_input(node, alu->children[0]);
138       code->mul_op = gpir_codegen_mul_op_select;
139       break;
140 
141    default:
142       assert(0);
143    }
144 }
145 
gpir_codegen_mul1_slot(gpir_codegen_instr * code,gpir_instr * instr)146 static void gpir_codegen_mul1_slot(gpir_codegen_instr *code, gpir_instr *instr)
147 {
148    gpir_node *node = instr->slots[GPIR_INSTR_SLOT_MUL1];
149 
150    if (!node) {
151       code->mul1_src0 = gpir_codegen_src_unused;
152       code->mul1_src1 = gpir_codegen_src_unused;
153       return;
154    }
155 
156    gpir_alu_node *alu = gpir_node_to_alu(node);
157 
158    switch (node->op) {
159    case gpir_op_mul:
160       code->mul1_src0 = gpir_get_alu_input(node, alu->children[0]);
161       code->mul1_src1 = gpir_get_alu_input(node, alu->children[1]);
162       if (code->mul1_src1 == gpir_codegen_src_p1_complex) {
163          /* Will get confused with gpir_codegen_src_ident, so need to swap inputs */
164          code->mul1_src1 = code->mul1_src0;
165          code->mul1_src0 = gpir_codegen_src_p1_complex;
166       }
167 
168       code->mul1_neg = alu->dest_negate;
169       if (alu->children_negate[0])
170          code->mul1_neg = !code->mul1_neg;
171       if (alu->children_negate[1])
172          code->mul1_neg = !code->mul1_neg;
173       break;
174 
175    case gpir_op_neg:
176       code->mul1_neg = true;
177       FALLTHROUGH;
178    case gpir_op_mov:
179       code->mul1_src0 = gpir_get_alu_input(node, alu->children[0]);
180       code->mul1_src1 = gpir_codegen_src_ident;
181       break;
182 
183    case gpir_op_complex1:
184       code->mul1_src0 = gpir_get_alu_input(node, alu->children[0]);
185       code->mul1_src1 = gpir_get_alu_input(node, alu->children[2]);
186       break;
187 
188    case gpir_op_select:
189       code->mul1_src0 = gpir_get_alu_input(node, alu->children[1]);
190       code->mul1_src1 = gpir_codegen_src_unused;
191       break;
192 
193    default:
194       assert(0);
195    }
196 }
197 
gpir_codegen_add0_slot(gpir_codegen_instr * code,gpir_instr * instr)198 static void gpir_codegen_add0_slot(gpir_codegen_instr *code, gpir_instr *instr)
199 {
200    gpir_node *node = instr->slots[GPIR_INSTR_SLOT_ADD0];
201 
202    if (!node) {
203       code->acc0_src0 = gpir_codegen_src_unused;
204       code->acc0_src1 = gpir_codegen_src_unused;
205       return;
206    }
207 
208    gpir_alu_node *alu = gpir_node_to_alu(node);
209 
210    switch (node->op) {
211    case gpir_op_add:
212    case gpir_op_min:
213    case gpir_op_max:
214    case gpir_op_lt:
215    case gpir_op_ge:
216       code->acc0_src0 = gpir_get_alu_input(node, alu->children[0]);
217       code->acc0_src1 = gpir_get_alu_input(node, alu->children[1]);
218 
219       code->acc0_src0_neg = alu->children_negate[0];
220       code->acc0_src1_neg = alu->children_negate[1];
221 
222       switch (node->op) {
223       case gpir_op_add:
224          code->acc_op = gpir_codegen_acc_op_add;
225          if (code->acc0_src1 == gpir_codegen_src_p1_complex) {
226             code->acc0_src1 = code->acc0_src0;
227             code->acc0_src0 = gpir_codegen_src_p1_complex;
228 
229             bool tmp = code->acc0_src0_neg;
230             code->acc0_src0_neg = code->acc0_src1_neg;
231             code->acc0_src1_neg = tmp;
232          }
233          break;
234       case gpir_op_min:
235          code->acc_op = gpir_codegen_acc_op_min;
236          break;
237       case gpir_op_max:
238          code->acc_op = gpir_codegen_acc_op_max;
239          break;
240       case gpir_op_lt:
241          code->acc_op = gpir_codegen_acc_op_lt;
242          break;
243       case gpir_op_ge:
244          code->acc_op = gpir_codegen_acc_op_ge;
245          break;
246       default:
247          assert(0);
248       }
249 
250       break;
251 
252    case gpir_op_floor:
253    case gpir_op_sign:
254       code->acc0_src0 = gpir_get_alu_input(node, alu->children[0]);
255       code->acc0_src0_neg = alu->children_negate[0];
256       switch (node->op) {
257       case gpir_op_floor:
258          code->acc_op = gpir_codegen_acc_op_floor;
259          break;
260       case gpir_op_sign:
261          code->acc_op = gpir_codegen_acc_op_sign;
262          break;
263       default:
264          assert(0);
265       }
266       break;
267 
268    case gpir_op_neg:
269       code->acc0_src0_neg = true;
270       FALLTHROUGH;
271    case gpir_op_mov:
272       code->acc_op = gpir_codegen_acc_op_add;
273       code->acc0_src0 = gpir_get_alu_input(node, alu->children[0]);
274       code->acc0_src1 = gpir_codegen_src_ident;
275       code->acc0_src1_neg = true;
276       break;
277 
278    default:
279       assert(0);
280    }
281 }
282 
gpir_codegen_add1_slot(gpir_codegen_instr * code,gpir_instr * instr)283 static void gpir_codegen_add1_slot(gpir_codegen_instr *code, gpir_instr *instr)
284 {
285    gpir_node *node = instr->slots[GPIR_INSTR_SLOT_ADD1];
286 
287    if (!node) {
288       code->acc1_src0 = gpir_codegen_src_unused;
289       code->acc1_src1 = gpir_codegen_src_unused;
290       return;
291    }
292 
293    gpir_alu_node *alu = gpir_node_to_alu(node);
294 
295    switch (node->op) {
296    case gpir_op_add:
297    case gpir_op_min:
298    case gpir_op_max:
299    case gpir_op_lt:
300    case gpir_op_ge:
301       code->acc1_src0 = gpir_get_alu_input(node, alu->children[0]);
302       code->acc1_src1 = gpir_get_alu_input(node, alu->children[1]);
303 
304       code->acc1_src0_neg = alu->children_negate[0];
305       code->acc1_src1_neg = alu->children_negate[1];
306 
307       switch (node->op) {
308       case gpir_op_add:
309          code->acc_op = gpir_codegen_acc_op_add;
310          if (code->acc1_src1 == gpir_codegen_src_p1_complex) {
311             code->acc1_src1 = code->acc1_src0;
312             code->acc1_src0 = gpir_codegen_src_p1_complex;
313 
314             bool tmp = code->acc1_src0_neg;
315             code->acc1_src0_neg = code->acc1_src1_neg;
316             code->acc1_src1_neg = tmp;
317          }
318          break;
319       case gpir_op_min:
320          code->acc_op = gpir_codegen_acc_op_min;
321          break;
322       case gpir_op_max:
323          code->acc_op = gpir_codegen_acc_op_max;
324          break;
325       case gpir_op_lt:
326          code->acc_op = gpir_codegen_acc_op_lt;
327          break;
328       case gpir_op_ge:
329          code->acc_op = gpir_codegen_acc_op_ge;
330          break;
331       default:
332          assert(0);
333       }
334 
335       break;
336 
337    case gpir_op_floor:
338    case gpir_op_sign:
339       code->acc1_src0 = gpir_get_alu_input(node, alu->children[0]);
340       code->acc1_src0_neg = alu->children_negate[0];
341       switch (node->op) {
342       case gpir_op_floor:
343          code->acc_op = gpir_codegen_acc_op_floor;
344          break;
345       case gpir_op_sign:
346          code->acc_op = gpir_codegen_acc_op_sign;
347          break;
348       default:
349          assert(0);
350       }
351       break;
352 
353    case gpir_op_neg:
354       code->acc1_src0_neg = true;
355       FALLTHROUGH;
356    case gpir_op_mov:
357       code->acc_op = gpir_codegen_acc_op_add;
358       code->acc1_src0 = gpir_get_alu_input(node, alu->children[0]);
359       code->acc1_src1 = gpir_codegen_src_ident;
360       code->acc1_src1_neg = true;
361       break;
362 
363    default:
364       assert(0);
365    }
366 }
367 
gpir_codegen_complex_slot(gpir_codegen_instr * code,gpir_instr * instr)368 static void gpir_codegen_complex_slot(gpir_codegen_instr *code, gpir_instr *instr)
369 {
370    gpir_node *node = instr->slots[GPIR_INSTR_SLOT_COMPLEX];
371 
372    if (!node) {
373       code->complex_src = gpir_codegen_src_unused;
374       return;
375    }
376 
377    switch (node->op) {
378    case gpir_op_mov:
379    case gpir_op_rcp_impl:
380    case gpir_op_rsqrt_impl:
381    case gpir_op_exp2_impl:
382    case gpir_op_log2_impl:
383    {
384       gpir_alu_node *alu = gpir_node_to_alu(node);
385       code->complex_src = gpir_get_alu_input(node, alu->children[0]);
386       break;
387    }
388    default:
389       assert(0);
390    }
391 
392    switch (node->op) {
393    case gpir_op_mov:
394       code->complex_op = gpir_codegen_complex_op_pass;
395       break;
396    case gpir_op_rcp_impl:
397       code->complex_op = gpir_codegen_complex_op_rcp;
398       break;
399    case gpir_op_rsqrt_impl:
400       code->complex_op = gpir_codegen_complex_op_rsqrt;
401       break;
402    case gpir_op_exp2_impl:
403       code->complex_op = gpir_codegen_complex_op_exp2;
404       break;
405    case gpir_op_log2_impl:
406       code->complex_op = gpir_codegen_complex_op_log2;
407       break;
408    default:
409       assert(0);
410    }
411 }
412 
gpir_codegen_pass_slot(gpir_codegen_instr * code,gpir_instr * instr)413 static void gpir_codegen_pass_slot(gpir_codegen_instr *code, gpir_instr *instr)
414 {
415    gpir_node *node = instr->slots[GPIR_INSTR_SLOT_PASS];
416 
417    if (!node) {
418       code->pass_op = gpir_codegen_pass_op_pass;
419       code->pass_src = gpir_codegen_src_unused;
420       return;
421    }
422 
423    if (node->op == gpir_op_branch_cond) {
424       gpir_branch_node *branch = gpir_node_to_branch(node);
425 
426       code->pass_op = gpir_codegen_pass_op_pass;
427       code->pass_src = gpir_get_alu_input(node, branch->cond);
428 
429       /* Fill out branch information */
430       unsigned offset = branch->dest->instr_offset;
431       assert(offset < 0x200);
432       code->branch = true;
433       code->branch_target = offset & 0xff;
434       code->branch_target_lo = !(offset >> 8);
435       code->unknown_1 = 13;
436       return;
437    }
438 
439    gpir_alu_node *alu = gpir_node_to_alu(node);
440    code->pass_src = gpir_get_alu_input(node, alu->children[0]);
441 
442    switch (node->op) {
443    case gpir_op_mov:
444       code->pass_op = gpir_codegen_pass_op_pass;
445       break;
446    case gpir_op_preexp2:
447       code->pass_op = gpir_codegen_pass_op_preexp2;
448       break;
449    case gpir_op_postlog2:
450       code->pass_op = gpir_codegen_pass_op_postlog2;
451       break;
452    default:
453       assert(0);
454    }
455 
456 }
457 
gpir_codegen_reg0_slot(gpir_codegen_instr * code,gpir_instr * instr)458 static void gpir_codegen_reg0_slot(gpir_codegen_instr *code, gpir_instr *instr)
459 {
460    if (!instr->reg0_use_count)
461       return;
462 
463    code->register0_attribute = instr->reg0_is_attr;
464    code->register0_addr = instr->reg0_index;
465 }
466 
gpir_codegen_reg1_slot(gpir_codegen_instr * code,gpir_instr * instr)467 static void gpir_codegen_reg1_slot(gpir_codegen_instr *code, gpir_instr *instr)
468 {
469    if (!instr->reg1_use_count)
470       return;
471 
472    code->register1_addr = instr->reg1_index;
473 }
474 
gpir_codegen_mem_slot(gpir_codegen_instr * code,gpir_instr * instr)475 static void gpir_codegen_mem_slot(gpir_codegen_instr *code, gpir_instr *instr)
476 {
477    if (!instr->mem_use_count) {
478       code->load_offset = gpir_codegen_load_off_none;
479       return;
480    }
481 
482    code->load_addr = instr->mem_index;
483    code->load_offset = gpir_codegen_load_off_none;
484 }
485 
gpir_get_store_input(gpir_node * node)486 static gpir_codegen_store_src gpir_get_store_input(gpir_node *node)
487 {
488    static int slot_to_src[GPIR_INSTR_SLOT_NUM] = {
489       [GPIR_INSTR_SLOT_MUL0] = gpir_codegen_store_src_mul_0,
490       [GPIR_INSTR_SLOT_MUL1] = gpir_codegen_store_src_mul_1,
491       [GPIR_INSTR_SLOT_ADD0] = gpir_codegen_store_src_acc_0,
492       [GPIR_INSTR_SLOT_ADD1] = gpir_codegen_store_src_acc_1,
493       [GPIR_INSTR_SLOT_COMPLEX] = gpir_codegen_store_src_complex,
494       [GPIR_INSTR_SLOT_PASS] = gpir_codegen_store_src_pass,
495       [GPIR_INSTR_SLOT_REG0_LOAD0...GPIR_INSTR_SLOT_STORE3] = gpir_codegen_store_src_none,
496    };
497 
498    gpir_store_node *store = gpir_node_to_store(node);
499    return slot_to_src[store->child->sched.pos];
500 }
501 
gpir_codegen_store_slot(gpir_codegen_instr * code,gpir_instr * instr)502 static void gpir_codegen_store_slot(gpir_codegen_instr *code, gpir_instr *instr)
503 {
504 
505    gpir_node *node = instr->slots[GPIR_INSTR_SLOT_STORE0];
506    if (node)
507       code->store0_src_x = gpir_get_store_input(node);
508    else
509       code->store0_src_x = gpir_codegen_store_src_none;
510 
511    node = instr->slots[GPIR_INSTR_SLOT_STORE1];
512    if (node)
513       code->store0_src_y = gpir_get_store_input(node);
514    else
515       code->store0_src_y = gpir_codegen_store_src_none;
516 
517    node = instr->slots[GPIR_INSTR_SLOT_STORE2];
518    if (node)
519       code->store1_src_z = gpir_get_store_input(node);
520    else
521       code->store1_src_z = gpir_codegen_store_src_none;
522 
523    node = instr->slots[GPIR_INSTR_SLOT_STORE3];
524    if (node)
525       code->store1_src_w = gpir_get_store_input(node);
526    else
527       code->store1_src_w = gpir_codegen_store_src_none;
528 
529    if (instr->store_content[0] == GPIR_INSTR_STORE_TEMP) {
530       code->store0_temporary = true;
531       code->unknown_1 = 12;
532    }
533    else {
534       code->store0_varying = instr->store_content[0] == GPIR_INSTR_STORE_VARYING;
535       code->store0_addr = instr->store_index[0];
536    }
537 
538    if (instr->store_content[1] == GPIR_INSTR_STORE_TEMP) {
539       code->store1_temporary = true;
540       code->unknown_1 = 12;
541    }
542    else {
543       code->store1_varying = instr->store_content[1] == GPIR_INSTR_STORE_VARYING;
544       code->store1_addr = instr->store_index[1];
545    }
546 }
547 
gpir_codegen(gpir_codegen_instr * code,gpir_instr * instr)548 static void gpir_codegen(gpir_codegen_instr *code, gpir_instr *instr)
549 {
550    gpir_codegen_mul0_slot(code, instr);
551    gpir_codegen_mul1_slot(code, instr);
552 
553    gpir_codegen_add0_slot(code, instr);
554    gpir_codegen_add1_slot(code, instr);
555 
556    gpir_codegen_complex_slot(code, instr);
557    gpir_codegen_pass_slot(code, instr);
558 
559    gpir_codegen_reg0_slot(code, instr);
560    gpir_codegen_reg1_slot(code, instr);
561    gpir_codegen_mem_slot(code, instr);
562 
563    gpir_codegen_store_slot(code, instr);
564 }
565 
gpir_codegen_print_prog(gpir_compiler * comp)566 static void gpir_codegen_print_prog(gpir_compiler *comp)
567 {
568    uint32_t *data = comp->prog->shader;
569    int num_dword_per_instr = sizeof(gpir_codegen_instr) / sizeof(uint32_t);
570 
571    for (int i = 0; i < comp->num_instr; i++) {
572       printf("%03d: ", i);
573       for (int j = 0; j < num_dword_per_instr; j++)
574          printf("%08x ", data[i * num_dword_per_instr + j]);
575       printf("\n");
576    }
577 }
578 
gpir_codegen_prog(gpir_compiler * comp)579 bool gpir_codegen_prog(gpir_compiler *comp)
580 {
581    int num_instr = 0;
582    list_for_each_entry(gpir_block, block, &comp->block_list, list) {
583       block->instr_offset = num_instr;
584       num_instr += list_length(&block->instr_list);
585    }
586 
587    assert(num_instr <= 512);
588 
589    gpir_codegen_instr *code = rzalloc_array(comp->prog, gpir_codegen_instr, num_instr);
590    if (!code)
591       return false;
592 
593    int instr_index = 0;
594    list_for_each_entry(gpir_block, block, &comp->block_list, list) {
595       list_for_each_entry(gpir_instr, instr, &block->instr_list, list) {
596          gpir_codegen(code + instr_index, instr);
597          instr_index++;
598       }
599    }
600 
601    for (int i = 0; i < num_instr; i++) {
602       if (code[i].register0_attribute)
603          comp->prog->state.prefetch = i;
604    }
605 
606    comp->prog->shader = code;
607    comp->prog->state.shader_size = num_instr * sizeof(gpir_codegen_instr);
608 
609    if (lima_debug & LIMA_DEBUG_GP) {
610       gpir_codegen_print_prog(comp);
611       gpir_disassemble_program(code, num_instr, stdout);
612    }
613 
614    return true;
615 }
616 
gpir_codegen_get_acc_op(gpir_op op)617 static gpir_codegen_acc_op gpir_codegen_get_acc_op(gpir_op op)
618 {
619    switch (op) {
620    case gpir_op_add:
621    case gpir_op_neg:
622    case gpir_op_mov:
623       return gpir_codegen_acc_op_add;
624    case gpir_op_min:
625       return gpir_codegen_acc_op_min;
626    case gpir_op_max:
627       return gpir_codegen_acc_op_max;
628    case gpir_op_lt:
629       return gpir_codegen_acc_op_lt;
630    case gpir_op_ge:
631       return gpir_codegen_acc_op_ge;
632    case gpir_op_floor:
633       return gpir_codegen_acc_op_floor;
634    case gpir_op_sign:
635       return gpir_codegen_acc_op_sign;
636    default:
637       assert(0);
638    }
639    return -1;
640 }
641 
gpir_codegen_acc_same_op(gpir_op op1,gpir_op op2)642 bool gpir_codegen_acc_same_op(gpir_op op1, gpir_op op2)
643 {
644    return gpir_codegen_get_acc_op(op1) == gpir_codegen_get_acc_op(op2);
645 }
646