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#include "dxil_module.h"
25#include "dxil_internal.h"
26
27#include "util/macros.h"
28#include "util/u_math.h"
29#include "util/u_memory.h"
30#include "util/rb_tree.h"
31
32#include <assert.h>
33#include <stdio.h>
34
35void
36dxil_module_init(struct dxil_module *m, void *ralloc_ctx)
37{
38   assert(ralloc_ctx);
39
40   memset(m, 0, sizeof(struct dxil_module));
41   m->ralloc_ctx = ralloc_ctx;
42
43   dxil_buffer_init(&m->buf, 2);
44   memset(&m->feats, 0, sizeof(m->feats));
45
46   list_inithead(&m->type_list);
47   list_inithead(&m->func_list);
48   list_inithead(&m->func_def_list);
49   list_inithead(&m->attr_set_list);
50   list_inithead(&m->gvar_list);
51   list_inithead(&m->const_list);
52   list_inithead(&m->mdnode_list);
53   list_inithead(&m->md_named_node_list);
54
55   m->functions = rzalloc(ralloc_ctx, struct rb_tree);
56   rb_tree_init(m->functions);
57}
58
59void
60dxil_module_release(struct dxil_module *m)
61{
62   dxil_buffer_finish(&m->buf);
63}
64
65static bool
66emit_bits64(struct dxil_buffer *b, uint64_t data, unsigned width)
67{
68   if (data > UINT32_MAX) {
69      assert(width > 32);
70      return dxil_buffer_emit_bits(b, (uint32_t)(data & UINT32_MAX), width) &&
71             dxil_buffer_emit_bits(b, (uint32_t)(data >> 32), width - 32);
72   } else
73      return dxil_buffer_emit_bits(b, (uint32_t)data, width);
74}
75
76/* See the LLVM documentation for details about what these are all about:
77 * https://www.llvm.org/docs/BitCodeFormat.html#abbreviation-ids
78 */
79enum dxil_fixed_abbrev {
80   DXIL_END_BLOCK = 0,
81   DXIL_ENTER_SUBBLOCK = 1,
82   DXIL_DEFINE_ABBREV = 2,
83   DXIL_UNABBREV_RECORD = 3,
84   DXIL_FIRST_APPLICATION_ABBREV = 4
85};
86
87static bool
88enter_subblock(struct dxil_module *m, unsigned id, unsigned abbrev_width)
89{
90   assert(m->num_blocks < ARRAY_SIZE(m->blocks));
91   m->blocks[m->num_blocks].abbrev_width = m->buf.abbrev_width;
92
93   if (!dxil_buffer_emit_abbrev_id(&m->buf, DXIL_ENTER_SUBBLOCK) ||
94       !dxil_buffer_emit_vbr_bits(&m->buf, id, 8) ||
95       !dxil_buffer_emit_vbr_bits(&m->buf, abbrev_width, 4) ||
96       !dxil_buffer_align(&m->buf))
97      return false;
98
99   m->buf.abbrev_width = abbrev_width;
100   m->blocks[m->num_blocks++].offset = blob_reserve_uint32(&m->buf.blob);
101   return true;
102}
103
104static bool
105exit_block(struct dxil_module *m)
106{
107   assert(m->num_blocks > 0);
108   assert(m->num_blocks < ARRAY_SIZE(m->blocks));
109
110   if (!dxil_buffer_emit_abbrev_id(&m->buf, DXIL_END_BLOCK) ||
111       !dxil_buffer_align(&m->buf))
112      return false;
113
114   intptr_t size_offset = m->blocks[m->num_blocks - 1].offset;
115   uint32_t size = (m->buf.blob.size - size_offset - 1) / sizeof(uint32_t);
116   if (!blob_overwrite_uint32(&m->buf.blob, size_offset, size))
117      return false;
118
119   m->num_blocks--;
120   m->buf.abbrev_width = m->blocks[m->num_blocks].abbrev_width;
121   return true;
122}
123
124static bool
125emit_record_no_abbrev(struct dxil_buffer *b, unsigned code,
126                      const uint64_t *data, size_t size)
127{
128   if (!dxil_buffer_emit_abbrev_id(b, DXIL_UNABBREV_RECORD) ||
129       !dxil_buffer_emit_vbr_bits(b, code, 6) ||
130       !dxil_buffer_emit_vbr_bits(b, size, 6))
131      return false;
132
133   for (size_t i = 0; i < size; ++i)
134      if (!dxil_buffer_emit_vbr_bits(b, data[i], 6))
135         return false;
136
137   return true;
138}
139
140static bool
141emit_record(struct dxil_module *m, unsigned code,
142            const uint64_t *data, size_t size)
143{
144   return emit_record_no_abbrev(&m->buf, code, data, size);
145}
146
147static bool
148emit_record_int(struct dxil_module *m, unsigned code, int value)
149{
150   uint64_t data = value;
151   return emit_record(m, code, &data, 1);
152}
153
154static bool
155is_char6(char ch)
156{
157   if ((ch >= 'a' && ch <= 'z') ||
158       (ch >= 'A' && ch <= 'Z') ||
159       (ch >= '0' && ch <= '9'))
160     return true;
161
162   switch (ch) {
163   case '.':
164   case '_':
165      return true;
166
167   default:
168      return false;
169   }
170}
171
172static bool
173is_char6_string(const char *str)
174{
175   while (*str != '\0') {
176      if (!is_char6(*str++))
177         return false;
178   }
179   return true;
180}
181
182static bool
183is_char7_string(const char *str)
184{
185   while (*str != '\0') {
186      if (*str++ & 0x80)
187         return false;
188   }
189   return true;
190}
191
192static unsigned
193encode_char6(char ch)
194{
195   const int letters = 'z' - 'a' + 1;
196
197   if (ch >= 'a' && ch <= 'z')
198      return ch - 'a';
199   else if (ch >= 'A' && ch <= 'Z')
200      return letters + ch - 'A';
201   else if (ch >= '0' && ch <= '9')
202      return 2 * letters + ch - '0';
203
204   switch (ch) {
205   case '.': return 62;
206   case '_': return 63;
207   default:
208      unreachable("invalid char6-character");
209   }
210}
211
212static bool
213emit_fixed(struct dxil_buffer *b, uint64_t data, unsigned width)
214{
215   if (!width)
216      return true;
217
218   return emit_bits64(b, data, width);
219}
220
221static bool
222emit_vbr(struct dxil_buffer *b, uint64_t data, unsigned width)
223{
224   if (!width)
225      return true;
226
227   return dxil_buffer_emit_vbr_bits(b, data, width);
228}
229
230static bool
231emit_char6(struct dxil_buffer *b, uint64_t data)
232{
233   return dxil_buffer_emit_bits(b, encode_char6((char)data), 6);
234}
235
236struct dxil_abbrev {
237   struct {
238      enum {
239         DXIL_OP_LITERAL = 0,
240         DXIL_OP_FIXED = 1,
241         DXIL_OP_VBR = 2,
242         DXIL_OP_ARRAY = 3,
243         DXIL_OP_CHAR6 = 4,
244         DXIL_OP_BLOB = 5
245      } type;
246      union {
247         uint64_t value;
248         uint64_t encoding_data;
249      };
250   } operands[7];
251   size_t num_operands;
252};
253
254static bool
255emit_record_abbrev(struct dxil_buffer *b,
256                   unsigned abbrev, const struct dxil_abbrev *a,
257                   const uint64_t *data, size_t size)
258{
259   assert(abbrev >= DXIL_FIRST_APPLICATION_ABBREV);
260
261   if (!dxil_buffer_emit_abbrev_id(b, abbrev))
262      return false;
263
264   size_t curr_data = 0;
265   for (int i = 0; i < a->num_operands; ++i) {
266      switch (a->operands[i].type) {
267      case DXIL_OP_LITERAL:
268         assert(curr_data < size);
269         assert(data[curr_data] == a->operands[i].value);
270         curr_data++;
271         /* literals are no-ops, because their value is defined in the
272            abbrev-definition already */
273         break;
274
275      case DXIL_OP_FIXED:
276         assert(curr_data < size);
277         if (!emit_fixed(b, data[curr_data++], a->operands[i].encoding_data))
278            return false;
279         break;
280
281      case DXIL_OP_VBR:
282         assert(curr_data < size);
283         if (!emit_vbr(b, data[curr_data++], a->operands[i].encoding_data))
284            return false;
285         break;
286
287      case DXIL_OP_ARRAY:
288         assert(i == a->num_operands - 2); /* arrays should always be second to last */
289
290         if (!dxil_buffer_emit_vbr_bits(b, size - curr_data, 6))
291            return false;
292
293         switch (a->operands[i + 1].type) {
294         case DXIL_OP_FIXED:
295            while (curr_data < size)
296               if (!emit_fixed(b, data[curr_data++], a->operands[i + 1].encoding_data))
297                  return false;
298            break;
299
300         case DXIL_OP_VBR:
301            while (curr_data < size)
302               if (!emit_vbr(b, data[curr_data++], a->operands[i + 1].encoding_data))
303                  return false;
304            break;
305
306         case DXIL_OP_CHAR6:
307            while (curr_data < size)
308               if (!emit_char6(b, data[curr_data++]))
309                  return false;
310            break;
311
312         default:
313            unreachable("unexpected operand type");
314         }
315         return true; /* we're done */
316
317      case DXIL_OP_CHAR6:
318         assert(curr_data < size);
319         if (!emit_char6(b, data[curr_data++]))
320            return false;
321         break;
322
323      case DXIL_OP_BLOB:
324         unreachable("HALP, unplement!");
325
326      default:
327         unreachable("unexpected operand type");
328      }
329   }
330
331   assert(curr_data == size);
332   return true;
333}
334
335
336static struct dxil_type *
337create_type(struct dxil_module *m, enum type_type type)
338{
339   struct dxil_type *ret = rzalloc_size(m->ralloc_ctx,
340                                        sizeof(struct dxil_type));
341   if (ret) {
342      ret->type = type;
343      ret->id = list_length(&m->type_list);
344      list_addtail(&ret->head, &m->type_list);
345   }
346   return ret;
347}
348
349static bool
350types_equal(const struct dxil_type *lhs, const struct dxil_type *rhs);
351
352static bool
353type_list_equal(const struct dxil_type_list *lhs,
354                const struct dxil_type_list *rhs)
355{
356   if (lhs->num_types != rhs->num_types)
357      return false;
358   for (unsigned i = 0; i < lhs->num_types; ++i)
359      if (!types_equal(lhs->types[i],  rhs->types[i]))
360          return false;
361   return true;
362}
363
364static bool
365types_equal(const struct dxil_type *lhs, const struct dxil_type *rhs)
366{
367   if (lhs == rhs)
368      return true;
369
370   /* Below we only assert that different type pointers really define different types
371    * Since this function is only called in asserts, it is not needed to put the code
372    * into a #ifdef NDEBUG statement */
373   if (lhs->type != rhs->type)
374      return false;
375
376   bool retval = false;
377   switch (lhs->type) {
378   case TYPE_VOID:
379      retval = true;
380      break;
381   case TYPE_FLOAT:
382      retval = lhs->float_bits == rhs->float_bits;
383      break;
384   case TYPE_INTEGER:
385      retval = lhs->int_bits == rhs->int_bits;
386      break;
387   case TYPE_POINTER:
388      retval = types_equal(lhs->ptr_target_type, rhs->ptr_target_type);
389      break;
390   case TYPE_ARRAY:
391   case TYPE_VECTOR:
392      retval = (lhs->array_or_vector_def.num_elems == rhs->array_or_vector_def.num_elems) &&
393               types_equal(lhs->array_or_vector_def.elem_type,
394                           rhs->array_or_vector_def.elem_type);
395      break;
396   case TYPE_FUNCTION:
397      if (!types_equal(lhs->function_def.ret_type,
398                            rhs->function_def.ret_type))
399         return false;
400      retval = type_list_equal(&lhs->function_def.args, &rhs->function_def.args);
401      break;
402   case TYPE_STRUCT:
403      retval = type_list_equal(&lhs->struct_def.elem, &rhs->struct_def.elem);
404   }
405   assert(!retval && "Types are equal in structure but not as pointers");
406   return retval;
407}
408
409bool
410dxil_value_type_equal_to(const struct dxil_value *value,
411                         const struct dxil_type *rhs)
412{
413   return types_equal(value->type, rhs);
414}
415
416nir_alu_type
417dxil_type_to_nir_type(const struct dxil_type *type)
418{
419   assert(type);
420   switch (type->type) {
421   case TYPE_INTEGER:
422      return type->int_bits == 1 ? nir_type_bool : nir_type_int;
423   case TYPE_FLOAT:
424      return nir_type_float;
425   default:
426      unreachable("Unexpected type in dxil_type_to_nir_type");
427   }
428}
429
430bool
431dxil_value_type_bitsize_equal_to(const struct dxil_value *value, unsigned bitsize)
432{
433   switch (value->type->type) {
434   case TYPE_INTEGER:
435      return value->type->int_bits == bitsize;
436   case TYPE_FLOAT:
437      return value->type->float_bits == bitsize;
438   default:
439      return false;
440   }
441}
442
443const struct dxil_type *
444dxil_value_get_type(const struct dxil_value *value)
445{
446   return value->type;
447}
448
449const struct dxil_type *
450dxil_module_get_void_type(struct dxil_module *m)
451{
452   if (!m->void_type)
453      m->void_type = create_type(m, TYPE_VOID);
454   return m->void_type;
455}
456
457static const struct dxil_type *
458create_int_type(struct dxil_module *m, unsigned bit_size)
459{
460   struct dxil_type *type = create_type(m, TYPE_INTEGER);
461   if (type)
462      type->int_bits = bit_size;
463   return type;
464}
465
466static const struct dxil_type *
467get_int1_type(struct dxil_module *m)
468{
469   if (!m->int1_type)
470      m->int1_type = create_int_type(m, 1);
471   return m->int1_type;
472}
473
474static const struct dxil_type *
475get_int8_type(struct dxil_module *m)
476{
477   if (!m->int8_type)
478      m->int8_type = create_int_type(m, 8);
479   return m->int8_type;
480}
481
482static const struct dxil_type *
483get_int16_type(struct dxil_module *m)
484{
485   if (!m->int16_type)
486      m->int16_type = create_int_type(m, 16);
487   return m->int16_type;
488}
489
490static const struct dxil_type *
491get_int32_type(struct dxil_module *m)
492{
493   if (!m->int32_type)
494      m->int32_type = create_int_type(m, 32);
495   return m->int32_type;
496}
497
498static const struct dxil_type *
499get_int64_type(struct dxil_module *m)
500{
501   if (!m->int64_type)
502      m->int64_type = create_int_type(m, 64);
503   return m->int64_type;
504}
505
506static const struct dxil_type *
507create_float_type(struct dxil_module *m, unsigned bit_size)
508{
509   struct dxil_type *type = create_type(m, TYPE_FLOAT);
510   if (type)
511      type->float_bits = bit_size;
512   return type;
513}
514
515const struct dxil_type *
516dxil_module_get_int_type(struct dxil_module *m, unsigned bit_size)
517{
518   switch (bit_size) {
519   case 1: return get_int1_type(m);
520   case 8: return get_int8_type(m);
521   case 16: return get_int16_type(m);
522   case 32: return get_int32_type(m);
523   case 64: return get_int64_type(m);
524   default:
525      unreachable("unsupported bit-width");
526   }
527}
528
529static const struct dxil_type *
530get_float16_type(struct dxil_module *m)
531{
532   if (!m->float16_type)
533      m->float16_type = create_float_type(m, 16);
534   return m->float16_type;
535}
536
537static const struct dxil_type *
538get_float32_type(struct dxil_module *m)
539{
540   if (!m->float32_type)
541      m->float32_type = create_float_type(m, 32);
542   return m->float32_type;
543}
544
545static const struct dxil_type *
546get_float64_type(struct dxil_module *m)
547{
548   if (!m->float64_type)
549      m->float64_type = create_float_type(m, 64);
550   return m->float64_type;
551}
552
553const struct dxil_type *
554dxil_module_get_float_type(struct dxil_module *m, unsigned bit_size)
555{
556   switch (bit_size) {
557   case 16: return get_float16_type(m);
558   case 32: return get_float32_type(m);
559   case 64: return get_float64_type(m);
560   default:
561      unreachable("unsupported bit-width");
562   }
563   return get_float32_type(m);
564}
565
566const struct dxil_type *
567dxil_module_get_pointer_type(struct dxil_module *m,
568                             const struct dxil_type *target)
569{
570   struct dxil_type *type;
571   LIST_FOR_EACH_ENTRY(type, &m->type_list, head) {
572      if (type->type == TYPE_POINTER &&
573          type->ptr_target_type == target)
574         return type;
575   }
576
577   type = create_type(m, TYPE_POINTER);
578   if (type)
579      type->ptr_target_type = target;
580   return type;
581}
582
583const struct dxil_type *
584dxil_module_get_struct_type(struct dxil_module *m,
585                            const char *name,
586                            const struct dxil_type **elem_types,
587                            size_t num_elem_types)
588{
589   assert(!name || strlen(name) > 0);
590
591   struct dxil_type *type;
592   LIST_FOR_EACH_ENTRY(type, &m->type_list, head) {
593      if (type->type != TYPE_STRUCT)
594         continue;
595
596      if ((name == NULL) != (type->struct_def.name == NULL))
597         continue;
598
599      if (name && strcmp(type->struct_def.name, name))
600         continue;
601
602      if (type->struct_def.elem.num_types == num_elem_types &&
603          !memcmp(type->struct_def.elem.types, elem_types,
604                  sizeof(struct dxil_type *) * num_elem_types))
605         return type;
606   }
607
608   type = create_type(m, TYPE_STRUCT);
609   if (type) {
610      if (name) {
611         type->struct_def.name = ralloc_strdup(type, name);
612         if (!type->struct_def.name)
613            return NULL;
614      } else
615         type->struct_def.name = NULL;
616
617      type->struct_def.elem.types = ralloc_array(type, struct dxil_type *,
618                                                 num_elem_types);
619      if (!type->struct_def.elem.types)
620         return NULL;
621
622      memcpy(type->struct_def.elem.types, elem_types,
623             sizeof(struct dxil_type *) * num_elem_types);
624      type->struct_def.elem.num_types = num_elem_types;
625   }
626   return type;
627}
628
629const struct dxil_type *
630dxil_module_get_array_type(struct dxil_module *m,
631                           const struct dxil_type *elem_type,
632                           size_t num_elems)
633{
634   struct dxil_type *type;
635   LIST_FOR_EACH_ENTRY(type, &m->type_list, head) {
636      if (type->type != TYPE_ARRAY)
637         continue;
638
639      if (type->array_or_vector_def.elem_type == elem_type &&
640          type->array_or_vector_def.num_elems == num_elems)
641         return type;
642   }
643
644   type = create_type(m, TYPE_ARRAY);
645   if (type) {
646      type->array_or_vector_def.elem_type = elem_type;
647      type->array_or_vector_def.num_elems = num_elems;
648   }
649   return type;
650}
651
652const struct dxil_type *
653dxil_module_get_vector_type(struct dxil_module *m,
654                            const struct dxil_type *elem_type,
655                            size_t num_elems)
656{
657   struct dxil_type *type;
658   LIST_FOR_EACH_ENTRY(type, &m->type_list, head) {
659      if (type->type == TYPE_VECTOR &&
660          type->array_or_vector_def.elem_type == elem_type &&
661          type->array_or_vector_def.num_elems == num_elems)
662         return type;
663   }
664
665   type = create_type(m, TYPE_VECTOR);
666   if (!type)
667      return NULL;
668
669   type->array_or_vector_def.elem_type = elem_type;
670   type->array_or_vector_def.num_elems = num_elems;
671   return type;
672}
673
674const struct dxil_type *
675dxil_get_overload_type(struct dxil_module *mod, enum overload_type overload)
676{
677   switch (overload) {
678   case DXIL_I16: return get_int16_type(mod);
679   case DXIL_I32: return get_int32_type(mod);
680   case DXIL_I64: return get_int64_type(mod);
681   case DXIL_F16: return get_float16_type(mod);
682   case DXIL_F32: return get_float32_type(mod);
683   case DXIL_F64: return get_float64_type(mod);
684   default:
685      unreachable("unexpected overload type");
686   }
687}
688
689const struct dxil_type *
690dxil_module_get_handle_type(struct dxil_module *m)
691{
692   const struct dxil_type *int8_type = get_int8_type(m);
693   if (!int8_type)
694      return NULL;
695
696   const struct dxil_type *ptr_type = dxil_module_get_pointer_type(m, int8_type);
697   if (!ptr_type)
698      return NULL;
699
700   return dxil_module_get_struct_type(m, "dx.types.Handle", &ptr_type, 1);
701}
702
703const struct dxil_type *
704dxil_module_get_cbuf_ret_type(struct dxil_module *mod, enum overload_type overload)
705{
706   const struct dxil_type *overload_type = dxil_get_overload_type(mod, overload);
707   const struct dxil_type *fields[4] = { overload_type, overload_type, overload_type, overload_type };
708   unsigned num_fields;
709
710   char name[64];
711   snprintf(name, sizeof(name), "dx.types.CBufRet.%s", dxil_overload_suffix(overload));
712
713   switch (overload) {
714   case DXIL_I32:
715   case DXIL_F32:
716      num_fields = 4;
717      break;
718   case DXIL_I64:
719   case DXIL_F64:
720      num_fields = 2;
721      break;
722   default:
723      unreachable("unexpected overload type");
724   }
725
726   return dxil_module_get_struct_type(mod, name, fields, num_fields);
727}
728
729const struct dxil_type *
730dxil_module_get_split_double_ret_type(struct dxil_module *mod)
731{
732   const struct dxil_type *int32_type = dxil_module_get_int_type(mod, 32);
733   const struct dxil_type *fields[2] = { int32_type, int32_type };
734
735   return dxil_module_get_struct_type(mod, "dx.types.splitdouble", fields, 2);
736}
737
738static const struct dxil_type *
739dxil_module_get_type_from_comp_type(struct dxil_module *m, enum dxil_component_type comp_type)
740{
741   switch (comp_type) {
742   case DXIL_COMP_TYPE_U32: return get_int32_type(m);
743   case DXIL_COMP_TYPE_I32: return get_int32_type(m);
744   case DXIL_COMP_TYPE_F32: return get_float32_type(m);
745   case DXIL_COMP_TYPE_F64: return get_float64_type(m);
746   case DXIL_COMP_TYPE_U16: return get_int16_type(m);
747   case DXIL_COMP_TYPE_I16: return get_int16_type(m);
748   case DXIL_COMP_TYPE_U64: return get_int64_type(m);
749   case DXIL_COMP_TYPE_I64: return get_int64_type(m);
750   case DXIL_COMP_TYPE_I1: return get_int1_type(m);
751
752   case DXIL_COMP_TYPE_F16:
753   default:
754      unreachable("unexpected component type");
755   }
756}
757
758static const char *
759get_res_comp_type_name(enum dxil_component_type comp_type)
760{
761   switch (comp_type) {
762   case DXIL_COMP_TYPE_F64: return "double";
763   case DXIL_COMP_TYPE_F32: return "float";
764   case DXIL_COMP_TYPE_I32: return "int";
765   case DXIL_COMP_TYPE_U32: return "uint";
766   case DXIL_COMP_TYPE_I64: return "int64";
767   case DXIL_COMP_TYPE_U64: return "uint64";
768   default:
769      unreachable("unexpected resource component type");
770   }
771}
772
773static const char *
774get_res_dimension_type_name(enum dxil_resource_kind kind)
775{
776   switch (kind) {
777   case DXIL_RESOURCE_KIND_TYPED_BUFFER: return "Buffer";
778   case DXIL_RESOURCE_KIND_TEXTURE1D: return "Texture1D";
779   case DXIL_RESOURCE_KIND_TEXTURE1D_ARRAY: return "Texture1DArray";
780   case DXIL_RESOURCE_KIND_TEXTURE2D: return "Texture2D";
781   case DXIL_RESOURCE_KIND_TEXTURE2DMS: return "Texture2DMS";
782   case DXIL_RESOURCE_KIND_TEXTURE2D_ARRAY: return "Texture2DArray";
783   case DXIL_RESOURCE_KIND_TEXTURE2DMS_ARRAY: return "Texture2DMSArray";
784   case DXIL_RESOURCE_KIND_TEXTURE3D: return "Texture3D";
785   case DXIL_RESOURCE_KIND_TEXTURECUBE: return "TextureCube";
786   case DXIL_RESOURCE_KIND_TEXTURECUBE_ARRAY: return "TextureCubeArray";
787   default:
788      unreachable("unexpected resource kind");
789   }
790}
791
792static const char *
793get_res_ms_postfix(enum dxil_resource_kind kind)
794{
795   switch (kind) {
796   case DXIL_RESOURCE_KIND_TEXTURE2DMS:
797   case DXIL_RESOURCE_KIND_TEXTURE2DMS_ARRAY:
798      return ", 0";
799
800   default:
801      return " ";
802   }
803}
804const struct dxil_type *
805dxil_module_get_res_type(struct dxil_module *m, enum dxil_resource_kind kind,
806                         enum dxil_component_type comp_type, bool readwrite)
807{
808   switch (kind) {
809   case DXIL_RESOURCE_KIND_TYPED_BUFFER:
810   case DXIL_RESOURCE_KIND_TEXTURE1D:
811   case DXIL_RESOURCE_KIND_TEXTURE1D_ARRAY:
812   case DXIL_RESOURCE_KIND_TEXTURE2D:
813   case DXIL_RESOURCE_KIND_TEXTURE2D_ARRAY:
814   case DXIL_RESOURCE_KIND_TEXTURE2DMS:
815   case DXIL_RESOURCE_KIND_TEXTURE2DMS_ARRAY:
816   case DXIL_RESOURCE_KIND_TEXTURE3D:
817   case DXIL_RESOURCE_KIND_TEXTURECUBE:
818   case DXIL_RESOURCE_KIND_TEXTURECUBE_ARRAY:
819   {
820      const struct dxil_type *component_type = dxil_module_get_type_from_comp_type(m, comp_type);
821      const struct dxil_type *vec_type = dxil_module_get_vector_type(m, component_type, 4);
822      char class_name[64] = { 0 };
823      snprintf(class_name, 64, "class.%s%s<vector<%s, 4>%s>",
824               readwrite ? "RW" : "",
825               get_res_dimension_type_name(kind),
826               get_res_comp_type_name(comp_type),
827               get_res_ms_postfix(kind));
828      return dxil_module_get_struct_type(m, class_name, &vec_type, 1);
829   }
830
831   case DXIL_RESOURCE_KIND_RAW_BUFFER:
832   {
833      const struct dxil_type *component_type = dxil_module_get_int_type(m, 32);
834      char class_name[64] = { 0 };
835      snprintf(class_name, 64, "struct.%sByteAddressBuffer", readwrite ? "RW" : "");
836      return dxil_module_get_struct_type(m, class_name, &component_type, 1);
837   }
838
839   default:
840      unreachable("resource type not supported");
841   }
842}
843
844const struct dxil_type *
845dxil_module_get_resret_type(struct dxil_module *m, enum overload_type overload)
846{
847   const struct dxil_type *overload_type = dxil_get_overload_type(m, overload);
848   const struct dxil_type *int32_type = dxil_module_get_int_type(m, 32);
849   const char *name;
850   if (!overload_type)
851      return NULL;
852
853   const struct dxil_type *resret[] =
854      { overload_type, overload_type, overload_type, overload_type, int32_type };
855
856   switch (overload) {
857   case DXIL_I32: name = "dx.types.ResRet.i32"; break;
858   case DXIL_I64: name = "dx.types.ResRet.i64"; break;
859   case DXIL_F32: name = "dx.types.ResRet.f32"; break;
860   case DXIL_F64: name = "dx.types.ResRet.f64"; break;
861   default:
862      unreachable("unexpected overload type");
863   }
864
865   return dxil_module_get_struct_type(m, name, resret, 5);
866}
867
868const struct dxil_type *
869dxil_module_get_dimret_type(struct dxil_module *m)
870{
871   const struct dxil_type *int32_type = dxil_module_get_int_type(m, 32);
872
873   const struct dxil_type *dimret[] =
874      { int32_type, int32_type, int32_type, int32_type };
875
876   return dxil_module_get_struct_type(m, "dx.types.Dimensions", dimret, 4);
877}
878
879const struct dxil_type *
880dxil_module_get_samplepos_type(struct dxil_module *m)
881{
882   const struct dxil_type *float_type = dxil_module_get_float_type(m, 32);
883
884   const struct dxil_type *samplepos[] =
885      { float_type, float_type };
886
887   return dxil_module_get_struct_type(m, "dx.types.SamplePos", samplepos, 2);
888}
889
890const struct dxil_type *
891dxil_module_add_function_type(struct dxil_module *m,
892                              const struct dxil_type *ret_type,
893                              const struct dxil_type **arg_types,
894                              size_t num_arg_types)
895{
896   struct dxil_type *type = create_type(m, TYPE_FUNCTION);
897   if (type) {
898      type->function_def.args.types = ralloc_array(type,
899                                                  struct dxil_type *,
900                                                  num_arg_types);
901      if (!type->function_def.args.types)
902         return NULL;
903
904      memcpy(type->function_def.args.types, arg_types,
905             sizeof(struct dxil_type *) * num_arg_types);
906      type->function_def.args.num_types = num_arg_types;
907      type->function_def.ret_type = ret_type;
908   }
909   return type;
910}
911
912
913enum type_codes {
914  TYPE_CODE_NUMENTRY = 1,
915  TYPE_CODE_VOID = 2,
916  TYPE_CODE_FLOAT = 3,
917  TYPE_CODE_DOUBLE = 4,
918  TYPE_CODE_LABEL = 5,
919  TYPE_CODE_OPAQUE = 6,
920  TYPE_CODE_INTEGER = 7,
921  TYPE_CODE_POINTER = 8,
922  TYPE_CODE_FUNCTION_OLD = 9,
923  TYPE_CODE_HALF = 10,
924  TYPE_CODE_ARRAY = 11,
925  TYPE_CODE_VECTOR = 12,
926  TYPE_CODE_X86_FP80 = 13,
927  TYPE_CODE_FP128 = 14,
928  TYPE_CODE_PPC_FP128 = 15,
929  TYPE_CODE_METADATA = 16,
930  TYPE_CODE_X86_MMX = 17,
931  TYPE_CODE_STRUCT_ANON = 18,
932  TYPE_CODE_STRUCT_NAME = 19,
933  TYPE_CODE_STRUCT_NAMED = 20,
934  TYPE_CODE_FUNCTION = 21
935};
936
937#define LITERAL(x) { DXIL_OP_LITERAL, { (x) } }
938#define FIXED(x) { DXIL_OP_FIXED, { (x) } }
939#define VBR(x) { DXIL_OP_VBR, { (x) } }
940#define ARRAY { DXIL_OP_ARRAY, { 0 } }
941#define CHAR6 { DXIL_OP_CHAR6, { 0 } }
942#define BLOB { DXIL_OP_BLOB, { 0 } }
943
944#define TYPE_INDEX FIXED(32)
945
946enum type_table_abbrev_id {
947   TYPE_TABLE_ABBREV_POINTER,
948   TYPE_TABLE_ABBREV_FUNCTION,
949   TYPE_TABLE_ABBREV_STRUCT_ANON,
950   TYPE_TABLE_ABBREV_STRUCT_NAME,
951   TYPE_TABLE_ABBREV_STRUCT_NAMED,
952   TYPE_TABLE_ABBREV_ARRAY,
953   TYPE_TABLE_ABBREV_VECTOR,
954};
955
956static const struct dxil_abbrev
957type_table_abbrevs[] = {
958   [TYPE_TABLE_ABBREV_POINTER] = {
959      { LITERAL(TYPE_CODE_POINTER), TYPE_INDEX, LITERAL(0) }, 3
960   },
961   [TYPE_TABLE_ABBREV_FUNCTION] = {
962      { LITERAL(TYPE_CODE_FUNCTION), FIXED(1), ARRAY, TYPE_INDEX }, 4
963   },
964   [TYPE_TABLE_ABBREV_STRUCT_ANON] = {
965      { LITERAL(TYPE_CODE_STRUCT_ANON), FIXED(1), ARRAY, TYPE_INDEX }, 4
966   },
967   [TYPE_TABLE_ABBREV_STRUCT_NAME] = {
968      { LITERAL(TYPE_CODE_STRUCT_NAME), ARRAY, CHAR6 }, 3
969   },
970   [TYPE_TABLE_ABBREV_STRUCT_NAMED] = {
971      { LITERAL(TYPE_CODE_STRUCT_NAMED), FIXED(1), ARRAY, TYPE_INDEX }, 4
972   },
973   [TYPE_TABLE_ABBREV_ARRAY] = {
974      { LITERAL(TYPE_CODE_ARRAY), VBR(8), TYPE_INDEX }, 3
975   },
976   [TYPE_TABLE_ABBREV_VECTOR] = {
977      { LITERAL(TYPE_CODE_VECTOR), VBR(8), TYPE_INDEX }, 3
978   },
979};
980
981static bool
982emit_type_table_abbrev_record(struct dxil_module *m,
983                              enum type_table_abbrev_id abbrev,
984                              const uint64_t *data, size_t size)
985{
986   assert(abbrev < ARRAY_SIZE(type_table_abbrevs));
987   return emit_record_abbrev(&m->buf, abbrev + DXIL_FIRST_APPLICATION_ABBREV,
988                             type_table_abbrevs + abbrev, data, size);
989}
990
991enum constant_code {
992  CST_CODE_SETTYPE = 1,
993  CST_CODE_NULL = 2,
994  CST_CODE_UNDEF = 3,
995  CST_CODE_INTEGER = 4,
996  CST_CODE_WIDE_INTEGER = 5,
997  CST_CODE_FLOAT = 6,
998  CST_CODE_AGGREGATE = 7,
999  CST_CODE_STRING = 8,
1000  CST_CODE_CSTRING = 9,
1001  CST_CODE_CE_BINOP = 10,
1002  CST_CODE_CE_CAST = 11,
1003  CST_CODE_CE_GEP = 12,
1004  CST_CODE_CE_SELECT = 13,
1005  CST_CODE_CE_EXTRACTELT = 14,
1006  CST_CODE_CE_INSERTELT = 15,
1007  CST_CODE_CE_SHUFFLEVEC = 16,
1008  CST_CODE_CE_CMP = 17,
1009  CST_CODE_INLINEASM_OLD = 18,
1010  CST_CODE_CE_SHUFVEC_EX = 19,
1011  CST_CODE_CE_INBOUNDS_GEP = 20,
1012  CST_CODE_BLOCKADDRESS = 21,
1013  CST_CODE_DATA = 22,
1014  CST_CODE_INLINEASM = 23
1015};
1016
1017enum const_abbrev_id {
1018   CONST_ABBREV_SETTYPE,
1019   CONST_ABBREV_INTEGER,
1020   CONST_ABBREV_CE_CAST,
1021   CONST_ABBREV_NULL,
1022};
1023
1024static const struct dxil_abbrev
1025const_abbrevs[] = {
1026   [CONST_ABBREV_SETTYPE] = { { LITERAL(CST_CODE_SETTYPE), TYPE_INDEX }, 2 },
1027   [CONST_ABBREV_INTEGER] = { { LITERAL(CST_CODE_INTEGER), VBR(8) }, 2 },
1028   [CONST_ABBREV_CE_CAST] = {
1029      { LITERAL(CST_CODE_CE_CAST), FIXED(4), TYPE_INDEX, VBR(8) }, 4
1030   },
1031   [CONST_ABBREV_NULL] = { { LITERAL(CST_CODE_NULL) }, 1 },
1032};
1033
1034static bool
1035emit_const_abbrev_record(struct dxil_module *m, enum const_abbrev_id abbrev,
1036                         const uint64_t *data, size_t size)
1037{
1038   assert(abbrev < ARRAY_SIZE(const_abbrevs));
1039
1040   return emit_record_abbrev(&m->buf, abbrev + DXIL_FIRST_APPLICATION_ABBREV,
1041                             const_abbrevs + abbrev, data, size);
1042}
1043
1044enum function_code {
1045  FUNC_CODE_DECLAREBLOCKS = 1,
1046  FUNC_CODE_INST_BINOP = 2,
1047  FUNC_CODE_INST_CAST = 3,
1048  FUNC_CODE_INST_GEP_OLD = 4,
1049  FUNC_CODE_INST_SELECT = 5,
1050  FUNC_CODE_INST_EXTRACTELT = 6,
1051  FUNC_CODE_INST_INSERTELT = 7,
1052  FUNC_CODE_INST_SHUFFLEVEC = 8,
1053  FUNC_CODE_INST_CMP = 9,
1054  FUNC_CODE_INST_RET = 10,
1055  FUNC_CODE_INST_BR = 11,
1056  FUNC_CODE_INST_SWITCH = 12,
1057  FUNC_CODE_INST_INVOKE = 13,
1058  /* 14: unused */
1059  FUNC_CODE_INST_UNREACHABLE = 15,
1060  FUNC_CODE_INST_PHI = 16,
1061  /* 17-18: unused */
1062  FUNC_CODE_INST_ALLOCA = 19,
1063  FUNC_CODE_INST_LOAD = 20,
1064  /* 21-22: unused */
1065  FUNC_CODE_INST_VAARG = 23,
1066  FUNC_CODE_INST_STORE_OLD = 24,
1067  /* 25: unused */
1068  FUNC_CODE_INST_EXTRACTVAL = 26,
1069  FUNC_CODE_INST_INSERTVAL = 27,
1070  FUNC_CODE_INST_CMP2 = 28,
1071  FUNC_CODE_INST_VSELECT = 29,
1072  FUNC_CODE_INST_INBOUNDS_GEP_OLD = 30,
1073  FUNC_CODE_INST_INDIRECTBR = 31,
1074  /* 32: unused */
1075  FUNC_CODE_DEBUG_LOC_AGAIN = 33,
1076  FUNC_CODE_INST_CALL = 34,
1077  FUNC_CODE_DEBUG_LOC = 35,
1078  FUNC_CODE_INST_FENCE = 36,
1079  FUNC_CODE_INST_CMPXCHG_OLD = 37,
1080  FUNC_CODE_INST_ATOMICRMW = 38,
1081  FUNC_CODE_INST_RESUME = 39,
1082  FUNC_CODE_INST_LANDINGPAD_OLD = 40,
1083  FUNC_CODE_INST_LOADATOMIC = 41,
1084  FUNC_CODE_INST_STOREATOMIC_OLD = 42,
1085  FUNC_CODE_INST_GEP = 43,
1086  FUNC_CODE_INST_STORE = 44,
1087  FUNC_CODE_INST_STOREATOMIC = 45,
1088  FUNC_CODE_INST_CMPXCHG = 46,
1089  FUNC_CODE_INST_LANDINGPAD = 47,
1090};
1091
1092enum func_abbrev_id {
1093   FUNC_ABBREV_LOAD,
1094   FUNC_ABBREV_BINOP,
1095   FUNC_ABBREV_BINOP_FLAGS,
1096   FUNC_ABBREV_CAST,
1097   FUNC_ABBREV_RET_VOID,
1098   FUNC_ABBREV_RET_VAL,
1099   FUNC_ABBREV_UNREACHABLE,
1100   FUNC_ABBREV_GEP,
1101};
1102
1103static const struct dxil_abbrev
1104func_abbrevs[] = {
1105   [FUNC_ABBREV_LOAD] = {
1106      { LITERAL(FUNC_CODE_INST_LOAD), VBR(6), TYPE_INDEX, VBR(4),
1107        FIXED(1) }, 5
1108   },
1109   [FUNC_ABBREV_BINOP] = {
1110      { LITERAL(FUNC_CODE_INST_BINOP), VBR(6), VBR(6), FIXED(4) }, 4
1111   },
1112   [FUNC_ABBREV_BINOP_FLAGS] = {
1113      { LITERAL(FUNC_CODE_INST_BINOP), VBR(6), VBR(6), FIXED(4),
1114        FIXED(7) }, 5
1115   },
1116   [FUNC_ABBREV_CAST] = {
1117      { LITERAL(FUNC_CODE_INST_CAST), VBR(6), TYPE_INDEX, FIXED(4) }, 4
1118   },
1119   [FUNC_ABBREV_RET_VOID] = { { LITERAL(FUNC_CODE_INST_RET) }, 1 },
1120   [FUNC_ABBREV_RET_VAL] = { { LITERAL(FUNC_CODE_INST_RET), VBR(6) }, 2 },
1121   [FUNC_ABBREV_UNREACHABLE] = {
1122      { LITERAL(FUNC_CODE_INST_UNREACHABLE) }, 1
1123   },
1124   [FUNC_ABBREV_GEP] = {
1125      { LITERAL(FUNC_CODE_INST_GEP), FIXED(1), TYPE_INDEX, ARRAY,
1126        VBR(6) }, 5
1127   },
1128};
1129
1130static bool
1131emit_func_abbrev_record(struct dxil_module *m, enum func_abbrev_id abbrev,
1132                        const uint64_t *data, size_t size)
1133{
1134   assert(abbrev < ARRAY_SIZE(func_abbrevs));
1135   return emit_record_abbrev(&m->buf, abbrev + DXIL_FIRST_APPLICATION_ABBREV,
1136                             func_abbrevs + abbrev, data, size);
1137}
1138
1139static bool
1140define_abbrev(struct dxil_module *m, const struct dxil_abbrev *a)
1141{
1142   if (!dxil_buffer_emit_abbrev_id(&m->buf, DXIL_DEFINE_ABBREV) ||
1143       !dxil_buffer_emit_vbr_bits(&m->buf, a->num_operands, 5))
1144      return false;
1145
1146   for (int i = 0; i < a->num_operands; ++i) {
1147      unsigned is_literal = a->operands[i].type == DXIL_OP_LITERAL;
1148      if (!dxil_buffer_emit_bits(&m->buf, is_literal, 1))
1149         return false;
1150      if (a->operands[i].type == DXIL_OP_LITERAL) {
1151         if (!dxil_buffer_emit_vbr_bits(&m->buf, a->operands[i].value, 8))
1152            return false;
1153      } else {
1154         if (!dxil_buffer_emit_bits(&m->buf, a->operands[i].type, 3))
1155            return false;
1156         if (a->operands[i].type == DXIL_OP_FIXED) {
1157            if (!dxil_buffer_emit_vbr_bits(&m->buf,
1158                                           a->operands[i].encoding_data, 5))
1159               return false;
1160         } else if (a->operands[i].type == DXIL_OP_VBR) {
1161            if (!dxil_buffer_emit_vbr_bits(&m->buf,
1162                                           a->operands[i].encoding_data, 5))
1163               return false;
1164         }
1165      }
1166   }
1167
1168   return true;
1169}
1170
1171enum dxil_blockinfo_code {
1172   DXIL_BLOCKINFO_CODE_SETBID = 1,
1173   DXIL_BLOCKINFO_CODE_BLOCKNAME = 2,
1174   DXIL_BLOCKINFO_CODE_SETRECORDNAME = 3
1175};
1176
1177static bool
1178switch_to_block(struct dxil_module *m, uint32_t block)
1179{
1180   return emit_record_int(m, DXIL_BLOCKINFO_CODE_SETBID, block);
1181}
1182
1183enum dxil_standard_block {
1184   DXIL_BLOCKINFO = 0,
1185   DXIL_FIRST_APPLICATION_BLOCK = 8
1186};
1187
1188enum dxil_llvm_block {
1189   DXIL_MODULE = DXIL_FIRST_APPLICATION_BLOCK,
1190   DXIL_PARAMATTR = DXIL_FIRST_APPLICATION_BLOCK + 1,
1191   DXIL_PARAMATTR_GROUP = DXIL_FIRST_APPLICATION_BLOCK + 2,
1192   DXIL_CONST_BLOCK = DXIL_FIRST_APPLICATION_BLOCK + 3,
1193   DXIL_FUNCTION_BLOCK = DXIL_FIRST_APPLICATION_BLOCK + 4,
1194   DXIL_VALUE_SYMTAB_BLOCK = DXIL_FIRST_APPLICATION_BLOCK + 6,
1195   DXIL_METADATA_BLOCK = DXIL_FIRST_APPLICATION_BLOCK + 7,
1196   DXIL_TYPE_BLOCK = DXIL_FIRST_APPLICATION_BLOCK + 9,
1197};
1198
1199enum value_symtab_code {
1200  VST_CODE_ENTRY = 1,
1201  VST_CODE_BBENTRY = 2
1202};
1203
1204enum value_symtab_abbrev_id {
1205   VST_ABBREV_ENTRY_8,
1206   VST_ABBREV_ENTRY_7,
1207   VST_ABBREV_ENTRY_6,
1208   VST_ABBREV_BBENTRY_6,
1209};
1210
1211static struct dxil_abbrev value_symtab_abbrevs[] = {
1212   [VST_ABBREV_ENTRY_8] = { { FIXED(3), VBR(8), ARRAY, FIXED(8) }, 4 },
1213   [VST_ABBREV_ENTRY_7] = {
1214      { LITERAL(VST_CODE_ENTRY), VBR(8), ARRAY, FIXED(7), }, 4
1215   },
1216   [VST_ABBREV_ENTRY_6] = {
1217      { LITERAL(VST_CODE_ENTRY), VBR(8), ARRAY, CHAR6, }, 4
1218   },
1219   [VST_ABBREV_BBENTRY_6] = {
1220      { LITERAL(VST_CODE_BBENTRY), VBR(8), ARRAY, CHAR6, }, 4
1221   },
1222};
1223
1224static bool
1225emit_value_symtab_abbrevs(struct dxil_module *m)
1226{
1227   if (!switch_to_block(m, DXIL_VALUE_SYMTAB_BLOCK))
1228      return false;
1229
1230   for (int i = 0; i < ARRAY_SIZE(value_symtab_abbrevs); ++i) {
1231      if (!define_abbrev(m, value_symtab_abbrevs + i))
1232         return false;
1233   }
1234
1235   return true;
1236}
1237
1238static bool
1239emit_const_abbrevs(struct dxil_module *m)
1240{
1241   if (!switch_to_block(m, DXIL_CONST_BLOCK))
1242      return false;
1243
1244   for (int i = 0; i < ARRAY_SIZE(const_abbrevs); ++i) {
1245      if (!define_abbrev(m, const_abbrevs + i))
1246         return false;
1247   }
1248
1249   return true;
1250}
1251
1252static bool
1253emit_function_abbrevs(struct dxil_module *m)
1254{
1255   if (!switch_to_block(m, DXIL_FUNCTION_BLOCK))
1256      return false;
1257
1258   for (int i = 0; i < ARRAY_SIZE(func_abbrevs); ++i) {
1259      if (!define_abbrev(m, func_abbrevs + i))
1260         return false;
1261   }
1262
1263   return true;
1264}
1265
1266static bool
1267emit_blockinfo(struct dxil_module *m)
1268{
1269   return enter_subblock(m, DXIL_BLOCKINFO, 2) &&
1270          emit_value_symtab_abbrevs(m) &&
1271          emit_const_abbrevs(m) &&
1272          emit_function_abbrevs(m) &&
1273          exit_block(m);
1274}
1275
1276enum attribute_codes {
1277   PARAMATTR_GRP_CODE_ENTRY = 3,
1278   PARAMATTR_CODE_ENTRY = 2
1279};
1280
1281static bool
1282emit_attrib_group(struct dxil_module *m, int id, uint32_t slot,
1283                  const struct dxil_attrib *attrs, size_t num_attrs)
1284{
1285   uint64_t record[64];
1286   record[0] = id;
1287   record[1] = slot;
1288   size_t size = 2;
1289
1290   for (int i = 0; i < num_attrs; ++i) {
1291      switch (attrs[i].type) {
1292      case DXIL_ATTR_ENUM:
1293         assert(size < ARRAY_SIZE(record) - 2);
1294         record[size++] = 0;
1295         record[size++] = attrs[i].kind;
1296         break;
1297
1298      default:
1299         unreachable("unsupported attrib type");
1300      }
1301   }
1302
1303   return emit_record(m, PARAMATTR_GRP_CODE_ENTRY, record, size);
1304}
1305
1306static bool
1307emit_attrib_group_table(struct dxil_module *m)
1308{
1309   if (!enter_subblock(m, DXIL_PARAMATTR_GROUP, 3))
1310      return false;
1311
1312   struct attrib_set *as;
1313   int id = 1;
1314   LIST_FOR_EACH_ENTRY(as, &m->attr_set_list, head) {
1315      if (!emit_attrib_group(m, id, UINT32_MAX, as->attrs, as->num_attrs))
1316         return false;
1317      id++;
1318   }
1319
1320   return exit_block(m);
1321}
1322
1323static bool
1324emit_attribute_table(struct dxil_module *m)
1325{
1326   if (!enter_subblock(m, DXIL_PARAMATTR, 3))
1327      return false;
1328
1329   struct attrib_set *as;
1330   int id = 1;
1331   LIST_FOR_EACH_ENTRY(as, &m->attr_set_list, head) {
1332      if (!emit_record_int(m, PARAMATTR_CODE_ENTRY, id))
1333         return false;
1334      id++;
1335   }
1336
1337   return exit_block(m);
1338}
1339
1340static bool
1341emit_type_table_abbrevs(struct dxil_module *m)
1342{
1343   for (int i = 0; i < ARRAY_SIZE(type_table_abbrevs); ++i) {
1344      if (!define_abbrev(m, type_table_abbrevs + i))
1345         return false;
1346   }
1347
1348   return true;
1349}
1350
1351static bool
1352emit_float_type(struct dxil_module *m, unsigned bit_size)
1353{
1354   switch (bit_size) {
1355   case 16: return emit_record(m, TYPE_CODE_HALF, NULL, 0);
1356   case 32: return emit_record(m, TYPE_CODE_FLOAT, NULL, 0);
1357   case 64: return emit_record(m, TYPE_CODE_DOUBLE, NULL, 0);
1358   default:
1359      unreachable("unexpected bit_size for float type");
1360   }
1361}
1362
1363static bool
1364emit_pointer_type(struct dxil_module *m, int type_index)
1365{
1366   uint64_t data[] = { TYPE_CODE_POINTER, type_index, 0 };
1367   return emit_type_table_abbrev_record(m, TYPE_TABLE_ABBREV_POINTER,
1368                                        data, ARRAY_SIZE(data));
1369}
1370
1371static bool
1372emit_struct_name(struct dxil_module *m, const char *name)
1373{
1374   uint64_t temp[256];
1375   assert(strlen(name) < ARRAY_SIZE(temp));
1376
1377   for (int i = 0; i < strlen(name); ++i)
1378      temp[i] = name[i];
1379
1380   return emit_record(m, TYPE_CODE_STRUCT_NAME, temp, strlen(name));
1381}
1382
1383static bool
1384emit_struct_name_char6(struct dxil_module *m, const char *name)
1385{
1386   uint64_t temp[256];
1387   assert(strlen(name) < ARRAY_SIZE(temp) - 1);
1388
1389   temp[0] = TYPE_CODE_STRUCT_NAME;
1390   for (int i = 0; i < strlen(name); ++i)
1391      temp[i + 1] = name[i];
1392
1393   return emit_type_table_abbrev_record(m, TYPE_TABLE_ABBREV_STRUCT_NAME,
1394                                        temp, 1 + strlen(name));
1395}
1396
1397static bool
1398emit_struct_type(struct dxil_module *m, const struct dxil_type *type)
1399{
1400   enum type_table_abbrev_id abbrev = TYPE_TABLE_ABBREV_STRUCT_ANON;
1401   enum type_codes type_code = TYPE_CODE_STRUCT_ANON;
1402   if (type->struct_def.name) {
1403      abbrev = TYPE_TABLE_ABBREV_STRUCT_NAMED;
1404      type_code = TYPE_CODE_STRUCT_NAMED;
1405      if (is_char6_string(type->struct_def.name)) {
1406         if (!emit_struct_name_char6(m, type->struct_def.name))
1407            return false;
1408      } else {
1409         if (!emit_struct_name(m, type->struct_def.name))
1410            return false;
1411      }
1412   }
1413
1414   uint64_t temp[256];
1415   assert(type->struct_def.elem.num_types < ARRAY_SIZE(temp) - 2);
1416   temp[0] = type_code;
1417   temp[1] = 0; /* packed */
1418   for (int i = 0; i < type->struct_def.elem.num_types; ++i) {
1419      assert(type->struct_def.elem.types[i]->id >= 0);
1420      temp[2 + i] = type->struct_def.elem.types[i]->id;
1421   }
1422
1423   return emit_type_table_abbrev_record(m, abbrev, temp,
1424                                        2 + type->struct_def.elem.num_types);
1425}
1426
1427static bool
1428emit_array_type(struct dxil_module *m, const struct dxil_type *type)
1429{
1430   assert(type->array_or_vector_def.elem_type->id >= 0);
1431   uint64_t data[] = {
1432      TYPE_CODE_ARRAY,
1433      type->array_or_vector_def.num_elems,
1434      type->array_or_vector_def.elem_type->id
1435   };
1436   return emit_type_table_abbrev_record(m, TYPE_TABLE_ABBREV_ARRAY, data,
1437                                        ARRAY_SIZE(data));
1438}
1439
1440static bool
1441emit_function_type(struct dxil_module *m, const struct dxil_type *type)
1442{
1443   uint64_t temp[256];
1444   assert(type->function_def.args.num_types < ARRAY_SIZE(temp) - 3);
1445   assert(type->function_def.ret_type->id >= 0);
1446
1447   temp[0] = TYPE_CODE_FUNCTION;
1448   temp[1] = 0; // vararg
1449   temp[2] = type->function_def.ret_type->id;
1450   for (int i = 0; i < type->function_def.args.num_types; ++i) {
1451      assert(type->function_def.args.types[i]->id >= 0);
1452      temp[3 + i] = type->function_def.args.types[i]->id;
1453   }
1454
1455   return emit_type_table_abbrev_record(m, TYPE_TABLE_ABBREV_FUNCTION,
1456                                        temp, 3 + type->function_def.args.num_types);
1457}
1458
1459static bool
1460emit_vector_type(struct dxil_module *m, const struct dxil_type *type)
1461{
1462   uint64_t temp[3];
1463   temp[0] = TYPE_CODE_VECTOR;
1464   temp[1] = type->array_or_vector_def.num_elems;
1465   temp[2] = type->array_or_vector_def.elem_type->id;
1466
1467   return emit_type_table_abbrev_record(m, TYPE_TABLE_ABBREV_VECTOR , temp, 3);
1468}
1469
1470static bool
1471emit_metadata_type(struct dxil_module *m)
1472{
1473   return emit_record(m, TYPE_CODE_METADATA, NULL, 0);
1474}
1475
1476static bool
1477emit_type(struct dxil_module *m, struct dxil_type *type)
1478{
1479   switch (type->type) {
1480   case TYPE_VOID:
1481      return emit_record(m, TYPE_CODE_VOID, NULL, 0);
1482
1483   case TYPE_INTEGER:
1484      return emit_record_int(m, TYPE_CODE_INTEGER, type->int_bits);
1485
1486   case TYPE_FLOAT:
1487      return emit_float_type(m, type->float_bits);
1488
1489   case TYPE_POINTER:
1490      return emit_pointer_type(m, type->ptr_target_type->id);
1491
1492   case TYPE_STRUCT:
1493      return emit_struct_type(m, type);
1494
1495   case TYPE_ARRAY:
1496      return emit_array_type(m, type);
1497
1498   case TYPE_FUNCTION:
1499      return emit_function_type(m, type);
1500
1501   case TYPE_VECTOR:
1502      return emit_vector_type(m, type);
1503
1504   default:
1505      unreachable("unexpected type->type");
1506   }
1507}
1508
1509static bool
1510emit_type_table(struct dxil_module *m)
1511{
1512   if (!enter_subblock(m, DXIL_TYPE_BLOCK, 4) ||
1513       !emit_type_table_abbrevs(m) ||
1514       !emit_record_int(m, 1, 1 + list_length(&m->type_list)))
1515      return false;
1516
1517   list_for_each_entry(struct dxil_type, type, &m->type_list, head) {
1518      if (!emit_type(m, type))
1519         return false;
1520   }
1521
1522   return emit_metadata_type(m) &&
1523          exit_block(m);
1524}
1525
1526static struct dxil_const *
1527create_const(struct dxil_module *m, const struct dxil_type *type, bool undef)
1528{
1529   struct dxil_const *ret = ralloc_size(m->ralloc_ctx,
1530                                        sizeof(struct dxil_const));
1531   if (ret) {
1532      ret->value.id = -1;
1533      ret->value.type = type;
1534      ret->undef = undef;
1535      list_addtail(&ret->head, &m->const_list);
1536   }
1537   return ret;
1538}
1539
1540static const struct dxil_value *
1541get_int_const(struct dxil_module *m, const struct dxil_type *type,
1542              intmax_t value)
1543{
1544   assert(type && type->type == TYPE_INTEGER);
1545
1546   struct dxil_const *c;
1547   LIST_FOR_EACH_ENTRY(c, &m->const_list, head) {
1548      if (c->value.type != type || c->undef)
1549         continue;
1550
1551      if (c->int_value == value)
1552         return &c->value;
1553   }
1554
1555   c = create_const(m, type, false);
1556   if (!c)
1557      return NULL;
1558
1559   c->int_value = value;
1560   return &c->value;
1561}
1562
1563const struct dxil_value *
1564dxil_module_get_int1_const(struct dxil_module *m, bool value)
1565{
1566   const struct dxil_type *type = get_int1_type(m);
1567   if (!type)
1568      return NULL;
1569
1570   return get_int_const(m, type, value);
1571}
1572
1573const struct dxil_value *
1574dxil_module_get_int8_const(struct dxil_module *m, int8_t value)
1575{
1576   const struct dxil_type *type = get_int8_type(m);
1577   if (!type)
1578      return NULL;
1579
1580   return get_int_const(m, type, value);
1581}
1582
1583const struct dxil_value *
1584dxil_module_get_int16_const(struct dxil_module *m, int16_t value)
1585{
1586   const struct dxil_type *type = get_int16_type(m);
1587   if (!type)
1588      return NULL;
1589
1590   return get_int_const(m, type, value);
1591}
1592
1593const struct dxil_value *
1594dxil_module_get_int32_const(struct dxil_module *m, int32_t value)
1595{
1596   const struct dxil_type *type = get_int32_type(m);
1597   if (!type)
1598      return NULL;
1599
1600   return get_int_const(m, type, value);
1601}
1602
1603const struct dxil_value *
1604dxil_module_get_int64_const(struct dxil_module *m, int64_t value)
1605{
1606   const struct dxil_type *type = get_int64_type(m);
1607   if (!type)
1608      return NULL;
1609
1610   return get_int_const(m, type, value);
1611}
1612
1613const struct dxil_value *
1614dxil_module_get_int_const(struct dxil_module *m, intmax_t value,
1615                          unsigned bit_size)
1616{
1617   switch (bit_size) {
1618   case 1:
1619      assert(value == 0 || value == 1);
1620      return dxil_module_get_int1_const(m, value);
1621
1622   case 8:
1623      assert(INT8_MIN <= value && value <= INT8_MAX);
1624      return dxil_module_get_int8_const(m, value);
1625
1626   case 16:
1627      assert(INT16_MIN <= value && value <= INT16_MAX);
1628      return dxil_module_get_int16_const(m, value);
1629
1630   case 32:
1631      assert(INT32_MIN <= value && value <= INT32_MAX);
1632      return dxil_module_get_int32_const(m, value);
1633
1634   case 64:
1635      assert(INT64_MIN <= value && value <= INT64_MAX);
1636      return dxil_module_get_int64_const(m, value);
1637
1638   default:
1639      unreachable("unsupported bit-width");
1640   }
1641}
1642
1643const struct dxil_value *
1644dxil_module_get_float16_const(struct dxil_module *m, uint16_t value)
1645{
1646   const struct dxil_type *type = get_float16_type(m);
1647   if (!type)
1648      return NULL;
1649
1650   struct dxil_const *c;
1651   LIST_FOR_EACH_ENTRY(c, &m->const_list, head) {
1652      if (c->value.type != type || c->undef)
1653         continue;
1654
1655      if (c->int_value == (uintmax_t)value)
1656         return &c->value;
1657   }
1658
1659   c = create_const(m, type, false);
1660   if (!c)
1661      return NULL;
1662
1663   c->int_value = (uintmax_t)value;
1664   return &c->value;
1665}
1666
1667const struct dxil_value *
1668dxil_module_get_float_const(struct dxil_module *m, float value)
1669{
1670   const struct dxil_type *type = get_float32_type(m);
1671   if (!type)
1672      return NULL;
1673
1674   struct dxil_const *c;
1675   LIST_FOR_EACH_ENTRY(c, &m->const_list, head) {
1676      if (c->value.type != type || c->undef)
1677         continue;
1678
1679      if (c->float_value == value)
1680         return &c->value;
1681   }
1682
1683   c = create_const(m, type, false);
1684   if (!c)
1685      return NULL;
1686
1687   c->float_value = value;
1688   return &c->value;
1689}
1690
1691const struct dxil_value *
1692dxil_module_get_double_const(struct dxil_module *m, double value)
1693{
1694   const struct dxil_type *type = get_float64_type(m);
1695   if (!type)
1696      return NULL;
1697
1698   struct dxil_const *c;
1699   LIST_FOR_EACH_ENTRY(c, &m->const_list, head) {
1700      if (c->value.type != type || c->undef)
1701         continue;
1702
1703      if (c->float_value == value)
1704         return &c->value;
1705   }
1706
1707   c = create_const(m, type, false);
1708   if (!c)
1709      return NULL;
1710
1711   c->float_value = value;
1712   return &c->value;
1713}
1714
1715const struct dxil_value *
1716dxil_module_get_array_const(struct dxil_module *m, const struct dxil_type *type,
1717                            const struct dxil_value **values)
1718{
1719   assert(type->type == TYPE_ARRAY);
1720   unsigned int num_values = type->array_or_vector_def.num_elems;
1721
1722   struct dxil_const *c;
1723   LIST_FOR_EACH_ENTRY(c, &m->const_list, head) {
1724      if (c->value.type != type || c->undef)
1725         continue;
1726
1727      if (!memcmp(c->array_values, values, sizeof(*values) * num_values))
1728         return &c->value;
1729   }
1730
1731   c = create_const(m, type, false);
1732   if (!c)
1733      return NULL;
1734   void *tmp =
1735      ralloc_array(m->ralloc_ctx, struct dxil_value *, num_values);
1736   memcpy(tmp, values, sizeof(*values) * num_values);
1737   c->array_values = tmp;
1738
1739   return &c->value;
1740}
1741
1742const struct dxil_value *
1743dxil_module_get_undef(struct dxil_module *m, const struct dxil_type *type)
1744{
1745   assert(type != NULL);
1746
1747   struct dxil_const *c;
1748   LIST_FOR_EACH_ENTRY(c, &m->const_list, head) {
1749      if (c->value.type != type)
1750         continue;
1751
1752      if (c->undef)
1753         return &c->value;
1754   }
1755
1756   c = create_const(m, type, true);
1757   return c ? &c->value : NULL;
1758}
1759
1760enum dxil_module_code {
1761   DXIL_MODULE_CODE_VERSION = 1,
1762   DXIL_MODULE_CODE_TRIPLE = 2,
1763   DXIL_MODULE_CODE_DATALAYOUT = 3,
1764   DXIL_MODULE_CODE_ASM = 4,
1765   DXIL_MODULE_CODE_SECTIONNAME = 5,
1766   DXIL_MODULE_CODE_DEPLIB = 6,
1767   DXIL_MODULE_CODE_GLOBALVAR = 7,
1768   DXIL_MODULE_CODE_FUNCTION = 8,
1769   DXIL_MODULE_CODE_ALIAS = 9,
1770   DXIL_MODULE_CODE_PURGEVALS = 10,
1771   DXIL_MODULE_CODE_GCNAME = 11,
1772   DXIL_MODULE_CODE_COMDAT = 12,
1773};
1774
1775static bool
1776emit_target_triple(struct dxil_module *m, const char *triple)
1777{
1778   uint64_t temp[256];
1779   assert(strlen(triple) < ARRAY_SIZE(temp));
1780
1781   for (int i = 0; i < strlen(triple); ++i)
1782      temp[i] = triple[i];
1783
1784   return emit_record(m, DXIL_MODULE_CODE_TRIPLE, temp, strlen(triple));
1785}
1786
1787static bool
1788emit_datalayout(struct dxil_module *m, const char *datalayout)
1789{
1790   uint64_t temp[256];
1791   assert(strlen(datalayout) < ARRAY_SIZE(temp));
1792
1793   for (int i = 0; i < strlen(datalayout); ++i)
1794      temp[i] = datalayout[i];
1795
1796   return emit_record(m, DXIL_MODULE_CODE_DATALAYOUT,
1797                      temp, strlen(datalayout));
1798}
1799
1800static const struct dxil_value *
1801add_gvar(struct dxil_module *m, const char *name,
1802         const struct dxil_type *type, const struct dxil_type *value_type,
1803         enum dxil_address_space as, int align, const struct dxil_value *value)
1804{
1805   struct dxil_gvar *gvar = ralloc_size(m->ralloc_ctx,
1806                                        sizeof(struct dxil_gvar));
1807   if (!gvar)
1808      return NULL;
1809
1810   gvar->type = type;
1811   gvar->name = ralloc_strdup(m->ralloc_ctx, name);
1812   gvar->as = as;
1813   gvar->align = align;
1814   gvar->constant = !!value;
1815   gvar->initializer = value;
1816
1817   gvar->value.id = -1;
1818   gvar->value.type = value_type;
1819
1820   list_addtail(&gvar->head, &m->gvar_list);
1821   return &gvar->value;
1822}
1823
1824const struct dxil_value *
1825dxil_add_global_var(struct dxil_module *m, const char *name,
1826                    const struct dxil_type *type,
1827                    enum dxil_address_space as, int align,
1828                    const struct dxil_value *value)
1829{
1830   return add_gvar(m, name, type, type, as, align, value);
1831}
1832
1833const struct dxil_value *
1834dxil_add_global_ptr_var(struct dxil_module *m, const char *name,
1835                        const struct dxil_type *type,
1836                        enum dxil_address_space as, int align,
1837                        const struct dxil_value *value)
1838{
1839   return add_gvar(m, name, type, dxil_module_get_pointer_type(m, type),
1840                   as, align, value);
1841}
1842
1843static const struct dxil_func *
1844add_function(struct dxil_module *m, const char *name,
1845             const struct dxil_type *type,
1846             bool decl, unsigned attr_set)
1847{
1848   assert(type->type == TYPE_FUNCTION);
1849
1850   struct dxil_func *func = ralloc_size(m->ralloc_ctx,
1851                                        sizeof(struct dxil_func));
1852   if (!func)
1853      return NULL;
1854
1855   /* Truncate function name to make emit_symtab_entry() happy. */
1856   func->name = ralloc_strndup(func, name, 253);
1857   if (!func->name) {
1858      return NULL;
1859   }
1860
1861   func->type = type;
1862   func->decl = decl;
1863   func->attr_set = attr_set;
1864
1865   func->value.id = -1;
1866   func->value.type  = type->function_def.ret_type;
1867   list_addtail(&func->head, &m->func_list);
1868   return func;
1869}
1870
1871struct dxil_func_def *
1872dxil_add_function_def(struct dxil_module *m, const char *name,
1873                      const struct dxil_type *type, unsigned num_blocks)
1874{
1875   struct dxil_func_def *def = ralloc_size(m->ralloc_ctx, sizeof(struct dxil_func_def));
1876
1877   def->func = add_function(m, name, type, false, 0);
1878   if (!def->func)
1879      return NULL;
1880
1881   list_inithead(&def->instr_list);
1882   def->curr_block = 0;
1883
1884   assert(num_blocks > 0);
1885   def->basic_block_ids = rzalloc_array(m->ralloc_ctx, int,
1886                                        num_blocks);
1887   if (!def->basic_block_ids)
1888      return NULL;
1889
1890   for (int i = 0; i < num_blocks; ++i)
1891      def->basic_block_ids[i] = -1;
1892   def->num_basic_block_ids = num_blocks;
1893
1894   list_addtail(&def->head, &m->func_def_list);
1895   m->cur_emitting_func = def;
1896
1897   return def;
1898}
1899
1900static unsigned
1901get_attr_set(struct dxil_module *m, enum dxil_attr_kind attr)
1902{
1903   struct dxil_attrib attrs[2] = {
1904      { DXIL_ATTR_ENUM, { DXIL_ATTR_KIND_NO_UNWIND } },
1905      { DXIL_ATTR_ENUM, { attr } }
1906   };
1907
1908   int index = 1;
1909   struct attrib_set *as;
1910   LIST_FOR_EACH_ENTRY(as, &m->attr_set_list, head) {
1911      if (!memcmp(as->attrs, attrs, sizeof(attrs)))
1912         return index;
1913      index++;
1914   }
1915
1916   as = ralloc_size(m->ralloc_ctx, sizeof(struct attrib_set));
1917   if (!as)
1918      return 0;
1919
1920   memcpy(as->attrs, attrs, sizeof(attrs));
1921   as->num_attrs = 1;
1922   if (attr != DXIL_ATTR_KIND_NONE)
1923      as->num_attrs++;
1924
1925   list_addtail(&as->head, &m->attr_set_list);
1926   assert(list_length(&m->attr_set_list) == index);
1927   return index;
1928}
1929
1930const struct dxil_func *
1931dxil_add_function_decl(struct dxil_module *m, const char *name,
1932                       const struct dxil_type *type,
1933                       enum dxil_attr_kind attr)
1934{
1935   unsigned attr_set = get_attr_set(m, attr);
1936   if (!attr_set)
1937      return NULL;
1938
1939   return add_function(m, name, type, true, attr_set);
1940}
1941
1942static bool
1943emit_module_info_function(struct dxil_module *m, int type, bool declaration,
1944                          int attr_set_index)
1945{
1946   uint64_t data[] = {
1947      type, 0/* address space */, declaration, 0/* linkage */,
1948      attr_set_index, 0/* alignment */, 0 /* section */, 0 /* visibility */,
1949      0 /* GC */, 0 /* unnamed addr */, 0 /* prologue data */,
1950      0 /* storage class */, 0 /* comdat */, 0 /* prefix-data */,
1951      0 /* personality */
1952   };
1953   return emit_record(m, DXIL_MODULE_CODE_FUNCTION, data, ARRAY_SIZE(data));
1954}
1955
1956enum gvar_var_flags {
1957   GVAR_FLAG_CONSTANT = (1 << 0),
1958   GVAR_FLAG_EXPLICIT_TYPE = (1 << 1),
1959};
1960
1961enum gvar_var_linkage {
1962   GVAR_LINKAGE_EXTERNAL = 0,
1963   GVAR_LINKAGE_APPENDING = 2,
1964   GVAR_LINKAGE_INTERNAL = 3,
1965   GVAR_LINKAGE_EXTERNAL_WEAK = 7,
1966   GVAR_LINKAGE_COMMON = 8,
1967   GVAR_LINKAGE_PRIVATE = 9,
1968   GVAR_LINKAGE_AVAILABLE_EXTERNALLY = 12,
1969   GVAR_LINKAGE_WEAK_ANY = 16,
1970   GVAR_LINKAGE_WEAK_ODR = 17,
1971   GVAR_LINKAGE_LINK_ONCE_ODR = 19,
1972};
1973
1974static bool
1975emit_module_info_global(struct dxil_module *m, const struct dxil_gvar *gvar,
1976                        const struct dxil_abbrev *simple_gvar_abbr)
1977{
1978   uint64_t data[] = {
1979      DXIL_MODULE_CODE_GLOBALVAR,
1980      gvar->type->id,
1981      (gvar->as << 2) | GVAR_FLAG_EXPLICIT_TYPE |
1982      (gvar->constant ? GVAR_FLAG_CONSTANT : 0),
1983      gvar->initializer ? gvar->initializer->id + 1 : 0,
1984      (gvar->initializer ? GVAR_LINKAGE_INTERNAL : GVAR_LINKAGE_EXTERNAL),
1985      util_logbase2(gvar->align) + 1,
1986      0
1987   };
1988   return emit_record_abbrev(&m->buf, 4, simple_gvar_abbr,
1989                             data, ARRAY_SIZE(data));
1990}
1991
1992static bool
1993emit_module_info(struct dxil_module *m)
1994{
1995   struct dxil_gvar *gvar;
1996   int max_global_type = 0;
1997   int max_alignment = 0;
1998   LIST_FOR_EACH_ENTRY(gvar, &m->gvar_list, head) {
1999      assert(gvar->type->id >= 0);
2000      max_global_type = MAX2(max_global_type, gvar->type->id);
2001      max_alignment = MAX2(max_alignment, gvar->align);
2002   }
2003
2004   struct dxil_abbrev simple_gvar_abbr = {
2005      { LITERAL(DXIL_MODULE_CODE_GLOBALVAR),
2006        FIXED(util_logbase2(max_global_type) + 1),
2007        VBR(6), VBR(6), FIXED(5),
2008        FIXED(util_logbase2(max_alignment) + 1),
2009        LITERAL(0) }, 7
2010   };
2011
2012   if (!emit_target_triple(m, "dxil-ms-dx") ||
2013       !emit_datalayout(m, "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64") ||
2014       !define_abbrev(m, &simple_gvar_abbr))
2015      return false;
2016
2017   LIST_FOR_EACH_ENTRY(gvar, &m->gvar_list, head) {
2018      assert(gvar->type->id >= 0);
2019      if (!emit_module_info_global(m, gvar, &simple_gvar_abbr))
2020         return false;
2021   }
2022
2023   struct dxil_func *func;
2024   LIST_FOR_EACH_ENTRY(func, &m->func_list, head) {
2025      assert(func->type->id >= 0);
2026      if (!emit_module_info_function(m, func->type->id, func->decl,
2027                                     func->attr_set))
2028         return false;
2029   }
2030
2031   return true;
2032}
2033
2034static bool
2035emit_module_const_abbrevs(struct dxil_module *m)
2036{
2037   /* these are unused for now, so let's not even record them */
2038   struct dxil_abbrev abbrevs[] = {
2039      { { LITERAL(CST_CODE_AGGREGATE), ARRAY, FIXED(5) }, 3 },
2040      { { LITERAL(CST_CODE_STRING), ARRAY, FIXED(8) }, 3 },
2041      { { LITERAL(CST_CODE_CSTRING), ARRAY, FIXED(7) }, 3 },
2042      { { LITERAL(CST_CODE_CSTRING), ARRAY, CHAR6 }, 3 },
2043   };
2044
2045   for (int i = 0; i < ARRAY_SIZE(abbrevs); ++i) {
2046      if (!define_abbrev(m, abbrevs + i))
2047         return false;
2048   }
2049
2050   return true;
2051}
2052
2053static bool
2054emit_set_type(struct dxil_module *m, unsigned type_index)
2055{
2056   uint64_t data[] = { CST_CODE_SETTYPE, type_index };
2057   return emit_const_abbrev_record(m, CONST_ABBREV_SETTYPE,
2058                                   data, ARRAY_SIZE(data));
2059}
2060
2061static bool
2062emit_null_value(struct dxil_module *m)
2063{
2064   return emit_record_no_abbrev(&m->buf, CST_CODE_NULL, NULL, 0);
2065}
2066
2067static bool
2068emit_undef_value(struct dxil_module *m)
2069{
2070   return emit_record_no_abbrev(&m->buf, CST_CODE_UNDEF, NULL, 0);
2071}
2072
2073static uint64_t
2074encode_signed(int64_t value)
2075{
2076   return value >= 0 ?
2077      (value << 1) :
2078      ((-value << 1) | 1);
2079}
2080
2081static bool
2082emit_int_value(struct dxil_module *m, int64_t value)
2083{
2084   if (!value)
2085      return emit_null_value(m);
2086
2087   uint64_t data[] = { CST_CODE_INTEGER, encode_signed(value) };
2088   return emit_const_abbrev_record(m, CONST_ABBREV_INTEGER,
2089                                   data, ARRAY_SIZE(data));
2090}
2091
2092static bool
2093emit_float16_value(struct dxil_module *m, uint16_t value)
2094{
2095   if (!value)
2096      return emit_null_value(m);
2097   uint64_t data = value;
2098   return emit_record_no_abbrev(&m->buf, CST_CODE_FLOAT, &data, 1);
2099}
2100
2101static bool
2102emit_float_value(struct dxil_module *m, float value)
2103{
2104   uint64_t data = fui(value);
2105   if (data == UINT32_C(0))
2106      return emit_null_value(m);
2107   return emit_record_no_abbrev(&m->buf, CST_CODE_FLOAT, &data, 1);
2108}
2109
2110static bool
2111emit_double_value(struct dxil_module *m, double value)
2112{
2113   union di u;
2114   u.d = value;
2115   if (u.ui == UINT64_C(0))
2116      return emit_null_value(m);
2117   return emit_record_no_abbrev(&m->buf, CST_CODE_FLOAT, &u.ui, 1);
2118}
2119
2120static bool
2121emit_aggregate_values(struct dxil_module *m, const struct dxil_value **values,
2122                      int num_values)
2123{
2124   uint64_t *value_ids = ralloc_array(m->ralloc_ctx, uint64_t, num_values);
2125   int i;
2126
2127   for (i = 0; i < num_values; i++)
2128      value_ids[i] = values[i]->id;
2129
2130   return emit_record_no_abbrev(&m->buf, CST_CODE_AGGREGATE, value_ids,
2131                                num_values);
2132}
2133
2134static bool
2135emit_consts(struct dxil_module *m)
2136{
2137   const struct dxil_type *curr_type = NULL;
2138   struct dxil_const *c;
2139   LIST_FOR_EACH_ENTRY(c, &m->const_list, head) {
2140      assert(c->value.id >= 0);
2141      assert(c->value.type != NULL);
2142      if (curr_type != c->value.type) {
2143         assert(c->value.type->id >= 0);
2144         if (!emit_set_type(m, c->value.type->id))
2145            return false;
2146         curr_type = c->value.type;
2147      }
2148
2149      if (c->undef) {
2150         if (!emit_undef_value(m))
2151            return false;
2152         continue;
2153      }
2154
2155      switch (curr_type->type) {
2156      case TYPE_INTEGER:
2157         if (!emit_int_value(m, c->int_value))
2158            return false;
2159         break;
2160
2161      case TYPE_FLOAT:
2162         switch (curr_type->float_bits) {
2163         case 16:
2164            if (!emit_float16_value(m, (uint16_t)(uintmax_t)c->int_value))
2165               return false;
2166            break;
2167         case 32:
2168            if (!emit_float_value(m, c->float_value))
2169               return false;
2170            break;
2171         case 64:
2172            if (!emit_double_value(m, c->float_value))
2173               return false;
2174            break;
2175         default:
2176            unreachable("unexpected float_bits");
2177         }
2178         break;
2179
2180      case TYPE_ARRAY:
2181         if (!emit_aggregate_values(m, c->array_values,
2182                                    c->value.type->array_or_vector_def.num_elems))
2183            return false;
2184         break;
2185
2186      default:
2187         unreachable("unsupported constant type");
2188      }
2189   }
2190
2191   return true;
2192}
2193
2194static bool
2195emit_module_consts(struct dxil_module *m)
2196{
2197   return enter_subblock(m, DXIL_CONST_BLOCK, 4) &&
2198          emit_module_const_abbrevs(m) &&
2199          emit_consts(m) &&
2200          exit_block(m);
2201}
2202
2203static bool
2204emit_value_symtab_abbrev_record(struct dxil_module *m,
2205                                enum value_symtab_abbrev_id abbrev,
2206                                const uint64_t *data, size_t size)
2207{
2208   assert(abbrev < ARRAY_SIZE(value_symtab_abbrevs));
2209   return emit_record_abbrev(&m->buf, abbrev + DXIL_FIRST_APPLICATION_ABBREV,
2210                             value_symtab_abbrevs + abbrev, data, size);
2211}
2212
2213static bool
2214emit_symtab_entry(struct dxil_module *m, unsigned value, const char *name)
2215{
2216   uint64_t temp[256];
2217   assert(strlen(name) < ARRAY_SIZE(temp) - 2);
2218
2219   temp[0] = VST_CODE_ENTRY;
2220   temp[1] = value;
2221   for (int i = 0; i < strlen(name); ++i)
2222      temp[i + 2] = (uint8_t)(name[i]);
2223
2224   enum value_symtab_abbrev_id abbrev = VST_ABBREV_ENTRY_8;
2225   if (is_char6_string(name))
2226      abbrev = VST_ABBREV_ENTRY_6;
2227   else if (is_char7_string(name))
2228      abbrev = VST_ABBREV_ENTRY_7;
2229
2230   return emit_value_symtab_abbrev_record(m, abbrev, temp, 2 + strlen(name));
2231}
2232
2233static bool
2234emit_value_symbol_table(struct dxil_module *m)
2235{
2236   if (!enter_subblock(m, DXIL_VALUE_SYMTAB_BLOCK, 4))
2237      return false;
2238
2239   struct dxil_func *func;
2240   LIST_FOR_EACH_ENTRY(func, &m->func_list, head) {
2241      if (!emit_symtab_entry(m, func->value.id, func->name))
2242         return false;
2243   }
2244   struct dxil_gvar *gvar;
2245   LIST_FOR_EACH_ENTRY(gvar, &m->gvar_list, head) {
2246      if (!emit_symtab_entry(m, gvar->value.id, gvar->name))
2247         return false;
2248   }
2249   return exit_block(m);
2250}
2251
2252enum metadata_codes {
2253  METADATA_STRING = 1,
2254  METADATA_VALUE = 2,
2255  METADATA_NODE = 3,
2256  METADATA_NAME = 4,
2257  METADATA_KIND = 6,
2258  METADATA_NAMED_NODE = 10
2259};
2260
2261enum metadata_abbrev_id {
2262   METADATA_ABBREV_STRING,
2263   METADATA_ABBREV_NAME
2264};
2265
2266static const struct dxil_abbrev metadata_abbrevs[] = {
2267   [METADATA_ABBREV_STRING] = {
2268      { LITERAL(METADATA_STRING), ARRAY, FIXED(8) }, 3
2269   },
2270   [METADATA_ABBREV_NAME] = {
2271      { LITERAL(METADATA_NAME), ARRAY, FIXED(8) }, 3
2272   },
2273};
2274
2275static bool
2276emit_metadata_abbrevs(struct dxil_module *m)
2277{
2278   for (int i = 0; i < ARRAY_SIZE(metadata_abbrevs); ++i) {
2279      if (!define_abbrev(m, metadata_abbrevs + i))
2280         return false;
2281   }
2282   return true;
2283}
2284
2285static struct dxil_mdnode *
2286create_mdnode(struct dxil_module *m, enum mdnode_type type)
2287{
2288   struct dxil_mdnode *ret = rzalloc_size(m->ralloc_ctx,
2289                                          sizeof(struct dxil_mdnode));
2290   if (ret) {
2291      ret->type = type;
2292      ret->id = list_length(&m->mdnode_list) + 1; /* zero is reserved for NULL nodes */
2293      list_addtail(&ret->head, &m->mdnode_list);
2294   }
2295   return ret;
2296}
2297
2298const struct dxil_mdnode *
2299dxil_get_metadata_string(struct dxil_module *m, const char *str)
2300{
2301   assert(str);
2302
2303   struct dxil_mdnode *n;
2304   LIST_FOR_EACH_ENTRY(n, &m->mdnode_list, head) {
2305      if (n->type == MD_STRING &&
2306          !strcmp(n->string, str))
2307         return n;
2308   }
2309
2310   n = create_mdnode(m, MD_STRING);
2311   if (n) {
2312      n->string = ralloc_strdup(n, str);
2313      if (!n->string)
2314         return NULL;
2315   }
2316   return n;
2317}
2318
2319const struct dxil_mdnode *
2320dxil_get_metadata_value(struct dxil_module *m, const struct dxil_type *type,
2321                        const struct dxil_value *value)
2322{
2323   struct dxil_mdnode *n;
2324   LIST_FOR_EACH_ENTRY(n, &m->mdnode_list, head) {
2325      if (n->type == MD_VALUE &&
2326          n->value.type == type &&
2327          n->value.value == value)
2328         return n;
2329   }
2330
2331   n = create_mdnode(m, MD_VALUE);
2332   if (n) {
2333      n->value.type = type;
2334      n->value.value = value;
2335   }
2336   return n;
2337}
2338
2339const struct dxil_mdnode *
2340dxil_get_metadata_func(struct dxil_module *m, const struct dxil_func *func)
2341{
2342   const struct dxil_type *ptr_type =
2343      dxil_module_get_pointer_type(m, func->type);
2344   return dxil_get_metadata_value(m, ptr_type, &func->value);
2345}
2346
2347const struct dxil_mdnode *
2348dxil_get_metadata_node(struct dxil_module *m,
2349                       const struct dxil_mdnode *subnodes[],
2350                       size_t num_subnodes)
2351{
2352   struct dxil_mdnode *n;
2353   LIST_FOR_EACH_ENTRY(n, &m->mdnode_list, head) {
2354      if (n->type == MD_NODE &&
2355          n->node.num_subnodes == num_subnodes &&
2356          !memcmp(n->node.subnodes, subnodes, sizeof(struct dxil_mdnode *) *
2357                  num_subnodes))
2358         return n;
2359   }
2360
2361   n = create_mdnode(m, MD_NODE);
2362   if (n) {
2363      void *tmp = ralloc_array(n, struct dxil_mdnode *, num_subnodes);
2364      if (!tmp)
2365         return NULL;
2366
2367      memcpy(tmp, subnodes, sizeof(struct dxil_mdnode *) * num_subnodes);
2368      n->node.subnodes = tmp;
2369      n->node.num_subnodes = num_subnodes;
2370   }
2371   return n;
2372}
2373
2374const struct dxil_mdnode *
2375dxil_get_metadata_int1(struct dxil_module *m, bool value)
2376{
2377   const struct dxil_type *type = get_int1_type(m);
2378   if (!type)
2379      return NULL;
2380
2381   const struct dxil_value *const_value = get_int_const(m, type, value);
2382   if (!const_value)
2383      return NULL;
2384
2385   return dxil_get_metadata_value(m, type, const_value);
2386}
2387
2388const struct dxil_mdnode *
2389dxil_get_metadata_int8(struct dxil_module *m, int8_t value)
2390{
2391   const struct dxil_type *type = get_int8_type(m);
2392   if (!type)
2393      return NULL;
2394
2395   const struct dxil_value *const_value = get_int_const(m, type, value);
2396   if (!const_value)
2397      return NULL;
2398
2399   return dxil_get_metadata_value(m, type, const_value);
2400}
2401
2402const struct dxil_mdnode *
2403dxil_get_metadata_int32(struct dxil_module *m, int32_t value)
2404{
2405   const struct dxil_type *type = get_int32_type(m);
2406   if (!type)
2407      return NULL;
2408
2409   const struct dxil_value *const_value = get_int_const(m, type, value);
2410   if (!const_value)
2411      return NULL;
2412
2413   return dxil_get_metadata_value(m, type, const_value);
2414}
2415
2416const struct dxil_mdnode *
2417dxil_get_metadata_int64(struct dxil_module *m, int64_t value)
2418{
2419   const struct dxil_type *type = get_int64_type(m);
2420   if (!type)
2421      return NULL;
2422
2423   const struct dxil_value *const_value = get_int_const(m, type, value);
2424   if (!const_value)
2425      return NULL;
2426
2427   return dxil_get_metadata_value(m, type, const_value);
2428}
2429
2430const struct dxil_mdnode *
2431dxil_get_metadata_float32(struct dxil_module *m, float value)
2432{
2433   const struct dxil_type *type = get_float32_type(m);
2434   if (!type)
2435      return NULL;
2436
2437   const struct dxil_value *const_value = dxil_module_get_float_const(m, value);
2438   if (!const_value)
2439      return NULL;
2440
2441   return dxil_get_metadata_value(m, type, const_value);
2442}
2443
2444bool
2445dxil_add_metadata_named_node(struct dxil_module *m, const char *name,
2446                             const struct dxil_mdnode *subnodes[],
2447                             size_t num_subnodes)
2448{
2449   struct dxil_named_node *n = ralloc_size(m->ralloc_ctx,
2450                                           sizeof(struct dxil_named_node));
2451   if (!n)
2452      return false;
2453
2454   n->name = ralloc_strdup(n, name);
2455   if (!n->name)
2456      return false;
2457
2458   void *tmp = ralloc_array(n, struct dxil_mdnode *, num_subnodes);
2459   if (!tmp)
2460      return false;
2461
2462   memcpy(tmp, subnodes, sizeof(struct dxil_mdnode *) * num_subnodes);
2463   n->subnodes = tmp;
2464   n->num_subnodes = num_subnodes;
2465
2466   list_addtail(&n->head, &m->md_named_node_list);
2467   return true;
2468}
2469
2470static bool
2471emit_metadata_value(struct dxil_module *m, const struct dxil_type *type,
2472                    const struct dxil_value *value)
2473{
2474   assert(type->id >= 0 && value->id >= 0);
2475   uint64_t data[2] = { type->id, value->id };
2476   return emit_record(m, METADATA_VALUE, data, ARRAY_SIZE(data));
2477}
2478
2479static bool
2480emit_metadata_abbrev_record(struct dxil_module *m,
2481                            enum metadata_abbrev_id abbrev,
2482                            const uint64_t *data, size_t size)
2483{
2484   assert(abbrev < ARRAY_SIZE(metadata_abbrevs));
2485   return emit_record_abbrev(&m->buf, abbrev + DXIL_FIRST_APPLICATION_ABBREV,
2486                             metadata_abbrevs + abbrev, data, size);
2487}
2488
2489static bool
2490emit_metadata_string(struct dxil_module *m, const char *str)
2491{
2492   uint64_t data[256];
2493   assert(strlen(str) < ARRAY_SIZE(data) - 1);
2494   data[0] = METADATA_STRING;
2495   for (size_t i = 0; i < strlen(str); ++i)
2496      data[i + 1] = (uint8_t)(str[i]);
2497
2498   return emit_metadata_abbrev_record(m, METADATA_ABBREV_STRING,
2499                                      data, strlen(str) + 1);
2500}
2501
2502static bool
2503emit_metadata_node(struct dxil_module *m,
2504                   const struct dxil_mdnode *subnodes[],
2505                   size_t num_subnodes)
2506{
2507   uint64_t data[256];
2508   assert(num_subnodes < ARRAY_SIZE(data));
2509   for (size_t i = 0; i < num_subnodes; ++i)
2510      data[i] = subnodes[i] ? subnodes[i]->id : 0;
2511
2512   return emit_record(m, METADATA_NODE, data, num_subnodes);
2513}
2514
2515static bool
2516emit_mdnode(struct dxil_module *m, struct dxil_mdnode *n)
2517{
2518   switch (n->type) {
2519   case MD_STRING:
2520      return emit_metadata_string(m, n->string);
2521
2522   case MD_VALUE:
2523      return emit_metadata_value(m, n->value.type, n->value.value);
2524
2525   case MD_NODE:
2526      return emit_metadata_node(m, n->node.subnodes, n->node.num_subnodes);
2527
2528   default:
2529      unreachable("unexpected n->type");
2530   }
2531}
2532
2533static bool
2534emit_metadata_nodes(struct dxil_module *m)
2535{
2536   list_for_each_entry(struct dxil_mdnode, n,  &m->mdnode_list, head) {
2537      if (!emit_mdnode(m, n))
2538         return false;
2539   }
2540   return true;
2541}
2542
2543static bool
2544emit_metadata_name(struct dxil_module *m, const char *name)
2545{
2546   uint64_t data[256];
2547   assert(strlen(name) < ARRAY_SIZE(data) - 1);
2548   data[0] = METADATA_NAME;
2549   for (size_t i = 0; i < strlen(name); ++i)
2550      data[i + 1] = name[i];
2551
2552   return emit_metadata_abbrev_record(m, METADATA_ABBREV_NAME,
2553                                      data, strlen(name) + 1);
2554}
2555
2556static bool
2557emit_metadata_named_node(struct dxil_module *m, const char *name,
2558                         const struct dxil_mdnode *subnodes[],
2559                         size_t num_subnodes)
2560{
2561   uint64_t data[256];
2562   assert(num_subnodes < ARRAY_SIZE(data));
2563   for (size_t i = 0; i < num_subnodes; ++i) {
2564      assert(subnodes[i]->id > 0); /* NULL nodes not allowed */
2565      data[i] = subnodes[i]->id - 1;
2566   }
2567
2568   return emit_metadata_name(m, name) &&
2569          emit_record(m, METADATA_NAMED_NODE, data, num_subnodes);
2570}
2571
2572static bool
2573emit_metadata_named_nodes(struct dxil_module *m)
2574{
2575   struct dxil_named_node *n;
2576   LIST_FOR_EACH_ENTRY(n, &m->md_named_node_list, head) {
2577      if (!emit_metadata_named_node(m, n->name, n->subnodes,
2578                                    n->num_subnodes))
2579         return false;
2580   }
2581   return true;
2582}
2583
2584static bool
2585emit_metadata(struct dxil_module *m)
2586{
2587   return enter_subblock(m, DXIL_METADATA_BLOCK, 3) &&
2588          emit_metadata_abbrevs(m) &&
2589          emit_metadata_nodes(m) &&
2590          emit_metadata_named_nodes(m) &&
2591          exit_block(m);
2592}
2593
2594static struct dxil_instr *
2595create_instr(struct dxil_module *m, enum instr_type type,
2596             const struct dxil_type *ret_type)
2597{
2598   struct dxil_instr *ret = ralloc_size(m->ralloc_ctx,
2599                                        sizeof(struct dxil_instr));
2600   if (ret) {
2601      ret->type = type;
2602      ret->value.id = -1;
2603      ret->value.type = ret_type;
2604      ret->has_value = false;
2605      list_addtail(&ret->head, &m->cur_emitting_func->instr_list);
2606   }
2607   return ret;
2608}
2609
2610static inline bool
2611legal_arith_type(const struct dxil_type *type)
2612{
2613   switch (type->type) {
2614   case TYPE_INTEGER:
2615      return type->int_bits == 1 ||
2616             type->int_bits == 16 ||
2617             type->int_bits == 32 ||
2618             type->int_bits == 64;
2619
2620   case TYPE_FLOAT:
2621      return type->float_bits == 16 ||
2622             type->float_bits == 32 ||
2623             type->float_bits == 64;
2624
2625   default:
2626      return false;
2627   }
2628}
2629
2630const struct dxil_value *
2631dxil_emit_binop(struct dxil_module *m, enum dxil_bin_opcode opcode,
2632                const struct dxil_value *op0, const struct dxil_value *op1,
2633                enum dxil_opt_flags flags)
2634{
2635   assert(types_equal(op0->type, op1->type));
2636   assert(legal_arith_type(op0->type));
2637   struct dxil_instr *instr = create_instr(m, INSTR_BINOP, op0->type);
2638   if (!instr)
2639      return NULL;
2640
2641   instr->binop.opcode = opcode;
2642   instr->binop.operands[0] = op0;
2643   instr->binop.operands[1] = op1;
2644   instr->binop.flags = flags;
2645   instr->has_value = true;
2646   return &instr->value;
2647}
2648
2649const struct dxil_value *
2650dxil_emit_cmp(struct dxil_module *m, enum dxil_cmp_pred pred,
2651                const struct dxil_value *op0, const struct dxil_value *op1)
2652{
2653   assert(types_equal(op0->type, op1->type));
2654   assert(legal_arith_type(op0->type));
2655   struct dxil_instr *instr = create_instr(m, INSTR_CMP, get_int1_type(m));
2656   if (!instr)
2657      return NULL;
2658
2659   instr->cmp.pred = pred;
2660   instr->cmp.operands[0] = op0;
2661   instr->cmp.operands[1] = op1;
2662   instr->has_value = true;
2663   return &instr->value;
2664}
2665
2666const struct dxil_value *
2667dxil_emit_select(struct dxil_module *m,
2668                const struct dxil_value *op0,
2669                const struct dxil_value *op1,
2670                const struct dxil_value *op2)
2671{
2672   assert(types_equal(op0->type, get_int1_type(m)));
2673   assert(types_equal(op1->type, op2->type));
2674   assert(legal_arith_type(op1->type));
2675
2676   struct dxil_instr *instr = create_instr(m, INSTR_SELECT, op1->type);
2677   if (!instr)
2678      return NULL;
2679
2680   instr->select.operands[0] = op0;
2681   instr->select.operands[1] = op1;
2682   instr->select.operands[2] = op2;
2683   instr->has_value = true;
2684   return &instr->value;
2685}
2686
2687const struct dxil_value *
2688dxil_emit_cast(struct dxil_module *m, enum dxil_cast_opcode opcode,
2689               const struct dxil_type *type,
2690               const struct dxil_value *value)
2691{
2692   assert(legal_arith_type(value->type));
2693   assert(legal_arith_type(type));
2694
2695   struct dxil_instr *instr = create_instr(m, INSTR_CAST, type);
2696   if (!instr)
2697      return NULL;
2698
2699   instr->cast.opcode = opcode;
2700   instr->cast.type = type;
2701   instr->cast.value = value;
2702   instr->has_value = true;
2703   return &instr->value;
2704}
2705
2706bool
2707dxil_emit_branch(struct dxil_module *m, const struct dxil_value *cond,
2708                 unsigned true_block, unsigned false_block)
2709{
2710   assert(!cond || types_equal(cond->type, get_int1_type(m)));
2711
2712   struct dxil_instr *instr = create_instr(m, INSTR_BR,
2713                                           dxil_module_get_void_type(m));
2714   if (!instr)
2715      return false;
2716
2717   instr->br.cond = cond;
2718   instr->br.succ[0] = true_block;
2719   instr->br.succ[1] = false_block;
2720   m->cur_emitting_func->curr_block++;
2721   return true;
2722}
2723
2724const struct dxil_value *
2725dxil_instr_get_return_value(struct dxil_instr *instr)
2726{
2727   return instr->has_value ? &instr->value : NULL;
2728}
2729
2730struct dxil_instr *
2731dxil_emit_phi(struct dxil_module *m, const struct dxil_type *type)
2732{
2733   assert(legal_arith_type(type));
2734
2735   struct dxil_instr *instr = create_instr(m, INSTR_PHI, type);
2736   if (!instr)
2737      return NULL;
2738
2739   instr->phi.type = type;
2740   instr->phi.incoming = NULL;
2741   instr->phi.num_incoming = 0;
2742   instr->has_value = true;
2743
2744   return instr;
2745}
2746
2747bool
2748dxil_phi_add_incoming(struct dxil_instr *instr,
2749                      const struct dxil_value *incoming_values[],
2750                      const unsigned incoming_blocks[],
2751                      size_t num_incoming)
2752{
2753   assert(instr->type == INSTR_PHI);
2754   assert(num_incoming > 0);
2755
2756   instr->phi.incoming = reralloc(instr, instr->phi.incoming,
2757                                  struct dxil_phi_src,
2758                                  instr->phi.num_incoming + num_incoming);
2759   if (!instr->phi.incoming)
2760      return false;
2761
2762   for (int i = 0; i < num_incoming; ++i) {
2763      assert(incoming_values[i]);
2764      assert(types_equal(incoming_values[i]->type, instr->phi.type));
2765      int dst = instr->phi.num_incoming + i;
2766      instr->phi.incoming[dst].value = incoming_values[i];
2767      instr->phi.incoming[dst].block = incoming_blocks[i];
2768   }
2769   instr->phi.num_incoming += num_incoming;
2770   return true;
2771}
2772
2773static struct dxil_instr *
2774create_call_instr(struct dxil_module *m,
2775                  const struct dxil_func *func,
2776                  const struct dxil_value **args, size_t num_args)
2777{
2778   assert(num_args == func->type->function_def.args.num_types);
2779   for (size_t i = 0; i < num_args; ++ i)
2780      assert(types_equal(func->type->function_def.args.types[i], args[i]->type));
2781
2782   struct dxil_instr *instr = create_instr(m, INSTR_CALL,
2783                                           func->type->function_def.ret_type);
2784   if (instr) {
2785      instr->call.func = func;
2786      instr->call.args = ralloc_array(instr, struct dxil_value *, num_args);
2787      if (!args)
2788         return false;
2789      memcpy(instr->call.args, args, sizeof(struct dxil_value *) * num_args);
2790      instr->call.num_args = num_args;
2791   }
2792   return instr;
2793}
2794
2795const struct dxil_value *
2796dxil_emit_call(struct dxil_module *m,
2797               const struct dxil_func *func,
2798               const struct dxil_value **args, size_t num_args)
2799{
2800   assert(func->type->function_def.ret_type->type != TYPE_VOID);
2801
2802   struct dxil_instr *instr = create_call_instr(m, func, args, num_args);
2803   if (!instr)
2804      return NULL;
2805
2806   instr->has_value = true;
2807   return &instr->value;
2808}
2809
2810bool
2811dxil_emit_call_void(struct dxil_module *m,
2812                    const struct dxil_func *func,
2813                    const struct dxil_value **args, size_t num_args)
2814{
2815   assert(func->type->function_def.ret_type->type == TYPE_VOID);
2816
2817   struct dxil_instr *instr = create_call_instr(m, func, args, num_args);
2818   if (!instr)
2819      return false;
2820
2821   return true;
2822}
2823
2824bool
2825dxil_emit_ret_void(struct dxil_module *m)
2826{
2827   struct dxil_instr *instr = create_instr(m, INSTR_RET,
2828                                           dxil_module_get_void_type(m));
2829   if (!instr)
2830      return false;
2831
2832   instr->ret.value = NULL;
2833   m->cur_emitting_func->curr_block++;
2834   return true;
2835}
2836
2837const struct dxil_value *
2838dxil_emit_extractval(struct dxil_module *m, const struct dxil_value *src,
2839                     const unsigned int index)
2840{
2841   assert(src->type->type == TYPE_STRUCT);
2842   assert(index < src->type->struct_def.elem.num_types);
2843
2844   struct dxil_instr *instr =
2845      create_instr(m, INSTR_EXTRACTVAL,
2846                   src->type->struct_def.elem.types[index]);
2847   if (!instr)
2848      return NULL;
2849
2850   instr->extractval.src = src;
2851   instr->extractval.type = src->type;
2852   instr->extractval.idx = index;
2853   instr->has_value = true;
2854
2855   return &instr->value;
2856}
2857
2858const struct dxil_value *
2859dxil_emit_alloca(struct dxil_module *m, const struct dxil_type *alloc_type,
2860                 const struct dxil_type *size_type,
2861                 const struct dxil_value *size,
2862                 unsigned int align)
2863{
2864   assert(size_type && size_type->type == TYPE_INTEGER);
2865
2866   const struct dxil_type *return_type =
2867      dxil_module_get_pointer_type(m, alloc_type);
2868   if (!return_type)
2869      return NULL;
2870
2871   struct dxil_instr *instr = create_instr(m, INSTR_ALLOCA, return_type);
2872   if (!instr)
2873      return NULL;
2874
2875   instr->alloca.alloc_type = alloc_type;
2876   instr->alloca.size_type = size_type;
2877   instr->alloca.size = size;
2878   instr->alloca.align = util_logbase2(align) + 1;
2879   assert(instr->alloca.align < (1 << 5));
2880   instr->alloca.align |= 1 << 6;
2881
2882   instr->has_value = true;
2883   return &instr->value;
2884}
2885
2886static const struct dxil_type *
2887get_deref_type(const struct dxil_type *type)
2888{
2889   switch (type->type) {
2890   case TYPE_POINTER: return type->ptr_target_type;
2891   case TYPE_ARRAY: return type->array_or_vector_def.elem_type;
2892   default: unreachable("unexpected type");
2893   }
2894}
2895
2896const struct dxil_value *
2897dxil_emit_gep_inbounds(struct dxil_module *m,
2898                       const struct dxil_value **operands,
2899                       size_t num_operands)
2900{
2901   assert(num_operands > 0);
2902   const struct dxil_type *source_elem_type =
2903      get_deref_type(operands[0]->type);
2904
2905   const struct dxil_type *type = operands[0]->type;
2906   for (int i = 1; i < num_operands; ++i) {
2907      assert(operands[i]->type == get_int32_type(m));
2908      type = get_deref_type(type);
2909   }
2910
2911   type = dxil_module_get_pointer_type(m, type);
2912   if (!type)
2913      return NULL;
2914
2915   struct dxil_instr *instr = create_instr(m, INSTR_GEP, type);
2916   if (!instr)
2917      return NULL;
2918
2919   instr->gep.operands = ralloc_array(instr, struct dxil_value *,
2920                                      num_operands);
2921   if (!instr->gep.operands)
2922      return NULL;
2923
2924   instr->gep.source_elem_type = source_elem_type;
2925   memcpy(instr->gep.operands, operands,
2926          sizeof(struct dxil_value *) * num_operands);
2927   instr->gep.num_operands = num_operands;
2928   instr->gep.inbounds = true;
2929
2930   instr->has_value = true;
2931   return &instr->value;
2932}
2933
2934const struct dxil_value *
2935dxil_emit_load(struct dxil_module *m, const struct dxil_value *ptr,
2936               unsigned align,
2937               bool is_volatile)
2938{
2939   assert(ptr->type->type == TYPE_POINTER ||
2940          ptr->type->type == TYPE_ARRAY);
2941   const struct dxil_type *type = ptr->type->type == TYPE_POINTER ?
2942      ptr->type->ptr_target_type :
2943      ptr->type->array_or_vector_def.elem_type;
2944
2945   struct dxil_instr *instr = create_instr(m, INSTR_LOAD, type);
2946   if (!instr)
2947      return false;
2948
2949   instr->load.ptr = ptr;
2950   instr->load.type = type;
2951   instr->load.align = util_logbase2(align) + 1;
2952   instr->load.is_volatile = is_volatile;
2953
2954   instr->has_value = true;
2955   return &instr->value;
2956}
2957
2958bool
2959dxil_emit_store(struct dxil_module *m, const struct dxil_value *value,
2960                const struct dxil_value *ptr, unsigned align,
2961                bool is_volatile)
2962{
2963   assert(legal_arith_type(value->type));
2964
2965   struct dxil_instr *instr = create_instr(m, INSTR_STORE,
2966                                           dxil_module_get_void_type(m));
2967   if (!instr)
2968      return false;
2969
2970   instr->store.value = value;
2971   instr->store.ptr = ptr;
2972   instr->store.align = util_logbase2(align) + 1;
2973   instr->store.is_volatile = is_volatile;
2974   return true;
2975}
2976
2977const struct dxil_value *
2978dxil_emit_cmpxchg(struct dxil_module *m, const struct dxil_value *cmpval,
2979                  const struct dxil_value *newval,
2980                  const struct dxil_value *ptr, bool is_volatile,
2981                  enum dxil_atomic_ordering ordering,
2982                  enum dxil_sync_scope syncscope)
2983{
2984   assert(ptr->type->type == TYPE_POINTER);
2985
2986   struct dxil_instr *instr = create_instr(m, INSTR_CMPXCHG,
2987                                           ptr->type->ptr_target_type);
2988   if (!instr)
2989      return false;
2990
2991   instr->cmpxchg.cmpval = cmpval;
2992   instr->cmpxchg.newval = newval;
2993   instr->cmpxchg.ptr = ptr;
2994   instr->cmpxchg.is_volatile = is_volatile;
2995   instr->cmpxchg.ordering = ordering;
2996   instr->cmpxchg.syncscope = syncscope;
2997
2998   instr->has_value = true;
2999   return &instr->value;
3000}
3001
3002const struct dxil_value *
3003dxil_emit_atomicrmw(struct dxil_module *m, const struct dxil_value *value,
3004                    const struct dxil_value *ptr, enum dxil_rmw_op op,
3005                    bool is_volatile, enum dxil_atomic_ordering ordering,
3006                    enum dxil_sync_scope syncscope)
3007{
3008   assert(ptr->type->type == TYPE_POINTER);
3009
3010   struct dxil_instr *instr = create_instr(m, INSTR_ATOMICRMW,
3011                                           ptr->type->ptr_target_type);
3012   if (!instr)
3013      return false;
3014
3015   instr->atomicrmw.value = value;
3016   instr->atomicrmw.ptr = ptr;
3017   instr->atomicrmw.op = op;
3018   instr->atomicrmw.is_volatile = is_volatile;
3019   instr->atomicrmw.ordering = ordering;
3020   instr->atomicrmw.syncscope = syncscope;
3021
3022   instr->has_value = true;
3023   return &instr->value;
3024}
3025
3026static bool
3027emit_binop(struct dxil_module *m, struct dxil_instr *instr)
3028{
3029   assert(instr->type == INSTR_BINOP);
3030   assert(instr->value.id > instr->binop.operands[0]->id);
3031   assert(instr->value.id > instr->binop.operands[1]->id);
3032
3033   if (instr->binop.flags) {
3034      uint64_t data[] = {
3035         FUNC_CODE_INST_BINOP,
3036         instr->value.id - instr->binop.operands[0]->id,
3037         instr->value.id - instr->binop.operands[1]->id,
3038         instr->binop.opcode,
3039         instr->binop.flags
3040      };
3041      return emit_func_abbrev_record(m, FUNC_ABBREV_BINOP_FLAGS,
3042                                     data, ARRAY_SIZE(data));
3043   }
3044   uint64_t data[] = {
3045      FUNC_CODE_INST_BINOP,
3046      instr->value.id - instr->binop.operands[0]->id,
3047      instr->value.id - instr->binop.operands[1]->id,
3048      instr->binop.opcode
3049   };
3050   return emit_func_abbrev_record(m, FUNC_ABBREV_BINOP,
3051                                  data, ARRAY_SIZE(data));
3052}
3053
3054static bool
3055emit_cmp(struct dxil_module *m, struct dxil_instr *instr)
3056{
3057   assert(instr->type == INSTR_CMP);
3058   assert(instr->value.id > instr->cmp.operands[0]->id);
3059   assert(instr->value.id > instr->cmp.operands[1]->id);
3060   uint64_t data[] = {
3061      instr->value.id - instr->cmp.operands[0]->id,
3062      instr->value.id - instr->cmp.operands[1]->id,
3063      instr->cmp.pred
3064   };
3065   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_CMP2,
3066                                data, ARRAY_SIZE(data));
3067}
3068
3069static bool
3070emit_select(struct dxil_module *m, struct dxil_instr *instr)
3071{
3072   assert(instr->type == INSTR_SELECT);
3073   assert(instr->value.id > instr->select.operands[0]->id);
3074   assert(instr->value.id > instr->select.operands[1]->id);
3075   assert(instr->value.id > instr->select.operands[2]->id);
3076   uint64_t data[] = {
3077      instr->value.id - instr->select.operands[1]->id,
3078      instr->value.id - instr->select.operands[2]->id,
3079      instr->value.id - instr->select.operands[0]->id
3080   };
3081   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_VSELECT,
3082                                data, ARRAY_SIZE(data));
3083}
3084
3085static bool
3086emit_cast(struct dxil_module *m, struct dxil_instr *instr)
3087{
3088   assert(instr->type == INSTR_CAST);
3089   assert(instr->value.id > instr->cast.value->id);
3090   uint64_t data[] = {
3091      FUNC_CODE_INST_CAST,
3092      instr->value.id - instr->cast.value->id,
3093      instr->cast.type->id,
3094      instr->cast.opcode
3095   };
3096   return emit_func_abbrev_record(m, FUNC_ABBREV_CAST,
3097                                  data, ARRAY_SIZE(data));
3098}
3099
3100static bool
3101emit_branch(struct dxil_module *m, struct dxil_func_def *func, struct dxil_instr *instr)
3102{
3103   assert(instr->type == INSTR_BR);
3104   assert(instr->br.succ[0] < func->num_basic_block_ids);
3105   assert(func->basic_block_ids[instr->br.succ[0]] >= 0);
3106
3107   if (!instr->br.cond) {
3108      /* unconditional branch */
3109      uint64_t succ = func->basic_block_ids[instr->br.succ[0]];
3110      return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_BR, &succ, 1);
3111   }
3112   /* conditional branch */
3113   assert(instr->value.id > instr->br.cond->id);
3114   assert(instr->br.succ[1] < func->num_basic_block_ids);
3115   assert(func->basic_block_ids[instr->br.succ[1]] >= 0);
3116
3117   uint64_t data[] = {
3118      func->basic_block_ids[instr->br.succ[0]],
3119      func->basic_block_ids[instr->br.succ[1]],
3120      instr->value.id - instr->br.cond->id
3121   };
3122   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_BR,
3123                                data, ARRAY_SIZE(data));
3124}
3125
3126static bool
3127emit_phi(struct dxil_module *m, struct dxil_func_def *func, struct dxil_instr *instr)
3128{
3129   assert(instr->type == INSTR_PHI);
3130   uint64_t data[128];
3131   data[0] = instr->phi.type->id;
3132   assert(instr->phi.num_incoming > 0);
3133   for (int i = 0; i < instr->phi.num_incoming; ++i) {
3134      int64_t value_delta = instr->value.id - instr->phi.incoming[i].value->id;
3135      data[1 + i * 2] = encode_signed(value_delta);
3136      assert(instr->phi.incoming[i].block < func->num_basic_block_ids);
3137      assert(func->basic_block_ids[instr->phi.incoming[i].block] >= 0);
3138      data[1 + i * 2 + 1] = func->basic_block_ids[instr->phi.incoming[i].block];
3139   }
3140   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_PHI,
3141                                data, 1 + 2 * instr->phi.num_incoming);
3142}
3143
3144static bool
3145emit_extractval(struct dxil_module *m, struct dxil_instr *instr)
3146{
3147   assert(instr->type == INSTR_EXTRACTVAL);
3148   assert(instr->value.id > instr->extractval.src->id);
3149   assert(instr->value.id > instr->extractval.type->id);
3150
3151   /* relative value ID, followed by absolute type ID (only if
3152    * forward-declared), followed by n indices */
3153   uint64_t data[] = {
3154      instr->value.id - instr->extractval.src->id,
3155      instr->extractval.idx
3156   };
3157   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_EXTRACTVAL,
3158                                data, ARRAY_SIZE(data));
3159}
3160
3161static bool
3162emit_call(struct dxil_module *m, struct dxil_instr *instr)
3163{
3164   assert(instr->type == INSTR_CALL);
3165   assert(instr->call.func->value.id >= 0 && instr->value.id >= 0);
3166   assert(instr->call.func->type->id >= 0);
3167   assert(instr->call.func->value.id <= instr->value.id);
3168   int value_id_delta = instr->value.id - instr->call.func->value.id;
3169
3170   uint64_t data[256];
3171   data[0] = 0; // attribute id
3172   data[1] = 1 << 15; // calling convention etc
3173   data[2] = instr->call.func->type->id;
3174   data[3] = value_id_delta;
3175
3176   assert(instr->call.num_args < ARRAY_SIZE(data) - 4);
3177   for (size_t i = 0; i < instr->call.num_args; ++i) {
3178      assert(instr->call.args[i]->id >= 0);
3179      data[4 + i] = instr->value.id - instr->call.args[i]->id;
3180   }
3181
3182   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_CALL,
3183                                data, 4 + instr->call.num_args);
3184}
3185
3186static bool
3187emit_ret(struct dxil_module *m, struct dxil_instr *instr)
3188{
3189   assert(instr->type == INSTR_RET);
3190
3191   if (instr->ret.value) {
3192      assert(instr->ret.value->id >= 0);
3193      uint64_t data[] = { FUNC_CODE_INST_RET, instr->ret.value->id };
3194      return emit_func_abbrev_record(m, FUNC_ABBREV_RET_VAL,
3195                                     data, ARRAY_SIZE(data));
3196   }
3197
3198   uint64_t data[] = { FUNC_CODE_INST_RET };
3199   return emit_func_abbrev_record(m, FUNC_ABBREV_RET_VOID,
3200                                  data, ARRAY_SIZE(data));
3201}
3202
3203static bool
3204emit_alloca(struct dxil_module *m, struct dxil_instr *instr)
3205{
3206   assert(instr->type == INSTR_ALLOCA);
3207   assert(instr->alloca.alloc_type->id >= 0);
3208   assert(instr->alloca.size_type->id >= 0);
3209   assert(instr->alloca.size->id >= 0);
3210
3211   uint64_t data[] = {
3212      instr->alloca.alloc_type->id,
3213      instr->alloca.size_type->id,
3214      instr->alloca.size->id,
3215      instr->alloca.align,
3216   };
3217   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_ALLOCA,
3218                                data, ARRAY_SIZE(data));
3219}
3220
3221static bool
3222emit_gep(struct dxil_module *m, struct dxil_instr *instr)
3223{
3224   assert(instr->type == INSTR_GEP);
3225   assert(instr->gep.source_elem_type->id >= 0);
3226
3227   uint64_t data[256];
3228   data[0] = FUNC_CODE_INST_GEP;
3229   data[1] = instr->gep.inbounds;
3230   data[2] = instr->gep.source_elem_type->id;
3231
3232   assert(instr->gep.num_operands < ARRAY_SIZE(data) - 3);
3233   for (int i = 0; i < instr->gep.num_operands; ++i) {
3234      assert(instr->value.id > instr->gep.operands[i]->id);
3235      data[3 + i] = instr->value.id - instr->gep.operands[i]->id;
3236   }
3237   return emit_func_abbrev_record(m, FUNC_ABBREV_GEP,
3238                                  data, 3 + instr->gep.num_operands);
3239}
3240
3241static bool
3242emit_load(struct dxil_module *m, struct dxil_instr *instr)
3243{
3244   assert(instr->type == INSTR_LOAD);
3245   assert(instr->value.id > instr->load.ptr->id);
3246   assert(instr->load.type->id >= 0);
3247
3248   uint64_t data[] = {
3249      instr->value.id - instr->load.ptr->id,
3250      instr->load.type->id,
3251      instr->load.align,
3252      instr->load.is_volatile
3253   };
3254   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_LOAD,
3255                                data, ARRAY_SIZE(data));
3256}
3257static bool
3258emit_store(struct dxil_module *m, struct dxil_instr *instr)
3259{
3260   assert(instr->type == INSTR_STORE);
3261   assert(instr->value.id > instr->store.value->id);
3262   assert(instr->value.id > instr->store.ptr->id);
3263
3264   uint64_t data[] = {
3265      instr->value.id - instr->store.ptr->id,
3266      instr->value.id - instr->store.value->id,
3267      instr->store.align,
3268      instr->store.is_volatile
3269   };
3270   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_STORE,
3271                                data, ARRAY_SIZE(data));
3272}
3273
3274static bool
3275emit_cmpxchg(struct dxil_module *m, struct dxil_instr *instr)
3276{
3277   assert(instr->type == INSTR_CMPXCHG);
3278   assert(instr->value.id > instr->cmpxchg.cmpval->id);
3279   assert(instr->value.id > instr->cmpxchg.newval->id);
3280   assert(instr->value.id > instr->cmpxchg.ptr->id);
3281   uint64_t data[] = {
3282      instr->value.id - instr->cmpxchg.ptr->id,
3283      instr->value.id - instr->cmpxchg.cmpval->id,
3284      instr->value.id - instr->cmpxchg.newval->id,
3285      instr->cmpxchg.is_volatile,
3286      instr->cmpxchg.ordering,
3287      instr->cmpxchg.syncscope,
3288   };
3289   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_CMPXCHG_OLD,
3290                                data, ARRAY_SIZE(data));
3291}
3292
3293static bool
3294emit_atomicrmw(struct dxil_module *m, struct dxil_instr *instr)
3295{
3296   assert(instr->type == INSTR_ATOMICRMW);
3297   assert(instr->value.id > instr->atomicrmw.value->id);
3298   assert(instr->value.id > instr->atomicrmw.ptr->id);
3299   uint64_t data[] = {
3300      instr->value.id - instr->atomicrmw.ptr->id,
3301      instr->value.id - instr->atomicrmw.value->id,
3302      instr->atomicrmw.op,
3303      instr->atomicrmw.is_volatile,
3304      instr->atomicrmw.ordering,
3305      instr->atomicrmw.syncscope,
3306   };
3307   return emit_record_no_abbrev(&m->buf, FUNC_CODE_INST_ATOMICRMW,
3308                                data, ARRAY_SIZE(data));
3309}
3310
3311static bool
3312emit_instr(struct dxil_module *m, struct dxil_func_def *func, struct dxil_instr *instr)
3313{
3314   switch (instr->type) {
3315   case INSTR_BINOP:
3316      return emit_binop(m, instr);
3317
3318   case INSTR_CMP:
3319      return emit_cmp(m, instr);
3320
3321   case INSTR_SELECT:
3322      return emit_select(m, instr);
3323
3324   case INSTR_CAST:
3325      return emit_cast(m, instr);
3326
3327   case INSTR_BR:
3328      return emit_branch(m, func, instr);
3329
3330   case INSTR_PHI:
3331      return emit_phi(m, func, instr);
3332
3333   case INSTR_CALL:
3334      return emit_call(m, instr);
3335
3336   case INSTR_RET:
3337      return emit_ret(m, instr);
3338
3339   case INSTR_EXTRACTVAL:
3340      return emit_extractval(m, instr);
3341
3342   case INSTR_ALLOCA:
3343      return emit_alloca(m, instr);
3344
3345   case INSTR_GEP:
3346      return emit_gep(m, instr);
3347
3348   case INSTR_LOAD:
3349      return emit_load(m, instr);
3350
3351   case INSTR_STORE:
3352      return emit_store(m, instr);
3353
3354   case INSTR_ATOMICRMW:
3355      return emit_atomicrmw(m, instr);
3356
3357   case INSTR_CMPXCHG:
3358      return emit_cmpxchg(m, instr);
3359
3360   default:
3361      unreachable("unexpected instruction type");
3362   }
3363}
3364
3365static bool
3366emit_function(struct dxil_module *m, struct dxil_func_def *func)
3367{
3368   if (!enter_subblock(m, DXIL_FUNCTION_BLOCK, 4) ||
3369       !emit_record_int(m, FUNC_CODE_DECLAREBLOCKS, func->curr_block))
3370      return false;
3371
3372   list_for_each_entry(struct dxil_instr, instr, &func->instr_list, head) {
3373      if (!emit_instr(m, func, instr))
3374         return false;
3375   }
3376
3377   return exit_block(m);
3378}
3379
3380static void
3381assign_values(struct dxil_module *m)
3382{
3383   int next_value_id = 0;
3384
3385   struct dxil_gvar *gvar;
3386   LIST_FOR_EACH_ENTRY(gvar, &m->gvar_list, head) {
3387      gvar->value.id = next_value_id++;
3388   }
3389
3390   struct dxil_func *func;
3391   LIST_FOR_EACH_ENTRY(func, &m->func_list, head) {
3392      func->value.id = next_value_id++;
3393   }
3394
3395   struct dxil_const *c;
3396   LIST_FOR_EACH_ENTRY(c, &m->const_list, head) {
3397      c->value.id = next_value_id++;
3398   }
3399
3400   /* All functions start at this ID */
3401   unsigned value_id_at_functions_start = next_value_id;
3402
3403   struct dxil_func_def *func_def;
3404   LIST_FOR_EACH_ENTRY(func_def, &m->func_def_list, head) {
3405      struct dxil_instr *instr;
3406      next_value_id = value_id_at_functions_start;
3407      LIST_FOR_EACH_ENTRY(instr, &func_def->instr_list, head) {
3408         instr->value.id = next_value_id;
3409         if (instr->has_value)
3410            next_value_id++;
3411      }
3412   }
3413}
3414
3415bool
3416dxil_emit_module(struct dxil_module *m)
3417{
3418   assign_values(m);
3419   if (!(dxil_buffer_emit_bits(&m->buf, 'B', 8) &&
3420         dxil_buffer_emit_bits(&m->buf, 'C', 8) &&
3421         dxil_buffer_emit_bits(&m->buf, 0xC0, 8) &&
3422         dxil_buffer_emit_bits(&m->buf, 0xDE, 8) &&
3423         enter_subblock(m, DXIL_MODULE, 3) &&
3424         emit_record_int(m, DXIL_MODULE_CODE_VERSION, 1) &&
3425         emit_blockinfo(m) &&
3426         emit_attrib_group_table(m) &&
3427         emit_attribute_table(m) &&
3428         emit_type_table(m) &&
3429         emit_module_info(m) &&
3430         emit_module_consts(m) &&
3431         emit_metadata(m) &&
3432         emit_value_symbol_table(m)))
3433      return false;
3434
3435   struct dxil_func_def *func;
3436   LIST_FOR_EACH_ENTRY(func, &m->func_def_list, head) {
3437      if (!emit_function(m, func))
3438         return false;
3439   }
3440
3441   return exit_block(m);
3442}
3443