Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/lima/ir/gp/codegen.c
4574 views
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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);
612
}
613
614
return true;
615
}
616
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
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
647