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 
37 struct dxil_type_list {
38    struct dxil_type **types;
39    size_t num_types;
40 };
41 
42 struct 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 
76 struct dxil_value {
77    int id;
78    const struct dxil_type *type;
79 };
80 
81 struct 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 
93 struct 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 
103 struct dxil_attrib {
104    enum {
105       DXIL_ATTR_ENUM
106    } type;
107 
108    union {
109       enum dxil_attr_kind kind;
110    };
111 };
112 
113 struct attrib_set {
114    struct dxil_attrib attrs[2];
115    unsigned num_attrs;
116    struct list_head head;
117 };
118 
119 struct dxil_instr_binop {
120    enum dxil_bin_opcode opcode;
121    const struct dxil_value *operands[2];
122    enum dxil_opt_flags flags;
123 };
124 
125 struct dxil_instr_cmp {
126    enum dxil_cmp_pred pred;
127    const struct dxil_value *operands[2];
128 };
129 
130 struct dxil_instr_select {
131    const struct dxil_value *operands[3];
132 };
133 
134 struct dxil_instr_cast {
135    enum dxil_cast_opcode opcode;
136    const struct dxil_type *type;
137    const struct dxil_value *value;
138 };
139 
140 struct dxil_instr_call {
141    const struct dxil_func *func;
142    struct dxil_value **args;
143    size_t num_args;
144 };
145 
146 struct dxil_instr_ret {
147    struct dxil_value *value;
148 };
149 
150 struct dxil_instr_extractval {
151    const struct dxil_value *src;
152    const struct dxil_type *type;
153    unsigned int idx;
154 };
155 
156 struct dxil_instr_br {
157    const struct dxil_value *cond;
158    unsigned succ[2];
159 };
160 
161 struct 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[127];
167    size_t num_incoming;
168 };
169 
170 struct 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 
177 struct 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 
184 struct dxil_instr_load {
185    const struct dxil_value *ptr;
186    const struct dxil_type *type;
187    unsigned align;
188    bool is_volatile;
189 };
190 
191 struct dxil_instr_store {
192    const struct dxil_value *value, *ptr;
193    unsigned align;
194    bool is_volatile;
195 };
196 
197 struct 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 
205 struct 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 
212 struct 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 
255 struct 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 
268 struct 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 
293 struct 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