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