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