Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2013 Rob Clark <robdclark@gmail.com>
  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 FROM,
  20.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21.  * SOFTWARE.
  22.  */
  23.  
  24. #include "ir-a3xx.h"
  25.  
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <assert.h>
  30. #include <stdbool.h>
  31. #include <errno.h>
  32.  
  33. #include "freedreno_util.h"
  34. #include "instr-a3xx.h"
  35.  
  36. /* simple allocator to carve allocations out of an up-front allocated heap,
  37.  * so that we can free everything easily in one shot.
  38.  */
  39. static void * ir3_alloc(struct ir3_shader *shader, int sz)
  40. {
  41.         void *ptr = &shader->heap[shader->heap_idx];
  42.         shader->heap_idx += align(sz, 4);
  43.         return ptr;
  44. }
  45.  
  46. struct ir3_shader * ir3_shader_create(void)
  47. {
  48.         return calloc(1, sizeof(struct ir3_shader));
  49. }
  50.  
  51. void ir3_shader_destroy(struct ir3_shader *shader)
  52. {
  53.         free(shader);
  54. }
  55.  
  56. #define iassert(cond) do { \
  57.         if (!(cond)) { \
  58.                 assert(cond); \
  59.                 return -1; \
  60.         } } while (0)
  61.  
  62. static uint32_t reg(struct ir3_register *reg, struct ir3_shader_info *info,
  63.                 uint32_t repeat, uint32_t valid_flags)
  64. {
  65.         reg_t val = { .dummy32 = 0 };
  66.  
  67.         assert(!(reg->flags & ~valid_flags));
  68.  
  69.         if (!(reg->flags & IR3_REG_R))
  70.                 repeat = 0;
  71.  
  72.         if (reg->flags & IR3_REG_IMMED) {
  73.                 val.iim_val = reg->iim_val;
  74.         } else {
  75.                 int8_t max = (reg->num + repeat) >> 2;
  76.  
  77.                 val.comp = reg->num & 0x3;
  78.                 val.num  = reg->num >> 2;
  79.  
  80.                 if (reg->flags & IR3_REG_CONST) {
  81.                         info->max_const = MAX2(info->max_const, max);
  82.                 } else if ((max != REG_A0) && (max != REG_P0)) {
  83.                         if (reg->flags & IR3_REG_HALF) {
  84.                                 info->max_half_reg = MAX2(info->max_half_reg, max);
  85.                         } else {
  86.                                 info->max_reg = MAX2(info->max_reg, max);
  87.                         }
  88.                 }
  89.         }
  90.  
  91.         return val.dummy32;
  92. }
  93.  
  94. static int emit_cat0(struct ir3_instruction *instr, void *ptr,
  95.                 struct ir3_shader_info *info)
  96. {
  97.         instr_cat0_t *cat0 = ptr;
  98.  
  99.         cat0->immed    = instr->cat0.immed;
  100.         cat0->repeat   = instr->repeat;
  101.         cat0->ss       = !!(instr->flags & IR3_INSTR_SS);
  102.         cat0->inv      = instr->cat0.inv;
  103.         cat0->comp     = instr->cat0.comp;
  104.         cat0->opc      = instr->opc;
  105.         cat0->jmp_tgt  = !!(instr->flags & IR3_INSTR_JP);
  106.         cat0->sync     = !!(instr->flags & IR3_INSTR_SY);
  107.         cat0->opc_cat  = 0;
  108.  
  109.         return 0;
  110. }
  111.  
  112. static uint32_t type_flags(type_t type)
  113. {
  114.         return (type_size(type) == 32) ? 0 : IR3_REG_HALF;
  115. }
  116.  
  117. static int emit_cat1(struct ir3_instruction *instr, void *ptr,
  118.                 struct ir3_shader_info *info)
  119. {
  120.         struct ir3_register *dst = instr->regs[0];
  121.         struct ir3_register *src = instr->regs[1];
  122.         instr_cat1_t *cat1 = ptr;
  123.  
  124.         iassert(instr->regs_count == 2);
  125.         iassert(!((dst->flags ^ type_flags(instr->cat1.dst_type)) & IR3_REG_HALF));
  126.         iassert((src->flags & IR3_REG_IMMED) ||
  127.                         !((src->flags ^ type_flags(instr->cat1.src_type)) & IR3_REG_HALF));
  128.  
  129.         if (src->flags & IR3_REG_IMMED) {
  130.                 cat1->iim_val = src->iim_val;
  131.                 cat1->src_im  = 1;
  132.         } else if (src->flags & IR3_REG_RELATIV) {
  133.                 cat1->off       = src->offset;
  134.                 cat1->src_rel   = 1;
  135.                 cat1->must_be_3 = 3;
  136.         } else {
  137.                 cat1->src  = reg(src, info, instr->repeat,
  138.                                 IR3_REG_IMMED | IR3_REG_RELATIV |
  139.                                 IR3_REG_R | IR3_REG_CONST | IR3_REG_HALF);
  140.         }
  141.  
  142.         cat1->dst      = reg(dst, info, instr->repeat,
  143.                         IR3_REG_RELATIV | IR3_REG_EVEN |
  144.                         IR3_REG_R | IR3_REG_POS_INF | IR3_REG_HALF);
  145.         cat1->repeat   = instr->repeat;
  146.         cat1->src_r    = !!(src->flags & IR3_REG_R);
  147.         cat1->ss       = !!(instr->flags & IR3_INSTR_SS);
  148.         cat1->dst_type = instr->cat1.dst_type;
  149.         cat1->dst_rel  = !!(dst->flags & IR3_REG_RELATIV);
  150.         cat1->src_type = instr->cat1.src_type;
  151.         cat1->src_c    = !!(src->flags & IR3_REG_CONST);
  152.         cat1->even     = !!(dst->flags & IR3_REG_EVEN);
  153.         cat1->pos_inf  = !!(dst->flags & IR3_REG_POS_INF);
  154.         cat1->jmp_tgt  = !!(instr->flags & IR3_INSTR_JP);
  155.         cat1->sync     = !!(instr->flags & IR3_INSTR_SY);
  156.         cat1->opc_cat  = 1;
  157.  
  158.         return 0;
  159. }
  160.  
  161. static int emit_cat2(struct ir3_instruction *instr, void *ptr,
  162.                 struct ir3_shader_info *info)
  163. {
  164.         struct ir3_register *dst = instr->regs[0];
  165.         struct ir3_register *src1 = instr->regs[1];
  166.         struct ir3_register *src2 = instr->regs[2];
  167.         instr_cat2_t *cat2 = ptr;
  168.  
  169.         iassert((instr->regs_count == 2) || (instr->regs_count == 3));
  170.  
  171.         cat2->src1     = reg(src1, info, instr->repeat,
  172.                         IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_IMMED |
  173.                         IR3_REG_NEGATE | IR3_REG_ABS | IR3_REG_R | IR3_REG_HALF);
  174.         cat2->src1_rel = !!(src1->flags & IR3_REG_RELATIV);
  175.         cat2->src1_c   = !!(src1->flags & IR3_REG_CONST);
  176.         cat2->src1_im  = !!(src1->flags & IR3_REG_IMMED);
  177.         cat2->src1_neg = !!(src1->flags & IR3_REG_NEGATE);
  178.         cat2->src1_abs = !!(src1->flags & IR3_REG_ABS);
  179.         cat2->src1_r   = !!(src1->flags & IR3_REG_R);
  180.  
  181.         if (src2) {
  182.                 iassert((src2->flags & IR3_REG_IMMED) ||
  183.                                 !((src1->flags ^ src2->flags) & IR3_REG_HALF));
  184.                 cat2->src2     = reg(src2, info, instr->repeat,
  185.                                 IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_IMMED |
  186.                                 IR3_REG_NEGATE | IR3_REG_ABS | IR3_REG_R | IR3_REG_HALF);
  187.                 cat2->src2_rel = !!(src2->flags & IR3_REG_RELATIV);
  188.                 cat2->src2_c   = !!(src2->flags & IR3_REG_CONST);
  189.                 cat2->src2_im  = !!(src2->flags & IR3_REG_IMMED);
  190.                 cat2->src2_neg = !!(src2->flags & IR3_REG_NEGATE);
  191.                 cat2->src2_abs = !!(src2->flags & IR3_REG_ABS);
  192.                 cat2->src2_r   = !!(src2->flags & IR3_REG_R);
  193.         }
  194.  
  195.         cat2->dst      = reg(dst, info, instr->repeat,
  196.                         IR3_REG_R | IR3_REG_EI | IR3_REG_HALF);
  197.         cat2->repeat   = instr->repeat;
  198.         cat2->ss       = !!(instr->flags & IR3_INSTR_SS);
  199.         cat2->ul       = !!(instr->flags & IR3_INSTR_UL);
  200.         cat2->dst_half = !!((src1->flags ^ dst->flags) & IR3_REG_HALF);
  201.         cat2->ei       = !!(dst->flags & IR3_REG_EI);
  202.         cat2->cond     = instr->cat2.condition;
  203.         cat2->full     = ! (src1->flags & IR3_REG_HALF);
  204.         cat2->opc      = instr->opc;
  205.         cat2->jmp_tgt  = !!(instr->flags & IR3_INSTR_JP);
  206.         cat2->sync     = !!(instr->flags & IR3_INSTR_SY);
  207.         cat2->opc_cat  = 2;
  208.  
  209.         return 0;
  210. }
  211.  
  212. static int emit_cat3(struct ir3_instruction *instr, void *ptr,
  213.                 struct ir3_shader_info *info)
  214. {
  215.         struct ir3_register *dst = instr->regs[0];
  216.         struct ir3_register *src1 = instr->regs[1];
  217.         struct ir3_register *src2 = instr->regs[2];
  218.         struct ir3_register *src3 = instr->regs[3];
  219.         instr_cat3_t *cat3 = ptr;
  220.         uint32_t src_flags = 0;
  221.  
  222.         switch (instr->opc) {
  223.         case OPC_MAD_F16:
  224.         case OPC_MAD_U16:
  225.         case OPC_MAD_S16:
  226.         case OPC_SEL_B16:
  227.         case OPC_SEL_S16:
  228.         case OPC_SEL_F16:
  229.         case OPC_SAD_S16:
  230.         case OPC_SAD_S32:  // really??
  231.                 src_flags |= IR3_REG_HALF;
  232.                 break;
  233.         default:
  234.                 break;
  235.         }
  236.  
  237.         iassert(instr->regs_count == 4);
  238.         iassert(!((src1->flags ^ src_flags) & IR3_REG_HALF));
  239.         iassert(!((src2->flags ^ src_flags) & IR3_REG_HALF));
  240.         iassert(!((src3->flags ^ src_flags) & IR3_REG_HALF));
  241.  
  242.         cat3->src1     = reg(src1, info, instr->repeat,
  243.                         IR3_REG_RELATIV | IR3_REG_CONST |
  244.                         IR3_REG_NEGATE | IR3_REG_R | IR3_REG_HALF);
  245.         cat3->src1_rel = !!(src1->flags & IR3_REG_RELATIV);
  246.         cat3->src1_c   = !!(src1->flags & IR3_REG_CONST);
  247.         cat3->src1_neg = !!(src1->flags & IR3_REG_NEGATE);
  248.         cat3->src1_r   = !!(src1->flags & IR3_REG_R);
  249.  
  250.         cat3->src2     = reg(src2, info, instr->repeat,
  251.                         IR3_REG_CONST | IR3_REG_NEGATE |
  252.                         IR3_REG_R | IR3_REG_HALF);
  253.         cat3->src2_c   = !!(src2->flags & IR3_REG_CONST);
  254.         cat3->src2_neg = !!(src2->flags & IR3_REG_NEGATE);
  255.         cat3->src2_r   = !!(src2->flags & IR3_REG_R);
  256.  
  257.         cat3->src3     = reg(src3, info, instr->repeat,
  258.                         IR3_REG_RELATIV | IR3_REG_CONST |
  259.                         IR3_REG_NEGATE | IR3_REG_R | IR3_REG_HALF);
  260.         cat3->src3_rel = !!(src3->flags & IR3_REG_RELATIV);
  261.         cat3->src3_c   = !!(src3->flags & IR3_REG_CONST);
  262.         cat3->src3_neg = !!(src3->flags & IR3_REG_NEGATE);
  263.         cat3->src3_r   = !!(src3->flags & IR3_REG_R);
  264.  
  265.         cat3->dst      = reg(dst, info, instr->repeat, IR3_REG_R | IR3_REG_HALF);
  266.         cat3->repeat   = instr->repeat;
  267.         cat3->ss       = !!(instr->flags & IR3_INSTR_SS);
  268.         cat3->ul       = !!(instr->flags & IR3_INSTR_UL);
  269.         cat3->dst_half = !!((src_flags ^ dst->flags) & IR3_REG_HALF);
  270.         cat3->opc      = instr->opc;
  271.         cat3->jmp_tgt  = !!(instr->flags & IR3_INSTR_JP);
  272.         cat3->sync     = !!(instr->flags & IR3_INSTR_SY);
  273.         cat3->opc_cat  = 3;
  274.  
  275.         return 0;
  276. }
  277.  
  278. static int emit_cat4(struct ir3_instruction *instr, void *ptr,
  279.                 struct ir3_shader_info *info)
  280. {
  281.         struct ir3_register *dst = instr->regs[0];
  282.         struct ir3_register *src = instr->regs[1];
  283.         instr_cat4_t *cat4 = ptr;
  284.  
  285.         iassert(instr->regs_count == 2);
  286.  
  287.         cat4->src      = reg(src, info, instr->repeat,
  288.                         IR3_REG_RELATIV | IR3_REG_CONST | IR3_REG_IMMED |
  289.                         IR3_REG_NEGATE | IR3_REG_ABS | IR3_REG_R |
  290.                         IR3_REG_HALF);
  291.         cat4->src_rel  = !!(src->flags & IR3_REG_RELATIV);
  292.         cat4->src_c    = !!(src->flags & IR3_REG_CONST);
  293.         cat4->src_im   = !!(src->flags & IR3_REG_IMMED);
  294.         cat4->src_neg  = !!(src->flags & IR3_REG_NEGATE);
  295.         cat4->src_abs  = !!(src->flags & IR3_REG_ABS);
  296.         cat4->src_r    = !!(src->flags & IR3_REG_R);
  297.  
  298.         cat4->dst      = reg(dst, info, instr->repeat, IR3_REG_R | IR3_REG_HALF);
  299.         cat4->repeat   = instr->repeat;
  300.         cat4->ss       = !!(instr->flags & IR3_INSTR_SS);
  301.         cat4->ul       = !!(instr->flags & IR3_INSTR_UL);
  302.         cat4->dst_half = !!((src->flags ^ dst->flags) & IR3_REG_HALF);
  303.         cat4->full     = ! (src->flags & IR3_REG_HALF);
  304.         cat4->opc      = instr->opc;
  305.         cat4->jmp_tgt  = !!(instr->flags & IR3_INSTR_JP);
  306.         cat4->sync     = !!(instr->flags & IR3_INSTR_SY);
  307.         cat4->opc_cat  = 4;
  308.  
  309.         return 0;
  310. }
  311.  
  312. static int emit_cat5(struct ir3_instruction *instr, void *ptr,
  313.                 struct ir3_shader_info *info)
  314. {
  315.         struct ir3_register *dst = instr->regs[0];
  316.         struct ir3_register *src1 = instr->regs[1];
  317.         struct ir3_register *src2 = instr->regs[2];
  318.         struct ir3_register *src3 = instr->regs[3];
  319.         instr_cat5_t *cat5 = ptr;
  320.  
  321.         iassert(!((dst->flags ^ type_flags(instr->cat5.type)) & IR3_REG_HALF));
  322.  
  323.         if (src1) {
  324.                 cat5->full = ! (src1->flags & IR3_REG_HALF);
  325.                 cat5->src1 = reg(src1, info, instr->repeat, IR3_REG_HALF);
  326.         }
  327.  
  328.  
  329.         if (instr->flags & IR3_INSTR_S2EN) {
  330.                 if (src2) {
  331.                         iassert(!((src1->flags ^ src2->flags) & IR3_REG_HALF));
  332.                         cat5->s2en.src2 = reg(src2, info, instr->repeat, IR3_REG_HALF);
  333.                 }
  334.                 if (src3) {
  335.                         iassert(src3->flags & IR3_REG_HALF);
  336.                         cat5->s2en.src3 = reg(src3, info, instr->repeat, IR3_REG_HALF);
  337.                 }
  338.                 iassert(!(instr->cat5.samp | instr->cat5.tex));
  339.         } else {
  340.                 iassert(!src3);
  341.                 if (src2) {
  342.                         iassert(!((src1->flags ^ src2->flags) & IR3_REG_HALF));
  343.                         cat5->norm.src2 = reg(src2, info, instr->repeat, IR3_REG_HALF);
  344.                 }
  345.                 cat5->norm.samp = instr->cat5.samp;
  346.                 cat5->norm.tex  = instr->cat5.tex;
  347.         }
  348.  
  349.         cat5->dst      = reg(dst, info, instr->repeat, IR3_REG_R | IR3_REG_HALF);
  350.         cat5->wrmask   = dst->wrmask;
  351.         cat5->type     = instr->cat5.type;
  352.         cat5->is_3d    = !!(instr->flags & IR3_INSTR_3D);
  353.         cat5->is_a     = !!(instr->flags & IR3_INSTR_A);
  354.         cat5->is_s     = !!(instr->flags & IR3_INSTR_S);
  355.         cat5->is_s2en  = !!(instr->flags & IR3_INSTR_S2EN);
  356.         cat5->is_o     = !!(instr->flags & IR3_INSTR_O);
  357.         cat5->is_p     = !!(instr->flags & IR3_INSTR_P);
  358.         cat5->opc      = instr->opc;
  359.         cat5->jmp_tgt  = !!(instr->flags & IR3_INSTR_JP);
  360.         cat5->sync     = !!(instr->flags & IR3_INSTR_SY);
  361.         cat5->opc_cat  = 5;
  362.  
  363.         return 0;
  364. }
  365.  
  366. static int emit_cat6(struct ir3_instruction *instr, void *ptr,
  367.                 struct ir3_shader_info *info)
  368. {
  369.         struct ir3_register *dst = instr->regs[0];
  370.         struct ir3_register *src = instr->regs[1];
  371.         instr_cat6_t *cat6 = ptr;
  372.  
  373.         iassert(instr->regs_count == 2);
  374.  
  375.         switch (instr->opc) {
  376.         /* load instructions: */
  377.         case OPC_LDG:
  378.         case OPC_LDP:
  379.         case OPC_LDL:
  380.         case OPC_LDLW:
  381.         case OPC_LDLV:
  382.         case OPC_PREFETCH: {
  383.                 instr_cat6a_t *cat6a = ptr;
  384.  
  385.                 iassert(!((dst->flags ^ type_flags(instr->cat6.type)) & IR3_REG_HALF));
  386.  
  387.                 cat6a->must_be_one1  = 1;
  388.                 cat6a->must_be_one2  = 1;
  389.                 cat6a->off = instr->cat6.offset;
  390.                 cat6a->src = reg(src, info, instr->repeat, 0);
  391.                 cat6a->dst = reg(dst, info, instr->repeat, IR3_REG_R | IR3_REG_HALF);
  392.                 break;
  393.         }
  394.         /* store instructions: */
  395.         case OPC_STG:
  396.         case OPC_STP:
  397.         case OPC_STL:
  398.         case OPC_STLW:
  399.         case OPC_STI: {
  400.                 instr_cat6b_t *cat6b = ptr;
  401.                 uint32_t src_flags = type_flags(instr->cat6.type);
  402.                 uint32_t dst_flags = (instr->opc == OPC_STI) ? IR3_REG_HALF : 0;
  403.  
  404.                 iassert(!((src->flags ^ src_flags) & IR3_REG_HALF));
  405.  
  406.                 cat6b->must_be_one1  = 1;
  407.                 cat6b->must_be_one2  = 1;
  408.                 cat6b->src    = reg(src, info, instr->repeat, src_flags);
  409.                 cat6b->off_hi = instr->cat6.offset >> 8;
  410.                 cat6b->off    = instr->cat6.offset;
  411.                 cat6b->dst    = reg(dst, info, instr->repeat, IR3_REG_R | dst_flags);
  412.  
  413.                 break;
  414.         }
  415.         default:
  416.                 // TODO
  417.                 break;
  418.         }
  419.  
  420.         cat6->iim_val  = instr->cat6.iim_val;
  421.         cat6->type     = instr->cat6.type;
  422.         cat6->opc      = instr->opc;
  423.         cat6->jmp_tgt  = !!(instr->flags & IR3_INSTR_JP);
  424.         cat6->sync     = !!(instr->flags & IR3_INSTR_SY);
  425.         cat6->opc_cat  = 6;
  426.  
  427.         return 0;
  428. }
  429.  
  430. static int (*emit[])(struct ir3_instruction *instr, void *ptr,
  431.                 struct ir3_shader_info *info) = {
  432.         emit_cat0, emit_cat1, emit_cat2, emit_cat3, emit_cat4, emit_cat5, emit_cat6,
  433. };
  434.  
  435. void * ir3_shader_assemble(struct ir3_shader *shader, struct ir3_shader_info *info)
  436. {
  437.         uint32_t *ptr, *dwords;
  438.         uint32_t i;
  439.  
  440.         info->max_reg       = -1;
  441.         info->max_half_reg  = -1;
  442.         info->max_const     = -1;
  443.  
  444.         /* need a integer number of instruction "groups" (sets of four
  445.          * instructions), so pad out w/ NOPs if needed:
  446.          */
  447.         while (shader->instrs_count != align(shader->instrs_count, 4))
  448.                 ir3_instr_create(shader, 0, OPC_NOP);
  449.  
  450.         /* each instruction is 64bits: */
  451.         info->sizedwords = 2 * shader->instrs_count;
  452.  
  453.         ptr = dwords = calloc(1, 4 * info->sizedwords);
  454.  
  455.         for (i = 0; i < shader->instrs_count; i++) {
  456.                 struct ir3_instruction *instr = shader->instrs[i];
  457.                 int ret = emit[instr->category](instr, dwords, info);
  458.                 if (ret)
  459.                         goto fail;
  460.                 dwords += 2;
  461.         }
  462.  
  463.         return ptr;
  464.  
  465. fail:
  466.         free(ptr);
  467.         return NULL;
  468. }
  469.  
  470. static struct ir3_register * reg_create(struct ir3_shader *shader,
  471.                 int num, int flags)
  472. {
  473.         struct ir3_register *reg =
  474.                         ir3_alloc(shader, sizeof(struct ir3_register));
  475.         reg->flags = flags;
  476.         reg->num = num;
  477.         return reg;
  478. }
  479.  
  480. static void insert_instr(struct ir3_shader *shader,
  481.                 struct ir3_instruction *instr)
  482. {
  483.         assert(shader->instrs_count < ARRAY_SIZE(shader->instrs));
  484.         shader->instrs[shader->instrs_count++] = instr;
  485. }
  486.  
  487. struct ir3_instruction * ir3_instr_create(struct ir3_shader *shader,
  488.                 int category, opc_t opc)
  489. {
  490.         struct ir3_instruction *instr =
  491.                         ir3_alloc(shader, sizeof(struct ir3_instruction));
  492.         instr->shader = shader;
  493.         instr->category = category;
  494.         instr->opc = opc;
  495.         insert_instr(shader, instr);
  496.         return instr;
  497. }
  498.  
  499. struct ir3_instruction * ir3_instr_clone(struct ir3_instruction *instr)
  500. {
  501.         struct ir3_instruction *new_instr =
  502.                         ir3_alloc(instr->shader, sizeof(struct ir3_instruction));
  503.         unsigned i;
  504.  
  505.         *new_instr = *instr;
  506.         insert_instr(instr->shader, new_instr);
  507.  
  508.         /* clone registers: */
  509.         new_instr->regs_count = 0;
  510.         for (i = 0; i < instr->regs_count; i++) {
  511.                 struct ir3_register *reg = instr->regs[i];
  512.                 struct ir3_register *new_reg =
  513.                                 ir3_reg_create(new_instr, reg->num, reg->flags);
  514.                 *new_reg = *reg;
  515.         }
  516.  
  517.         return new_instr;
  518. }
  519.  
  520. struct ir3_register * ir3_reg_create(struct ir3_instruction *instr,
  521.                 int num, int flags)
  522. {
  523.         struct ir3_register *reg = reg_create(instr->shader, num, flags);
  524.         assert(instr->regs_count < ARRAY_SIZE(instr->regs));
  525.         instr->regs[instr->regs_count++] = reg;
  526.         return reg;
  527. }
  528.