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 IDEF_PARSER_H 19 #define IDEF_PARSER_H 20 21 #include <inttypes.h> 22 #include <stdio.h> 23 #include <stdbool.h> 24 #include <glib.h> 25 26 /* Variadic macros to wrap the buffer printing functions */ 27 #define EMIT(c, ...) \ 28 do { \ 29 g_string_append_printf((c)->out_str, __VA_ARGS__); \ 30 } while (0) 31 32 #define EMIT_SIG(c, ...) \ 33 do { \ 34 g_string_append_printf((c)->signature_str, __VA_ARGS__); \ 35 } while (0) 36 37 #define EMIT_HEAD(c, ...) \ 38 do { \ 39 g_string_append_printf((c)->header_str, __VA_ARGS__); \ 40 } while (0) 41 42 /** 43 * Type of register, assigned to the HexReg.type field 44 */ 45 typedef enum { GENERAL_PURPOSE, CONTROL, MODIFIER, DOTNEW } HexRegType; 46 47 typedef enum { UNKNOWN_SIGNEDNESS, SIGNED, UNSIGNED } HexSignedness; 48 49 /** 50 * Semantic record of the REG tokens, identifying registers 51 */ 52 typedef struct HexReg { 53 uint8_t id; /**< Identifier of the register */ 54 HexRegType type; /**< Type of the register */ 55 unsigned bit_width; /**< Bit width of the reg, 32 or 64 bits */ 56 } HexReg; 57 58 /** 59 * Data structure, identifying a TCGv temporary value 60 */ 61 typedef struct HexTmp { 62 unsigned index; /**< Index of the TCGv temporary value */ 63 } HexTmp; 64 65 /** 66 * Enum of the possible immediate, an immediate is a value which is known 67 * at tinycode generation time, e.g. an integer value, not a TCGv 68 */ 69 enum ImmUnionTag { 70 I, 71 VARIABLE, 72 VALUE, 73 QEMU_TMP, 74 IMM_PC, 75 IMM_CONSTEXT, 76 }; 77 78 /** 79 * Semantic record of the IMM token, identifying an immediate constant 80 */ 81 typedef struct HexImm { 82 union { 83 char id; /**< Identifier, used when type is VARIABLE */ 84 uint64_t value; /**< Immediate value, used when type is VALUE */ 85 uint64_t index; /**< Index, used when type is QEMU_TMP */ 86 }; 87 enum ImmUnionTag type; /**< Type of the immediate */ 88 } HexImm; 89 90 /** 91 * Semantic record of the PRED token, identifying a predicate 92 */ 93 typedef struct HexPred { 94 char id; /**< Identifier of the predicate */ 95 } HexPred; 96 97 /** 98 * Semantic record of the SAT token, identifying the saturate operator 99 * Note: All saturates are assumed to implicitly set overflow. 100 */ 101 typedef struct HexSat { 102 HexSignedness signedness; /**< Signedness of the sat. op. */ 103 } HexSat; 104 105 /** 106 * Semantic record of the CAST token, identifying the cast operator 107 */ 108 typedef struct HexCast { 109 unsigned bit_width; /**< Bit width of the cast operator */ 110 HexSignedness signedness; /**< Unsigned flag for the cast operator */ 111 } HexCast; 112 113 /** 114 * Semantic record of the EXTRACT token, identifying the cast operator 115 */ 116 typedef struct HexExtract { 117 unsigned bit_width; /**< Bit width of the extract operator */ 118 unsigned storage_bit_width; /**< Actual bit width of the extract operator */ 119 HexSignedness signedness; /**< Unsigned flag for the extract operator */ 120 } HexExtract; 121 122 /** 123 * Semantic record of the MPY token, identifying the fMPY multiplication 124 * operator 125 */ 126 typedef struct HexMpy { 127 unsigned first_bit_width; /**< Bit width of 1st operand of fMPY */ 128 unsigned second_bit_width; /**< Bit width of 2nd operand of fMPY */ 129 HexSignedness first_signedness; /**< Signedness of 1st operand of fMPY */ 130 HexSignedness second_signedness; /**< Signedness of 2nd operand of fMPY */ 131 } HexMpy; 132 133 /** 134 * Semantic record of the VARID token, identifying declared variables 135 * of the input language 136 */ 137 typedef struct HexVar { 138 GString *name; /**< Name of the VARID variable */ 139 } HexVar; 140 141 /** 142 * Data structure uniquely identifying a declared VARID variable, used for 143 * keeping track of declared variable, so that any variable is declared only 144 * once, and its properties are propagated through all the subsequent instances 145 * of that variable 146 */ 147 typedef struct Var { 148 GString *name; /**< Name of the VARID variable */ 149 uint8_t bit_width; /**< Bit width of the VARID variable */ 150 HexSignedness signedness; /**< Unsigned flag for the VARID var */ 151 } Var; 152 153 /** 154 * Enum of the possible rvalue types, used in the HexValue.type field 155 */ 156 typedef enum RvalueUnionTag { 157 REGISTER, REGISTER_ARG, TEMP, IMMEDIATE, PREDICATE, VARID 158 } RvalueUnionTag; 159 160 /** 161 * Semantic record of the rvalue token, identifying any numeric value, 162 * immediate or register based. The rvalue tokens are combined together 163 * through the use of several operators, to encode expressions 164 */ 165 typedef struct HexValue { 166 union { 167 HexReg reg; /**< rvalue of register type */ 168 HexTmp tmp; /**< rvalue of temporary type */ 169 HexImm imm; /**< rvalue of immediate type */ 170 HexPred pred; /**< rvalue of predicate type */ 171 HexVar var; /**< rvalue of declared variable type */ 172 }; 173 RvalueUnionTag type; /**< Type of the rvalue */ 174 unsigned bit_width; /**< Bit width of the rvalue */ 175 HexSignedness signedness; /**< Unsigned flag for the rvalue */ 176 bool is_dotnew; /**< rvalue of predicate type is dotnew? */ 177 } HexValue; 178 179 /** 180 * State of ternary operator 181 */ 182 typedef enum TernaryState { IN_LEFT, IN_RIGHT } TernaryState; 183 184 /** 185 * Data structure used to handle side effects inside ternary operators 186 */ 187 typedef struct Ternary { 188 TernaryState state; 189 HexValue cond; 190 } Ternary; 191 192 /** 193 * Operator type, used for referencing the correct operator when calling the 194 * gen_bin_op() function, which in turn will generate the correct code to 195 * execute the operation between the two rvalues 196 */ 197 typedef enum OpType { 198 ADD_OP, SUB_OP, MUL_OP, ASL_OP, ASR_OP, LSR_OP, ANDB_OP, ORB_OP, 199 XORB_OP, ANDL_OP, MINI_OP, MAXI_OP 200 } OpType; 201 202 /** 203 * Data structure including instruction specific information, to be cleared 204 * out after the compilation of each instruction 205 */ 206 typedef struct Inst { 207 GString *name; /**< Name of the compiled instruction */ 208 char *code_begin; /**< Beginning of instruction input code */ 209 char *code_end; /**< End of instruction input code */ 210 unsigned tmp_count; /**< Index of the last declared TCGv temp */ 211 unsigned qemu_tmp_count; /**< Index of the last declared int temp */ 212 unsigned if_count; /**< Index of the last declared if label */ 213 unsigned error_count; /**< Number of generated errors */ 214 GArray *allocated; /**< Allocated declaredVARID vars */ 215 GArray *init_list; /**< List of initialized registers */ 216 GArray *strings; /**< Strings allocated by the instruction */ 217 } Inst; 218 219 /** 220 * Data structure representing the whole translation context, which in a 221 * reentrant flex/bison parser just like ours is passed between the scanner 222 * and the parser, holding all the necessary information to perform the 223 * parsing, this data structure survives between the compilation of different 224 * instructions 225 */ 226 typedef struct Context { 227 void *scanner; /**< Reentrant parser state pointer */ 228 char *input_buffer; /**< Buffer containing the input code */ 229 GString *out_str; /**< String containing the output code */ 230 GString *signature_str; /**< String containing the signatures code */ 231 GString *header_str; /**< String containing the header code */ 232 FILE *defines_file; /**< FILE * of the generated header */ 233 FILE *output_file; /**< FILE * of the C output file */ 234 FILE *enabled_file; /**< FILE * of the list of enabled inst */ 235 GArray *ternary; /**< Array to track nesting of ternary ops */ 236 unsigned total_insn; /**< Number of instructions in input file */ 237 unsigned implemented_insn; /**< Instruction compiled without errors */ 238 Inst inst; /**< Parsing data of the current inst */ 239 } Context; 240 241 #endif /* IDEF_PARSER_H */ 242