ir_to_mesa.cpp revision 455290e4281bf53ce2fe248a2adf5163563c44c8
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"
48fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt#include "program/hash_table.h"
49afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_instruction.h"
50afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_optimize.h"
51afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_print.h"
52afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/program.h"
53afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_uniform.h"
54afe125e0a18ac3886c45c7e6b02b122fb2d327b5Eric Anholt#include "program/prog_parameter.h"
55aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt}
5684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
579c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtstatic int swizzle_for_size(int size);
589c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt
59554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt/**
60554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * This struct is a corresponding struct to Mesa prog_src_register, with
61554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt * wider fields.
62554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt */
63554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_src_reg {
649c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   ir_to_mesa_src_reg(int file, int index, const glsl_type *type)
659c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   {
669c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      this->file = file;
679c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      this->index = index;
689c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      if (type && (type->is_scalar() || type->is_vector() || type->is_matrix()))
699c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt	 this->swizzle = swizzle_for_size(type->vector_elements);
709c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      else
719c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt	 this->swizzle = SWIZZLE_XYZW;
729c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      this->negate = 0;
739c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      this->reladdr = NULL;
749c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   }
759c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt
769c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   ir_to_mesa_src_reg()
779c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   {
789c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      this->file = PROGRAM_UNDEFINED;
799c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   }
809c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt
81554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
82554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
83582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   GLuint swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
84554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int negate; /**< NEGATE_XYZW mask from mesa */
85f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /** Register index should be offset by the integer in this reg. */
86f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_src_reg *reladdr;
87554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_src_reg;
88554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
89554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholttypedef struct ir_to_mesa_dst_reg {
90554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file; /**< PROGRAM_* from Mesa */
91554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
92554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int writemask; /**< Bitfield of WRITEMASK_[XYZW] */
93854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   GLuint cond_mask:4;
94f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /** Register index should be offset by the integer in this reg. */
95f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_src_reg *reladdr;
96554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt} ir_to_mesa_dst_reg;
97554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
98554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtextern ir_to_mesa_src_reg ir_to_mesa_undef;
99554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
100554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_instruction : public exec_node {
101554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
102554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   enum prog_opcode op;
103554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_dst_reg dst_reg;
104554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_src_reg src_reg[3];
105554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** Pointer to the ir source this tree came from for debugging */
106554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_instruction *ir;
107854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   GLboolean cond_update;
108d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int sampler; /**< sampler index */
109d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   int tex_target; /**< One of TEXTURE_*_INDEX */
110b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   GLboolean tex_shadow;
1117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   class function_entry *function; /* Set on OPCODE_CAL or OPCODE_BGNSUB */
113554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
114554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
115b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtclass variable_storage : public exec_node {
116554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
117b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage(ir_variable *var, int file, int index)
118554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      : file(file), index(index), var(var)
119554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   {
120554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt      /* empty */
121554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   }
122554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
123554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int file;
124554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int index;
125554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_variable *var; /* variable that maps to this, if any */
126554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
127554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtclass function_entry : public exec_node {
1297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtpublic:
1307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_function_signature *sig;
1317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * identifier of this function signature used by the program.
1347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * At the point that Mesa instructions for function calls are
1367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * generated, we don't know the address of the first instruction of
1377b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * the function body.  So we make the BranchTarget that is called a
1387b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * small integer and rewrite them during set_branchtargets().
1397b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int sig_id;
1417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Pointer to first instruction of the function body.
1447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Set during function body emits after main() is processed.
1467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_instruction *bgn_inst;
1487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /**
1507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Index of the first instruction of the function body in actual
1517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Mesa IR.
1527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    *
1537b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    * Set after convertion from ir_to_mesa_instruction to prog_instruction.
1547b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt    */
1557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int inst;
1567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /** Storage for the return value. */
1587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_src_reg return_reg;
1597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt};
1607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
161554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtclass ir_to_mesa_visitor : public ir_visitor {
162554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholtpublic:
163554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_visitor();
164fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   ~ir_to_mesa_visitor();
165554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *current_function;
1677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
168364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   GLcontext *ctx;
169364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct gl_program *prog;
170364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
171554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   int next_temp;
172a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
173b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *find_variable_storage(ir_variable *var);
174554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
1757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *get_function_signature(ir_function_signature *sig);
1767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1778364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   ir_to_mesa_src_reg get_temp(const glsl_type *type);
178f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   void reladdr_to_temp(ir_instruction *ir,
179f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt			ir_to_mesa_src_reg *reg, int *num_reladdr);
180554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
181554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg src_reg_for_float(float val);
182554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
183554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /**
184554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * \name Visit methods
185554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    *
186554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * As typical for the visitor pattern, there must be one \c visit method for
187554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * each concrete subclass of \c ir_instruction.  Virtual base classes within
188554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    * the hierarchy should not have \c visit methods.
189554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt    */
190554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@{*/
191554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_variable *);
192554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop *);
193554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_loop_jump *);
194554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function_signature *);
195554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_function *);
196554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_expression *);
197554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_swizzle *);
198554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_variable  *);
199554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_array *);
200554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_dereference_record *);
201554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_assignment *);
202554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_constant *);
203554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_call *);
204554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_return *);
20516efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke   virtual void visit(ir_discard *);
206554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_texture *);
207554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   virtual void visit(ir_if *);
208554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /*@}*/
209554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
210554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   struct ir_to_mesa_src_reg result;
211554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
212b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   /** List of variable_storage */
213b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   exec_list variables;
214554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
2157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /** List of function_entry */
2167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   exec_list function_signatures;
2177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int next_signature_id;
2187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
219554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   /** List of ir_to_mesa_instruction */
220554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   exec_list instructions;
221554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
222021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op0(ir_instruction *ir,
223021222c6a872ca2eef770ebadb8754f659775204Eric Anholt					       enum prog_opcode op);
224021222c6a872ca2eef770ebadb8754f659775204Eric Anholt
225554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op1(ir_instruction *ir,
226554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
227554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
228554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0);
229554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
230554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op2(ir_instruction *ir,
231554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
232554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
233554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
234554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1);
235554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
236554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   ir_to_mesa_instruction *ir_to_mesa_emit_op3(ir_instruction *ir,
237554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       enum prog_opcode op,
238554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_dst_reg dst,
239554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src0,
240554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src1,
241554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt					       ir_to_mesa_src_reg src2);
242554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
243554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt   void ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
244554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   enum prog_opcode op,
245554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_dst_reg dst,
246554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt				   ir_to_mesa_src_reg src0);
2470ee7d80269bfab14683623b0c8fc12da43db8d78Eric Anholt
248904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   void ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
249904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   enum prog_opcode op,
250904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_dst_reg dst,
251904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_src_reg src0,
252904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   ir_to_mesa_src_reg src1);
253904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
2543f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   GLboolean try_emit_mad(ir_expression *ir,
2553f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt			  int mul_operand);
2563f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
25747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   int add_uniform(const char *name,
25847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt		   const glsl_type *type,
25947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt		   ir_constant *constant);
26026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt   void add_aggregate_uniform(ir_instruction *ir,
26126675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt			      const char *name,
26226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt			      const struct glsl_type *type,
26347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt			      ir_constant *constant,
26426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt			      struct ir_to_mesa_dst_reg temp);
26526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
266fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   struct hash_table *sampler_map;
267d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
268fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   void set_sampler_location(ir_variable *sampler, int location);
269fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   int get_sampler_location(ir_variable *sampler);
270d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
271364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   void *mem_ctx;
272554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt};
273554dbcce77cc7eb38b786c77eee87a5f391b090bEric Anholt
2749c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholtir_to_mesa_src_reg ir_to_mesa_undef = ir_to_mesa_src_reg(PROGRAM_UNDEFINED, 0, NULL);
27584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
276c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtir_to_mesa_dst_reg ir_to_mesa_undef_dst = {
277f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP, COND_TR, NULL,
278c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt};
279c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2800161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg ir_to_mesa_address_reg = {
281f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   PROGRAM_ADDRESS, 0, WRITEMASK_X, COND_TR, NULL
2820161515c395c44233529c8d51f823b60050bc7baEric Anholt};
2830161515c395c44233529c8d51f823b60050bc7baEric Anholt
2840161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic int swizzle_for_size(int size)
2850161515c395c44233529c8d51f823b60050bc7baEric Anholt{
2860161515c395c44233529c8d51f823b60050bc7baEric Anholt   int size_swizzles[4] = {
2870161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
2880161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
2890161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
2900161515c395c44233529c8d51f823b60050bc7baEric Anholt      MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
2910161515c395c44233529c8d51f823b60050bc7baEric Anholt   };
2920161515c395c44233529c8d51f823b60050bc7baEric Anholt
2930161515c395c44233529c8d51f823b60050bc7baEric Anholt   return size_swizzles[size - 1];
2940161515c395c44233529c8d51f823b60050bc7baEric Anholt}
2950161515c395c44233529c8d51f823b60050bc7baEric Anholt
29684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
2970161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op3(ir_instruction *ir,
2980161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
2990161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
3000161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
3010161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1,
3020161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src2)
30384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
304364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   ir_to_mesa_instruction *inst = new(mem_ctx) ir_to_mesa_instruction();
305f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   int num_reladdr = 0;
306f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
307f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   /* If we have to do relative addressing, we want to load the ARL
308f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    * reg directly for one of the regs, and preload the other reladdr
309f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    * sources into temps.
310f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt    */
311f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += dst.reladdr != NULL;
312f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src0.reladdr != NULL;
313f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src1.reladdr != NULL;
314f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   num_reladdr += src2.reladdr != NULL;
315f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
316f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src2, &num_reladdr);
317f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src1, &num_reladdr);
318f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   reladdr_to_temp(ir, &src0, &num_reladdr);
319f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
320f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (dst.reladdr) {
321f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg,
322f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt                          *dst.reladdr);
323f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
324f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      num_reladdr--;
325f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   }
326f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   assert(num_reladdr == 0);
32784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
32884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->op = op;
32984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->dst_reg = dst;
33084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[0] = src0;
33184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[1] = src1;
33284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   inst->src_reg[2] = src2;
333c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   inst->ir = ir;
33484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   inst->function = NULL;
3367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
3370161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->instructions.push_tail(inst);
33884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
33984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return inst;
34084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
34184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
34284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
34384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
3440161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op2(ir_instruction *ir,
3450161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
3460161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
3470161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0,
3480161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src1)
34984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
3500161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst, src0, src1, ir_to_mesa_undef);
35184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
35284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
35384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_instruction *
3540161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op1(ir_instruction *ir,
3550161515c395c44233529c8d51f823b60050bc7baEric Anholt					enum prog_opcode op,
3560161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_dst_reg dst,
3570161515c395c44233529c8d51f823b60050bc7baEric Anholt					ir_to_mesa_src_reg src0)
358bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt{
3595a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   assert(dst.writemask != 0);
3600161515c395c44233529c8d51f823b60050bc7baEric Anholt   return ir_to_mesa_emit_op3(ir, op, dst,
3610161515c395c44233529c8d51f823b60050bc7baEric Anholt			      src0, ir_to_mesa_undef, ir_to_mesa_undef);
362bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
363bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
364021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_instruction *
365021222c6a872ca2eef770ebadb8754f659775204Eric Anholtir_to_mesa_visitor::ir_to_mesa_emit_op0(ir_instruction *ir,
366021222c6a872ca2eef770ebadb8754f659775204Eric Anholt					enum prog_opcode op)
367021222c6a872ca2eef770ebadb8754f659775204Eric Anholt{
368021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   return ir_to_mesa_emit_op3(ir, op, ir_to_mesa_undef_dst,
369021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef,
370021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef,
371021222c6a872ca2eef770ebadb8754f659775204Eric Anholt			      ir_to_mesa_undef);
372021222c6a872ca2eef770ebadb8754f659775204Eric Anholt}
373021222c6a872ca2eef770ebadb8754f659775204Eric Anholt
374d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtvoid
375fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::set_sampler_location(ir_variable *sampler, int location)
376d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{
377fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   if (this->sampler_map == NULL) {
378fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt      this->sampler_map = hash_table_ctor(0, hash_table_pointer_hash,
379fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt					  hash_table_pointer_compare);
380d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
381d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
382fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   hash_table_insert(this->sampler_map, (void *)(uintptr_t)location, sampler);
383d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt}
384d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
385d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholtint
386fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::get_sampler_location(ir_variable *sampler)
387d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt{
388fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   void *result = hash_table_find(this->sampler_map, sampler);
389fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt
390fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   return (int)(uintptr_t)result;
391d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt}
392d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
3930161515c395c44233529c8d51f823b60050bc7baEric Anholtinline ir_to_mesa_dst_reg
3940161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
39584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
3960161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_dst_reg dst_reg;
39784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
3980161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.file = reg.file;
3990161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.index = reg.index;
4000161515c395c44233529c8d51f823b60050bc7baEric Anholt   dst_reg.writemask = WRITEMASK_XYZW;
401854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   dst_reg.cond_mask = COND_TR;
402f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   dst_reg.reladdr = reg.reladdr;
4030161515c395c44233529c8d51f823b60050bc7baEric Anholt
4040161515c395c44233529c8d51f823b60050bc7baEric Anholt   return dst_reg;
405bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt}
406bf9953335031b3de721245ec7a2986d0b4f70027Eric Anholt
4072d1789e667c4180777829f96856daf91326721b9Eric Anholtinline ir_to_mesa_src_reg
4082d1789e667c4180777829f96856daf91326721b9Eric Anholtir_to_mesa_src_reg_from_dst(ir_to_mesa_dst_reg reg)
4092d1789e667c4180777829f96856daf91326721b9Eric Anholt{
4109c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   return ir_to_mesa_src_reg(reg.file, reg.index, NULL);
4112d1789e667c4180777829f96856daf91326721b9Eric Anholt}
4122d1789e667c4180777829f96856daf91326721b9Eric Anholt
41312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt/**
41412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Emits Mesa scalar opcodes to produce unique answers across channels.
41512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt *
41612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * Some Mesa opcodes are scalar-only, like ARB_fp/vp.  The src X
41712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * channel determines the result across all channels.  So to do a vec4
41812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * of this operation, we want to emit a scalar per source channel used
41912f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt * to produce dest channels.
42012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt */
42112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholtvoid
422904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op2(ir_instruction *ir,
4230161515c395c44233529c8d51f823b60050bc7baEric Anholt					       enum prog_opcode op,
4240161515c395c44233529c8d51f823b60050bc7baEric Anholt					       ir_to_mesa_dst_reg dst,
425904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg orig_src0,
426904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg orig_src1)
42712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt{
42812f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   int i, j;
429315c638b8cf0a92f9f0a8ee496e77e90e4b66d09Eric Anholt   int done_mask = ~dst.writemask;
43012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
43112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   /* Mesa RCP is a scalar operation splatting results to all channels,
43212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * like ARB_fp/vp.  So emit as many RCPs as necessary to cover our
43312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    * dst channels.
43412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt    */
43512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   for (i = 0; i < 4; i++) {
436582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt      GLuint this_mask = (1 << i);
43712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      ir_to_mesa_instruction *inst;
438904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_src_reg src0 = orig_src0;
439904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_src_reg src1 = orig_src1;
44012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
44112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      if (done_mask & this_mask)
44212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 continue;
44312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
444904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      GLuint src0_swiz = GET_SWZ(src0.swizzle, i);
445904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      GLuint src1_swiz = GET_SWZ(src1.swizzle, i);
44612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      for (j = i + 1; j < 4; j++) {
447904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	 if (!(done_mask & (1 << j)) &&
448904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	     GET_SWZ(src0.swizzle, j) == src0_swiz &&
449904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt	     GET_SWZ(src1.swizzle, j) == src1_swiz) {
45012f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	    this_mask |= (1 << j);
45112f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt	 }
45212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      }
453904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      src0.swizzle = MAKE_SWIZZLE4(src0_swiz, src0_swiz,
454904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				   src0_swiz, src0_swiz);
455904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      src1.swizzle = MAKE_SWIZZLE4(src1_swiz, src1_swiz,
456904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				  src1_swiz, src1_swiz);
45712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
458904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      inst = ir_to_mesa_emit_op2(ir, op,
4590161515c395c44233529c8d51f823b60050bc7baEric Anholt				 dst,
460904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				 src0,
461904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt				 src1);
46212f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      inst->dst_reg.writemask = this_mask;
46312f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      done_mask |= this_mask;
46412f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt   }
46512f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt}
46612f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt
467904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtvoid
468904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholtir_to_mesa_visitor::ir_to_mesa_emit_scalar_op1(ir_instruction *ir,
469904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       enum prog_opcode op,
470904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_dst_reg dst,
471904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt					       ir_to_mesa_src_reg src0)
472904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt{
47359a23d7fb93603b2449db4c5d786934a07aebfcbEric Anholt   ir_to_mesa_src_reg undef = ir_to_mesa_undef;
474904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
475904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   undef.swizzle = SWIZZLE_XXXX;
476904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
477904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   ir_to_mesa_emit_scalar_op2(ir, op, dst, src0, undef);
478904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt}
479904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt
4800161515c395c44233529c8d51f823b60050bc7baEric Anholtstruct ir_to_mesa_src_reg
4810161515c395c44233529c8d51f823b60050bc7baEric Anholtir_to_mesa_visitor::src_reg_for_float(float val)
482b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
4839c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   ir_to_mesa_src_reg src_reg(PROGRAM_CONSTANT, -1, NULL);
4841d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
485582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
486582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt					      &val, 1, &src_reg.swizzle);
4871d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4880161515c395c44233529c8d51f823b60050bc7baEric Anholt   return src_reg;
4891d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt}
4901d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt
4912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtstatic int
4922c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholttype_size(const struct glsl_type *type)
4932c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
4942c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
4952c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int size;
4962c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
4972c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   switch (type->base_type) {
4982c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_UINT:
4992c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_INT:
5002c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_FLOAT:
5012c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_BOOL:
502a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      if (type->is_matrix()) {
5039968f1b23c475c99139f0209c7a049ed00df01afEric Anholt	 return type->matrix_columns;
504a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      } else {
505a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 /* Regardless of size of vector, it gets a vec4. This is bad
506a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * packing for things like floats, but otherwise arrays become a
507a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * mess.  Hopefully a later pass over the code can pack scalars
508a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  * down if appropriate.
509a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	  */
510a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return 1;
511a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt      }
5122c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_ARRAY:
5132c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return type_size(type->fields.array) * type->length;
5142c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   case GLSL_TYPE_STRUCT:
5152c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      size = 0;
5162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      for (i = 0; i < type->length; i++) {
5172c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 size += type_size(type->fields.structure[i].type);
5182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      }
5192c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      return size;
5202c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   default:
5212c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      assert(0);
5222c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
5232c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
5242c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
525d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt/**
526d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * In the initial pass of codegen, we assign temporary numbers to
527d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * intermediate results.  (not SSA -- variable assignments will reuse
528d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * storage).  Actual register allocation for the Mesa VM occurs in a
529d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt * pass over the Mesa IR later.
530d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt */
531d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_src_reg
532d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholtir_to_mesa_visitor::get_temp(const glsl_type *type)
533d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt{
534d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   ir_to_mesa_src_reg src_reg;
535d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   int swizzle[4];
536d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   int i;
537d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
538d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.file = PROGRAM_TEMPORARY;
539d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   src_reg.index = next_temp;
540f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   src_reg.reladdr = NULL;
541d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   next_temp += type_size(type);
542d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
54320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt   if (type->is_array() || type->is_record()) {
54420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      src_reg.swizzle = SWIZZLE_NOOP;
54520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt   } else {
54620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      for (i = 0; i < type->vector_elements; i++)
54720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 swizzle[i] = i;
54820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      for (; i < 4; i++)
54920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 swizzle[i] = type->vector_elements - 1;
55020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1],
55120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt				      swizzle[2], swizzle[3]);
55220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt   }
553ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt   src_reg.negate = 0;
554d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
555d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt   return src_reg;
556d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt}
557d5a5df45a4af93bb845483bdeeae7c8e042b03d8Eric Anholt
558b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtvariable_storage *
559a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholtir_to_mesa_visitor::find_variable_storage(ir_variable *var)
56084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
561a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt
562b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry;
56384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
564b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   foreach_iter(exec_list_iterator, iter, this->variables) {
565b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      entry = (variable_storage *)iter.get();
56684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
5670161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (entry->var == var)
568a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt	 return entry;
56984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
57084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
571a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt   return NULL;
572a9b619bb3b96a90d14650771dedaf1db840d70a6Eric Anholt}
57384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
57484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
57584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_variable *ir)
57684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
5774a962170d7cf4243d6ae156fca20a6167388925dEric Anholt   if (strcmp(ir->name, "gl_FragCoord") == 0) {
5784a962170d7cf4243d6ae156fca20a6167388925dEric Anholt      struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
5794a962170d7cf4243d6ae156fca20a6167388925dEric Anholt
5804a962170d7cf4243d6ae156fca20a6167388925dEric Anholt      fp->OriginUpperLeft = ir->origin_upper_left;
5814a962170d7cf4243d6ae156fca20a6167388925dEric Anholt      fp->PixelCenterInteger = ir->pixel_center_integer;
5824a962170d7cf4243d6ae156fca20a6167388925dEric Anholt   }
58384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
58484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
58584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
58684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop *ir)
58784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
58864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->from);
58964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->to);
59064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->increment);
59164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   assert(!ir->counter);
59284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
593021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(NULL, OPCODE_BGNLOOP);
59464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   visit_exec_list(&ir->body_instructions, this);
595021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(NULL, OPCODE_ENDLOOP);
59684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
59784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
59884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
59984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_loop_jump *ir)
60084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
60164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   switch (ir->mode) {
60264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_break:
603021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      ir_to_mesa_emit_op0(NULL, OPCODE_BRK);
60464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
60564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   case ir_loop_jump::jump_continue:
606021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      ir_to_mesa_emit_op0(NULL, OPCODE_CONT);
60764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      break;
60864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   }
60984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
61084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
61184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
61284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
61384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function_signature *ir)
61484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
61584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   assert(0);
61684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   (void)ir;
61784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
61884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
61984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
62084771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_function *ir)
62184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
62284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* Ignore function bodies other than main() -- we shouldn't see calls to
62384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    * them since they should all be inlined before we get to ir_to_mesa.
62484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt    */
62584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   if (strcmp(ir->name, "main") == 0) {
62684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      const ir_function_signature *sig;
62784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      exec_list empty;
62884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
62984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      sig = ir->matching_signature(&empty);
63084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
63184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      assert(sig);
63284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
63384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      foreach_iter(exec_list_iterator, iter, sig->body) {
63484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_instruction *ir = (ir_instruction *)iter.get();
63584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
63684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->accept(this);
63784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
63884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
63984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
64084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6413f08989267d9cdd944787fcf7a300c6f1f84462cEric AnholtGLboolean
6423f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholtir_to_mesa_visitor::try_emit_mad(ir_expression *ir, int mul_operand)
6433f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt{
6443f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   int nonmul_operand = 1 - mul_operand;
6453f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_to_mesa_src_reg a, b, c;
6463f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6473f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_expression *expr = ir->operands[mul_operand]->as_expression();
6483f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   if (!expr || expr->operation != ir_binop_mul)
6493f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      return false;
6503f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6513f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   expr->operands[0]->accept(this);
6523f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   a = this->result;
6533f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   expr->operands[1]->accept(this);
6543f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   b = this->result;
6553f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir->operands[nonmul_operand]->accept(this);
6563f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   c = this->result;
6573f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6583f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   this->result = get_temp(ir->type);
6593f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   ir_to_mesa_emit_op3(ir, OPCODE_MAD,
6603f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt		       ir_to_mesa_dst_reg_from_src(this->result), a, b, c);
6613f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
6623f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   return true;
6633f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt}
6643f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
66584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
666f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtir_to_mesa_visitor::reladdr_to_temp(ir_instruction *ir,
667f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt				    ir_to_mesa_src_reg *reg, int *num_reladdr)
668f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt{
669f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (!reg->reladdr)
670f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      return;
671f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
672f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   ir_to_mesa_emit_op1(ir, OPCODE_ARL, ir_to_mesa_address_reg, *reg->reladdr);
673f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
674f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   if (*num_reladdr != 1) {
675f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_src_reg temp = get_temp(glsl_type::vec4_type);
676f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
677f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV,
678f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt			  ir_to_mesa_dst_reg_from_src(temp), *reg);
679f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      *reg = temp;
680f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   }
681f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
682f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   (*num_reladdr)--;
683f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt}
684f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
685f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholtvoid
68684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_expression *ir)
68784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
68884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   unsigned int operand;
689f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt   struct ir_to_mesa_src_reg op[2];
6900161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg result_src;
6910161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg result_dst;
69284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
69384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
69484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
69584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
6963f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   /* Quick peephole: Emit OPCODE_MAD(a, b, c) instead of ADD(MUL(a, b), c)
6973f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt    */
6983f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   if (ir->operation == ir_binop_add) {
6993f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      if (try_emit_mad(ir, 1))
7003f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt	 return;
7013f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt      if (try_emit_mad(ir, 0))
7023f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt	 return;
7033f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt   }
7043f08989267d9cdd944787fcf7a300c6f1f84462cEric Anholt
70584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (operand = 0; operand < ir->get_num_operands(); operand++) {
7060161515c395c44233529c8d51f823b60050bc7baEric Anholt      this->result.file = PROGRAM_UNDEFINED;
70784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir->operands[operand]->accept(this);
7080161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (this->result.file == PROGRAM_UNDEFINED) {
70984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir_print_visitor v;
71084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 printf("Failed to get tree for expression operand:\n");
71184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 ir->operands[operand]->accept(&v);
71284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 exit(1);
71384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
71484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      op[operand] = this->result;
7158364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
7164ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      /* Matrix expression operands should have been broken down to vector
7174ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt       * operations already.
7184ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt       */
7194ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      assert(!ir->operands[operand]->type->is_matrix());
72084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
72184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
7220161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.file = PROGRAM_UNDEFINED;
7230161515c395c44233529c8d51f823b60050bc7baEric Anholt
7240161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
7250161515c395c44233529c8d51f823b60050bc7baEric Anholt    * the actual storage for the result here, instead.
7260161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
7278364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   result_src = get_temp(ir->type);
7280161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* convenience for the emit functions below. */
7290161515c395c44233529c8d51f823b60050bc7baEric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
7309cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   /* Limit writes to the channels that will be used by result_src later.
7319cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * This does limit this temp's use as a temporary for multi-instruction
7329cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    * sequences.
7339cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt    */
7349cd8cad9f3dc4774366193acbfc5ab22198096e7Eric Anholt   result_dst.writemask = (1 << ir->type->vector_elements) - 1;
73584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
73684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   switch (ir->operation) {
7371d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_logic_not:
738f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst,
739f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt			  op[0], src_reg_for_float(0.0));
7401d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
741c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt   case ir_unop_neg:
7420161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
7430161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
744c45b615a379e5b9cbcf951f9d738a1be77a5964bEric Anholt      break;
745524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt   case ir_unop_abs:
746524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_ABS, result_dst, op[0]);
747524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt      break;
7483acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt   case ir_unop_sign:
7493acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_SSG, result_dst, op[0]);
7503acd92a91f3e799b9f839a074f4d76a0e88d71feEric Anholt      break;
7518761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt   case ir_unop_rcp:
7528761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, op[0]);
7538761fcc2bf964d26c70229c712ce446dbe504ab7Eric Anholt      break;
754524745bc55dd23c612aebdb545125727bfb16e4dEric Anholt
7558c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp:
756b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst,
757b0ac07e3de8d9609fb0b1b7ec85b4149c4ee2c70Eric Anholt				 src_reg_for_float(M_E), op[0]);
7588c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7598c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_exp2:
7600161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_EX2, result_dst, op[0]);
7618c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7628c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log:
7630161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LOG, result_dst, op[0]);
7648c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7658c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt   case ir_unop_log2:
7660161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_LG2, result_dst, op[0]);
7678c29a1d84d738cfddf16d5f013876ee2cca96a81Eric Anholt      break;
7683c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_sin:
7690161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_SIN, result_dst, op[0]);
7703c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
7713c5979565facebc82000a611b991d2977b8e9bbfEric Anholt   case ir_unop_cos:
7720161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_COS, result_dst, op[0]);
7733c5979565facebc82000a611b991d2977b8e9bbfEric Anholt      break;
774ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt
775ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt   case ir_unop_dFdx:
776ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_DDX, result_dst, op[0]);
777ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      break;
778ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt   case ir_unop_dFdy:
779ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_DDY, result_dst, op[0]);
780ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt      break;
781ba9bd708cb3480817e18cc47e57d83a4e4c305bbEric Anholt
78284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_add:
7837b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD, result_dst, op[0], op[1]);
78484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
78584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_sub:
7867b48843ecd6690902e4f3bd709a041133b7fb540Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SUB, result_dst, op[0], op[1]);
78784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
7889b68b88e43c424439d425534ef280ee7a9406a1bEric Anholt
78984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_mul:
7904ca07882afad656bf0a0f56b68038ce556bceec4Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL, result_dst, op[0], op[1]);
79184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
79284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_div:
7939a0e421983edc31371440c08687fa2bb2207924dEric Anholt      assert(!"not reached: should be handled by ir_div_to_mul_rcp");
794411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt   case ir_binop_mod:
795411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt      assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
796411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt      break;
79738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
79838315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_less:
799f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLT, result_dst, op[0], op[1]);
80038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
80138315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_greater:
802f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGT, result_dst, op[0], op[1]);
80338315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
80438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_lequal:
805f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SLE, result_dst, op[0], op[1]);
80638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
80738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_gequal:
808f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SGE, result_dst, op[0], op[1]);
80938315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
81038315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_equal:
811f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SEQ, result_dst, op[0], op[1]);
81238315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
813763cd75863ed9a16912e585887580c44d1e8109fEric Anholt   case ir_binop_logic_xor:
81438315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt   case ir_binop_nequal:
815f4bd7f262e43301158f059af90176a476ffdbf60Eric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst, op[0], op[1]);
81638315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt      break;
81738315079571512dc5b502d9522d7a8c3eaf2cc8fEric Anholt
8184380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_or:
8190161515c395c44233529c8d51f823b60050bc7baEric Anholt      /* This could be a saturated add and skip the SNE. */
8200161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_ADD,
8210161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
8220161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
8230161515c395c44233529c8d51f823b60050bc7baEric Anholt
8240161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE,
8250161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
8260161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
8274380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
8284380099c98119611ceee684669d00be26195c7d7Eric Anholt
8294380099c98119611ceee684669d00be26195c7d7Eric Anholt   case ir_binop_logic_and:
8304380099c98119611ceee684669d00be26195c7d7Eric Anholt      /* the bool args are stored as float 0.0 or 1.0, so "mul" gives us "and". */
8310161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MUL,
8320161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_dst,
8330161515c395c44233529c8d51f823b60050bc7baEric Anholt			  op[0], op[1]);
8344380099c98119611ceee684669d00be26195c7d7Eric Anholt      break;
8354380099c98119611ceee684669d00be26195c7d7Eric Anholt
83684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_binop_dot:
83784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (ir->operands[0]->type == vec4_type) {
83884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec4_type);
8390161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP4,
8400161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8410161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
84284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec3_type) {
84384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec3_type);
8440161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP3,
8450161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8460161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
84784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else if (ir->operands[0]->type == vec2_type) {
84884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 assert(ir->operands[1]->type == vec2_type);
8490161515c395c44233529c8d51f823b60050bc7baEric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_DP2,
8500161515c395c44233529c8d51f823b60050bc7baEric Anholt			     result_dst,
8510161515c395c44233529c8d51f823b60050bc7baEric Anholt			     op[0], op[1]);
85284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
85384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
8549be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt
8559be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt   case ir_binop_cross:
8569be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_XPD, result_dst, op[0], op[1]);
8579be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt      break;
8589be7f638130f46a9df2bfbcd4a03b36de9e4f3aaEric Anholt
85984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   case ir_unop_sqrt:
8600161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
8618f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RCP, result_dst, result_src);
8628f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      /* For incoming channels < 0, set the result to 0. */
8638f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt      ir_to_mesa_emit_op3(ir, OPCODE_CMP, result_dst,
8648f62ad6d0ff3c11808739c74441f82f6f12485d6Eric Anholt			  op[0], src_reg_for_float(0.0), result_src);
86584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      break;
866878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt   case ir_unop_rsq:
8670161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_scalar_op1(ir, OPCODE_RSQ, result_dst, op[0]);
868878740bedf418e5bf42ed6d350c938d29abaaf25Eric Anholt      break;
86950ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt   case ir_unop_i2f:
870d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt   case ir_unop_b2f:
871d6ebe9b16b25f25ba763baf3738addc50676d5d0Eric Anholt   case ir_unop_b2i:
872423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      /* Mesa IR lacks types, ints are stored as truncated floats. */
8730161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src = op[0];
87450ad96ebce6ea19b414a02d2d45f0b0c73586abfEric Anholt      break;
875423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt   case ir_unop_f2i:
8760161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
877423a75c5d607a33cb5fe76a0a9c903cccc645fa7Eric Anholt      break;
8781d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt   case ir_unop_f2b:
879411fb36b7cee223e090b4b9ef9bc14e058201a68Eric Anholt   case ir_unop_i2b:
8800161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_SNE, result_dst,
8810161515c395c44233529c8d51f823b60050bc7baEric Anholt			  result_src, src_reg_for_float(0.0));
8821d20862c8a0e100e43458f01217c047c76da05f3Eric Anholt      break;
883c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_trunc:
8840161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_TRUNC, result_dst, op[0]);
885c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
886c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_ceil:
8870161515c395c44233529c8d51f823b60050bc7baEric Anholt      op[0].negate = ~op[0].negate;
8880161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
8890161515c395c44233529c8d51f823b60050bc7baEric Anholt      result_src.negate = ~result_src.negate;
890c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
891c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt   case ir_unop_floor:
8920161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FLR, result_dst, op[0]);
893c2014f03e8d6b7e21e2d0c31270ced04e1025653Eric Anholt      break;
894d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt   case ir_unop_fract:
895d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_FRC, result_dst, op[0]);
896d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt      break;
897d925c9173009e9e5d48df30b30aaef22753183aaEric Anholt
898c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_min:
8990161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MIN, result_dst, op[0], op[1]);
900c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
901c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt   case ir_binop_max:
9020161515c395c44233529c8d51f823b60050bc7baEric Anholt      ir_to_mesa_emit_op2(ir, OPCODE_MAX, result_dst, op[0], op[1]);
903c23c6c773a5c79b458e52ff42bd9f431c87d4036Eric Anholt      break;
904904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt   case ir_binop_pow:
905904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      ir_to_mesa_emit_scalar_op2(ir, OPCODE_POW, result_dst, op[0], op[1]);
906904b5bfe9986a297dc71fe081ce0f2661d43b00bEric Anholt      break;
907e64a4aaacbc682f24180dff3627b84861844476dEric Anholt
908e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_unop_bit_not:
909e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_unop_u2f:
910e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_lshift:
911e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_rshift:
912e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_and:
913e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_xor:
914e64a4aaacbc682f24180dff3627b84861844476dEric Anholt   case ir_binop_bit_or:
915e64a4aaacbc682f24180dff3627b84861844476dEric Anholt      assert(!"GLSL 1.30 features unsupported");
916e64a4aaacbc682f24180dff3627b84861844476dEric Anholt      break;
91784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
918b2ed4dd7b0270e469302965269007292117d02e2Eric Anholt
9190161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = result_src;
92084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
92184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
92284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
92384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
92484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_swizzle *ir)
92584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
9260161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
92784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int i;
92884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int swizzle[4];
92984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
930b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt   /* Note that this is only swizzles in expressions, not those on the left
931b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * hand side of an assignment, which do write masking.  See ir_assignment
932b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    * for that.
933b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt    */
93484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
93584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->val->accept(this);
9364006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   src_reg = this->result;
9374006424f5b5b3b189209faf03f2335f45c22b148Eric Anholt   assert(src_reg.file != PROGRAM_UNDEFINED);
93884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
93984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   for (i = 0; i < 4; i++) {
94084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      if (i < ir->type->vector_elements) {
94184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 switch (i) {
94284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 0:
943698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.x);
94484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
94584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 1:
946698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.y);
94784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
94884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 2:
949698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.z);
95084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
95184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 case 3:
952698b84444343189357ad252856d3c5493e47e4faEric Anholt	    swizzle[i] = GET_SWZ(src_reg.swizzle, ir->mask.w);
95384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	    break;
95484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 }
95584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      } else {
95684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	 /* If the type is smaller than a vec4, replicate the last
95784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  * channel out.
95884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt	  */
959698b84444343189357ad252856d3c5493e47e4faEric Anholt	 swizzle[i] = swizzle[ir->type->vector_elements - 1];
96084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
96184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
96284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9630161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
9640161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[1],
9650161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[2],
9660161515c395c44233529c8d51f823b60050bc7baEric Anholt				   swizzle[3]);
96784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
9680161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
96984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
97084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
971dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtstatic const struct {
972dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   const char *name;
973dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   const char *field;
974dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   int tokens[STATE_LENGTH];
975dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   int swizzle;
976dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   bool array_indexed;
977dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt} statevars[] = {
978dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_DepthRange", "near",
979dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX},
980dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_DepthRange", "far",
981dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY},
982dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_DepthRange", "diff",
983dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ},
984dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
985dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_ClipPlane", NULL,
986dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW, true}
987dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt,
988dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "size",
989dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_POINT_SIZE}, SWIZZLE_XXXX},
990dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "sizeMin",
991dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_POINT_SIZE}, SWIZZLE_YYYY},
992dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "sizeMax",
993dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_POINT_SIZE}, SWIZZLE_ZZZZ},
994dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "fadeThresholdSize",
995dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_POINT_SIZE}, SWIZZLE_WWWW},
996dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "distanceConstantAttenuation",
997dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX},
998dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "distanceLinearAttenuation",
999dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY},
1000dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Point", "distanceQuadraticAttenuation",
1001dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ},
1002dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1003dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontMaterial", "emission",
1004dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW},
1005dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontMaterial", "ambient",
1006dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
1007dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontMaterial", "diffuse",
1008dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
1009dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontMaterial", "specular",
1010dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
1011dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontMaterial", "shininess",
1012dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX},
1013dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1014dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackMaterial", "emission",
1015dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW},
1016dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackMaterial", "ambient",
1017dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
1018dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackMaterial", "diffuse",
1019dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
1020dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackMaterial", "specular",
1021dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
1022dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackMaterial", "shininess",
1023dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX},
1024dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1025dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "ambient",
1026dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true},
1027dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "diffuse",
1028dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
1029dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "specular",
1030dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true},
1031dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "position",
1032dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW, true},
1033dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "halfVector",
1034dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW, true},
1035dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "spotDirection",
1036dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_XYZW, true},
1037dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "spotCosCutoff",
1038dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW, true},
1039dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "spotCutoff",
1040dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX, true},
1041dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "spotExponent",
1042dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW, true},
1043dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "constantAttenuation",
1044dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX, true},
1045dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "linearAttenuation",
1046dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY, true},
1047dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightSource", "quadraticAttenuation",
1048dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ, true},
1049dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1050dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_LightModel", NULL,
1051dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW},
1052dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1053dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontLightModelProduct", NULL,
1054dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW},
1055dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackLightModelProduct", NULL,
1056dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW},
1057dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1058dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontLightProduct", "ambient",
1059dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true},
1060dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontLightProduct", "diffuse",
1061dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
1062dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_FrontLightProduct", "specular",
1063dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true},
1064dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1065dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackLightProduct", "ambient",
1066dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW, true},
1067dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackLightProduct", "diffuse",
1068dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
1069dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_BackLightProduct", "specular",
1070dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW, true},
1071dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1072dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_TextureEnvColor", "ambient",
1073dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW, true},
1074dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1075dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_EyePlaneS", NULL,
1076dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW, true},
1077dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_EyePlaneT", NULL,
1078dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW, true},
1079dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_EyePlaneR", NULL,
1080dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW, true},
1081dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_EyePlaneQ", NULL,
1082dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW, true},
1083dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1084dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_ObjectPlaneS", NULL,
1085dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW, true},
1086dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_ObjectPlaneT", NULL,
1087dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW, true},
1088dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_ObjectPlaneR", NULL,
1089dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW, true},
1090dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_ObjectPlaneQ", NULL,
1091dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW, true},
1092dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1093dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Fog", "color",
1094dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_FOG_COLOR}, SWIZZLE_XYZW},
1095dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Fog", "density",
1096dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_FOG_PARAMS}, SWIZZLE_XXXX},
1097dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Fog", "start",
1098dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_FOG_PARAMS}, SWIZZLE_YYYY},
1099dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Fog", "end",
1100dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ},
1101dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   {"gl_Fog", "scale",
1102dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt    {STATE_FOG_PARAMS}, SWIZZLE_WWWW},
1103dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt};
1104dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1105dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtstatic ir_to_mesa_src_reg
1106dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholtget_builtin_uniform_reg(struct gl_program *prog,
1107dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt			const char *name, int array_index, const char *field)
1108dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt{
1109dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   unsigned int i;
1110dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   ir_to_mesa_src_reg src_reg;
1111dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   int tokens[STATE_LENGTH];
1112dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1113dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   for (i = 0; i < Elements(statevars); i++) {
1114dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      if (strcmp(statevars[i].name, name) != 0)
1115dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	 continue;
1116dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      if (!field && statevars[i].field) {
1117dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	 assert(!"FINISHME: whole-structure state var dereference");
1118dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      }
1119dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      if (field && strcmp(statevars[i].field, field) != 0)
1120dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	 continue;
1121dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      break;
1122dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   }
1123dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1124dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   if (i ==  Elements(statevars)) {
1125dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      printf("builtin uniform %s%s%s not found\n",
1126dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	     name,
1127dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	     field ? "." : "",
1128dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	     field ? field : "");
1129dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      abort();
1130dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   }
1131dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1132dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   memcpy(&tokens, statevars[i].tokens, sizeof(tokens));
1133dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   if (statevars[i].array_indexed)
1134dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      tokens[1] = array_index;
1135dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1136dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   src_reg.file = PROGRAM_STATE_VAR;
1137dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   src_reg.index = _mesa_add_state_reference(prog->Parameters,
1138dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     (gl_state_index *)tokens);
1139dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   src_reg.swizzle = statevars[i].swizzle;
1140dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   src_reg.negate = 0;
1141dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   src_reg.reladdr = false;
1142dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1143dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   return src_reg;
1144dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt}
1145dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
114676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtstatic int
114776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtadd_matrix_ref(struct gl_program *prog, int *tokens)
114876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt{
114976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   int base_pos = -1;
115076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   int i;
115176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
115276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   /* Add a ref for each column.  It looks like the reason we do
115376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * it this way is that _mesa_add_state_reference doesn't work
115476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * for things that aren't vec4s, so the tokens[2]/tokens[3]
115576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    * range has to be equal.
115676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt    */
115776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   for (i = 0; i < 4; i++) {
115876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      tokens[2] = i;
115976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      tokens[3] = i;
116076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      int pos = _mesa_add_state_reference(prog->Parameters,
116176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt					  (gl_state_index *)tokens);
116276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      if (base_pos == -1)
116376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 base_pos = pos;
116476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      else
116576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 assert(base_pos + i == pos);
116676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   }
116776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
116876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   return base_pos;
116976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt}
117076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
1171b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholtstatic variable_storage *
117276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholtget_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
117376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		       ir_rvalue *array_index)
1174bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt{
1175bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   /*
1176bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * NOTE: The ARB_vertex_program extension specified that matrices get
1177bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * loaded in registers in row-major order.  With GLSL, we want column-
1178bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * major order.  So, we need to transpose all matrices here...
1179bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    */
1180bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   static const struct {
1181bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      const char *name;
1182bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      int matrix;
1183bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      int modifier;
1184bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   } matrices[] = {
1185bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
1186bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
1187bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
1188bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
1189bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1190bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
1191bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
1192bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
1193bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
1194bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1195bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
1196bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
1197bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
1198bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
1199bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1200bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
1201bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
1202bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
1203bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
1204bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1205bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
1206bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1207bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   };
1208bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   unsigned int i;
1209b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry;
1210bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1211bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   /* C++ gets angry when we try to use an int as a gl_state_index, so we use
1212bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    * ints for gl_state_index.  Make sure they're compatible.
1213bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt    */
1214bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   assert(sizeof(gl_state_index) == sizeof(int));
1215bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1216bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   for (i = 0; i < Elements(matrices); i++) {
1217bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      if (strcmp(var->name, matrices[i].name) == 0) {
1218bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 int tokens[STATE_LENGTH];
121976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 int base_pos = -1;
1220bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1221bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[0] = matrices[i].matrix;
1222bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 tokens[4] = matrices[i].modifier;
122376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 if (matrices[i].matrix == STATE_TEXTURE_MATRIX) {
122476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    ir_constant *index = array_index->constant_expression_value();
122576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    if (index) {
122676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       tokens[1] = index->value.i[0];
122776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       base_pos = add_matrix_ref(prog, tokens);
122876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    } else {
122976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       for (i = 0; i < var->type->length; i++) {
123076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  tokens[1] = i;
123176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  int pos = add_matrix_ref(prog, tokens);
123276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  if (base_pos == -1)
123376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		     base_pos = pos;
123476101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		  else
123576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt		     assert(base_pos + (int)i * 4 == pos);
123676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	       }
123776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    }
123876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 } else {
123976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    tokens[1] = 0; /* unused array index */
124076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	    base_pos = add_matrix_ref(prog, tokens);
1241bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 }
124276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 tokens[4] = matrices[i].modifier;
1243bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1244b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(var,
1245b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       PROGRAM_STATE_VAR,
1246b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       base_pos);
1247bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1248bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 return entry;
1249bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt      }
1250bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   }
1251bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
1252bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt   return NULL;
1253bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt}
1254bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
125547f305a4fcd23f859d097c6cc25a739547462939Eric Anholtint
125647f305a4fcd23f859d097c6cc25a739547462939Eric Anholtir_to_mesa_visitor::add_uniform(const char *name,
125747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt				const glsl_type *type,
125847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt				ir_constant *constant)
125947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt{
126047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   int len;
126147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
126247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   if (type->is_vector() ||
126347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt       type->is_scalar()) {
126447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      len = type->vector_elements;
126547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   } else {
126647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      len = type_size(type) * 4;
126747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   }
126847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
126947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   float *values = NULL;
127047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   if (constant && type->is_array()) {
127147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      values = (float *)malloc(type->length * 4 * sizeof(float));
127247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
127347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      assert(type->fields.array->is_scalar() ||
127447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	     type->fields.array->is_vector() ||
127547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	     !"FINISHME: uniform array initializers for non-vector");
127647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
127747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      for (unsigned int i = 0; i < type->length; i++) {
127847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 ir_constant *element = constant->array_elements[i];
127947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 unsigned int c;
128047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
128147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 for (c = 0; c < type->fields.array->vector_elements; c++) {
128247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    switch (type->fields.array->base_type) {
128347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    case GLSL_TYPE_FLOAT:
128447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	       values[4 * i + c] = element->value.f[c];
128547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	       break;
128647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    case GLSL_TYPE_INT:
128747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	       values[4 * i + c] = element->value.i[c];
128847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	       break;
128947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    case GLSL_TYPE_UINT:
129047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	       values[4 * i + c] = element->value.u[c];
129147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	       break;
129247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    case GLSL_TYPE_BOOL:
129347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	       values[4 * i + c] = element->value.b[c];
129447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	       break;
129547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    default:
129647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	       assert(!"not reached");
129747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    }
129847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 }
129947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      }
130047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   } else if (constant) {
130147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      values = (float *)malloc(16 * sizeof(float));
130247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      for (unsigned int i = 0; i < type->components(); i++) {
130347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 switch (type->base_type) {
130447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 case GLSL_TYPE_FLOAT:
130547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    values[i] = constant->value.f[i];
130647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    break;
130747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 case GLSL_TYPE_INT:
130847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    values[i] = constant->value.i[i];
130947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    break;
131047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 case GLSL_TYPE_UINT:
131147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    values[i] = constant->value.u[i];
131247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    break;
131347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 case GLSL_TYPE_BOOL:
131447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    values[i] = constant->value.b[i];
131547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    break;
131647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 default:
131747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    assert(!"not reached");
131847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 }
131947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      }
132047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   }
132147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
132247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   int loc = _mesa_add_uniform(this->prog->Parameters,
132347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt			       name,
132447f305a4fcd23f859d097c6cc25a739547462939Eric Anholt			       len,
132547f305a4fcd23f859d097c6cc25a739547462939Eric Anholt			       type->gl_type,
132647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt			       values);
132747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   free(values);
132847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
132947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   return loc;
133047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt}
133147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
133226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt/* Recursively add all the members of the aggregate uniform as uniform names
133326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt * to Mesa, moving those uniforms to our structured temporary.
133426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt */
133526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholtvoid
133626675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholtir_to_mesa_visitor::add_aggregate_uniform(ir_instruction *ir,
133726675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt					  const char *name,
133826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt					  const struct glsl_type *type,
133947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt					  ir_constant *constant,
134026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt					  struct ir_to_mesa_dst_reg temp)
134126675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt{
134226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt   int loc;
134326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
134426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt   if (type->is_record()) {
134526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt      void *mem_ctx = talloc_new(NULL);
134647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      ir_constant *field_constant = NULL;
134747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
134847f305a4fcd23f859d097c6cc25a739547462939Eric Anholt      if (constant)
134947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 field_constant = (ir_constant *)constant->components.get_head();
135026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
135126675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt      for (unsigned int i = 0; i < type->length; i++) {
135226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	 const glsl_type *field_type = type->fields.structure[i].type;
135347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
135426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	 add_aggregate_uniform(ir,
135526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt			       talloc_asprintf(mem_ctx, "%s.%s", name,
135626675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt					       type->fields.structure[i].name),
135747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt			       field_type, field_constant, temp);
135826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	 temp.index += type_size(field_type);
135947f305a4fcd23f859d097c6cc25a739547462939Eric Anholt
136047f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 if (constant)
136147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	    field_constant = (ir_constant *)field_constant->next;
136226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt      }
136326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
136426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt      talloc_free(mem_ctx);
136526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
136626675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt      return;
136726675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt   }
136826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
136926675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt   assert(type->is_vector() || type->is_scalar() || !"FINISHME: other types");
137026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
137147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt   loc = add_uniform(name, type, constant);
137226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
137326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt   ir_to_mesa_src_reg uniform(PROGRAM_UNIFORM, loc, type);
137426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
137526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt   for (int i = 0; i < type_size(type); i++) {
137626675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, uniform);
137726675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt      temp.index++;
137826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt      uniform.index++;
137926675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt   }
138026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt}
138126675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
138226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
138384771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
138484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_variable *ir)
138584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1386b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt   variable_storage *entry = find_variable_storage(ir->var);
1387a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt   unsigned int loc;
138884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
13898364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt   if (!entry) {
13908364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      switch (ir->var->mode) {
13918364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_uniform:
139276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var,
139376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt					NULL);
1394bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	 if (entry)
1395bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt	    break;
1396bd3b835e7c32e093f91f636330fd93b3dedd8362Eric Anholt
139785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 /* FINISHME: Fix up uniform name for arrays and things */
1398d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) {
1399d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    int sampler = _mesa_add_sampler(this->prog->Parameters,
1400d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					    ir->var->name,
1401d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt					    ir->var->type->gl_type);
1402fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt	    set_sampler_location(ir->var, sampler);
1403d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1404b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_SAMPLER,
1405b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  sampler);
1406b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    this->variables.push_tail(entry);
1407d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    break;
1408d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 }
1409d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
141085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 assert(ir->var->type->gl_type != 0 &&
141185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt		ir->var->type->gl_type != GL_INVALID_ENUM);
14129a670c2e9b7e07ba43d175f3bfb23951296794c4Eric Anholt
141326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	 /* Oh, the joy of aggregate types in Mesa.  Like constants,
141426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	  * we can only really do vec4s.  So, make a temp, chop the
141526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	  * aggregate up into vec4s, and move those vec4s to the temp.
141626675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	  */
141726675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	 if (ir->var->type->is_record()) {
141826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	    ir_to_mesa_src_reg temp = get_temp(ir->var->type);
141926675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
142026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	    entry = new(mem_ctx) variable_storage(ir->var,
142126675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt						  temp.file,
142226675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt						  temp.index);
142326675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	    this->variables.push_tail(entry);
142426675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
142526675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	    add_aggregate_uniform(ir->var, ir->var->name, ir->var->type,
142647f305a4fcd23f859d097c6cc25a739547462939Eric Anholt				  ir->var->constant_value,
142747f305a4fcd23f859d097c6cc25a739547462939Eric Anholt				  ir_to_mesa_dst_reg_from_src(temp));
142826675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	    break;
142926675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt	 }
143026675e37bc5a086c6df77946d2dada34dc9129f0Eric Anholt
143147f305a4fcd23f859d097c6cc25a739547462939Eric Anholt	 loc = add_uniform(ir->var->name,
143247f305a4fcd23f859d097c6cc25a739547462939Eric Anholt			   ir->var->type,
143347f305a4fcd23f859d097c6cc25a739547462939Eric Anholt			   ir->var->constant_value);
1434d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
143585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 /* Always mark the uniform used at this point.  If it isn't
143685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	  * used, dead code elimination should have nuked the decl already.
143785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	  */
143885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 this->prog->Parameters->Parameters[loc].Used = GL_TRUE;
1439224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
1440b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM, loc);
1441b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 this->variables.push_tail(entry);
14428364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
14438364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_in:
14448364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_out:
14458364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_inout:
1446a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	 /* The linker assigns locations for varyings and attributes,
1447a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * including deprecated builtins (like gl_Color), user-assign
1448a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * generic attributes (glBindVertexLocation), and
1449a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * user-defined varyings.
1450a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  *
1451a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	  * FINISHME: We would hit this path for function arguments.  Fix!
1452f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	  */
1453f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 assert(ir->var->location != -1);
1454a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	 if (ir->var->mode == ir_var_in ||
1455a0b3b9302978ab6d4db62f0c9b2b313ebc7ed0b4Eric Anholt	     ir->var->mode == ir_var_inout) {
1456b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var,
1457b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  PROGRAM_INPUT,
1458b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  ir->var->location);
1459edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt
1460edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	    if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
1461edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt		ir->var->location >= VERT_ATTRIB_GENERIC0) {
1462edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	       _mesa_add_attribute(prog->Attributes,
1463edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   ir->var->name,
1464edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   type_size(ir->var->type) * 4,
1465edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt				   ir->var->type->gl_type,
1466c64da87611823b4b53e93188f861f748a69936a3Eric Anholt				   ir->var->location - VERT_ATTRIB_GENERIC0);
1467edcb9c2b062693a5974aa74725f6259023fff794Eric Anholt	    }
1468f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 } else {
1469b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	    entry = new(mem_ctx) variable_storage(ir->var,
1470b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  PROGRAM_OUTPUT,
1471b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt						  ir->var->location);
1472f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt	 }
1473f9ffccb06bcc90c862f20f8849b824022fbeebbfEric Anholt
14748364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
14758364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      case ir_var_auto:
14767e2aa91507a5883e33473e0a94215ee3985baad1Ian Romanick      case ir_var_temporary:
1477b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_TEMPORARY,
1478b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					       this->next_temp);
1479b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 this->variables.push_tail(entry);
1480224f712950494730c76b48864f2ca19acde1c8cfEric Anholt
14818364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 next_temp += type_size(ir->var->type);
14828364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 break;
148384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      }
14848364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt
14858364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt      if (!entry) {
14868364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 printf("Failed to make storage for %s\n", ir->var->name);
14878364fc85b8273b4d0f2ecebe7e0085e250d29990Eric Anholt	 exit(1);
1488224f712950494730c76b48864f2ca19acde1c8cfEric Anholt      }
148984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
149084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
14919c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   this->result = ir_to_mesa_src_reg(entry->file, entry->index, ir->var->type);
149284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
149384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
149484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
149584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_dereference_array *ir)
149684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
1497dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   ir_variable *var = ir->variable_referenced();
1498ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir_constant *index;
14990161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
150076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   ir_dereference_variable *deref_var = ir->array->as_dereference_variable();
15018258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt   int element_size = type_size(ir->type);
1502ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt
1503ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   index = ir->array_index->constant_expression_value();
15044e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
150576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   if (deref_var && strncmp(deref_var->var->name,
150676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			    "gl_TextureMatrix",
150776101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			    strlen("gl_TextureMatrix")) == 0) {
1508b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      struct variable_storage *entry;
150976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
151076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var,
151176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt				     ir->array_index);
151276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      assert(entry);
151376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
15149c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt      ir_to_mesa_src_reg src_reg(entry->file, entry->index, ir->type);
151576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
151676101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      if (index) {
1517f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 src_reg.reladdr = NULL;
151876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      } else {
151976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type);
152076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
152176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir->array_index->accept(this);
152276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
152376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt			     ir_to_mesa_dst_reg_from_src(index_reg),
15248258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt			     this->result, src_reg_for_float(element_size));
152576101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
1526f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
1527f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt	 memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
152876101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      }
152976101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
153076101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      this->result = src_reg;
153176101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt      return;
153276101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt   }
153376101f7c0468c7f346b1a8d6b824fc8914a17bd1Eric Anholt
1534dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   if (strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform &&
1535dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt       !var->type->is_matrix()) {
1536dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      ir_dereference_record *record = NULL;
1537dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      if (ir->array->ir_type == ir_type_dereference_record)
1538dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt	 record = (ir_dereference_record *)ir->array;
1539dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1540dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      assert(index || !"FINISHME: variable-indexed builtin uniform access");
1541dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1542dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      this->result = get_builtin_uniform_reg(prog,
1543dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     var->name,
1544dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     index->value.i[0],
1545dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     record ? record->field : NULL);
1546dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   }
1547dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1548ab386f18b045fe260112bd9a239cb503e737c1dbEric Anholt   ir->array->accept(this);
15490161515c395c44233529c8d51f823b60050bc7baEric Anholt   src_reg = this->result;
15504e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt
15514d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   if (index) {
15524d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      src_reg.index += index->value.i[0] * element_size;
15534e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   } else {
15544d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir_to_mesa_src_reg array_base = this->result;
15554d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      /* Variable index array dereference.  It eats the "vec4" of the
15564d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       * base of the array and an index that offsets the Mesa register
15574d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       * index.
15584d5da50b94115d055ba8d0ff8717054582665384Eric Anholt       */
15594d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir->array_index->accept(this);
15608258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt
15614d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      ir_to_mesa_src_reg index_reg;
15628258a6a2c36c9769428f4525415d6c0d565e588cEric Anholt
15634d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      if (element_size == 1) {
15644d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 index_reg = this->result;
15654d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      } else {
15664d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 index_reg = get_temp(glsl_type::float_type);
1567f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt
15684d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL,
15694d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			     ir_to_mesa_dst_reg_from_src(index_reg),
15704d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			     this->result, src_reg_for_float(element_size));
1571bdbd9f112e2832eeddce8fc4f70f11005bbe4027Eric Anholt      }
15724d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
15734d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
15744d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
15754e5e0f018baedb2d0aa0e1f43efe339da16a09c6Eric Anholt   }
157684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
157784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   /* If the type is smaller than a vec4, replicate the last channel out. */
157885e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   if (ir->type->is_scalar() || ir->type->is_vector())
157985e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = swizzle_for_size(ir->type->vector_elements);
158085e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   else
158185e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt      src_reg.swizzle = SWIZZLE_NOOP;
158284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
15830161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result = src_reg;
158484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
158584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
15862c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtvoid
15872c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholtir_to_mesa_visitor::visit(ir_dereference_record *ir)
15882c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt{
15892c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   unsigned int i;
15900161515c395c44233529c8d51f823b60050bc7baEric Anholt   const glsl_type *struct_type = ir->record->type;
15912c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   int offset = 0;
1592dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   ir_variable *var = ir->record->variable_referenced();
1593dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1594dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   if (strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform) {
1595dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      assert(var);
1596dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt
1597dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      this->result = get_builtin_uniform_reg(prog,
1598dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     var->name,
1599dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     0,
1600dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt					     ir->field);
1601dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt      return;
1602dc27e7356952984d023e05fef90d0f8c4bb07a09Eric Anholt   }
16032c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
16040161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir->record->accept(this);
16052c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
16062c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   for (i = 0; i < struct_type->length; i++) {
16070161515c395c44233529c8d51f823b60050bc7baEric Anholt      if (strcmp(struct_type->fields.structure[i].name, ir->field) == 0)
16082c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt	 break;
16092c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt      offset += type_size(struct_type->fields.structure[i].type);
16102c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   }
161185e93da18ca2c967ca12870b62ab1aac2f0b880cEric Anholt   this->result.swizzle = swizzle_for_size(ir->type->vector_elements);
16120161515c395c44233529c8d51f823b60050bc7baEric Anholt   this->result.index += offset;
16132c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt}
16142c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt
16152c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt/**
16162c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * We want to be careful in assignment setup to hit the actual storage
16172c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * instead of potentially using a temporary like we might with the
16182c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt * ir_dereference handler.
16192c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt */
16200161515c395c44233529c8d51f823b60050bc7baEric Anholtstatic struct ir_to_mesa_dst_reg
16215a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanickget_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v,
162218ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt		   ir_to_mesa_src_reg *r)
1623b07cc372c6360d0e59c84bb7586597f028c74b02Eric Anholt{
16245a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   /* The LHS must be a dereference.  If the LHS is a variable indexed array
16255a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    * access of a vector, it must be separated into a series conditional moves
16265a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    * before reaching this point (see ir_vec_index_to_cond_assign).
16275a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    */
16285a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   assert(ir->as_dereference());
1629ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   ir_dereference_array *deref_array = ir->as_dereference_array();
1630ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   if (deref_array) {
1631ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt      assert(!deref_array->array->type->is_vector());
1632ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt   }
1633ea2a03f0a5b8b58ea88ecb607664ea50c9d6e96eEric Anholt
16340161515c395c44233529c8d51f823b60050bc7baEric Anholt   /* Use the rvalue deref handler for the most part.  We'll ignore
16350161515c395c44233529c8d51f823b60050bc7baEric Anholt    * swizzles in it and write swizzles using writemask, though.
16360161515c395c44233529c8d51f823b60050bc7baEric Anholt    */
16372c432637d0960aa522ccd09416ba1d8a65c6988bEric Anholt   ir->accept(v);
16385a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   return ir_to_mesa_dst_reg_from_src(v->result);
1639cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt}
1640cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
164184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
164284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_assignment *ir)
164384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
16440161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_dst_reg l;
16450161515c395c44233529c8d51f823b60050bc7baEric Anholt   struct ir_to_mesa_src_reg r;
16467d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt   int i;
164784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
164884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->rhs->accept(this);
164984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   r = this->result;
1650cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
165118ab797d3aff776833fac1bd0ea01a2750f377b1Eric Anholt   l = get_assignment_lhs(ir->lhs, this, &r);
1652cab95c228b12f0fc568164d57475c561c8d6053eEric Anholt
16535a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   /* FINISHME: This should really set to the correct maximal writemask for each
16545a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    * FINISHME: component written (in the loops below).  This case can only
16555a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    * FINISHME: occur for matrices, arrays, and structures.
16565a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick    */
16575a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   if (ir->write_mask == 0) {
16585a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      assert(!ir->lhs->type->is_scalar() && !ir->lhs->type->is_vector());
16595a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      l.writemask = WRITEMASK_XYZW;
16605a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   } else if (ir->lhs->type->is_scalar()) {
16615a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      /* FINISHME: This hack makes writing to gl_FragData, which lives in the
16625a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick       * FINISHME: W component of fragment shader output zero, work correctly.
16635a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick       */
16645a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      l.writemask = WRITEMASK_XYZW;
16655a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   } else {
16665a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      assert(ir->lhs->type->is_vector());
16675a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick      l.writemask = ir->write_mask;
16685a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick   }
16695a7758efbe14dee026245a4f4f4fb3ccf7b2c23bIan Romanick
16700161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(l.file != PROGRAM_UNDEFINED);
16710161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(r.file != PROGRAM_UNDEFINED);
167284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
1673346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   if (ir->condition) {
16742d1789e667c4180777829f96856daf91326721b9Eric Anholt      ir_to_mesa_src_reg condition;
16752d1789e667c4180777829f96856daf91326721b9Eric Anholt
16762d1789e667c4180777829f96856daf91326721b9Eric Anholt      ir->condition->accept(this);
16772d1789e667c4180777829f96856daf91326721b9Eric Anholt      condition = this->result;
16782d1789e667c4180777829f96856daf91326721b9Eric Anholt
16792d1789e667c4180777829f96856daf91326721b9Eric Anholt      /* We use the OPCODE_CMP (a < 0 ? b : c) for conditional moves,
16802d1789e667c4180777829f96856daf91326721b9Eric Anholt       * and the condition we produced is 0.0 or 1.0.  By flipping the
16812d1789e667c4180777829f96856daf91326721b9Eric Anholt       * sign, we can choose which value OPCODE_CMP produces without
16822d1789e667c4180777829f96856daf91326721b9Eric Anholt       * an extra computing the condition.
16832d1789e667c4180777829f96856daf91326721b9Eric Anholt       */
16842d1789e667c4180777829f96856daf91326721b9Eric Anholt      condition.negate = ~condition.negate;
16857d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      for (i = 0; i < type_size(ir->lhs->type); i++) {
16867d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 ir_to_mesa_emit_op3(ir, OPCODE_CMP, l,
16877d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt			     condition, r, ir_to_mesa_src_reg_from_dst(l));
16887d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 l.index++;
16897d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 r.index++;
16907d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      }
16912d1789e667c4180777829f96856daf91326721b9Eric Anholt   } else {
16927d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      for (i = 0; i < type_size(ir->lhs->type); i++) {
16937d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
16947d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 l.index++;
16957d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt	 r.index++;
16967d8091f7cca0314dd66599bdce5bfcf09fe8b578Eric Anholt      }
1697346daeca07d3c19c051799f96fa9f442262bd49fEric Anholt   }
169884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
169984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
170084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
170184771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
170284771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_constant *ir)
170384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
17040161515c395c44233529c8d51f823b60050bc7baEric Anholt   ir_to_mesa_src_reg src_reg;
17050bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   GLfloat stack_vals[4];
17060bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   GLfloat *values = stack_vals;
17070bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   unsigned int i;
170884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
17095b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt   /* Unfortunately, 4 floats is all we can get into
17105b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    * _mesa_add_unnamed_constant.  So, make a temp to store an
17115b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    * aggregate constant and move each constant value into it.  If we
17125b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    * get lucky, copy propagation will eliminate the extra moves.
17135b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt    */
17145b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
17155b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt   if (ir->type->base_type == GLSL_TYPE_STRUCT) {
17165b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      ir_to_mesa_src_reg temp_base = get_temp(ir->type);
17175b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
17185b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
17195b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      foreach_iter(exec_list_iterator, iter, ir->components) {
17205b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 ir_constant *field_value = (ir_constant *)iter.get();
17215b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 int size = type_size(field_value->type);
17225b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
17235b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 assert(size > 0);
17245b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
17255b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 field_value->accept(this);
17265b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 src_reg = this->result;
17275b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
17285b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 for (i = 0; i < (unsigned int)size; i++) {
17295b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg);
17305b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
17315b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	    src_reg.index++;
17325b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	    temp.index++;
17335b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt	 }
17345b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      }
17355b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      this->result = temp_base;
17365b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt      return;
17375b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt   }
17385b6890a388d554f06880e88d61c73dcd62c5f141Eric Anholt
173920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt   if (ir->type->is_array()) {
174020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      ir_to_mesa_src_reg temp_base = get_temp(ir->type);
174120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      ir_to_mesa_dst_reg temp = ir_to_mesa_dst_reg_from_src(temp_base);
174220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      int size = type_size(ir->type->fields.array);
174320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt
174420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      assert(size > 0);
174520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt
174620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      for (i = 0; i < ir->type->length; i++) {
174720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 ir->array_elements[i]->accept(this);
174820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 src_reg = this->result;
174920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 for (int j = 0; j < size; j++) {
175020c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, temp, src_reg);
175120c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt
175220c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	    src_reg.index++;
175320c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	    temp.index++;
175420c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt	 }
175520c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      }
175620c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      this->result = temp_base;
175720c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt      return;
175820c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt   }
175920c074ae28b310348a6a1920ad0ddf1e5cbb7a46Eric Anholt
1760ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt   if (ir->type->is_matrix()) {
1761c91809e1e4a4fa8884e6588159368ea32431ee0eEric Anholt      ir_to_mesa_src_reg mat = get_temp(ir->type);
1762ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      ir_to_mesa_dst_reg mat_column = ir_to_mesa_dst_reg_from_src(mat);
1763ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1764ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      for (i = 0; i < ir->type->matrix_columns; i++) {
1765ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 assert(ir->type->base_type == GLSL_TYPE_FLOAT);
1766ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 values = &ir->value.f[i * ir->type->vector_elements];
1767ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
17689c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt	 src_reg = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, NULL);
1769ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 src_reg.index = _mesa_add_unnamed_constant(this->prog->Parameters,
17709c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						values,
17719c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						ir->type->vector_elements,
17729c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						&src_reg.swizzle);
1773ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, mat_column, src_reg);
1774ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1775ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt	 mat_column.index++;
1776ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      }
1777ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt
1778ffd24b0a6844871eed0c78608431e2f82d5615e1Eric Anholt      this->result = mat;
1779582b73fe691ef7ea12a002cb2ae57505c3b1c21eEric Anholt   }
17800bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt
17810bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   src_reg.file = PROGRAM_CONSTANT;
17820bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   switch (ir->type->base_type) {
17830bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_FLOAT:
17840bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      values = &ir->value.f[0];
17850bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
17860bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_UINT:
17870bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
17880bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.u[i];
17890bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
17900bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
17910bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_INT:
17920bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
17930bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.i[i];
17940bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
17950bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
17960bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   case GLSL_TYPE_BOOL:
17970bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      for (i = 0; i < ir->type->vector_elements; i++) {
17980bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt	 values[i] = ir->value.b[i];
17990bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      }
18000bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      break;
18010bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   default:
18020bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt      assert(!"Non-float/uint/int/bool constant");
18030bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt   }
18040bef5b97a9eccebc4b59dff42b2863770da770feEric Anholt
18059c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   this->result = ir_to_mesa_src_reg(PROGRAM_CONSTANT, -1, ir->type);
18069c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   this->result.index = _mesa_add_unnamed_constant(this->prog->Parameters,
18079c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						   values,
18089c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						   ir->type->vector_elements,
18099c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt						   &this->result.swizzle);
181084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
181184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
18127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtfunction_entry *
18137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtir_to_mesa_visitor::get_function_signature(ir_function_signature *sig)
18147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt{
18157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *entry;
18167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, this->function_signatures) {
18187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry = (function_entry *)iter.get();
18197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (entry->sig == sig)
18217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 return entry;
18227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
18237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry = talloc(mem_ctx, function_entry);
18257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->sig = sig;
18267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->sig_id = this->next_signature_id++;
18277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   entry->bgn_inst = NULL;
18287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Allocate storage for all the parameters. */
18307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, sig->parameters) {
18317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)iter.get();
1832b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      variable_storage *storage;
18337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18347b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      storage = find_variable_storage(param);
18357b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      assert(!storage);
18367b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1837b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      storage = new(mem_ctx) variable_storage(param, PROGRAM_TEMPORARY,
1838b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt					      this->next_temp);
1839b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt      this->variables.push_tail(storage);
18407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      this->next_temp += type_size(param->type);
18427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
18437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
1844576d01ad8c8b8aa57b4711c98d8e004d4f20fc0bEric Anholt   if (!sig->return_type->is_void()) {
18457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry->return_reg = get_temp(sig->return_type);
18467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   } else {
18477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      entry->return_reg = ir_to_mesa_undef;
18487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
18497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   this->function_signatures.push_tail(entry);
18517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   return entry;
18527b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt}
185384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
185484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
185584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_call *ir)
185684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
18577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_instruction *call_inst;
18587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_function_signature *sig = ir->get_callee();
18597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   function_entry *entry = get_function_signature(sig);
18607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   int i;
18617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process in parameters. */
18637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   exec_list_iterator sig_iter = sig->parameters.iterator();
18647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, *ir) {
18657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
18667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)sig_iter.get();
18677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (param->mode == ir_var_in ||
18697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	  param->mode == ir_var_inout) {
1870b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 variable_storage *storage = find_variable_storage(param);
18717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 assert(storage);
18727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 param_rval->accept(this);
18747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_src_reg r = this->result;
18757b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_dst_reg l;
18777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.file = storage->file;
18787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.index = storage->index;
18797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.reladdr = NULL;
18807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.writemask = WRITEMASK_XYZW;
18817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.cond_mask = COND_TR;
18827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 for (i = 0; i < type_size(param->type); i++) {
18847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
18857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    l.index++;
18867b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    r.index++;
18877b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
18887b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
18897b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18907b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      sig_iter.next();
18917b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
18927b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(!sig_iter.has_next());
18937b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18947b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Emit call instruction */
18957b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   call_inst = ir_to_mesa_emit_op1(ir, OPCODE_CAL,
18967b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt				   ir_to_mesa_undef_dst, ir_to_mesa_undef);
18977b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   call_inst->function = entry;
18987b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
18997b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process out parameters. */
19007b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   sig_iter = sig->parameters.iterator();
19017b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   foreach_iter(exec_list_iterator, iter, *ir) {
19027b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_rvalue *param_rval = (ir_rvalue *)iter.get();
19037b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_variable *param = (ir_variable *)sig_iter.get();
19047b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
19057b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      if (param->mode == ir_var_out ||
19067b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	  param->mode == ir_var_inout) {
1907b29d31cd67a423995b5673fdeedea82dfa12ec3cEric Anholt	 variable_storage *storage = find_variable_storage(param);
19087b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 assert(storage);
19097b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
19107b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_src_reg r;
19117b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.file = storage->file;
19127b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.index = storage->index;
19137b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.reladdr = NULL;
19147b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.swizzle = SWIZZLE_NOOP;
19157b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.negate = 0;
19167b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
19177b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 param_rval->accept(this);
19187b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_dst_reg l = ir_to_mesa_dst_reg_from_src(this->result);
19197b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
19207b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 for (i = 0; i < type_size(param->type); i++) {
19217b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
19227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    l.index++;
19237b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    r.index++;
19247b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
19257b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
19267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
19277b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      sig_iter.next();
19287b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
19297b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(!sig_iter.has_next());
19307b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
19317b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Process return value. */
19327b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   this->result = entry->return_reg;
193384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
193484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
193584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
193684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
193784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_texture *ir)
193884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
19399c02412cdc0270f2b0dc64afe709721e049fd5b0Eric Anholt   ir_to_mesa_src_reg result_src, coord, lod_info, projector;
1940d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   ir_to_mesa_dst_reg result_dst, coord_dst;
1941d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_to_mesa_instruction *inst = NULL;
1942d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   prog_opcode opcode = OPCODE_NOP;
194384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
194484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir->coordinate->accept(this);
1945d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1946d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   /* Put our coords in a temp.  We'll need to modify them for shadow,
1947d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * projection, or LOD, so the only case we'd use it as is is if
1948d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * we're doing plain old texturing.  Mesa IR optimization should
1949d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    * handle cleaning up our mess in that case.
1950d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt    */
1951d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   coord = get_temp(glsl_type::vec4_type);
1952d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   coord_dst = ir_to_mesa_dst_reg_from_src(coord);
1953d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst,
1954d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt		       this->result);
1955d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1956de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt   if (ir->projector) {
1957de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt      ir->projector->accept(this);
1958de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt      projector = this->result;
1959de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt   }
1960de75dfac4ea2cad64dc91f6ac16fe205b5015af6Eric Anholt
1961d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   /* Storage for our result.  Ideally for an assignment we'd be using
1962d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    * the actual storage for the result here, instead.
1963d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    */
1964d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   result_src = get_temp(glsl_type::vec4_type);
1965d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   result_dst = ir_to_mesa_dst_reg_from_src(result_src);
1966d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1967d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   switch (ir->op) {
1968d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_tex:
1969d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TEX;
1970d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1971d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txb:
1972d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TXB;
1973d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir->lod_info.bias->accept(this);
1974d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      lod_info = this->result;
1975d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1976d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txl:
1977d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      opcode = OPCODE_TXL;
1978d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      ir->lod_info.lod->accept(this);
1979d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      lod_info = this->result;
1980d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1981d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txd:
1982d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case ir_txf:
1983d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      assert(!"GLSL 1.30 features unsupported");
1984d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
1985d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
1986d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
1987d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   if (ir->projector) {
1988d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      if (opcode == OPCODE_TEX) {
1989d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 /* Slot the projector in as the last component of the coord. */
1990d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_W;
1991d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, projector);
1992d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZW;
1993d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 opcode = OPCODE_TXP;
1994d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      } else {
1995d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_src_reg coord_w = coord;
1996d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_w.swizzle = SWIZZLE_WWWW;
1997d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
1998d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 /* For the other TEX opcodes there's no projective version
1999d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  * since the last slot is taken up by lod info.  Do the
2000d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  * projective divide now.
2001d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	  */
2002d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_W;
2003d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_RCP, coord_dst, projector);
2004d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
2005d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZ;
2006d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 ir_to_mesa_emit_op2(ir, OPCODE_MUL, coord_dst, coord, coord_w);
2007d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
2008d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord_dst.writemask = WRITEMASK_XYZW;
2009d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt	 coord.swizzle = SWIZZLE_XYZW;
2010d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      }
2011d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   }
2012d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
2013b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   if (ir->shadow_comparitor) {
2014b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      /* Slot the shadow value in as the second to last component of the
2015b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt       * coord.
2016b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt       */
2017b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      ir->shadow_comparitor->accept(this);
2018b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      coord_dst.writemask = WRITEMASK_Z;
2019b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, this->result);
2020b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      coord_dst.writemask = WRITEMASK_XYZW;
2021b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   }
2022b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt
2023d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   if (opcode == OPCODE_TXL || opcode == OPCODE_TXB) {
2024d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      /* Mesa IR stores lod or lod bias in the last channel of the coords. */
2025d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      coord_dst.writemask = WRITEMASK_W;
2026d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      ir_to_mesa_emit_op1(ir, OPCODE_MOV, coord_dst, lod_info);
2027d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt      coord_dst.writemask = WRITEMASK_XYZW;
2028d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   }
2029d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
2030d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt   inst = ir_to_mesa_emit_op1(ir, opcode, result_dst, coord);
2031d3983ca03248092d92b5240fbc6a30c24f80d313Eric Anholt
2032b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt   if (ir->shadow_comparitor)
2033b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      inst->tex_shadow = GL_TRUE;
2034b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt
2035d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   ir_dereference_variable *sampler = ir->sampler->as_dereference_variable();
2036d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   assert(sampler); /* FINISHME: sampler arrays */
2037d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   /* generate the mapping, remove when we generate storage at
2038d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    * declaration time
2039d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt    */
2040d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler->accept(this);
2041d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2042fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   inst->sampler = get_sampler_location(sampler->var);
2043d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2044d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   switch (sampler->type->sampler_dimensionality) {
2045d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_1D:
2046d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_1D_INDEX;
2047d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
2048d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_2D:
2049d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_2D_INDEX;
2050d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
2051d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_3D:
2052d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_3D_INDEX;
2053d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
2054d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   case GLSL_SAMPLER_DIM_CUBE:
2055d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      inst->tex_target = TEXTURE_CUBE_INDEX;
2056d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      break;
2057d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   default:
2058d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      assert(!"FINISHME: other texture targets");
2059d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   }
2060d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2061d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   this->result = result_src;
206284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
206384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
206484771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
206584771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_return *ir)
206684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
20677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   assert(current_function);
20687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   if (ir->get_value()) {
20707b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_to_mesa_dst_reg l;
20717b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      int i;
20727b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20737b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir->get_value()->accept(this);
20747b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      ir_to_mesa_src_reg r = this->result;
207584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
20767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      l = ir_to_mesa_dst_reg_from_src(current_function->return_reg);
20777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20787b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      for (i = 0; i < type_size(current_function->sig->return_type); i++) {
20797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 ir_to_mesa_emit_op1(ir, OPCODE_MOV, l, r);
20807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 l.index++;
20817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 r.index++;
20827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
20837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   }
20847b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
20857b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   ir_to_mesa_emit_op0(ir, OPCODE_RET);
208684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
208784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
208816efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkevoid
208916efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunkeir_to_mesa_visitor::visit(ir_discard *ir)
209016efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke{
20915e4dd061d17563828bcce5525400a0ce363aa15dEric Anholt   assert(ir->condition == NULL); /* FINISHME */
209216efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke
2093021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   ir_to_mesa_emit_op0(ir, OPCODE_KIL_NV);
209416efab1c4dee6e6a827ba5f1c482378159545ae5Kenneth Graunke}
209584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
209684771df82ed2ed8718013795089edd38cf5bd84dEric Anholtvoid
209784771df82ed2ed8718013795089edd38cf5bd84dEric Anholtir_to_mesa_visitor::visit(ir_if *ir)
209884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
2099854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   ir_to_mesa_instruction *cond_inst, *if_inst, *else_inst = NULL;
2100cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt   ir_to_mesa_instruction *prev_inst;
2101cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt
2102cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt   prev_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
2103c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2104c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir->condition->accept(this);
21050161515c395c44233529c8d51f823b60050bc7baEric Anholt   assert(this->result.file != PROGRAM_UNDEFINED);
2106c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2107854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   if (ctx->Shader.EmitCondCodes) {
2108854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      cond_inst = (ir_to_mesa_instruction *)this->instructions.get_tail();
2109cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt
2110cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      /* See if we actually generated any instruction for generating
2111cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       * the condition.  If not, then cook up a move to a temp so we
2112cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       * have something to set cond_update on.
2113cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt       */
2114cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      if (cond_inst == prev_inst) {
2115cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt	 ir_to_mesa_src_reg temp = get_temp(glsl_type::bool_type);
2116cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt	 cond_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_MOV,
2117cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt					 ir_to_mesa_dst_reg_from_src(temp),
2118cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt					 result);
2119cbe52c8012659abe5d81cf1180659820e704d290Eric Anholt      }
2120854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      cond_inst->cond_update = GL_TRUE;
2121854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt
2122021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      if_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_IF);
2123854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst->dst_reg.cond_mask = COND_NE;
2124854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   } else {
2125854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      if_inst = ir_to_mesa_emit_op1(ir->condition,
2126854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    OPCODE_IF, ir_to_mesa_undef_dst,
2127854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt				    this->result);
2128854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt   }
2129c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2130c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   this->instructions.push_tail(if_inst);
2131c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2132c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   visit_exec_list(&ir->then_instructions, this);
2133c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2134c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   if (!ir->else_instructions.is_empty()) {
2135021222c6a872ca2eef770ebadb8754f659775204Eric Anholt      else_inst = ir_to_mesa_emit_op0(ir->condition, OPCODE_ELSE);
21360a52e8b691cecfeec27717c3289763226d5f1bdaEric Anholt      visit_exec_list(&ir->else_instructions, this);
2137c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
2138c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
21390161515c395c44233529c8d51f823b60050bc7baEric Anholt   if_inst = ir_to_mesa_emit_op1(ir->condition, OPCODE_ENDIF,
21400161515c395c44233529c8d51f823b60050bc7baEric Anholt				 ir_to_mesa_undef_dst, ir_to_mesa_undef);
214184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
214284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2143ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholtir_to_mesa_visitor::ir_to_mesa_visitor()
2144ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt{
21450161515c395c44233529c8d51f823b60050bc7baEric Anholt   result.file = PROGRAM_UNDEFINED;
2146ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt   next_temp = 1;
21477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   next_signature_id = 1;
2148d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   sampler_map = NULL;
21497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   current_function = NULL;
2150ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt}
2151ae252d3613d10a051657c4ca6db27409f7cf40aeEric Anholt
2152fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholtir_to_mesa_visitor::~ir_to_mesa_visitor()
2153fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt{
2154fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt   if (this->sampler_map)
2155fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt      hash_table_dtor(this->sampler_map);
2156fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt}
2157fe1918c71c3e387939cef9359d4b31ebc5c11a17Eric Anholt
215884771df82ed2ed8718013795089edd38cf5bd84dEric Anholtstatic struct prog_src_register
215984771df82ed2ed8718013795089edd38cf5bd84dEric Anholtmesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
216084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
216184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_src_register mesa_reg;
216284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
216384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.File = reg.file;
2164aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt   assert(reg.index < (1 << INST_INDEX_BITS) - 1);
216584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_reg.Index = reg.index;
216634195832669f0eb7c4a80997cc524f8d10319307Eric Anholt   mesa_reg.Swizzle = reg.swizzle;
2167f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt   mesa_reg.RelAddr = reg.reladdr != NULL;
2168ea6b34cce4471d6239201101a3b24db17eaae870Eric Anholt   mesa_reg.Negate = reg.negate;
2169285ff93819724b9a858984dc8c30858784a5ee5bEric Anholt   mesa_reg.Abs = 0;
2170b10bb527eaf39378da25dd4ad21b1c68ceaa1e2dEric Anholt   mesa_reg.HasIndex2 = GL_FALSE;
217184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
217284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   return mesa_reg;
217384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt}
217484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
2175c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
21767b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholtset_branchtargets(ir_to_mesa_visitor *v,
21777b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt		  struct prog_instruction *mesa_instructions,
2178c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt		  int num_instructions)
2179c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
2180e2a358348b143a163c065d82c7375e6a94e98f2aKenneth Graunke   int if_count = 0, loop_count = 0;
218164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int *if_stack, *loop_stack;
218264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int if_stack_pos = 0, loop_stack_pos = 0;
218364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   int i, j;
2184c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2185c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
218664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      switch (mesa_instructions[i].Opcode) {
218764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_IF:
2188c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_count++;
218964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
219064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
219164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_count++;
219264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
219364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BRK:
219464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_CONT:
219564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = -1;
219664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
219764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      default:
219864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
219964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      }
2200c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
2201c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
220264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   if_stack = (int *)calloc(if_count, sizeof(*if_stack));
220364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt   loop_stack = (int *)calloc(loop_count, sizeof(*loop_stack));
2204c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2205c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
2206c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      switch (mesa_instructions[i].Opcode) {
2207c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_IF:
220864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos] = i;
2209c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos++;
2210c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
2211c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ELSE:
221264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
221364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 if_stack[if_stack_pos - 1] = i;
2214c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
2215c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      case OPCODE_ENDIF:
221664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[if_stack[if_stack_pos - 1]].BranchTarget = i;
2217c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 if_stack_pos--;
2218c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
221964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_BGNLOOP:
222064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack[loop_stack_pos] = i;
222164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos++;
222264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 break;
222364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      case OPCODE_ENDLOOP:
222464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 loop_stack_pos--;
222564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* Rewrite any breaks/conts at this nesting level (haven't
222664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * already had a BranchTarget assigned) to point to the end
222764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  * of the loop.
222864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	  */
222964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 for (j = loop_stack[loop_stack_pos]; j < i; j++) {
223064fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    if (mesa_instructions[j].Opcode == OPCODE_BRK ||
223164fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		mesa_instructions[j].Opcode == OPCODE_CONT) {
223264fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       if (mesa_instructions[j].BranchTarget == -1) {
223364fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt		  mesa_instructions[j].BranchTarget = i;
223464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	       }
223564fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	    }
223664fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 }
223764fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 /* The loop ends point at each other. */
223864fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[i].BranchTarget = loop_stack[loop_stack_pos];
223964fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt	 mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
22407b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 break;
22417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      case OPCODE_CAL:
22427b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 foreach_iter(exec_list_iterator, iter, v->function_signatures) {
22437b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    function_entry *entry = (function_entry *)iter.get();
22447b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
22457b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    if (entry->sig_id == mesa_instructions[i].BranchTarget) {
22467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	       mesa_instructions[i].BranchTarget = entry->inst;
22477b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	       break;
22487b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    }
22497b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
22507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 break;
2251c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      default:
2252c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 break;
2253c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
2254c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
2255c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2256c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   free(if_stack);
2257c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
2258c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2259c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtstatic void
2260c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholtprint_program(struct prog_instruction *mesa_instructions,
2261c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      ir_instruction **mesa_instruction_annotation,
2262c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	      int num_instructions)
2263c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt{
2264c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction *last_ir = NULL;
2265c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
2266748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt   int indent = 0;
2267c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2268c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   for (i = 0; i < num_instructions; i++) {
2269c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      struct prog_instruction *mesa_inst = mesa_instructions + i;
2270c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      ir_instruction *ir = mesa_instruction_annotation[i];
2271c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2272748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt      fprintf(stdout, "%3d: ", i);
2273748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
227464fcbbca9ca8191b5131304af2026d0ed914b765Eric Anholt      if (last_ir != ir && ir) {
2275748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 int j;
2276748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
2277748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 for (j = 0; j < indent; j++) {
2278748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	    fprintf(stdout, " ");
2279748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 }
2280748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 ir->print();
2281c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 printf("\n");
2282c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt	 last_ir = ir;
2283748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt
2284748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt	 fprintf(stdout, "     "); /* line number spacing. */
2285c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      }
2286c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2287748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt      indent = _mesa_fprint_instruction_opt(stdout, mesa_inst, indent,
2288748c343f8bdbbc8c5f00403b790ad7130424c35fEric Anholt					    PROG_PRINT_DEBUG, NULL);
2289c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   }
2290c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt}
2291c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2292ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtstatic void
22934d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_input(struct gl_program *prog,
22944d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   int index,
22954d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   GLboolean reladdr)
22964d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{
22974d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   prog->InputsRead |= BITFIELD64_BIT(index);
22984d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   int i;
22994d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
23004d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   if (reladdr) {
23014d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      if (index >= FRAG_ATTRIB_TEX0 && index <= FRAG_ATTRIB_TEX7) {
23024d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 for (i = 0; i < 8; i++) {
23034d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    prog->InputsRead |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
23044d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 }
23054d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      } else {
23064d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 assert(!"FINISHME: Mark InputsRead for varying arrays");
23074d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      }
23084d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   }
23094d5da50b94115d055ba8d0ff8717054582665384Eric Anholt}
23104d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
23114d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void
23124d5da50b94115d055ba8d0ff8717054582665384Eric Anholtmark_output(struct gl_program *prog,
23134d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   int index,
23144d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	   GLboolean reladdr)
23154d5da50b94115d055ba8d0ff8717054582665384Eric Anholt{
23164d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   prog->OutputsWritten |= BITFIELD64_BIT(index);
23174d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   int i;
23184d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
23194d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   if (reladdr) {
23204d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      if (index >= VERT_RESULT_TEX0 && index <= VERT_RESULT_TEX7) {
23214d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 for (i = 0; i < 8; i++) {
23224d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    prog->OutputsWritten |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
23234d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 }
23244d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      } else {
23254d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 assert(!"FINISHME: Mark OutputsWritten for varying arrays");
23264d5da50b94115d055ba8d0ff8717054582665384Eric Anholt      }
23274d5da50b94115d055ba8d0ff8717054582665384Eric Anholt   }
23284d5da50b94115d055ba8d0ff8717054582665384Eric Anholt}
23294d5da50b94115d055ba8d0ff8717054582665384Eric Anholt
23304d5da50b94115d055ba8d0ff8717054582665384Eric Anholtstatic void
2331ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholtcount_resources(struct gl_program *prog)
2332ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt{
2333d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   unsigned int i;
2334d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2335ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   prog->InputsRead = 0;
2336ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   prog->OutputsWritten = 0;
2337d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   prog->SamplersUsed = 0;
2338ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
2339ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   for (i = 0; i < prog->NumInstructions; i++) {
2340ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      struct prog_instruction *inst = &prog->Instructions[i];
2341ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      unsigned int reg;
2342ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
2343ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      switch (inst->DstReg.File) {
2344ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      case PROGRAM_OUTPUT:
23454d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 mark_output(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
2346ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
2347ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      case PROGRAM_INPUT:
23484d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	 mark_input(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
2349ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
2350ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      default:
2351ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 break;
2352ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      }
2353ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
2354ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) {
2355ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 switch (inst->SrcReg[reg].File) {
2356ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 case PROGRAM_OUTPUT:
23574d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    mark_output(prog, inst->SrcReg[reg].Index,
23584d5da50b94115d055ba8d0ff8717054582665384Eric Anholt			inst->SrcReg[reg].RelAddr);
2359ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
2360ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 case PROGRAM_INPUT:
23614d5da50b94115d055ba8d0ff8717054582665384Eric Anholt	    mark_input(prog, inst->SrcReg[reg].Index, inst->SrcReg[reg].RelAddr);
2362ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
2363ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 default:
2364ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	    break;
2365ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 }
2366ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt      }
2367d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2368d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      /* Instead of just using the uniform's value to map to a
2369d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * sampler, Mesa first allocates a separate number for the
2370d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * sampler (_mesa_add_sampler), then we reindex it down to a
2371d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * small integer (sampler_map[], SamplersUsed), then that gets
2372d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       * mapped to the uniform's value, and we get an actual sampler.
2373d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt       */
2374d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      if (_mesa_is_tex_instruction(inst->Opcode)) {
2375d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 prog->SamplerTargets[inst->TexSrcUnit] =
2376d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    (gl_texture_index)inst->TexSrcTarget;
2377d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 prog->SamplersUsed |= 1 << inst->TexSrcUnit;
2378d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 if (inst->TexShadow) {
2379d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	    prog->ShadowSamplers |= 1 << inst->TexSrcUnit;
2380d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt	 }
2381d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      }
2382ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt   }
2383d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt
2384d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt   _mesa_update_shader_textures_used(prog);
2385ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt}
2386ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt
238785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt/* Each stage has some uniforms in its Parameters list.  The Uniforms
238885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * list for the linked shader program has a pointer to these uniforms
238985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * in each of the stage's Parameters list, so that their values can be
239085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt * updated when a uniform is set.
239185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt */
239285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtstatic void
239385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholtlink_uniforms_to_shared_uniform_list(struct gl_uniform_list *uniforms,
239485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt				     struct gl_program *prog)
239585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt{
239685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   unsigned int i;
239785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
239885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   for (i = 0; i < prog->Parameters->NumParameters; i++) {
239985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      const struct gl_program_parameter *p = prog->Parameters->Parameters + i;
240085c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
240185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      if (p->Type == PROGRAM_UNIFORM || p->Type == PROGRAM_SAMPLER) {
240285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 struct gl_uniform *uniform =
240385c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	    _mesa_append_uniform(uniforms, p->Name, prog->Target, i);
240485c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 if (uniform)
240585c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	    uniform->Initialized = p->Initialized;
240685c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt      }
240785c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt   }
240885c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt}
240985c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
2410364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtstruct gl_program *
241195c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholtget_mesa_program(GLcontext *ctx, struct gl_shader_program *shader_program,
241295c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt		 struct gl_shader *shader)
241384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt{
241495c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt   void *mem_ctx = shader_program;
241584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   ir_to_mesa_visitor v;
241684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   struct prog_instruction *mesa_instructions, *mesa_inst;
2417c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   ir_instruction **mesa_instruction_annotation;
2418c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   int i;
2419364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   struct gl_program *prog;
2420364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   GLenum target;
2421c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   const char *target_string;
24227b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   GLboolean progress;
2423364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2424364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   switch (shader->Type) {
2425c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   case GL_VERTEX_SHADER:
2426c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target = GL_VERTEX_PROGRAM_ARB;
2427c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target_string = "vertex";
2428c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2429c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   case GL_FRAGMENT_SHADER:
2430c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target = GL_FRAGMENT_PROGRAM_ARB;
2431c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      target_string = "fragment";
2432c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2433c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   default:
2434c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      assert(!"should not be reached");
2435c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt      break;
2436364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
243784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
24381124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt   validate_ir_tree(shader->ir);
24391124e5a3cbba839ffd968742bfa3295c8de5498cEric Anholt
2440859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt   prog = ctx->Driver.NewProgram(ctx, target, shader_program->Name);
2441364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (!prog)
2442364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      return NULL;
2443364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Parameters = _mesa_new_parameter_list();
2444364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Varying = _mesa_new_parameter_list();
2445364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Attributes = _mesa_new_parameter_list();
2446364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.ctx = ctx;
2447364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.prog = prog;
2448364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2449364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   v.mem_ctx = talloc_new(NULL);
24507b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
24517b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Emit Mesa IR for main(). */
245216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   visit_exec_list(shader->ir, &v);
2453021222c6a872ca2eef770ebadb8754f659775204Eric Anholt   v.ir_to_mesa_emit_op0(NULL, OPCODE_END);
245484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
24557b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   /* Now emit bodies for any functions that were used. */
24567b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   do {
24577b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      progress = GL_FALSE;
24587b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
24597b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      foreach_iter(exec_list_iterator, iter, v.function_signatures) {
24607b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 function_entry *entry = (function_entry *)iter.get();
24617b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
24627b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 if (!entry->bgn_inst) {
24637b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    v.current_function = entry;
24647b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
24657b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst = v.ir_to_mesa_emit_op0(NULL, OPCODE_BGNSUB);
24667b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    entry->bgn_inst->function = entry;
24677b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
24687b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    visit_exec_list(&entry->sig->body, &v);
24697b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
2470806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt	    ir_to_mesa_instruction *last;
2471806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt	    last = (ir_to_mesa_instruction *)v.instructions.get_tail();
2472806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt	    if (last->op != OPCODE_RET)
2473806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt	       v.ir_to_mesa_emit_op0(NULL, OPCODE_RET);
2474806cb9f9528e3c55c157d7e8bbb751b769b6fcb7Eric Anholt
247540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	    ir_to_mesa_instruction *end;
247640f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	    end = v.ir_to_mesa_emit_op0(NULL, OPCODE_ENDSUB);
247740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	    end->function = entry;
247840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt
24797b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	    progress = GL_TRUE;
24807b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 }
24817b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt      }
24827b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   } while (progress);
24837b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
2484364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->NumTemporaries = v.next_temp;
2485364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
248684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   int num_instructions = 0;
248784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
248884771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      num_instructions++;
248984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
249084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
249184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_instructions =
249284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      (struct prog_instruction *)calloc(num_instructions,
249384771df82ed2ed8718013795089edd38cf5bd84dEric Anholt					sizeof(*mesa_instructions));
2494364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   mesa_instruction_annotation = talloc_array(mem_ctx, ir_instruction *,
2495364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt					      num_instructions);
249684771df82ed2ed8718013795089edd38cf5bd84dEric Anholt
249784771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   mesa_inst = mesa_instructions;
2498c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt   i = 0;
249984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   foreach_iter(exec_list_iterator, iter, v.instructions) {
250084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
2501b7abce770fe9bb09a6f435d35c1a4afd134fa855Eric Anholt
250284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->Opcode = inst->op;
2503854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      mesa_inst->CondUpdate = inst->cond_update;
250484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.File = inst->dst_reg.file;
250584771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->DstReg.Index = inst->dst_reg.index;
2506854fd66cbb569cb3d4768196f4c680eff489733eEric Anholt      mesa_inst->DstReg.CondMask = inst->dst_reg.cond_mask;
250712f654c63bc42d353e258cde989d9114cdde26c6Eric Anholt      mesa_inst->DstReg.WriteMask = inst->dst_reg.writemask;
2508f8a2b65bc9bf3dfb4a4aa6fe1c0ea65f78a01922Eric Anholt      mesa_inst->DstReg.RelAddr = inst->dst_reg.reladdr != NULL;
250984771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
251084771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
251184771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
2512d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      mesa_inst->TexSrcUnit = inst->sampler;
2513d4f7e660dd81e05b0829c1b70663b3959fd78f47Eric Anholt      mesa_inst->TexSrcTarget = inst->tex_target;
2514b61f4241f314144d3290085cda5db1959d8960a2Eric Anholt      mesa_inst->TexShadow = inst->tex_shadow;
2515c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      mesa_instruction_annotation[i] = inst->ir;
2516aaee40e107cf07a12c8e373d8bb910254f4ba30bEric Anholt
251795c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt      if (ctx->Shader.EmitNoIfs && mesa_inst->Opcode == OPCODE_IF) {
251895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	 shader_program->InfoLog =
251995c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	    talloc_asprintf_append(shader_program->InfoLog,
252095c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt				   "Couldn't flatten if statement\n");
252195c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	 shader_program->LinkStatus = false;
252295c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt      }
252395c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt
252440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      switch (mesa_inst->Opcode) {
252540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      case OPCODE_BGNSUB:
25267b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 inst->function->inst = i;
252740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 mesa_inst->Comment = strdup(inst->function->sig->function_name());
252840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 break;
252940f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      case OPCODE_ENDSUB:
253040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 mesa_inst->Comment = strdup(inst->function->sig->function_name());
253140f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 break;
253240f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      case OPCODE_CAL:
25337b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt	 mesa_inst->BranchTarget = inst->function->sig_id; /* rewritten later */
253440f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 break;
253540f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      case OPCODE_ARL:
2536d64343f1ae84979bd154475badf11af8a9bfc2ebEric Anholt	 prog->NumAddressRegs = 1;
253740f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 break;
253840f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      default:
253940f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt	 break;
254040f57c2becbb2cee7cfb6d6ed49dc1db57987e9aEric Anholt      }
25417b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt
254284771df82ed2ed8718013795089edd38cf5bd84dEric Anholt      mesa_inst++;
2543c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt      i++;
254484771df82ed2ed8718013795089edd38cf5bd84dEric Anholt   }
2545c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
25467b130149427019ac9ae6d39b6871c14fb6ba2dadEric Anholt   set_branchtargets(&v, mesa_instructions, num_instructions);
2547c8d0a9f0065c321308be635529c95735f3beb68fEric Anholt   if (ctx->Shader.Flags & GLSL_DUMP) {
2548455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("\n");
2549455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("GLSL IR for linked %s program %d:\n", target_string,
2550455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt	     shader_program->Name);
2551455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      _mesa_print_ir(shader->ir, NULL);
2552455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("\n");
2553455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("\n");
2554455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("Mesa IR for linked %s program %d:\n", target_string,
2555455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt	     shader_program->Name);
2556364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      print_program(mesa_instructions, mesa_instruction_annotation,
2557364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt		    num_instructions);
2558364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2559364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2560364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Instructions = mesa_instructions;
2561364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->NumInstructions = num_instructions;
2562364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
256316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   _mesa_reference_program(ctx, &shader->Program, prog);
2564364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
256528faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt   if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
256628faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt      _mesa_optimize_program(ctx, prog);
256728faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt   }
256828faa12dc2413d93c7f4778327a5e7c4c8f57c85Eric Anholt
2569364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   return prog;
2570364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt}
2571364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
257216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtextern "C" {
257316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt
257416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholtvoid
257516b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt_mesa_glsl_compile_shader(GLcontext *ctx, struct gl_shader *shader)
2576364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{
25772462a536ea5c98867296905e3da127eba7c7bdffIan Romanick   struct _mesa_glsl_parse_state *state =
25782462a536ea5c98867296905e3da127eba7c7bdffIan Romanick      new(shader) _mesa_glsl_parse_state(ctx, shader->Type, shader);
25795e18b051c039564d1998818d08caf1bff3983630Ian Romanick
2580153eca98064252be4daad9cc27746f37c245b627Ian Romanick   const char *source = shader->Source;
258106143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick   state->error = preprocess(state, &source, &state->info_log,
258206143ea09411aa283ac3633bfbfa4326584cd952Ian Romanick			     &ctx->Extensions);
2583153eca98064252be4daad9cc27746f37c245b627Ian Romanick
2584153eca98064252be4daad9cc27746f37c245b627Ian Romanick   if (!state->error) {
2585153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_lexer_ctor(state, source);
2586153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_parse(state);
2587153eca98064252be4daad9cc27746f37c245b627Ian Romanick     _mesa_glsl_lexer_dtor(state);
2588153eca98064252be4daad9cc27746f37c245b627Ian Romanick   }
2589364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
259016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   shader->ir = new(shader) exec_list;
2591364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (!state->error && !state->translation_unit.is_empty())
259216b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt      _mesa_ast_to_hir(shader->ir, state);
2593364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
259416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt   if (!state->error && !shader->ir->is_empty()) {
2595ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt      validate_ir_tree(shader->ir);
2596ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt
25974802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      /* Lowering */
25984802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      do_mat_op_to_vec(shader->ir);
25994802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      do_mod_to_fract(shader->ir);
26004802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      do_div_to_mul_rcp(shader->ir);
26014802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt
26024802fd905ae7c1a1122ec71c0556c2b19214a7fdEric Anholt      /* Optimization passes */
2603364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      bool progress;
2604364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      do {
2605364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 progress = false;
2606364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
260716b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_function_inlining(shader->ir) || progress;
260816b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_if_simplification(shader->ir) || progress;
260916b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_copy_propagation(shader->ir) || progress;
261016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_dead_code_local(shader->ir) || progress;
261166d4c65ee2c311ea0c71c39a28456d0c11798d6bEric Anholt	 progress = do_dead_code_unlinked(shader->ir) || progress;
2612784695442c415cf0be882434a25671ecfb635d34Eric Anholt	 progress = do_tree_grafting(shader->ir) || progress;
261316b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_constant_variable_unlinked(shader->ir) || progress;
261416b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_constant_folding(shader->ir) || progress;
2615832aad989e3d319a8aaac046aa49df25da134d82Eric Anholt	 progress = do_algebraic(shader->ir) || progress;
2616d674ebcee0d2731e50d6530502cefcebc39dcdb6Eric Anholt	 progress = do_if_return(shader->ir) || progress;
2617952d0f88e1741d51b641be75f7c5a6565e245a69Eric Anholt	 if (1 || ctx->Shader.EmitNoIfs)
261895c08920ea3d040360e5cc51d8a852d21a0329eeEric Anholt	    progress = do_if_to_cond_assign(shader->ir) || progress;
2619a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
262016b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_vec_index_to_swizzle(shader->ir) || progress;
2621a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	 /* Do this one after the previous to let the easier pass handle
2622a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	  * constant vector indexing.
2623a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	  */
2624a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt	 progress = do_vec_index_to_cond_assign(shader->ir) || progress;
2625a36334be02cb0a2b834667116bfeb680bf365857Eric Anholt
262616b68b1952d0da14b9ce8306efa64988ce46b4b7Eric Anholt	 progress = do_swizzle_swizzle(shader->ir) || progress;
2627364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      } while (progress);
2628ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt
2629ee7b2b3f44d09c2311887d3524e197b9738580a9Eric Anholt      validate_ir_tree(shader->ir);
2630364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2631364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2632364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->symbols = state->symbols;
2633364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2634364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->CompileStatus = !state->error;
2635364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   shader->InfoLog = state->info_log;
263625f51d3b9b8c36c41cd23d2797b6a06f6e27ff86Ian Romanick   shader->Version = state->language_version;
2637d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick   memcpy(shader->builtins_to_link, state->builtins_to_link,
2638d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick	  sizeof(shader->builtins_to_link[0]) * state->num_builtins_to_link);
2639d5be2acae379783c4aa31243e0a88a9e67e6ca7eIan Romanick   shader->num_builtins_to_link = state->num_builtins_to_link;
2640c5ca73e72c27b2e5d7fcf4662b9921ddb3a9627bEric Anholt
2641b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt   if (ctx->Shader.Flags & GLSL_LOG) {
2642b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt      _mesa_write_shader_to_file(shader);
2643b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt   }
2644b42519108dc7ab104cf9ade65a508f54a0294406Eric Anholt
2645455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt   if (ctx->Shader.Flags & GLSL_DUMP) {
2646455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("GLSL source for shader %d:\n", shader->Name);
2647455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("%s\n", shader->Source);
2648455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt
2649455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("GLSL IR for shader %d:\n", shader->Name);
2650455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      _mesa_print_ir(shader->ir, NULL);
2651455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt      printf("\n\n");
2652455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt   }
2653455290e4281bf53ce2fe248a2adf5163563c44c8Eric Anholt
2654116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke   /* Retain any live IR, but trash the rest. */
265560e2d06d1ccc66ad00cd7ab81c418853f21be291Ian Romanick   reparent_ir(shader->ir, shader);
2656116f1d4f95d8eb0a82b272016590549632c865b3Kenneth Graunke
2657364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   talloc_free(state);
2658364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt }
2659364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2660364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholtvoid
2661364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt_mesa_glsl_link_shader(GLcontext *ctx, struct gl_shader_program *prog)
2662364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt{
2663364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   unsigned int i;
2664849e18153cd91d812f694b806a84008498860bc3Eric Anholt
2665364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_clear_shader_program_data(ctx, prog);
2666364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2667849e18153cd91d812f694b806a84008498860bc3Eric Anholt   prog->LinkStatus = GL_TRUE;
2668364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2669364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   for (i = 0; i < prog->NumShaders; i++) {
2670849e18153cd91d812f694b806a84008498860bc3Eric Anholt      if (!prog->Shaders[i]->CompileStatus) {
2671849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 prog->InfoLog =
2672849e18153cd91d812f694b806a84008498860bc3Eric Anholt	    talloc_asprintf_append(prog->InfoLog,
2673364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				   "linking with uncompiled shader");
2674849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 prog->LinkStatus = GL_FALSE;
2675364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      }
2676364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2677364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2678364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   prog->Varying = _mesa_new_parameter_list();
2679364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
2680364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   _mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
2681364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2682849e18153cd91d812f694b806a84008498860bc3Eric Anholt   if (prog->LinkStatus) {
2683849e18153cd91d812f694b806a84008498860bc3Eric Anholt      link_shaders(prog);
2684849e18153cd91d812f694b806a84008498860bc3Eric Anholt
2685849e18153cd91d812f694b806a84008498860bc3Eric Anholt      /* We don't use the linker's uniforms list, and cook up our own at
2686849e18153cd91d812f694b806a84008498860bc3Eric Anholt       * generate time.
2687849e18153cd91d812f694b806a84008498860bc3Eric Anholt       */
2688849e18153cd91d812f694b806a84008498860bc3Eric Anholt      free(prog->Uniforms);
2689849e18153cd91d812f694b806a84008498860bc3Eric Anholt      prog->Uniforms = _mesa_new_uniform_list();
2690849e18153cd91d812f694b806a84008498860bc3Eric Anholt   }
2691364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2692364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   if (prog->LinkStatus) {
26933fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick      for (i = 0; i < prog->_NumLinkedShaders; i++) {
2694364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 struct gl_program *linked_prog;
2695859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt	 bool ok = true;
2696364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2697849e18153cd91d812f694b806a84008498860bc3Eric Anholt	 linked_prog = get_mesa_program(ctx, prog,
26983fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick					prog->_LinkedShaders[i]);
2699ffc845a50a69b48446f5e25e7b4485089231bbe7Eric Anholt	 count_resources(linked_prog);
2700364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
270185c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt	 link_uniforms_to_shared_uniform_list(prog->Uniforms, linked_prog);
270285c978f38c819003b6447e8e4feb8b90bb352eeaEric Anholt
27033fb878722ed53d79eedb9fe68972ef32b79575d4Ian Romanick	 switch (prog->_LinkedShaders[i]->Type) {
2704364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 case GL_VERTEX_SHADER:
2705364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    _mesa_reference_vertprog(ctx, &prog->VertexProgram,
2706364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				     (struct gl_vertex_program *)linked_prog);
2707859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt	    ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,
2708859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt						 linked_prog);
2709364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    break;
2710364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 case GL_FRAGMENT_SHADER:
2711364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    _mesa_reference_fragprog(ctx, &prog->FragmentProgram,
2712364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt				     (struct gl_fragment_program *)linked_prog);
2713859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt	    ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB,
2714859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt						 linked_prog);
2715364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	    break;
2716364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt	 }
2717859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt	 if (!ok) {
2718859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt	    prog->LinkStatus = GL_FALSE;
2719859fd56245c1d725cacab17a34793d41ea14e867Eric Anholt	 }
2720364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt      }
2721364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt   }
2722364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt}
2723364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt
2724364fcd8ee1af39e215338fba59306a14dd81c2b2Eric Anholt} /* extern "C" */
2725