17118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu/*
27118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * Mesa 3-D graphics library
37118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu *
47118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * Copyright (C) 2012-2013 LunarG, Inc.
57118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu *
67118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * Permission is hereby granted, free of charge, to any person obtaining a
77118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * copy of this software and associated documentation files (the "Software"),
87118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * to deal in the Software without restriction, including without limitation
97118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * the rights to use, copy, modify, merge, publish, distribute, sublicense,
107118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * and/or sell copies of the Software, and to permit persons to whom the
117118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * Software is furnished to do so, subject to the following conditions:
127118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu *
137118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * The above copyright notice and this permission notice shall be included
147118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * in all copies or substantial portions of the Software.
157118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu *
167118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
177118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
197118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
207118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
217118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
227118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * DEALINGS IN THE SOFTWARE.
237118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu *
247118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * Authors:
257118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu *    Chia-I Wu <olv@lunarg.com>
267118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu */
277118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
287118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu#include "pipe/p_shader_tokens.h"
297118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu#include "toy_compiler.h"
307118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu#include "toy_tgsi.h"
317118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu#include "toy_helpers.h"
327118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu#include "toy_legalize.h"
337118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
347118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu/**
356c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu * Lower an instruction to GEN6_OPCODE_SEND(C).
367118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu */
377118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wuvoid
387118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wutoy_compiler_lower_to_send(struct toy_compiler *tc, struct toy_inst *inst,
397118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu                           bool sendc, unsigned sfid)
407118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
417118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   assert(inst->opcode >= 128);
427118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
436c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   inst->opcode = (sendc) ? GEN6_OPCODE_SENDC : GEN6_OPCODE_SEND;
447118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
457118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* thread control is reserved */
467118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   assert(inst->thread_ctrl == 0);
477118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
48b51b349942ffd22a12d578bee6ba5db60d88d1bdChia-I Wu   assert(inst->cond_modifier == GEN6_COND_NONE);
497118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   inst->cond_modifier = sfid;
507118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
517118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
527118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wustatic int
537118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wumath_op_to_func(unsigned opcode)
547118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
557118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   switch (opcode) {
566c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_INV:    return GEN6_MATH_INV;
576c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_LOG:    return GEN6_MATH_LOG;
586c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_EXP:    return GEN6_MATH_EXP;
596c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_SQRT:   return GEN6_MATH_SQRT;
606c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_RSQ:    return GEN6_MATH_RSQ;
616c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_SIN:    return GEN6_MATH_SIN;
626c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_COS:    return GEN6_MATH_COS;
636c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_FDIV:   return GEN6_MATH_FDIV;
646c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_POW:    return GEN6_MATH_POW;
656c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_INT_DIV_QUOTIENT:   return GEN6_MATH_INT_DIV_QUOTIENT;
666c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   case TOY_OPCODE_INT_DIV_REMAINDER:  return GEN6_MATH_INT_DIV_REMAINDER;
677118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   default:
687118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       assert(!"unknown math opcode");
697118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       return -1;
707118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
717118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
727118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
737118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu/**
746c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu * Lower virtual math opcodes to GEN6_OPCODE_MATH.
757118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu */
767118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wuvoid
777118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wutoy_compiler_lower_math(struct toy_compiler *tc, struct toy_inst *inst)
787118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
797118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   struct toy_dst tmp;
807118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   int i;
817118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
827118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* see commit 250770b74d33bb8625c780a74a89477af033d13a */
83e193c5dd59555cea56f5d72b4800a54cc77bc76dBrian Paul   for (i = 0; i < ARRAY_SIZE(inst->src); i++) {
847118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (tsrc_is_null(inst->src[i]))
857118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
867118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
877118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      /* no swizzling in align1 */
887118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      /* XXX how about source modifiers? */
897118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (toy_file_is_virtual(inst->src[i].file) &&
907118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu          !tsrc_is_swizzled(inst->src[i]) &&
917118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu          !inst->src[i].absolute &&
927118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu          !inst->src[i].negate)
937118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         continue;
947118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
957118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tmp = tdst_type(tc_alloc_tmp(tc), inst->src[i].type);
967118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tc_MOV(tc, tmp, inst->src[i]);
977118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->src[i] = tsrc_from(tmp);
987118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
997118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1007118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* FC[0:3] */
101b51b349942ffd22a12d578bee6ba5db60d88d1bdChia-I Wu   assert(inst->cond_modifier == GEN6_COND_NONE);
1027118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   inst->cond_modifier = math_op_to_func(inst->opcode);
1037118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* FC[4:5] */
1047118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   assert(inst->thread_ctrl == 0);
1057118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   inst->thread_ctrl = 0;
1067118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1076c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   inst->opcode = GEN6_OPCODE_MATH;
1087118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   tc_move_inst(tc, inst);
1097118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1107118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* no writemask in align1 */
1117118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   if (inst->dst.writemask != TOY_WRITEMASK_XYZW) {
1127118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      struct toy_dst dst = inst->dst;
1137118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      struct toy_inst *inst2;
1147118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1157118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tmp = tc_alloc_tmp(tc);
1167118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tmp.type = inst->dst.type;
1177118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->dst = tmp;
1187118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1197118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst2 = tc_MOV(tc, dst, tsrc_from(tmp));
1207118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst2->pred_ctrl = inst->pred_ctrl;
1217118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
1227118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
1237118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1247118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wustatic uint32_t
1257118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wuabsolute_imm(uint32_t imm32, enum toy_type type)
1267118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
1277118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   union fi val = { .ui = imm32 };
1287118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1297118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   switch (type) {
1307118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   case TOY_TYPE_F:
1317118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      val.f = fabs(val.f);
1327118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      break;
1337118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   case TOY_TYPE_D:
1347118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (val.i < 0)
1357118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         val.i = -val.i;
1367118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      break;
1377118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   case TOY_TYPE_W:
1387118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if ((int16_t) (val.ui & 0xffff) < 0)
1397118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         val.i = -((int16_t) (val.ui & 0xffff));
1407118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      break;
1417118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   case TOY_TYPE_V:
1427118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      assert(!"cannot take absoulte of immediates of type V");
1437118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      break;
1447118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   default:
1457118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      break;
1467118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
1477118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1487118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   return val.ui;
1497118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
1507118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1517118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wustatic uint32_t
1527118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wunegate_imm(uint32_t imm32, enum toy_type type)
1537118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
1547118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   union fi val = { .ui = imm32 };
1557118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1567118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   switch (type) {
1577118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   case TOY_TYPE_F:
1587118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      val.f = -val.f;
1597118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      break;
1607118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   case TOY_TYPE_D:
1617118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   case TOY_TYPE_UD:
1627118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      val.i = -val.i;
1637118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      break;
1647118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   case TOY_TYPE_W:
1657118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   case TOY_TYPE_UW:
1667118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      val.i = -((int16_t) (val.ui & 0xffff));
1677118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      break;
1687118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   default:
1697118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      assert(!"negate immediate of unknown type");
1707118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      break;
1717118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
1727118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1737118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   return val.ui;
1747118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
1757118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1767118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wustatic void
1777118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wuvalidate_imm(struct toy_compiler *tc, struct toy_inst *inst)
1787118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
1797118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   bool move_inst = false;
1807118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   int i;
1817118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
182e193c5dd59555cea56f5d72b4800a54cc77bc76dBrian Paul   for (i = 0; i < ARRAY_SIZE(inst->src); i++) {
1837118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      struct toy_dst tmp;
1847118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1857118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (tsrc_is_null(inst->src[i]))
1867118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
1877118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1887118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (inst->src[i].file != TOY_FILE_IMM)
1897118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         continue;
1907118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1917118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (inst->src[i].absolute) {
1927118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         inst->src[i].val32 =
1937118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            absolute_imm(inst->src[i].val32, inst->src[i].type);
1947118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         inst->src[i].absolute = false;
1957118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
1967118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
1977118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (inst->src[i].negate) {
1987118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         inst->src[i].val32 =
1997118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            negate_imm(inst->src[i].val32, inst->src[i].type);
2007118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         inst->src[i].negate = false;
2017118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
2027118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2037118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      /* this is the last operand */
204e193c5dd59555cea56f5d72b4800a54cc77bc76dBrian Paul      if (i + 1 == ARRAY_SIZE(inst->src) || tsrc_is_null(inst->src[i + 1]))
2057118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
2067118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2077118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      /* need to use a temp if this imm is not the last operand */
2087118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      /* TODO we should simply swap the operands if the op is commutative */
2097118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tmp = tc_alloc_tmp(tc);
2107118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tmp = tdst_type(tmp, inst->src[i].type);
2117118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tc_MOV(tc, tmp, inst->src[i]);
2127118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->src[i] = tsrc_from(tmp);
2137118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2147118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      move_inst = true;
2157118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
2167118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2177118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   if (move_inst)
2187118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tc_move_inst(tc, inst);
2197118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
2207118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2217118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wustatic void
2227118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wulower_opcode_mul(struct toy_compiler *tc, struct toy_inst *inst)
2237118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
2247118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   const enum toy_type inst_type = inst->dst.type;
2257118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   const struct toy_dst acc0 =
2266c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      tdst_type(tdst(TOY_FILE_ARF, GEN6_ARF_ACC0, 0), inst_type);
2277118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   struct toy_inst *inst2;
2287118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2297118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* only need to take care of integer multiplications */
2307118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   if (inst_type != TOY_TYPE_UD && inst_type != TOY_TYPE_D)
2317118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      return;
2327118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2337118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* acc0 = (src0 & 0x0000ffff) * src1 */
2347118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   tc_MUL(tc, acc0, inst->src[0], inst->src[1]);
2357118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2367118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* acc0 = (src0 & 0xffff0000) * src1 + acc0 */
2376c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu   inst2 = tc_add2(tc, GEN6_OPCODE_MACH, tdst_type(tdst_null(), inst_type),
2387118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         inst->src[0], inst->src[1]);
2397118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   inst2->acc_wr_ctrl = true;
2407118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2417118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* dst = acc0 & 0xffffffff */
2427118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   tc_MOV(tc, inst->dst, tsrc_from(acc0));
2437118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2447118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   tc_discard_inst(tc, inst);
2457118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
2467118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2477118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wustatic void
2487118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wulower_opcode_mac(struct toy_compiler *tc, struct toy_inst *inst)
2497118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
2507118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   const enum toy_type inst_type = inst->dst.type;
2517118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2527118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   if (inst_type != TOY_TYPE_UD && inst_type != TOY_TYPE_D) {
2536c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      const struct toy_dst acc0 = tdst(TOY_FILE_ARF, GEN6_ARF_ACC0, 0);
2547118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2557118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tc_MOV(tc, acc0, inst->src[2]);
2567118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->src[2] = tsrc_null();
2577118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tc_move_inst(tc, inst);
2587118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
2597118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   else {
2607118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      struct toy_dst tmp = tdst_type(tc_alloc_tmp(tc), inst_type);
2617118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      struct toy_inst *inst2;
2627118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2637118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst2 = tc_MUL(tc, tmp, inst->src[0], inst->src[1]);
2647118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      lower_opcode_mul(tc, inst2);
2657118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2667118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tc_ADD(tc, inst->dst, tsrc_from(tmp), inst->src[2]);
2677118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2687118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      tc_discard_inst(tc, inst);
2697118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
2707118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
2717118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2727118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu/**
2737118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * Legalize the instructions for register allocation.
2747118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu */
2757118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wuvoid
2767118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wutoy_compiler_legalize_for_ra(struct toy_compiler *tc)
2777118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
2787118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   struct toy_inst *inst;
2797118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2807118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   tc_head(tc);
2817118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   while ((inst = tc_next(tc)) != NULL) {
2827118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      switch (inst->opcode) {
2836c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_MAC:
2847118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         lower_opcode_mac(tc, inst);
2857118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
2866c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_MAD:
2877118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         /* TODO operands must be floats */
2887118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
2896c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_MUL:
2907118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         lower_opcode_mul(tc, inst);
2917118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
2927118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      default:
2937118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         if (inst->opcode > TOY_OPCODE_LAST_HW)
2947118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            tc_fail(tc, "internal opcodes not lowered");
2957118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
2967118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
2977118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
2987118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* loop again as the previous pass may add new instructions */
2997118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   tc_head(tc);
3007118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   while ((inst = tc_next(tc)) != NULL) {
3017118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      validate_imm(tc, inst);
3027118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
3037118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
3047118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3057118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wustatic void
3067118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wupatch_while_jip(struct toy_compiler *tc, struct toy_inst *inst)
3077118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
3087118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   struct toy_inst *inst2;
3097118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   int nest_level, dist;
3107118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3117118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   nest_level = 0;
3127118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   dist = -1;
3137118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3147118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* search backward */
3157118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   LIST_FOR_EACH_ENTRY_FROM_REV(inst2, inst->list.prev,
3167118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         &tc->instructions, list) {
3177118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (inst2->marker) {
318ad39b991ce34d8af11589c78102873d8c28b1682Chia-I Wu         if (inst2->opcode == TOY_OPCODE_DO) {
3197118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            if (nest_level) {
3207118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               nest_level--;
3217118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            }
3227118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            else {
3237118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               /* the following instruction */
3247118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               dist++;
3257118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               break;
3267118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            }
3277118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         }
3287118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3297118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         continue;
3307118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
3317118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3326c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      if (inst2->opcode == GEN6_OPCODE_WHILE)
3337118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         nest_level++;
3347118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3357118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      dist--;
3367118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
3377118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3388323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu   if (ilo_dev_gen(tc->dev) >= ILO_GEN(8))
3398323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu      inst->src[1] = tsrc_imm_d(dist * 16);
3408323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu   else if (ilo_dev_gen(tc->dev) >= ILO_GEN(7))
3417118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->src[1] = tsrc_imm_w(dist * 2);
3427118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   else
3437118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->dst = tdst_imm_w(dist * 2);
3447118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
3457118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3467118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wustatic void
3477118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wupatch_if_else_jip(struct toy_compiler *tc, struct toy_inst *inst)
3487118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
3497118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   struct toy_inst *inst2;
3507118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   int nest_level, dist;
3517118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   int jip, uip;
3527118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3537118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   nest_level = 0;
3547118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   dist = 1;
3557118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   jip = 0;
3567118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   uip = 0;
3577118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3587118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* search forward */
3597118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   LIST_FOR_EACH_ENTRY_FROM(inst2, inst->list.next, &tc->instructions, list) {
3607118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (inst2->marker)
3617118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         continue;
3627118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3636c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      if (inst2->opcode == GEN6_OPCODE_ENDIF) {
3647118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         if (nest_level) {
3657118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            nest_level--;
3667118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         }
3677118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         else {
3687118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            uip = dist * 2;
3697118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            if (!jip)
3707118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               jip = uip;
3717118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            break;
3727118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         }
3737118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
3746c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      else if (inst2->opcode == GEN6_OPCODE_ELSE &&
3756c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu               inst->opcode == GEN6_OPCODE_IF) {
3767118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         if (!nest_level) {
3777118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            /* the following instruction */
3787118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            jip = (dist + 1) * 2;
3797118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
38056d2ebb019f38d727a41f8f4a8ebd4f1aeee19e0Chia-I Wu            if (ilo_dev_gen(tc->dev) == ILO_GEN(6)) {
3817118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               uip = jip;
3827118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               break;
3837118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            }
3847118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         }
3857118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
3866c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      else if (inst2->opcode == GEN6_OPCODE_IF) {
3877118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         nest_level++;
3887118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
3897118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3907118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      dist++;
3917118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
3927118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
3938323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu   if (ilo_dev_gen(tc->dev) >= ILO_GEN(8)) {
3948323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu      inst->dst.type = TOY_TYPE_D;
3958323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu      inst->src[0] = tsrc_imm_d(uip * 8);
3968323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu      inst->src[1] = tsrc_imm_d(jip * 8);
3978323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu   } else if (ilo_dev_gen(tc->dev) >= ILO_GEN(7)) {
3987118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      /* what should the type be? */
3997118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->dst.type = TOY_TYPE_D;
4007118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->src[0].type = TOY_TYPE_D;
4017118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->src[1] = tsrc_imm_d(uip << 16 | jip);
4028323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu   } else {
4037118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->dst = tdst_imm_w(jip);
4047118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
4057118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
4067118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4077118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wustatic void
4087118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wupatch_endif_jip(struct toy_compiler *tc, struct toy_inst *inst)
4097118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
4107118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   struct toy_inst *inst2;
4117118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   bool found = false;
4127118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   int dist = 1;
4137118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4147118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* search forward for instructions that may enable channels */
4157118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   LIST_FOR_EACH_ENTRY_FROM(inst2, inst->list.next, &tc->instructions, list) {
4167118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (inst2->marker)
4177118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         continue;
4187118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4197118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      switch (inst2->opcode) {
4206c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_ENDIF:
4216c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_ELSE:
4226c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_WHILE:
4237118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         found = true;
4247118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
4257118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      default:
4267118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
4277118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
4287118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4297118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (found)
4307118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
4317118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4327118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      dist++;
4337118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
4347118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4357118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* should we set dist to (dist - 1) or 1? */
4367118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   if (!found)
4377118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      dist = 1;
4387118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4398323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu   if (ilo_dev_gen(tc->dev) >= ILO_GEN(8))
4408323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu      inst->src[1] = tsrc_imm_d(dist * 16);
4418323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu   else if (ilo_dev_gen(tc->dev) >= ILO_GEN(7))
4427118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->src[1] = tsrc_imm_w(dist * 2);
4437118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   else
4447118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      inst->dst = tdst_imm_w(dist * 2);
4457118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
4467118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4477118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wustatic void
4487118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wupatch_break_continue_jip(struct toy_compiler *tc, struct toy_inst *inst)
4497118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
4507118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   struct toy_inst *inst2, *inst3;
4517118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   int nest_level, dist, jip, uip;
4527118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4537118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   nest_level = 0;
4547118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   dist = 1;
4557118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   jip = 1 * 2;
4567118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   uip = 1 * 2;
4577118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4587118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* search forward */
4597118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   LIST_FOR_EACH_ENTRY_FROM(inst2, inst->list.next, &tc->instructions, list) {
4607118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (inst2->marker) {
461ad39b991ce34d8af11589c78102873d8c28b1682Chia-I Wu         if (inst2->opcode == TOY_OPCODE_DO)
4627118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            nest_level++;
4637118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         continue;
4647118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
4657118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4666c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      if (inst2->opcode == GEN6_OPCODE_ELSE ||
4676c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu          inst2->opcode == GEN6_OPCODE_ENDIF ||
4686c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu          inst2->opcode == GEN6_OPCODE_WHILE) {
4697118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         jip = dist * 2;
4707118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
4717118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
4727118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4737118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      dist++;
4747118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
4757118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4767118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* go on to determine uip */
4777118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   inst3 = inst2;
4787118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   LIST_FOR_EACH_ENTRY_FROM(inst2, &inst3->list, &tc->instructions, list) {
4797118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (inst2->marker) {
480ad39b991ce34d8af11589c78102873d8c28b1682Chia-I Wu         if (inst2->opcode == TOY_OPCODE_DO)
4817118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            nest_level++;
4827118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         continue;
4837118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
4847118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4856c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      if (inst2->opcode == GEN6_OPCODE_WHILE) {
4867118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         if (nest_level) {
4877118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            nest_level--;
4887118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         }
4897118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         else {
4907118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            /* the following instruction */
49156d2ebb019f38d727a41f8f4a8ebd4f1aeee19e0Chia-I Wu            if (ilo_dev_gen(tc->dev) == ILO_GEN(6) &&
49256d2ebb019f38d727a41f8f4a8ebd4f1aeee19e0Chia-I Wu                inst->opcode == GEN6_OPCODE_BREAK)
4937118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               dist++;
4947118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
4957118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            uip = dist * 2;
4967118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            break;
4977118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         }
4987118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
4997118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5007118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      dist++;
5017118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
5027118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5037118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* should the type be D or W? */
5047118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   inst->dst.type = TOY_TYPE_D;
5058323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu   if (ilo_dev_gen(tc->dev) >= ILO_GEN(8)) {
5068323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu      inst->src[0] = tsrc_imm_d(uip * 8);
5078323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu      inst->src[1] = tsrc_imm_d(jip * 8);
5088323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu   } else {
5098323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu      inst->src[0].type = TOY_TYPE_D;
5108323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu      inst->src[1] = tsrc_imm_d(uip << 16 | jip);
5118323796840a343ee39687cc8e8b424ee43d6fee7Chia-I Wu   }
5127118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
5137118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5147118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu/**
5157118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu * Legalize the instructions for assembling.
5167118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu */
5177118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wuvoid
5187118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wutoy_compiler_legalize_for_asm(struct toy_compiler *tc)
5197118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu{
5207118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   struct toy_inst *inst;
5217118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   int pc = 0;
5227118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5237118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   tc_head(tc);
5247118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   while ((inst = tc_next(tc)) != NULL) {
5257118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      int i;
5267118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5277118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      pc++;
5287118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5297118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      /*
5307118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       * From the Sandy Bridge PRM, volume 4 part 2, page 112:
5317118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       *
5327118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       *     "Specifically, for instructions with a single source, it only
5337118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       *      uses the first source operand <src0>. In this case, the second
5347118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       *      source operand <src1> must be set to null and also with the same
5357118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       *      type as the first source operand <src0>.  It is a special case
5367118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       *      when <src0> is an immediate, as an immediate <src0> uses DW3 of
5377118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       *      the instruction word, which is normally used by <src1>.  In this
5387118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       *      case, <src1> must be programmed with register file ARF and the
5397118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       *      same data type as <src0>."
5407118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       *
5417118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       * Since we already fill unused operands with null, we only need to take
5427118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       * care of the type.
5437118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu       */
5447118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      if (tsrc_is_null(inst->src[1]))
5457118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         inst->src[1].type = inst->src[0].type;
5467118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5477118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      switch (inst->opcode) {
5486c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_MATH:
5497118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         /* math does not support align16 nor exec_size > 8 */
5506c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu         inst->access_mode = GEN6_ALIGN_1;
5517118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5526c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu         if (inst->exec_size == GEN6_EXECSIZE_16) {
5537118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            /*
5547118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu             * From the Ivy Bridge PRM, volume 4 part 3, page 192:
5557118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu             *
5567118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu             *     "INT DIV function does not support SIMD16."
5577118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu             */
55856d2ebb019f38d727a41f8f4a8ebd4f1aeee19e0Chia-I Wu            if (ilo_dev_gen(tc->dev) < ILO_GEN(7) ||
5596c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu                inst->cond_modifier == GEN6_MATH_INT_DIV_QUOTIENT ||
5606c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu                inst->cond_modifier == GEN6_MATH_INT_DIV_REMAINDER) {
5617118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               struct toy_inst *inst2;
5627118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5636c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu               inst->exec_size = GEN6_EXECSIZE_8;
5646c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu               inst->qtr_ctrl = GEN6_QTRCTRL_1Q;
5657118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5667118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               inst2 = tc_duplicate_inst(tc, inst);
5676c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu               inst2->qtr_ctrl = GEN6_QTRCTRL_2Q;
5687118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               inst2->dst = tdst_offset(inst2->dst, 1, 0);
5697118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               inst2->src[0] = tsrc_offset(inst2->src[0], 1, 0);
5707118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               if (!tsrc_is_null(inst2->src[1]))
5717118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu                  inst2->src[1] = tsrc_offset(inst2->src[1], 1, 0);
5727118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5737118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               pc++;
5747118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            }
5757118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         }
5767118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
5776c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_IF:
57856d2ebb019f38d727a41f8f4a8ebd4f1aeee19e0Chia-I Wu         if (ilo_dev_gen(tc->dev) >= ILO_GEN(7) &&
579b51b349942ffd22a12d578bee6ba5db60d88d1bdChia-I Wu             inst->cond_modifier != GEN6_COND_NONE) {
5807118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            struct toy_inst *inst2;
5817118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5827118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            inst2 = tc_duplicate_inst(tc, inst);
5837118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5847118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            /* replace the original IF by CMP */
5856c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu            inst->opcode = GEN6_OPCODE_CMP;
5867118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5877118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            /* predicate control instead of condition modifier */
5887118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            inst2->dst = tdst_null();
5897118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            inst2->src[0] = tsrc_null();
5907118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            inst2->src[1] = tsrc_null();
591b51b349942ffd22a12d578bee6ba5db60d88d1bdChia-I Wu            inst2->cond_modifier = GEN6_COND_NONE;
5926c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu            inst2->pred_ctrl = GEN6_PREDCTRL_NORMAL;
5937118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
5947118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            pc++;
5957118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         }
5967118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
5977118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      default:
5987118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
5997118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
6007118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
6017118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      /* MRF to GRF */
60256d2ebb019f38d727a41f8f4a8ebd4f1aeee19e0Chia-I Wu      if (ilo_dev_gen(tc->dev) >= ILO_GEN(7)) {
603e193c5dd59555cea56f5d72b4800a54cc77bc76dBrian Paul         for (i = 0; i < ARRAY_SIZE(inst->src); i++) {
6047118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            if (inst->src[i].file != TOY_FILE_MRF)
6057118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               continue;
6067118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            else if (tsrc_is_null(inst->src[i]))
6077118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu               break;
6087118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
6097118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            inst->src[i].file = TOY_FILE_GRF;
6107118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         }
6117118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
6127118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         if (inst->dst.file == TOY_FILE_MRF)
6137118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu            inst->dst.file = TOY_FILE_GRF;
6147118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
6157118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
6167118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
6177118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   tc->num_instructions = pc;
6187118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu
6197118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   /* set JIP/UIP */
6207118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   tc_head(tc);
6217118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   while ((inst = tc_next(tc)) != NULL) {
6227118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      switch (inst->opcode) {
6236c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_IF:
6246c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_ELSE:
6257118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         patch_if_else_jip(tc, inst);
6267118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
6276c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_ENDIF:
6287118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         patch_endif_jip(tc, inst);
6297118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
6306c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_WHILE:
6317118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         patch_while_jip(tc, inst);
6327118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
6336c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_BREAK:
6346c6bd796adda4173ebaf494d6cd2a96d511f1ea3Chia-I Wu      case GEN6_OPCODE_CONT:
6357118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         patch_break_continue_jip(tc, inst);
6367118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
6377118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      default:
6387118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu         break;
6397118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu      }
6407118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu   }
6417118ff8bb02046bb2f440e2a5c48d9a41bb057b1Chia-I Wu}
642