master
h 355 lines 11.1 KB
Raw
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_framecheck(Context *c, YYLTYPE *locp, HexValue *addr, HexValue *ea);
299
300 void gen_load(Context *c, YYLTYPE *locp, HexValue *size,
301 HexSignedness signedness, HexValue *ea, HexValue *dst);
302
303 void gen_store(Context *c, YYLTYPE *locp, HexValue *size, HexValue *ea,
304 HexValue *src);
305
306 void gen_sethalf(Context *c, YYLTYPE *locp, HexCast *sh, HexValue *n,
307 HexValue *dst, HexValue *value);
308
309 void gen_setbits(Context *c, YYLTYPE *locp, HexValue *hi, HexValue *lo,
310 HexValue *dst, HexValue *value);
311
312 unsigned gen_if_cond(Context *c, YYLTYPE *locp, HexValue *cond);
313
314 unsigned gen_if_else(Context *c, YYLTYPE *locp, unsigned index);
315
316 HexValue gen_rvalue_pred(Context *c, YYLTYPE *locp, HexValue *pred);
317
318 HexValue gen_rvalue_var(Context *c, YYLTYPE *locp, HexValue *var);
319
320 HexValue gen_rvalue_mpy(Context *c, YYLTYPE *locp, HexMpy *mpy, HexValue *op1,
321 HexValue *op2);
322
323 HexValue gen_rvalue_not(Context *c, YYLTYPE *locp, HexValue *value);
324
325 HexValue gen_rvalue_notl(Context *c, YYLTYPE *locp, HexValue *value);
326
327 HexValue gen_rvalue_sat(Context *c, YYLTYPE *locp, HexSat *sat, HexValue *n,
328 HexValue *value);
329
330 HexValue gen_rvalue_fscr(Context *c, YYLTYPE *locp, HexValue *value);
331
332 HexValue gen_rvalue_abs(Context *c, YYLTYPE *locp, HexValue *value);
333
334 HexValue gen_rvalue_neg(Context *c, YYLTYPE *locp, HexValue *value);
335
336 HexValue gen_rvalue_brev(Context *c, YYLTYPE *locp, HexValue *value);
337
338 HexValue gen_rvalue_ternary(Context *c, YYLTYPE *locp, HexValue *cond,
339 HexValue *true_branch, HexValue *false_branch);
340
341 const char *cond_to_str(TCGCond cond);
342
343 void emit_arg(Context *c, YYLTYPE *locp, HexValue *arg);
344
345 void emit_footer(Context *c);
346
347 void track_string(Context *c, GString *s);
348
349 void free_instruction(Context *c);
350
351 void assert_signedness(Context *c,
352 YYLTYPE *locp,
353 HexSignedness signedness);
354
355 #endif /* PARSER_HELPERS_h */