ir_to_mesa.cpp revision 5b6890a388d554f06880e88d61c73dcd62c5f141
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"
46afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/shaderobj.h"
47afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "main/uniforms.h"
48afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_instruction.h"
49afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_optimize.h"
50afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_print.h"
51afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/program.h"
52afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_uniform.h"
53afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_parameter.h"
54aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt}
5584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
56554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/**
57554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with
58554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields.
59554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */
60554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_src_reg {
61554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
62554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
63582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
64554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int negate; /**< NEGATE_XYZW mask from mesa */
65f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /** Register index should be offset by the integer in this reg. */
66f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_src_reg *reladdr;
67554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_src_reg;
68554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
69554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_dst_reg {
70554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
71554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
72554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
73854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   GLuint cond_mask:4;
74f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /** Register index should be offset by the integer in this reg. */
75f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_src_reg *reladdr;
76554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_dst_reg;
77554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
78554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtextern ir_to_mesa_src_reg ir_to_mesa_undef;
79554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
80554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node {
81554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
82554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   enum prog_opcode op;
83554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_dst_reg dst_reg;
84554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_src_reg src_reg[3];
85554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** Pointer to the ir source this tree came from for debugging */
86554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_instruction *ir;
87854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   GLboolean cond_update;
88d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int sampler; /**< sampler index */
89d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int tex_target; /**< One of TEXTURE_*_INDEX */
90b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   GLboolean tex_shadow;
917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */
93554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
94554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
95b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node {
96554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
97b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage(ir_variable *var, int file, int index)
98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      : file(file), index(index), var(var)
99554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   {
100554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      /* empty */
101554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   }
102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
103554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file;
104554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index;
105554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_variable *var; /* variable that maps to this, if any */
106554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
107554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node {
1097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic:
1107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_function_signature *sig;
1117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * identifier of this function signature used by the program.
1147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * At the point that Mesa instructions for function calls are
1167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * generated, we don't know the address of the first instruction of
1177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * the function body.  So we make the BranchTarget that is called a
1187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * small integer and rewrite them during set_branchtargets().
1197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int sig_id;
1217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Pointer to first instruction of the function body.
1247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Set during function body emits after main() is processed.
1267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_instruction *bgn_inst;
1287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Index of the first instruction of the function body in actual
1317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Mesa IR.
1327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Set after convertion from ir_to_mesa_instruction to prog_instruction.
1347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int inst;
1367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /** Storage for the return value. */
1387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_src_reg return_reg;
1397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt};
1407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
141554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor {
142554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
143554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_visitor();
144554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *current_function;
1467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
147364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   GLcontext *ctx;
148364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct gl_program *prog;
149364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
150554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int next_temp;
151a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
152b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *find_variable_storage(ir_variable *var);
153554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *get_function_signature(ir_function_signature *sig);
1557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1568364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   ir_to_mesa_src_reg get_temp(const glsl_type *type);
157f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   void reladdr_to_temp(ir_instruction *ir,
158f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt			ir_to_mesa_src_reg *reg, int *num_reladdr);
159554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
160554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg src_reg_for_float(float val);
161554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
162554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /**
163554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * \name Visit methods
164554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    *
165554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * As typical for the visitor pattern, there must be one \c visit method for
166554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * each concrete subclass of \c ir_instruction.  Virtual base classes within
167554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * the hierarchy should not have \c visit methods.
168554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    */
169554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@{*/
170554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_variable *);
171554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop *);
172554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop_jump *);
173554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function_signature *);
174554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function *);
175554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_expression *);
176554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_swizzle *);
177554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_variable  *);
178554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_array *);
179554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_record *);
180554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_assignment *);
181554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_constant *);
182554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_call *);
183554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_return *);
18416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke   virtual void visit(ir_discard *);
185554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_texture *);
186554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_if *);
187554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@}*/
188554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
189554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg result;
190554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
191b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   /** List of variable_storage */
192b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   exec_list variables;
193554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /** List of function_entry */
1957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   exec_list function_signatures;
1967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int next_signature_id;
1977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
198554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** List of ir_to_mesa_instruction */
199554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   exec_list instructions;
200554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
201021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir,
202021222c6a872ca2eef770ebadb8754f659775204Eric Anholt					       enum prog_opcode op);
203021222c6a872ca2eef770ebadb8754f659775204Eric Anholt
204554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
205554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
206554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
207554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0);
208554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
209554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
210554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
211554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
212554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
213554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1);
214554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
215554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
216554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
217554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
218554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
219554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1,
220554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src2);
221554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
222554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
223554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   enum prog_opcode op,
224554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_dst_reg dst,
225554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_src_reg src0);
2260ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt
227904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
228904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   enum prog_opcode op,
229904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_dst_reg dst,
230904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_src_reg src0,
231904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_src_reg src1);
232904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
2333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   GLboolean try_emit_mad(ir_expression *ir,
2343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt			  int mul_operand);
2353f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
236d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int *sampler_map;
237d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int sampler_map_size;
238d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
239d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   void map_sampler(int location, int sampler);
240d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int get_sampler_number(int location);
241d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
242364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   void *mem_ctx;
243554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
244554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
24584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_src_reg ir_to_mesa_undef = {
246f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, NEGATE_NONE, NULL,
24784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt};
24884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
249c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
250f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL,
251c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt};
252c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2530161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = {
254f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL
2550161515c395c44233529c8d51f823b60050bc7baEric Anholt};
2560161515c395c44233529c8d51f823b60050bc7baEric Anholt
2570161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic int swizzle_for_size(int size)
2580161515c395c44233529c8d51f823b60050bc7baEric Anholt{
2590161515c395c44233529c8d51f823b60050bc7baEric Anholt   int size_swizzles[4] = {
2600161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
2610161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
2620161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
2630161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
2640161515c395c44233529c8d51f823b60050bc7baEric Anholt   };
2650161515c395c44233529c8d51f823b60050bc7baEric Anholt
2660161515c395c44233529c8d51f823b60050bc7baEric Anholt   return size_swizzles[size - 1];
2670161515c395c44233529c8d51f823b60050bc7baEric Anholt}
2680161515c395c44233529c8d51f823b60050bc7baEric Anholt
26984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
2700161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
2710161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
2720161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
2730161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
2740161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1,
2750161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src2)
27684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
277364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
278f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   int num_reladdr = 0;
279f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
280f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /* If we have to do relative addressing, we want to load the ARL
281f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    * reg directly for one of the regs, and preload the other reladdr
282f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    * sources into temps.
283f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    */
284f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += dst.reladdr != NULL;
285f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src0.reladdr != NULL;
286f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src1.reladdr != NULL;
287f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src2.reladdr != NULL;
288f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
289f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src2, &num_reladdr);
290f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src1, &num_reladdr);
291f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src0, &num_reladdr);
292f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
293f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (dst.reladdr) {
294f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
295f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt                          *dst.reladdr);
296f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
297f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      num_reladdr--;
298f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   }
299f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   assert(num_reladdr == 0);
30084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
30184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->op = op;
30284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->dst_reg = dst;
30384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[0] = src0;
30484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[1] = src1;
30584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[2] = src2;
306c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   inst->ir = ir;
30784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   inst->function = NULL;
3097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
3100161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->instructions.push_tail(inst);
31184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
31284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return inst;
31384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
31484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
31584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
31684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
3170161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
3180161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
3190161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
3200161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
3210161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1)
32284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
3230161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
32484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
32584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
32684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
3270161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
3280161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
3290161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
3300161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0)
331bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{
3320161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst,
3330161515c395c44233529c8d51f823b60050bc7baEric Anholt			      src0, ir_to_mesa_undef, ir_to_mesa_undef);
334bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
335bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
336021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction *
337021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir,
338021222c6a872ca2eef770ebadb8754f659775204Eric Anholt					enum prog_opcode op)
339021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{
340021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst,
341021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef,
342021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef,
343021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef);
344021222c6a872ca2eef770ebadb8754f659775204Eric Anholt}
345021222c6a872ca2eef770ebadb8754f659775204Eric Anholt
346d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtvoid
347d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtir_to_mesa_visitor::map_sampler(int location, int sampler)
348d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{
349d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   if (this->sampler_map_size <= location) {
350d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      this->sampler_map = talloc_realloc(this->mem_ctx, this->sampler_map,
351d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					 int, location + 1);
352d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      this->sampler_map_size = location + 1;
353d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
354d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
355d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   this->sampler_map[location] = sampler;
356d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt}
357d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
358d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtint
359d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtir_to_mesa_visitor::get_sampler_number(int location)
360d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{
361d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   assert(location < this->sampler_map_size);
362d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   return this->sampler_map[location];
363d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt}
364d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
3650161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg
3660161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
36784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
3680161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_dst_reg dst_reg;
36984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3700161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.file = reg.file;
3710161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.index = reg.index;
3720161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.writemask = WRITEMASK_XYZW;
373854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   dst_reg.cond_mask = COND_TR;
374f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   dst_reg.reladdr = reg.reladdr;
3750161515c395c44233529c8d51f823b60050bc7baEric Anholt
3760161515c395c44233529c8d51f823b60050bc7baEric Anholt   return dst_reg;
377bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
378bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
3792d1789e667c4180777829f96856daf91326721b9Eric Anholtinline ir_to_mesa_src_reg
3802d1789e667c4180777829f96856daf91326721b9Eric Anholtir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg)
3812d1789e667c4180777829f96856daf91326721b9Eric Anholt{
3822d1789e667c4180777829f96856daf91326721b9Eric Anholt   ir_to_mesa_src_reg src_reg;
3832d1789e667c4180777829f96856daf91326721b9Eric Anholt
3842d1789e667c4180777829f96856daf91326721b9Eric Anholt   src_reg.file = reg.file;
3852d1789e667c4180777829f96856daf91326721b9Eric Anholt   src_reg.index = reg.index;
3862d1789e667c4180777829f96856daf91326721b9Eric Anholt   src_reg.swizzle = SWIZZLE_XYZW;
3872d1789e667c4180777829f96856daf91326721b9Eric Anholt   src_reg.negate = 0;
388f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = reg.reladdr;
3892d1789e667c4180777829f96856daf91326721b9Eric Anholt
3902d1789e667c4180777829f96856daf91326721b9Eric Anholt   return src_reg;
3912d1789e667c4180777829f96856daf91326721b9Eric Anholt}
3922d1789e667c4180777829f96856daf91326721b9Eric Anholt
39312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/**
39412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels.
39512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt *
39612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp.  The src X
39712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels.  So to do a vec4
39812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used
39912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels.
40012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */
40112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid
402904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
4030161515c395c44233529c8d51f823b60050bc7baEric Anholt					       enum prog_opcode op,
4040161515c395c44233529c8d51f823b60050bc7baEric Anholt					       ir_to_mesa_dst_reg dst,
405904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg orig_src0,
406904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg orig_src1)
40712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{
40812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   int i, j;
409315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt   int done_mask = ~dst.writemask;
41012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
41112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   /* Mesa RCP is a scalar operation splatting results to all channels,
41212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
41312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * dst channels.
41412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    */
41512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   for (i = 0; i < 4; i++) {
416582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt      GLuint this_mask = (1 << i);
41712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      ir_to_mesa_instruction *inst;
418904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_src_reg src0 = orig_src0;
419904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_src_reg src1 = orig_src1;
42012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
42112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      if (done_mask & this_mask)
42212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 continue;
42312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
424904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
425904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
42612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      for (j = i + 1; j < 4; j++) {
427904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	 if (!(done_mask & (1 << j)) &&
428904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	     GET_SWZ(src0.swizzle, j) == src0_swiz &&
429904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	     GET_SWZ(src1.swizzle, j) == src1_swiz) {
43012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	    this_mask |= (1 << j);
43112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 }
43212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      }
433904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
434904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   src0_swiz, src0_swiz);
435904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
436904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				  src1_swiz, src1_swiz);
43712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
438904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      inst = ir_to_mesa_emit_op2(ir, op,
4390161515c395c44233529c8d51f823b60050bc7baEric Anholt				 dst,
440904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				 src0,
441904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				 src1);
44212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      inst->dst_reg.writemask = this_mask;
44312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      done_mask |= this_mask;
44412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   }
44512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt}
44612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
447904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid
448904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
449904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       enum prog_opcode op,
450904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_dst_reg dst,
451904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg src0)
452904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{
45359a23d7fb93603b2449db4c5d786934a07aebfcbEric Anholt   ir_to_mesa_src_reg undef = ir_to_mesa_undef;
454904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
455904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   undef.swizzle = SWIZZLE_XXXX;
456904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
457904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
458904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt}
459904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
4600161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg
4610161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val)
462b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
4630161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
4641d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4650161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.file = PROGRAM_CONSTANT;
466582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
467582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt					      &val, 1, &src_reg.swizzle);
468f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = NULL;
4698bb15c1ed55eb71533d2af94a6afbf01e3d23610Eric Anholt   src_reg.negate = 0;
4701d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4710161515c395c44233529c8d51f823b60050bc7baEric Anholt   return src_reg;
4721d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt}
4731d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4742c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int
4752c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type)
4762c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
4772c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
4782c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int size;
4792c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
4802c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   switch (type->base_type) {
4812c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_UINT:
4822c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_INT:
4832c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_FLOAT:
4842c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_BOOL:
485a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      if (type->is_matrix()) {
4869968f1b23c475c99139f0209c7a049ed00df01afEric Anholt	 return type->matrix_columns;
487a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      } else {
488a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 /* Regardless of size of vector, it gets a vec4. This is bad
489a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * packing for things like floats, but otherwise arrays become a
490a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * mess.  Hopefully a later pass over the code can pack scalars
491a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * down if appropriate.
492a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  */
493a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return 1;
494a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      }
4952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_ARRAY:
4962c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return type_size(type->fields.array) * type->length;
4972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_STRUCT:
4982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      size = 0;
4992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      for (i = 0; i < type->length; i++) {
5002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 size += type_size(type->fields.structure[i].type);
5012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      }
5022c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return size;
5032c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   default:
5042c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(0);
5052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
5062c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
5072c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
508d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/**
509d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to
510d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results.  (not SSA -- variable assignments will reuse
511d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage).  Actual register allocation for the Mesa VM occurs in a
512d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later.
513d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */
514d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_src_reg
515d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type)
516d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{
517d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   ir_to_mesa_src_reg src_reg;
518d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   int swizzle[4];
519d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   int i;
520d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
521d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   assert(!type->is_array());
522d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
523d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.file = PROGRAM_TEMPORARY;
524d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.index = next_temp;
525f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = NULL;
526d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   next_temp += type_size(type);
527d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
528d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   for (i = 0; i < type->vector_elements; i++)
529d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt      swizzle[i] = i;
530d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   for (; i < 4; i++)
531d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt      swizzle[i] = type->vector_elements - 1;
532d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
533d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt				   swizzle[2], swizzle[3]);
534ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt   src_reg.negate = 0;
535d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
536d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   return src_reg;
537d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt}
538d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
539b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage *
540a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var)
54184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
542a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
543b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry;
54484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
545b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   foreach_iter(exec_list_iterator, iter, this->variables) {
546b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      entry = (variable_storage *)iter.get();
54784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
5480161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (entry->var == var)
549a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return entry;
55084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
55184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
552a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt   return NULL;
553a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt}
55484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
55584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
55684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir)
55784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
5588364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   (void)ir;
55984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
56084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
56184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
56284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir)
56384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
56464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->from);
56564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->to);
56664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->increment);
56764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->counter);
56884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
569021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP);
57064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   visit_exec_list(&ir->body_instructions, this);
571021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP);
57284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
57384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
57584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir)
57684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
57764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   switch (ir->mode) {
57864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_break:
579021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      ir_to_mesa_emit_op0(NULL, OPCODE_BRK);
58064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
58164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_continue:
582021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      ir_to_mesa_emit_op0(NULL, OPCODE_CONT);
58364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
58464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   }
58584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
58684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
58784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
58884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
58984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir)
59084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
59184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
59284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   (void)ir;
59384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
59484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
59584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
59684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir)
59784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
59884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* Ignore function bodies other than main() -- we shouldn't see calls to
59984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * them since they should all be inlined before we get to ir_to_mesa.
60084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
60184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   if (strcmp(ir->name, "main") == 0) {
60284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      const ir_function_signature *sig;
60384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      exec_list empty;
60484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
60584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      sig = ir->matching_signature(&empty);
60684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
60784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      assert(sig);
60884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
60984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      foreach_iter(exec_list_iterator, iter, sig->body) {
61084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_instruction *ir = (ir_instruction *)iter.get();
61184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
61284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->accept(this);
61384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
61484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
61584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
61684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6173f08989267d9cdd944787fcf7a300c6f1f84462cEric AnholtGLboolean
6183f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
6193f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{
6203f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   int nonmul_operand = 1 - mul_operand;
6213f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_to_mesa_src_reg a, b, c;
6223f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6233f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_expression *expr = ir->operands[mul_operand]->as_expression();
6243f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   if (!expr || expr->operation != ir_binop_mul)
6253f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      return false;
6263f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6273f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   expr->operands[0]->accept(this);
6283f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   a = this->result;
6293f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   expr->operands[1]->accept(this);
6303f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   b = this->result;
6313f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir->operands[nonmul_operand]->accept(this);
6323f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   c = this->result;
6333f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6343f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   this->result = get_temp(ir->type);
6353f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_to_mesa_emit_op3(ir, OPCODE_MAD,
6363f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt		       ir_to_mesa_dst_reg_from_src(this->result), a, b, c);
6373f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6383f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   return true;
6393f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt}
6403f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
64184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
642f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir,
643f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt				    ir_to_mesa_src_reg *reg, int *num_reladdr)
644f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{
645f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (!reg->reladdr)
646f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      return;
647f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
648f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr);
649f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
650f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (*num_reladdr != 1) {
651f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
652f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
653f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV,
654f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt			  ir_to_mesa_dst_reg_from_src(temp), *reg);
655f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      *reg = temp;
656f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   }
657f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
658f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   (*num_reladdr)--;
659f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt}
660f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
661f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid
66284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir)
66384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
66484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   unsigned int operand;
665f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt   struct ir_to_mesa_src_reg op[2];
6660161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg result_src;
6670161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg result_dst;
66884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
66984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
67084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
67184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6723f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
6733f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt    */
6743f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   if (ir->operation == ir_binop_add) {
6753f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      if (try_emit_mad(ir, 1))
6763f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt	 return;
6773f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      if (try_emit_mad(ir, 0))
6783f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt	 return;
6793f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   }
6803f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
68184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (operand = 0; operand < ir->get_num_operands(); operand++) {
6820161515c395c44233529c8d51f823b60050bc7baEric Anholt      this->result.file = PROGRAM_UNDEFINED;
68384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir->operands[operand]->accept(this);
6840161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (this->result.file == PROGRAM_UNDEFINED) {
68584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_print_visitor v;
68684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 printf("Failed to get tree for expression operand:\n");
68784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->operands[operand]->accept(&v);
68884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 exit(1);
68984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
69084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      op[operand] = this->result;
6918364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
6924ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      /* Matrix expression operands should have been broken down to vector
6934ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt       * operations already.
6944ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt       */
6954ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      assert(!ir->operands[operand]->type->is_matrix());
69684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
69784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6980161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.file = PROGRAM_UNDEFINED;
6990161515c395c44233529c8d51f823b60050bc7baEric Anholt
7000161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
7010161515c395c44233529c8d51f823b60050bc7baEric Anholt    * the actual storage for the result here, instead.
7020161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
7038364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   result_src = get_temp(ir->type);
7040161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* convenience for the emit functions below. */
7050161515c395c44233529c8d51f823b60050bc7baEric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
7069cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   /* Limit writes to the channels that will be used by result_src later.
7079cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * This does limit this temp's use as a temporary for multi-instruction
7089cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * sequences.
7099cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    */
7109cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
71184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
71284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   switch (ir->operation) {
7131d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_logic_not:
714f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
715f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt			  op[0], src_reg_for_float(0.0));
7161d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
717c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   case ir_unop_neg:
7180161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
7190161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
720c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt      break;
721524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt   case ir_unop_abs:
722524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
723524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt      break;
7243acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt   case ir_unop_sign:
7253acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]);
7263acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt      break;
7278761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt   case ir_unop_rcp:
7288761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]);
7298761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt      break;
730524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt
7318c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp:
732b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst,
733b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt				 src_reg_for_float(M_E), op[0]);
7348c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7358c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp2:
7360161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
7378c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7388c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log:
7390161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
7408c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7418c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log2:
7420161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
7438c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7443c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_sin:
7450161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
7463c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
7473c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_cos:
7480161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
7493c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
750ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt
751ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt   case ir_unop_dFdx:
752ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
753ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      break;
754ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt   case ir_unop_dFdy:
755ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
756ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      break;
757ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt
75884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_add:
7597b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
76084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
76184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_sub:
7627b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
76384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
7649b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt
76584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_mul:
7664ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
76784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
76884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_div:
7699a0e421983edc31371440c08687fa2bb2207924dEric Anholt      assert(!"not reached: should be handled by ir_div_to_mul_rcp");
770411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt   case ir_binop_mod:
771411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt      assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
772411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt      break;
77338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
77438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_less:
775f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
77638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
77738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_greater:
778f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
77938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
78038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_lequal:
781f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
78238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
78338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_gequal:
784f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
78538315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
78638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_equal:
787f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
78838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
789763cd75863ed9a16912e585887580c44d1e8109fEric Anholt   case ir_binop_logic_xor:
79038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_nequal:
791f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
79238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
79338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
7944380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_or:
7950161515c395c44233529c8d51f823b60050bc7baEric Anholt      /* This could be a saturated add and skip the SNE. */
7960161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD,
7970161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
7980161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
7990161515c395c44233529c8d51f823b60050bc7baEric Anholt
8000161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE,
8010161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
8020161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
8034380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
8044380099c98119611ceee684669d00be26195c7d7Eric Anholt
8054380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_and:
8064380099c98119611ceee684669d00be26195c7d7Eric Anholt      /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
8070161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL,
8080161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
8090161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
8104380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
8114380099c98119611ceee684669d00be26195c7d7Eric Anholt
81284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_dot:
81384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (ir->operands[0]->type == vec4_type) {
81484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec4_type);
8150161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP4,
8160161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8170161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
81884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec3_type) {
81984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec3_type);
8200161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP3,
8210161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8220161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
82384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec2_type) {
82484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec2_type);
8250161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP2,
8260161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8270161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
82884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
82984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
8309be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt
8319be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt   case ir_binop_cross:
8329be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]);
8339be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt      break;
8349be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt
83584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_unop_sqrt:
8360161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
8378f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src);
8388f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      /* For incoming channels < 0, set the result to 0. */
8398f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
8408f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt			  op[0], src_reg_for_float(0.0), result_src);
84184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
842878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt   case ir_unop_rsq:
8430161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
844878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt      break;
84550ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt   case ir_unop_i2f:
846d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt   case ir_unop_b2f:
847d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt   case ir_unop_b2i:
848423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      /* Mesa IR lacks types, ints are stored as truncated floats. */
8490161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
85050ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt      break;
851423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt   case ir_unop_f2i:
8520161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
853423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      break;
8541d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_f2b:
855411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt   case ir_unop_i2b:
8560161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
8570161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
8581d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
859c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_trunc:
8600161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
861c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
862c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_ceil:
8630161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
8640161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
8650161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src.negate = ~result_src.negate;
866c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
867c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_floor:
8680161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
869c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
870d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt   case ir_unop_fract:
871d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]);
872d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt      break;
873d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt
874c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_min:
8750161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
876c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
877c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_max:
8780161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
879c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
880904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   case ir_binop_pow:
881904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
882904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      break;
883e64a4aaacbc682f24180dff3627b84861844476dEric Anholt
884e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_unop_bit_not:
885e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_unop_u2f:
886e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_lshift:
887e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_rshift:
888e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_and:
889e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_xor:
890e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_or:
891e64a4aaacbc682f24180dff3627b84861844476dEric Anholt      assert(!"GLSL 1.30 features unsupported");
892e64a4aaacbc682f24180dff3627b84861844476dEric Anholt      break;
89384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
894b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt
8950161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = result_src;
89684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
89784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
89884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
89984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
90084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir)
90184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
9020161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
90384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int i;
90484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int swizzle[4];
90584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
906b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   /* Note that this is only swizzles in expressions, not those on the left
907b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * hand side of an assignment, which do write masking.  See ir_assignment
908b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * for that.
909b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    */
91084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
91184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->val->accept(this);
9124006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   src_reg = this->result;
9134006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   assert(src_reg.file != PROGRAM_UNDEFINED);
91484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
91584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (i = 0; i < 4; i++) {
91684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (i < ir->type->vector_elements) {
91784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 switch (i) {
91884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 0:
919698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
92084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
92184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 1:
922698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
92384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
92484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 2:
925698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
92684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
92784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 3:
928698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
92984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
93084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 }
93184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else {
93284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 /* If the type is smaller than a vec4, replicate the last
93384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  * channel out.
93484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  */
935698b84444343189357ad252856d3c5493e47e4faEric Anholt	 swizzle[i] = swizzle[ir->type->vector_elements - 1];
93684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
93784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
93884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9390161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
9400161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[1],
9410161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[2],
9420161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[3]);
94384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9440161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
94584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
94684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
94776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtstatic int
94876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtadd_matrix_ref(struct gl_program *prog, int *tokens)
94976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt{
95076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   int base_pos = -1;
95176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   int i;
95276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
95376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   /* Add a ref for each column.  It looks like the reason we do
95476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * it this way is that _mesa_add_state_reference doesn't work
95576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * for things that aren't vec4s, so the tokens[2]/tokens[3]
95676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * range has to be equal.
95776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    */
95876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   for (i = 0; i < 4; i++) {
95976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      tokens[2] = i;
96076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      tokens[3] = i;
96176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      int pos = _mesa_add_state_reference(prog->Parameters,
96276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt					  (gl_state_index *)tokens);
96376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      if (base_pos == -1)
96476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 base_pos = pos;
96576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      else
96676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 assert(base_pos + i == pos);
96776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   }
96876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
96976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   return base_pos;
97076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt}
97176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
972b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtstatic variable_storage *
97376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtget_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
97476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		       ir_rvalue *array_index)
975bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt{
976bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   /*
977bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * NOTE: The ARB_vertex_program extension specified that matrices get
978bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * loaded in registers in row-major order.  With GLSL, we want column-
979bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * major order.  So, we need to transpose all matrices here...
980bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    */
981bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   static const struct {
982bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      const char *name;
983bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      int matrix;
984bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      int modifier;
985bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   } matrices[] = {
986bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
987bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
988bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
989bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
990bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
991bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
992bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
993bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
994bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
995bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
996bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
997bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
998bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
999bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
1000bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1001bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
1002bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
1003bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
1004bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
1005bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1006bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
1007bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1008bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   };
1009bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   unsigned int i;
1010b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry;
1011bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1012bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   /* C++ gets angry when we try to use an int as a gl_state_index, so we use
1013bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * ints for gl_state_index.  Make sure they're compatible.
1014bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    */
1015bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   assert(sizeof(gl_state_index) == sizeof(int));
1016bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1017bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   for (i = 0; i < Elements(matrices); i++) {
1018bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      if (strcmp(var->name, matrices[i].name) == 0) {
1019bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 int tokens[STATE_LENGTH];
102076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 int base_pos = -1;
1021bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1022bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[0] = matrices[i].matrix;
1023bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[4] = matrices[i].modifier;
102476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 if (matrices[i].matrix == STATE_TEXTURE_MATRIX) {
102576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    ir_constant *index = array_index->constant_expression_value();
102676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    if (index) {
102776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       tokens[1] = index->value.i[0];
102876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       base_pos = add_matrix_ref(prog, tokens);
102976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    } else {
103076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       for (i = 0; i < var->type->length; i++) {
103176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  tokens[1] = i;
103276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  int pos = add_matrix_ref(prog, tokens);
103376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  if (base_pos == -1)
103476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		     base_pos = pos;
103576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  else
103676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		     assert(base_pos + (int)i * 4 == pos);
103776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       }
103876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    }
103976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 } else {
104076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    tokens[1] = 0; /* unused array index */
104176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    base_pos = add_matrix_ref(prog, tokens);
1042bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 }
104376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 tokens[4] = matrices[i].modifier;
1044bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1045b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(var,
1046b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       PROGRAM_STATE_VAR,
1047b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       base_pos);
1048bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1049bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 return entry;
1050bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      }
1051bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   }
1052bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1053bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   return NULL;
1054bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt}
1055bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
105684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
105784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir)
105884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
10590161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
1060b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry = find_variable_storage(ir->var);
1061a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt   unsigned int loc;
106284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
10638364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   if (!entry) {
10648364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      switch (ir->var->mode) {
10658364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_uniform:
106676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var,
106776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt					NULL);
1068bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 if (entry)
1069bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	    break;
1070bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
107185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 /* FINISHME: Fix up uniform name for arrays and things */
1072d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) {
1073d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    /* FINISHME: we whack the location of the var here, which
1074d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	     * is probably not expected.  But we need to communicate
1075d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	     * mesa's sampler number to the tex instruction.
1076d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	     */
1077d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    int sampler = _mesa_add_sampler(this->prog->Parameters,
1078d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					    ir->var->name,
1079d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					    ir->var->type->gl_type);
1080d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    map_sampler(ir->var->location, sampler);
1081d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1082b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_SAMPLER,
1083b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  sampler);
1084b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    this->variables.push_tail(entry);
1085d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    break;
1086d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 }
1087d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
108885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 assert(ir->var->type->gl_type != 0 &&
108985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt		ir->var->type->gl_type != GL_INVALID_ENUM);
109085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 loc = _mesa_add_uniform(this->prog->Parameters,
109185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 ir->var->name,
109285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 type_size(ir->var->type) * 4,
109385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 ir->var->type->gl_type,
109485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				 NULL);
1095d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
109685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 /* Always mark the uniform used at this point.  If it isn't
109785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	  * used, dead code elimination should have nuked the decl already.
109885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	  */
109985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 this->prog->Parameters->Parameters[loc].Used = GL_TRUE;
1100224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
1101b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM, loc);
1102b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 this->variables.push_tail(entry);
11038364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
11048364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_in:
11058364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_out:
11068364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_inout:
1107a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	 /* The linker assigns locations for varyings and attributes,
1108a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * including deprecated builtins (like gl_Color), user-assign
1109a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * generic attributes (glBindVertexLocation), and
1110a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * user-defined varyings.
1111a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  *
1112a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * FINISHME: We would hit this path for function arguments.  Fix!
1113f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	  */
1114f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 assert(ir->var->location != -1);
1115a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	 if (ir->var->mode == ir_var_in ||
1116a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	     ir->var->mode == ir_var_inout) {
1117b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var,
1118b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  PROGRAM_INPUT,
1119b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  ir->var->location);
1120edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt
1121edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	    if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
1122edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt		ir->var->location >= VERT_ATTRIB_GENERIC0) {
1123edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	       _mesa_add_attribute(prog->Attributes,
1124edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   ir->var->name,
1125edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   type_size(ir->var->type) * 4,
1126edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   ir->var->type->gl_type,
1127c64da87611823b4b53e93188f861f748a69936a3Eric Anholt				   ir->var->location - VERT_ATTRIB_GENERIC0);
1128edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	    }
1129f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 } else {
1130b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var,
1131b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  PROGRAM_OUTPUT,
1132b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  ir->var->location);
1133f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 }
1134f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt
11358364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
11368364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_auto:
11377e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick      case ir_var_temporary:
1138b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY,
1139b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       this->next_temp);
1140b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 this->variables.push_tail(entry);
1141224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
11428364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 next_temp += type_size(ir->var->type);
11438364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
114484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
11458364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
11468364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      if (!entry) {
11478364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 printf("Failed to make storage for %s\n", ir->var->name);
11488364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 exit(1);
1149224f712950494730c76b48864f2ca19acde1c8cfEric Anholt      }
115084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
115184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
11528364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.file = entry->file;
11538364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   src_reg.index = entry->index;
115484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
115585e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   if (ir->type->is_scalar() || ir->type->is_vector())
115685e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = swizzle_for_size(ir->var->type->vector_elements);
115785e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   else
115885e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = SWIZZLE_NOOP;
1159f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = NULL;
11600161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.negate = 0;
116184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
11620161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
116384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
116484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
116584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
116684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir)
116784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1168ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir_constant *index;
11690161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
117076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   ir_dereference_variable *deref_var = ir->array->as_dereference_variable();
11718258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt   int element_size = type_size(ir->type);
1172ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt
1173ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   index = ir->array_index->constant_expression_value();
11744e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
117576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   if (deref_var && strncmp(deref_var->var->name,
117676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			    "gl_TextureMatrix",
117776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			    strlen("gl_TextureMatrix")) == 0) {
117876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      ir_to_mesa_src_reg src_reg;
1179b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      struct variable_storage *entry;
118076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
118176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var,
118276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt				     ir->array_index);
118376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      assert(entry);
118476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
118576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      src_reg.file = entry->file;
118676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      src_reg.index = entry->index;
118776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
118876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      src_reg.negate = 0;
118976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
119076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      if (index) {
1191f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 src_reg.reladdr = NULL;
119276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      } else {
119376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type);
119476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
119576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir->array_index->accept(this);
119676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
119776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			     ir_to_mesa_dst_reg_from_src(index_reg),
11988258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt			     this->result, src_reg_for_float(element_size));
119976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
1200f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
1201f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
120276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      }
120376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
120476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      this->result = src_reg;
120576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      return;
120676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   }
120776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
1208ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir->array->accept(this);
12090161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg = this->result;
12104e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
12114d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   if (index) {
12124d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      src_reg.index += index->value.i[0] * element_size;
12134e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   } else {
12144d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir_to_mesa_src_reg array_base = this->result;
12154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      /* Variable index array dereference.  It eats the "vec4" of the
12164d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       * base of the array and an index that offsets the Mesa register
12174d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       * index.
12184d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       */
12194d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir->array_index->accept(this);
12208258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt
12214d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir_to_mesa_src_reg index_reg;
12228258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt
12234d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      if (element_size == 1) {
12244d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 index_reg = this->result;
12254d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      } else {
12264d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 index_reg = get_temp(glsl_type::float_type);
1227f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
12284d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
12294d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			     ir_to_mesa_dst_reg_from_src(index_reg),
12304d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			     this->result, src_reg_for_float(element_size));
1231bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      }
12324d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
12334d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
12344d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
12354e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   }
123684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
123784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
123885e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   if (ir->type->is_scalar() || ir->type->is_vector())
123985e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
124085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   else
124185e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = SWIZZLE_NOOP;
124284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
12430161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
124484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
124584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
12462c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid
12472c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir)
12482c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
12492c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
12500161515c395c44233529c8d51f823b60050bc7baEric Anholt   const glsl_type *struct_type = ir->record->type;
12512c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int offset = 0;
12522c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
12530161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir->record->accept(this);
12542c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
12552c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   for (i = 0; i < struct_type->length; i++) {
12560161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
12572c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 break;
12582c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      offset += type_size(struct_type->fields.structure[i].type);
12592c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
126085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
12610161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.index += offset;
12622c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
12632c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
12642c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/**
12652c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage
12662c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the
12672c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler.
12682c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt *
12692c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * Thanks to ir_swizzle_swizzle, and ir_vec_index_to_swizzle, we
12702c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * should only see potentially one variable array index of a vector,
12712c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * and one swizzle, before getting to actual vec4 storage.  So handle
12722c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * those, then go use ir_dereference to handle the rest.
12732c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */
12740161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg
127518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholtget_assignment_lhs(ir_instruction *ir, ir_to_mesa_visitor *v,
127618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt		   ir_to_mesa_src_reg *r)
1277b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
12780161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg dst_reg;
1279b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   ir_swizzle *swiz;
1280b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt
1281ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   ir_dereference_array *deref_array = ir->as_dereference_array();
1282ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   /* This should have been handled by ir_vec_index_to_cond_assign */
1283ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   if (deref_array) {
1284ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt      assert(!deref_array->array->type->is_vector());
1285ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   }
1286ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt
12870161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Use the rvalue deref handler for the most part.  We'll ignore
12880161515c395c44233529c8d51f823b60050bc7baEric Anholt    * swizzles in it and write swizzles using writemask, though.
12890161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
12902c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   ir->accept(v);
12910161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg = ir_to_mesa_dst_reg_from_src(v->result);
12922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
1293ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   if ((swiz = ir->as_swizzle())) {
129418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      int swizzles[4] = {
129518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 swiz->mask.x,
129618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 swiz->mask.y,
129718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 swiz->mask.z,
129818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 swiz->mask.w
129918ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      };
130018ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      int new_r_swizzle[4];
130118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      int orig_r_swizzle = r->swizzle;
130218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      int i;
130318ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt
130418ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      for (i = 0; i < 4; i++) {
130518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 new_r_swizzle[i] = GET_SWZ(orig_r_swizzle, 0);
130618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      }
1307cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
130818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      dst_reg.writemask = 0;
130918ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      for (i = 0; i < 4; i++) {
131018ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 if (i < swiz->mask.num_components) {
131118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	    dst_reg.writemask |= 1 << swizzles[i];
131218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	    new_r_swizzle[swizzles[i]] = GET_SWZ(orig_r_swizzle, i);
131318ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt	 }
1314cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt      }
131518ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt
131618ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt      r->swizzle = MAKE_SWIZZLE4(new_r_swizzle[0],
131718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt				 new_r_swizzle[1],
131818ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt				 new_r_swizzle[2],
131918ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt				 new_r_swizzle[3]);
1320cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt   }
1321cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
132218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt   return dst_reg;
1323cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt}
1324cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
132584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
132684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir)
132784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
13280161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg l;
13290161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg r;
13307d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt   int i;
133184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
13322c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   assert(!ir->lhs->type->is_array());
13332c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
133484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->rhs->accept(this);
133584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   r = this->result;
1336cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
133718ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt   l = get_assignment_lhs(ir->lhs, this, &r);
1338cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
13390161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(l.file != PROGRAM_UNDEFINED);
13400161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(r.file != PROGRAM_UNDEFINED);
134184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1342346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   if (ir->condition) {
13432d1789e667c4180777829f96856daf91326721b9Eric Anholt      ir_to_mesa_src_reg condition;
13442d1789e667c4180777829f96856daf91326721b9Eric Anholt
13452d1789e667c4180777829f96856daf91326721b9Eric Anholt      ir->condition->accept(this);
13462d1789e667c4180777829f96856daf91326721b9Eric Anholt      condition = this->result;
13472d1789e667c4180777829f96856daf91326721b9Eric Anholt
13482d1789e667c4180777829f96856daf91326721b9Eric Anholt      /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves,
13492d1789e667c4180777829f96856daf91326721b9Eric Anholt       * and the condition we produced is 0.0 or 1.0.  By flipping the
13502d1789e667c4180777829f96856daf91326721b9Eric Anholt       * sign, we can choose which value OPCODE_CMP produces without
13512d1789e667c4180777829f96856daf91326721b9Eric Anholt       * an extra computing the condition.
13522d1789e667c4180777829f96856daf91326721b9Eric Anholt       */
13532d1789e667c4180777829f96856daf91326721b9Eric Anholt      condition.negate = ~condition.negate;
13547d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      for (i = 0; i < type_size(ir->lhs->type); i++) {
13557d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 ir_to_mesa_emit_op3(ir, OPCODE_CMP, l,
13567d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt			     condition, r, ir_to_mesa_src_reg_from_dst(l));
13577d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 l.index++;
13587d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 r.index++;
13597d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      }
13602d1789e667c4180777829f96856daf91326721b9Eric Anholt   } else {
13617d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      for (i = 0; i < type_size(ir->lhs->type); i++) {
13627d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
13637d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 l.index++;
13647d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 r.index++;
13657d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      }
1366346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   }
136784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
136884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
136984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
137084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
137184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir)
137284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
13730161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
13740bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   GLfloat stack_vals[4];
13750bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   GLfloat *values = stack_vals;
13760bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   unsigned int i;
137784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1378ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt   if (ir->type->is_array()) {
1379ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      ir->print();
1380ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      printf("\n");
1381ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      assert(!"FINISHME: array constants");
1382ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt   }
1383ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
13845b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt   /* Unfortunately, 4 floats is all we can get into
13855b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    * _mesa_add_unnamed_constant.  So, make a temp to store an
13865b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    * aggregate constant and move each constant value into it.  If we
13875b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    * get lucky, copy propagation will eliminate the extra moves.
13885b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    */
13895b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
13905b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt   if (ir->type->base_type == GLSL_TYPE_STRUCT) {
13915b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      ir_to_mesa_src_reg temp_base = get_temp(ir->type);
13925b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
13935b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
13945b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      foreach_iter(exec_list_iterator, iter, ir->components) {
13955b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 ir_constant *field_value = (ir_constant *)iter.get();
13965b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 int size = type_size(field_value->type);
13975b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
13985b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 assert(size > 0);
13995b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
14005b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 field_value->accept(this);
14015b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 src_reg = this->result;
14025b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
14035b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 for (i = 0; i < (unsigned int)size; i++) {
14045b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg);
14055b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
14065b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	    src_reg.index++;
14075b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	    temp.index++;
14085b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 }
14095b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      }
14105b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      this->result = temp_base;
14115b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      return;
14125b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt   }
14135b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
1414ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt   if (ir->type->is_matrix()) {
1415ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      ir_to_mesa_src_reg mat = get_temp(glsl_type::vec4_type);
1416ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat);
1417ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1418ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      for (i = 0; i < ir->type->matrix_columns; i++) {
1419ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 src_reg.file = PROGRAM_CONSTANT;
1420ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1421ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 assert(ir->type->base_type == GLSL_TYPE_FLOAT);
1422ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 values = &ir->value.f[i * ir->type->vector_elements];
1423ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1424ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
1425ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt						    values,
1426ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt						    ir->type->vector_elements,
1427ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt						    &src_reg.swizzle);
1428f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 src_reg.reladdr = NULL;
1429ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 src_reg.negate = 0;
1430ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg);
1431ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1432ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 mat_column.index++;
1433ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      }
1434ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1435ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      this->result = mat;
1436582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   }
14370bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt
14380bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   src_reg.file = PROGRAM_CONSTANT;
14390bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   switch (ir->type->base_type) {
14400bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_FLOAT:
14410bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      values = &ir->value.f[0];
14420bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
14430bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_UINT:
14440bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
14450bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.u[i];
14460bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
14470bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
14480bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_INT:
14490bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
14500bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.i[i];
14510bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
14520bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
14530bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_BOOL:
14540bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
14550bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.b[i];
14560bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
14570bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
14580bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   default:
14590bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      assert(!"Non-float/uint/int/bool constant");
14600bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   }
14610bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt
14620bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
14630bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt					      values, ir->type->vector_elements,
14640bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt					      &src_reg.swizzle);
1465f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = NULL;
14660161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.negate = 0;
146784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
14680161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
146984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
147084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
14717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry *
14727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig)
14737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{
14747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *entry;
14757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, this->function_signatures) {
14777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry = (function_entry *)iter.get();
14787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (entry->sig == sig)
14807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 return entry;
14817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
14827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry = talloc(mem_ctx, function_entry);
14847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->sig = sig;
14857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->sig_id = this->next_signature_id++;
14867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->bgn_inst = NULL;
14877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Allocate storage for all the parameters. */
14897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, sig->parameters) {
14907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)iter.get();
1491b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      variable_storage *storage;
14927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
14937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      storage = find_variable_storage(param);
14947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      assert(!storage);
14957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1496b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
1497b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					      this->next_temp);
1498b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      this->variables.push_tail(storage);
14997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      this->next_temp += type_size(param->type);
15017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      break;
15027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
15037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   if (sig->return_type) {
15057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry->return_reg = get_temp(sig->return_type);
15067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   } else {
15077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry->return_reg = ir_to_mesa_undef;
15087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
15097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   this->function_signatures.push_tail(entry);
15117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   return entry;
15127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}
151384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
151484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
151584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir)
151684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
15177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_instruction *call_inst;
15187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_function_signature *sig = ir->get_callee();
15197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *entry = get_function_signature(sig);
15207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int i;
15217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process in parameters. */
15237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   exec_list_iterator sig_iter = sig->parameters.iterator();
15247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, *ir) {
15257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
15267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)sig_iter.get();
15277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (param->mode == ir_var_in ||
15297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	  param->mode == ir_var_inout) {
1530b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 variable_storage *storage = find_variable_storage(param);
15317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 assert(storage);
15327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 param_rval->accept(this);
15347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_src_reg r = this->result;
15357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_dst_reg l;
15377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.file = storage->file;
15387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.index = storage->index;
15397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.reladdr = NULL;
15407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.writemask = WRITEMASK_XYZW;
15417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.cond_mask = COND_TR;
15427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 for (i = 0; i < type_size(param->type); i++) {
15447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
15457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    l.index++;
15467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    r.index++;
15477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
15487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
15497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      sig_iter.next();
15517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
15527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(!sig_iter.has_next());
15537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Emit call instruction */
15557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL,
15567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt				   ir_to_mesa_undef_dst, ir_to_mesa_undef);
15577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   call_inst->function = entry;
15587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process out parameters. */
15607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   sig_iter = sig->parameters.iterator();
15617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, *ir) {
15627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
15637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)sig_iter.get();
15647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (param->mode == ir_var_out ||
15667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	  param->mode == ir_var_inout) {
1567b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 variable_storage *storage = find_variable_storage(param);
15687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 assert(storage);
15697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_src_reg r;
15717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.file = storage->file;
15727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.index = storage->index;
15737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.reladdr = NULL;
15747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.swizzle = SWIZZLE_NOOP;
15757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.negate = 0;
15767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 param_rval->accept(this);
15787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result);
15797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 for (i = 0; i < type_size(param->type); i++) {
15817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
15827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    l.index++;
15837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    r.index++;
15847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
15857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
15867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      sig_iter.next();
15887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
15897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(!sig_iter.has_next());
15907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
15917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process return value. */
15927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   this->result = entry->return_reg;
159384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
159484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
159584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
159684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
159784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir)
159884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
159956d33f8e2be1695c951a811fac1800117c2ca406Carl Worth   ir_to_mesa_src_reg result_src, coord, lod_info = { 0 }, projector;
1600d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   ir_to_mesa_dst_reg result_dst, coord_dst;
1601d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_to_mesa_instruction *inst = NULL;
1602d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   prog_opcode opcode = OPCODE_NOP;
160384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
160484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->coordinate->accept(this);
1605d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1606d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   /* Put our coords in a temp.  We'll need to modify them for shadow,
1607d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * projection, or LOD, so the only case we'd use it as is is if
1608d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * we're doing plain old texturing.  Mesa IR optimization should
1609d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * handle cleaning up our mess in that case.
1610d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    */
1611d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   coord = get_temp(glsl_type::vec4_type);
1612d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   coord_dst = ir_to_mesa_dst_reg_from_src(coord);
1613d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst,
1614d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt		       this->result);
1615d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1616de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt   if (ir->projector) {
1617de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt      ir->projector->accept(this);
1618de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt      projector = this->result;
1619de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt   }
1620de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt
1621d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
1622d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    * the actual storage for the result here, instead.
1623d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    */
1624d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   result_src = get_temp(glsl_type::vec4_type);
1625d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
1626d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1627d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   switch (ir->op) {
1628d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_tex:
1629d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TEX;
1630d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1631d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txb:
1632d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TXB;
1633d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir->lod_info.bias->accept(this);
1634d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      lod_info = this->result;
1635d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1636d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txl:
1637d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TXL;
1638d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir->lod_info.lod->accept(this);
1639d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      lod_info = this->result;
1640d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1641d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txd:
1642d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txf:
1643d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      assert(!"GLSL 1.30 features unsupported");
1644d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1645d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
1646d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1647d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   if (ir->projector) {
1648d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      if (opcode == OPCODE_TEX) {
1649d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 /* Slot the projector in as the last component of the coord. */
1650d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_W;
1651d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector);
1652d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZW;
1653d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 opcode = OPCODE_TXP;
1654d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      } else {
1655d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_src_reg coord_w = coord;
1656d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_w.swizzle = SWIZZLE_WWWW;
1657d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1658d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 /* For the other TEX opcodes there's no projective version
1659d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  * since the last slot is taken up by lod info.  Do the
1660d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  * projective divide now.
1661d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  */
1662d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_W;
1663d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector);
1664d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1665d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZ;
1666d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w);
1667d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1668d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZW;
1669d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord.swizzle = SWIZZLE_XYZW;
1670d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      }
1671d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   }
1672d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1673b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   if (ir->shadow_comparitor) {
1674b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      /* Slot the shadow value in as the second to last component of the
1675b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt       * coord.
1676b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt       */
1677b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      ir->shadow_comparitor->accept(this);
1678b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      coord_dst.writemask = WRITEMASK_Z;
1679b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result);
1680b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      coord_dst.writemask = WRITEMASK_XYZW;
1681b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   }
1682b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt
1683d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) {
1684d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      /* Mesa IR stores lod or lod bias in the last channel of the coords. */
1685d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      coord_dst.writemask = WRITEMASK_W;
1686d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info);
1687d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      coord_dst.writemask = WRITEMASK_XYZW;
1688d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   }
1689d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1690d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord);
1691d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1692b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   if (ir->shadow_comparitor)
1693b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      inst->tex_shadow = GL_TRUE;
1694b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt
1695d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_dereference_variable *sampler = ir->sampler->as_dereference_variable();
1696d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   assert(sampler); /* FINISHME: sampler arrays */
1697d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   /* generate the mapping, remove when we generate storage at
1698d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    * declaration time
1699d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    */
1700d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler->accept(this);
1701d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1702d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   inst->sampler = get_sampler_number(sampler->var->location);
1703d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1704d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   switch (sampler->type->sampler_dimensionality) {
1705d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_1D:
1706d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_1D_INDEX;
1707d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1708d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_2D:
1709d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_2D_INDEX;
1710d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1711d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_3D:
1712d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_3D_INDEX;
1713d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1714d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_CUBE:
1715d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_CUBE_INDEX;
1716d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1717d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   default:
1718d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      assert(!"FINISHME: other texture targets");
1719d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
1720d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1721d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   this->result = result_src;
172284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
172384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
172484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
172584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir)
172684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
17277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(current_function);
17287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   if (ir->get_value()) {
17307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_to_mesa_dst_reg l;
17317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      int i;
17327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir->get_value()->accept(this);
17347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_to_mesa_src_reg r = this->result;
173584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
17367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      l = ir_to_mesa_dst_reg_from_src(current_function->return_reg);
17377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      for (i = 0; i < type_size(current_function->sig->return_type); i++) {
17397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
17407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.index++;
17417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.index++;
17427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
17437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
17447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
17457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_emit_op0(ir, OPCODE_RET);
174684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
174784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
174816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid
174916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir)
175016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{
17515e4dd061d17563828bcce5525400a0ce363aa15dEric Anholt   assert(ir->condition == NULL); /* FINISHME */
175216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
1753021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
175416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke}
175584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
175684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
175784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir)
175884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1759854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
1760cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt   ir_to_mesa_instruction *prev_inst;
1761cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt
1762cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt   prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
1763c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1764c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir->condition->accept(this);
17650161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(this->result.file != PROGRAM_UNDEFINED);
1766c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1767854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   if (ctx->Shader.EmitCondCodes) {
1768854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
1769cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt
1770cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      /* See if we actually generated any instruction for generating
1771cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       * the condition.  If not, then cook up a move to a temp so we
1772cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       * have something to set cond_update on.
1773cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       */
1774cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      if (cond_inst == prev_inst) {
1775cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt	 ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
1776cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt	 cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
1777cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt					 ir_to_mesa_dst_reg_from_src(temp),
1778cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt					 result);
1779cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      }
1780854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      cond_inst->cond_update = GL_TRUE;
1781854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt
1782021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF);
1783854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst->dst_reg.cond_mask = COND_NE;
1784854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   } else {
1785854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst = ir_to_mesa_emit_op1(ir->condition,
1786854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    OPCODE_IF, ir_to_mesa_undef_dst,
1787854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    this->result);
1788854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   }
1789c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1790c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   this->instructions.push_tail(if_inst);
1791c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1792c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   visit_exec_list(&ir->then_instructions, this);
1793c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1794c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   if (!ir->else_instructions.is_empty()) {
1795021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE);
17960a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt      visit_exec_list(&ir->else_instructions, this);
1797c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1798c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
17990161515c395c44233529c8d51f823b60050bc7baEric Anholt   if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
18000161515c395c44233529c8d51f823b60050bc7baEric Anholt				 ir_to_mesa_undef_dst, ir_to_mesa_undef);
180184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
180284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1803ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor()
1804ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{
18050161515c395c44233529c8d51f823b60050bc7baEric Anholt   result.file = PROGRAM_UNDEFINED;
1806ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt   next_temp = 1;
18077b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   next_signature_id = 1;
1808d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler_map = NULL;
1809d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler_map_size = 0;
18107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   current_function = NULL;
1811ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt}
1812ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt
181384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register
181484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
181584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
181684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_src_register mesa_reg;
181784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
181884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.File = reg.file;
1819aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt   assert(reg.index < (1 << INST_INDEX_BITS) - 1);
182084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.Index = reg.index;
182134195832669f0eb7c4a80997cc524f8d10319307Eric Anholt   mesa_reg.Swizzle = reg.swizzle;
1822f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   mesa_reg.RelAddr = reg.reladdr != NULL;
1823ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt   mesa_reg.Negate = reg.negate;
1824285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt   mesa_reg.Abs = 0;
182584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
182684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return mesa_reg;
182784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
182884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1829c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
18307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v,
18317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt		  struct prog_instruction *mesa_instructions,
1832c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt		  int num_instructions)
1833c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
1834e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke   int if_count = 0, loop_count = 0;
183564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int *if_stack, *loop_stack;
183664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int if_stack_pos = 0, loop_stack_pos = 0;
183764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int i, j;
1838c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1839c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
184064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      switch (mesa_instructions[i].Opcode) {
184164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_IF:
1842c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_count++;
184364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
184464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
184564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_count++;
184664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
184764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BRK:
184864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_CONT:
184964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = -1;
185064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
185164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      default:
185264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
185364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      }
1854c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1855c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
185664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   if_stack = (int *)calloc(if_count, sizeof(*if_stack));
185764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
1858c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1859c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
1860c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      switch (mesa_instructions[i].Opcode) {
1861c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_IF:
186264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos] = i;
1863c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos++;
1864c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1865c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ELSE:
186664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
186764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos - 1] = i;
1868c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1869c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ENDIF:
187064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
1871c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos--;
1872c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
187364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
187464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack[loop_stack_pos] = i;
187564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos++;
187664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
187764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_ENDLOOP:
187864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos--;
187964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* Rewrite any breaks/conts at this nesting level (haven't
188064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * already had a BranchTarget assigned) to point to the end
188164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * of the loop.
188264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  */
188364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 for (j = loop_stack[loop_stack_pos]; j < i; j++) {
188464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    if (mesa_instructions[j].Opcode == OPCODE_BRK ||
188564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		mesa_instructions[j].Opcode == OPCODE_CONT) {
188664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       if (mesa_instructions[j].BranchTarget == -1) {
188764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		  mesa_instructions[j].BranchTarget = i;
188864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       }
188964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    }
189064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 }
189164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* The loop ends point at each other. */
189264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
189364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
18947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 break;
18957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      case OPCODE_CAL:
18967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 foreach_iter(exec_list_iterator, iter, v->function_signatures) {
18977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    function_entry *entry = (function_entry *)iter.get();
18987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    if (entry->sig_id == mesa_instructions[i].BranchTarget) {
19007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	       mesa_instructions[i].BranchTarget = entry->inst;
19017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	       break;
19027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    }
19037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
19047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 break;
1905c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      default:
1906c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
1907c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
1908c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1909c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1910c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   free(if_stack);
1911c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
1912c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1913c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
1914c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions,
1915c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      ir_instruction **mesa_instruction_annotation,
1916c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      int num_instructions)
1917c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
1918c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction *last_ir = NULL;
1919c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
1920748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt   int indent = 0;
1921c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1922c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
1923c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      struct prog_instruction *mesa_inst = mesa_instructions + i;
1924c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      ir_instruction *ir = mesa_instruction_annotation[i];
1925c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1926748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt      fprintf(stdout, "%3d: ", i);
1927748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
192864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      if (last_ir != ir && ir) {
1929748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 int j;
1930748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
1931748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 for (j = 0; j < indent; j++) {
1932748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	    fprintf(stdout, " ");
1933748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 }
1934748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 ir->print();
1935c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 printf("\n");
1936c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 last_ir = ir;
1937748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
1938748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 fprintf(stdout, "     "); /* line number spacing. */
1939c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
1940c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1941748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt      indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent,
1942748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt					    PROG_PRINT_DEBUG, NULL);
1943c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
1944c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
1945c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
1946ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void
19474d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_input(struct gl_program *prog,
19484d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   int index,
19494d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   GLboolean reladdr)
19504d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{
19514d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   prog->InputsRead |= BITFIELD64_BIT(index);
19524d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   int i;
19534d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
19544d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   if (reladdr) {
19554d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      if (index >= FRAG_ATTRIB_TEX0 && index <= FRAG_ATTRIB_TEX7) {
19564d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 for (i = 0; i < 8; i++) {
19574d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    prog->InputsRead |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
19584d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 }
19594d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      } else {
19604d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 assert(!"FINISHME: Mark InputsRead for varying arrays");
19614d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      }
19624d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   }
19634d5da50b94115d055ba8d0ff8717054582665384Eric Anholt}
19644d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
19654d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void
19664d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_output(struct gl_program *prog,
19674d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   int index,
19684d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   GLboolean reladdr)
19694d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{
19704d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   prog->OutputsWritten |= BITFIELD64_BIT(index);
19714d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   int i;
19724d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
19734d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   if (reladdr) {
19744d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      if (index >= VERT_RESULT_TEX0 && index <= VERT_RESULT_TEX7) {
19754d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 for (i = 0; i < 8; i++) {
19764d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    prog->OutputsWritten |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
19774d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 }
19784d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      } else {
19794d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 assert(!"FINISHME: Mark OutputsWritten for varying arrays");
19804d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      }
19814d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   }
19824d5da50b94115d055ba8d0ff8717054582665384Eric Anholt}
19834d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
19844d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void
1985ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog)
1986ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{
1987d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   unsigned int i;
1988d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1989ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   prog->InputsRead = 0;
1990ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   prog->OutputsWritten = 0;
1991d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   prog->SamplersUsed = 0;
1992ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
1993ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   for (i = 0; i < prog->NumInstructions; i++) {
1994ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      struct prog_instruction *inst = &prog->Instructions[i];
1995ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      unsigned int reg;
1996ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
1997ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      switch (inst->DstReg.File) {
1998ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      case PROGRAM_OUTPUT:
19994d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 mark_output(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
2000ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
2001ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      case PROGRAM_INPUT:
20024d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 mark_input(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
2003ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
2004ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      default:
2005ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
2006ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      }
2007ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
2008ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) {
2009ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 switch (inst->SrcReg[reg].File) {
2010ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 case PROGRAM_OUTPUT:
20114d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    mark_output(prog, inst->SrcReg[reg].Index,
20124d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			inst->SrcReg[reg].RelAddr);
2013ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
2014ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 case PROGRAM_INPUT:
20154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    mark_input(prog, inst->SrcReg[reg].Index, inst->SrcReg[reg].RelAddr);
2016ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
2017ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 default:
2018ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
2019ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 }
2020ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      }
2021d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2022d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      /* Instead of just using the uniform's value to map to a
2023d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * sampler, Mesa first allocates a separate number for the
2024d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * sampler (_mesa_add_sampler), then we reindex it down to a
2025d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * small integer (sampler_map[], SamplersUsed), then that gets
2026d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * mapped to the uniform's value, and we get an actual sampler.
2027d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       */
2028d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      if (_mesa_is_tex_instruction(inst->Opcode)) {
2029d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 prog->SamplerTargets[inst->TexSrcUnit] =
2030d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    (gl_texture_index)inst->TexSrcTarget;
2031d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 prog->SamplersUsed |= 1 << inst->TexSrcUnit;
2032d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 if (inst->TexShadow) {
2033d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
2034d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 }
2035d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      }
2036ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   }
2037d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2038d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   _mesa_update_shader_textures_used(prog);
2039ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt}
2040ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
204185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt/* Each stage has some uniforms in its Parameters list.  The Uniforms
204285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * list for the linked shader program has a pointer to these uniforms
204385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * in each of the stage's Parameters list, so that their values can be
204485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * updated when a uniform is set.
204585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */
204685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void
204785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtlink_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms,
204885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				     struct gl_program *prog)
204985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{
205085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   unsigned int i;
205185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
205285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   for (i = 0; i < prog->Parameters->NumParameters; i++) {
205385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
205485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
205585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) {
205685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 struct gl_uniform *uniform =
205785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	    _mesa_append_uniform(uniforms, p->Name, prog->Target, i);
205885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 if (uniform)
205985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	    uniform->Initialized = p->Initialized;
206085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      }
206185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   }
206285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt}
206385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
2064364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtstruct gl_program *
206595c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholtget_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
206695c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt		 struct gl_shader *shader)
206784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
206895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt   void *mem_ctx = shader_program;
206984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir_to_mesa_visitor v;
207084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_instruction *mesa_instructions, *mesa_inst;
2071c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction **mesa_instruction_annotation;
2072c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
2073364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct gl_program *prog;
2074364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   GLenum target;
2075c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   const char *target_string;
20767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   GLboolean progress;
2077364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2078364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   switch (shader->Type) {
2079c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   case GL_VERTEX_SHADER:
2080c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target = GL_VERTEX_PROGRAM_ARB;
2081c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target_string = "vertex";
2082c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2083c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   case GL_FRAGMENT_SHADER:
2084c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target = GL_FRAGMENT_PROGRAM_ARB;
2085c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target_string = "fragment";
2086c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2087c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   default:
2088c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      assert(!"should not be reached");
2089c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2090364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
209184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
20921124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt   validate_ir_tree(shader->ir);
20931124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt
2094364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog = ctx->Driver.NewProgram(ctx, target, 1);
2095364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (!prog)
2096364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      return NULL;
2097364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Parameters = _mesa_new_parameter_list();
2098364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Varying = _mesa_new_parameter_list();
2099364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Attributes = _mesa_new_parameter_list();
2100364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.ctx = ctx;
2101364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.prog = prog;
2102364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2103364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.mem_ctx = talloc_new(NULL);
21047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
21057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Emit Mesa IR for main(). */
210616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   visit_exec_list(shader->ir, &v);
2107021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   v.ir_to_mesa_emit_op0(NULL, OPCODE_END);
210884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
21097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Now emit bodies for any functions that were used. */
21107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   do {
21117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      progress = GL_FALSE;
21127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
21137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      foreach_iter(exec_list_iterator, iter, v.function_signatures) {
21147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 function_entry *entry = (function_entry *)iter.get();
21157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
21167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 if (!entry->bgn_inst) {
21177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    v.current_function = entry;
21187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
21197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB);
21207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst->function = entry;
21217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
21227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    visit_exec_list(&entry->sig->body, &v);
21237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
21247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_RET);
21257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB);
21267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    progress = GL_TRUE;
21277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
21287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
21297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   } while (progress);
21307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
2131364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->NumTemporaries = v.next_temp;
2132364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
213384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int num_instructions = 0;
213484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
213584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      num_instructions++;
213684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
213784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
213884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_instructions =
213984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      (struct prog_instruction *)calloc(num_instructions,
214084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt					sizeof(*mesa_instructions));
2141364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *,
2142364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt					      num_instructions);
214384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
214484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_inst = mesa_instructions;
2145c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   i = 0;
214684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
214784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
2148b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt
214984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->Opcode = inst->op;
2150854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      mesa_inst->CondUpdate = inst->cond_update;
215184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.File = inst->dst_reg.file;
215284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.Index = inst->dst_reg.index;
2153854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
215412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
2155f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL;
215684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
215784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
215884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
2159d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      mesa_inst->TexSrcUnit = inst->sampler;
2160d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      mesa_inst->TexSrcTarget = inst->tex_target;
2161b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      mesa_inst->TexShadow = inst->tex_shadow;
2162c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      mesa_instruction_annotation[i] = inst->ir;
2163aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt
216495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt      if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) {
216595c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	 shader_program->InfoLog =
216695c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	    talloc_asprintf_append(shader_program->InfoLog,
216795c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt				   "Couldn't flatten if statement\n");
216895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	 shader_program->LinkStatus = false;
216995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt      }
217095c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt
21717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (mesa_inst->Opcode == OPCODE_BGNSUB)
21727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 inst->function->inst = i;
21737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      else if (mesa_inst->Opcode == OPCODE_CAL)
21747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */
2175d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt      else if (mesa_inst->Opcode == OPCODE_ARL)
2176d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt	 prog->NumAddressRegs = 1;
21777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
217884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst++;
2179c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      i++;
218084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
2181c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
21827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   set_branchtargets(&v, mesa_instructions, num_instructions);
2183c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   if (ctx->Shader.Flags & GLSL_DUMP) {
2184c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      printf("Mesa %s program:\n", target_string);
2185364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      print_program(mesa_instructions, mesa_instruction_annotation,
2186364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt		    num_instructions);
2187364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2188364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2189364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Instructions = mesa_instructions;
2190364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->NumInstructions = num_instructions;
2191364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
219216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   _mesa_reference_program(ctx, &shader->Program, prog);
2193364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
219428faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt   if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
219528faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt      _mesa_optimize_program(ctx, prog);
219628faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt   }
219728faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt
2198364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   return prog;
2199364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt}
2200364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
220116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" {
220216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt
220316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid
220416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
2205364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{
22062462a536ea5c98867296905e3da127eba7c7bdffIan Romanick   struct _mesa_glsl_parse_state *state =
22072462a536ea5c98867296905e3da127eba7c7bdffIan Romanick      new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
22085e18b051c039564d1998818d08caf1bff3983630Ian Romanick
2209153eca98064252be4daad9cc27746f37c245b627Ian Romanick   const char *source = shader->Source;
221006143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick   state->error = preprocess(state, &source, &state->info_log,
221106143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick			     &ctx->Extensions);
2212153eca98064252be4daad9cc27746f37c245b627Ian Romanick
2213153eca98064252be4daad9cc27746f37c245b627Ian Romanick   if (!state->error) {
2214153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_lexer_ctor(state, source);
2215153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_parse(state);
2216153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_lexer_dtor(state);
2217153eca98064252be4daad9cc27746f37c245b627Ian Romanick   }
2218364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
221916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   shader->ir = new(shader) exec_list;
2220364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (!state->error && !state->translation_unit.is_empty())
222116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt      _mesa_ast_to_hir(shader->ir, state);
2222364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
222316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   if (!state->error && !shader->ir->is_empty()) {
2224ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt      validate_ir_tree(shader->ir);
2225ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt
22264802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      /* Lowering */
22274802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      do_mat_op_to_vec(shader->ir);
22284802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      do_mod_to_fract(shader->ir);
22294802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      do_div_to_mul_rcp(shader->ir);
22304802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt
22314802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      /* Optimization passes */
2232364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      bool progress;
2233364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      do {
2234364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 progress = false;
2235364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
223616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_function_inlining(shader->ir) || progress;
223716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_if_simplification(shader->ir) || progress;
223816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_copy_propagation(shader->ir) || progress;
223916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_dead_code_local(shader->ir) || progress;
224016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_dead_code_unlinked(state, shader->ir) || progress;
224116b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_constant_variable_unlinked(shader->ir) || progress;
224216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_constant_folding(shader->ir) || progress;
2243d674ebcee0d2731e50d6530502cefcebc39dcdb6Eric Anholt	 progress = do_if_return(shader->ir) || progress;
224495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	 if (ctx->Shader.EmitNoIfs)
224595c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	    progress = do_if_to_cond_assign(shader->ir) || progress;
2246a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
224716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_vec_index_to_swizzle(shader->ir) || progress;
2248a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	 /* Do this one after the previous to let the easier pass handle
2249a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	  * constant vector indexing.
2250a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	  */
2251a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	 progress = do_vec_index_to_cond_assign(shader->ir) || progress;
2252a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
225316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_swizzle_swizzle(shader->ir) || progress;
2254364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      } while (progress);
2255ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt
2256ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt      validate_ir_tree(shader->ir);
2257364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2258364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2259364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->symbols = state->symbols;
2260364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2261364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->CompileStatus = !state->error;
2262364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->InfoLog = state->info_log;
226325f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick   shader->Version = state->language_version;
2264d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick   memcpy(shader->builtins_to_link, state->builtins_to_link,
2265d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick	  sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
2266d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick   shader->num_builtins_to_link = state->num_builtins_to_link;
2267c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2268116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke   /* Retain any live IR, but trash the rest. */
226960e2d06d1ccc66ad00cd7ab81c418853f21be291Ian Romanick   reparent_ir(shader->ir, shader);
2270116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke
2271364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   talloc_free(state);
2272364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt }
2273364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2274364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid
2275364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
2276364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{
2277364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   unsigned int i;
2278849e18153cd91d812f694b806a84008498860bc3Eric Anholt
2279364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_clear_shader_program_data(ctx, prog);
2280364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2281849e18153cd91d812f694b806a84008498860bc3Eric Anholt   prog->LinkStatus = GL_TRUE;
2282364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2283364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   for (i = 0; i < prog->NumShaders; i++) {
2284849e18153cd91d812f694b806a84008498860bc3Eric Anholt      if (!prog->Shaders[i]->CompileStatus) {
2285849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 prog->InfoLog =
2286849e18153cd91d812f694b806a84008498860bc3Eric Anholt	    talloc_asprintf_append(prog->InfoLog,
2287364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				   "linking with uncompiled shader");
2288849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 prog->LinkStatus = GL_FALSE;
2289364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      }
2290364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2291364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2292364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Varying = _mesa_new_parameter_list();
2293364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
2294364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
2295364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2296849e18153cd91d812f694b806a84008498860bc3Eric Anholt   if (prog->LinkStatus) {
2297849e18153cd91d812f694b806a84008498860bc3Eric Anholt      link_shaders(prog);
2298849e18153cd91d812f694b806a84008498860bc3Eric Anholt
2299849e18153cd91d812f694b806a84008498860bc3Eric Anholt      /* We don't use the linker's uniforms list, and cook up our own at
2300849e18153cd91d812f694b806a84008498860bc3Eric Anholt       * generate time.
2301849e18153cd91d812f694b806a84008498860bc3Eric Anholt       */
2302849e18153cd91d812f694b806a84008498860bc3Eric Anholt      free(prog->Uniforms);
2303849e18153cd91d812f694b806a84008498860bc3Eric Anholt      prog->Uniforms = _mesa_new_uniform_list();
2304849e18153cd91d812f694b806a84008498860bc3Eric Anholt   }
2305364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2306364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (prog->LinkStatus) {
23073fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick      for (i = 0; i < prog->_NumLinkedShaders; i++) {
2308364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 struct gl_program *linked_prog;
2309364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2310849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 linked_prog = get_mesa_program(ctx, prog,
23113fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick					prog->_LinkedShaders[i]);
2312ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 count_resources(linked_prog);
2313364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
231485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
231585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
23163fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick	 switch (prog->_LinkedShaders[i]->Type) {
2317364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 case GL_VERTEX_SHADER:
2318364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    _mesa_reference_vertprog(ctx, &prog->VertexProgram,
2319364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				     (struct gl_vertex_program *)linked_prog);
23207dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt	    ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
23217dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt					    linked_prog);
2322364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    break;
2323364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 case GL_FRAGMENT_SHADER:
2324364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
2325364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				     (struct gl_fragment_program *)linked_prog);
23267dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt	    ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
23277dc1e0b3267f0bf4dc0ef015b972f7fa6c4c317aEric Anholt					    linked_prog);
2328364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    break;
2329364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 }
2330364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      }
2331364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2332364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt}
2333364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2334364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */
2335