lima/gp: Support exp2 and log2
[mesa.git] / src / gallium / drivers / lima / ir / gp / codegen.c
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
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 [GPIR_INSTR_SLOT_BRANCH] = {
49 gpir_codegen_src_unused, gpir_codegen_src_unused, gpir_codegen_src_unused },
50
51 [GPIR_INSTR_SLOT_REG0_LOAD0] = {
52 gpir_codegen_src_attrib_x, gpir_codegen_src_p1_attrib_x, gpir_codegen_src_unused },
53 [GPIR_INSTR_SLOT_REG0_LOAD1] = {
54 gpir_codegen_src_attrib_y, gpir_codegen_src_p1_attrib_y, gpir_codegen_src_unused },
55 [GPIR_INSTR_SLOT_REG0_LOAD2] = {
56 gpir_codegen_src_attrib_z, gpir_codegen_src_p1_attrib_z, gpir_codegen_src_unused },
57 [GPIR_INSTR_SLOT_REG0_LOAD3] = {
58 gpir_codegen_src_attrib_w, gpir_codegen_src_p1_attrib_w, gpir_codegen_src_unused },
59
60 [GPIR_INSTR_SLOT_REG1_LOAD0] = {
61 gpir_codegen_src_register_x, gpir_codegen_src_unused, gpir_codegen_src_unused},
62 [GPIR_INSTR_SLOT_REG1_LOAD1] = {
63 gpir_codegen_src_register_y, gpir_codegen_src_unused, gpir_codegen_src_unused},
64 [GPIR_INSTR_SLOT_REG1_LOAD2] = {
65 gpir_codegen_src_register_z, gpir_codegen_src_unused, gpir_codegen_src_unused},
66 [GPIR_INSTR_SLOT_REG1_LOAD3] = {
67 gpir_codegen_src_register_w, gpir_codegen_src_unused, gpir_codegen_src_unused},
68
69 [GPIR_INSTR_SLOT_MEM_LOAD0] = {
70 gpir_codegen_src_load_x, gpir_codegen_src_unused, gpir_codegen_src_unused },
71 [GPIR_INSTR_SLOT_MEM_LOAD1] = {
72 gpir_codegen_src_load_y, gpir_codegen_src_unused, gpir_codegen_src_unused },
73 [GPIR_INSTR_SLOT_MEM_LOAD2] = {
74 gpir_codegen_src_load_z, gpir_codegen_src_unused, gpir_codegen_src_unused },
75 [GPIR_INSTR_SLOT_MEM_LOAD3] = {
76 gpir_codegen_src_load_w, gpir_codegen_src_unused, gpir_codegen_src_unused },
77 };
78
79 int diff = child->sched.instr->index - parent->sched.instr->index;
80 assert(diff < 3);
81 assert(diff >= 0);
82
83 int src = slot_to_src[child->sched.pos][diff];
84 assert(src != gpir_codegen_src_unused);
85 return src;
86 }
87
88 static void gpir_codegen_mul0_slot(gpir_codegen_instr *code, gpir_instr *instr)
89 {
90 gpir_node *node = instr->slots[GPIR_INSTR_SLOT_MUL0];
91
92 if (!node) {
93 code->mul0_src0 = gpir_codegen_src_unused;
94 code->mul0_src1 = gpir_codegen_src_unused;
95 return;
96 }
97
98 gpir_alu_node *alu = gpir_node_to_alu(node);
99
100 switch (node->op) {
101 case gpir_op_mul:
102 code->mul0_src0 = gpir_get_alu_input(node, alu->children[0]);
103 code->mul0_src1 = gpir_get_alu_input(node, alu->children[1]);
104 if (code->mul0_src1 == gpir_codegen_src_p1_complex) {
105 /* Will get confused with gpir_codegen_src_ident, so need to swap inputs */
106 code->mul0_src1 = code->mul0_src0;
107 code->mul0_src0 = gpir_codegen_src_p1_complex;
108 }
109
110 code->mul0_neg = alu->dest_negate;
111 if (alu->children_negate[0])
112 code->mul0_neg = !code->mul0_neg;
113 if (alu->children_negate[1])
114 code->mul0_neg = !code->mul0_neg;
115 break;
116
117 case gpir_op_neg:
118 code->mul0_neg = true;
119 case gpir_op_mov:
120 code->mul0_src0 = gpir_get_alu_input(node, alu->children[0]);
121 code->mul0_src1 = gpir_codegen_src_ident;
122 break;
123
124 case gpir_op_complex1:
125 code->mul0_src0 = gpir_get_alu_input(node, alu->children[0]);
126 code->mul0_src1 = gpir_get_alu_input(node, alu->children[1]);
127 code->mul_op = gpir_codegen_mul_op_complex1;
128 break;
129
130 case gpir_op_complex2:
131 code->mul0_src0 = gpir_get_alu_input(node, alu->children[0]);
132 code->mul0_src1 = code->mul0_src0;
133 code->mul_op = gpir_codegen_mul_op_complex2;
134 break;
135
136 case gpir_op_select:
137 code->mul0_src0 = gpir_get_alu_input(node, alu->children[2]);
138 code->mul0_src1 = gpir_get_alu_input(node, alu->children[0]);
139 code->mul_op = gpir_codegen_mul_op_select;
140 break;
141
142 default:
143 assert(0);
144 }
145 }
146
147 static void gpir_codegen_mul1_slot(gpir_codegen_instr *code, gpir_instr *instr)
148 {
149 gpir_node *node = instr->slots[GPIR_INSTR_SLOT_MUL1];
150
151 if (!node) {
152 code->mul1_src0 = gpir_codegen_src_unused;
153 code->mul1_src1 = gpir_codegen_src_unused;
154 return;
155 }
156
157 gpir_alu_node *alu = gpir_node_to_alu(node);
158
159 switch (node->op) {
160 case gpir_op_mul:
161 code->mul1_src0 = gpir_get_alu_input(node, alu->children[0]);
162 code->mul1_src1 = gpir_get_alu_input(node, alu->children[1]);
163 if (code->mul1_src1 == gpir_codegen_src_p1_complex) {
164 /* Will get confused with gpir_codegen_src_ident, so need to swap inputs */
165 code->mul1_src1 = code->mul1_src0;
166 code->mul1_src0 = gpir_codegen_src_p1_complex;
167 }
168
169 code->mul1_neg = alu->dest_negate;
170 if (alu->children_negate[0])
171 code->mul1_neg = !code->mul1_neg;
172 if (alu->children_negate[1])
173 code->mul1_neg = !code->mul1_neg;
174 break;
175
176 case gpir_op_neg:
177 code->mul1_neg = true;
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
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 case gpir_op_mov:
271 code->acc_op = gpir_codegen_acc_op_add;
272 code->acc0_src0 = gpir_get_alu_input(node, alu->children[0]);
273 code->acc0_src1 = gpir_codegen_src_ident;
274 code->acc0_src1_neg = true;
275 break;
276
277 default:
278 assert(0);
279 }
280 }
281
282 static void gpir_codegen_add1_slot(gpir_codegen_instr *code, gpir_instr *instr)
283 {
284 gpir_node *node = instr->slots[GPIR_INSTR_SLOT_ADD1];
285
286 if (!node) {
287 code->acc1_src0 = gpir_codegen_src_unused;
288 code->acc1_src1 = gpir_codegen_src_unused;
289 return;
290 }
291
292 gpir_alu_node *alu = gpir_node_to_alu(node);
293
294 switch (node->op) {
295 case gpir_op_add:
296 case gpir_op_min:
297 case gpir_op_max:
298 case gpir_op_lt:
299 case gpir_op_ge:
300 code->acc1_src0 = gpir_get_alu_input(node, alu->children[0]);
301 code->acc1_src1 = gpir_get_alu_input(node, alu->children[1]);
302
303 code->acc1_src0_neg = alu->children_negate[0];
304 code->acc1_src1_neg = alu->children_negate[1];
305
306 switch (node->op) {
307 case gpir_op_add:
308 code->acc_op = gpir_codegen_acc_op_add;
309 if (code->acc1_src1 == gpir_codegen_src_p1_complex) {
310 code->acc1_src1 = code->acc1_src0;
311 code->acc1_src0 = gpir_codegen_src_p1_complex;
312
313 bool tmp = code->acc1_src0_neg;
314 code->acc1_src0_neg = code->acc1_src1_neg;
315 code->acc1_src1_neg = tmp;
316 }
317 break;
318 case gpir_op_min:
319 code->acc_op = gpir_codegen_acc_op_min;
320 break;
321 case gpir_op_max:
322 code->acc_op = gpir_codegen_acc_op_max;
323 break;
324 case gpir_op_lt:
325 code->acc_op = gpir_codegen_acc_op_lt;
326 break;
327 case gpir_op_ge:
328 code->acc_op = gpir_codegen_acc_op_ge;
329 break;
330 default:
331 assert(0);
332 }
333
334 break;
335
336 case gpir_op_floor:
337 case gpir_op_sign:
338 code->acc1_src0 = gpir_get_alu_input(node, alu->children[0]);
339 code->acc1_src0_neg = alu->children_negate[0];
340 switch (node->op) {
341 case gpir_op_floor:
342 code->acc_op = gpir_codegen_acc_op_floor;
343 break;
344 case gpir_op_sign:
345 code->acc_op = gpir_codegen_acc_op_sign;
346 break;
347 default:
348 assert(0);
349 }
350 break;
351
352 case gpir_op_neg:
353 code->acc1_src0_neg = true;
354 case gpir_op_mov:
355 code->acc_op = gpir_codegen_acc_op_add;
356 code->acc1_src0 = gpir_get_alu_input(node, alu->children[0]);
357 code->acc1_src1 = gpir_codegen_src_ident;
358 code->acc1_src1_neg = true;
359 break;
360
361 default:
362 assert(0);
363 }
364 }
365
366 static void gpir_codegen_complex_slot(gpir_codegen_instr *code, gpir_instr *instr)
367 {
368 gpir_node *node = instr->slots[GPIR_INSTR_SLOT_COMPLEX];
369
370 if (!node) {
371 code->complex_src = gpir_codegen_src_unused;
372 return;
373 }
374
375 switch (node->op) {
376 case gpir_op_mov:
377 case gpir_op_rcp_impl:
378 case gpir_op_rsqrt_impl:
379 case gpir_op_exp2_impl:
380 case gpir_op_log2_impl:
381 {
382 gpir_alu_node *alu = gpir_node_to_alu(node);
383 code->complex_src = gpir_get_alu_input(node, alu->children[0]);
384 break;
385 }
386 default:
387 assert(0);
388 }
389
390 switch (node->op) {
391 case gpir_op_mov:
392 code->complex_op = gpir_codegen_complex_op_pass;
393 break;
394 case gpir_op_rcp_impl:
395 code->complex_op = gpir_codegen_complex_op_rcp;
396 break;
397 case gpir_op_rsqrt_impl:
398 code->complex_op = gpir_codegen_complex_op_rsqrt;
399 break;
400 case gpir_op_exp2_impl:
401 code->complex_op = gpir_codegen_complex_op_exp2;
402 break;
403 case gpir_op_log2_impl:
404 code->complex_op = gpir_codegen_complex_op_log2;
405 break;
406 default:
407 assert(0);
408 }
409 }
410
411 static void gpir_codegen_pass_slot(gpir_codegen_instr *code, gpir_instr *instr)
412 {
413 gpir_node *node = instr->slots[GPIR_INSTR_SLOT_PASS];
414
415 if (!node) {
416 code->pass_op = gpir_codegen_pass_op_pass;
417 code->pass_src = gpir_codegen_src_unused;
418 return;
419 }
420
421 gpir_alu_node *alu = gpir_node_to_alu(node);
422 code->pass_src = gpir_get_alu_input(node, alu->children[0]);
423
424 switch (node->op) {
425 case gpir_op_mov:
426 code->pass_op = gpir_codegen_pass_op_pass;
427 break;
428 case gpir_op_preexp2:
429 code->pass_op = gpir_codegen_pass_op_preexp2;
430 break;
431 case gpir_op_postlog2:
432 code->pass_op = gpir_codegen_pass_op_postlog2;
433 break;
434 default:
435 assert(0);
436 }
437 }
438
439 static void gpir_codegen_branch_slot(gpir_codegen_instr *code, gpir_instr *instr)
440 {
441 gpir_node *node = instr->slots[GPIR_INSTR_SLOT_BRANCH];
442
443 if (!node)
444 return;
445
446 assert(0);
447 }
448
449 static void gpir_codegen_reg0_slot(gpir_codegen_instr *code, gpir_instr *instr)
450 {
451 if (!instr->reg0_use_count)
452 return;
453
454 code->register0_attribute = instr->reg0_is_attr;
455 code->register0_addr = instr->reg0_index;
456 }
457
458 static void gpir_codegen_reg1_slot(gpir_codegen_instr *code, gpir_instr *instr)
459 {
460 if (!instr->reg1_use_count)
461 return;
462
463 code->register1_addr = instr->reg1_index;
464 }
465
466 static void gpir_codegen_mem_slot(gpir_codegen_instr *code, gpir_instr *instr)
467 {
468 if (!instr->mem_use_count) {
469 code->load_offset = gpir_codegen_load_off_none;
470 return;
471 }
472
473 code->load_addr = instr->mem_index;
474 code->load_offset = gpir_codegen_load_off_none;
475 }
476
477 static gpir_codegen_store_src gpir_get_store_input(gpir_node *node)
478 {
479 static int slot_to_src[GPIR_INSTR_SLOT_NUM] = {
480 [GPIR_INSTR_SLOT_MUL0] = gpir_codegen_store_src_mul_0,
481 [GPIR_INSTR_SLOT_MUL1] = gpir_codegen_store_src_mul_1,
482 [GPIR_INSTR_SLOT_ADD0] = gpir_codegen_store_src_acc_0,
483 [GPIR_INSTR_SLOT_ADD1] = gpir_codegen_store_src_acc_1,
484 [GPIR_INSTR_SLOT_COMPLEX] = gpir_codegen_store_src_complex,
485 [GPIR_INSTR_SLOT_PASS] = gpir_codegen_store_src_pass,
486 [GPIR_INSTR_SLOT_BRANCH...GPIR_INSTR_SLOT_STORE3] = gpir_codegen_store_src_none,
487 };
488
489 gpir_store_node *store = gpir_node_to_store(node);
490 return slot_to_src[store->child->sched.pos];
491 }
492
493 static void gpir_codegen_store_slot(gpir_codegen_instr *code, gpir_instr *instr)
494 {
495
496 gpir_node *node = instr->slots[GPIR_INSTR_SLOT_STORE0];
497 if (node)
498 code->store0_src_x = gpir_get_store_input(node);
499 else
500 code->store0_src_x = gpir_codegen_store_src_none;
501
502 node = instr->slots[GPIR_INSTR_SLOT_STORE1];
503 if (node)
504 code->store0_src_y = gpir_get_store_input(node);
505 else
506 code->store0_src_y = gpir_codegen_store_src_none;
507
508 node = instr->slots[GPIR_INSTR_SLOT_STORE2];
509 if (node)
510 code->store1_src_z = gpir_get_store_input(node);
511 else
512 code->store1_src_z = gpir_codegen_store_src_none;
513
514 node = instr->slots[GPIR_INSTR_SLOT_STORE3];
515 if (node)
516 code->store1_src_w = gpir_get_store_input(node);
517 else
518 code->store1_src_w = gpir_codegen_store_src_none;
519
520 if (instr->store_content[0] == GPIR_INSTR_STORE_TEMP) {
521 code->store0_temporary = true;
522 code->unknown_1 = 12;
523 }
524 else {
525 code->store0_varying = instr->store_content[0] == GPIR_INSTR_STORE_VARYING;
526 code->store0_addr = instr->store_index[0];
527 }
528
529 if (instr->store_content[1] == GPIR_INSTR_STORE_TEMP) {
530 code->store1_temporary = true;
531 code->unknown_1 = 12;
532 }
533 else {
534 code->store1_varying = instr->store_content[1] == GPIR_INSTR_STORE_VARYING;
535 code->store1_addr = instr->store_index[1];
536 }
537 }
538
539 static void gpir_codegen(gpir_codegen_instr *code, gpir_instr *instr)
540 {
541 gpir_codegen_mul0_slot(code, instr);
542 gpir_codegen_mul1_slot(code, instr);
543
544 gpir_codegen_add0_slot(code, instr);
545 gpir_codegen_add1_slot(code, instr);
546
547 gpir_codegen_complex_slot(code, instr);
548 gpir_codegen_pass_slot(code, instr);
549 gpir_codegen_branch_slot(code, instr);
550
551 gpir_codegen_reg0_slot(code, instr);
552 gpir_codegen_reg1_slot(code, instr);
553 gpir_codegen_mem_slot(code, instr);
554
555 gpir_codegen_store_slot(code, instr);
556 }
557
558 static void gpir_codegen_print_prog(gpir_compiler *comp)
559 {
560 uint32_t *data = comp->prog->shader;
561 int size = comp->prog->shader_size;
562 int num_instr = size / sizeof(gpir_codegen_instr);
563 int num_dword_per_instr = sizeof(gpir_codegen_instr) / sizeof(uint32_t);
564
565 for (int i = 0; i < num_instr; i++) {
566 printf("%03d: ", i);
567 for (int j = 0; j < num_dword_per_instr; j++)
568 printf("%08x ", data[i * num_dword_per_instr + j]);
569 printf("\n");
570 }
571 }
572
573 bool gpir_codegen_prog(gpir_compiler *comp)
574 {
575 int num_instr = 0;
576 list_for_each_entry(gpir_block, block, &comp->block_list, list) {
577 num_instr += list_length(&block->instr_list);
578 }
579
580 if (num_instr > 512) {
581 gpir_error("shader too big (%d), GP has a 512 instruction limit.\n",
582 num_instr);
583 return false;
584 }
585
586 gpir_codegen_instr *code = rzalloc_array(comp->prog, gpir_codegen_instr, num_instr);
587 if (!code)
588 return false;
589
590 int instr_index = 0;
591 list_for_each_entry(gpir_block, block, &comp->block_list, list) {
592 list_for_each_entry(gpir_instr, instr, &block->instr_list, list) {
593 gpir_codegen(code + instr_index, instr);
594 instr_index++;
595 }
596 }
597
598 for (int i = 0; i < num_instr; i++) {
599 if (code[i].register0_attribute)
600 comp->prog->prefetch = i;
601 }
602
603 comp->prog->shader = code;
604 comp->prog->shader_size = num_instr * sizeof(gpir_codegen_instr);
605
606 if (lima_debug & LIMA_DEBUG_GP) {
607 gpir_codegen_print_prog(comp);
608 gpir_disassemble_program(code, num_instr);
609 }
610
611 return true;
612 }
613
614 static gpir_codegen_acc_op gpir_codegen_get_acc_op(gpir_op op)
615 {
616 switch (op) {
617 case gpir_op_add:
618 case gpir_op_neg:
619 case gpir_op_mov:
620 return gpir_codegen_acc_op_add;
621 case gpir_op_min:
622 return gpir_codegen_acc_op_min;
623 case gpir_op_max:
624 return gpir_codegen_acc_op_max;
625 case gpir_op_lt:
626 return gpir_codegen_acc_op_lt;
627 case gpir_op_ge:
628 return gpir_codegen_acc_op_ge;
629 case gpir_op_floor:
630 return gpir_codegen_acc_op_floor;
631 case gpir_op_sign:
632 return gpir_codegen_acc_op_sign;
633 default:
634 assert(0);
635 }
636 return -1;
637 }
638
639 bool gpir_codegen_acc_same_op(gpir_op op1, gpir_op op2)
640 {
641 return gpir_codegen_get_acc_op(op1) == gpir_codegen_get_acc_op(op2);
642 }