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 31static 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 86static 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 146static 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 198static 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 283static 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 368static 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 413static 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 458static 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 467static 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 475static 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 486static 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 502static 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 548static 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 566static 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 579bool 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 617static 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 642bool 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