xref: /qemu/target/hexagon/idef-parser/idef-parser.h (revision e4418354c0789330b57b06358d51d8ecc21eb39c)
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