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