Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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@lunarg.com>
  26.  */
  27.  
  28. #include "pipe/p_shader_tokens.h"
  29. #include "toy_compiler.h"
  30. #include "toy_tgsi.h"
  31. #include "toy_helpers.h"
  32. #include "toy_legalize.h"
  33.  
  34. /**
  35.  * Lower an instruction to GEN6_OPCODE_SEND(C).
  36.  */
  37. void
  38. toy_compiler_lower_to_send(struct toy_compiler *tc, struct toy_inst *inst,
  39.                            bool sendc, unsigned sfid)
  40. {
  41.    assert(inst->opcode >= 128);
  42.  
  43.    inst->opcode = (sendc) ? GEN6_OPCODE_SENDC : GEN6_OPCODE_SEND;
  44.  
  45.    /* thread control is reserved */
  46.    assert(inst->thread_ctrl == 0);
  47.  
  48.    assert(inst->cond_modifier == GEN6_COND_NONE);
  49.    inst->cond_modifier = sfid;
  50. }
  51.  
  52. static int
  53. math_op_to_func(unsigned opcode)
  54. {
  55.    switch (opcode) {
  56.    case TOY_OPCODE_INV:    return GEN6_MATH_INV;
  57.    case TOY_OPCODE_LOG:    return GEN6_MATH_LOG;
  58.    case TOY_OPCODE_EXP:    return GEN6_MATH_EXP;
  59.    case TOY_OPCODE_SQRT:   return GEN6_MATH_SQRT;
  60.    case TOY_OPCODE_RSQ:    return GEN6_MATH_RSQ;
  61.    case TOY_OPCODE_SIN:    return GEN6_MATH_SIN;
  62.    case TOY_OPCODE_COS:    return GEN6_MATH_COS;
  63.    case TOY_OPCODE_FDIV:   return GEN6_MATH_FDIV;
  64.    case TOY_OPCODE_POW:    return GEN6_MATH_POW;
  65.    case TOY_OPCODE_INT_DIV_QUOTIENT:   return GEN6_MATH_INT_DIV_QUOTIENT;
  66.    case TOY_OPCODE_INT_DIV_REMAINDER:  return GEN6_MATH_INT_DIV_REMAINDER;
  67.    default:
  68.        assert(!"unknown math opcode");
  69.        return -1;
  70.    }
  71. }
  72.  
  73. /**
  74.  * Lower virtual math opcodes to GEN6_OPCODE_MATH.
  75.  */
  76. void
  77. toy_compiler_lower_math(struct toy_compiler *tc, struct toy_inst *inst)
  78. {
  79.    struct toy_dst tmp;
  80.    int i;
  81.  
  82.    /* see commit 250770b74d33bb8625c780a74a89477af033d13a */
  83.    for (i = 0; i < Elements(inst->src); i++) {
  84.       if (tsrc_is_null(inst->src[i]))
  85.          break;
  86.  
  87.       /* no swizzling in align1 */
  88.       /* XXX how about source modifiers? */
  89.       if (toy_file_is_virtual(inst->src[i].file) &&
  90.           !tsrc_is_swizzled(inst->src[i]) &&
  91.           !inst->src[i].absolute &&
  92.           !inst->src[i].negate)
  93.          continue;
  94.  
  95.       tmp = tdst_type(tc_alloc_tmp(tc), inst->src[i].type);
  96.       tc_MOV(tc, tmp, inst->src[i]);
  97.       inst->src[i] = tsrc_from(tmp);
  98.    }
  99.  
  100.    /* FC[0:3] */
  101.    assert(inst->cond_modifier == GEN6_COND_NONE);
  102.    inst->cond_modifier = math_op_to_func(inst->opcode);
  103.    /* FC[4:5] */
  104.    assert(inst->thread_ctrl == 0);
  105.    inst->thread_ctrl = 0;
  106.  
  107.    inst->opcode = GEN6_OPCODE_MATH;
  108.    tc_move_inst(tc, inst);
  109.  
  110.    /* no writemask in align1 */
  111.    if (inst->dst.writemask != TOY_WRITEMASK_XYZW) {
  112.       struct toy_dst dst = inst->dst;
  113.       struct toy_inst *inst2;
  114.  
  115.       tmp = tc_alloc_tmp(tc);
  116.       tmp.type = inst->dst.type;
  117.       inst->dst = tmp;
  118.  
  119.       inst2 = tc_MOV(tc, dst, tsrc_from(tmp));
  120.       inst2->pred_ctrl = inst->pred_ctrl;
  121.    }
  122. }
  123.  
  124. static uint32_t
  125. absolute_imm(uint32_t imm32, enum toy_type type)
  126. {
  127.    union fi val = { .ui = imm32 };
  128.  
  129.    switch (type) {
  130.    case TOY_TYPE_F:
  131.       val.f = fabs(val.f);
  132.       break;
  133.    case TOY_TYPE_D:
  134.       if (val.i < 0)
  135.          val.i = -val.i;
  136.       break;
  137.    case TOY_TYPE_W:
  138.       if ((int16_t) (val.ui & 0xffff) < 0)
  139.          val.i = -((int16_t) (val.ui & 0xffff));
  140.       break;
  141.    case TOY_TYPE_V:
  142.       assert(!"cannot take absoulte of immediates of type V");
  143.       break;
  144.    default:
  145.       break;
  146.    }
  147.  
  148.    return val.ui;
  149. }
  150.  
  151. static uint32_t
  152. negate_imm(uint32_t imm32, enum toy_type type)
  153. {
  154.    union fi val = { .ui = imm32 };
  155.  
  156.    switch (type) {
  157.    case TOY_TYPE_F:
  158.       val.f = -val.f;
  159.       break;
  160.    case TOY_TYPE_D:
  161.    case TOY_TYPE_UD:
  162.       val.i = -val.i;
  163.       break;
  164.    case TOY_TYPE_W:
  165.    case TOY_TYPE_UW:
  166.       val.i = -((int16_t) (val.ui & 0xffff));
  167.       break;
  168.    default:
  169.       assert(!"negate immediate of unknown type");
  170.       break;
  171.    }
  172.  
  173.    return val.ui;
  174. }
  175.  
  176. static void
  177. validate_imm(struct toy_compiler *tc, struct toy_inst *inst)
  178. {
  179.    bool move_inst = false;
  180.    int i;
  181.  
  182.    for (i = 0; i < Elements(inst->src); i++) {
  183.       struct toy_dst tmp;
  184.  
  185.       if (tsrc_is_null(inst->src[i]))
  186.          break;
  187.  
  188.       if (inst->src[i].file != TOY_FILE_IMM)
  189.          continue;
  190.  
  191.       if (inst->src[i].absolute) {
  192.          inst->src[i].val32 =
  193.             absolute_imm(inst->src[i].val32, inst->src[i].type);
  194.          inst->src[i].absolute = false;
  195.       }
  196.  
  197.       if (inst->src[i].negate) {
  198.          inst->src[i].val32 =
  199.             negate_imm(inst->src[i].val32, inst->src[i].type);
  200.          inst->src[i].negate = false;
  201.       }
  202.  
  203.       /* this is the last operand */
  204.       if (i + 1 == Elements(inst->src) || tsrc_is_null(inst->src[i + 1]))
  205.          break;
  206.  
  207.       /* need to use a temp if this imm is not the last operand */
  208.       /* TODO we should simply swap the operands if the op is commutative */
  209.       tmp = tc_alloc_tmp(tc);
  210.       tmp = tdst_type(tmp, inst->src[i].type);
  211.       tc_MOV(tc, tmp, inst->src[i]);
  212.       inst->src[i] = tsrc_from(tmp);
  213.  
  214.       move_inst = true;
  215.    }
  216.  
  217.    if (move_inst)
  218.       tc_move_inst(tc, inst);
  219. }
  220.  
  221. static void
  222. lower_opcode_mul(struct toy_compiler *tc, struct toy_inst *inst)
  223. {
  224.    const enum toy_type inst_type = inst->dst.type;
  225.    const struct toy_dst acc0 =
  226.       tdst_type(tdst(TOY_FILE_ARF, GEN6_ARF_ACC0, 0), inst_type);
  227.    struct toy_inst *inst2;
  228.  
  229.    /* only need to take care of integer multiplications */
  230.    if (inst_type != TOY_TYPE_UD && inst_type != TOY_TYPE_D)
  231.       return;
  232.  
  233.    /* acc0 = (src0 & 0x0000ffff) * src1 */
  234.    tc_MUL(tc, acc0, inst->src[0], inst->src[1]);
  235.  
  236.    /* acc0 = (src0 & 0xffff0000) * src1 + acc0 */
  237.    inst2 = tc_add2(tc, GEN6_OPCODE_MACH, tdst_type(tdst_null(), inst_type),
  238.          inst->src[0], inst->src[1]);
  239.    inst2->acc_wr_ctrl = true;
  240.  
  241.    /* dst = acc0 & 0xffffffff */
  242.    tc_MOV(tc, inst->dst, tsrc_from(acc0));
  243.  
  244.    tc_discard_inst(tc, inst);
  245. }
  246.  
  247. static void
  248. lower_opcode_mac(struct toy_compiler *tc, struct toy_inst *inst)
  249. {
  250.    const enum toy_type inst_type = inst->dst.type;
  251.  
  252.    if (inst_type != TOY_TYPE_UD && inst_type != TOY_TYPE_D) {
  253.       const struct toy_dst acc0 = tdst(TOY_FILE_ARF, GEN6_ARF_ACC0, 0);
  254.  
  255.       tc_MOV(tc, acc0, inst->src[2]);
  256.       inst->src[2] = tsrc_null();
  257.       tc_move_inst(tc, inst);
  258.    }
  259.    else {
  260.       struct toy_dst tmp = tdst_type(tc_alloc_tmp(tc), inst_type);
  261.       struct toy_inst *inst2;
  262.  
  263.       inst2 = tc_MUL(tc, tmp, inst->src[0], inst->src[1]);
  264.       lower_opcode_mul(tc, inst2);
  265.  
  266.       tc_ADD(tc, inst->dst, tsrc_from(tmp), inst->src[2]);
  267.  
  268.       tc_discard_inst(tc, inst);
  269.    }
  270. }
  271.  
  272. /**
  273.  * Legalize the instructions for register allocation.
  274.  */
  275. void
  276. toy_compiler_legalize_for_ra(struct toy_compiler *tc)
  277. {
  278.    struct toy_inst *inst;
  279.  
  280.    tc_head(tc);
  281.    while ((inst = tc_next(tc)) != NULL) {
  282.       switch (inst->opcode) {
  283.       case GEN6_OPCODE_MAC:
  284.          lower_opcode_mac(tc, inst);
  285.          break;
  286.       case GEN6_OPCODE_MAD:
  287.          /* TODO operands must be floats */
  288.          break;
  289.       case GEN6_OPCODE_MUL:
  290.          lower_opcode_mul(tc, inst);
  291.          break;
  292.       default:
  293.          if (inst->opcode > TOY_OPCODE_LAST_HW)
  294.             tc_fail(tc, "internal opcodes not lowered");
  295.       }
  296.    }
  297.  
  298.    /* loop again as the previous pass may add new instructions */
  299.    tc_head(tc);
  300.    while ((inst = tc_next(tc)) != NULL) {
  301.       validate_imm(tc, inst);
  302.    }
  303. }
  304.  
  305. static void
  306. patch_while_jip(struct toy_compiler *tc, struct toy_inst *inst)
  307. {
  308.    struct toy_inst *inst2;
  309.    int nest_level, dist;
  310.  
  311.    nest_level = 0;
  312.    dist = -1;
  313.  
  314.    /* search backward */
  315.    LIST_FOR_EACH_ENTRY_FROM_REV(inst2, inst->list.prev,
  316.          &tc->instructions, list) {
  317.       if (inst2->marker) {
  318.          if (inst2->opcode == TOY_OPCODE_DO) {
  319.             if (nest_level) {
  320.                nest_level--;
  321.             }
  322.             else {
  323.                /* the following instruction */
  324.                dist++;
  325.                break;
  326.             }
  327.          }
  328.  
  329.          continue;
  330.       }
  331.  
  332.       if (inst2->opcode == GEN6_OPCODE_WHILE)
  333.          nest_level++;
  334.  
  335.       dist--;
  336.    }
  337.  
  338.    if (ilo_dev_gen(tc->dev) >= ILO_GEN(8))
  339.       inst->src[1] = tsrc_imm_d(dist * 16);
  340.    else if (ilo_dev_gen(tc->dev) >= ILO_GEN(7))
  341.       inst->src[1] = tsrc_imm_w(dist * 2);
  342.    else
  343.       inst->dst = tdst_imm_w(dist * 2);
  344. }
  345.  
  346. static void
  347. patch_if_else_jip(struct toy_compiler *tc, struct toy_inst *inst)
  348. {
  349.    struct toy_inst *inst2;
  350.    int nest_level, dist;
  351.    int jip, uip;
  352.  
  353.    nest_level = 0;
  354.    dist = 1;
  355.    jip = 0;
  356.    uip = 0;
  357.  
  358.    /* search forward */
  359.    LIST_FOR_EACH_ENTRY_FROM(inst2, inst->list.next, &tc->instructions, list) {
  360.       if (inst2->marker)
  361.          continue;
  362.  
  363.       if (inst2->opcode == GEN6_OPCODE_ENDIF) {
  364.          if (nest_level) {
  365.             nest_level--;
  366.          }
  367.          else {
  368.             uip = dist * 2;
  369.             if (!jip)
  370.                jip = uip;
  371.             break;
  372.          }
  373.       }
  374.       else if (inst2->opcode == GEN6_OPCODE_ELSE &&
  375.                inst->opcode == GEN6_OPCODE_IF) {
  376.          if (!nest_level) {
  377.             /* the following instruction */
  378.             jip = (dist + 1) * 2;
  379.  
  380.             if (ilo_dev_gen(tc->dev) == ILO_GEN(6)) {
  381.                uip = jip;
  382.                break;
  383.             }
  384.          }
  385.       }
  386.       else if (inst2->opcode == GEN6_OPCODE_IF) {
  387.          nest_level++;
  388.       }
  389.  
  390.       dist++;
  391.    }
  392.  
  393.    if (ilo_dev_gen(tc->dev) >= ILO_GEN(8)) {
  394.       inst->dst.type = TOY_TYPE_D;
  395.       inst->src[0] = tsrc_imm_d(uip * 8);
  396.       inst->src[1] = tsrc_imm_d(jip * 8);
  397.    } else if (ilo_dev_gen(tc->dev) >= ILO_GEN(7)) {
  398.       /* what should the type be? */
  399.       inst->dst.type = TOY_TYPE_D;
  400.       inst->src[0].type = TOY_TYPE_D;
  401.       inst->src[1] = tsrc_imm_d(uip << 16 | jip);
  402.    } else {
  403.       inst->dst = tdst_imm_w(jip);
  404.    }
  405. }
  406.  
  407. static void
  408. patch_endif_jip(struct toy_compiler *tc, struct toy_inst *inst)
  409. {
  410.    struct toy_inst *inst2;
  411.    bool found = false;
  412.    int dist = 1;
  413.  
  414.    /* search forward for instructions that may enable channels */
  415.    LIST_FOR_EACH_ENTRY_FROM(inst2, inst->list.next, &tc->instructions, list) {
  416.       if (inst2->marker)
  417.          continue;
  418.  
  419.       switch (inst2->opcode) {
  420.       case GEN6_OPCODE_ENDIF:
  421.       case GEN6_OPCODE_ELSE:
  422.       case GEN6_OPCODE_WHILE:
  423.          found = true;
  424.          break;
  425.       default:
  426.          break;
  427.       }
  428.  
  429.       if (found)
  430.          break;
  431.  
  432.       dist++;
  433.    }
  434.  
  435.    /* should we set dist to (dist - 1) or 1? */
  436.    if (!found)
  437.       dist = 1;
  438.  
  439.    if (ilo_dev_gen(tc->dev) >= ILO_GEN(8))
  440.       inst->src[1] = tsrc_imm_d(dist * 16);
  441.    else if (ilo_dev_gen(tc->dev) >= ILO_GEN(7))
  442.       inst->src[1] = tsrc_imm_w(dist * 2);
  443.    else
  444.       inst->dst = tdst_imm_w(dist * 2);
  445. }
  446.  
  447. static void
  448. patch_break_continue_jip(struct toy_compiler *tc, struct toy_inst *inst)
  449. {
  450.    struct toy_inst *inst2, *inst3;
  451.    int nest_level, dist, jip, uip;
  452.  
  453.    nest_level = 0;
  454.    dist = 1;
  455.    jip = 1 * 2;
  456.    uip = 1 * 2;
  457.  
  458.    /* search forward */
  459.    LIST_FOR_EACH_ENTRY_FROM(inst2, inst->list.next, &tc->instructions, list) {
  460.       if (inst2->marker) {
  461.          if (inst2->opcode == TOY_OPCODE_DO)
  462.             nest_level++;
  463.          continue;
  464.       }
  465.  
  466.       if (inst2->opcode == GEN6_OPCODE_ELSE ||
  467.           inst2->opcode == GEN6_OPCODE_ENDIF ||
  468.           inst2->opcode == GEN6_OPCODE_WHILE) {
  469.          jip = dist * 2;
  470.          break;
  471.       }
  472.  
  473.       dist++;
  474.    }
  475.  
  476.    /* go on to determine uip */
  477.    inst3 = inst2;
  478.    LIST_FOR_EACH_ENTRY_FROM(inst2, &inst3->list, &tc->instructions, list) {
  479.       if (inst2->marker) {
  480.          if (inst2->opcode == TOY_OPCODE_DO)
  481.             nest_level++;
  482.          continue;
  483.       }
  484.  
  485.       if (inst2->opcode == GEN6_OPCODE_WHILE) {
  486.          if (nest_level) {
  487.             nest_level--;
  488.          }
  489.          else {
  490.             /* the following instruction */
  491.             if (ilo_dev_gen(tc->dev) == ILO_GEN(6) &&
  492.                 inst->opcode == GEN6_OPCODE_BREAK)
  493.                dist++;
  494.  
  495.             uip = dist * 2;
  496.             break;
  497.          }
  498.       }
  499.  
  500.       dist++;
  501.    }
  502.  
  503.    /* should the type be D or W? */
  504.    inst->dst.type = TOY_TYPE_D;
  505.    if (ilo_dev_gen(tc->dev) >= ILO_GEN(8)) {
  506.       inst->src[0] = tsrc_imm_d(uip * 8);
  507.       inst->src[1] = tsrc_imm_d(jip * 8);
  508.    } else {
  509.       inst->src[0].type = TOY_TYPE_D;
  510.       inst->src[1] = tsrc_imm_d(uip << 16 | jip);
  511.    }
  512. }
  513.  
  514. /**
  515.  * Legalize the instructions for assembling.
  516.  */
  517. void
  518. toy_compiler_legalize_for_asm(struct toy_compiler *tc)
  519. {
  520.    struct toy_inst *inst;
  521.    int pc = 0;
  522.  
  523.    tc_head(tc);
  524.    while ((inst = tc_next(tc)) != NULL) {
  525.       int i;
  526.  
  527.       pc++;
  528.  
  529.       /*
  530.        * From the Sandy Bridge PRM, volume 4 part 2, page 112:
  531.        *
  532.        *     "Specifically, for instructions with a single source, it only
  533.        *      uses the first source operand <src0>. In this case, the second
  534.        *      source operand <src1> must be set to null and also with the same
  535.        *      type as the first source operand <src0>.  It is a special case
  536.        *      when <src0> is an immediate, as an immediate <src0> uses DW3 of
  537.        *      the instruction word, which is normally used by <src1>.  In this
  538.        *      case, <src1> must be programmed with register file ARF and the
  539.        *      same data type as <src0>."
  540.        *
  541.        * Since we already fill unused operands with null, we only need to take
  542.        * care of the type.
  543.        */
  544.       if (tsrc_is_null(inst->src[1]))
  545.          inst->src[1].type = inst->src[0].type;
  546.  
  547.       switch (inst->opcode) {
  548.       case GEN6_OPCODE_MATH:
  549.          /* math does not support align16 nor exec_size > 8 */
  550.          inst->access_mode = GEN6_ALIGN_1;
  551.  
  552.          if (inst->exec_size == GEN6_EXECSIZE_16) {
  553.             /*
  554.              * From the Ivy Bridge PRM, volume 4 part 3, page 192:
  555.              *
  556.              *     "INT DIV function does not support SIMD16."
  557.              */
  558.             if (ilo_dev_gen(tc->dev) < ILO_GEN(7) ||
  559.                 inst->cond_modifier == GEN6_MATH_INT_DIV_QUOTIENT ||
  560.                 inst->cond_modifier == GEN6_MATH_INT_DIV_REMAINDER) {
  561.                struct toy_inst *inst2;
  562.  
  563.                inst->exec_size = GEN6_EXECSIZE_8;
  564.                inst->qtr_ctrl = GEN6_QTRCTRL_1Q;
  565.  
  566.                inst2 = tc_duplicate_inst(tc, inst);
  567.                inst2->qtr_ctrl = GEN6_QTRCTRL_2Q;
  568.                inst2->dst = tdst_offset(inst2->dst, 1, 0);
  569.                inst2->src[0] = tsrc_offset(inst2->src[0], 1, 0);
  570.                if (!tsrc_is_null(inst2->src[1]))
  571.                   inst2->src[1] = tsrc_offset(inst2->src[1], 1, 0);
  572.  
  573.                pc++;
  574.             }
  575.          }
  576.          break;
  577.       case GEN6_OPCODE_IF:
  578.          if (ilo_dev_gen(tc->dev) >= ILO_GEN(7) &&
  579.              inst->cond_modifier != GEN6_COND_NONE) {
  580.             struct toy_inst *inst2;
  581.  
  582.             inst2 = tc_duplicate_inst(tc, inst);
  583.  
  584.             /* replace the original IF by CMP */
  585.             inst->opcode = GEN6_OPCODE_CMP;
  586.  
  587.             /* predicate control instead of condition modifier */
  588.             inst2->dst = tdst_null();
  589.             inst2->src[0] = tsrc_null();
  590.             inst2->src[1] = tsrc_null();
  591.             inst2->cond_modifier = GEN6_COND_NONE;
  592.             inst2->pred_ctrl = GEN6_PREDCTRL_NORMAL;
  593.  
  594.             pc++;
  595.          }
  596.          break;
  597.       default:
  598.          break;
  599.       }
  600.  
  601.       /* MRF to GRF */
  602.       if (ilo_dev_gen(tc->dev) >= ILO_GEN(7)) {
  603.          for (i = 0; i < Elements(inst->src); i++) {
  604.             if (inst->src[i].file != TOY_FILE_MRF)
  605.                continue;
  606.             else if (tsrc_is_null(inst->src[i]))
  607.                break;
  608.  
  609.             inst->src[i].file = TOY_FILE_GRF;
  610.          }
  611.  
  612.          if (inst->dst.file == TOY_FILE_MRF)
  613.             inst->dst.file = TOY_FILE_GRF;
  614.       }
  615.    }
  616.  
  617.    tc->num_instructions = pc;
  618.  
  619.    /* set JIP/UIP */
  620.    tc_head(tc);
  621.    while ((inst = tc_next(tc)) != NULL) {
  622.       switch (inst->opcode) {
  623.       case GEN6_OPCODE_IF:
  624.       case GEN6_OPCODE_ELSE:
  625.          patch_if_else_jip(tc, inst);
  626.          break;
  627.       case GEN6_OPCODE_ENDIF:
  628.          patch_endif_jip(tc, inst);
  629.          break;
  630.       case GEN6_OPCODE_WHILE:
  631.          patch_while_jip(tc, inst);
  632.          break;
  633.       case GEN6_OPCODE_BREAK:
  634.       case GEN6_OPCODE_CONT:
  635.          patch_break_continue_jip(tc, inst);
  636.          break;
  637.       default:
  638.          break;
  639.       }
  640.    }
  641. }
  642.