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