1 /* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2012-2013 LunarG, Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Chia-I Wu <olv (at) lunarg.com> 26 */ 27 28 #ifndef TOY_REG_H 29 #define TOY_REG_H 30 31 #include "pipe/p_compiler.h" 32 #include "util/u_debug.h" /* for assert() */ 33 #include "util/u_math.h" /* for union fi */ 34 35 /* a toy reg is 256-bit wide */ 36 #define TOY_REG_WIDTH 32 37 38 /** 39 * Register files. 40 */ 41 enum toy_file { 42 /* virtual register file */ 43 TOY_FILE_VRF, 44 45 TOY_FILE_ARF, 46 TOY_FILE_GRF, 47 TOY_FILE_MRF, 48 TOY_FILE_IMM, 49 50 TOY_FILE_COUNT, 51 }; 52 53 /** 54 * Register types. 55 */ 56 enum toy_type { 57 TOY_TYPE_F, 58 TOY_TYPE_D, 59 TOY_TYPE_UD, 60 TOY_TYPE_W, 61 TOY_TYPE_UW, 62 TOY_TYPE_V, /* only valid for immediates */ 63 64 TOY_TYPE_COUNT, 65 }; 66 67 /** 68 * Register rectangles. The three numbers stand for vertical stride, width, 69 * and horizontal stride respectively. 70 */ 71 enum toy_rect { 72 TOY_RECT_LINEAR, 73 TOY_RECT_041, 74 TOY_RECT_010, 75 TOY_RECT_220, 76 TOY_RECT_440, 77 TOY_RECT_240, 78 79 TOY_RECT_COUNT, 80 }; 81 82 /** 83 * Source swizzles. They are compatible with TGSI_SWIZZLE_x and hardware 84 * values. 85 */ 86 enum toy_swizzle { 87 TOY_SWIZZLE_X = 0, 88 TOY_SWIZZLE_Y = 1, 89 TOY_SWIZZLE_Z = 2, 90 TOY_SWIZZLE_W = 3, 91 }; 92 93 /** 94 * Destination writemasks. They are compatible with TGSI_WRITEMASK_x and 95 * hardware values. 96 */ 97 enum toy_writemask { 98 TOY_WRITEMASK_X = (1 << TOY_SWIZZLE_X), 99 TOY_WRITEMASK_Y = (1 << TOY_SWIZZLE_Y), 100 TOY_WRITEMASK_Z = (1 << TOY_SWIZZLE_Z), 101 TOY_WRITEMASK_W = (1 << TOY_SWIZZLE_W), 102 TOY_WRITEMASK_XY = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y), 103 TOY_WRITEMASK_XZ = (TOY_WRITEMASK_X | TOY_WRITEMASK_Z), 104 TOY_WRITEMASK_XW = (TOY_WRITEMASK_X | TOY_WRITEMASK_W), 105 TOY_WRITEMASK_YZ = (TOY_WRITEMASK_Y | TOY_WRITEMASK_Z), 106 TOY_WRITEMASK_YW = (TOY_WRITEMASK_Y | TOY_WRITEMASK_W), 107 TOY_WRITEMASK_ZW = (TOY_WRITEMASK_Z | TOY_WRITEMASK_W), 108 TOY_WRITEMASK_XYZ = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y | TOY_WRITEMASK_Z), 109 TOY_WRITEMASK_XYW = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y | TOY_WRITEMASK_W), 110 TOY_WRITEMASK_XZW = (TOY_WRITEMASK_X | TOY_WRITEMASK_Z | TOY_WRITEMASK_W), 111 TOY_WRITEMASK_YZW = (TOY_WRITEMASK_Y | TOY_WRITEMASK_Z | TOY_WRITEMASK_W), 112 TOY_WRITEMASK_XYZW = (TOY_WRITEMASK_X | TOY_WRITEMASK_Y | 113 TOY_WRITEMASK_Z | TOY_WRITEMASK_W), 114 }; 115 116 /** 117 * Destination operand. 118 */ 119 struct toy_dst { 120 unsigned file:3; /* TOY_FILE_x */ 121 unsigned type:4; /* TOY_TYPE_x */ 122 unsigned rect:3; /* TOY_RECT_x */ 123 unsigned indirect:1; /* true or false */ 124 unsigned indirect_subreg:6; /* which subreg of a0? */ 125 126 unsigned writemask:4; /* TOY_WRITEMASK_x */ 127 unsigned pad:11; 128 129 uint32_t val32; 130 }; 131 132 /** 133 * Source operand. 134 */ 135 struct toy_src { 136 unsigned file:3; /* TOY_FILE_x */ 137 unsigned type:4; /* TOY_TYPE_x */ 138 unsigned rect:3; /* TOY_RECT_x */ 139 unsigned indirect:1; /* true or false */ 140 unsigned indirect_subreg:6; /* which subreg of a0? */ 141 142 unsigned swizzle_x:2; /* TOY_SWIZZLE_x */ 143 unsigned swizzle_y:2; /* TOY_SWIZZLE_x */ 144 unsigned swizzle_z:2; /* TOY_SWIZZLE_x */ 145 unsigned swizzle_w:2; /* TOY_SWIZZLE_x */ 146 unsigned absolute:1; /* true or false */ 147 unsigned negate:1; /* true or false */ 148 unsigned pad:5; 149 150 uint32_t val32; 151 }; 152 153 /** 154 * Return true if the file is virtual. 155 */ 156 static inline bool 157 toy_file_is_virtual(enum toy_file file) 158 { 159 return (file == TOY_FILE_VRF); 160 } 161 162 /** 163 * Return true if the file is a hardware one. 164 */ 165 static inline bool 166 toy_file_is_hw(enum toy_file file) 167 { 168 return !toy_file_is_virtual(file); 169 } 170 171 /** 172 * Return the size of the file. 173 */ 174 static inline uint32_t 175 toy_file_size(enum toy_file file) 176 { 177 switch (file) { 178 case TOY_FILE_GRF: 179 return 256 * TOY_REG_WIDTH; 180 case TOY_FILE_MRF: 181 /* there is no MRF on GEN7+ */ 182 return 256 * TOY_REG_WIDTH; 183 default: 184 assert(!"invalid toy file"); 185 return 0; 186 } 187 } 188 189 /** 190 * Return the size of the type. 191 */ 192 static inline int 193 toy_type_size(enum toy_type type) 194 { 195 switch (type) { 196 case TOY_TYPE_F: 197 case TOY_TYPE_D: 198 case TOY_TYPE_UD: 199 return 4; 200 case TOY_TYPE_W: 201 case TOY_TYPE_UW: 202 return 2; 203 case TOY_TYPE_V: 204 default: 205 assert(!"invalid toy type"); 206 return 0; 207 } 208 } 209 210 /** 211 * Return true if the destination operand is null. 212 */ 213 static inline bool 214 tdst_is_null(struct toy_dst dst) 215 { 216 /* GEN6_ARF_NULL happens to be 0 */ 217 return (dst.file == TOY_FILE_ARF && dst.val32 == 0); 218 } 219 220 /** 221 * Validate the destination operand. 222 */ 223 static inline struct toy_dst 224 tdst_validate(struct toy_dst dst) 225 { 226 switch (dst.file) { 227 case TOY_FILE_VRF: 228 case TOY_FILE_ARF: 229 case TOY_FILE_MRF: 230 assert(!dst.indirect); 231 if (dst.file == TOY_FILE_MRF) 232 assert(dst.val32 < toy_file_size(dst.file)); 233 break; 234 case TOY_FILE_GRF: 235 if (!dst.indirect) 236 assert(dst.val32 < toy_file_size(dst.file)); 237 break; 238 case TOY_FILE_IMM: 239 /* yes, dst can be IMM of type W (for IF/ELSE/ENDIF/WHILE) */ 240 assert(!dst.indirect); 241 assert(dst.type == TOY_TYPE_W); 242 break; 243 default: 244 assert(!"invalid dst file"); 245 break; 246 } 247 248 switch (dst.type) { 249 case TOY_TYPE_V: 250 assert(!"invalid dst type"); 251 break; 252 default: 253 break; 254 } 255 256 assert(dst.rect == TOY_RECT_LINEAR); 257 if (dst.file != TOY_FILE_IMM) 258 assert(dst.val32 % toy_type_size(dst.type) == 0); 259 260 assert(dst.writemask <= TOY_WRITEMASK_XYZW); 261 262 return dst; 263 } 264 265 /** 266 * Change the type of the destination operand. 267 */ 268 static inline struct toy_dst 269 tdst_type(struct toy_dst dst, enum toy_type type) 270 { 271 dst.type = type; 272 return tdst_validate(dst); 273 } 274 275 /** 276 * Change the type of the destination operand to TOY_TYPE_D. 277 */ 278 static inline struct toy_dst 279 tdst_d(struct toy_dst dst) 280 { 281 return tdst_type(dst, TOY_TYPE_D); 282 } 283 284 /** 285 * Change the type of the destination operand to TOY_TYPE_UD. 286 */ 287 static inline struct toy_dst 288 tdst_ud(struct toy_dst dst) 289 { 290 return tdst_type(dst, TOY_TYPE_UD); 291 } 292 293 /** 294 * Change the type of the destination operand to TOY_TYPE_W. 295 */ 296 static inline struct toy_dst 297 tdst_w(struct toy_dst dst) 298 { 299 return tdst_type(dst, TOY_TYPE_W); 300 } 301 302 /** 303 * Change the type of the destination operand to TOY_TYPE_UW. 304 */ 305 static inline struct toy_dst 306 tdst_uw(struct toy_dst dst) 307 { 308 return tdst_type(dst, TOY_TYPE_UW); 309 } 310 311 /** 312 * Change the rectangle of the destination operand. 313 */ 314 static inline struct toy_dst 315 tdst_rect(struct toy_dst dst, enum toy_rect rect) 316 { 317 dst.rect = rect; 318 return tdst_validate(dst); 319 } 320 321 /** 322 * Apply writemask to the destination operand. Note that the current 323 * writemask is honored. 324 */ 325 static inline struct toy_dst 326 tdst_writemask(struct toy_dst dst, enum toy_writemask writemask) 327 { 328 dst.writemask &= writemask; 329 return tdst_validate(dst); 330 } 331 332 /** 333 * Offset the destination operand. 334 */ 335 static inline struct toy_dst 336 tdst_offset(struct toy_dst dst, int reg, int subreg) 337 { 338 dst.val32 += reg * TOY_REG_WIDTH + subreg * toy_type_size(dst.type); 339 return tdst_validate(dst); 340 } 341 342 /** 343 * Construct a destination operand. 344 */ 345 static inline struct toy_dst 346 tdst_full(enum toy_file file, enum toy_type type, enum toy_rect rect, 347 bool indirect, unsigned indirect_subreg, 348 enum toy_writemask writemask, uint32_t val32) 349 { 350 struct toy_dst dst; 351 352 dst.file = file; 353 dst.type = type; 354 dst.rect = rect; 355 dst.indirect = indirect; 356 dst.indirect_subreg = indirect_subreg; 357 dst.writemask = writemask; 358 dst.pad = 0; 359 360 dst.val32 = val32; 361 362 return tdst_validate(dst); 363 } 364 365 /** 366 * Construct a null destination operand. 367 */ 368 static inline struct toy_dst 369 tdst_null(void) 370 { 371 static const struct toy_dst null_dst = { 372 .file = TOY_FILE_ARF, 373 .type = TOY_TYPE_F, 374 .rect = TOY_RECT_LINEAR, 375 .indirect = false, 376 .indirect_subreg = 0, 377 .writemask = TOY_WRITEMASK_XYZW, 378 .pad = 0, 379 .val32 = 0, 380 }; 381 382 return null_dst; 383 } 384 385 /** 386 * Construct a destination operand from a source operand. 387 */ 388 static inline struct toy_dst 389 tdst_from(struct toy_src src) 390 { 391 const enum toy_writemask writemask = 392 (1 << src.swizzle_x) | 393 (1 << src.swizzle_y) | 394 (1 << src.swizzle_z) | 395 (1 << src.swizzle_w); 396 397 return tdst_full(src.file, src.type, src.rect, 398 src.indirect, src.indirect_subreg, writemask, src.val32); 399 } 400 401 /** 402 * Construct a destination operand, assuming the type is TOY_TYPE_F, the 403 * rectangle is TOY_RECT_LINEAR, and the writemask is TOY_WRITEMASK_XYZW. 404 */ 405 static inline struct toy_dst 406 tdst(enum toy_file file, unsigned reg, unsigned subreg_in_bytes) 407 { 408 const enum toy_type type = TOY_TYPE_F; 409 const enum toy_rect rect = TOY_RECT_LINEAR; 410 const uint32_t val32 = reg * TOY_REG_WIDTH + subreg_in_bytes; 411 412 return tdst_full(file, type, rect, 413 false, 0, TOY_WRITEMASK_XYZW, val32); 414 } 415 416 /** 417 * Construct an immediate destination operand of type TOY_TYPE_W. 418 */ 419 static inline struct toy_dst 420 tdst_imm_w(int16_t w) 421 { 422 const union fi fi = { .i = w }; 423 424 return tdst_full(TOY_FILE_IMM, TOY_TYPE_W, TOY_RECT_LINEAR, 425 false, 0, TOY_WRITEMASK_XYZW, fi.ui); 426 } 427 428 /** 429 * Return true if the source operand is null. 430 */ 431 static inline bool 432 tsrc_is_null(struct toy_src src) 433 { 434 /* GEN6_ARF_NULL happens to be 0 */ 435 return (src.file == TOY_FILE_ARF && src.val32 == 0); 436 } 437 438 /** 439 * Return true if the source operand is swizzled. 440 */ 441 static inline bool 442 tsrc_is_swizzled(struct toy_src src) 443 { 444 return (src.swizzle_x != TOY_SWIZZLE_X || 445 src.swizzle_y != TOY_SWIZZLE_Y || 446 src.swizzle_z != TOY_SWIZZLE_Z || 447 src.swizzle_w != TOY_SWIZZLE_W); 448 } 449 450 /** 451 * Return true if the source operand is swizzled to the same channel. 452 */ 453 static inline bool 454 tsrc_is_swizzle1(struct toy_src src) 455 { 456 return (src.swizzle_x == src.swizzle_y && 457 src.swizzle_x == src.swizzle_z && 458 src.swizzle_x == src.swizzle_w); 459 } 460 461 /** 462 * Validate the source operand. 463 */ 464 static inline struct toy_src 465 tsrc_validate(struct toy_src src) 466 { 467 switch (src.file) { 468 case TOY_FILE_VRF: 469 case TOY_FILE_ARF: 470 case TOY_FILE_MRF: 471 assert(!src.indirect); 472 if (src.file == TOY_FILE_MRF) 473 assert(src.val32 < toy_file_size(src.file)); 474 break; 475 case TOY_FILE_GRF: 476 if (!src.indirect) 477 assert(src.val32 < toy_file_size(src.file)); 478 break; 479 case TOY_FILE_IMM: 480 assert(!src.indirect); 481 break; 482 default: 483 assert(!"invalid src file"); 484 break; 485 } 486 487 switch (src.type) { 488 case TOY_TYPE_V: 489 assert(src.file == TOY_FILE_IMM); 490 break; 491 default: 492 break; 493 } 494 495 if (src.file != TOY_FILE_IMM) 496 assert(src.val32 % toy_type_size(src.type) == 0); 497 498 assert(src.swizzle_x < 4 && src.swizzle_y < 4 && 499 src.swizzle_z < 4 && src.swizzle_w < 4); 500 501 return src; 502 } 503 504 /** 505 * Change the type of the source operand. 506 */ 507 static inline struct toy_src 508 tsrc_type(struct toy_src src, enum toy_type type) 509 { 510 src.type = type; 511 return tsrc_validate(src); 512 } 513 514 /** 515 * Change the type of the source operand to TOY_TYPE_D. 516 */ 517 static inline struct toy_src 518 tsrc_d(struct toy_src src) 519 { 520 return tsrc_type(src, TOY_TYPE_D); 521 } 522 523 /** 524 * Change the type of the source operand to TOY_TYPE_UD. 525 */ 526 static inline struct toy_src 527 tsrc_ud(struct toy_src src) 528 { 529 return tsrc_type(src, TOY_TYPE_UD); 530 } 531 532 /** 533 * Change the type of the source operand to TOY_TYPE_W. 534 */ 535 static inline struct toy_src 536 tsrc_w(struct toy_src src) 537 { 538 return tsrc_type(src, TOY_TYPE_W); 539 } 540 541 /** 542 * Change the type of the source operand to TOY_TYPE_UW. 543 */ 544 static inline struct toy_src 545 tsrc_uw(struct toy_src src) 546 { 547 return tsrc_type(src, TOY_TYPE_UW); 548 } 549 550 /** 551 * Change the rectangle of the source operand. 552 */ 553 static inline struct toy_src 554 tsrc_rect(struct toy_src src, enum toy_rect rect) 555 { 556 src.rect = rect; 557 return tsrc_validate(src); 558 } 559 560 /** 561 * Swizzle the source operand. Note that the current swizzles are honored. 562 */ 563 static inline struct toy_src 564 tsrc_swizzle(struct toy_src src, 565 enum toy_swizzle swizzle_x, enum toy_swizzle swizzle_y, 566 enum toy_swizzle swizzle_z, enum toy_swizzle swizzle_w) 567 { 568 const enum toy_swizzle current[4] = { 569 src.swizzle_x, src.swizzle_y, 570 src.swizzle_z, src.swizzle_w, 571 }; 572 573 src.swizzle_x = current[swizzle_x]; 574 src.swizzle_y = current[swizzle_y]; 575 src.swizzle_z = current[swizzle_z]; 576 src.swizzle_w = current[swizzle_w]; 577 578 return tsrc_validate(src); 579 } 580 581 /** 582 * Swizzle the source operand to the same channel. Note that the current 583 * swizzles are honored. 584 */ 585 static inline struct toy_src 586 tsrc_swizzle1(struct toy_src src, enum toy_swizzle swizzle) 587 { 588 return tsrc_swizzle(src, swizzle, swizzle, swizzle, swizzle); 589 } 590 591 /** 592 * Set absolute and unset negate of the source operand. 593 */ 594 static inline struct toy_src 595 tsrc_absolute(struct toy_src src) 596 { 597 src.absolute = true; 598 src.negate = false; 599 return tsrc_validate(src); 600 } 601 602 /** 603 * Negate the source operand. 604 */ 605 static inline struct toy_src 606 tsrc_negate(struct toy_src src) 607 { 608 src.negate = !src.negate; 609 return tsrc_validate(src); 610 } 611 612 /** 613 * Offset the source operand. 614 */ 615 static inline struct toy_src 616 tsrc_offset(struct toy_src src, int reg, int subreg) 617 { 618 src.val32 += reg * TOY_REG_WIDTH + subreg * toy_type_size(src.type); 619 return tsrc_validate(src); 620 } 621 622 /** 623 * Construct a source operand. 624 */ 625 static inline struct toy_src 626 tsrc_full(enum toy_file file, enum toy_type type, 627 enum toy_rect rect, bool indirect, unsigned indirect_subreg, 628 enum toy_swizzle swizzle_x, enum toy_swizzle swizzle_y, 629 enum toy_swizzle swizzle_z, enum toy_swizzle swizzle_w, 630 bool absolute, bool negate, 631 uint32_t val32) 632 { 633 struct toy_src src; 634 635 src.file = file; 636 src.type = type; 637 src.rect = rect; 638 src.indirect = indirect; 639 src.indirect_subreg = indirect_subreg; 640 src.swizzle_x = swizzle_x; 641 src.swizzle_y = swizzle_y; 642 src.swizzle_z = swizzle_z; 643 src.swizzle_w = swizzle_w; 644 src.absolute = absolute; 645 src.negate = negate; 646 src.pad = 0; 647 648 src.val32 = val32; 649 650 return tsrc_validate(src); 651 } 652 653 /** 654 * Construct a null source operand. 655 */ 656 static inline struct toy_src 657 tsrc_null(void) 658 { 659 static const struct toy_src null_src = { 660 .file = TOY_FILE_ARF, 661 .type = TOY_TYPE_F, 662 .rect = TOY_RECT_LINEAR, 663 .indirect = false, 664 .indirect_subreg = 0, 665 .swizzle_x = TOY_SWIZZLE_X, 666 .swizzle_y = TOY_SWIZZLE_Y, 667 .swizzle_z = TOY_SWIZZLE_Z, 668 .swizzle_w = TOY_SWIZZLE_W, 669 .absolute = false, 670 .negate = false, 671 .pad = 0, 672 .val32 = 0, 673 }; 674 675 return null_src; 676 } 677 678 /** 679 * Construct a source operand from a destination operand. 680 */ 681 static inline struct toy_src 682 tsrc_from(struct toy_dst dst) 683 { 684 enum toy_swizzle swizzle[4]; 685 686 if (dst.writemask == TOY_WRITEMASK_XYZW) { 687 swizzle[0] = TOY_SWIZZLE_X; 688 swizzle[1] = TOY_SWIZZLE_Y; 689 swizzle[2] = TOY_SWIZZLE_Z; 690 swizzle[3] = TOY_SWIZZLE_W; 691 } 692 else { 693 const enum toy_swizzle first = 694 (dst.writemask & TOY_WRITEMASK_X) ? TOY_SWIZZLE_X : 695 (dst.writemask & TOY_WRITEMASK_Y) ? TOY_SWIZZLE_Y : 696 (dst.writemask & TOY_WRITEMASK_Z) ? TOY_SWIZZLE_Z : 697 (dst.writemask & TOY_WRITEMASK_W) ? TOY_SWIZZLE_W : 698 TOY_SWIZZLE_X; 699 700 swizzle[0] = (dst.writemask & TOY_WRITEMASK_X) ? TOY_SWIZZLE_X : first; 701 swizzle[1] = (dst.writemask & TOY_WRITEMASK_Y) ? TOY_SWIZZLE_Y : first; 702 swizzle[2] = (dst.writemask & TOY_WRITEMASK_Z) ? TOY_SWIZZLE_Z : first; 703 swizzle[3] = (dst.writemask & TOY_WRITEMASK_W) ? TOY_SWIZZLE_W : first; 704 } 705 706 return tsrc_full(dst.file, dst.type, dst.rect, 707 dst.indirect, dst.indirect_subreg, 708 swizzle[0], swizzle[1], swizzle[2], swizzle[3], 709 false, false, dst.val32); 710 } 711 712 /** 713 * Construct a source operand, assuming the type is TOY_TYPE_F, the 714 * rectangle is TOY_RECT_LINEAR, and no swizzles/absolute/negate. 715 */ 716 static inline struct toy_src 717 tsrc(enum toy_file file, unsigned reg, unsigned subreg_in_bytes) 718 { 719 const enum toy_type type = TOY_TYPE_F; 720 const enum toy_rect rect = TOY_RECT_LINEAR; 721 const uint32_t val32 = reg * TOY_REG_WIDTH + subreg_in_bytes; 722 723 return tsrc_full(file, type, rect, false, 0, 724 TOY_SWIZZLE_X, TOY_SWIZZLE_Y, 725 TOY_SWIZZLE_Z, TOY_SWIZZLE_W, 726 false, false, val32); 727 } 728 729 /** 730 * Construct an immediate source operand. 731 */ 732 static inline struct toy_src 733 tsrc_imm(enum toy_type type, uint32_t val32) 734 { 735 return tsrc_full(TOY_FILE_IMM, type, TOY_RECT_LINEAR, false, 0, 736 TOY_SWIZZLE_X, TOY_SWIZZLE_Y, 737 TOY_SWIZZLE_Z, TOY_SWIZZLE_W, 738 false, false, val32); 739 } 740 741 /** 742 * Construct an immediate source operand of type TOY_TYPE_F. 743 */ 744 static inline struct toy_src 745 tsrc_imm_f(float f) 746 { 747 const union fi fi = { .f = f }; 748 return tsrc_imm(TOY_TYPE_F, fi.ui); 749 } 750 751 /** 752 * Construct an immediate source operand of type TOY_TYPE_D. 753 */ 754 static inline struct toy_src 755 tsrc_imm_d(int32_t d) 756 { 757 const union fi fi = { .i = d }; 758 return tsrc_imm(TOY_TYPE_D, fi.ui); 759 } 760 761 /** 762 * Construct an immediate source operand of type TOY_TYPE_UD. 763 */ 764 static inline struct toy_src 765 tsrc_imm_ud(uint32_t ud) 766 { 767 const union fi fi = { .ui = ud }; 768 return tsrc_imm(TOY_TYPE_UD, fi.ui); 769 } 770 771 /** 772 * Construct an immediate source operand of type TOY_TYPE_W. 773 */ 774 static inline struct toy_src 775 tsrc_imm_w(int16_t w) 776 { 777 const union fi fi = { .i = w }; 778 return tsrc_imm(TOY_TYPE_W, fi.ui); 779 } 780 781 /** 782 * Construct an immediate source operand of type TOY_TYPE_UW. 783 */ 784 static inline struct toy_src 785 tsrc_imm_uw(uint16_t uw) 786 { 787 const union fi fi = { .ui = uw }; 788 return tsrc_imm(TOY_TYPE_UW, fi.ui); 789 } 790 791 /** 792 * Construct an immediate source operand of type TOY_TYPE_V. 793 */ 794 static inline struct toy_src 795 tsrc_imm_v(uint32_t v) 796 { 797 return tsrc_imm(TOY_TYPE_V, v); 798 } 799 800 #endif /* TOY_REG_H */ 801