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, HexValue *rvalue);
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 /**
147  * Temporary values creation
148  */
149 
150 HexValue gen_tmp(Context *c,
151                  YYLTYPE *locp,
152                  unsigned bit_width,
153                  HexSignedness signedness);
154 
155 HexValue gen_imm_value(Context *c __attribute__((unused)),
156                        YYLTYPE *locp,
157                        int value,
158                        unsigned bit_width,
159                        HexSignedness signedness);
160 
161 HexValue gen_imm_qemu_tmp(Context *c, YYLTYPE *locp, unsigned bit_width,
162                           HexSignedness signedness);
163 
164 HexValue rvalue_materialize(Context *c, YYLTYPE *locp, HexValue *rvalue);
165 
166 HexValue gen_rvalue_extend(Context *c, YYLTYPE *locp, HexValue *rvalue);
167 
168 HexValue gen_rvalue_truncate(Context *c, YYLTYPE *locp, HexValue *rvalue);
169 
170 void gen_varid_allocate(Context *c,
171                         YYLTYPE *locp,
172                         HexValue *varid,
173                         unsigned bit_width,
174                         HexSignedness signedness);
175 
176 /**
177  * Code generation functions
178  */
179 
180 HexValue gen_bin_cmp(Context *c,
181                      YYLTYPE *locp,
182                      TCGCond type,
183                      HexValue *op1,
184                      HexValue *op2);
185 
186 HexValue gen_bin_op(Context *c,
187                     YYLTYPE *locp,
188                     OpType type,
189                     HexValue *op1,
190                     HexValue *op2);
191 
192 HexValue gen_cast_op(Context *c,
193                      YYLTYPE *locp,
194                      HexValue *src,
195                      unsigned target_width,
196                      HexSignedness signedness);
197 
198 /**
199  * gen_extend_op extends a region of src_width_ptr bits stored in a
200  * value_ptr to the size of dst_width. Note: src_width_ptr is a
201  * HexValue * to handle the special case where it is unknown at
202  * translation time.
203  */
204 HexValue gen_extend_op(Context *c,
205                        YYLTYPE *locp,
206                        HexValue *src_width,
207                        unsigned dst_width,
208                        HexValue *value,
209                        HexSignedness signedness);
210 
211 void gen_rdeposit_op(Context *c,
212                      YYLTYPE *locp,
213                      HexValue *dst,
214                      HexValue *value,
215                      HexValue *begin,
216                      HexValue *width);
217 
218 void gen_deposit_op(Context *c,
219                     YYLTYPE *locp,
220                     HexValue *dst,
221                     HexValue *value,
222                     HexValue *index,
223                     HexCast *cast);
224 
225 HexValue gen_rextract_op(Context *c,
226                          YYLTYPE *locp,
227                          HexValue *src,
228                          unsigned begin,
229                          unsigned width);
230 
231 HexValue gen_extract_op(Context *c,
232                         YYLTYPE *locp,
233                         HexValue *src,
234                         HexValue *index,
235                         HexExtract *extract);
236 
237 void gen_write_reg(Context *c, YYLTYPE *locp, HexValue *reg, HexValue *value);
238 
239 void gen_assign(Context *c,
240                 YYLTYPE *locp,
241                 HexValue *dst,
242                 HexValue *value);
243 
244 HexValue gen_convround(Context *c,
245                        YYLTYPE *locp,
246                        HexValue *src);
247 
248 HexValue gen_round(Context *c,
249                    YYLTYPE *locp,
250                    HexValue *src,
251                    HexValue *position);
252 
253 HexValue gen_convround_n(Context *c,
254                          YYLTYPE *locp,
255                          HexValue *src,
256                          HexValue *pos);
257 
258 /**
259  * Circular addressing mode with auto-increment
260  */
261 void gen_circ_op(Context *c,
262                  YYLTYPE *locp,
263                  HexValue *addr,
264                  HexValue *increment,
265                  HexValue *modifier);
266 
267 HexValue gen_locnt_op(Context *c, YYLTYPE *locp, HexValue *src);
268 
269 HexValue gen_ctpop_op(Context *c, YYLTYPE *locp, HexValue *src);
270 
271 HexValue gen_rotl(Context *c, YYLTYPE *locp, HexValue *src, HexValue *n);
272 
273 HexValue gen_carry_from_add(Context *c,
274                             YYLTYPE *locp,
275                             HexValue *op1,
276                             HexValue *op2,
277                             HexValue *op3);
278 
279 void gen_addsat64(Context *c,
280                   YYLTYPE *locp,
281                   HexValue *dst,
282                   HexValue *op1,
283                   HexValue *op2);
284 
285 void gen_inst(Context *c, GString *iname);
286 
287 void gen_inst_init_args(Context *c, YYLTYPE *locp);
288 
289 void gen_inst_code(Context *c, YYLTYPE *locp);
290 
291 void gen_pred_assign(Context *c, YYLTYPE *locp, HexValue *left_pred,
292                      HexValue *right_pred);
293 
294 void gen_cancel(Context *c, YYLTYPE *locp);
295 
296 void gen_load_cancel(Context *c, YYLTYPE *locp);
297 
298 void gen_load(Context *c, YYLTYPE *locp, HexValue *size,
299               HexSignedness signedness, HexValue *ea, HexValue *dst);
300 
301 void gen_store(Context *c, YYLTYPE *locp, HexValue *size, HexValue *ea,
302                HexValue *src);
303 
304 void gen_sethalf(Context *c, YYLTYPE *locp, HexCast *sh, HexValue *n,
305                  HexValue *dst, HexValue *value);
306 
307 void gen_setbits(Context *c, YYLTYPE *locp, HexValue *hi, HexValue *lo,
308                  HexValue *dst, HexValue *value);
309 
310 unsigned gen_if_cond(Context *c, YYLTYPE *locp, HexValue *cond);
311 
312 unsigned gen_if_else(Context *c, YYLTYPE *locp, unsigned index);
313 
314 HexValue gen_rvalue_pred(Context *c, YYLTYPE *locp, HexValue *pred);
315 
316 HexValue gen_rvalue_var(Context *c, YYLTYPE *locp, HexValue *var);
317 
318 HexValue gen_rvalue_mpy(Context *c, YYLTYPE *locp, HexMpy *mpy, HexValue *op1,
319                         HexValue *op2);
320 
321 HexValue gen_rvalue_not(Context *c, YYLTYPE *locp, HexValue *value);
322 
323 HexValue gen_rvalue_notl(Context *c, YYLTYPE *locp, HexValue *value);
324 
325 HexValue gen_rvalue_sat(Context *c, YYLTYPE *locp, HexSat *sat, HexValue *n,
326                         HexValue *value);
327 
328 HexValue gen_rvalue_fscr(Context *c, YYLTYPE *locp, HexValue *value);
329 
330 HexValue gen_rvalue_abs(Context *c, YYLTYPE *locp, HexValue *value);
331 
332 HexValue gen_rvalue_neg(Context *c, YYLTYPE *locp, HexValue *value);
333 
334 HexValue gen_rvalue_brev(Context *c, YYLTYPE *locp, HexValue *value);
335 
336 HexValue gen_rvalue_ternary(Context *c, YYLTYPE *locp, HexValue *cond,
337                             HexValue *true_branch, HexValue *false_branch);
338 
339 const char *cond_to_str(TCGCond cond);
340 
341 void emit_arg(Context *c, YYLTYPE *locp, HexValue *arg);
342 
343 void emit_footer(Context *c);
344 
345 void track_string(Context *c, GString *s);
346 
347 void free_instruction(Context *c);
348 
349 void assert_signedness(Context *c,
350                        YYLTYPE *locp,
351                        HexSignedness signedness);
352 
353 #endif /* PARSER_HELPERS_h */
354