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