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