ir_to_mesa.cpp revision 346daeca07d3c19c051799f96fa9f442262bd49f
184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/*
284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Copyright © 2010 Intel Corporation
384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * copy of this software and associated documentation files (the "Software"),
684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * to deal in the Software without restriction, including without limitation
784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * and/or sell copies of the Software, and to permit persons to whom the
984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software is furnished to do so, subject to the following conditions:
1084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
1184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * The above copyright notice and this permission notice (including the next
1284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * paragraph) shall be included in all copies or substantial portions of the
1384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software.
1484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
1584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * DEALINGS IN THE SOFTWARE.
2284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
2384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/**
2584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * \file ir_to_mesa.cpp
2684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
2784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Translates the IR to ARB_fragment_program text if possible,
2884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * printing the result
2984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
3084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/* Quiet compiler warnings due to monoburg not marking functions defined
3284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * in the header as inline.
3384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
3484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#define g_new
3584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#define g_error
3684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "mesa_codegen.h"
3784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir.h"
3984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_visitor.h"
4084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_print_visitor.h"
4184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_expression_flattening.h"
4284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h"
4384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
44aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholtextern "C" {
4584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "shader/prog_instruction.h"
46aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt#include "shader/prog_print.h"
47aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt}
4884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
4984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_src_reg ir_to_mesa_undef = {
50c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, false,
5184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt};
5284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
53c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
54c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP
55c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt};
56c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
5784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
58c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_emit_op3(ir_to_mesa_visitor *v, ir_instruction *ir,
59c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt		    enum prog_opcode op,
6084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt		    ir_to_mesa_dst_reg dst,
6184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt		    ir_to_mesa_src_reg src0,
6284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt		    ir_to_mesa_src_reg src1,
6384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt		    ir_to_mesa_src_reg src2)
6484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
6584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir_to_mesa_instruction *inst = new ir_to_mesa_instruction();
6684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->op = op;
6884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->dst_reg = dst;
6984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[0] = src0;
7084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[1] = src1;
7184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[2] = src2;
72c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   inst->ir = ir;
7384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
74c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   v->instructions.push_tail(inst);
7584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
7684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return inst;
7784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
7884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
7984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
8084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
81c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_emit_op2_full(ir_to_mesa_visitor *v, ir_instruction *ir,
82c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt			 enum prog_opcode op,
83bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt			 ir_to_mesa_dst_reg dst,
84bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt			 ir_to_mesa_src_reg src0,
85bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt			 ir_to_mesa_src_reg src1)
8684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
87c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   return ir_to_mesa_emit_op3(v, ir,
88c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt			      op, dst, src0, src1, ir_to_mesa_undef);
8984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
9084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
92bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholtir_to_mesa_emit_op2(struct mbtree *tree, enum prog_opcode op)
93bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{
94c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   return ir_to_mesa_emit_op2_full(tree->v, tree->ir, op,
95bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt				   tree->dst_reg,
96bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt				   tree->left->src_reg,
97bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt				   tree->right->src_reg);
98bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
99bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
100bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholtir_to_mesa_instruction *
101c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_emit_op1_full(ir_to_mesa_visitor *v, ir_instruction *ir,
102c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt			 enum prog_opcode op,
103bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt			 ir_to_mesa_dst_reg dst,
104bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt			 ir_to_mesa_src_reg src0)
10584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
106c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   return ir_to_mesa_emit_op3(v, ir, op,
10784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt			      dst, src0, ir_to_mesa_undef, ir_to_mesa_undef);
10884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
10984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
110bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholtir_to_mesa_instruction *
111bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholtir_to_mesa_emit_op1(struct mbtree *tree, enum prog_opcode op)
112bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{
113c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   return ir_to_mesa_emit_op1_full(tree->v, tree->ir, op,
114bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt				   tree->dst_reg,
115bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt				   tree->left->src_reg);
116bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
117bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
11812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/**
11912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels.
12012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt *
12112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp.  The src X
12212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels.  So to do a vec4
12312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used
12412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels.
12512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */
12612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid
12712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtir_to_mesa_emit_scalar_op1(struct mbtree *tree, enum prog_opcode op,
12812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt			   ir_to_mesa_dst_reg dst,
12912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt			   ir_to_mesa_src_reg src0)
13012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{
13112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   int i, j;
132315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt   int done_mask = ~dst.writemask;
13312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
13412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   /* Mesa RCP is a scalar operation splatting results to all channels,
13512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
13612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * dst channels.
13712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    */
13812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   for (i = 0; i < 4; i++) {
13912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      int this_mask = (1 << i);
14012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      ir_to_mesa_instruction *inst;
14112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      ir_to_mesa_src_reg src = src0;
14212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
14312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      if (done_mask & this_mask)
14412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 continue;
14512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
14612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      int src_swiz = GET_SWZ(src.swizzle, i);
14712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      for (j = i + 1; j < 4; j++) {
148315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt	 if (!(done_mask & (1 << j)) && GET_SWZ(src.swizzle, j) == src_swiz) {
14912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	    this_mask |= (1 << j);
15012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 }
15112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      }
15212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      src.swizzle = MAKE_SWIZZLE4(src_swiz, src_swiz,
15312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt				  src_swiz, src_swiz);
15412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
155c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      inst = ir_to_mesa_emit_op1_full(tree->v, tree->ir, op,
156bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt				      dst,
157bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt				      src);
15812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      inst->dst_reg.writemask = this_mask;
15912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      done_mask |= this_mask;
16012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   }
16112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt}
16212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
163b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholtstatic void
164b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholtir_to_mesa_set_tree_reg(struct mbtree *tree, int file, int index)
165b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
166b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   tree->dst_reg.file = file;
167b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   tree->dst_reg.index = index;
168b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
169b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   tree->src_reg.file = file;
170b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   tree->src_reg.index = index;
171b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt}
172b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
17384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstruct mbtree *
174b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholtir_to_mesa_visitor::create_tree(int op,
175b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt				ir_instruction *ir,
176b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt				struct mbtree *left, struct mbtree *right)
17784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
17884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct mbtree *tree = (struct mbtree *)calloc(sizeof(struct mbtree), 1);
17984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
180b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt   assert(ir);
181b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt
18284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   tree->op = op;
18384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   tree->left = left;
18484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   tree->right = right;
18584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   tree->v = this;
18684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   tree->src_reg.swizzle = SWIZZLE_XYZW;
187c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   tree->src_reg.negate = 0;
188b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   tree->dst_reg.writemask = WRITEMASK_XYZW;
189b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_to_mesa_set_tree_reg(tree, PROGRAM_UNDEFINED, 0);
190b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt   tree->ir = ir;
19184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
19284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return tree;
19384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
19484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1951d20862c8a0e100e43458f01217c047c76da05f3Eric Anholtstruct mbtree *
1961d20862c8a0e100e43458f01217c047c76da05f3Eric Anholtir_to_mesa_visitor::create_tree_for_float(ir_instruction *ir, float val)
1971d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt{
1981d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   struct mbtree *tree = (struct mbtree *)calloc(sizeof(struct mbtree), 1);
1991d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
2001d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
2011d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
2021d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   /* FINISHME: This will end up being _mesa_add_unnamed_constant,
2031d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt    * which handles sharing values and sharing channels of vec4
2041d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt    * constants for small values.
2051d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt    */
2061d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   /* FINISHME: Do something with the constant values for now.
2071d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt    */
2081d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   (void)val;
2091d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   ir_to_mesa_set_tree_reg(tree, PROGRAM_CONSTANT, this->next_constant++);
2101d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   tree->src_reg.swizzle = SWIZZLE_NOOP;
2111d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
2121d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   this->result = tree;
2131d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   return tree;
2141d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt}
2151d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
21684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/**
21784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * In the initial pass of codegen, we assign temporary numbers to
21884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * intermediate results.  (not SSA -- variable assignments will reuse
21984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * storage).  Actual register allocation for the Mesa VM occurs in a
22084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * pass over the Mesa IR later.
22184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
22284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
2233d70d1f4d684a943b8b4a65319641415882b72cbEric Anholtir_to_mesa_visitor::get_temp(struct mbtree *tree, int size)
22484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
225315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt   int swizzle[4];
2263d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt   int i;
2273d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt
228b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_to_mesa_set_tree_reg(tree, PROGRAM_TEMPORARY, this->next_temp++);
2293d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt
2303d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt   for (i = 0; i < size; i++)
231315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt      swizzle[i] = i;
2323d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt   for (; i < 4; i++)
233315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt      swizzle[i] = size - 1;
234315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt   tree->src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
235315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt					 swizzle[2], swizzle[3]);
2363d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt   tree->dst_reg.writemask = (1 << size) - 1;
23784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
23884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2392c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int
2402c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type)
2412c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
2422c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
2432c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int size;
2442c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
2452c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   switch (type->base_type) {
2462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_UINT:
2472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_INT:
2482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_FLOAT:
2492c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_BOOL:
2502c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(!type->is_matrix());
2512c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      /* Regardless of size of vector, it gets a vec4. This is bad
2522c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt       * packing for things like floats, but otherwise arrays become a
2532c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt       * mess.  Hopefully a later pass over the code can pack scalars
2542c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt       * down if appropriate.
2552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt       */
2562c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return 1;
2572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_ARRAY:
2582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return type_size(type->fields.array) * type->length;
2592c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_STRUCT:
2602c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      size = 0;
2612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      for (i = 0; i < type->length; i++) {
2622c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 size += type_size(type->fields.structure[i].type);
2632c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      }
2642c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return size;
2652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   default:
2662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(0);
2672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
2682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
2692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
27084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
27184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::get_temp_for_var(ir_variable *var, struct mbtree *tree)
27284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
27384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   temp_entry *entry;
27484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
27584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, this->variable_storage) {
27684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      entry = (temp_entry *)iter.get();
27784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
27884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (entry->var == var) {
279b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt	 ir_to_mesa_set_tree_reg(tree, entry->file, entry->index);
28084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 return;
28184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
28284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
28384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2844e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   entry = new temp_entry(var, PROGRAM_TEMPORARY, this->next_temp);
28584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   this->variable_storage.push_tail(entry);
28684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2872c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   next_temp += type_size(var->type);
2884e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
289b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_to_mesa_set_tree_reg(tree, entry->file, entry->index);
29084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
29184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
29284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic void
29384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtreduce(struct mbtree *t, int goal)
29484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
29584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct mbtree *kids[10];
29684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int rule = mono_burg_rule((MBState *)t->state, goal);
29784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const uint16_t *nts = mono_burg_nts[rule];
29884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int i;
29984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
30084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mono_burg_kids (t, rule, kids);
30184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
30284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (i = 0; nts[i]; i++) {
30384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      reduce(kids[i], nts[i]);
30484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
30584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
30684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   if (t->left) {
30784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (mono_burg_func[rule]) {
30884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 mono_burg_func[rule](t, NULL);
30984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else {
31084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 printf("no code for rules %s\n", mono_burg_rule_string[rule]);
31184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 exit(1);
31284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
31384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   } else {
31484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (mono_burg_func[rule]) {
31584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 printf("unused code for rule %s\n", mono_burg_rule_string[rule]);
31684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 exit(1);
31784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
31884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
31984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
32084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
32184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
32284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir)
32384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
32484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   (void)ir;
32584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
32684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
32784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
32884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir)
32984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
33064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->from);
33164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->to);
33264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->increment);
33364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->counter);
33484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
33564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   ir_to_mesa_emit_op1_full(this, NULL,
33664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt			    OPCODE_BGNLOOP, ir_to_mesa_undef_dst,
33764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt			    ir_to_mesa_undef);
33864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt
33964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   visit_exec_list(&ir->body_instructions, this);
34064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt
34164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   ir_to_mesa_emit_op1_full(this, NULL,
34264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt			    OPCODE_ENDLOOP, ir_to_mesa_undef_dst,
34364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt			    ir_to_mesa_undef);
34484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
34584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
34684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
34784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir)
34884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
34964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   switch (ir->mode) {
35064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_break:
35164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      ir_to_mesa_emit_op1_full(this, NULL,
35264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt			       OPCODE_BRK, ir_to_mesa_undef_dst,
35364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt			       ir_to_mesa_undef);
35464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
35564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_continue:
35664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      ir_to_mesa_emit_op1_full(this, NULL,
35764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt			       OPCODE_CONT, ir_to_mesa_undef_dst,
35864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt			       ir_to_mesa_undef);
35964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
36064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   }
36184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
36284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
36384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
36484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
36584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir)
36684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
36784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
36884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   (void)ir;
36984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
37084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
37184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
37284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir)
37384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
37484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* Ignore function bodies other than main() -- we shouldn't see calls to
37584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * them since they should all be inlined before we get to ir_to_mesa.
37684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
37784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   if (strcmp(ir->name, "main") == 0) {
37884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      const ir_function_signature *sig;
37984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      exec_list empty;
38084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
38184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      sig = ir->matching_signature(&empty);
38284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
38384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      assert(sig);
38484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
38584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      foreach_iter(exec_list_iterator, iter, sig->body) {
38684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_instruction *ir = (ir_instruction *)iter.get();
38784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
38884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->accept(this);
38984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
39084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
39184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
39284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
39384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
39484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir)
39584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
39684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   unsigned int operand;
39784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct mbtree *op[2];
39884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
39984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
40084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
40184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
40284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (operand = 0; operand < ir->get_num_operands(); operand++) {
40384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      this->result = NULL;
40484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir->operands[operand]->accept(this);
40584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (!this->result) {
40684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_print_visitor v;
40784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 printf("Failed to get tree for expression operand:\n");
40884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->operands[operand]->accept(&v);
40984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 exit(1);
41084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
41184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      op[operand] = this->result;
41284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
41384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
41484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   this->result = NULL;
41584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
41684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   switch (ir->operation) {
4171d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_logic_not:
4181d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      this->result = this->create_tree_for_float(ir, 0.0);
4191d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      this->result = this->create_tree(MB_TERM_seq_vec4_vec4, ir,
4201d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt				       op[0], this->result);
4211d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
422c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   case ir_unop_neg:
423c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt      op[0]->src_reg.negate = ~op[0]->src_reg.negate;
424c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt      this->result = op[0];
425c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt      break;
4268c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp:
4278c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      this->result = this->create_tree(MB_TERM_exp_vec4, ir, op[0], NULL);
4288c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
4298c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp2:
4308c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      this->result = this->create_tree(MB_TERM_exp2_vec4, ir, op[0], NULL);
4318c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
4328c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log:
4338c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      this->result = this->create_tree(MB_TERM_log_vec4, ir, op[0], NULL);
4348c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
4358c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log2:
4368c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      this->result = this->create_tree(MB_TERM_log2_vec4, ir, op[0], NULL);
4378c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
4383c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_sin:
4393c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      this->result = this->create_tree(MB_TERM_sin_vec4, ir, op[0], NULL);
4403c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
4413c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_cos:
4423c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      this->result = this->create_tree(MB_TERM_cos_vec4, ir, op[0], NULL);
4433c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
44484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_add:
445b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt      this->result = this->create_tree(MB_TERM_add_vec4_vec4, ir, op[0], op[1]);
44684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
44784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_sub:
448b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt      this->result = this->create_tree(MB_TERM_sub_vec4_vec4, ir, op[0], op[1]);
44984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
45084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_mul:
451b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt      this->result = this->create_tree(MB_TERM_mul_vec4_vec4, ir, op[0], op[1]);
45284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
45384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_div:
454b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt      this->result = this->create_tree(MB_TERM_div_vec4_vec4, ir, op[0], op[1]);
45584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
45638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
45738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_less:
45838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      this->result = this->create_tree(MB_TERM_slt_vec4_vec4, ir, op[0], op[1]);
45938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
46038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_greater:
46138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      this->result = this->create_tree(MB_TERM_sgt_vec4_vec4, ir, op[0], op[1]);
46238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
46338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_lequal:
46438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      this->result = this->create_tree(MB_TERM_sle_vec4_vec4, ir, op[0], op[1]);
46538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
46638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_gequal:
46738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      this->result = this->create_tree(MB_TERM_sge_vec4_vec4, ir, op[0], op[1]);
46838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
46938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_equal:
47038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      this->result = this->create_tree(MB_TERM_seq_vec4_vec4, ir, op[0], op[1]);
47138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
472763cd75863ed9a16912e585887580c44d1e8109fEric Anholt   case ir_binop_logic_xor:
47338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_nequal:
47438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      this->result = this->create_tree(MB_TERM_sne_vec4_vec4, ir, op[0], op[1]);
47538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
47638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
4774380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_or:
4784380099c98119611ceee684669d00be26195c7d7Eric Anholt      /* This could be a saturated add. */
4794380099c98119611ceee684669d00be26195c7d7Eric Anholt      this->result = this->create_tree(MB_TERM_add_vec4_vec4, ir, op[0], op[1]);
4804380099c98119611ceee684669d00be26195c7d7Eric Anholt      this->result = this->create_tree(MB_TERM_sne_vec4_vec4, ir,
4814380099c98119611ceee684669d00be26195c7d7Eric Anholt				       this->create_tree_for_float(ir, 0.0),
4824380099c98119611ceee684669d00be26195c7d7Eric Anholt				       this->result);
4834380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
4844380099c98119611ceee684669d00be26195c7d7Eric Anholt
4854380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_and:
4864380099c98119611ceee684669d00be26195c7d7Eric Anholt      /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
4874380099c98119611ceee684669d00be26195c7d7Eric Anholt      this->result = this->create_tree(MB_TERM_mul_vec4_vec4, ir, op[0], op[1]);
4884380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
4894380099c98119611ceee684669d00be26195c7d7Eric Anholt
49084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_dot:
49184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (ir->operands[0]->type == vec4_type) {
49284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec4_type);
493b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt	 this->result = this->create_tree(MB_TERM_dp4_vec4_vec4,
494b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt					  ir, op[0], op[1]);
49584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec3_type) {
49684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec3_type);
497b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt	 this->result = this->create_tree(MB_TERM_dp3_vec4_vec4,
498b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt					  ir, op[0], op[1]);
49984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec2_type) {
50084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec2_type);
501b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt	 this->result = this->create_tree(MB_TERM_dp2_vec4_vec4,
502b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt					  ir, op[0], op[1]);
50384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
50484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
50584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_unop_sqrt:
506b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt      this->result = this->create_tree(MB_TERM_sqrt_vec4, ir, op[0], op[1]);
50784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
508878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt   case ir_unop_rsq:
509878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt      this->result = this->create_tree(MB_TERM_rsq_vec4, ir, op[0], op[1]);
510878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt      break;
51150ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt   case ir_unop_i2f:
512423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      /* Mesa IR lacks types, ints are stored as truncated floats. */
51350ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt      this->result = op[0];
51450ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt      break;
515423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt   case ir_unop_f2i:
516423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      this->result = this->create_tree(MB_TERM_trunc_vec4, ir, op[0], NULL);
517423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      break;
5181d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_f2b:
5191d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      this->result = this->create_tree_for_float(ir, 0.0);
5201d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      this->result = this->create_tree(MB_TERM_sne_vec4_vec4, ir,
5211d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt				       op[0], this->result);
5221d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
523c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_trunc:
524c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      this->result = this->create_tree(MB_TERM_trunc_vec4, ir, op[0], NULL);
525c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
526c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_ceil:
527c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      this->result = this->create_tree(MB_TERM_ceil_vec4, ir, op[0], NULL);
528c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
529c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_floor:
530c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      this->result = this->create_tree(MB_TERM_floor_vec4, ir, op[0], NULL);
531c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
53284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   default:
53384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
53484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
53584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   if (!this->result) {
53684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir_print_visitor v;
53784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      printf("Failed to get tree for expression:\n");
53884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir->accept(&v);
53984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      exit(1);
54084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
541b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt
542b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt   /* Allocate a temporary for the result. */
5433d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt   this->get_temp(this->result, ir->type->vector_elements);
54484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
54584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
54684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
54784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
54884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir)
54984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
55084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct mbtree *tree;
55184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int i;
55284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int swizzle[4];
55384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
554b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   /* Note that this is only swizzles in expressions, not those on the left
555b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * hand side of an assignment, which do write masking.  See ir_assignment
556b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * for that.
557b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    */
55884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
55984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->val->accept(this);
56084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(this->result);
56184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
562b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt   tree = this->create_tree(MB_TERM_swizzle_vec4, ir, this->result, NULL);
5633d70d1f4d684a943b8b4a65319641415882b72cbEric Anholt   this->get_temp(tree, 4);
56484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
56584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (i = 0; i < 4; i++) {
56684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (i < ir->type->vector_elements) {
56784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 switch (i) {
56884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 0:
56984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    swizzle[i] = ir->mask.x;
57084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
57184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 1:
57284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    swizzle[i] = ir->mask.y;
57384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 2:
57584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    swizzle[i] = ir->mask.z;
57684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
57784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 3:
57884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    swizzle[i] = ir->mask.w;
57984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
58084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 }
58184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else {
58284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 /* If the type is smaller than a vec4, replicate the last
58384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  * channel out.
58484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  */
58584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 swizzle[i] = ir->type->vector_elements - 1;
58684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
58784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
58884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
58984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   tree->src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
59084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt					 swizzle[1],
59184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt					 swizzle[2],
59284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt					 swizzle[3]);
59384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
59484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   this->result = tree;
59584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
59684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
597829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt/* This list should match up with builtin_variables.h */
598829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholtstatic const struct {
599829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   const char *name;
600829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   int file;
601829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   int index;
602829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt} builtin_var_to_mesa_reg[] = {
603829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   /* core_vs */
604829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_Position", PROGRAM_OUTPUT, VERT_RESULT_HPOS},
605829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_PointSize", PROGRAM_OUTPUT, VERT_RESULT_PSIZ},
606829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt
607829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   /* core_fs */
608829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_FragCoord", PROGRAM_INPUT, FRAG_ATTRIB_WPOS},
609829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_FrontFacing", PROGRAM_INPUT, FRAG_ATTRIB_FACE},
610829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_FragColor", PROGRAM_INPUT, FRAG_ATTRIB_COL0},
611829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_FragDepth", PROGRAM_UNDEFINED, FRAG_ATTRIB_WPOS}, /* FINISHME: WPOS.z */
612829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt
613829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   /* 110_deprecated_fs */
614829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_Color", PROGRAM_INPUT, FRAG_ATTRIB_COL0},
615829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_SecondaryColor", PROGRAM_INPUT, FRAG_ATTRIB_COL1},
616829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_FogFragCoord", PROGRAM_INPUT, FRAG_ATTRIB_FOGC},
617829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt
618829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   /* 110_deprecated_vs */
619829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_Vertex", PROGRAM_INPUT, VERT_ATTRIB_POS},
620829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_Normal", PROGRAM_INPUT, VERT_ATTRIB_NORMAL},
621829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_Color", PROGRAM_INPUT, VERT_ATTRIB_COLOR0},
622829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_SecondaryColor", PROGRAM_INPUT, VERT_ATTRIB_COLOR1},
623829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_MultiTexCoord0", PROGRAM_INPUT, VERT_ATTRIB_TEX0},
624829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_MultiTexCoord1", PROGRAM_INPUT, VERT_ATTRIB_TEX1},
625829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_MultiTexCoord2", PROGRAM_INPUT, VERT_ATTRIB_TEX2},
626829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_MultiTexCoord3", PROGRAM_INPUT, VERT_ATTRIB_TEX3},
627829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_MultiTexCoord4", PROGRAM_INPUT, VERT_ATTRIB_TEX4},
628829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_MultiTexCoord5", PROGRAM_INPUT, VERT_ATTRIB_TEX5},
629829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_MultiTexCoord6", PROGRAM_INPUT, VERT_ATTRIB_TEX6},
630829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_MultiTexCoord7", PROGRAM_INPUT, VERT_ATTRIB_TEX7},
6314e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   {"gl_TexCoord", PROGRAM_OUTPUT, VERT_RESULT_TEX0}, /* array */
632829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_FogCoord", PROGRAM_INPUT, VERT_RESULT_FOGC},
633829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   /*{"gl_ClipVertex", PROGRAM_OUTPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
634829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_FrontColor", PROGRAM_OUTPUT, VERT_RESULT_COL0},
635829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_BackColor", PROGRAM_OUTPUT, VERT_RESULT_BFC0},
636829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_FrontSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_COL1},
637829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_BackSecondaryColor", PROGRAM_OUTPUT, VERT_RESULT_BFC1},
638829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   {"gl_FogFragCoord", PROGRAM_OUTPUT, VERT_RESULT_FOGC},
639829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt
640829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   /* 130_vs */
641829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   /*{"gl_VertexID", PROGRAM_INPUT, VERT_ATTRIB_FOGC},*/ /* FINISHME */
6424e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
6434e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   {"gl_FragData", PROGRAM_OUTPUT, FRAG_RESULT_DATA0}, /* array */
644829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt};
64584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
64684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
64784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir)
64884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
64984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct mbtree *tree;
65084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int size_swizzles[4] = {
65184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
65234195832669f0eb7c4a80997cc524f8d10319307Eric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
65334195832669f0eb7c4a80997cc524f8d10319307Eric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
65434195832669f0eb7c4a80997cc524f8d10319307Eric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
65584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   };
6564e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   ir_variable *var = ir->var;
65784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
658829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt   /* By the time we make it to this stage, matrices should be broken down
65984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * to vectors.
66084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
66184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(!var->type->is_matrix());
66284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
663b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
66484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
66584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   if (strncmp(var->name, "gl_", 3) == 0) {
666829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt      unsigned int i;
667829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt
668829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt      for (i = 0; i < ARRAY_SIZE(builtin_var_to_mesa_reg); i++) {
669829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt	 if (strcmp(var->name, builtin_var_to_mesa_reg[i].name) == 0)
670829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt	    break;
67184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
672829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt      assert(i != ARRAY_SIZE(builtin_var_to_mesa_reg));
673829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt      ir_to_mesa_set_tree_reg(tree, builtin_var_to_mesa_reg[i].file,
674829e0a8eff0e657c85fa7fc53a4b456375b434ccEric Anholt			      builtin_var_to_mesa_reg[i].index);
67584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   } else {
67684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      this->get_temp_for_var(var, tree);
67784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
67884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
67984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
68084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   tree->src_reg.swizzle = size_swizzles[ir->type->vector_elements - 1];
68184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
68284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   this->result = tree;
68384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
68484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
68584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
68684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir)
68784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
68884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct mbtree *tree;
68984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int size_swizzles[4] = {
69084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
69184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
69284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
69384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
69484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   };
6958041bce333a48033975eb83d47ecc6bd7a91cd1dEric Anholt   ir_variable *var = ir->variable_referenced();
6968041bce333a48033975eb83d47ecc6bd7a91cd1dEric Anholt   ir_constant *index = ir->array_index->constant_expression_value();
6974e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
6984e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   /* By the time we make it to this stage, matrices should be broken down
6994e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt    * to vectors.
7004e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt    */
7014e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   assert(!var->type->is_matrix());
70284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
7034e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   if (strncmp(var->name, "gl_", 3) == 0) {
7044e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt      unsigned int i;
7054e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt      unsigned int offset = 0;
7064e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
707bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
7084e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
7094e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt      offset = index->value.i[0];
7104e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
7114e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt      for (i = 0; i < ARRAY_SIZE(builtin_var_to_mesa_reg); i++) {
7124e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt	 if (strcmp(var->name, builtin_var_to_mesa_reg[i].name) == 0)
7134e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt	    break;
7144e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt      }
7154e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt      assert(i != ARRAY_SIZE(builtin_var_to_mesa_reg));
7164e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt      ir_to_mesa_set_tree_reg(tree, builtin_var_to_mesa_reg[i].file,
7174e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt			      builtin_var_to_mesa_reg[i].index + offset);
7184e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   } else {
719bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
7204e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt      this->get_temp_for_var(var, tree);
7214e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
722bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      if (index) {
723bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 tree->src_reg.index += index->value.i[0];
724bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 tree->dst_reg.index += index->value.i[0];
725bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      } else {
726bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 /* Variable index array dereference.  It eats the "vec4" of the
727bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	  * base of the array and an index that offsets the Mesa register
728bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	  * index.
729bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	  */
730bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 ir->array_index->accept(this);
731bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt
732bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 tree->src_reg.reladdr = true;
733bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 tree = this->create_tree(MB_TERM_array_reference_vec4_vec4,
734bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt				  ir, tree, this->result);
735bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt	 this->get_temp(tree, ir->type->vector_elements);
736bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      }
7374e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   }
73884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
73984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
74084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   tree->src_reg.swizzle = size_swizzles[ir->type->vector_elements - 1];
74184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
74284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   this->result = tree;
74384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
74484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
7452c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid
7462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir)
7472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
7482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   ir_variable *var = ir->variable_referenced();
7492c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   const char *field = ir->field;
7502c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   struct mbtree *tree;
7512c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
7522c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
7532c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   const glsl_type *struct_type = var->type;
7542c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int offset = 0;
7552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
7562c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
7572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   this->get_temp_for_var(var, tree);
7582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
7592c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   for (i = 0; i < struct_type->length; i++) {
7602c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      if (strcmp(struct_type->fields.structure[i].name, field) == 0)
7612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 break;
7622c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      offset += type_size(struct_type->fields.structure[i].type);
7632c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
7642c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   tree->src_reg.index += offset;
7652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   tree->dst_reg.index += offset;
7662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
7672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
7682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/**
7692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage
7702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the
7712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler.
7722c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt *
7732c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
7742c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * should only see potentially one variable array index of a vector,
7752c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * and one swizzle, before getting to actual vec4 storage.  So handle
7762c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * those, then go use ir_dereference to handle the rest.
7772c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */
778b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholtstatic struct mbtree *
779b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholtget_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v)
780b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
781b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   struct mbtree *tree = NULL;
782b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_dereference *deref;
783b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_swizzle *swiz;
784b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
7852c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   ir->accept(v);
7862c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   tree = v->result;
7872c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
788b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   if ((deref = ir->as_dereference())) {
7892c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      ir_dereference_array *deref_array = ir->as_dereference_array();
7902c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(!deref_array || deref_array->array->type->is_array());
7912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
792b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      ir->accept(v);
793b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      tree = v->result;
794b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   } else if ((swiz = ir->as_swizzle())) {
795b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      tree->dst_reg.writemask = 0;
796b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 1)
797b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt	 tree->dst_reg.writemask |= (1 << swiz->mask.x);
798b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 2)
799b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt	 tree->dst_reg.writemask |= (1 << swiz->mask.y);
800b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 3)
801b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt	 tree->dst_reg.writemask |= (1 << swiz->mask.z);
802b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt      if (swiz->mask.num_components >= 4)
803b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt	 tree->dst_reg.writemask |= (1 << swiz->mask.w);
804b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   }
805b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
806b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   assert(tree);
807b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
808b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   return tree;
809b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt}
810b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
81184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
81284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir)
81384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
81484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct mbtree *l, *r, *t;
81584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
8162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(!ir->lhs->type->is_matrix());
8172c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(!ir->lhs->type->is_array());
8182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(ir->lhs->type->base_type != GLSL_TYPE_STRUCT);
8192c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
820b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   l = get_assignment_lhs(ir->lhs, this);
821b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
82284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->rhs->accept(this);
82384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   r = this->result;
82484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(l);
82584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(r);
82684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
827346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   if (ir->condition) {
828346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt	 ir_constant *condition_constant;
829346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt
830346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt	 condition_constant = ir->condition->constant_expression_value();
831346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt
832346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt	 assert(condition_constant && condition_constant->value.b[0]);
833346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   }
83484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
835b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt   t = this->create_tree(MB_TERM_assign, ir, l, r);
83684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mono_burg_label(t, NULL);
83784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   reduce(t, MB_NTERM_stmt);
83884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
83984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
84084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
84184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
84284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir)
84384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
84484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct mbtree *tree;
84584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
84684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(!ir->type->is_matrix());
84784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
848b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt   tree = this->create_tree(MB_TERM_reference_vec4, ir, NULL, NULL);
84984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
85050ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt   assert(ir->type->base_type == GLSL_TYPE_FLOAT ||
85150ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt	  ir->type->base_type == GLSL_TYPE_UINT ||
85250ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt	  ir->type->base_type == GLSL_TYPE_INT ||
85350ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt	  ir->type->base_type == GLSL_TYPE_BOOL);
85484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
85584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* FINISHME: This will end up being _mesa_add_unnamed_constant,
85684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * which handles sharing values and sharing channels of vec4
85784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * constants for small values.
85884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
85984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* FINISHME: Do something with the constant values for now.
86084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
861b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_to_mesa_set_tree_reg(tree, PROGRAM_CONSTANT, this->next_constant++);
86284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   tree->src_reg.swizzle = SWIZZLE_NOOP;
86384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
86484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   this->result = tree;
86584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
86684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
86784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
86884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
86984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir)
87084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
87184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   printf("Can't support call to %s\n", ir->callee_name());
87284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   exit(1);
87384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
87484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
87584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
87684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
87784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir)
87884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
87984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
88084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
88184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->coordinate->accept(this);
88284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
88384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
88484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
88584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir)
88684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
88784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
88884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
88984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->get_value()->accept(this);
89084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
89184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
89284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
89384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
89484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir)
89584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
896c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_to_mesa_instruction *if_inst, *else_inst = NULL;
897c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
898c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir->condition->accept(this);
899c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   assert(this->result);
900c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
901c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   if_inst = ir_to_mesa_emit_op1_full(this, ir->condition,
902c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt				      OPCODE_IF, ir_to_mesa_undef_dst,
903c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt				      this->result->src_reg);
904c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
905c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   this->instructions.push_tail(if_inst);
906c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
907c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   visit_exec_list(&ir->then_instructions, this);
908c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
909c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   if (!ir->else_instructions.is_empty()) {
910c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      else_inst = ir_to_mesa_emit_op1_full(this, ir->condition,
911c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt					   OPCODE_ELSE, ir_to_mesa_undef_dst,
912c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt					   ir_to_mesa_undef);
913c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      visit_exec_list(&ir->then_instructions, this);
914c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
915c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
916c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   if_inst = ir_to_mesa_emit_op1_full(this, ir->condition,
917c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt				      OPCODE_ENDIF, ir_to_mesa_undef_dst,
918c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt				      ir_to_mesa_undef);
91984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
92084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
921ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor()
922ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{
923ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt   result = NULL;
924ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt   next_temp = 1;
925ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt   next_constant = 0;
926ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt}
927ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt
92884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register
92984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
93084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
93184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_src_register mesa_reg;
93284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
93384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.File = reg.file;
934aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt   assert(reg.index < (1 << INST_INDEX_BITS) - 1);
93584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.Index = reg.index;
93634195832669f0eb7c4a80997cc524f8d10319307Eric Anholt   mesa_reg.Swizzle = reg.swizzle;
937bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt   mesa_reg.RelAddr = reg.reladdr;
93884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
93984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return mesa_reg;
94084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
94184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
942c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
943c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtset_branchtargets(struct prog_instruction *mesa_instructions,
944c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt		  int num_instructions)
945c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
94664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int if_count = 0, loop_count;
94764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int *if_stack, *loop_stack;
94864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int if_stack_pos = 0, loop_stack_pos = 0;
94964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int i, j;
950c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
951c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
95264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      switch (mesa_instructions[i].Opcode) {
95364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_IF:
954c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_count++;
95564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
95664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
95764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_count++;
95864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
95964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BRK:
96064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_CONT:
96164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = -1;
96264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
96364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      default:
96464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
96564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      }
966c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
967c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
96864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   if_stack = (int *)calloc(if_count, sizeof(*if_stack));
96964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
970c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
971c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
972c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      switch (mesa_instructions[i].Opcode) {
973c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_IF:
97464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos] = i;
975c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos++;
976c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
977c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ELSE:
97864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
97964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos - 1] = i;
980c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
981c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ENDIF:
98264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
983c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos--;
984c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
98564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
98664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack[loop_stack_pos] = i;
98764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos++;
98864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
98964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_ENDLOOP:
99064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos--;
99164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* Rewrite any breaks/conts at this nesting level (haven't
99264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * already had a BranchTarget assigned) to point to the end
99364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * of the loop.
99464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  */
99564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 for (j = loop_stack[loop_stack_pos]; j < i; j++) {
99664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    if (mesa_instructions[j].Opcode == OPCODE_BRK ||
99764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		mesa_instructions[j].Opcode == OPCODE_CONT) {
99864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       if (mesa_instructions[j].BranchTarget == -1) {
99964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		  mesa_instructions[j].BranchTarget = i;
100064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       }
100164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    }
100264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 }
100364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* The loop ends point at each other. */
100464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
100564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
1006c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      default:
1007c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1008c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
1009c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1010c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1011c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   free(if_stack);
1012c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
1013c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1014c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
1015c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions,
1016c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      ir_instruction **mesa_instruction_annotation,
1017c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      int num_instructions)
1018c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
1019c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction *last_ir = NULL;
1020c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
1021c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1022c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
1023c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      struct prog_instruction *mesa_inst = mesa_instructions + i;
1024c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      ir_instruction *ir = mesa_instruction_annotation[i];
1025c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
102664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      if (last_ir != ir && ir) {
1027c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 ir_print_visitor print;
1028c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 ir->accept(&print);
1029c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 printf("\n");
1030c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 last_ir = ir;
1031c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
1032c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1033c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      _mesa_print_instruction(mesa_inst);
1034c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1035c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
1036c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
103784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
103884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtdo_ir_to_mesa(exec_list *instructions)
103984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
104084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir_to_mesa_visitor v;
104184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_instruction *mesa_instructions, *mesa_inst;
1042c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction **mesa_instruction_annotation;
1043c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
104484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
104584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   visit_exec_list(instructions, &v);
104684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
104784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int num_instructions = 0;
104884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
104984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      num_instructions++;
105084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
105184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
105284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_instructions =
105384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      (struct prog_instruction *)calloc(num_instructions,
105484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt					sizeof(*mesa_instructions));
1055c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   mesa_instruction_annotation =
1056c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      (ir_instruction **)calloc(num_instructions,
1057c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt				sizeof(*mesa_instruction_annotation));
105884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
105984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_inst = mesa_instructions;
1060c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   i = 0;
106184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
106284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
1063b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt
106484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->Opcode = inst->op;
106584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.File = inst->dst_reg.file;
106684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.Index = inst->dst_reg.index;
10678197eeee3bbca4ab2deacfbf675285560f49e13cEric Anholt      mesa_inst->DstReg.CondMask = COND_TR;
106812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
106984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
107084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
107184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
1072c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      mesa_instruction_annotation[i] = inst->ir;
1073aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt
107484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst++;
1075c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      i++;
107684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
1077c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1078c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   set_branchtargets(mesa_instructions, num_instructions);
1079c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   print_program(mesa_instructions, mesa_instruction_annotation, num_instructions);
1080c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1081c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   free(mesa_instruction_annotation);
108284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
1083