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