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->reg.id, ", ",
1420         &value_m, ");\n");
1421     OUT(c,
1422         locp,
1423         "ctx_log_reg_write(ctx, ", &reg->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