1/*
2 * Copyright © Microsoft Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24#ifndef DXIL_INTERNAL_H
25#define DXIL_INTERNAL_H
26
27#include "dxil_module.h"
28
29#include "util/list.h"
30
31#include <stdint.h>
32
33// Malloc.h defines a macro for alloca. Let's at least make sure that all includers
34// of this header have the same definition of alloca.
35#include <malloc.h>
36
37struct dxil_type_list {
38   struct dxil_type **types;
39   size_t num_types;
40};
41
42struct dxil_type {
43   enum type_type {
44      TYPE_VOID,
45      TYPE_INTEGER,
46      TYPE_FLOAT,
47      TYPE_POINTER,
48      TYPE_STRUCT,
49      TYPE_ARRAY,
50      TYPE_VECTOR,
51      TYPE_FUNCTION
52   } type;
53
54   union {
55      unsigned int_bits;
56      unsigned float_bits;
57      const struct dxil_type *ptr_target_type;
58      struct {
59         const char *name;
60         struct dxil_type_list elem;
61      } struct_def;
62      struct {
63         const struct dxil_type *ret_type;
64         struct dxil_type_list args;
65      } function_def;
66      struct {
67         const struct dxil_type *elem_type;
68         size_t num_elems;
69      } array_or_vector_def;
70   };
71
72   struct list_head head;
73   unsigned id;
74};
75
76struct dxil_value {
77   int id;
78   const struct dxil_type *type;
79};
80
81struct dxil_gvar {
82   const char *name;
83   const struct dxil_type *type;
84   bool constant;
85   enum dxil_address_space as;
86   int align;
87
88   const struct dxil_value *initializer;
89   struct dxil_value value;
90   struct list_head head;
91};
92
93struct dxil_func {
94   char *name;
95   const struct dxil_type *type;
96   bool decl;
97   unsigned attr_set;
98
99   struct dxil_value value;
100   struct list_head head;
101};
102
103struct dxil_attrib {
104   enum {
105      DXIL_ATTR_ENUM
106   } type;
107
108   union {
109      enum dxil_attr_kind kind;
110   };
111};
112
113struct attrib_set {
114   struct dxil_attrib attrs[2];
115   unsigned num_attrs;
116   struct list_head head;
117};
118
119struct dxil_instr_binop {
120   enum dxil_bin_opcode opcode;
121   const struct dxil_value *operands[2];
122   enum dxil_opt_flags flags;
123};
124
125struct dxil_instr_cmp {
126   enum dxil_cmp_pred pred;
127   const struct dxil_value *operands[2];
128};
129
130struct dxil_instr_select {
131   const struct dxil_value *operands[3];
132};
133
134struct dxil_instr_cast {
135   enum dxil_cast_opcode opcode;
136   const struct dxil_type *type;
137   const struct dxil_value *value;
138};
139
140struct dxil_instr_call {
141   const struct dxil_func *func;
142   struct dxil_value **args;
143   size_t num_args;
144};
145
146struct dxil_instr_ret {
147   struct dxil_value *value;
148};
149
150struct dxil_instr_extractval {
151   const struct dxil_value *src;
152   const struct dxil_type *type;
153   unsigned int idx;
154};
155
156struct dxil_instr_br {
157   const struct dxil_value *cond;
158   unsigned succ[2];
159};
160
161struct dxil_instr_phi {
162   const struct dxil_type *type;
163   struct dxil_phi_src {
164      const struct dxil_value *value;
165      unsigned block;
166   } *incoming;
167   size_t num_incoming;
168};
169
170struct dxil_instr_alloca {
171   const struct dxil_type *alloc_type;
172   const struct dxil_type *size_type;
173   const struct dxil_value *size;
174   unsigned align;
175};
176
177struct dxil_instr_gep {
178   bool inbounds;
179   const struct dxil_type *source_elem_type;
180   struct dxil_value **operands;
181   size_t num_operands;
182};
183
184struct dxil_instr_load {
185   const struct dxil_value *ptr;
186   const struct dxil_type *type;
187   unsigned align;
188   bool is_volatile;
189};
190
191struct dxil_instr_store {
192   const struct dxil_value *value, *ptr;
193   unsigned align;
194   bool is_volatile;
195};
196
197struct dxil_instr_atomicrmw {
198   const struct dxil_value *value, *ptr;
199   enum dxil_rmw_op op;
200   bool is_volatile;
201   enum dxil_atomic_ordering ordering;
202   enum dxil_sync_scope syncscope;
203};
204
205struct dxil_instr_cmpxchg {
206   const struct dxil_value *cmpval, *newval, *ptr;
207   bool is_volatile;
208   enum dxil_atomic_ordering ordering;
209   enum dxil_sync_scope syncscope;
210};
211
212struct dxil_instr {
213   enum instr_type {
214      INSTR_BINOP,
215      INSTR_CMP,
216      INSTR_SELECT,
217      INSTR_CAST,
218      INSTR_BR,
219      INSTR_PHI,
220      INSTR_CALL,
221      INSTR_RET,
222      INSTR_EXTRACTVAL,
223      INSTR_ALLOCA,
224      INSTR_GEP,
225      INSTR_LOAD,
226      INSTR_STORE,
227      INSTR_ATOMICRMW,
228      INSTR_CMPXCHG,
229   } type;
230
231   union {
232      struct dxil_instr_binop binop;
233      struct dxil_instr_cmp cmp;
234      struct dxil_instr_select select;
235      struct dxil_instr_cast cast;
236      struct dxil_instr_call call;
237      struct dxil_instr_ret ret;
238      struct dxil_instr_extractval extractval;
239      struct dxil_instr_phi phi;
240      struct dxil_instr_br br;
241      struct dxil_instr_alloca alloca;
242      struct dxil_instr_gep gep;
243      struct dxil_instr_load load;
244      struct dxil_instr_store store;
245      struct dxil_instr_atomicrmw atomicrmw;
246      struct dxil_instr_cmpxchg cmpxchg;
247   };
248
249   bool has_value;
250   struct dxil_value value;
251
252   struct list_head head;
253};
254
255struct dxil_const {
256   struct dxil_value value;
257
258   bool undef;
259   union {
260      intmax_t int_value;
261      double float_value;
262      const struct dxil_value **array_values;
263   };
264
265   struct list_head head;
266};
267
268struct dxil_mdnode {
269   enum mdnode_type {
270      MD_STRING,
271      MD_VALUE,
272      MD_NODE
273   } type;
274
275   union {
276      char *string;
277
278      struct {
279         const struct dxil_type *type;
280         const struct dxil_value *value;
281      } value;
282
283      struct {
284         const struct dxil_mdnode **subnodes;
285         size_t num_subnodes;
286      } node;
287   };
288
289   struct list_head head;
290   unsigned id;
291};
292
293struct dxil_named_node {
294   char *name;
295   const struct dxil_mdnode **subnodes;
296   size_t num_subnodes;
297   struct list_head head;
298};
299
300#endif // DXIL_INTERNAL_H
301