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