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