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