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 #ifndef PARSER_HELPERS_H
19 #define PARSER_HELPERS_H
20 
21 #include <assert.h>
22 #include <inttypes.h>
23 #include <stdarg.h>
24 #include <stdbool.h>
25 #include <stdint.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 
31 #include "tcg/tcg-cond.h"
32 
33 #include "idef-parser.tab.h"
34 #include "idef-parser.yy.h"
35 #include "idef-parser.h"
36 
37 /* Decomment this to disable yyasserts */
38 /* #define NDEBUG */
39 
40 #define ERR_LINE_CONTEXT 40
41 
42 #define START_COMMENT "/" "*"
43 #define END_COMMENT "*" "/"
44 
45 void yyerror(YYLTYPE *locp,
46              yyscan_t scanner __attribute__((unused)),
47              Context *c,
48              const char *s);
49 
50 #ifndef NDEBUG
51 #define yyassert(context, locp, condition, msg)              \
52     if (!(condition)) {                                      \
53         yyerror(locp, (context)->scanner, (context), (msg)); \
54     }
55 #endif
56 
57 bool is_direct_predicate(HexValue *value);
58 
59 bool is_inside_ternary(Context *c);
60 
61 /**
62  * Print functions
63  */
64 
65 void str_print(Context *c, YYLTYPE *locp, const char *string);
66 
67 void uint8_print(Context *c, YYLTYPE *locp, uint8_t *num);
68 
69 void uint64_print(Context *c, YYLTYPE *locp, uint64_t *num);
70 
71 void int_print(Context *c, YYLTYPE *locp, int *num);
72 
73 void uint_print(Context *c, YYLTYPE *locp, unsigned *num);
74 
75 void tmp_print(Context *c, YYLTYPE *locp, HexTmp *tmp);
76 
77 void pred_print(Context *c, YYLTYPE *locp, HexPred *pred, bool is_dotnew);
78 
79 void reg_compose(Context *c, YYLTYPE *locp, HexReg *reg, char reg_id[5]);
80 
81 void reg_print(Context *c, YYLTYPE *locp, HexReg *reg);
82 
83 void imm_print(Context *c, YYLTYPE *locp, HexImm *imm);
84 
85 void var_print(Context *c, YYLTYPE *locp, HexVar *var);
86 
87 void rvalue_print(Context *c, YYLTYPE *locp, void *pointer);
88 
89 void out_assert(Context *c, YYLTYPE *locp, void *dummy);
90 
91 /**
92  * Copies output code buffer into stdout
93  */
94 void commit(Context *c);
95 
96 #define OUT_IMPL(c, locp, x)                    \
97     _Generic(*(x),                              \
98         char:      str_print,                   \
99         uint8_t:   uint8_print,                 \
100         uint64_t:  uint64_print,                \
101         int:       int_print,                   \
102         unsigned:  uint_print,                  \
103         HexValue:  rvalue_print,                \
104         default:   out_assert                   \
105     )(c, locp, x);
106 
107 /* FOREACH macro */
108 #define FE_1(c, locp, WHAT, X) WHAT(c, locp, X)
109 #define FE_2(c, locp, WHAT, X, ...) \
110     WHAT(c, locp, X)FE_1(c, locp, WHAT, __VA_ARGS__)
111 #define FE_3(c, locp, WHAT, X, ...) \
112     WHAT(c, locp, X)FE_2(c, locp, WHAT, __VA_ARGS__)
113 #define FE_4(c, locp, WHAT, X, ...) \
114     WHAT(c, locp, X)FE_3(c, locp, WHAT, __VA_ARGS__)
115 #define FE_5(c, locp, WHAT, X, ...) \
116     WHAT(c, locp, X)FE_4(c, locp, WHAT, __VA_ARGS__)
117 #define FE_6(c, locp, WHAT, X, ...) \
118     WHAT(c, locp, X)FE_5(c, locp, WHAT, __VA_ARGS__)
119 #define FE_7(c, locp, WHAT, X, ...) \
120     WHAT(c, locp, X)FE_6(c, locp, WHAT, __VA_ARGS__)
121 #define FE_8(c, locp, WHAT, X, ...) \
122     WHAT(c, locp, X)FE_7(c, locp, WHAT, __VA_ARGS__)
123 #define FE_9(c, locp, WHAT, X, ...) \
124     WHAT(c, locp, X)FE_8(c, locp, WHAT, __VA_ARGS__)
125 /* repeat as needed */
126 
127 #define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, NAME, ...) NAME
128 
129 #define FOR_EACH(c, locp, action, ...)          \
130   do {                                          \
131     GET_MACRO(__VA_ARGS__,                      \
132               FE_9,                             \
133               FE_8,                             \
134               FE_7,                             \
135               FE_6,                             \
136               FE_5,                             \
137               FE_4,                             \
138               FE_3,                             \
139               FE_2,                             \
140               FE_1)(c, locp, action,            \
141                     __VA_ARGS__)                \
142   } while (0)
143 
144 #define OUT(c, locp, ...) FOR_EACH((c), (locp), OUT_IMPL, __VA_ARGS__)
145 
146 const char *cmp_swap(Context *c, YYLTYPE *locp, const char *type);
147 
148 /**
149  * Temporary values creation
150  */
151 
152 HexValue gen_tmp(Context *c,
153                  YYLTYPE *locp,
154                  unsigned bit_width,
155                  HexSignedness signedness);
156 
157 HexValue gen_tmp_value(Context *c,
158                        YYLTYPE *locp,
159                        const char *value,
160                        unsigned bit_width,
161                        HexSignedness signedness);
162 
163 HexValue gen_imm_value(Context *c __attribute__((unused)),
164                        YYLTYPE *locp,
165                        int value,
166                        unsigned bit_width,
167                        HexSignedness signedness);
168 
169 HexValue gen_imm_qemu_tmp(Context *c, YYLTYPE *locp, unsigned bit_width,
170                           HexSignedness signedness);
171 
172 void gen_rvalue_free(Context *c, YYLTYPE *locp, HexValue *rvalue);
173 
174 HexValue rvalue_materialize(Context *c, YYLTYPE *locp, HexValue *rvalue);
175 
176 HexValue gen_rvalue_extend(Context *c, YYLTYPE *locp, HexValue *rvalue);
177 
178 HexValue gen_rvalue_truncate(Context *c, YYLTYPE *locp, HexValue *rvalue);
179 
180 void gen_varid_allocate(Context *c,
181                         YYLTYPE *locp,
182                         HexValue *varid,
183                         unsigned bit_width,
184                         HexSignedness signedness);
185 
186 /**
187  * Code generation functions
188  */
189 
190 HexValue gen_bin_cmp(Context *c,
191                      YYLTYPE *locp,
192                      TCGCond type,
193                      HexValue *op1,
194                      HexValue *op2);
195 
196 HexValue gen_bin_op(Context *c,
197                     YYLTYPE *locp,
198                     OpType type,
199                     HexValue *op1,
200                     HexValue *op2);
201 
202 HexValue gen_cast_op(Context *c,
203                      YYLTYPE *locp,
204                      HexValue *src,
205                      unsigned target_width,
206                      HexSignedness signedness);
207 
208 /**
209  * gen_extend_op extends a region of src_width_ptr bits stored in a
210  * value_ptr to the size of dst_width. Note: src_width_ptr is a
211  * HexValue * to handle the special case where it is unknown at
212  * translation time.
213  */
214 HexValue gen_extend_op(Context *c,
215                        YYLTYPE *locp,
216                        HexValue *src_width,
217                        unsigned dst_width,
218                        HexValue *value,
219                        HexSignedness signedness);
220 
221 void gen_rdeposit_op(Context *c,
222                      YYLTYPE *locp,
223                      HexValue *dst,
224                      HexValue *value,
225                      HexValue *begin,
226                      HexValue *width);
227 
228 void gen_deposit_op(Context *c,
229                     YYLTYPE *locp,
230                     HexValue *dst,
231                     HexValue *value,
232                     HexValue *index,
233                     HexCast *cast);
234 
235 HexValue gen_rextract_op(Context *c,
236                          YYLTYPE *locp,
237                          HexValue *src,
238                          unsigned begin,
239                          unsigned width);
240 
241 HexValue gen_extract_op(Context *c,
242                         YYLTYPE *locp,
243                         HexValue *src,
244                         HexValue *index,
245                         HexExtract *extract);
246 
247 HexValue gen_read_reg(Context *c, YYLTYPE *locp, HexValue *reg);
248 
249 void gen_write_reg(Context *c, YYLTYPE *locp, HexValue *reg, HexValue *value);
250 
251 void gen_assign(Context *c,
252                 YYLTYPE *locp,
253                 HexValue *dst,
254                 HexValue *value);
255 
256 HexValue gen_convround(Context *c,
257                        YYLTYPE *locp,
258                        HexValue *src);
259 
260 HexValue gen_round(Context *c,
261                    YYLTYPE *locp,
262                    HexValue *src,
263                    HexValue *position);
264 
265 HexValue gen_convround_n(Context *c,
266                          YYLTYPE *locp,
267                          HexValue *src,
268                          HexValue *pos);
269 
270 /**
271  * Circular addressing mode with auto-increment
272  */
273 void gen_circ_op(Context *c,
274                  YYLTYPE *locp,
275                  HexValue *addr,
276                  HexValue *increment,
277                  HexValue *modifier);
278 
279 HexValue gen_locnt_op(Context *c, YYLTYPE *locp, HexValue *src);
280 
281 HexValue gen_ctpop_op(Context *c, YYLTYPE *locp, HexValue *src);
282 
283 HexValue gen_rotl(Context *c, YYLTYPE *locp, HexValue *src, HexValue *n);
284 
285 HexValue gen_deinterleave(Context *c, YYLTYPE *locp, HexValue *mixed);
286 
287 HexValue gen_interleave(Context *c,
288                         YYLTYPE *locp,
289                         HexValue *odd,
290                         HexValue *even);
291 
292 HexValue gen_carry_from_add(Context *c,
293                             YYLTYPE *locp,
294                             HexValue *op1,
295                             HexValue *op2,
296                             HexValue *op3);
297 
298 void gen_addsat64(Context *c,
299                   YYLTYPE *locp,
300                   HexValue *dst,
301                   HexValue *op1,
302                   HexValue *op2);
303 
304 void gen_inst(Context *c, GString *iname);
305 
306 void gen_inst_init_args(Context *c, YYLTYPE *locp);
307 
308 void gen_inst_code(Context *c, YYLTYPE *locp);
309 
310 void gen_pred_assign(Context *c, YYLTYPE *locp, HexValue *left_pred,
311                      HexValue *right_pred);
312 
313 void gen_cancel(Context *c, YYLTYPE *locp);
314 
315 void gen_load_cancel(Context *c, YYLTYPE *locp);
316 
317 void gen_load(Context *c, YYLTYPE *locp, HexValue *size,
318               HexSignedness signedness, HexValue *ea, HexValue *dst);
319 
320 void gen_store(Context *c, YYLTYPE *locp, HexValue *size, HexValue *ea,
321                HexValue *src);
322 
323 void gen_sethalf(Context *c, YYLTYPE *locp, HexCast *sh, HexValue *n,
324                  HexValue *dst, HexValue *value);
325 
326 void gen_setbits(Context *c, YYLTYPE *locp, HexValue *hi, HexValue *lo,
327                  HexValue *dst, HexValue *value);
328 
329 unsigned gen_if_cond(Context *c, YYLTYPE *locp, HexValue *cond);
330 
331 unsigned gen_if_else(Context *c, YYLTYPE *locp, unsigned index);
332 
333 HexValue gen_rvalue_pred(Context *c, YYLTYPE *locp, HexValue *pred);
334 
335 HexValue gen_rvalue_var(Context *c, YYLTYPE *locp, HexValue *var);
336 
337 HexValue gen_rvalue_mpy(Context *c, YYLTYPE *locp, HexMpy *mpy, HexValue *op1,
338                         HexValue *op2);
339 
340 HexValue gen_rvalue_not(Context *c, YYLTYPE *locp, HexValue *value);
341 
342 HexValue gen_rvalue_notl(Context *c, YYLTYPE *locp, HexValue *value);
343 
344 HexValue gen_rvalue_sat(Context *c, YYLTYPE *locp, HexSat *sat, HexValue *n,
345                         HexValue *value);
346 
347 HexValue gen_rvalue_fscr(Context *c, YYLTYPE *locp, HexValue *value);
348 
349 HexValue gen_rvalue_abs(Context *c, YYLTYPE *locp, HexValue *value);
350 
351 HexValue gen_rvalue_neg(Context *c, YYLTYPE *locp, HexValue *value);
352 
353 HexValue gen_rvalue_brev(Context *c, YYLTYPE *locp, HexValue *value);
354 
355 HexValue gen_rvalue_ternary(Context *c, YYLTYPE *locp, HexValue *cond,
356                             HexValue *true_branch, HexValue *false_branch);
357 
358 const char *cond_to_str(TCGCond cond);
359 
360 void emit_header(Context *c);
361 
362 void emit_arg(Context *c, YYLTYPE *locp, HexValue *arg);
363 
364 void emit_footer(Context *c);
365 
366 void track_string(Context *c, GString *s);
367 
368 void free_variables(Context *c, YYLTYPE *locp);
369 
370 void free_instruction(Context *c);
371 
372 void assert_signedness(Context *c,
373                        YYLTYPE *locp,
374                        HexSignedness signedness);
375 
376 #endif /* PARSER_HELPERS_h */
377