1 /* 2 * Copyright(c) 2019-2022 rev.ng Labs Srl. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #include <assert.h> 19 #include <inttypes.h> 20 #include <stdarg.h> 21 #include <stdbool.h> 22 #include <stdint.h> 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <unistd.h> 27 28 #include "idef-parser.h" 29 #include "parser-helpers.h" 30 #include "idef-parser.tab.h" 31 #include "idef-parser.yy.h" 32 33 void yyerror(YYLTYPE *locp, 34 yyscan_t scanner __attribute__((unused)), 35 Context *c, 36 const char *s) 37 { 38 const char *code_ptr = c->input_buffer; 39 40 fprintf(stderr, "WARNING (%s): '%s'\n", c->inst.name->str, s); 41 42 fprintf(stderr, "Problematic range: "); 43 for (int i = locp->first_column; i < locp->last_column; i++) { 44 if (code_ptr[i] != '\n') { 45 fprintf(stderr, "%c", code_ptr[i]); 46 } 47 } 48 fprintf(stderr, "\n"); 49 50 for (unsigned i = 0; 51 i < 80 && 52 code_ptr[locp->first_column - 10 + i] != '\0' && 53 code_ptr[locp->first_column - 10 + i] != '\n'; 54 i++) { 55 fprintf(stderr, "%c", code_ptr[locp->first_column - 10 + i]); 56 } 57 fprintf(stderr, "\n"); 58 for (unsigned i = 0; i < 9; i++) { 59 fprintf(stderr, " "); 60 } 61 fprintf(stderr, "^"); 62 for (int i = 0; i < (locp->last_column - locp->first_column) - 1; i++) { 63 fprintf(stderr, "~"); 64 } 65 fprintf(stderr, "\n"); 66 c->inst.error_count++; 67 } 68 69 bool is_direct_predicate(HexValue *value) 70 { 71 return value->pred.id >= '0' && value->pred.id <= '3'; 72 } 73 74 bool is_inside_ternary(Context *c) 75 { 76 return c->ternary->len > 0; 77 } 78 79 /* Print functions */ 80 void str_print(Context *c, YYLTYPE *locp, const char *string) 81 { 82 (void) locp; 83 EMIT(c, "%s", string); 84 } 85 86 void uint8_print(Context *c, YYLTYPE *locp, uint8_t *num) 87 { 88 (void) locp; 89 EMIT(c, "%u", *num); 90 } 91 92 void uint64_print(Context *c, YYLTYPE *locp, uint64_t *num) 93 { 94 (void) locp; 95 EMIT(c, "%" PRIu64, *num); 96 } 97 98 void int_print(Context *c, YYLTYPE *locp, int *num) 99 { 100 (void) locp; 101 EMIT(c, "%d", *num); 102 } 103 104 void uint_print(Context *c, YYLTYPE *locp, unsigned *num) 105 { 106 (void) locp; 107 EMIT(c, "%u", *num); 108 } 109 110 void tmp_print(Context *c, YYLTYPE *locp, HexTmp *tmp) 111 { 112 (void) locp; 113 EMIT(c, "tmp_%d", tmp->index); 114 } 115 116 void pred_print(Context *c, YYLTYPE *locp, HexPred *pred, bool is_dotnew) 117 { 118 (void) locp; 119 char suffix = is_dotnew ? 'N' : 'V'; 120 EMIT(c, "P%c%c", pred->id, suffix); 121 } 122 123 void reg_compose(Context *c, YYLTYPE *locp, HexReg *reg, char reg_id[5]) 124 { 125 memset(reg_id, 0, 5 * sizeof(char)); 126 switch (reg->type) { 127 case GENERAL_PURPOSE: 128 reg_id[0] = 'R'; 129 break; 130 case CONTROL: 131 reg_id[0] = 'C'; 132 break; 133 case MODIFIER: 134 reg_id[0] = 'M'; 135 break; 136 case DOTNEW: 137 reg_id[0] = 'N'; 138 reg_id[1] = reg->id; 139 reg_id[2] = 'N'; 140 return; 141 } 142 switch (reg->bit_width) { 143 case 32: 144 reg_id[1] = reg->id; 145 reg_id[2] = 'V'; 146 break; 147 case 64: 148 reg_id[1] = reg->id; 149 reg_id[2] = reg->id; 150 reg_id[3] = 'V'; 151 break; 152 default: 153 yyassert(c, locp, false, "Unhandled register bit width!\n"); 154 } 155 } 156 157 static void reg_arg_print(Context *c, YYLTYPE *locp, HexReg *reg) 158 { 159 char reg_id[5]; 160 reg_compose(c, locp, reg, reg_id); 161 EMIT(c, "%s", reg_id); 162 } 163 164 void reg_print(Context *c, YYLTYPE *locp, HexReg *reg) 165 { 166 (void) locp; 167 EMIT(c, "hex_gpr[%u]", reg->id); 168 } 169 170 void imm_print(Context *c, YYLTYPE *locp, HexImm *imm) 171 { 172 switch (imm->type) { 173 case I: 174 EMIT(c, "i"); 175 break; 176 case VARIABLE: 177 EMIT(c, "%ciV", imm->id); 178 break; 179 case VALUE: 180 EMIT(c, "((int64_t) %" PRIu64 "ULL)", (int64_t) imm->value); 181 break; 182 case QEMU_TMP: 183 EMIT(c, "qemu_tmp_%" PRIu64, imm->index); 184 break; 185 case IMM_PC: 186 EMIT(c, "ctx->base.pc_next"); 187 break; 188 case IMM_NPC: 189 EMIT(c, "ctx->npc"); 190 break; 191 case IMM_CONSTEXT: 192 EMIT(c, "insn->extension_valid"); 193 break; 194 default: 195 yyassert(c, locp, false, "Cannot print this expression!"); 196 } 197 } 198 199 void var_print(Context *c, YYLTYPE *locp, HexVar *var) 200 { 201 (void) locp; 202 EMIT(c, "%s", var->name->str); 203 } 204 205 void rvalue_print(Context *c, YYLTYPE *locp, void *pointer) 206 { 207 HexValue *rvalue = (HexValue *) pointer; 208 switch (rvalue->type) { 209 case REGISTER: 210 reg_print(c, locp, &rvalue->reg); 211 break; 212 case REGISTER_ARG: 213 reg_arg_print(c, locp, &rvalue->reg); 214 break; 215 case TEMP: 216 tmp_print(c, locp, &rvalue->tmp); 217 break; 218 case IMMEDIATE: 219 imm_print(c, locp, &rvalue->imm); 220 break; 221 case VARID: 222 var_print(c, locp, &rvalue->var); 223 break; 224 case PREDICATE: 225 pred_print(c, locp, &rvalue->pred, rvalue->is_dotnew); 226 break; 227 default: 228 yyassert(c, locp, false, "Cannot print this expression!"); 229 } 230 } 231 232 void out_assert(Context *c, YYLTYPE *locp, 233 void *dummy __attribute__((unused))) 234 { 235 yyassert(c, locp, false, "Unhandled print type!"); 236 } 237 238 /* Copy output code buffer */ 239 void commit(Context *c) 240 { 241 /* Emit instruction pseudocode */ 242 EMIT_SIG(c, "\n" START_COMMENT " "); 243 for (char *x = c->inst.code_begin; x < c->inst.code_end; x++) { 244 EMIT_SIG(c, "%c", *x); 245 } 246 EMIT_SIG(c, " " END_COMMENT "\n"); 247 248 /* Commit instruction code to output file */ 249 fwrite(c->signature_str->str, sizeof(char), c->signature_str->len, 250 c->output_file); 251 fwrite(c->header_str->str, sizeof(char), c->header_str->len, 252 c->output_file); 253 fwrite(c->out_str->str, sizeof(char), c->out_str->len, 254 c->output_file); 255 256 fwrite(c->signature_str->str, sizeof(char), c->signature_str->len, 257 c->defines_file); 258 fprintf(c->defines_file, ";\n"); 259 } 260 261 static void gen_c_int_type(Context *c, YYLTYPE *locp, unsigned bit_width, 262 HexSignedness signedness) 263 { 264 const char *signstr = (signedness == UNSIGNED) ? "u" : ""; 265 OUT(c, locp, signstr, "int", &bit_width, "_t"); 266 } 267 268 static HexValue gen_constant(Context *c, 269 YYLTYPE *locp, 270 const char *value, 271 unsigned bit_width, 272 HexSignedness signedness) 273 { 274 HexValue rvalue; 275 assert(bit_width == 32 || bit_width == 64); 276 memset(&rvalue, 0, sizeof(HexValue)); 277 rvalue.type = TEMP; 278 rvalue.bit_width = bit_width; 279 rvalue.signedness = signedness; 280 rvalue.is_dotnew = false; 281 rvalue.is_manual = true; 282 rvalue.tmp.index = c->inst.tmp_count; 283 OUT(c, locp, "TCGv_i", &bit_width, " tmp_", &c->inst.tmp_count, 284 " = tcg_constant_i", &bit_width, "(", value, ");\n"); 285 c->inst.tmp_count++; 286 return rvalue; 287 } 288 289 /* Temporary values creation */ 290 HexValue gen_tmp(Context *c, 291 YYLTYPE *locp, 292 unsigned bit_width, 293 HexSignedness signedness) 294 { 295 HexValue rvalue; 296 assert(bit_width == 32 || bit_width == 64); 297 memset(&rvalue, 0, sizeof(HexValue)); 298 rvalue.type = TEMP; 299 rvalue.bit_width = bit_width; 300 rvalue.signedness = signedness; 301 rvalue.is_dotnew = false; 302 rvalue.is_manual = false; 303 rvalue.tmp.index = c->inst.tmp_count; 304 OUT(c, locp, "TCGv_i", &bit_width, " tmp_", &c->inst.tmp_count, 305 " = tcg_temp_new_i", &bit_width, "();\n"); 306 c->inst.tmp_count++; 307 return rvalue; 308 } 309 310 HexValue gen_tmp_value(Context *c, 311 YYLTYPE *locp, 312 const char *value, 313 unsigned bit_width, 314 HexSignedness signedness) 315 { 316 HexValue rvalue; 317 assert(bit_width == 32 || bit_width == 64); 318 memset(&rvalue, 0, sizeof(HexValue)); 319 rvalue.type = TEMP; 320 rvalue.bit_width = bit_width; 321 rvalue.signedness = signedness; 322 rvalue.is_dotnew = false; 323 rvalue.is_manual = false; 324 rvalue.tmp.index = c->inst.tmp_count; 325 OUT(c, locp, "TCGv_i", &bit_width, " tmp_", &c->inst.tmp_count, 326 " = tcg_const_i", &bit_width, "(", value, ");\n"); 327 c->inst.tmp_count++; 328 return rvalue; 329 } 330 331 static HexValue gen_tmp_value_from_imm(Context *c, 332 YYLTYPE *locp, 333 HexValue *value) 334 { 335 HexValue rvalue; 336 assert(value->type == IMMEDIATE); 337 memset(&rvalue, 0, sizeof(HexValue)); 338 rvalue.type = TEMP; 339 rvalue.bit_width = value->bit_width; 340 rvalue.signedness = value->signedness; 341 rvalue.is_dotnew = false; 342 rvalue.is_manual = false; 343 rvalue.tmp.index = c->inst.tmp_count; 344 /* 345 * Here we output the call to `tcg_const_i<width>` in 346 * order to create the temporary value. Note, that we 347 * add a cast 348 * 349 * `tcg_const_i<width>`((int<width>_t) ...)` 350 * 351 * This cast is required to avoid implicit integer 352 * conversion warnings since all immediates are 353 * output as `((int64_t) 123ULL)`, even if the 354 * integer is 32-bit. 355 */ 356 OUT(c, locp, "TCGv_i", &rvalue.bit_width, " tmp_", &c->inst.tmp_count); 357 OUT(c, locp, " = tcg_const_i", &rvalue.bit_width, 358 "((int", &rvalue.bit_width, "_t) (", value, "));\n"); 359 360 c->inst.tmp_count++; 361 return rvalue; 362 } 363 364 HexValue gen_imm_value(Context *c __attribute__((unused)), 365 YYLTYPE *locp, 366 int value, 367 unsigned bit_width, 368 HexSignedness signedness) 369 { 370 (void) locp; 371 HexValue rvalue; 372 assert(bit_width == 32 || bit_width == 64); 373 memset(&rvalue, 0, sizeof(HexValue)); 374 rvalue.type = IMMEDIATE; 375 rvalue.bit_width = bit_width; 376 rvalue.signedness = signedness; 377 rvalue.is_dotnew = false; 378 rvalue.is_manual = false; 379 rvalue.imm.type = VALUE; 380 rvalue.imm.value = value; 381 return rvalue; 382 } 383 384 HexValue gen_imm_qemu_tmp(Context *c, YYLTYPE *locp, unsigned bit_width, 385 HexSignedness signedness) 386 { 387 (void) locp; 388 HexValue rvalue; 389 assert(bit_width == 32 || bit_width == 64); 390 memset(&rvalue, 0, sizeof(HexValue)); 391 rvalue.type = IMMEDIATE; 392 rvalue.is_dotnew = false; 393 rvalue.is_manual = false; 394 rvalue.bit_width = bit_width; 395 rvalue.signedness = signedness; 396 rvalue.imm.type = QEMU_TMP; 397 rvalue.imm.index = c->inst.qemu_tmp_count++; 398 return rvalue; 399 } 400 401 void gen_rvalue_free(Context *c, YYLTYPE *locp, HexValue *rvalue) 402 { 403 if (rvalue->type == TEMP && !rvalue->is_manual) { 404 const char *bit_suffix = (rvalue->bit_width == 64) ? "i64" : "i32"; 405 OUT(c, locp, "tcg_temp_free_", bit_suffix, "(", rvalue, ");\n"); 406 } 407 } 408 409 static void gen_rvalue_free_manual(Context *c, YYLTYPE *locp, HexValue *rvalue) 410 { 411 rvalue->is_manual = false; 412 gen_rvalue_free(c, locp, rvalue); 413 } 414 415 HexValue rvalue_materialize(Context *c, YYLTYPE *locp, HexValue *rvalue) 416 { 417 if (rvalue->type == IMMEDIATE) { 418 HexValue res = gen_tmp_value_from_imm(c, locp, rvalue); 419 gen_rvalue_free(c, locp, rvalue); 420 return res; 421 } 422 return *rvalue; 423 } 424 425 HexValue gen_rvalue_extend(Context *c, YYLTYPE *locp, HexValue *rvalue) 426 { 427 assert_signedness(c, locp, rvalue->signedness); 428 if (rvalue->bit_width > 32) { 429 return *rvalue; 430 } 431 432 if (rvalue->type == IMMEDIATE) { 433 HexValue res = gen_imm_qemu_tmp(c, locp, 64, rvalue->signedness); 434 bool is_unsigned = (rvalue->signedness == UNSIGNED); 435 const char *sign_suffix = is_unsigned ? "u" : ""; 436 gen_c_int_type(c, locp, 64, rvalue->signedness); 437 OUT(c, locp, " ", &res, " = "); 438 OUT(c, locp, "(", sign_suffix, "int64_t) "); 439 OUT(c, locp, "(", sign_suffix, "int32_t) "); 440 OUT(c, locp, rvalue, ";\n"); 441 return res; 442 } else { 443 HexValue res = gen_tmp(c, locp, 64, rvalue->signedness); 444 bool is_unsigned = (rvalue->signedness == UNSIGNED); 445 const char *sign_suffix = is_unsigned ? "u" : ""; 446 OUT(c, locp, "tcg_gen_ext", sign_suffix, 447 "_i32_i64(", &res, ", ", rvalue, ");\n"); 448 gen_rvalue_free(c, locp, rvalue); 449 return res; 450 } 451 } 452 453 HexValue gen_rvalue_truncate(Context *c, YYLTYPE *locp, HexValue *rvalue) 454 { 455 if (rvalue->type == IMMEDIATE) { 456 HexValue res = *rvalue; 457 res.bit_width = 32; 458 return res; 459 } else { 460 if (rvalue->bit_width == 64) { 461 HexValue res = gen_tmp(c, locp, 32, rvalue->signedness); 462 OUT(c, locp, "tcg_gen_trunc_i64_tl(", &res, ", ", rvalue, ");\n"); 463 gen_rvalue_free(c, locp, rvalue); 464 return res; 465 } 466 } 467 return *rvalue; 468 } 469 470 /* 471 * Attempts to lookup the `Var` struct associated with the given `varid`. 472 * The `dst` argument is populated with the found name, bit_width, and 473 * signedness, given that `dst` is non-NULL. Returns true if the lookup 474 * succeeded and false otherwise. 475 */ 476 static bool try_find_variable(Context *c, YYLTYPE *locp, 477 HexValue *dst, 478 HexValue *varid) 479 { 480 yyassert(c, locp, varid, "varid to lookup is NULL"); 481 yyassert(c, locp, varid->type == VARID, 482 "Can only lookup variables by varid"); 483 for (unsigned i = 0; i < c->inst.allocated->len; i++) { 484 Var *curr = &g_array_index(c->inst.allocated, Var, i); 485 if (g_string_equal(varid->var.name, curr->name)) { 486 if (dst) { 487 dst->var.name = curr->name; 488 dst->bit_width = curr->bit_width; 489 dst->signedness = curr->signedness; 490 } 491 return true; 492 } 493 } 494 return false; 495 } 496 497 /* Calls `try_find_variable` and asserts succcess. */ 498 static void find_variable(Context *c, YYLTYPE *locp, 499 HexValue *dst, 500 HexValue *varid) 501 { 502 bool found = try_find_variable(c, locp, dst, varid); 503 yyassert(c, locp, found, "Use of undeclared variable!\n"); 504 } 505 506 /* Handle signedness, if both unsigned -> result is unsigned, else signed */ 507 static inline HexSignedness bin_op_signedness(Context *c, YYLTYPE *locp, 508 HexSignedness sign1, 509 HexSignedness sign2) 510 { 511 assert_signedness(c, locp, sign1); 512 assert_signedness(c, locp, sign2); 513 return (sign1 == UNSIGNED && sign2 == UNSIGNED) ? UNSIGNED : SIGNED; 514 } 515 516 void gen_varid_allocate(Context *c, 517 YYLTYPE *locp, 518 HexValue *varid, 519 unsigned bit_width, 520 HexSignedness signedness) 521 { 522 const char *bit_suffix = (bit_width == 64) ? "i64" : "i32"; 523 bool found = try_find_variable(c, locp, NULL, varid); 524 Var new_var; 525 526 memset(&new_var, 0, sizeof(Var)); 527 528 yyassert(c, locp, !found, "Redeclaration of variables not allowed!"); 529 assert_signedness(c, locp, signedness); 530 531 /* `varid` only carries name information */ 532 new_var.name = varid->var.name; 533 new_var.bit_width = bit_width; 534 new_var.signedness = signedness; 535 536 EMIT_HEAD(c, "TCGv_%s %s", bit_suffix, varid->var.name->str); 537 EMIT_HEAD(c, " = tcg_temp_new_%s();\n", bit_suffix); 538 g_array_append_val(c->inst.allocated, new_var); 539 } 540 541 enum OpTypes { 542 IMM_IMM = 0, 543 IMM_REG = 1, 544 REG_IMM = 2, 545 REG_REG = 3, 546 }; 547 548 HexValue gen_bin_cmp(Context *c, 549 YYLTYPE *locp, 550 TCGCond type, 551 HexValue *op1, 552 HexValue *op2) 553 { 554 HexValue op1_m = *op1; 555 HexValue op2_m = *op2; 556 enum OpTypes op_types = (op1_m.type != IMMEDIATE) << 1 557 | (op2_m.type != IMMEDIATE); 558 559 bool op_is64bit = op1_m.bit_width == 64 || op2_m.bit_width == 64; 560 const char *bit_suffix = op_is64bit ? "i64" : "i32"; 561 unsigned bit_width = (op_is64bit) ? 64 : 32; 562 HexValue res = gen_tmp(c, locp, bit_width, UNSIGNED); 563 564 /* Extend to 64-bits, if required */ 565 if (op_is64bit) { 566 op1_m = gen_rvalue_extend(c, locp, &op1_m); 567 op2_m = gen_rvalue_extend(c, locp, &op2_m); 568 } 569 570 switch (op_types) { 571 case IMM_IMM: 572 case IMM_REG: 573 yyassert(c, locp, false, "Binary comparisons between IMM op IMM and" 574 "IMM op REG not handled!"); 575 break; 576 case REG_IMM: 577 OUT(c, locp, "tcg_gen_setcondi_", bit_suffix, "("); 578 OUT(c, locp, cond_to_str(type), ", ", &res, ", ", &op1_m, ", ", &op2_m, 579 ");\n"); 580 break; 581 case REG_REG: 582 OUT(c, locp, "tcg_gen_setcond_", bit_suffix, "("); 583 OUT(c, locp, cond_to_str(type), ", ", &res, ", ", &op1_m, ", ", &op2_m, 584 ");\n"); 585 break; 586 default: 587 fprintf(stderr, "Error in evalutating immediateness!"); 588 abort(); 589 } 590 591 /* Free operands */ 592 gen_rvalue_free(c, locp, &op1_m); 593 gen_rvalue_free(c, locp, &op2_m); 594 595 return res; 596 } 597 598 static void gen_simple_op(Context *c, YYLTYPE *locp, unsigned bit_width, 599 const char *bit_suffix, HexValue *res, 600 enum OpTypes op_types, 601 HexValue *op1, 602 HexValue *op2, 603 const char *imm_imm, 604 const char *imm_reg, 605 const char *reg_imm, 606 const char *reg_reg) 607 { 608 switch (op_types) { 609 case IMM_IMM: { 610 HexSignedness signedness = bin_op_signedness(c, locp, 611 op1->signedness, 612 op2->signedness); 613 gen_c_int_type(c, locp, bit_width, signedness); 614 OUT(c, locp, " ", res, 615 " = ", op1, imm_imm, op2, ";\n"); 616 } break; 617 case IMM_REG: 618 OUT(c, locp, imm_reg, bit_suffix, 619 "(", res, ", ", op2, ", ", op1, ");\n"); 620 break; 621 case REG_IMM: 622 OUT(c, locp, reg_imm, bit_suffix, 623 "(", res, ", ", op1, ", ", op2, ");\n"); 624 break; 625 case REG_REG: 626 OUT(c, locp, reg_reg, bit_suffix, 627 "(", res, ", ", op1, ", ", op2, ");\n"); 628 break; 629 } 630 gen_rvalue_free(c, locp, op1); 631 gen_rvalue_free(c, locp, op2); 632 } 633 634 static void gen_sub_op(Context *c, YYLTYPE *locp, unsigned bit_width, 635 const char *bit_suffix, HexValue *res, 636 enum OpTypes op_types, HexValue *op1, 637 HexValue *op2) 638 { 639 switch (op_types) { 640 case IMM_IMM: { 641 HexSignedness signedness = bin_op_signedness(c, locp, 642 op1->signedness, 643 op2->signedness); 644 gen_c_int_type(c, locp, bit_width, signedness); 645 OUT(c, locp, " ", res, 646 " = ", op1, " - ", op2, ";\n"); 647 } break; 648 case IMM_REG: { 649 OUT(c, locp, "tcg_gen_subfi_", bit_suffix, 650 "(", res, ", ", op1, ", ", op2, ");\n"); 651 } break; 652 case REG_IMM: { 653 OUT(c, locp, "tcg_gen_subi_", bit_suffix, 654 "(", res, ", ", op1, ", ", op2, ");\n"); 655 } break; 656 case REG_REG: { 657 OUT(c, locp, "tcg_gen_sub_", bit_suffix, 658 "(", res, ", ", op1, ", ", op2, ");\n"); 659 } break; 660 } 661 gen_rvalue_free(c, locp, op1); 662 gen_rvalue_free(c, locp, op2); 663 } 664 665 static void gen_asl_op(Context *c, YYLTYPE *locp, unsigned bit_width, 666 bool op_is64bit, const char *bit_suffix, 667 HexValue *res, enum OpTypes op_types, 668 HexValue *op1, HexValue *op2) 669 { 670 HexValue op1_m = *op1; 671 HexValue op2_m = *op2; 672 switch (op_types) { 673 case IMM_IMM: { 674 HexSignedness signedness = bin_op_signedness(c, locp, 675 op1->signedness, 676 op2->signedness); 677 gen_c_int_type(c, locp, bit_width, signedness); 678 OUT(c, locp, " ", res, 679 " = ", op1, " << ", op2, ";\n"); 680 } break; 681 case REG_IMM: { 682 OUT(c, locp, "if (", op2, " >= ", &bit_width, ") {\n"); 683 OUT(c, locp, "tcg_gen_movi_", bit_suffix, "(", res, ", 0);\n"); 684 OUT(c, locp, "} else {\n"); 685 OUT(c, locp, "tcg_gen_shli_", bit_suffix, 686 "(", res, ", ", op1, ", ", op2, ");\n"); 687 OUT(c, locp, "}\n"); 688 } break; 689 case IMM_REG: 690 op1_m.bit_width = bit_width; 691 op1_m = rvalue_materialize(c, locp, &op1_m); 692 /* fallthrough */ 693 case REG_REG: { 694 OUT(c, locp, "tcg_gen_shl_", bit_suffix, 695 "(", res, ", ", &op1_m, ", ", op2, ");\n"); 696 } break; 697 } 698 if (op_types == IMM_REG || op_types == REG_REG) { 699 /* 700 * Handle left shift by 64/32 which hexagon-sim expects to clear out 701 * register 702 */ 703 HexValue zero = gen_constant(c, locp, "0", bit_width, UNSIGNED); 704 HexValue edge = gen_imm_value(c, locp, bit_width, bit_width, UNSIGNED); 705 edge = rvalue_materialize(c, locp, &edge); 706 if (op_is64bit) { 707 op2_m = gen_rvalue_extend(c, locp, &op2_m); 708 } 709 op1_m = rvalue_materialize(c, locp, &op1_m); 710 op2_m = rvalue_materialize(c, locp, &op2_m); 711 OUT(c, locp, "tcg_gen_movcond_i", &bit_width); 712 OUT(c, locp, "(TCG_COND_GEU, ", res, ", ", &op2_m, ", ", &edge); 713 OUT(c, locp, ", ", &zero, ", ", res, ");\n"); 714 gen_rvalue_free(c, locp, &edge); 715 } 716 gen_rvalue_free(c, locp, &op1_m); 717 gen_rvalue_free(c, locp, &op2_m); 718 } 719 720 static void gen_asr_op(Context *c, YYLTYPE *locp, unsigned bit_width, 721 bool op_is64bit, const char *bit_suffix, 722 HexValue *res, enum OpTypes op_types, 723 HexValue *op1, HexValue *op2) 724 { 725 HexValue op1_m = *op1; 726 HexValue op2_m = *op2; 727 switch (op_types) { 728 case IMM_IMM: 729 case IMM_REG: 730 yyassert(c, locp, false, "ASR between IMM op IMM, and IMM op REG" 731 " not handled!"); 732 break; 733 case REG_IMM: { 734 HexSignedness signedness = bin_op_signedness(c, locp, 735 op1->signedness, 736 op2->signedness); 737 OUT(c, locp, "{\n"); 738 gen_c_int_type(c, locp, bit_width, signedness); 739 OUT(c, locp, " shift = ", op2, ";\n"); 740 OUT(c, locp, "if (", op2, " >= ", &bit_width, ") {\n"); 741 OUT(c, locp, " shift = ", &bit_width, " - 1;\n"); 742 OUT(c, locp, "}\n"); 743 OUT(c, locp, "tcg_gen_sari_", bit_suffix, 744 "(", res, ", ", op1, ", shift);\n}\n"); 745 } break; 746 case REG_REG: 747 OUT(c, locp, "tcg_gen_sar_", bit_suffix, 748 "(", res, ", ", &op1_m, ", ", op2, ");\n"); 749 break; 750 } 751 if (op_types == REG_REG) { 752 /* Handle right shift by values >= bit_width */ 753 const char *offset = op_is64bit ? "63" : "31"; 754 HexValue tmp = gen_tmp(c, locp, bit_width, SIGNED); 755 HexValue zero = gen_constant(c, locp, "0", bit_width, SIGNED); 756 HexValue edge = gen_imm_value(c, locp, bit_width, bit_width, UNSIGNED); 757 758 edge = rvalue_materialize(c, locp, &edge); 759 if (op_is64bit) { 760 op2_m = gen_rvalue_extend(c, locp, &op2_m); 761 } 762 op1_m = rvalue_materialize(c, locp, &op1_m); 763 op2_m = rvalue_materialize(c, locp, &op2_m); 764 765 OUT(c, locp, "tcg_gen_extract_", bit_suffix, "(", 766 &tmp, ", ", &op1_m, ", ", offset, ", 1);\n"); 767 OUT(c, locp, "tcg_gen_sub_", bit_suffix, "(", 768 &tmp, ", ", &zero, ", ", &tmp, ");\n"); 769 OUT(c, locp, "tcg_gen_movcond_i", &bit_width); 770 OUT(c, locp, "(TCG_COND_GEU, ", res, ", ", &op2_m, ", ", &edge); 771 OUT(c, locp, ", ", &tmp, ", ", res, ");\n"); 772 gen_rvalue_free(c, locp, &edge); 773 gen_rvalue_free(c, locp, &tmp); 774 } 775 gen_rvalue_free(c, locp, &op1_m); 776 gen_rvalue_free(c, locp, &op2_m); 777 } 778 779 static void gen_lsr_op(Context *c, YYLTYPE *locp, unsigned bit_width, 780 bool op_is64bit, const char *bit_suffix, 781 HexValue *res, enum OpTypes op_types, 782 HexValue *op1, HexValue *op2) 783 { 784 HexValue op1_m = *op1; 785 HexValue op2_m = *op2; 786 switch (op_types) { 787 case IMM_IMM: 788 case IMM_REG: 789 yyassert(c, locp, false, "LSR between IMM op IMM, and IMM op REG" 790 " not handled!"); 791 break; 792 case REG_IMM: 793 OUT(c, locp, "if (", op2, " >= ", &bit_width, ") {\n"); 794 OUT(c, locp, "tcg_gen_movi_", bit_suffix, "(", res, ", 0);\n"); 795 OUT(c, locp, "} else {\n"); 796 OUT(c, locp, "tcg_gen_shri_", bit_suffix, 797 "(", res, ", ", op1, ", ", op2, ");\n"); 798 OUT(c, locp, "}\n"); 799 break; 800 case REG_REG: 801 OUT(c, locp, "tcg_gen_shr_", bit_suffix, 802 "(", res, ", ", &op1_m, ", ", op2, ");\n"); 803 break; 804 } 805 if (op_types == REG_REG) { 806 /* Handle right shift by values >= bit_width */ 807 HexValue zero = gen_constant(c, locp, "0", bit_width, UNSIGNED); 808 HexValue edge = gen_imm_value(c, locp, bit_width, bit_width, UNSIGNED); 809 edge = rvalue_materialize(c, locp, &edge); 810 if (op_is64bit) { 811 op2_m = gen_rvalue_extend(c, locp, &op2_m); 812 } 813 op1_m = rvalue_materialize(c, locp, &op1_m); 814 op2_m = rvalue_materialize(c, locp, &op2_m); 815 OUT(c, locp, "tcg_gen_movcond_i", &bit_width); 816 OUT(c, locp, "(TCG_COND_GEU, ", res, ", ", &op2_m, ", ", &edge); 817 OUT(c, locp, ", ", &zero, ", ", res, ");\n"); 818 gen_rvalue_free(c, locp, &edge); 819 } 820 gen_rvalue_free(c, locp, &op1_m); 821 gen_rvalue_free(c, locp, &op2_m); 822 } 823 824 /* 825 * Note: This implementation of logical `and` does not mirror that in C. 826 * We do not short-circuit logical expressions! 827 */ 828 static void gen_andl_op(Context *c, YYLTYPE *locp, unsigned bit_width, 829 const char *bit_suffix, HexValue *res, 830 enum OpTypes op_types, HexValue *op1, 831 HexValue *op2) 832 { 833 (void) bit_width; 834 HexValue tmp1, tmp2; 835 HexValue zero = gen_constant(c, locp, "0", 32, UNSIGNED); 836 memset(&tmp1, 0, sizeof(HexValue)); 837 memset(&tmp2, 0, sizeof(HexValue)); 838 switch (op_types) { 839 case IMM_IMM: 840 case IMM_REG: 841 case REG_IMM: 842 yyassert(c, locp, false, "ANDL between IMM op IMM, IMM op REG, and" 843 " REG op IMM, not handled!"); 844 break; 845 case REG_REG: 846 tmp1 = gen_bin_cmp(c, locp, TCG_COND_NE, op1, &zero); 847 tmp2 = gen_bin_cmp(c, locp, TCG_COND_NE, op2, &zero); 848 OUT(c, locp, "tcg_gen_and_", bit_suffix, 849 "(", res, ", ", &tmp1, ", ", &tmp2, ");\n"); 850 gen_rvalue_free_manual(c, locp, &zero); 851 gen_rvalue_free(c, locp, &tmp1); 852 gen_rvalue_free(c, locp, &tmp2); 853 break; 854 } 855 } 856 857 static void gen_minmax_op(Context *c, YYLTYPE *locp, unsigned bit_width, 858 HexValue *res, enum OpTypes op_types, 859 HexValue *op1, HexValue *op2, bool minmax) 860 { 861 const char *mm; 862 HexValue op1_m = *op1; 863 HexValue op2_m = *op2; 864 bool is_unsigned; 865 866 assert_signedness(c, locp, res->signedness); 867 is_unsigned = res->signedness == UNSIGNED; 868 869 if (minmax) { 870 /* Max */ 871 mm = is_unsigned ? "tcg_gen_umax" : "tcg_gen_smax"; 872 } else { 873 /* Min */ 874 mm = is_unsigned ? "tcg_gen_umin" : "tcg_gen_smin"; 875 } 876 switch (op_types) { 877 case IMM_IMM: 878 yyassert(c, locp, false, "MINMAX between IMM op IMM, not handled!"); 879 break; 880 case IMM_REG: 881 op1_m.bit_width = bit_width; 882 op1_m = rvalue_materialize(c, locp, &op1_m); 883 OUT(c, locp, mm, "_i", &bit_width, "("); 884 OUT(c, locp, res, ", ", &op1_m, ", ", op2, ");\n"); 885 break; 886 case REG_IMM: 887 op2_m.bit_width = bit_width; 888 op2_m = rvalue_materialize(c, locp, &op2_m); 889 /* Fallthrough */ 890 case REG_REG: 891 OUT(c, locp, mm, "_i", &bit_width, "("); 892 OUT(c, locp, res, ", ", op1, ", ", &op2_m, ");\n"); 893 break; 894 } 895 gen_rvalue_free(c, locp, &op1_m); 896 gen_rvalue_free(c, locp, &op2_m); 897 } 898 899 /* Code generation functions */ 900 HexValue gen_bin_op(Context *c, 901 YYLTYPE *locp, 902 OpType type, 903 HexValue *op1, 904 HexValue *op2) 905 { 906 /* Replicate operands to avoid side effects */ 907 HexValue op1_m = *op1; 908 HexValue op2_m = *op2; 909 enum OpTypes op_types; 910 bool op_is64bit; 911 HexSignedness signedness; 912 unsigned bit_width; 913 const char *bit_suffix; 914 HexValue res; 915 916 memset(&res, 0, sizeof(HexValue)); 917 918 /* 919 * If the operands are VARID's we need to look up the 920 * type information. 921 */ 922 if (op1_m.type == VARID) { 923 find_variable(c, locp, &op1_m, &op1_m); 924 } 925 if (op2_m.type == VARID) { 926 find_variable(c, locp, &op2_m, &op2_m); 927 } 928 929 op_types = (op1_m.type != IMMEDIATE) << 1 930 | (op2_m.type != IMMEDIATE); 931 op_is64bit = op1_m.bit_width == 64 || op2_m.bit_width == 64; 932 /* Shift greater than 32 are 64 bits wide */ 933 934 if (type == ASL_OP && op2_m.type == IMMEDIATE && 935 op2_m.imm.type == VALUE && op2_m.imm.value >= 32) { 936 op_is64bit = true; 937 } 938 939 bit_width = (op_is64bit) ? 64 : 32; 940 bit_suffix = op_is64bit ? "i64" : "i32"; 941 942 /* Extend to 64-bits, if required */ 943 if (op_is64bit) { 944 op1_m = gen_rvalue_extend(c, locp, &op1_m); 945 op2_m = gen_rvalue_extend(c, locp, &op2_m); 946 } 947 948 signedness = bin_op_signedness(c, locp, op1_m.signedness, op2_m.signedness); 949 if (op_types != IMM_IMM) { 950 res = gen_tmp(c, locp, bit_width, signedness); 951 } else { 952 res = gen_imm_qemu_tmp(c, locp, bit_width, signedness); 953 } 954 955 switch (type) { 956 case ADD_OP: 957 gen_simple_op(c, locp, bit_width, bit_suffix, &res, 958 op_types, &op1_m, &op2_m, 959 " + ", 960 "tcg_gen_addi_", 961 "tcg_gen_addi_", 962 "tcg_gen_add_"); 963 break; 964 case SUB_OP: 965 gen_sub_op(c, locp, bit_width, bit_suffix, &res, op_types, 966 &op1_m, &op2_m); 967 break; 968 case MUL_OP: 969 gen_simple_op(c, locp, bit_width, bit_suffix, &res, 970 op_types, &op1_m, &op2_m, 971 " * ", 972 "tcg_gen_muli_", 973 "tcg_gen_muli_", 974 "tcg_gen_mul_"); 975 break; 976 case ASL_OP: 977 gen_asl_op(c, locp, bit_width, op_is64bit, bit_suffix, &res, op_types, 978 &op1_m, &op2_m); 979 break; 980 case ASR_OP: 981 gen_asr_op(c, locp, bit_width, op_is64bit, bit_suffix, &res, op_types, 982 &op1_m, &op2_m); 983 break; 984 case LSR_OP: 985 gen_lsr_op(c, locp, bit_width, op_is64bit, bit_suffix, &res, op_types, 986 &op1_m, &op2_m); 987 break; 988 case ANDB_OP: 989 gen_simple_op(c, locp, bit_width, bit_suffix, &res, 990 op_types, &op1_m, &op2_m, 991 " & ", 992 "tcg_gen_andi_", 993 "tcg_gen_andi_", 994 "tcg_gen_and_"); 995 break; 996 case ORB_OP: 997 gen_simple_op(c, locp, bit_width, bit_suffix, &res, 998 op_types, &op1_m, &op2_m, 999 " | ", 1000 "tcg_gen_ori_", 1001 "tcg_gen_ori_", 1002 "tcg_gen_or_"); 1003 break; 1004 case XORB_OP: 1005 gen_simple_op(c, locp, bit_width, bit_suffix, &res, 1006 op_types, &op1_m, &op2_m, 1007 " ^ ", 1008 "tcg_gen_xori_", 1009 "tcg_gen_xori_", 1010 "tcg_gen_xor_"); 1011 break; 1012 case ANDL_OP: 1013 gen_andl_op(c, locp, bit_width, bit_suffix, &res, op_types, &op1_m, 1014 &op2_m); 1015 break; 1016 case MINI_OP: 1017 gen_minmax_op(c, locp, bit_width, &res, op_types, &op1_m, &op2_m, 1018 false); 1019 break; 1020 case MAXI_OP: 1021 gen_minmax_op(c, locp, bit_width, &res, op_types, &op1_m, &op2_m, true); 1022 break; 1023 } 1024 return res; 1025 } 1026 1027 HexValue gen_cast_op(Context *c, 1028 YYLTYPE *locp, 1029 HexValue *src, 1030 unsigned target_width, 1031 HexSignedness signedness) 1032 { 1033 assert_signedness(c, locp, src->signedness); 1034 if (src->bit_width == target_width) { 1035 return *src; 1036 } else if (src->type == IMMEDIATE) { 1037 HexValue res = *src; 1038 res.bit_width = target_width; 1039 res.signedness = signedness; 1040 return res; 1041 } else { 1042 HexValue res = gen_tmp(c, locp, target_width, signedness); 1043 /* Truncate */ 1044 if (src->bit_width > target_width) { 1045 OUT(c, locp, "tcg_gen_trunc_i64_tl(", &res, ", ", src, ");\n"); 1046 } else { 1047 assert_signedness(c, locp, src->signedness); 1048 if (src->signedness == UNSIGNED) { 1049 /* Extend unsigned */ 1050 OUT(c, locp, "tcg_gen_extu_i32_i64(", 1051 &res, ", ", src, ");\n"); 1052 } else { 1053 /* Extend signed */ 1054 OUT(c, locp, "tcg_gen_ext_i32_i64(", 1055 &res, ", ", src, ");\n"); 1056 } 1057 } 1058 gen_rvalue_free(c, locp, src); 1059 return res; 1060 } 1061 } 1062 1063 1064 /* 1065 * Implements an extension when the `src_width` is an immediate. 1066 * If the `value` to extend is also an immediate we use `extract/sextract` 1067 * from QEMU `bitops.h`. If `value` is a TCGv then we rely on 1068 * `tcg_gen_extract/tcg_gen_sextract`. 1069 */ 1070 static HexValue gen_extend_imm_width_op(Context *c, 1071 YYLTYPE *locp, 1072 HexValue *src_width, 1073 unsigned dst_width, 1074 HexValue *value, 1075 HexSignedness signedness) 1076 { 1077 /* 1078 * If the source width is not an immediate value, we need to guard 1079 * our extend op with if statements to handle the case where 1080 * `src_width_m` is 0. 1081 */ 1082 const char *sign_prefix; 1083 bool need_guarding; 1084 1085 assert_signedness(c, locp, signedness); 1086 assert(dst_width == 64 || dst_width == 32); 1087 assert(src_width->type == IMMEDIATE); 1088 1089 sign_prefix = (signedness == UNSIGNED) ? "" : "s"; 1090 need_guarding = (src_width->imm.type != VALUE); 1091 1092 if (src_width->imm.type == VALUE && 1093 src_width->imm.value == 0) { 1094 /* 1095 * We can bail out early if the source width is known to be zero 1096 * at translation time. 1097 */ 1098 return gen_imm_value(c, locp, 0, dst_width, signedness); 1099 } 1100 1101 if (value->type == IMMEDIATE) { 1102 /* 1103 * If both the value and source width are immediates, 1104 * we can perform the extension at translation time 1105 * using QEMUs bitops. 1106 */ 1107 HexValue res = gen_imm_qemu_tmp(c, locp, dst_width, signedness); 1108 gen_c_int_type(c, locp, dst_width, signedness); 1109 OUT(c, locp, " ", &res, " = 0;\n"); 1110 if (need_guarding) { 1111 OUT(c, locp, "if (", src_width, " != 0) {\n"); 1112 } 1113 OUT(c, locp, &res, " = ", sign_prefix, "extract", &dst_width); 1114 OUT(c, locp, "(", value, ", 0, ", src_width, ");\n"); 1115 if (need_guarding) { 1116 OUT(c, locp, "}\n"); 1117 } 1118 1119 gen_rvalue_free(c, locp, value); 1120 return res; 1121 } else { 1122 /* 1123 * If the source width is an immediate and the value to 1124 * extend is a TCGv, then use tcg_gen_extract/tcg_gen_sextract 1125 */ 1126 HexValue res = gen_tmp(c, locp, dst_width, signedness); 1127 1128 /* 1129 * If the width is an immediate value we know it is non-zero 1130 * at this point, otherwise we need an if-statement 1131 */ 1132 if (need_guarding) { 1133 OUT(c, locp, "if (", src_width, " != 0) {\n"); 1134 } 1135 OUT(c, locp, "tcg_gen_", sign_prefix, "extract_i", &dst_width); 1136 OUT(c, locp, "(", &res, ", ", value, ", 0, ", src_width, 1137 ");\n"); 1138 if (need_guarding) { 1139 OUT(c, locp, "} else {\n"); 1140 OUT(c, locp, "tcg_gen_movi_i", &dst_width, "(", &res, 1141 ", 0);\n"); 1142 OUT(c, locp, "}\n"); 1143 } 1144 1145 gen_rvalue_free(c, locp, value); 1146 return res; 1147 } 1148 } 1149 1150 /* 1151 * Implements an extension when the `src_width` is given by 1152 * a TCGv. Here we need to reimplement the behaviour of 1153 * `tcg_gen_extract` and the like using shifts and masks. 1154 */ 1155 static HexValue gen_extend_tcg_width_op(Context *c, 1156 YYLTYPE *locp, 1157 HexValue *src_width, 1158 unsigned dst_width, 1159 HexValue *value, 1160 HexSignedness signedness) 1161 { 1162 HexValue src_width_m = rvalue_materialize(c, locp, src_width); 1163 HexValue zero = gen_constant(c, locp, "0", dst_width, UNSIGNED); 1164 HexValue shift = gen_tmp(c, locp, dst_width, UNSIGNED); 1165 HexValue res; 1166 1167 assert_signedness(c, locp, signedness); 1168 assert(dst_width == 64 || dst_width == 32); 1169 assert(src_width->type != IMMEDIATE); 1170 1171 res = gen_tmp(c, locp, dst_width, signedness); 1172 1173 OUT(c, locp, "tcg_gen_subfi_i", &dst_width); 1174 OUT(c, locp, "(", &shift, ", ", &dst_width, ", ", &src_width_m, ");\n"); 1175 if (signedness == UNSIGNED) { 1176 const char *mask_str = (dst_width == 32) 1177 ? "0xffffffff" 1178 : "0xffffffffffffffff"; 1179 HexValue mask = gen_tmp_value(c, locp, mask_str, 1180 dst_width, UNSIGNED); 1181 OUT(c, locp, "tcg_gen_shr_i", &dst_width, "(", 1182 &mask, ", ", &mask, ", ", &shift, ");\n"); 1183 OUT(c, locp, "tcg_gen_and_i", &dst_width, "(", 1184 &res, ", ", value, ", ", &mask, ");\n"); 1185 gen_rvalue_free(c, locp, &mask); 1186 } else { 1187 OUT(c, locp, "tcg_gen_shl_i", &dst_width, "(", 1188 &res, ", ", value, ", ", &shift, ");\n"); 1189 OUT(c, locp, "tcg_gen_sar_i", &dst_width, "(", 1190 &res, ", ", &res, ", ", &shift, ");\n"); 1191 } 1192 OUT(c, locp, "tcg_gen_movcond_i", &dst_width, "(TCG_COND_EQ, ", &res, 1193 ", "); 1194 OUT(c, locp, &src_width_m, ", ", &zero, ", ", &zero, ", ", &res, 1195 ");\n"); 1196 1197 gen_rvalue_free(c, locp, &src_width_m); 1198 gen_rvalue_free(c, locp, value); 1199 gen_rvalue_free(c, locp, &shift); 1200 1201 return res; 1202 } 1203 1204 HexValue gen_extend_op(Context *c, 1205 YYLTYPE *locp, 1206 HexValue *src_width, 1207 unsigned dst_width, 1208 HexValue *value, 1209 HexSignedness signedness) 1210 { 1211 unsigned bit_width = (dst_width = 64) ? 64 : 32; 1212 HexValue value_m = *value; 1213 HexValue src_width_m = *src_width; 1214 1215 assert_signedness(c, locp, signedness); 1216 yyassert(c, locp, value_m.bit_width <= bit_width && 1217 src_width_m.bit_width <= bit_width, 1218 "Extending to a size smaller than the current size" 1219 " makes no sense"); 1220 1221 if (value_m.bit_width < bit_width) { 1222 value_m = gen_rvalue_extend(c, locp, &value_m); 1223 } 1224 1225 if (src_width_m.bit_width < bit_width) { 1226 src_width_m = gen_rvalue_extend(c, locp, &src_width_m); 1227 } 1228 1229 if (src_width_m.type == IMMEDIATE) { 1230 return gen_extend_imm_width_op(c, locp, &src_width_m, bit_width, 1231 &value_m, signedness); 1232 } else { 1233 return gen_extend_tcg_width_op(c, locp, &src_width_m, bit_width, 1234 &value_m, signedness); 1235 } 1236 } 1237 1238 /* 1239 * Implements `rdeposit` for the special case where `width` 1240 * is of TCGv type. In this case we need to reimplement the behaviour 1241 * of `tcg_gen_deposit*` using binary operations and masks/shifts. 1242 * 1243 * Note: this is the only type of `rdeposit` that occurs, meaning the 1244 * `width` is _NEVER_ of IMMEDIATE type. 1245 */ 1246 void gen_rdeposit_op(Context *c, 1247 YYLTYPE *locp, 1248 HexValue *dst, 1249 HexValue *value, 1250 HexValue *begin, 1251 HexValue *width) 1252 { 1253 /* 1254 * Otherwise if the width is not known, we fallback on reimplementing 1255 * desposit in TCG. 1256 */ 1257 HexValue begin_m = *begin; 1258 HexValue value_m = *value; 1259 HexValue width_m = *width; 1260 const char *mask_str = (dst->bit_width == 32) 1261 ? "0xffffffffUL" 1262 : "0xffffffffffffffffUL"; 1263 HexValue mask = gen_constant(c, locp, mask_str, dst->bit_width, 1264 UNSIGNED); 1265 const char *dst_width_str = (dst->bit_width == 32) ? "32" : "64"; 1266 HexValue k64 = gen_constant(c, locp, dst_width_str, dst->bit_width, 1267 UNSIGNED); 1268 HexValue res; 1269 HexValue zero; 1270 1271 assert(dst->bit_width >= value->bit_width); 1272 assert(begin->type == IMMEDIATE && begin->imm.type == VALUE); 1273 assert(dst->type == REGISTER_ARG); 1274 1275 yyassert(c, locp, width->type != IMMEDIATE, 1276 "Immediate index to rdeposit not handled!"); 1277 1278 yyassert(c, locp, value_m.bit_width == dst->bit_width && 1279 begin_m.bit_width == dst->bit_width && 1280 width_m.bit_width == dst->bit_width, 1281 "Extension/truncation should be taken care of" 1282 " before rdeposit!"); 1283 1284 width_m = rvalue_materialize(c, locp, &width_m); 1285 1286 /* 1287 * mask = 0xffffffffffffffff >> (64 - width) 1288 * mask = mask << begin 1289 * value = (value << begin) & mask 1290 * res = dst & ~mask 1291 * res = res | value 1292 * dst = (width != 0) ? res : dst 1293 */ 1294 k64 = gen_bin_op(c, locp, SUB_OP, &k64, &width_m); 1295 mask = gen_bin_op(c, locp, LSR_OP, &mask, &k64); 1296 begin_m.is_manual = true; 1297 mask = gen_bin_op(c, locp, ASL_OP, &mask, &begin_m); 1298 mask.is_manual = true; 1299 value_m = gen_bin_op(c, locp, ASL_OP, &value_m, &begin_m); 1300 value_m = gen_bin_op(c, locp, ANDB_OP, &value_m, &mask); 1301 1302 OUT(c, locp, "tcg_gen_not_i", &dst->bit_width, "(", &mask, ", ", 1303 &mask, ");\n"); 1304 mask.is_manual = false; 1305 res = gen_bin_op(c, locp, ANDB_OP, dst, &mask); 1306 res = gen_bin_op(c, locp, ORB_OP, &res, &value_m); 1307 1308 /* 1309 * We don't need to truncate `res` here, since all operations involved use 1310 * the same bit width. 1311 */ 1312 1313 /* If the width is zero, then return the identity dst = dst */ 1314 zero = gen_constant(c, locp, "0", res.bit_width, UNSIGNED); 1315 OUT(c, locp, "tcg_gen_movcond_i", &res.bit_width, "(TCG_COND_NE, ", 1316 dst); 1317 OUT(c, locp, ", ", &width_m, ", ", &zero, ", ", &res, ", ", dst, 1318 ");\n"); 1319 1320 gen_rvalue_free(c, locp, width); 1321 gen_rvalue_free(c, locp, &res); 1322 } 1323 1324 void gen_deposit_op(Context *c, 1325 YYLTYPE *locp, 1326 HexValue *dst, 1327 HexValue *value, 1328 HexValue *index, 1329 HexCast *cast) 1330 { 1331 HexValue value_m = *value; 1332 unsigned bit_width = (dst->bit_width == 64) ? 64 : 32; 1333 unsigned width = cast->bit_width; 1334 1335 yyassert(c, locp, index->type == IMMEDIATE, 1336 "Deposit index must be immediate!\n"); 1337 1338 /* 1339 * Using tcg_gen_deposit_i**(dst, dst, ...) requires dst to be 1340 * initialized. 1341 */ 1342 gen_inst_init_args(c, locp); 1343 1344 /* If the destination value is 32, truncate the value, otherwise extend */ 1345 if (dst->bit_width != value->bit_width) { 1346 if (bit_width == 32) { 1347 value_m = gen_rvalue_truncate(c, locp, &value_m); 1348 } else { 1349 value_m = gen_rvalue_extend(c, locp, &value_m); 1350 } 1351 } 1352 value_m = rvalue_materialize(c, locp, &value_m); 1353 OUT(c, locp, "tcg_gen_deposit_i", &bit_width, "(", dst, ", ", dst, ", "); 1354 OUT(c, locp, &value_m, ", ", index, " * ", &width, ", ", &width, ");\n"); 1355 gen_rvalue_free(c, locp, index); 1356 gen_rvalue_free(c, locp, &value_m); 1357 } 1358 1359 HexValue gen_rextract_op(Context *c, 1360 YYLTYPE *locp, 1361 HexValue *src, 1362 unsigned begin, 1363 unsigned width) 1364 { 1365 unsigned bit_width = (src->bit_width == 64) ? 64 : 32; 1366 HexValue res = gen_tmp(c, locp, bit_width, UNSIGNED); 1367 OUT(c, locp, "tcg_gen_extract_i", &bit_width, "(", &res); 1368 OUT(c, locp, ", ", src, ", ", &begin, ", ", &width, ");\n"); 1369 gen_rvalue_free(c, locp, src); 1370 return res; 1371 } 1372 1373 HexValue gen_extract_op(Context *c, 1374 YYLTYPE *locp, 1375 HexValue *src, 1376 HexValue *index, 1377 HexExtract *extract) 1378 { 1379 unsigned bit_width = (src->bit_width == 64) ? 64 : 32; 1380 unsigned width = extract->bit_width; 1381 const char *sign_prefix; 1382 HexValue res; 1383 1384 yyassert(c, locp, index->type == IMMEDIATE, 1385 "Extract index must be immediate!\n"); 1386 assert_signedness(c, locp, extract->signedness); 1387 1388 sign_prefix = (extract->signedness == UNSIGNED) ? "" : "s"; 1389 res = gen_tmp(c, locp, bit_width, extract->signedness); 1390 1391 OUT(c, locp, "tcg_gen_", sign_prefix, "extract_i", &bit_width, 1392 "(", &res, ", ", src); 1393 OUT(c, locp, ", ", index, " * ", &width, ", ", &width, ");\n"); 1394 1395 /* Some extract operations have bit_width != storage_bit_width */ 1396 if (extract->storage_bit_width > bit_width) { 1397 HexValue tmp = gen_tmp(c, locp, extract->storage_bit_width, 1398 extract->signedness); 1399 const char *sign_suffix = (extract->signedness == UNSIGNED) ? "u" : ""; 1400 OUT(c, locp, "tcg_gen_ext", sign_suffix, "_i32_i64(", 1401 &tmp, ", ", &res, ");\n"); 1402 gen_rvalue_free(c, locp, &res); 1403 res = tmp; 1404 } 1405 1406 gen_rvalue_free(c, locp, src); 1407 gen_rvalue_free(c, locp, index); 1408 return res; 1409 } 1410 1411 void gen_write_reg(Context *c, YYLTYPE *locp, HexValue *reg, HexValue *value) 1412 { 1413 HexValue value_m = *value; 1414 yyassert(c, locp, reg->type == REGISTER, "reg must be a register!"); 1415 value_m = gen_rvalue_truncate(c, locp, &value_m); 1416 value_m = rvalue_materialize(c, locp, &value_m); 1417 OUT(c, 1418 locp, 1419 "gen_log_reg_write(", ®->reg.id, ", ", 1420 &value_m, ");\n"); 1421 OUT(c, 1422 locp, 1423 "ctx_log_reg_write(ctx, ", ®->reg.id, 1424 ");\n"); 1425 gen_rvalue_free(c, locp, reg); 1426 gen_rvalue_free(c, locp, &value_m); 1427 } 1428 1429 void gen_assign(Context *c, 1430 YYLTYPE *locp, 1431 HexValue *dst, 1432 HexValue *value) 1433 { 1434 HexValue value_m = *value; 1435 unsigned bit_width; 1436 1437 yyassert(c, locp, !is_inside_ternary(c), 1438 "Assign in ternary not allowed!"); 1439 1440 if (dst->type == REGISTER) { 1441 gen_write_reg(c, locp, dst, &value_m); 1442 return; 1443 } 1444 1445 if (dst->type == VARID) { 1446 find_variable(c, locp, dst, dst); 1447 } 1448 bit_width = dst->bit_width == 64 ? 64 : 32; 1449 1450 if (bit_width != value_m.bit_width) { 1451 if (bit_width == 64) { 1452 value_m = gen_rvalue_extend(c, locp, &value_m); 1453 } else { 1454 value_m = gen_rvalue_truncate(c, locp, &value_m); 1455 } 1456 } 1457 1458 const char *imm_suffix = (value_m.type == IMMEDIATE) ? "i" : ""; 1459 OUT(c, locp, "tcg_gen_mov", imm_suffix, "_i", &bit_width, 1460 "(", dst, ", ", &value_m, ");\n"); 1461 1462 gen_rvalue_free(c, locp, &value_m); 1463 } 1464 1465 HexValue gen_convround(Context *c, 1466 YYLTYPE *locp, 1467 HexValue *src) 1468 { 1469 HexValue src_m = *src; 1470 unsigned bit_width = src_m.bit_width; 1471 const char *size = (bit_width == 32) ? "32" : "64"; 1472 HexValue res = gen_tmp(c, locp, bit_width, src->signedness); 1473 HexValue mask = gen_constant(c, locp, "0x3", bit_width, UNSIGNED); 1474 HexValue one = gen_constant(c, locp, "1", bit_width, UNSIGNED); 1475 HexValue and; 1476 HexValue src_p1; 1477 1478 src_m.is_manual = true; 1479 1480 and = gen_bin_op(c, locp, ANDB_OP, &src_m, &mask); 1481 src_p1 = gen_bin_op(c, locp, ADD_OP, &src_m, &one); 1482 1483 OUT(c, locp, "tcg_gen_movcond_i", size, "(TCG_COND_EQ, ", &res); 1484 OUT(c, locp, ", ", &and, ", ", &mask, ", "); 1485 OUT(c, locp, &src_p1, ", ", &src_m, ");\n"); 1486 1487 /* Free src but use the original `is_manual` value */ 1488 gen_rvalue_free(c, locp, src); 1489 1490 /* Free the rest of the values */ 1491 gen_rvalue_free(c, locp, &src_p1); 1492 1493 return res; 1494 } 1495 1496 static HexValue gen_convround_n_b(Context *c, 1497 YYLTYPE *locp, 1498 HexValue *a, 1499 HexValue *n) 1500 { 1501 HexValue one = gen_constant(c, locp, "1", 32, UNSIGNED); 1502 HexValue res = gen_tmp(c, locp, 64, UNSIGNED); 1503 HexValue tmp = gen_tmp(c, locp, 32, UNSIGNED); 1504 HexValue tmp_64 = gen_tmp(c, locp, 64, UNSIGNED); 1505 1506 assert(n->type != IMMEDIATE); 1507 OUT(c, locp, "tcg_gen_ext_i32_i64(", &res, ", ", a, ");\n"); 1508 OUT(c, locp, "tcg_gen_shl_i32(", &tmp); 1509 OUT(c, locp, ", ", &one, ", ", n, ");\n"); 1510 OUT(c, locp, "tcg_gen_and_i32(", &tmp); 1511 OUT(c, locp, ", ", &tmp, ", ", a, ");\n"); 1512 OUT(c, locp, "tcg_gen_shri_i32(", &tmp); 1513 OUT(c, locp, ", ", &tmp, ", 1);\n"); 1514 OUT(c, locp, "tcg_gen_ext_i32_i64(", &tmp_64, ", ", &tmp, ");\n"); 1515 OUT(c, locp, "tcg_gen_add_i64(", &res); 1516 OUT(c, locp, ", ", &res, ", ", &tmp_64, ");\n"); 1517 1518 gen_rvalue_free(c, locp, &tmp); 1519 gen_rvalue_free(c, locp, &tmp_64); 1520 1521 return res; 1522 } 1523 1524 static HexValue gen_convround_n_c(Context *c, 1525 YYLTYPE *locp, 1526 HexValue *a, 1527 HexValue *n) 1528 { 1529 HexValue res = gen_tmp(c, locp, 64, UNSIGNED); 1530 HexValue one = gen_constant(c, locp, "1", 32, UNSIGNED); 1531 HexValue tmp = gen_tmp(c, locp, 32, UNSIGNED); 1532 HexValue tmp_64 = gen_tmp(c, locp, 64, UNSIGNED); 1533 1534 OUT(c, locp, "tcg_gen_ext_i32_i64(", &res, ", ", a, ");\n"); 1535 OUT(c, locp, "tcg_gen_subi_i32(", &tmp); 1536 OUT(c, locp, ", ", n, ", 1);\n"); 1537 OUT(c, locp, "tcg_gen_shl_i32(", &tmp); 1538 OUT(c, locp, ", ", &one, ", ", &tmp, ");\n"); 1539 OUT(c, locp, "tcg_gen_ext_i32_i64(", &tmp_64, ", ", &tmp, ");\n"); 1540 OUT(c, locp, "tcg_gen_add_i64(", &res); 1541 OUT(c, locp, ", ", &res, ", ", &tmp_64, ");\n"); 1542 1543 gen_rvalue_free(c, locp, &one); 1544 gen_rvalue_free(c, locp, &tmp); 1545 gen_rvalue_free(c, locp, &tmp_64); 1546 1547 return res; 1548 } 1549 1550 HexValue gen_convround_n(Context *c, 1551 YYLTYPE *locp, 1552 HexValue *src, 1553 HexValue *pos) 1554 { 1555 HexValue zero = gen_constant(c, locp, "0", 64, UNSIGNED); 1556 HexValue l_32 = gen_constant(c, locp, "1", 32, UNSIGNED); 1557 HexValue cond = gen_tmp(c, locp, 32, UNSIGNED); 1558 HexValue cond_64 = gen_tmp(c, locp, 64, UNSIGNED); 1559 HexValue mask = gen_tmp(c, locp, 32, UNSIGNED); 1560 HexValue n_64 = gen_tmp(c, locp, 64, UNSIGNED); 1561 HexValue res = gen_tmp(c, locp, 64, UNSIGNED); 1562 /* If input is 64 bit cast it to 32 */ 1563 HexValue src_casted = gen_cast_op(c, locp, src, 32, src->signedness); 1564 HexValue pos_casted = gen_cast_op(c, locp, pos, 32, pos->signedness); 1565 HexValue r1; 1566 HexValue r2; 1567 HexValue r3; 1568 1569 src_casted = rvalue_materialize(c, locp, &src_casted); 1570 pos_casted = rvalue_materialize(c, locp, &pos_casted); 1571 1572 /* 1573 * r1, r2, and r3 represent the results of three different branches. 1574 * - r1 picked if pos_casted == 0 1575 * - r2 picked if (src_casted & ((1 << (pos_casted - 1)) - 1)) == 0), 1576 * that is if bits 0, ..., pos_casted-1 are all 0. 1577 * - r3 picked otherwise. 1578 */ 1579 r1 = gen_rvalue_extend(c, locp, &src_casted); 1580 r2 = gen_convround_n_b(c, locp, &src_casted, &pos_casted); 1581 r3 = gen_convround_n_c(c, locp, &src_casted, &pos_casted); 1582 1583 /* 1584 * Calculate the condition 1585 * (src_casted & ((1 << (pos_casted - 1)) - 1)) == 0), 1586 * which checks if the bits 0,...,pos-1 are all 0. 1587 */ 1588 OUT(c, locp, "tcg_gen_sub_i32(", &mask); 1589 OUT(c, locp, ", ", &pos_casted, ", ", &l_32, ");\n"); 1590 OUT(c, locp, "tcg_gen_shl_i32(", &mask); 1591 OUT(c, locp, ", ", &l_32, ", ", &mask, ");\n"); 1592 OUT(c, locp, "tcg_gen_sub_i32(", &mask); 1593 OUT(c, locp, ", ", &mask, ", ", &l_32, ");\n"); 1594 OUT(c, locp, "tcg_gen_and_i32(", &cond); 1595 OUT(c, locp, ", ", &src_casted, ", ", &mask, ");\n"); 1596 OUT(c, locp, "tcg_gen_extu_i32_i64(", &cond_64, ", ", &cond, ");\n"); 1597 1598 OUT(c, locp, "tcg_gen_ext_i32_i64(", &n_64, ", ", &pos_casted, ");\n"); 1599 1600 /* 1601 * if the bits 0, ..., pos_casted-1 are all 0, then pick r2 otherwise, 1602 * pick r3. 1603 */ 1604 OUT(c, locp, "tcg_gen_movcond_i64"); 1605 OUT(c, locp, "(TCG_COND_EQ, ", &res, ", ", &cond_64, ", ", &zero); 1606 OUT(c, locp, ", ", &r2, ", ", &r3, ");\n"); 1607 1608 /* Lastly, if the pos_casted == 0, then pick r1 */ 1609 OUT(c, locp, "tcg_gen_movcond_i64"); 1610 OUT(c, locp, "(TCG_COND_EQ, ", &res, ", ", &n_64, ", ", &zero); 1611 OUT(c, locp, ", ", &r1, ", ", &res, ");\n"); 1612 1613 /* Finally shift back val >>= n */ 1614 OUT(c, locp, "tcg_gen_shr_i64(", &res); 1615 OUT(c, locp, ", ", &res, ", ", &n_64, ");\n"); 1616 1617 gen_rvalue_free(c, locp, &src_casted); 1618 gen_rvalue_free(c, locp, &pos_casted); 1619 1620 gen_rvalue_free(c, locp, &r1); 1621 gen_rvalue_free(c, locp, &r2); 1622 gen_rvalue_free(c, locp, &r3); 1623 1624 gen_rvalue_free(c, locp, &cond); 1625 gen_rvalue_free(c, locp, &cond_64); 1626 gen_rvalue_free(c, locp, &mask); 1627 gen_rvalue_free(c, locp, &n_64); 1628 1629 res = gen_rvalue_truncate(c, locp, &res); 1630 return res; 1631 } 1632 1633 HexValue gen_round(Context *c, 1634 YYLTYPE *locp, 1635 HexValue *src, 1636 HexValue *pos) 1637 { 1638 HexValue zero = gen_constant(c, locp, "0", 64, UNSIGNED); 1639 HexValue one = gen_constant(c, locp, "1", 64, UNSIGNED); 1640 HexValue res; 1641 HexValue n_m1; 1642 HexValue shifted; 1643 HexValue sum; 1644 HexValue src_width; 1645 HexValue a; 1646 HexValue b; 1647 1648 assert_signedness(c, locp, src->signedness); 1649 yyassert(c, locp, src->bit_width <= 32, 1650 "fRNDN not implemented for bit widths > 32!"); 1651 1652 res = gen_tmp(c, locp, 64, src->signedness); 1653 1654 src_width = gen_imm_value(c, locp, src->bit_width, 32, UNSIGNED); 1655 a = gen_extend_op(c, locp, &src_width, 64, src, SIGNED); 1656 a = rvalue_materialize(c, locp, &a); 1657 1658 src_width = gen_imm_value(c, locp, 5, 32, UNSIGNED); 1659 b = gen_extend_op(c, locp, &src_width, 64, pos, UNSIGNED); 1660 b = rvalue_materialize(c, locp, &b); 1661 1662 /* Disable auto-free of values used more than once */ 1663 a.is_manual = true; 1664 b.is_manual = true; 1665 1666 n_m1 = gen_bin_op(c, locp, SUB_OP, &b, &one); 1667 shifted = gen_bin_op(c, locp, ASL_OP, &one, &n_m1); 1668 sum = gen_bin_op(c, locp, ADD_OP, &shifted, &a); 1669 1670 OUT(c, locp, "tcg_gen_movcond_i64"); 1671 OUT(c, locp, "(TCG_COND_EQ, ", &res, ", ", &b, ", ", &zero); 1672 OUT(c, locp, ", ", &a, ", ", &sum, ");\n"); 1673 1674 gen_rvalue_free_manual(c, locp, &a); 1675 gen_rvalue_free_manual(c, locp, &b); 1676 gen_rvalue_free(c, locp, &sum); 1677 1678 return res; 1679 } 1680 1681 /* Circular addressing mode with auto-increment */ 1682 void gen_circ_op(Context *c, 1683 YYLTYPE *locp, 1684 HexValue *addr, 1685 HexValue *increment, 1686 HexValue *modifier) 1687 { 1688 HexValue cs = gen_tmp(c, locp, 32, UNSIGNED); 1689 HexValue increment_m = *increment; 1690 increment_m = rvalue_materialize(c, locp, &increment_m); 1691 OUT(c, locp, "gen_read_reg(", &cs, ", HEX_REG_CS0 + MuN);\n"); 1692 OUT(c, 1693 locp, 1694 "gen_helper_fcircadd(", 1695 addr, 1696 ", ", 1697 addr, 1698 ", ", 1699 &increment_m, 1700 ", ", 1701 modifier); 1702 OUT(c, locp, ", ", &cs, ");\n"); 1703 gen_rvalue_free(c, locp, &increment_m); 1704 gen_rvalue_free(c, locp, modifier); 1705 gen_rvalue_free(c, locp, &cs); 1706 } 1707 1708 HexValue gen_locnt_op(Context *c, YYLTYPE *locp, HexValue *src) 1709 { 1710 const char *bit_suffix = src->bit_width == 64 ? "64" : "32"; 1711 HexValue src_m = *src; 1712 HexValue res; 1713 1714 assert_signedness(c, locp, src->signedness); 1715 res = gen_tmp(c, locp, src->bit_width == 64 ? 64 : 32, src->signedness); 1716 src_m = rvalue_materialize(c, locp, &src_m); 1717 OUT(c, locp, "tcg_gen_not_i", bit_suffix, "(", 1718 &res, ", ", &src_m, ");\n"); 1719 OUT(c, locp, "tcg_gen_clzi_i", bit_suffix, "(", &res, ", ", &res, ", "); 1720 OUT(c, locp, bit_suffix, ");\n"); 1721 gen_rvalue_free(c, locp, &src_m); 1722 return res; 1723 } 1724 1725 HexValue gen_ctpop_op(Context *c, YYLTYPE *locp, HexValue *src) 1726 { 1727 const char *bit_suffix = src->bit_width == 64 ? "64" : "32"; 1728 HexValue src_m = *src; 1729 HexValue res; 1730 assert_signedness(c, locp, src->signedness); 1731 res = gen_tmp(c, locp, src->bit_width == 64 ? 64 : 32, src->signedness); 1732 src_m = rvalue_materialize(c, locp, &src_m); 1733 OUT(c, locp, "tcg_gen_ctpop_i", bit_suffix, 1734 "(", &res, ", ", &src_m, ");\n"); 1735 gen_rvalue_free(c, locp, &src_m); 1736 return res; 1737 } 1738 1739 HexValue gen_rotl(Context *c, YYLTYPE *locp, HexValue *src, HexValue *width) 1740 { 1741 const char *suffix = src->bit_width == 64 ? "i64" : "i32"; 1742 HexValue amount = *width; 1743 HexValue res; 1744 assert_signedness(c, locp, src->signedness); 1745 res = gen_tmp(c, locp, src->bit_width, src->signedness); 1746 if (amount.bit_width < src->bit_width) { 1747 amount = gen_rvalue_extend(c, locp, &amount); 1748 } else { 1749 amount = gen_rvalue_truncate(c, locp, &amount); 1750 } 1751 amount = rvalue_materialize(c, locp, &amount); 1752 OUT(c, locp, "tcg_gen_rotl_", suffix, "(", 1753 &res, ", ", src, ", ", &amount, ");\n"); 1754 gen_rvalue_free(c, locp, src); 1755 gen_rvalue_free(c, locp, &amount); 1756 1757 return res; 1758 } 1759 1760 HexValue gen_carry_from_add(Context *c, 1761 YYLTYPE *locp, 1762 HexValue *op1, 1763 HexValue *op2, 1764 HexValue *op3) 1765 { 1766 HexValue zero = gen_constant(c, locp, "0", 64, UNSIGNED); 1767 HexValue res = gen_tmp(c, locp, 64, UNSIGNED); 1768 HexValue cf = gen_tmp(c, locp, 64, UNSIGNED); 1769 HexValue op1_m = rvalue_materialize(c, locp, op1); 1770 HexValue op2_m = rvalue_materialize(c, locp, op2); 1771 HexValue op3_m = rvalue_materialize(c, locp, op3); 1772 op3_m = gen_rvalue_extend(c, locp, &op3_m); 1773 1774 OUT(c, locp, "tcg_gen_add2_i64(", &res, ", ", &cf, ", ", &op1_m, ", ", 1775 &zero); 1776 OUT(c, locp, ", ", &op3_m, ", ", &zero, ");\n"); 1777 OUT(c, locp, "tcg_gen_add2_i64(", &res, ", ", &cf, ", ", &res, ", ", &cf); 1778 OUT(c, locp, ", ", &op2_m, ", ", &zero, ");\n"); 1779 1780 gen_rvalue_free(c, locp, &op1_m); 1781 gen_rvalue_free(c, locp, &op2_m); 1782 gen_rvalue_free(c, locp, &op3_m); 1783 gen_rvalue_free(c, locp, &res); 1784 return cf; 1785 } 1786 1787 void gen_addsat64(Context *c, 1788 YYLTYPE *locp, 1789 HexValue *dst, 1790 HexValue *op1, 1791 HexValue *op2) 1792 { 1793 HexValue op1_m = rvalue_materialize(c, locp, op1); 1794 HexValue op2_m = rvalue_materialize(c, locp, op2); 1795 OUT(c, locp, "gen_add_sat_i64(", dst, ", ", &op1_m, ", ", &op2_m, ");\n"); 1796 } 1797 1798 void gen_inst(Context *c, GString *iname) 1799 { 1800 c->total_insn++; 1801 c->inst.name = iname; 1802 c->inst.allocated = g_array_new(FALSE, FALSE, sizeof(Var)); 1803 c->inst.init_list = g_array_new(FALSE, FALSE, sizeof(HexValue)); 1804 c->inst.strings = g_array_new(FALSE, FALSE, sizeof(GString *)); 1805 EMIT_SIG(c, "void emit_%s(DisasContext *ctx, Insn *insn, Packet *pkt", 1806 c->inst.name->str); 1807 } 1808 1809 1810 /* 1811 * Initialize declared but uninitialized registers, but only for 1812 * non-conditional instructions 1813 */ 1814 void gen_inst_init_args(Context *c, YYLTYPE *locp) 1815 { 1816 if (!c->inst.init_list) { 1817 return; 1818 } 1819 1820 for (unsigned i = 0; i < c->inst.init_list->len; i++) { 1821 HexValue *val = &g_array_index(c->inst.init_list, HexValue, i); 1822 if (val->type == REGISTER_ARG) { 1823 char reg_id[5]; 1824 reg_compose(c, locp, &val->reg, reg_id); 1825 EMIT_HEAD(c, "tcg_gen_movi_i%u(%s, 0);\n", val->bit_width, reg_id); 1826 } else if (val->type == PREDICATE) { 1827 char suffix = val->is_dotnew ? 'N' : 'V'; 1828 EMIT_HEAD(c, "tcg_gen_movi_i%u(P%c%c, 0);\n", val->bit_width, 1829 val->pred.id, suffix); 1830 } else { 1831 yyassert(c, locp, false, "Invalid arg type!"); 1832 } 1833 } 1834 1835 /* Free argument init list once we have initialized everything */ 1836 g_array_free(c->inst.init_list, TRUE); 1837 c->inst.init_list = NULL; 1838 } 1839 1840 void gen_inst_code(Context *c, YYLTYPE *locp) 1841 { 1842 if (c->inst.error_count != 0) { 1843 fprintf(stderr, 1844 "Parsing of instruction %s generated %d errors!\n", 1845 c->inst.name->str, 1846 c->inst.error_count); 1847 } else { 1848 free_variables(c, locp); 1849 c->implemented_insn++; 1850 fprintf(c->enabled_file, "%s\n", c->inst.name->str); 1851 emit_footer(c); 1852 commit(c); 1853 } 1854 free_instruction(c); 1855 } 1856 1857 void gen_pred_assign(Context *c, YYLTYPE *locp, HexValue *left_pred, 1858 HexValue *right_pred) 1859 { 1860 char pred_id[2] = {left_pred->pred.id, 0}; 1861 bool is_direct = is_direct_predicate(left_pred); 1862 HexValue r = rvalue_materialize(c, locp, right_pred); 1863 r = gen_rvalue_truncate(c, locp, &r); 1864 yyassert(c, locp, !is_inside_ternary(c), 1865 "Predicate assign not allowed in ternary!"); 1866 /* Extract predicate TCGv */ 1867 if (is_direct) { 1868 *left_pred = gen_tmp_value(c, locp, "0", 32, UNSIGNED); 1869 } 1870 /* Extract first 8 bits, and store new predicate value */ 1871 OUT(c, locp, "tcg_gen_mov_i32(", left_pred, ", ", &r, ");\n"); 1872 OUT(c, locp, "tcg_gen_andi_i32(", left_pred, ", ", left_pred, 1873 ", 0xff);\n"); 1874 if (is_direct) { 1875 OUT(c, locp, "gen_log_pred_write(ctx, ", pred_id, ", ", left_pred, 1876 ");\n"); 1877 OUT(c, locp, "ctx_log_pred_write(ctx, ", pred_id, ");\n"); 1878 gen_rvalue_free(c, locp, left_pred); 1879 } 1880 /* Free temporary value */ 1881 gen_rvalue_free(c, locp, &r); 1882 } 1883 1884 void gen_cancel(Context *c, YYLTYPE *locp) 1885 { 1886 OUT(c, locp, "gen_cancel(insn->slot);\n"); 1887 } 1888 1889 void gen_load_cancel(Context *c, YYLTYPE *locp) 1890 { 1891 gen_cancel(c, locp); 1892 OUT(c, locp, "if (insn->slot == 0 && pkt->pkt_has_store_s1) {\n"); 1893 OUT(c, locp, "ctx->s1_store_processed = false;\n"); 1894 OUT(c, locp, "process_store(ctx, 1);\n"); 1895 OUT(c, locp, "}\n"); 1896 } 1897 1898 void gen_load(Context *c, YYLTYPE *locp, HexValue *width, 1899 HexSignedness signedness, HexValue *ea, HexValue *dst) 1900 { 1901 char size_suffix[4] = {0}; 1902 const char *sign_suffix; 1903 /* Memop width is specified in the load macro */ 1904 assert_signedness(c, locp, signedness); 1905 sign_suffix = (width->imm.value > 4) 1906 ? "" 1907 : ((signedness == UNSIGNED) ? "u" : "s"); 1908 /* If dst is a variable, assert that is declared and load the type info */ 1909 if (dst->type == VARID) { 1910 find_variable(c, locp, dst, dst); 1911 } 1912 1913 snprintf(size_suffix, 4, "%" PRIu64, width->imm.value * 8); 1914 /* Lookup the effective address EA */ 1915 find_variable(c, locp, ea, ea); 1916 OUT(c, locp, "if (insn->slot == 0 && pkt->pkt_has_store_s1) {\n"); 1917 OUT(c, locp, "probe_noshuf_load(", ea, ", ", width, ", ctx->mem_idx);\n"); 1918 OUT(c, locp, "process_store(ctx, 1);\n"); 1919 OUT(c, locp, "}\n"); 1920 OUT(c, locp, "tcg_gen_qemu_ld", size_suffix, sign_suffix); 1921 OUT(c, locp, "("); 1922 if (dst->bit_width > width->imm.value * 8) { 1923 /* 1924 * Cast to the correct TCG type if necessary, to avoid implict cast 1925 * warnings. This is needed when the width of the destination var is 1926 * larger than the size of the requested load. 1927 */ 1928 OUT(c, locp, "(TCGv) "); 1929 } 1930 OUT(c, locp, dst, ", ", ea, ", ctx->mem_idx);\n"); 1931 /* If the var in EA was truncated it is now a tmp HexValue, so free it. */ 1932 gen_rvalue_free(c, locp, ea); 1933 } 1934 1935 void gen_store(Context *c, YYLTYPE *locp, HexValue *width, HexValue *ea, 1936 HexValue *src) 1937 { 1938 HexValue src_m = *src; 1939 /* Memop width is specified in the store macro */ 1940 unsigned mem_width = width->imm.value; 1941 /* Lookup the effective address EA */ 1942 find_variable(c, locp, ea, ea); 1943 src_m = rvalue_materialize(c, locp, &src_m); 1944 OUT(c, locp, "gen_store", &mem_width, "(cpu_env, ", ea, ", ", &src_m); 1945 OUT(c, locp, ", insn->slot);\n"); 1946 gen_rvalue_free(c, locp, &src_m); 1947 /* If the var in ea was truncated it is now a tmp HexValue, so free it. */ 1948 gen_rvalue_free(c, locp, ea); 1949 } 1950 1951 void gen_sethalf(Context *c, YYLTYPE *locp, HexCast *sh, HexValue *n, 1952 HexValue *dst, HexValue *value) 1953 { 1954 yyassert(c, locp, n->type == IMMEDIATE, 1955 "Deposit index must be immediate!\n"); 1956 if (dst->type == VARID) { 1957 find_variable(c, locp, dst, dst); 1958 } 1959 1960 gen_deposit_op(c, locp, dst, value, n, sh); 1961 } 1962 1963 void gen_setbits(Context *c, YYLTYPE *locp, HexValue *hi, HexValue *lo, 1964 HexValue *dst, HexValue *value) 1965 { 1966 unsigned len; 1967 HexValue tmp; 1968 1969 yyassert(c, locp, hi->type == IMMEDIATE && 1970 hi->imm.type == VALUE && 1971 lo->type == IMMEDIATE && 1972 lo->imm.type == VALUE, 1973 "Range deposit needs immediate values!\n"); 1974 1975 *value = gen_rvalue_truncate(c, locp, value); 1976 len = hi->imm.value + 1 - lo->imm.value; 1977 tmp = gen_tmp(c, locp, 32, value->signedness); 1978 /* Emit an `and` to ensure `value` is either 0 or 1. */ 1979 OUT(c, locp, "tcg_gen_andi_i32(", &tmp, ", ", value, ", 1);\n"); 1980 /* Use `neg` to map 0 -> 0 and 1 -> 0xffff... */ 1981 OUT(c, locp, "tcg_gen_neg_i32(", &tmp, ", ", &tmp, ");\n"); 1982 OUT(c, locp, "tcg_gen_deposit_i32(", dst, ", ", dst, 1983 ", ", &tmp, ", "); 1984 OUT(c, locp, lo, ", ", &len, ");\n"); 1985 1986 gen_rvalue_free(c, locp, &tmp); 1987 gen_rvalue_free(c, locp, hi); 1988 gen_rvalue_free(c, locp, lo); 1989 gen_rvalue_free(c, locp, value); 1990 } 1991 1992 unsigned gen_if_cond(Context *c, YYLTYPE *locp, HexValue *cond) 1993 { 1994 const char *bit_suffix; 1995 /* Generate an end label, if false branch to that label */ 1996 OUT(c, locp, "TCGLabel *if_label_", &c->inst.if_count, 1997 " = gen_new_label();\n"); 1998 *cond = rvalue_materialize(c, locp, cond); 1999 bit_suffix = (cond->bit_width == 64) ? "i64" : "i32"; 2000 OUT(c, locp, "tcg_gen_brcondi_", bit_suffix, "(TCG_COND_EQ, ", cond, 2001 ", 0, if_label_", &c->inst.if_count, ");\n"); 2002 gen_rvalue_free(c, locp, cond); 2003 return c->inst.if_count++; 2004 } 2005 2006 unsigned gen_if_else(Context *c, YYLTYPE *locp, unsigned index) 2007 { 2008 unsigned if_index = c->inst.if_count++; 2009 /* Generate label to jump if else is not verified */ 2010 OUT(c, locp, "TCGLabel *if_label_", &if_index, 2011 " = gen_new_label();\n"); 2012 /* Jump out of the else statement */ 2013 OUT(c, locp, "tcg_gen_br(if_label_", &if_index, ");\n"); 2014 /* Fix the else label */ 2015 OUT(c, locp, "gen_set_label(if_label_", &index, ");\n"); 2016 return if_index; 2017 } 2018 2019 HexValue gen_rvalue_pred(Context *c, YYLTYPE *locp, HexValue *pred) 2020 { 2021 /* Predicted instructions need to zero out result args */ 2022 gen_inst_init_args(c, locp); 2023 2024 if (is_direct_predicate(pred)) { 2025 bool is_dotnew = pred->is_dotnew; 2026 char predicate_id[2] = { pred->pred.id, '\0' }; 2027 char *pred_str = (char *) &predicate_id; 2028 *pred = gen_tmp_value(c, locp, "0", 32, UNSIGNED); 2029 if (is_dotnew) { 2030 OUT(c, locp, "tcg_gen_mov_i32(", pred, 2031 ", hex_new_pred_value["); 2032 OUT(c, locp, pred_str, "]);\n"); 2033 } else { 2034 OUT(c, locp, "gen_read_preg(", pred, ", ", pred_str, ");\n"); 2035 } 2036 } 2037 2038 return *pred; 2039 } 2040 2041 HexValue gen_rvalue_var(Context *c, YYLTYPE *locp, HexValue *var) 2042 { 2043 find_variable(c, locp, var, var); 2044 return *var; 2045 } 2046 2047 HexValue gen_rvalue_mpy(Context *c, YYLTYPE *locp, HexMpy *mpy, 2048 HexValue *op1, HexValue *op2) 2049 { 2050 HexValue res; 2051 memset(&res, 0, sizeof(HexValue)); 2052 2053 assert_signedness(c, locp, mpy->first_signedness); 2054 assert_signedness(c, locp, mpy->second_signedness); 2055 2056 *op1 = gen_cast_op(c, locp, op1, mpy->first_bit_width * 2, 2057 mpy->first_signedness); 2058 /* Handle fMPTY3216.. */ 2059 if (mpy->first_bit_width == 32) { 2060 *op2 = gen_cast_op(c, locp, op2, 64, mpy->second_signedness); 2061 } else { 2062 *op2 = gen_cast_op(c, locp, op2, mpy->second_bit_width * 2, 2063 mpy->second_signedness); 2064 } 2065 res = gen_bin_op(c, locp, MUL_OP, op1, op2); 2066 /* Handle special cases required by the language */ 2067 if (mpy->first_bit_width == 16 && mpy->second_bit_width == 16) { 2068 HexValue src_width = gen_imm_value(c, locp, 32, 32, UNSIGNED); 2069 HexSignedness signedness = bin_op_signedness(c, locp, 2070 mpy->first_signedness, 2071 mpy->second_signedness); 2072 res = gen_extend_op(c, locp, &src_width, 64, &res, 2073 signedness); 2074 } 2075 return res; 2076 } 2077 2078 static inline HexValue gen_rvalue_simple_unary(Context *c, YYLTYPE *locp, 2079 HexValue *value, 2080 const char *c_code, 2081 const char *tcg_code) 2082 { 2083 unsigned bit_width = (value->bit_width == 64) ? 64 : 32; 2084 HexValue res; 2085 if (value->type == IMMEDIATE) { 2086 res = gen_imm_qemu_tmp(c, locp, bit_width, value->signedness); 2087 gen_c_int_type(c, locp, value->bit_width, value->signedness); 2088 OUT(c, locp, " ", &res, " = ", c_code, "(", value, ");\n"); 2089 } else { 2090 res = gen_tmp(c, locp, bit_width, value->signedness); 2091 OUT(c, locp, tcg_code, "_i", &bit_width, "(", &res, ", ", value, 2092 ");\n"); 2093 gen_rvalue_free(c, locp, value); 2094 } 2095 return res; 2096 } 2097 2098 2099 HexValue gen_rvalue_not(Context *c, YYLTYPE *locp, HexValue *value) 2100 { 2101 return gen_rvalue_simple_unary(c, locp, value, "~", "tcg_gen_not"); 2102 } 2103 2104 HexValue gen_rvalue_notl(Context *c, YYLTYPE *locp, HexValue *value) 2105 { 2106 unsigned bit_width = (value->bit_width == 64) ? 64 : 32; 2107 HexValue res; 2108 if (value->type == IMMEDIATE) { 2109 res = gen_imm_qemu_tmp(c, locp, bit_width, value->signedness); 2110 gen_c_int_type(c, locp, value->bit_width, value->signedness); 2111 OUT(c, locp, " ", &res, " = !(", value, ");\n"); 2112 } else { 2113 HexValue zero = gen_constant(c, locp, "0", bit_width, UNSIGNED); 2114 HexValue one = gen_constant(c, locp, "0xff", bit_width, UNSIGNED); 2115 res = gen_tmp(c, locp, bit_width, value->signedness); 2116 OUT(c, locp, "tcg_gen_movcond_i", &bit_width); 2117 OUT(c, locp, "(TCG_COND_EQ, ", &res, ", ", value, ", ", &zero); 2118 OUT(c, locp, ", ", &one, ", ", &zero, ");\n"); 2119 gen_rvalue_free(c, locp, value); 2120 } 2121 return res; 2122 } 2123 2124 HexValue gen_rvalue_sat(Context *c, YYLTYPE *locp, HexSat *sat, 2125 HexValue *width, HexValue *value) 2126 { 2127 const char *unsigned_str; 2128 const char *bit_suffix = (value->bit_width == 64) ? "i64" : "i32"; 2129 HexValue res; 2130 HexValue ovfl; 2131 /* 2132 * Note: all saturates are assumed to implicitly set overflow. 2133 * This assumption holds for the instructions currently parsed 2134 * by idef-parser. 2135 */ 2136 yyassert(c, locp, width->imm.value < value->bit_width, 2137 "To compute overflow, source width must be greater than" 2138 " saturation width!"); 2139 yyassert(c, locp, !is_inside_ternary(c), 2140 "Saturating from within a ternary is not allowed!"); 2141 assert_signedness(c, locp, sat->signedness); 2142 2143 unsigned_str = (sat->signedness == UNSIGNED) ? "u" : ""; 2144 res = gen_tmp(c, locp, value->bit_width, sat->signedness); 2145 ovfl = gen_tmp(c, locp, 32, sat->signedness); 2146 OUT(c, locp, "gen_sat", unsigned_str, "_", bit_suffix, "_ovfl("); 2147 OUT(c, locp, &ovfl, ", ", &res, ", ", value, ", ", &width->imm.value, 2148 ");\n"); 2149 OUT(c, locp, "gen_set_usr_field_if(USR_OVF,", &ovfl, ");\n"); 2150 gen_rvalue_free(c, locp, value); 2151 2152 return res; 2153 } 2154 2155 HexValue gen_rvalue_fscr(Context *c, YYLTYPE *locp, HexValue *value) 2156 { 2157 HexValue key = gen_tmp(c, locp, 64, UNSIGNED); 2158 HexValue res = gen_tmp(c, locp, 64, UNSIGNED); 2159 HexValue frame_key = gen_tmp(c, locp, 32, UNSIGNED); 2160 *value = gen_rvalue_extend(c, locp, value); 2161 OUT(c, locp, "gen_read_reg(", &frame_key, ", HEX_REG_FRAMEKEY);\n"); 2162 OUT(c, locp, "tcg_gen_concat_i32_i64(", 2163 &key, ", ", &frame_key, ", ", &frame_key, ");\n"); 2164 OUT(c, locp, "tcg_gen_xor_i64(", &res, ", ", value, ", ", &key, ");\n"); 2165 gen_rvalue_free(c, locp, &key); 2166 gen_rvalue_free(c, locp, &frame_key); 2167 gen_rvalue_free(c, locp, value); 2168 return res; 2169 } 2170 2171 HexValue gen_rvalue_abs(Context *c, YYLTYPE *locp, HexValue *value) 2172 { 2173 return gen_rvalue_simple_unary(c, locp, value, "abs", "tcg_gen_abs"); 2174 } 2175 2176 HexValue gen_rvalue_neg(Context *c, YYLTYPE *locp, HexValue *value) 2177 { 2178 return gen_rvalue_simple_unary(c, locp, value, "-", "tcg_gen_neg"); 2179 } 2180 2181 HexValue gen_rvalue_brev(Context *c, YYLTYPE *locp, HexValue *value) 2182 { 2183 HexValue res; 2184 yyassert(c, locp, value->bit_width <= 32, 2185 "fbrev not implemented for 64-bit integers!"); 2186 res = gen_tmp(c, locp, value->bit_width, value->signedness); 2187 *value = rvalue_materialize(c, locp, value); 2188 OUT(c, locp, "gen_helper_fbrev(", &res, ", ", value, ");\n"); 2189 gen_rvalue_free(c, locp, value); 2190 return res; 2191 } 2192 2193 HexValue gen_rvalue_ternary(Context *c, YYLTYPE *locp, HexValue *cond, 2194 HexValue *true_branch, HexValue *false_branch) 2195 { 2196 bool is_64bit = (true_branch->bit_width == 64) || 2197 (false_branch->bit_width == 64); 2198 unsigned bit_width = (is_64bit) ? 64 : 32; 2199 HexValue zero = gen_constant(c, locp, "0", bit_width, UNSIGNED); 2200 HexValue res = gen_tmp(c, locp, bit_width, UNSIGNED); 2201 Ternary *ternary = NULL; 2202 2203 if (is_64bit) { 2204 *cond = gen_rvalue_extend(c, locp, cond); 2205 *true_branch = gen_rvalue_extend(c, locp, true_branch); 2206 *false_branch = gen_rvalue_extend(c, locp, false_branch); 2207 } else { 2208 *cond = gen_rvalue_truncate(c, locp, cond); 2209 } 2210 *cond = rvalue_materialize(c, locp, cond); 2211 *true_branch = rvalue_materialize(c, locp, true_branch); 2212 *false_branch = rvalue_materialize(c, locp, false_branch); 2213 2214 OUT(c, locp, "tcg_gen_movcond_i", &bit_width); 2215 OUT(c, locp, "(TCG_COND_NE, ", &res, ", ", cond, ", ", &zero); 2216 OUT(c, locp, ", ", true_branch, ", ", false_branch, ");\n"); 2217 2218 assert(c->ternary->len > 0); 2219 ternary = &g_array_index(c->ternary, Ternary, c->ternary->len - 1); 2220 gen_rvalue_free_manual(c, locp, &ternary->cond); 2221 g_array_remove_index(c->ternary, c->ternary->len - 1); 2222 2223 gen_rvalue_free(c, locp, cond); 2224 gen_rvalue_free(c, locp, true_branch); 2225 gen_rvalue_free(c, locp, false_branch); 2226 return res; 2227 } 2228 2229 const char *cond_to_str(TCGCond cond) 2230 { 2231 switch (cond) { 2232 case TCG_COND_NEVER: 2233 return "TCG_COND_NEVER"; 2234 case TCG_COND_ALWAYS: 2235 return "TCG_COND_ALWAYS"; 2236 case TCG_COND_EQ: 2237 return "TCG_COND_EQ"; 2238 case TCG_COND_NE: 2239 return "TCG_COND_NE"; 2240 case TCG_COND_LT: 2241 return "TCG_COND_LT"; 2242 case TCG_COND_GE: 2243 return "TCG_COND_GE"; 2244 case TCG_COND_LE: 2245 return "TCG_COND_LE"; 2246 case TCG_COND_GT: 2247 return "TCG_COND_GT"; 2248 case TCG_COND_LTU: 2249 return "TCG_COND_LTU"; 2250 case TCG_COND_GEU: 2251 return "TCG_COND_GEU"; 2252 case TCG_COND_LEU: 2253 return "TCG_COND_LEU"; 2254 case TCG_COND_GTU: 2255 return "TCG_COND_GTU"; 2256 default: 2257 abort(); 2258 } 2259 } 2260 2261 void emit_arg(Context *c, YYLTYPE *locp, HexValue *arg) 2262 { 2263 switch (arg->type) { 2264 case REGISTER_ARG: 2265 if (arg->reg.type == DOTNEW) { 2266 EMIT_SIG(c, ", TCGv N%cN", arg->reg.id); 2267 } else { 2268 bool is64 = (arg->bit_width == 64); 2269 const char *type = is64 ? "TCGv_i64" : "TCGv_i32"; 2270 char reg_id[5]; 2271 reg_compose(c, locp, &(arg->reg), reg_id); 2272 EMIT_SIG(c, ", %s %s", type, reg_id); 2273 /* MuV register requires also MuN to provide its index */ 2274 if (arg->reg.type == MODIFIER) { 2275 EMIT_SIG(c, ", int MuN"); 2276 } 2277 } 2278 break; 2279 case PREDICATE: 2280 { 2281 char suffix = arg->is_dotnew ? 'N' : 'V'; 2282 EMIT_SIG(c, ", TCGv P%c%c", arg->pred.id, suffix); 2283 } 2284 break; 2285 default: 2286 { 2287 fprintf(stderr, "emit_arg got unsupported argument!"); 2288 abort(); 2289 } 2290 } 2291 } 2292 2293 void emit_footer(Context *c) 2294 { 2295 EMIT(c, "}\n"); 2296 EMIT(c, "\n"); 2297 } 2298 2299 void track_string(Context *c, GString *s) 2300 { 2301 g_array_append_val(c->inst.strings, s); 2302 } 2303 2304 void free_variables(Context *c, YYLTYPE *locp) 2305 { 2306 for (unsigned i = 0; i < c->inst.allocated->len; ++i) { 2307 Var *var = &g_array_index(c->inst.allocated, Var, i); 2308 const char *suffix = var->bit_width == 64 ? "i64" : "i32"; 2309 OUT(c, locp, "tcg_temp_free_", suffix, "(", var->name->str, ");\n"); 2310 } 2311 } 2312 2313 void free_instruction(Context *c) 2314 { 2315 assert(!is_inside_ternary(c)); 2316 /* Free the strings */ 2317 g_string_truncate(c->signature_str, 0); 2318 g_string_truncate(c->out_str, 0); 2319 g_string_truncate(c->header_str, 0); 2320 /* Free strings allocated by the instruction */ 2321 for (unsigned i = 0; i < c->inst.strings->len; i++) { 2322 g_string_free(g_array_index(c->inst.strings, GString*, i), TRUE); 2323 } 2324 g_array_free(c->inst.strings, TRUE); 2325 /* Free INAME token value */ 2326 g_string_free(c->inst.name, TRUE); 2327 /* Free variables and registers */ 2328 g_array_free(c->inst.allocated, TRUE); 2329 /* Initialize instruction-specific portion of the context */ 2330 memset(&(c->inst), 0, sizeof(Inst)); 2331 } 2332 2333 void assert_signedness(Context *c, 2334 YYLTYPE *locp, 2335 HexSignedness signedness) 2336 { 2337 yyassert(c, locp, 2338 signedness != UNKNOWN_SIGNEDNESS, 2339 "Unspecified signedness"); 2340 } 2341