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