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