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