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