1/* 2 * Copyright © Microsoft Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include "dxil_module.h" 25#include "dxil_internal.h" 26 27#include "util/macros.h" 28#include "util/u_math.h" 29#include "util/u_memory.h" 30#include "util/rb_tree.h" 31 32#include <assert.h> 33#include <stdio.h> 34 35void 36dxil_module_init(struct dxil_module *m, void *ralloc_ctx) 37{ 38 assert(ralloc_ctx); 39 40 memset(m, 0, sizeof(struct dxil_module)); 41 m->ralloc_ctx = ralloc_ctx; 42 43 dxil_buffer_init(&m->buf, 2); 44 memset(&m->feats, 0, sizeof(m->feats)); 45 46 list_inithead(&m->type_list); 47 list_inithead(&m->func_list); 48 list_inithead(&m->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 61void 62dxil_module_release(struct dxil_module *m) 63{ 64 dxil_buffer_finish(&m->buf); 65} 66 67static bool 68emit_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 */ 81enum 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 89static bool 90enter_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 106static bool 107exit_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 126static bool 127emit_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 142static bool 143emit_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 149static bool 150emit_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 156static bool 157is_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 174static bool 175is_char6_string(const char *str) 176{ 177 while (*str != '\0') { 178 if (!is_char6(*str++)) 179 return false; 180 } 181 return true; 182} 183 184static bool 185is_char7_string(const char *str) 186{ 187 while (*str != '\0') { 188 if (*str++ & 0x80) 189 return false; 190 } 191 return true; 192} 193 194static unsigned 195encode_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 214static bool 215emit_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 223static bool 224emit_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 232static bool 233emit_char6(struct dxil_buffer *b, uint64_t data) 234{ 235 return dxil_buffer_emit_bits(b, encode_char6((char)data), 6); 236} 237 238struct 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 256static bool 257emit_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 338static struct dxil_type * 339create_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 351static bool 352types_equal(const struct dxil_type *lhs, const struct dxil_type *rhs); 353 354static bool 355type_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 366static bool 367types_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 411bool 412dxil_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 418nir_alu_type 419dxil_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 432bool 433dxil_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 445const struct dxil_type * 446dxil_value_get_type(const struct dxil_value *value) 447{ 448 return value->type; 449} 450 451const struct dxil_type * 452dxil_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 459static const struct dxil_type * 460create_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 468static const struct dxil_type * 469get_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 476static const struct dxil_type * 477get_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 484static const struct dxil_type * 485get_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 492static const struct dxil_type * 493get_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 500static const struct dxil_type * 501get_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 508static const struct dxil_type * 509create_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 517const struct dxil_type * 518dxil_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 531static const struct dxil_type * 532get_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 539static const struct dxil_type * 540get_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 547static const struct dxil_type * 548get_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 555const struct dxil_type * 556dxil_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 568const struct dxil_type * 569dxil_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 585const struct dxil_type * 586dxil_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 631const struct dxil_type * 632dxil_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 654const struct dxil_type * 655dxil_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 676const struct dxil_type * 677dxil_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 691const struct dxil_type * 692dxil_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 705const struct dxil_type * 706dxil_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 731const struct dxil_type * 732dxil_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 740static const struct dxil_type * 741dxil_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 760static const char * 761get_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 775static const char * 776get_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 794static const char * 795get_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} 806const struct dxil_type * 807dxil_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 846const struct dxil_type * 847dxil_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 870const struct dxil_type * 871dxil_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 881const struct dxil_type * 882dxil_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 904enum 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 937enum 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 947static const struct dxil_abbrev 948type_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 972static bool 973emit_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 982enum 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 1008enum const_abbrev_id { 1009 CONST_ABBREV_SETTYPE, 1010 CONST_ABBREV_INTEGER, 1011 CONST_ABBREV_CE_CAST, 1012 CONST_ABBREV_NULL, 1013}; 1014 1015static const struct dxil_abbrev 1016const_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 1025static bool 1026emit_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 1035enum 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 1083enum 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 1094static const struct dxil_abbrev 1095func_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 1121static bool 1122emit_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 1130static bool 1131define_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 1162enum dxil_blockinfo_code { 1163 DXIL_BLOCKINFO_CODE_SETBID = 1, 1164 DXIL_BLOCKINFO_CODE_BLOCKNAME = 2, 1165 DXIL_BLOCKINFO_CODE_SETRECORDNAME = 3 1166}; 1167 1168static bool 1169switch_to_block(struct dxil_module *m, uint32_t block) 1170{ 1171 return emit_record_int(m, DXIL_BLOCKINFO_CODE_SETBID, block); 1172} 1173 1174enum dxil_standard_block { 1175 DXIL_BLOCKINFO = 0, 1176 DXIL_FIRST_APPLICATION_BLOCK = 8 1177}; 1178 1179enum 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 1190enum value_symtab_code { 1191 VST_CODE_ENTRY = 1, 1192 VST_CODE_BBENTRY = 2 1193}; 1194 1195enum 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 1202static 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 1215static bool 1216emit_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 1229static bool 1230emit_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 1243static bool 1244emit_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 1257static bool 1258emit_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 1267enum attribute_codes { 1268 PARAMATTR_GRP_CODE_ENTRY = 3, 1269 PARAMATTR_CODE_ENTRY = 2 1270}; 1271 1272static bool 1273emit_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 1297static bool 1298emit_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 1314static bool 1315emit_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 1331static bool 1332emit_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 1342static bool 1343emit_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 1354static bool 1355emit_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 1362static bool 1363emit_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 1374static bool 1375emit_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 1388static bool 1389emit_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 1418static bool 1419emit_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 1431static bool 1432emit_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 1450static bool 1451emit_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 1461static bool 1462emit_metadata_type(struct dxil_module *m) 1463{ 1464 return emit_record(m, TYPE_CODE_METADATA, NULL, 0); 1465} 1466 1467static bool 1468emit_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 1500static bool 1501emit_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 1517static struct dxil_const * 1518create_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 1531static const struct dxil_value * 1532get_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 1554const struct dxil_value * 1555dxil_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 1564const struct dxil_value * 1565dxil_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 1574const struct dxil_value * 1575dxil_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 1584const struct dxil_value * 1585dxil_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 1594const struct dxil_value * 1595dxil_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 1604const struct dxil_value * 1605dxil_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 1634const struct dxil_value * 1635dxil_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 1658const struct dxil_value * 1659dxil_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 1682const struct dxil_value * 1683dxil_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 1706const struct dxil_value * 1707dxil_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 1733const struct dxil_value * 1734dxil_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 1751enum 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 1766static bool 1767emit_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 1778static bool 1779emit_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 1791static const struct dxil_value * 1792add_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 1815const struct dxil_value * 1816dxil_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 1824const struct dxil_value * 1825dxil_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 1834static struct dxil_func * 1835add_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 1861const struct dxil_func * 1862dxil_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 1868static unsigned 1869get_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 1898const struct dxil_func * 1899dxil_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 1910static bool 1911emit_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 1924enum gvar_var_flags { 1925 GVAR_FLAG_CONSTANT = (1 << 0), 1926 GVAR_FLAG_EXPLICIT_TYPE = (1 << 1), 1927}; 1928 1929enum 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 1942static bool 1943emit_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 1960static bool 1961emit_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 2002static bool 2003emit_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 2021static bool 2022emit_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 2029static bool 2030emit_null_value(struct dxil_module *m) 2031{ 2032 return emit_record_no_abbrev(&m->buf, CST_CODE_NULL, NULL, 0); 2033} 2034 2035static bool 2036emit_undef_value(struct dxil_module *m) 2037{ 2038 return emit_record_no_abbrev(&m->buf, CST_CODE_UNDEF, NULL, 0); 2039} 2040 2041static uint64_t 2042encode_signed(int64_t value) 2043{ 2044 return value >= 0 ? 2045 (value << 1) : 2046 ((-value << 1) | 1); 2047} 2048 2049static bool 2050emit_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 2060static bool 2061emit_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 2069static bool 2070emit_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 2078static bool 2079emit_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 2088static bool 2089emit_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 2102static bool 2103emit_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 2162static bool 2163emit_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 2171static bool 2172emit_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 2181static bool 2182emit_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 2201static bool 2202emit_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 2220enum 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 2229enum metadata_abbrev_id { 2230 METADATA_ABBREV_STRING, 2231 METADATA_ABBREV_NAME 2232}; 2233 2234static 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 2243static bool 2244emit_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 2253static struct dxil_mdnode * 2254create_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 2266const struct dxil_mdnode * 2267dxil_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 2287const struct dxil_mdnode * 2288dxil_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 2307const struct dxil_mdnode * 2308dxil_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 2315const struct dxil_mdnode * 2316dxil_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 2342const struct dxil_mdnode * 2343dxil_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 2356const struct dxil_mdnode * 2357dxil_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 2370const struct dxil_mdnode * 2371dxil_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 2384const struct dxil_mdnode * 2385dxil_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 2398bool 2399dxil_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 2424static bool 2425emit_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 2433static bool 2434emit_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 2443static bool 2444emit_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 2456static bool 2457emit_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 2469static bool 2470emit_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 2487static bool 2488emit_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 2497static bool 2498emit_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 2510static bool 2511emit_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 2526static bool 2527emit_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 2538static bool 2539emit_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 2548static struct dxil_instr * 2549create_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 2564static inline bool 2565legal_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 2584const struct dxil_value * 2585dxil_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 2603const struct dxil_value * 2604dxil_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 2620const struct dxil_value * 2621dxil_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 2641const struct dxil_value * 2642dxil_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 2660bool 2661dxil_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 2678const struct dxil_value * 2679dxil_instr_get_return_value(struct dxil_instr *instr) 2680{ 2681 return instr->has_value ? &instr->value : NULL; 2682} 2683 2684struct dxil_instr * 2685dxil_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 2700void 2701dxil_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 2719static struct dxil_instr * 2720create_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 2741const struct dxil_value * 2742dxil_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 2756bool 2757dxil_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 2770bool 2771dxil_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 2783const struct dxil_value * 2784dxil_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 2804const struct dxil_value * 2805dxil_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 2832static const struct dxil_type * 2833get_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 2842const struct dxil_value * 2843dxil_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 2880const struct dxil_value * 2881dxil_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 2904bool 2905dxil_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 2923const struct dxil_value * 2924dxil_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 2948const struct dxil_value * 2949dxil_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 2972static bool 2973emit_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 3000static bool 3001emit_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 3015static bool 3016emit_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 3031static bool 3032emit_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 3046static bool 3047emit_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 3072static bool 3073emit_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 3090static bool 3091emit_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 3107static bool 3108emit_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 3132static bool 3133emit_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 3149static bool 3150emit_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 3167static bool 3168emit_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 3187static bool 3188emit_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} 3203static bool 3204emit_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 3220static bool 3221emit_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 3239static bool 3240emit_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 3257static bool 3258emit_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 3311static bool 3312emit_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 3326static void 3327assign_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 3354bool 3355dxil_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