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