ir_to_mesa.cpp revision d64343f1ae84979bd154475badf11af8a9bfc2eb
184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/*
2bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
3bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt * Copyright (C) 2008  VMware, Inc.   All Rights Reserved.
484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Copyright © 2010 Intel Corporation
584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Permission is hereby granted, free of charge, to any person obtaining a
784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * copy of this software and associated documentation files (the "Software"),
884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * to deal in the Software without restriction, including without limitation
984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * and/or sell copies of the Software, and to permit persons to whom the
1184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software is furnished to do so, subject to the following conditions:
1284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
1384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * The above copyright notice and this permission notice (including the next
1484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * paragraph) shall be included in all copies or substantial portions of the
1584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Software.
1684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
1784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * DEALINGS IN THE SOFTWARE.
2484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
2584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt/**
2784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * \file ir_to_mesa.cpp
2884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt *
2984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * Translates the IR to ARB_fragment_program text if possible,
3084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt * printing the result
3184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt */
3284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
330161515c395c44233529c8d51f823b60050bc7baEric Anholt#include <stdio.h>
3484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir.h"
3584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_visitor.h"
3684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_print_visitor.h"
3784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "ir_expression_flattening.h"
3884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "glsl_types.h"
39364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "glsl_parser_extras.h"
40364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "../glsl/program.h"
41364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ir_optimization.h"
42364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "ast.h"
4384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
44aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholtextern "C" {
450a1b54df7ac118722bb627c61cb322cb4e248aceEric Anholt#include "main/mtypes.h"
4684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt#include "shader/prog_instruction.h"
4728faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt#include "shader/prog_optimize.h"
48aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt#include "shader/prog_print.h"
49364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/program.h"
50364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/prog_uniform.h"
51364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/prog_parameter.h"
52364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt#include "shader/shader_api.h"
53aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt}
5484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
55554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/**
56554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with
57554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields.
58554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */
59554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_src_reg {
60554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
61554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
62582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
63554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int negate; /**< NEGATE_XYZW mask from mesa */
64f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /** Register index should be offset by the integer in this reg. */
65f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_src_reg *reladdr;
66554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_src_reg;
67554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
68554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_dst_reg {
69554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
70554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
71554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
72854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   GLuint cond_mask:4;
73f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /** Register index should be offset by the integer in this reg. */
74f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_src_reg *reladdr;
75554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_dst_reg;
76554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
77554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtextern ir_to_mesa_src_reg ir_to_mesa_undef;
78554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
79554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node {
80554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
81554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   enum prog_opcode op;
82554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_dst_reg dst_reg;
83554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_src_reg src_reg[3];
84554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** Pointer to the ir source this tree came from for debugging */
85554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_instruction *ir;
86854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   GLboolean cond_update;
87d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int sampler; /**< sampler index */
88d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int tex_target; /**< One of TEXTURE_*_INDEX */
89b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   GLboolean tex_shadow;
907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */
92554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
93554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
94b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node {
95554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
96b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage(ir_variable *var, int file, int index)
97554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      : file(file), index(index), var(var)
98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   {
99554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      /* empty */
100554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   }
101554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file;
103554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index;
104554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_variable *var; /* variable that maps to this, if any */
105554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
106554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node {
1087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic:
1097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_function_signature *sig;
1107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * identifier of this function signature used by the program.
1137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * At the point that Mesa instructions for function calls are
1157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * generated, we don't know the address of the first instruction of
1167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * the function body.  So we make the BranchTarget that is called a
1177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * small integer and rewrite them during set_branchtargets().
1187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int sig_id;
1207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Pointer to first instruction of the function body.
1237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Set during function body emits after main() is processed.
1257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_instruction *bgn_inst;
1277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Index of the first instruction of the function body in actual
1307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Mesa IR.
1317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Set after convertion from ir_to_mesa_instruction to prog_instruction.
1337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int inst;
1357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /** Storage for the return value. */
1377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_src_reg return_reg;
1387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt};
1397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
140554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor {
141554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
142554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_visitor();
143554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *current_function;
1457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
146364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   GLcontext *ctx;
147364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct gl_program *prog;
148364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
149554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int next_temp;
150a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
151b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *find_variable_storage(ir_variable *var);
152554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *get_function_signature(ir_function_signature *sig);
1547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1558364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   ir_to_mesa_src_reg get_temp(const glsl_type *type);
156f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   void reladdr_to_temp(ir_instruction *ir,
157f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt			ir_to_mesa_src_reg *reg, int *num_reladdr);
158554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
159554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg src_reg_for_float(float val);
160554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
161554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /**
162554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * \name Visit methods
163554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    *
164554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * As typical for the visitor pattern, there must be one \c visit method for
165554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * each concrete subclass of \c ir_instruction.  Virtual base classes within
166554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * the hierarchy should not have \c visit methods.
167554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    */
168554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@{*/
169554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_variable *);
170554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop *);
171554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop_jump *);
172554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function_signature *);
173554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function *);
174554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_expression *);
175554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_swizzle *);
176554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_variable  *);
177554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_array *);
178554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_record *);
179554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_assignment *);
180554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_constant *);
181554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_call *);
182554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_return *);
18316efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke   virtual void visit(ir_discard *);
184554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_texture *);
185554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_if *);
186554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@}*/
187554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
188554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg result;
189554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
190b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   /** List of variable_storage */
191b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   exec_list variables;
192554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /** List of function_entry */
1947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   exec_list function_signatures;
1957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int next_signature_id;
1967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
197554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** List of ir_to_mesa_instruction */
198554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   exec_list instructions;
199554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
200021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir,
201021222c6a872ca2eef770ebadb8754f659775204Eric Anholt					       enum prog_opcode op);
202021222c6a872ca2eef770ebadb8754f659775204Eric Anholt
203554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
204554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
205554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
206554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0);
207554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
208554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
209554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
210554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
211554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
212554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1);
213554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
214554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
215554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
216554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
217554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
218554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1,
219554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src2);
220554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
221554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
222554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   enum prog_opcode op,
223554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_dst_reg dst,
224554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_src_reg src0);
2250ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt
226904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
227904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   enum prog_opcode op,
228904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_dst_reg dst,
229904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_src_reg src0,
230904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_src_reg src1);
231904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
2323f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   GLboolean try_emit_mad(ir_expression *ir,
2333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt			  int mul_operand);
2343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
235d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int *sampler_map;
236d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int sampler_map_size;
237d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
238d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   void map_sampler(int location, int sampler);
239d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int get_sampler_number(int location);
240d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
241364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   void *mem_ctx;
242554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
243554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
24484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_src_reg ir_to_mesa_undef = {
245f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, NULL,
24684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt};
24784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
248c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
249f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL,
250c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt};
251c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2520161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = {
253f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL
2540161515c395c44233529c8d51f823b60050bc7baEric Anholt};
2550161515c395c44233529c8d51f823b60050bc7baEric Anholt
2560161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic int swizzle_for_size(int size)
2570161515c395c44233529c8d51f823b60050bc7baEric Anholt{
2580161515c395c44233529c8d51f823b60050bc7baEric Anholt   int size_swizzles[4] = {
2590161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
2600161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
2610161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
2620161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
2630161515c395c44233529c8d51f823b60050bc7baEric Anholt   };
2640161515c395c44233529c8d51f823b60050bc7baEric Anholt
2650161515c395c44233529c8d51f823b60050bc7baEric Anholt   return size_swizzles[size - 1];
2660161515c395c44233529c8d51f823b60050bc7baEric Anholt}
2670161515c395c44233529c8d51f823b60050bc7baEric Anholt
26884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
2690161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
2700161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
2710161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
2720161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
2730161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1,
2740161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src2)
27584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
276364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
277f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   int num_reladdr = 0;
278f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
279f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /* If we have to do relative addressing, we want to load the ARL
280f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    * reg directly for one of the regs, and preload the other reladdr
281f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    * sources into temps.
282f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    */
283f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += dst.reladdr != NULL;
284f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src0.reladdr != NULL;
285f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src1.reladdr != NULL;
286f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src2.reladdr != NULL;
287f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
288f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src2, &num_reladdr);
289f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src1, &num_reladdr);
290f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src0, &num_reladdr);
291f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
292f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (dst.reladdr) {
293f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
294f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt                          *dst.reladdr);
295f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
296f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      num_reladdr--;
297f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   }
298f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   assert(num_reladdr == 0);
29984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
30084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->op = op;
30184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->dst_reg = dst;
30284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[0] = src0;
30384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[1] = src1;
30484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[2] = src2;
305c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   inst->ir = ir;
30684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   inst->function = NULL;
3087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
3090161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->instructions.push_tail(inst);
31084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
31184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return inst;
31284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
31384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
31484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
31584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
3160161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
3170161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
3180161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
3190161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
3200161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1)
32184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
3220161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
32384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
32484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
32584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
3260161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
3270161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
3280161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
3290161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0)
330bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{
3310161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst,
3320161515c395c44233529c8d51f823b60050bc7baEric Anholt			      src0, ir_to_mesa_undef, ir_to_mesa_undef);
333bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
334bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
335021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction *
336021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir,
337021222c6a872ca2eef770ebadb8754f659775204Eric Anholt					enum prog_opcode op)
338021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{
339021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst,
340021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef,
341021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef,
342021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef);
343021222c6a872ca2eef770ebadb8754f659775204Eric Anholt}
344021222c6a872ca2eef770ebadb8754f659775204Eric Anholt
345d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtvoid
346d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtir_to_mesa_visitor::map_sampler(int location, int sampler)
347d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{
348d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   if (this->sampler_map_size <= location) {
349d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      this->sampler_map = talloc_realloc(this->mem_ctx, this->sampler_map,
350d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					 int, location + 1);
351d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      this->sampler_map_size = location + 1;
352d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
353d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
354d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   this->sampler_map[location] = sampler;
355d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt}
356d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
357d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtint
358d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtir_to_mesa_visitor::get_sampler_number(int location)
359d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{
360d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   assert(location < this->sampler_map_size);
361d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   return this->sampler_map[location];
362d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt}
363d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
3640161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg
3650161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
36684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
3670161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_dst_reg dst_reg;
36884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3690161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.file = reg.file;
3700161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.index = reg.index;
3710161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.writemask = WRITEMASK_XYZW;
372854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   dst_reg.cond_mask = COND_TR;
373f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   dst_reg.reladdr = reg.reladdr;
3740161515c395c44233529c8d51f823b60050bc7baEric Anholt
3750161515c395c44233529c8d51f823b60050bc7baEric Anholt   return dst_reg;
376bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
377bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
3782d1789e667c4180777829f96856daf91326721b9Eric Anholtinline ir_to_mesa_src_reg
3792d1789e667c4180777829f96856daf91326721b9Eric Anholtir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg)
3802d1789e667c4180777829f96856daf91326721b9Eric Anholt{
3812d1789e667c4180777829f96856daf91326721b9Eric Anholt   ir_to_mesa_src_reg src_reg;
3822d1789e667c4180777829f96856daf91326721b9Eric Anholt
3832d1789e667c4180777829f96856daf91326721b9Eric Anholt   src_reg.file = reg.file;
3842d1789e667c4180777829f96856daf91326721b9Eric Anholt   src_reg.index = reg.index;
3852d1789e667c4180777829f96856daf91326721b9Eric Anholt   src_reg.swizzle = SWIZZLE_XYZW;
3862d1789e667c4180777829f96856daf91326721b9Eric Anholt   src_reg.negate = 0;
387f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = reg.reladdr;
3882d1789e667c4180777829f96856daf91326721b9Eric Anholt
3892d1789e667c4180777829f96856daf91326721b9Eric Anholt   return src_reg;
3902d1789e667c4180777829f96856daf91326721b9Eric Anholt}
3912d1789e667c4180777829f96856daf91326721b9Eric Anholt
39212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/**
39312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels.
39412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt *
39512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp.  The src X
39612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels.  So to do a vec4
39712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used
39812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels.
39912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */
40012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid
401904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
4020161515c395c44233529c8d51f823b60050bc7baEric Anholt					       enum prog_opcode op,
4030161515c395c44233529c8d51f823b60050bc7baEric Anholt					       ir_to_mesa_dst_reg dst,
404904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg orig_src0,
405904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg orig_src1)
40612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{
40712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   int i, j;
408315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt   int done_mask = ~dst.writemask;
40912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
41012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   /* Mesa RCP is a scalar operation splatting results to all channels,
41112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
41212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * dst channels.
41312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    */
41412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   for (i = 0; i < 4; i++) {
415582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt      GLuint this_mask = (1 << i);
41612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      ir_to_mesa_instruction *inst;
417904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_src_reg src0 = orig_src0;
418904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_src_reg src1 = orig_src1;
41912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
42012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      if (done_mask & this_mask)
42112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 continue;
42212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
423904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
424904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
42512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      for (j = i + 1; j < 4; j++) {
426904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	 if (!(done_mask & (1 << j)) &&
427904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	     GET_SWZ(src0.swizzle, j) == src0_swiz &&
428904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	     GET_SWZ(src1.swizzle, j) == src1_swiz) {
42912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	    this_mask |= (1 << j);
43012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 }
43112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      }
432904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
433904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   src0_swiz, src0_swiz);
434904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
435904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				  src1_swiz, src1_swiz);
43612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
437904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      inst = ir_to_mesa_emit_op2(ir, op,
4380161515c395c44233529c8d51f823b60050bc7baEric Anholt				 dst,
439904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				 src0,
440904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				 src1);
44112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      inst->dst_reg.writemask = this_mask;
44212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      done_mask |= this_mask;
44312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   }
44412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt}
44512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
446904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid
447904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
448904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       enum prog_opcode op,
449904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_dst_reg dst,
450904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg src0)
451904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{
45259a23d7fb93603b2449db4c5d786934a07aebfcbEric Anholt   ir_to_mesa_src_reg undef = ir_to_mesa_undef;
453904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
454904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   undef.swizzle = SWIZZLE_XXXX;
455904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
456904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
457904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt}
458904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
4590161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg
4600161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val)
461b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
4620161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
4631d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4640161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.file = PROGRAM_CONSTANT;
465582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
466582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt					      &val, 1, &src_reg.swizzle);
467f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = NULL;
4688bb15c1ed55eb71533d2af94a6afbf01e3d23610Eric Anholt   src_reg.negate = 0;
4691d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4700161515c395c44233529c8d51f823b60050bc7baEric Anholt   return src_reg;
4711d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt}
4721d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4732c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int
4742c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type)
4752c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
4762c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
4772c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int size;
4782c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
4792c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   switch (type->base_type) {
4802c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_UINT:
4812c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_INT:
4822c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_FLOAT:
4832c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_BOOL:
484a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      if (type->is_matrix()) {
4859968f1b23c475c99139f0209c7a049ed00df01afEric Anholt	 return type->matrix_columns;
486a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      } else {
487a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 /* Regardless of size of vector, it gets a vec4. This is bad
488a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * packing for things like floats, but otherwise arrays become a
489a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * mess.  Hopefully a later pass over the code can pack scalars
490a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * down if appropriate.
491a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  */
492a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return 1;
493a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      }
4942c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_ARRAY:
4952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return type_size(type->fields.array) * type->length;
4962c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_STRUCT:
4972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      size = 0;
4982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      for (i = 0; i < type->length; i++) {
4992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 size += type_size(type->fields.structure[i].type);
5002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      }
5012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return size;
5022c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   default:
5032c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(0);
5042c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
5052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
5062c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
507d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/**
508d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to
509d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results.  (not SSA -- variable assignments will reuse
510d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage).  Actual register allocation for the Mesa VM occurs in a
511d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later.
512d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */
513d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_src_reg
514d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type)
515d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{
516d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   ir_to_mesa_src_reg src_reg;
517d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   int swizzle[4];
518d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   int i;
519d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
520d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   assert(!type->is_array());
521d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
522d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.file = PROGRAM_TEMPORARY;
523d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.index = next_temp;
524f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = NULL;
525d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   next_temp += type_size(type);
526d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
527d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   for (i = 0; i < type->vector_elements; i++)
528d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt      swizzle[i] = i;
529d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   for (; i < 4; i++)
530d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt      swizzle[i] = type->vector_elements - 1;
531d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
532d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt				   swizzle[2], swizzle[3]);
533ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt   src_reg.negate = 0;
534d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
535d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   return src_reg;
536d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt}
537d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
538b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage *
539a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var)
54084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
541a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
542b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry;
54384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
544b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   foreach_iter(exec_list_iterator, iter, this->variables) {
545b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      entry = (variable_storage *)iter.get();
54684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
5470161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (entry->var == var)
548a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return entry;
54984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
55084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
551a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt   return NULL;
552a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt}
55384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
55484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
55584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir)
55684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
5578364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   (void)ir;
55884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
55984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
56084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
56184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir)
56284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
56364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->from);
56464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->to);
56564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->increment);
56664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->counter);
56784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
568021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP);
56964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   visit_exec_list(&ir->body_instructions, this);
570021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP);
57184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
57284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
57384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir)
57584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
57664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   switch (ir->mode) {
57764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_break:
578021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      ir_to_mesa_emit_op0(NULL, OPCODE_BRK);
57964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
58064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_continue:
581021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      ir_to_mesa_emit_op0(NULL, OPCODE_CONT);
58264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
58364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   }
58484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
58584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
58684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
58784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
58884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir)
58984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
59084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
59184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   (void)ir;
59284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
59384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
59484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
59584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir)
59684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
59784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* Ignore function bodies other than main() -- we shouldn't see calls to
59884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * them since they should all be inlined before we get to ir_to_mesa.
59984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
60084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   if (strcmp(ir->name, "main") == 0) {
60184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      const ir_function_signature *sig;
60284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      exec_list empty;
60384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
60484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      sig = ir->matching_signature(&empty);
60584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
60684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      assert(sig);
60784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
60884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      foreach_iter(exec_list_iterator, iter, sig->body) {
60984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_instruction *ir = (ir_instruction *)iter.get();
61084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
61184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->accept(this);
61284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
61384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
61484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
61584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6163f08989267d9cdd944787fcf7a300c6f1f84462cEric AnholtGLboolean
6173f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
6183f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{
6193f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   int nonmul_operand = 1 - mul_operand;
6203f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_to_mesa_src_reg a, b, c;
6213f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6223f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_expression *expr = ir->operands[mul_operand]->as_expression();
6233f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   if (!expr || expr->operation != ir_binop_mul)
6243f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      return false;
6253f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6263f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   expr->operands[0]->accept(this);
6273f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   a = this->result;
6283f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   expr->operands[1]->accept(this);
6293f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   b = this->result;
6303f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir->operands[nonmul_operand]->accept(this);
6313f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   c = this->result;
6323f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   this->result = get_temp(ir->type);
6343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_to_mesa_emit_op3(ir, OPCODE_MAD,
6353f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt		       ir_to_mesa_dst_reg_from_src(this->result), a, b, c);
6363f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6373f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   return true;
6383f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt}
6393f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
64084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
641f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir,
642f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt				    ir_to_mesa_src_reg *reg, int *num_reladdr)
643f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{
644f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (!reg->reladdr)
645f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      return;
646f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
647f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr);
648f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
649f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (*num_reladdr != 1) {
650f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
651f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
652f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV,
653f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt			  ir_to_mesa_dst_reg_from_src(temp), *reg);
654f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      *reg = temp;
655f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   }
656f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
657f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   (*num_reladdr)--;
658f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt}
659f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
660f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid
66184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir)
66284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
66384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   unsigned int operand;
664f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt   struct ir_to_mesa_src_reg op[2];
6650161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg result_src;
6660161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg result_dst;
66784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
66884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
66984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
67084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6713f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
6723f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt    */
6733f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   if (ir->operation == ir_binop_add) {
6743f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      if (try_emit_mad(ir, 1))
6753f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt	 return;
6763f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      if (try_emit_mad(ir, 0))
6773f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt	 return;
6783f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   }
6793f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
68084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (operand = 0; operand < ir->get_num_operands(); operand++) {
6810161515c395c44233529c8d51f823b60050bc7baEric Anholt      this->result.file = PROGRAM_UNDEFINED;
68284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir->operands[operand]->accept(this);
6830161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (this->result.file == PROGRAM_UNDEFINED) {
68484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_print_visitor v;
68584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 printf("Failed to get tree for expression operand:\n");
68684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->operands[operand]->accept(&v);
68784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 exit(1);
68884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
68984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      op[operand] = this->result;
6908364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
6914ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      /* Matrix expression operands should have been broken down to vector
6924ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt       * operations already.
6934ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt       */
6944ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      assert(!ir->operands[operand]->type->is_matrix());
69584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
69684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6970161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.file = PROGRAM_UNDEFINED;
6980161515c395c44233529c8d51f823b60050bc7baEric Anholt
6990161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
7000161515c395c44233529c8d51f823b60050bc7baEric Anholt    * the actual storage for the result here, instead.
7010161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
7028364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   result_src = get_temp(ir->type);
7030161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* convenience for the emit functions below. */
7040161515c395c44233529c8d51f823b60050bc7baEric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
7059cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   /* Limit writes to the channels that will be used by result_src later.
7069cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * This does limit this temp's use as a temporary for multi-instruction
7079cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * sequences.
7089cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    */
7099cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
71084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
71184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   switch (ir->operation) {
7121d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_logic_not:
713f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
714f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt			  op[0], src_reg_for_float(0.0));
7151d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
716c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   case ir_unop_neg:
7170161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
7180161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
719c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt      break;
720524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt   case ir_unop_abs:
721524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
722524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt      break;
7233acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt   case ir_unop_sign:
7243acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]);
7253acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt      break;
7268761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt   case ir_unop_rcp:
7278761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]);
7288761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt      break;
729524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt
7308c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp:
731b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst,
732b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt				 src_reg_for_float(M_E), op[0]);
7338c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7348c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp2:
7350161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
7368c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7378c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log:
7380161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
7398c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7408c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log2:
7410161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
7428c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7433c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_sin:
7440161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
7453c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
7463c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_cos:
7470161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
7483c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
749ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt
750ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt   case ir_unop_dFdx:
751ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
752ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      break;
753ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt   case ir_unop_dFdy:
754ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
755ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      break;
756ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt
75784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_add:
7587b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
75984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
76084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_sub:
7617b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
76284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
7639b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt
76484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_mul:
7654ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
76684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
76784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_div:
7689a0e421983edc31371440c08687fa2bb2207924dEric Anholt      assert(!"not reached: should be handled by ir_div_to_mul_rcp");
769411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt   case ir_binop_mod:
770411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt      assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
771411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt      break;
77238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
77338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_less:
774f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
77538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
77638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_greater:
777f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
77838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
77938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_lequal:
780f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
78138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
78238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_gequal:
783f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
78438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
78538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_equal:
786f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
78738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
788763cd75863ed9a16912e585887580c44d1e8109fEric Anholt   case ir_binop_logic_xor:
78938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_nequal:
790f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
79138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
79238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
7934380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_or:
7940161515c395c44233529c8d51f823b60050bc7baEric Anholt      /* This could be a saturated add and skip the SNE. */
7950161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD,
7960161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
7970161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
7980161515c395c44233529c8d51f823b60050bc7baEric Anholt
7990161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE,
8000161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
8010161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
8024380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
8034380099c98119611ceee684669d00be26195c7d7Eric Anholt
8044380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_and:
8054380099c98119611ceee684669d00be26195c7d7Eric Anholt      /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
8060161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL,
8070161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
8080161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
8094380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
8104380099c98119611ceee684669d00be26195c7d7Eric Anholt
81184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_dot:
81284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (ir->operands[0]->type == vec4_type) {
81384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec4_type);
8140161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP4,
8150161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8160161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
81784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec3_type) {
81884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec3_type);
8190161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP3,
8200161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8210161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
82284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec2_type) {
82384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec2_type);
8240161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP2,
8250161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8260161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
82784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
82884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
8299be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt
8309be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt   case ir_binop_cross:
8319be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]);
8329be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt      break;
8339be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt
83484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_unop_sqrt:
8350161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
8368f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src);
8378f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      /* For incoming channels < 0, set the result to 0. */
8388f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
8398f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt			  op[0], src_reg_for_float(0.0), result_src);
84084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
841878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt   case ir_unop_rsq:
8420161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
843878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt      break;
84450ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt   case ir_unop_i2f:
845d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt   case ir_unop_b2f:
846d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt   case ir_unop_b2i:
847423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      /* Mesa IR lacks types, ints are stored as truncated floats. */
8480161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
84950ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt      break;
850423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt   case ir_unop_f2i:
8510161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
852423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      break;
8531d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_f2b:
854411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt   case ir_unop_i2b:
8550161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
8560161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
8571d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
858c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_trunc:
8590161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
860c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
861c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_ceil:
8620161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
8630161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
8640161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src.negate = ~result_src.negate;
865c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
866c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_floor:
8670161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
868c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
869d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt   case ir_unop_fract:
870d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]);
871d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt      break;
872d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt
873c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_min:
8740161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
875c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
876c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_max:
8770161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
878c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
879904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   case ir_binop_pow:
880904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
881904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      break;
882e64a4aaacbc682f24180dff3627b84861844476dEric Anholt
883e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_unop_bit_not:
884e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_unop_u2f:
885e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_lshift:
886e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_rshift:
887e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_and:
888e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_xor:
889e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_or:
890e64a4aaacbc682f24180dff3627b84861844476dEric Anholt      assert(!"GLSL 1.30 features unsupported");
891e64a4aaacbc682f24180dff3627b84861844476dEric Anholt      break;
89284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
893b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt
8940161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = result_src;
89584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
89684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
89784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
89884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
89984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir)
90084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
9010161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
90284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int i;
90384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int swizzle[4];
90484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
905b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   /* Note that this is only swizzles in expressions, not those on the left
906b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * hand side of an assignment, which do write masking.  See ir_assignment
907b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * for that.
908b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    */
90984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
91084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->val->accept(this);
9114006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   src_reg = this->result;
9124006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   assert(src_reg.file != PROGRAM_UNDEFINED);
91384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
91484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (i = 0; i < 4; i++) {
91584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (i < ir->type->vector_elements) {
91684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 switch (i) {
91784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 0:
918698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
91984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
92084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 1:
921698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
92284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
92384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 2:
924698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
92584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
92684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 3:
927698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
92884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
92984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 }
93084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else {
93184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 /* If the type is smaller than a vec4, replicate the last
93284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  * channel out.
93384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  */
934698b84444343189357ad252856d3c5493e47e4faEric Anholt	 swizzle[i] = swizzle[ir->type->vector_elements - 1];
93584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
93684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
93784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9380161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
9390161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[1],
9400161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[2],
9410161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[3]);
94284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9430161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
94484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
94584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
94676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtstatic int
94776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtadd_matrix_ref(struct gl_program *prog, int *tokens)
94876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt{
94976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   int base_pos = -1;
95076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   int i;
95176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
95276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   /* Add a ref for each column.  It looks like the reason we do
95376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * it this way is that _mesa_add_state_reference doesn't work
95476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * for things that aren't vec4s, so the tokens[2]/tokens[3]
95576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * range has to be equal.
95676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    */
95776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   for (i = 0; i < 4; i++) {
95876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      tokens[2] = i;
95976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      tokens[3] = i;
96076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      int pos = _mesa_add_state_reference(prog->Parameters,
96176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt					  (gl_state_index *)tokens);
96276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      if (base_pos == -1)
96376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 base_pos = pos;
96476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      else
96576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 assert(base_pos + i == pos);
96676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   }
96776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
96876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   return base_pos;
96976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt}
97076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
971b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtstatic variable_storage *
97276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtget_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
97376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		       ir_rvalue *array_index)
974bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt{
975bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   /*
976bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * NOTE: The ARB_vertex_program extension specified that matrices get
977bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * loaded in registers in row-major order.  With GLSL, we want column-
978bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * major order.  So, we need to transpose all matrices here...
979bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    */
980bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   static const struct {
981bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      const char *name;
982bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      int matrix;
983bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      int modifier;
984bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   } matrices[] = {
985bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
986bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
987bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
988bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
989bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
990bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
991bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
992bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
993bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
994bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
995bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
996bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
997bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
998bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
999bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1000bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
1001bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
1002bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
1003bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
1004bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1005bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
1006bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1007bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   };
1008bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   unsigned int i;
1009b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry;
1010bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1011bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   /* C++ gets angry when we try to use an int as a gl_state_index, so we use
1012bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * ints for gl_state_index.  Make sure they're compatible.
1013bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    */
1014bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   assert(sizeof(gl_state_index) == sizeof(int));
1015bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1016bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   for (i = 0; i < Elements(matrices); i++) {
1017bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      if (strcmp(var->name, matrices[i].name) == 0) {
1018bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 int tokens[STATE_LENGTH];
101976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 int base_pos = -1;
1020bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1021bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[0] = matrices[i].matrix;
1022bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[4] = matrices[i].modifier;
102376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 if (matrices[i].matrix == STATE_TEXTURE_MATRIX) {
102476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    ir_constant *index = array_index->constant_expression_value();
102576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    if (index) {
102676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       tokens[1] = index->value.i[0];
102776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       base_pos = add_matrix_ref(prog, tokens);
102876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    } else {
102976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       for (i = 0; i < var->type->length; i++) {
103076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  tokens[1] = i;
103176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  int pos = add_matrix_ref(prog, tokens);
103276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  if (base_pos == -1)
103376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		     base_pos = pos;
103476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  else
103576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		     assert(base_pos + (int)i * 4 == pos);
103676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       }
103776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    }
103876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 } else {
103976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    tokens[1] = 0; /* unused array index */
104076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    base_pos = add_matrix_ref(prog, tokens);
1041bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 }
104276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 tokens[4] = matrices[i].modifier;
1043bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1044b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(var,
1045b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       PROGRAM_STATE_VAR,
1046b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       base_pos);
1047bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1048bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 return entry;
1049bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      }
1050bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   }
1051bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1052bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   return NULL;
1053bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt}
1054bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
105584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
105684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir)
105784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
10580161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
1059b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry = find_variable_storage(ir->var);
1060a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt   unsigned int loc;
106184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
10628364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   if (!entry) {
10638364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      switch (ir->var->mode) {
10648364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_uniform:
106576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var,
106676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt					NULL);
1067bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 if (entry)
1068bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	    break;
1069bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
107085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 /* FINISHME: Fix up uniform name for arrays and things */
1071d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) {
1072d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    /* FINISHME: we whack the location of the var here, which
1073d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	     * is probably not expected.  But we need to communicate
1074d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	     * mesa's sampler number to the tex instruction.
1075d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	     */
1076d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    int sampler = _mesa_add_sampler(this->prog->Parameters,
1077d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					    ir->var->name,
1078d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					    ir->var->type->gl_type);
1079d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    map_sampler(ir->var->location, sampler);
1080d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1081b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_SAMPLER,
1082b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  sampler);
1083b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    this->variables.push_tail(entry);
1084d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    break;
1085d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 }
1086d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
108785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 assert(ir->var->type->gl_type != 0 &&
108885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt		ir->var->type->gl_type != GL_INVALID_ENUM);
108985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 loc = _mesa_add_uniform(this->prog->Parameters,
109085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 ir->var->name,
109185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 type_size(ir->var->type) * 4,
109285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 ir->var->type->gl_type,
109385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 NULL);
1094d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
109585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 /* Always mark the uniform used at this point.  If it isn't
109685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	  * used, dead code elimination should have nuked the decl already.
109785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	  */
109885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 this->prog->Parameters->Parameters[loc].Used = GL_TRUE;
1099224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
1100b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM, loc);
1101b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 this->variables.push_tail(entry);
11028364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
11038364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_in:
11048364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_out:
11058364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_inout:
1106a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	 /* The linker assigns locations for varyings and attributes,
1107a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * including deprecated builtins (like gl_Color), user-assign
1108a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * generic attributes (glBindVertexLocation), and
1109a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * user-defined varyings.
1110a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  *
1111a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * FINISHME: We would hit this path for function arguments.  Fix!
1112f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	  */
1113f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 assert(ir->var->location != -1);
1114a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	 if (ir->var->mode == ir_var_in ||
1115a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	     ir->var->mode == ir_var_inout) {
1116b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var,
1117b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  PROGRAM_INPUT,
1118b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  ir->var->location);
1119edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt
1120edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	    if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
1121edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt		ir->var->location >= VERT_ATTRIB_GENERIC0) {
1122edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	       _mesa_add_attribute(prog->Attributes,
1123edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   ir->var->name,
1124edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   type_size(ir->var->type) * 4,
1125edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   ir->var->type->gl_type,
1126c64da87611823b4b53e93188f861f748a69936a3Eric Anholt				   ir->var->location - VERT_ATTRIB_GENERIC0);
1127edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	    }
1128f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 } else {
1129b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var,
1130b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  PROGRAM_OUTPUT,
1131b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  ir->var->location);
1132f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 }
1133f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt
11348364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
11358364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_auto:
11367e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick      case ir_var_temporary:
1137b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY,
1138b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       this->next_temp);
1139b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 this->variables.push_tail(entry);
1140224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
11418364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 next_temp += type_size(ir->var->type);
11428364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
114384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
11448364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
11458364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      if (!entry) {
11468364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 printf("Failed to make storage for %s\n", ir->var->name);
11478364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 exit(1);
1148224f712950494730c76b48864f2ca19acde1c8cfEric Anholt      }
114984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
115084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
11518364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.file = entry->file;
11528364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.index = entry->index;
115384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
115485e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   if (ir->type->is_scalar() || ir->type->is_vector())
115585e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
115685e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   else
115785e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = SWIZZLE_NOOP;
1158f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = NULL;
11590161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.negate = 0;
116084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
11610161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
116284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
116384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
116484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
116584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir)
116684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1167ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir_constant *index;
11680161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
116976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   ir_dereference_variable *deref_var = ir->array->as_dereference_variable();
11708258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt   int element_size = type_size(ir->type);
1171ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt
1172ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   index = ir->array_index->constant_expression_value();
11734e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
117476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   if (deref_var && strncmp(deref_var->var->name,
117576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			    "gl_TextureMatrix",
117676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			    strlen("gl_TextureMatrix")) == 0) {
117776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      ir_to_mesa_src_reg src_reg;
1178b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      struct variable_storage *entry;
117976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
118076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var,
118176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt				     ir->array_index);
118276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      assert(entry);
118376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
118476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      src_reg.file = entry->file;
118576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      src_reg.index = entry->index;
118676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
118776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      src_reg.negate = 0;
118876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
118976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      if (index) {
1190f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 src_reg.reladdr = NULL;
119176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      } else {
119276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type);
119376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
119476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir->array_index->accept(this);
119576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
119676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			     ir_to_mesa_dst_reg_from_src(index_reg),
11978258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt			     this->result, src_reg_for_float(element_size));
119876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
1199f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
1200f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
120176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      }
120276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
120376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      this->result = src_reg;
120476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      return;
120576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   }
120676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
1207ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir->array->accept(this);
12080161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg = this->result;
12094e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
12104d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   if (index) {
12114d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      src_reg.index += index->value.i[0] * element_size;
12124e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   } else {
12134d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir_to_mesa_src_reg array_base = this->result;
12144d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      /* Variable index array dereference.  It eats the "vec4" of the
12154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       * base of the array and an index that offsets the Mesa register
12164d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       * index.
12174d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       */
12184d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir->array_index->accept(this);
12198258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt
12204d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir_to_mesa_src_reg index_reg;
12218258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt
12224d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      if (element_size == 1) {
12234d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 index_reg = this->result;
12244d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      } else {
12254d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 index_reg = get_temp(glsl_type::float_type);
1226f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
12274d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
12284d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			     ir_to_mesa_dst_reg_from_src(index_reg),
12294d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			     this->result, src_reg_for_float(element_size));
1230bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      }
12314d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
12324d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
12334d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
12344e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   }
123584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
123684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
123785e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   if (ir->type->is_scalar() || ir->type->is_vector())
123885e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
123985e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   else
124085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = SWIZZLE_NOOP;
124184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
12420161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
124384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
124484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
12452c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid
12462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir)
12472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
12482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
12490161515c395c44233529c8d51f823b60050bc7baEric Anholt   const glsl_type *struct_type = ir->record->type;
12502c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int offset = 0;
12512c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
12520161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir->record->accept(this);
12532c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
12542c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   for (i = 0; i < struct_type->length; i++) {
12550161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
12562c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 break;
12572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      offset += type_size(struct_type->fields.structure[i].type);
12582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
125985e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
12600161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.index += offset;
12612c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
12622c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
12632c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/**
12642c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage
12652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the
12662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler.
12672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt *
12682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
12692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * should only see potentially one variable array index of a vector,
12702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * and one swizzle, before getting to actual vec4 storage.  So handle
12712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * those, then go use ir_dereference to handle the rest.
12722c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */
12730161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg
127418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholtget_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v,
127518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt		   ir_to_mesa_src_reg *r)
1276b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
12770161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg dst_reg;
1278b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_swizzle *swiz;
1279b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
1280ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   ir_dereference_array *deref_array = ir->as_dereference_array();
1281ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   /* This should have been handled by ir_vec_index_to_cond_assign */
1282ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   if (deref_array) {
1283ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt      assert(!deref_array->array->type->is_vector());
1284ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   }
1285ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt
12860161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Use the rvalue deref handler for the most part.  We'll ignore
12870161515c395c44233529c8d51f823b60050bc7baEric Anholt    * swizzles in it and write swizzles using writemask, though.
12880161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
12892c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   ir->accept(v);
12900161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
12912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
1292ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   if ((swiz = ir->as_swizzle())) {
129318ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      int swizzles[4] = {
129418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 swiz->mask.x,
129518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 swiz->mask.y,
129618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 swiz->mask.z,
129718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 swiz->mask.w
129818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      };
129918ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      int new_r_swizzle[4];
130018ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      int orig_r_swizzle = r->swizzle;
130118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      int i;
130218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt
130318ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      for (i = 0; i < 4; i++) {
130418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 new_r_swizzle[i] = GET_SWZ(orig_r_swizzle, 0);
130518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      }
1306cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
130718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      dst_reg.writemask = 0;
130818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      for (i = 0; i < 4; i++) {
130918ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 if (i < swiz->mask.num_components) {
131018ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	    dst_reg.writemask |= 1 << swizzles[i];
131118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	    new_r_swizzle[swizzles[i]] = GET_SWZ(orig_r_swizzle, i);
131218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 }
1313cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt      }
131418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt
131518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      r->swizzle = MAKE_SWIZZLE4(new_r_swizzle[0],
131618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt				 new_r_swizzle[1],
131718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt				 new_r_swizzle[2],
131818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt				 new_r_swizzle[3]);
1319cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt   }
1320cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
132118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt   return dst_reg;
1322cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt}
1323cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
132484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
132584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir)
132684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
13270161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg l;
13280161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg r;
13297d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt   int i;
133084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
13312c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(!ir->lhs->type->is_array());
13322c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
133384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->rhs->accept(this);
133484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   r = this->result;
1335cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
133618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt   l = get_assignment_lhs(ir->lhs, this, &r);
1337cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
13380161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(l.file != PROGRAM_UNDEFINED);
13390161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(r.file != PROGRAM_UNDEFINED);
134084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1341346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   if (ir->condition) {
13422d1789e667c4180777829f96856daf91326721b9Eric Anholt      ir_to_mesa_src_reg condition;
13432d1789e667c4180777829f96856daf91326721b9Eric Anholt
13442d1789e667c4180777829f96856daf91326721b9Eric Anholt      ir->condition->accept(this);
13452d1789e667c4180777829f96856daf91326721b9Eric Anholt      condition = this->result;
13462d1789e667c4180777829f96856daf91326721b9Eric Anholt
13472d1789e667c4180777829f96856daf91326721b9Eric Anholt      /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves,
13482d1789e667c4180777829f96856daf91326721b9Eric Anholt       * and the condition we produced is 0.0 or 1.0.  By flipping the
13492d1789e667c4180777829f96856daf91326721b9Eric Anholt       * sign, we can choose which value OPCODE_CMP produces without
13502d1789e667c4180777829f96856daf91326721b9Eric Anholt       * an extra computing the condition.
13512d1789e667c4180777829f96856daf91326721b9Eric Anholt       */
13522d1789e667c4180777829f96856daf91326721b9Eric Anholt      condition.negate = ~condition.negate;
13537d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      for (i = 0; i < type_size(ir->lhs->type); i++) {
13547d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 ir_to_mesa_emit_op3(ir, OPCODE_CMP, l,
13557d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt			     condition, r, ir_to_mesa_src_reg_from_dst(l));
13567d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 l.index++;
13577d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 r.index++;
13587d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      }
13592d1789e667c4180777829f96856daf91326721b9Eric Anholt   } else {
13607d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      for (i = 0; i < type_size(ir->lhs->type); i++) {
13617d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
13627d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 l.index++;
13637d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 r.index++;
13647d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      }
1365346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   }
136684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
136784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
136884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
136984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
137084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir)
137184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
13720161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
13730bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   GLfloat stack_vals[4];
13740bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   GLfloat *values = stack_vals;
13750bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   unsigned int i;
137684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1377ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt   if (ir->type->is_array()) {
1378ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      ir->print();
1379ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      printf("\n");
1380ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      assert(!"FINISHME: array constants");
1381ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt   }
1382ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1383ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt   if (ir->type->is_matrix()) {
1384ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      /* Unfortunately, 4 floats is all we can get into
1385ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt       * _mesa_add_unnamed_constant.  So, make a temp to store the
1386ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt       * matrix and move each constant value into it.  If we get
1387ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt       * lucky, copy propagation will eliminate the extra moves.
1388ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt       */
1389ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      ir_to_mesa_src_reg mat = get_temp(glsl_type::vec4_type);
1390ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat);
1391ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1392ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      for (i = 0; i < ir->type->matrix_columns; i++) {
1393ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 src_reg.file = PROGRAM_CONSTANT;
1394ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1395ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 assert(ir->type->base_type == GLSL_TYPE_FLOAT);
1396ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 values = &ir->value.f[i * ir->type->vector_elements];
1397ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1398ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
1399ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt						    values,
1400ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt						    ir->type->vector_elements,
1401ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt						    &src_reg.swizzle);
1402f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 src_reg.reladdr = NULL;
1403ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 src_reg.negate = 0;
1404ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg);
1405ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1406ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 mat_column.index++;
1407ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      }
1408ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1409ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      this->result = mat;
1410582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   }
14110bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt
14120bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   src_reg.file = PROGRAM_CONSTANT;
14130bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   switch (ir->type->base_type) {
14140bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_FLOAT:
14150bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      values = &ir->value.f[0];
14160bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
14170bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_UINT:
14180bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
14190bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.u[i];
14200bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
14210bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
14220bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_INT:
14230bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
14240bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.i[i];
14250bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
14260bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
14270bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_BOOL:
14280bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
14290bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.b[i];
14300bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
14310bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
14320bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   default:
14330bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      assert(!"Non-float/uint/int/bool constant");
14340bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   }
14350bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt
14360bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
14370bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt					      values, ir->type->vector_elements,
14380bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt					      &src_reg.swizzle);
1439f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = NULL;
14400161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.negate = 0;
144184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
14420161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
144384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
144484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
14457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry *
14467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig)
14477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{
14487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *entry;
14497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, this->function_signatures) {
14517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry = (function_entry *)iter.get();
14527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (entry->sig == sig)
14547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 return entry;
14557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
14567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry = talloc(mem_ctx, function_entry);
14587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->sig = sig;
14597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->sig_id = this->next_signature_id++;
14607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->bgn_inst = NULL;
14617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Allocate storage for all the parameters. */
14637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, sig->parameters) {
14647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)iter.get();
1465b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      variable_storage *storage;
14667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      storage = find_variable_storage(param);
14687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      assert(!storage);
14697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1470b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
1471b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					      this->next_temp);
1472b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      this->variables.push_tail(storage);
14737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      this->next_temp += type_size(param->type);
14757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      break;
14767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
14777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   if (sig->return_type) {
14797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry->return_reg = get_temp(sig->return_type);
14807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   } else {
14817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry->return_reg = ir_to_mesa_undef;
14827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
14837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   this->function_signatures.push_tail(entry);
14857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   return entry;
14867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}
148784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
148884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
148984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir)
149084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
14917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_instruction *call_inst;
14927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_function_signature *sig = ir->get_callee();
14937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *entry = get_function_signature(sig);
14947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int i;
14957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process in parameters. */
14977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   exec_list_iterator sig_iter = sig->parameters.iterator();
14987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, *ir) {
14997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
15007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)sig_iter.get();
15017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (param->mode == ir_var_in ||
15037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	  param->mode == ir_var_inout) {
1504b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 variable_storage *storage = find_variable_storage(param);
15057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 assert(storage);
15067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 param_rval->accept(this);
15087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_src_reg r = this->result;
15097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_dst_reg l;
15117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.file = storage->file;
15127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.index = storage->index;
15137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.reladdr = NULL;
15147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.writemask = WRITEMASK_XYZW;
15157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.cond_mask = COND_TR;
15167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 for (i = 0; i < type_size(param->type); i++) {
15187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
15197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    l.index++;
15207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    r.index++;
15217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
15227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
15237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      sig_iter.next();
15257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
15267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(!sig_iter.has_next());
15277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Emit call instruction */
15297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL,
15307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt				   ir_to_mesa_undef_dst, ir_to_mesa_undef);
15317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   call_inst->function = entry;
15327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process out parameters. */
15347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   sig_iter = sig->parameters.iterator();
15357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, *ir) {
15367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
15377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)sig_iter.get();
15387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (param->mode == ir_var_out ||
15407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	  param->mode == ir_var_inout) {
1541b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 variable_storage *storage = find_variable_storage(param);
15427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 assert(storage);
15437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_src_reg r;
15457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.file = storage->file;
15467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.index = storage->index;
15477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.reladdr = NULL;
15487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.swizzle = SWIZZLE_NOOP;
15497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.negate = 0;
15507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 param_rval->accept(this);
15527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result);
15537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 for (i = 0; i < type_size(param->type); i++) {
15557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
15567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    l.index++;
15577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    r.index++;
15587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
15597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
15607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      sig_iter.next();
15627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
15637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(!sig_iter.has_next());
15647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process return value. */
15667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   this->result = entry->return_reg;
156784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
156884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
156984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
157084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
157184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir)
157284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
157356d33f8e2be1695c951a811fac1800117c2ca406Carl Worth   ir_to_mesa_src_reg result_src, coord, lod_info = { 0 }, projector;
1574d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   ir_to_mesa_dst_reg result_dst, coord_dst;
1575d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_to_mesa_instruction *inst = NULL;
1576d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   prog_opcode opcode = OPCODE_NOP;
157784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
157884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->coordinate->accept(this);
1579d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1580d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   /* Put our coords in a temp.  We'll need to modify them for shadow,
1581d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * projection, or LOD, so the only case we'd use it as is is if
1582d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * we're doing plain old texturing.  Mesa IR optimization should
1583d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * handle cleaning up our mess in that case.
1584d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    */
1585d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   coord = get_temp(glsl_type::vec4_type);
1586d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   coord_dst = ir_to_mesa_dst_reg_from_src(coord);
1587d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst,
1588d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt		       this->result);
1589d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1590de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt   if (ir->projector) {
1591de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt      ir->projector->accept(this);
1592de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt      projector = this->result;
1593de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt   }
1594de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt
1595d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
1596d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    * the actual storage for the result here, instead.
1597d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    */
1598d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   result_src = get_temp(glsl_type::vec4_type);
1599d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
1600d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1601d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   switch (ir->op) {
1602d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_tex:
1603d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TEX;
1604d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1605d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txb:
1606d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TXB;
1607d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir->lod_info.bias->accept(this);
1608d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      lod_info = this->result;
1609d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1610d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txl:
1611d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TXL;
1612d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir->lod_info.lod->accept(this);
1613d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      lod_info = this->result;
1614d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1615d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txd:
1616d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txf:
1617d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      assert(!"GLSL 1.30 features unsupported");
1618d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1619d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
1620d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1621d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   if (ir->projector) {
1622d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      if (opcode == OPCODE_TEX) {
1623d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 /* Slot the projector in as the last component of the coord. */
1624d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_W;
1625d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector);
1626d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZW;
1627d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 opcode = OPCODE_TXP;
1628d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      } else {
1629d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_src_reg coord_w = coord;
1630d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_w.swizzle = SWIZZLE_WWWW;
1631d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1632d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 /* For the other TEX opcodes there's no projective version
1633d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  * since the last slot is taken up by lod info.  Do the
1634d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  * projective divide now.
1635d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  */
1636d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_W;
1637d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector);
1638d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1639d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZ;
1640d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w);
1641d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1642d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZW;
1643d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord.swizzle = SWIZZLE_XYZW;
1644d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      }
1645d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   }
1646d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1647b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   if (ir->shadow_comparitor) {
1648b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      /* Slot the shadow value in as the second to last component of the
1649b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt       * coord.
1650b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt       */
1651b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      ir->shadow_comparitor->accept(this);
1652b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      coord_dst.writemask = WRITEMASK_Z;
1653b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result);
1654b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      coord_dst.writemask = WRITEMASK_XYZW;
1655b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   }
1656b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt
1657d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) {
1658d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      /* Mesa IR stores lod or lod bias in the last channel of the coords. */
1659d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      coord_dst.writemask = WRITEMASK_W;
1660d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info);
1661d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      coord_dst.writemask = WRITEMASK_XYZW;
1662d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   }
1663d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1664d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord);
1665d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1666b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   if (ir->shadow_comparitor)
1667b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      inst->tex_shadow = GL_TRUE;
1668b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt
1669d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_dereference_variable *sampler = ir->sampler->as_dereference_variable();
1670d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   assert(sampler); /* FINISHME: sampler arrays */
1671d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   /* generate the mapping, remove when we generate storage at
1672d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    * declaration time
1673d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    */
1674d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler->accept(this);
1675d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1676d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   inst->sampler = get_sampler_number(sampler->var->location);
1677d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1678d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   switch (sampler->type->sampler_dimensionality) {
1679d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_1D:
1680d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_1D_INDEX;
1681d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1682d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_2D:
1683d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_2D_INDEX;
1684d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1685d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_3D:
1686d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_3D_INDEX;
1687d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1688d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_CUBE:
1689d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_CUBE_INDEX;
1690d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1691d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   default:
1692d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      assert(!"FINISHME: other texture targets");
1693d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
1694d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1695d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   this->result = result_src;
169684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
169784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
169884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
169984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir)
170084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
17017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(current_function);
17027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   if (ir->get_value()) {
17047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_to_mesa_dst_reg l;
17057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      int i;
17067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir->get_value()->accept(this);
17087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_to_mesa_src_reg r = this->result;
170984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
17107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      l = ir_to_mesa_dst_reg_from_src(current_function->return_reg);
17117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      for (i = 0; i < type_size(current_function->sig->return_type); i++) {
17137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
17147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.index++;
17157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.index++;
17167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
17177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
17187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_emit_op0(ir, OPCODE_RET);
172084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
172184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
172216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid
172316efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir)
172416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{
17255e4dd061d17563828bcce5525400a0ce363aa15dEric Anholt   assert(ir->condition == NULL); /* FINISHME */
172616efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
1727021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
172816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke}
172984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
173084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
173184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir)
173284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1733854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
1734cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt   ir_to_mesa_instruction *prev_inst;
1735cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt
1736cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt   prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
1737c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1738c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir->condition->accept(this);
17390161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(this->result.file != PROGRAM_UNDEFINED);
1740c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1741854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   if (ctx->Shader.EmitCondCodes) {
1742854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
1743cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt
1744cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      /* See if we actually generated any instruction for generating
1745cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       * the condition.  If not, then cook up a move to a temp so we
1746cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       * have something to set cond_update on.
1747cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       */
1748cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      if (cond_inst == prev_inst) {
1749cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt	 ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
1750cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt	 cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
1751cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt					 ir_to_mesa_dst_reg_from_src(temp),
1752cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt					 result);
1753cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      }
1754854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      cond_inst->cond_update = GL_TRUE;
1755854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt
1756021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF);
1757854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst->dst_reg.cond_mask = COND_NE;
1758854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   } else {
1759854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst = ir_to_mesa_emit_op1(ir->condition,
1760854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    OPCODE_IF, ir_to_mesa_undef_dst,
1761854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    this->result);
1762854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   }
1763c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1764c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   this->instructions.push_tail(if_inst);
1765c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1766c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   visit_exec_list(&ir->then_instructions, this);
1767c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1768c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   if (!ir->else_instructions.is_empty()) {
1769021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE);
17700a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt      visit_exec_list(&ir->else_instructions, this);
1771c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1772c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
17730161515c395c44233529c8d51f823b60050bc7baEric Anholt   if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
17740161515c395c44233529c8d51f823b60050bc7baEric Anholt				 ir_to_mesa_undef_dst, ir_to_mesa_undef);
177584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
177684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1777ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor()
1778ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{
17790161515c395c44233529c8d51f823b60050bc7baEric Anholt   result.file = PROGRAM_UNDEFINED;
1780ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt   next_temp = 1;
17817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   next_signature_id = 1;
1782d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler_map = NULL;
1783d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler_map_size = 0;
17847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   current_function = NULL;
1785ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt}
1786ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt
178784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register
178884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
178984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
179084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_src_register mesa_reg;
179184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
179284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.File = reg.file;
1793aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt   assert(reg.index < (1 << INST_INDEX_BITS) - 1);
179484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.Index = reg.index;
179534195832669f0eb7c4a80997cc524f8d10319307Eric Anholt   mesa_reg.Swizzle = reg.swizzle;
1796f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   mesa_reg.RelAddr = reg.reladdr != NULL;
1797ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt   mesa_reg.Negate = reg.negate;
1798285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt   mesa_reg.Abs = 0;
179984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
180084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return mesa_reg;
180184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
180284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1803c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
18047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v,
18057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt		  struct prog_instruction *mesa_instructions,
1806c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt		  int num_instructions)
1807c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
1808e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke   int if_count = 0, loop_count = 0;
180964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int *if_stack, *loop_stack;
181064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int if_stack_pos = 0, loop_stack_pos = 0;
181164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int i, j;
1812c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1813c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
181464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      switch (mesa_instructions[i].Opcode) {
181564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_IF:
1816c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_count++;
181764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
181864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
181964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_count++;
182064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
182164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BRK:
182264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_CONT:
182364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = -1;
182464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
182564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      default:
182664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
182764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      }
1828c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1829c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
183064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   if_stack = (int *)calloc(if_count, sizeof(*if_stack));
183164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
1832c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1833c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
1834c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      switch (mesa_instructions[i].Opcode) {
1835c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_IF:
183664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos] = i;
1837c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos++;
1838c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1839c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ELSE:
184064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
184164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos - 1] = i;
1842c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1843c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ENDIF:
184464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
1845c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos--;
1846c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
184764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
184864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack[loop_stack_pos] = i;
184964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos++;
185064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
185164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_ENDLOOP:
185264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos--;
185364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* Rewrite any breaks/conts at this nesting level (haven't
185464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * already had a BranchTarget assigned) to point to the end
185564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * of the loop.
185664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  */
185764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 for (j = loop_stack[loop_stack_pos]; j < i; j++) {
185864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    if (mesa_instructions[j].Opcode == OPCODE_BRK ||
185964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		mesa_instructions[j].Opcode == OPCODE_CONT) {
186064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       if (mesa_instructions[j].BranchTarget == -1) {
186164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		  mesa_instructions[j].BranchTarget = i;
186264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       }
186364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    }
186464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 }
186564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* The loop ends point at each other. */
186664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
186764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
18687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 break;
18697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      case OPCODE_CAL:
18707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 foreach_iter(exec_list_iterator, iter, v->function_signatures) {
18717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    function_entry *entry = (function_entry *)iter.get();
18727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    if (entry->sig_id == mesa_instructions[i].BranchTarget) {
18747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	       mesa_instructions[i].BranchTarget = entry->inst;
18757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	       break;
18767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    }
18777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
18787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 break;
1879c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      default:
1880c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1881c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
1882c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1883c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1884c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   free(if_stack);
1885c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
1886c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1887c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
1888c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions,
1889c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      ir_instruction **mesa_instruction_annotation,
1890c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      int num_instructions)
1891c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
1892c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction *last_ir = NULL;
1893c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
1894748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt   int indent = 0;
1895c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1896c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
1897c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      struct prog_instruction *mesa_inst = mesa_instructions + i;
1898c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      ir_instruction *ir = mesa_instruction_annotation[i];
1899c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1900748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt      fprintf(stdout, "%3d: ", i);
1901748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
190264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      if (last_ir != ir && ir) {
1903748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 int j;
1904748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
1905748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 for (j = 0; j < indent; j++) {
1906748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	    fprintf(stdout, " ");
1907748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 }
1908748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 ir->print();
1909c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 printf("\n");
1910c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 last_ir = ir;
1911748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
1912748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 fprintf(stdout, "     "); /* line number spacing. */
1913c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
1914c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1915748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt      indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent,
1916748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt					    PROG_PRINT_DEBUG, NULL);
1917c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1918c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
1919c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1920ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void
19214d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_input(struct gl_program *prog,
19224d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   int index,
19234d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   GLboolean reladdr)
19244d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{
19254d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   prog->InputsRead |= BITFIELD64_BIT(index);
19264d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   int i;
19274d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
19284d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   if (reladdr) {
19294d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      if (index >= FRAG_ATTRIB_TEX0 && index <= FRAG_ATTRIB_TEX7) {
19304d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 for (i = 0; i < 8; i++) {
19314d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    prog->InputsRead |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
19324d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 }
19334d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      } else {
19344d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 assert(!"FINISHME: Mark InputsRead for varying arrays");
19354d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      }
19364d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   }
19374d5da50b94115d055ba8d0ff8717054582665384Eric Anholt}
19384d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
19394d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void
19404d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_output(struct gl_program *prog,
19414d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   int index,
19424d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   GLboolean reladdr)
19434d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{
19444d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   prog->OutputsWritten |= BITFIELD64_BIT(index);
19454d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   int i;
19464d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
19474d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   if (reladdr) {
19484d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      if (index >= VERT_RESULT_TEX0 && index <= VERT_RESULT_TEX7) {
19494d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 for (i = 0; i < 8; i++) {
19504d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    prog->OutputsWritten |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
19514d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 }
19524d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      } else {
19534d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 assert(!"FINISHME: Mark OutputsWritten for varying arrays");
19544d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      }
19554d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   }
19564d5da50b94115d055ba8d0ff8717054582665384Eric Anholt}
19574d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
19584d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void
1959ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog)
1960ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{
1961d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   unsigned int i;
1962d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1963ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   prog->InputsRead = 0;
1964ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   prog->OutputsWritten = 0;
1965d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   prog->SamplersUsed = 0;
1966ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
1967ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   for (i = 0; i < prog->NumInstructions; i++) {
1968ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      struct prog_instruction *inst = &prog->Instructions[i];
1969ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      unsigned int reg;
1970ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
1971ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      switch (inst->DstReg.File) {
1972ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      case PROGRAM_OUTPUT:
19734d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 mark_output(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
1974ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
1975ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      case PROGRAM_INPUT:
19764d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 mark_input(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
1977ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
1978ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      default:
1979ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
1980ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      }
1981ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
1982ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) {
1983ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 switch (inst->SrcReg[reg].File) {
1984ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 case PROGRAM_OUTPUT:
19854d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    mark_output(prog, inst->SrcReg[reg].Index,
19864d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			inst->SrcReg[reg].RelAddr);
1987ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
1988ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 case PROGRAM_INPUT:
19894d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    mark_input(prog, inst->SrcReg[reg].Index, inst->SrcReg[reg].RelAddr);
1990ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
1991ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 default:
1992ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
1993ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 }
1994ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      }
1995d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1996d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      /* Instead of just using the uniform's value to map to a
1997d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * sampler, Mesa first allocates a separate number for the
1998d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * sampler (_mesa_add_sampler), then we reindex it down to a
1999d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * small integer (sampler_map[], SamplersUsed), then that gets
2000d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * mapped to the uniform's value, and we get an actual sampler.
2001d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       */
2002d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      if (_mesa_is_tex_instruction(inst->Opcode)) {
2003d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 prog->SamplerTargets[inst->TexSrcUnit] =
2004d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    (gl_texture_index)inst->TexSrcTarget;
2005d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 prog->SamplersUsed |= 1 << inst->TexSrcUnit;
2006d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 if (inst->TexShadow) {
2007d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
2008d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 }
2009d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      }
2010ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   }
2011d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2012d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   _mesa_update_shader_textures_used(prog);
2013ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt}
2014ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
201585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt/* Each stage has some uniforms in its Parameters list.  The Uniforms
201685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * list for the linked shader program has a pointer to these uniforms
201785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * in each of the stage's Parameters list, so that their values can be
201885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * updated when a uniform is set.
201985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */
202085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void
202185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtlink_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms,
202285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				     struct gl_program *prog)
202385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{
202485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   unsigned int i;
202585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
202685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   for (i = 0; i < prog->Parameters->NumParameters; i++) {
202785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
202885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
202985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) {
203085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 struct gl_uniform *uniform =
203185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	    _mesa_append_uniform(uniforms, p->Name, prog->Target, i);
203285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 if (uniform)
203385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	    uniform->Initialized = p->Initialized;
203485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      }
203585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   }
203685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt}
203785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
2038364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtstruct gl_program *
203995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholtget_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
204095c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt		 struct gl_shader *shader)
204184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
204295c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt   void *mem_ctx = shader_program;
204384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir_to_mesa_visitor v;
204484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_instruction *mesa_instructions, *mesa_inst;
2045c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction **mesa_instruction_annotation;
2046c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
2047364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct gl_program *prog;
2048364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   GLenum target;
2049c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   const char *target_string;
20507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   GLboolean progress;
2051364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2052364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   switch (shader->Type) {
2053c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   case GL_VERTEX_SHADER:
2054c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target = GL_VERTEX_PROGRAM_ARB;
2055c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target_string = "vertex";
2056c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2057c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   case GL_FRAGMENT_SHADER:
2058c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target = GL_FRAGMENT_PROGRAM_ARB;
2059c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target_string = "fragment";
2060c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2061c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   default:
2062c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      assert(!"should not be reached");
2063c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2064364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
206584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
20661124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt   validate_ir_tree(shader->ir);
20671124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt
2068364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog = ctx->Driver.NewProgram(ctx, target, 1);
2069364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (!prog)
2070364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      return NULL;
2071364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Parameters = _mesa_new_parameter_list();
2072364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Varying = _mesa_new_parameter_list();
2073364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Attributes = _mesa_new_parameter_list();
2074364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.ctx = ctx;
2075364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.prog = prog;
2076364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2077364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.mem_ctx = talloc_new(NULL);
20787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Emit Mesa IR for main(). */
208016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   visit_exec_list(shader->ir, &v);
2081021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   v.ir_to_mesa_emit_op0(NULL, OPCODE_END);
208284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
20837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Now emit bodies for any functions that were used. */
20847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   do {
20857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      progress = GL_FALSE;
20867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      foreach_iter(exec_list_iterator, iter, v.function_signatures) {
20887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 function_entry *entry = (function_entry *)iter.get();
20897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 if (!entry->bgn_inst) {
20917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    v.current_function = entry;
20927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB);
20947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst->function = entry;
20957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    visit_exec_list(&entry->sig->body, &v);
20977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_RET);
20997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB);
21007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    progress = GL_TRUE;
21017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
21027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
21037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   } while (progress);
21047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
2105364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->NumTemporaries = v.next_temp;
2106364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
210784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int num_instructions = 0;
210884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
210984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      num_instructions++;
211084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
211184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
211284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_instructions =
211384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      (struct prog_instruction *)calloc(num_instructions,
211484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt					sizeof(*mesa_instructions));
2115364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *,
2116364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt					      num_instructions);
211784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
211884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_inst = mesa_instructions;
2119c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   i = 0;
212084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
212184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
2122b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt
212384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->Opcode = inst->op;
2124854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      mesa_inst->CondUpdate = inst->cond_update;
212584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.File = inst->dst_reg.file;
212684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.Index = inst->dst_reg.index;
2127854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
212812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
2129f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL;
213084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
213184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
213284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
2133d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      mesa_inst->TexSrcUnit = inst->sampler;
2134d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      mesa_inst->TexSrcTarget = inst->tex_target;
2135b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      mesa_inst->TexShadow = inst->tex_shadow;
2136c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      mesa_instruction_annotation[i] = inst->ir;
2137aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt
213895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt      if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) {
213995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	 shader_program->InfoLog =
214095c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	    talloc_asprintf_append(shader_program->InfoLog,
214195c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt				   "Couldn't flatten if statement\n");
214295c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	 shader_program->LinkStatus = false;
214395c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt      }
214495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt
21457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (mesa_inst->Opcode == OPCODE_BGNSUB)
21467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 inst->function->inst = i;
21477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      else if (mesa_inst->Opcode == OPCODE_CAL)
21487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */
2149d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt      else if (mesa_inst->Opcode == OPCODE_ARL)
2150d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt	 prog->NumAddressRegs = 1;
21517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
215284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst++;
2153c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      i++;
215484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
2155c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
21567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   set_branchtargets(&v, mesa_instructions, num_instructions);
2157c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   if (ctx->Shader.Flags & GLSL_DUMP) {
2158c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      printf("Mesa %s program:\n", target_string);
2159364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      print_program(mesa_instructions, mesa_instruction_annotation,
2160364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt		    num_instructions);
2161364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2162364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2163364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Instructions = mesa_instructions;
2164364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->NumInstructions = num_instructions;
2165364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
216616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   _mesa_reference_program(ctx, &shader->Program, prog);
2167364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
216828faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt   if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
216928faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt      _mesa_optimize_program(ctx, prog);
217028faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt   }
217128faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt
2172364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   return prog;
2173364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt}
2174364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
217516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" {
217616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt
217716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid
217816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
2179364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{
21802462a536ea5c98867296905e3da127eba7c7bdffIan Romanick   struct _mesa_glsl_parse_state *state =
21812462a536ea5c98867296905e3da127eba7c7bdffIan Romanick      new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
21825e18b051c039564d1998818d08caf1bff3983630Ian Romanick
2183153eca98064252be4daad9cc27746f37c245b627Ian Romanick   const char *source = shader->Source;
218406143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick   state->error = preprocess(state, &source, &state->info_log,
218506143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick			     &ctx->Extensions);
2186153eca98064252be4daad9cc27746f37c245b627Ian Romanick
2187153eca98064252be4daad9cc27746f37c245b627Ian Romanick   if (!state->error) {
2188153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_lexer_ctor(state, source);
2189153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_parse(state);
2190153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_lexer_dtor(state);
2191153eca98064252be4daad9cc27746f37c245b627Ian Romanick   }
2192364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
219316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   shader->ir = new(shader) exec_list;
2194364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (!state->error && !state->translation_unit.is_empty())
219516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt      _mesa_ast_to_hir(shader->ir, state);
2196364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
219716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   if (!state->error && !shader->ir->is_empty()) {
2198ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt      validate_ir_tree(shader->ir);
2199ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt
22004802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      /* Lowering */
22014802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      do_mat_op_to_vec(shader->ir);
22024802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      do_mod_to_fract(shader->ir);
22034802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      do_div_to_mul_rcp(shader->ir);
22044802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt
22054802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      /* Optimization passes */
2206364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      bool progress;
2207364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      do {
2208364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 progress = false;
2209364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
221016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_function_inlining(shader->ir) || progress;
221116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_if_simplification(shader->ir) || progress;
221216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_copy_propagation(shader->ir) || progress;
221316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_dead_code_local(shader->ir) || progress;
221416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_dead_code_unlinked(state, shader->ir) || progress;
221516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_constant_variable_unlinked(shader->ir) || progress;
221616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_constant_folding(shader->ir) || progress;
2217d674ebcee0d2731e50d6530502cefcebc39dcdb6Eric Anholt	 progress = do_if_return(shader->ir) || progress;
221895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	 if (ctx->Shader.EmitNoIfs)
221995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	    progress = do_if_to_cond_assign(shader->ir) || progress;
2220a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
222116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_vec_index_to_swizzle(shader->ir) || progress;
2222a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	 /* Do this one after the previous to let the easier pass handle
2223a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	  * constant vector indexing.
2224a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	  */
2225a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	 progress = do_vec_index_to_cond_assign(shader->ir) || progress;
2226a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
222716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_swizzle_swizzle(shader->ir) || progress;
2228364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      } while (progress);
2229ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt
2230ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt      validate_ir_tree(shader->ir);
2231364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2232364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2233364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->symbols = state->symbols;
2234364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2235364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->CompileStatus = !state->error;
2236364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->InfoLog = state->info_log;
223725f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick   shader->Version = state->language_version;
2238d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick   memcpy(shader->builtins_to_link, state->builtins_to_link,
2239d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick	  sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
2240d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick   shader->num_builtins_to_link = state->num_builtins_to_link;
2241c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2242116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke   /* Retain any live IR, but trash the rest. */
224360e2d06d1ccc66ad00cd7ab81c418853f21be291Ian Romanick   reparent_ir(shader->ir, shader);
2244116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke
2245364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   talloc_free(state);
2246364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt }
2247364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2248364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid
2249364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
2250364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{
2251364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   unsigned int i;
2252849e18153cd91d812f694b806a84008498860bc3Eric Anholt
2253364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_clear_shader_program_data(ctx, prog);
2254364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2255849e18153cd91d812f694b806a84008498860bc3Eric Anholt   prog->LinkStatus = GL_TRUE;
2256364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2257364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   for (i = 0; i < prog->NumShaders; i++) {
2258849e18153cd91d812f694b806a84008498860bc3Eric Anholt      if (!prog->Shaders[i]->CompileStatus) {
2259849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 prog->InfoLog =
2260849e18153cd91d812f694b806a84008498860bc3Eric Anholt	    talloc_asprintf_append(prog->InfoLog,
2261364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				   "linking with uncompiled shader");
2262849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 prog->LinkStatus = GL_FALSE;
2263364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      }
2264364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2265364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2266364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Varying = _mesa_new_parameter_list();
2267364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
2268364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
2269364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2270849e18153cd91d812f694b806a84008498860bc3Eric Anholt   if (prog->LinkStatus) {
2271849e18153cd91d812f694b806a84008498860bc3Eric Anholt      link_shaders(prog);
2272849e18153cd91d812f694b806a84008498860bc3Eric Anholt
2273849e18153cd91d812f694b806a84008498860bc3Eric Anholt      /* We don't use the linker's uniforms list, and cook up our own at
2274849e18153cd91d812f694b806a84008498860bc3Eric Anholt       * generate time.
2275849e18153cd91d812f694b806a84008498860bc3Eric Anholt       */
2276849e18153cd91d812f694b806a84008498860bc3Eric Anholt      free(prog->Uniforms);
2277849e18153cd91d812f694b806a84008498860bc3Eric Anholt      prog->Uniforms = _mesa_new_uniform_list();
2278849e18153cd91d812f694b806a84008498860bc3Eric Anholt   }
2279364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2280364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (prog->LinkStatus) {
22813fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick      for (i = 0; i < prog->_NumLinkedShaders; i++) {
2282364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 struct gl_program *linked_prog;
2283364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2284849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 linked_prog = get_mesa_program(ctx, prog,
22853fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick					prog->_LinkedShaders[i]);
2286ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 count_resources(linked_prog);
2287364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
228885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
228985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
22903fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick	 switch (prog->_LinkedShaders[i]->Type) {
2291364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 case GL_VERTEX_SHADER:
2292364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    _mesa_reference_vertprog(ctx, &prog->VertexProgram,
2293364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				     (struct gl_vertex_program *)linked_prog);
22947dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt	    ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
22957dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt					    linked_prog);
2296364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    break;
2297364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 case GL_FRAGMENT_SHADER:
2298364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
2299364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				     (struct gl_fragment_program *)linked_prog);
23007dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt	    ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
23017dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt					    linked_prog);
2302364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    break;
2303364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 }
2304364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      }
2305364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2306364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt}
2307364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2308364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */
2309