1b8e80941Smrg/*
2b8e80941Smrg * Copyright © 2010 Intel Corporation
3b8e80941Smrg *
4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5b8e80941Smrg * copy of this software and associated documentation files (the "Software"),
6b8e80941Smrg * to deal in the Software without restriction, including without limitation
7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the
9b8e80941Smrg * Software is furnished to do so, subject to the following conditions:
10b8e80941Smrg *
11b8e80941Smrg * The above copyright notice and this permission notice (including the next
12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the
13b8e80941Smrg * Software.
14b8e80941Smrg *
15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21b8e80941Smrg * DEALINGS IN THE SOFTWARE.
22b8e80941Smrg */
23b8e80941Smrg#include <string.h>
24b8e80941Smrg#include "ir.h"
25b8e80941Smrg#include "compiler/glsl_types.h"
26b8e80941Smrg#include "glsl_parser_extras.h"
27b8e80941Smrg
28b8e80941Smrg
29b8e80941Smrgir_rvalue::ir_rvalue(enum ir_node_type t)
30b8e80941Smrg   : ir_instruction(t)
31b8e80941Smrg{
32b8e80941Smrg   this->type = glsl_type::error_type;
33b8e80941Smrg}
34b8e80941Smrg
35b8e80941Smrgbool ir_rvalue::is_zero() const
36b8e80941Smrg{
37b8e80941Smrg   return false;
38b8e80941Smrg}
39b8e80941Smrg
40b8e80941Smrgbool ir_rvalue::is_one() const
41b8e80941Smrg{
42b8e80941Smrg   return false;
43b8e80941Smrg}
44b8e80941Smrg
45b8e80941Smrgbool ir_rvalue::is_negative_one() const
46b8e80941Smrg{
47b8e80941Smrg   return false;
48b8e80941Smrg}
49b8e80941Smrg
50b8e80941Smrg/**
51b8e80941Smrg * Modify the swizzle make to move one component to another
52b8e80941Smrg *
53b8e80941Smrg * \param m    IR swizzle to be modified
54b8e80941Smrg * \param from Component in the RHS that is to be swizzled
55b8e80941Smrg * \param to   Desired swizzle location of \c from
56b8e80941Smrg */
57b8e80941Smrgstatic void
58b8e80941Smrgupdate_rhs_swizzle(ir_swizzle_mask &m, unsigned from, unsigned to)
59b8e80941Smrg{
60b8e80941Smrg   switch (to) {
61b8e80941Smrg   case 0: m.x = from; break;
62b8e80941Smrg   case 1: m.y = from; break;
63b8e80941Smrg   case 2: m.z = from; break;
64b8e80941Smrg   case 3: m.w = from; break;
65b8e80941Smrg   default: assert(!"Should not get here.");
66b8e80941Smrg   }
67b8e80941Smrg}
68b8e80941Smrg
69b8e80941Smrgvoid
70b8e80941Smrgir_assignment::set_lhs(ir_rvalue *lhs)
71b8e80941Smrg{
72b8e80941Smrg   void *mem_ctx = this;
73b8e80941Smrg   bool swizzled = false;
74b8e80941Smrg
75b8e80941Smrg   while (lhs != NULL) {
76b8e80941Smrg      ir_swizzle *swiz = lhs->as_swizzle();
77b8e80941Smrg
78b8e80941Smrg      if (swiz == NULL)
79b8e80941Smrg	 break;
80b8e80941Smrg
81b8e80941Smrg      unsigned write_mask = 0;
82b8e80941Smrg      ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
83b8e80941Smrg
84b8e80941Smrg      for (unsigned i = 0; i < swiz->mask.num_components; i++) {
85b8e80941Smrg	 unsigned c = 0;
86b8e80941Smrg
87b8e80941Smrg	 switch (i) {
88b8e80941Smrg	 case 0: c = swiz->mask.x; break;
89b8e80941Smrg	 case 1: c = swiz->mask.y; break;
90b8e80941Smrg	 case 2: c = swiz->mask.z; break;
91b8e80941Smrg	 case 3: c = swiz->mask.w; break;
92b8e80941Smrg	 default: assert(!"Should not get here.");
93b8e80941Smrg	 }
94b8e80941Smrg
95b8e80941Smrg	 write_mask |= (((this->write_mask >> i) & 1) << c);
96b8e80941Smrg	 update_rhs_swizzle(rhs_swiz, i, c);
97b8e80941Smrg         rhs_swiz.num_components = swiz->val->type->vector_elements;
98b8e80941Smrg      }
99b8e80941Smrg
100b8e80941Smrg      this->write_mask = write_mask;
101b8e80941Smrg      lhs = swiz->val;
102b8e80941Smrg
103b8e80941Smrg      this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
104b8e80941Smrg      swizzled = true;
105b8e80941Smrg   }
106b8e80941Smrg
107b8e80941Smrg   if (swizzled) {
108b8e80941Smrg      /* Now, RHS channels line up with the LHS writemask.  Collapse it
109b8e80941Smrg       * to just the channels that will be written.
110b8e80941Smrg       */
111b8e80941Smrg      ir_swizzle_mask rhs_swiz = { 0, 0, 0, 0, 0, 0 };
112b8e80941Smrg      int rhs_chan = 0;
113b8e80941Smrg      for (int i = 0; i < 4; i++) {
114b8e80941Smrg	 if (write_mask & (1 << i))
115b8e80941Smrg	    update_rhs_swizzle(rhs_swiz, i, rhs_chan++);
116b8e80941Smrg      }
117b8e80941Smrg      rhs_swiz.num_components = rhs_chan;
118b8e80941Smrg      this->rhs = new(mem_ctx) ir_swizzle(this->rhs, rhs_swiz);
119b8e80941Smrg   }
120b8e80941Smrg
121b8e80941Smrg   assert((lhs == NULL) || lhs->as_dereference());
122b8e80941Smrg
123b8e80941Smrg   this->lhs = (ir_dereference *) lhs;
124b8e80941Smrg}
125b8e80941Smrg
126b8e80941Smrgir_variable *
127b8e80941Smrgir_assignment::whole_variable_written()
128b8e80941Smrg{
129b8e80941Smrg   ir_variable *v = this->lhs->whole_variable_referenced();
130b8e80941Smrg
131b8e80941Smrg   if (v == NULL)
132b8e80941Smrg      return NULL;
133b8e80941Smrg
134b8e80941Smrg   if (v->type->is_scalar())
135b8e80941Smrg      return v;
136b8e80941Smrg
137b8e80941Smrg   if (v->type->is_vector()) {
138b8e80941Smrg      const unsigned mask = (1U << v->type->vector_elements) - 1;
139b8e80941Smrg
140b8e80941Smrg      if (mask != this->write_mask)
141b8e80941Smrg	 return NULL;
142b8e80941Smrg   }
143b8e80941Smrg
144b8e80941Smrg   /* Either all the vector components are assigned or the variable is some
145b8e80941Smrg    * composite type (and the whole thing is assigned.
146b8e80941Smrg    */
147b8e80941Smrg   return v;
148b8e80941Smrg}
149b8e80941Smrg
150b8e80941Smrgir_assignment::ir_assignment(ir_dereference *lhs, ir_rvalue *rhs,
151b8e80941Smrg			     ir_rvalue *condition, unsigned write_mask)
152b8e80941Smrg   : ir_instruction(ir_type_assignment)
153b8e80941Smrg{
154b8e80941Smrg   this->condition = condition;
155b8e80941Smrg   this->rhs = rhs;
156b8e80941Smrg   this->lhs = lhs;
157b8e80941Smrg   this->write_mask = write_mask;
158b8e80941Smrg
159b8e80941Smrg   if (lhs->type->is_scalar() || lhs->type->is_vector()) {
160b8e80941Smrg      int lhs_components = 0;
161b8e80941Smrg      for (int i = 0; i < 4; i++) {
162b8e80941Smrg	 if (write_mask & (1 << i))
163b8e80941Smrg	    lhs_components++;
164b8e80941Smrg      }
165b8e80941Smrg
166b8e80941Smrg      assert(lhs_components == this->rhs->type->vector_elements);
167b8e80941Smrg   }
168b8e80941Smrg}
169b8e80941Smrg
170b8e80941Smrgir_assignment::ir_assignment(ir_rvalue *lhs, ir_rvalue *rhs,
171b8e80941Smrg			     ir_rvalue *condition)
172b8e80941Smrg   : ir_instruction(ir_type_assignment)
173b8e80941Smrg{
174b8e80941Smrg   this->condition = condition;
175b8e80941Smrg   this->rhs = rhs;
176b8e80941Smrg
177b8e80941Smrg   /* If the RHS is a vector type, assume that all components of the vector
178b8e80941Smrg    * type are being written to the LHS.  The write mask comes from the RHS
179b8e80941Smrg    * because we can have a case where the LHS is a vec4 and the RHS is a
180b8e80941Smrg    * vec3.  In that case, the assignment is:
181b8e80941Smrg    *
182b8e80941Smrg    *     (assign (...) (xyz) (var_ref lhs) (var_ref rhs))
183b8e80941Smrg    */
184b8e80941Smrg   if (rhs->type->is_vector())
185b8e80941Smrg      this->write_mask = (1U << rhs->type->vector_elements) - 1;
186b8e80941Smrg   else if (rhs->type->is_scalar())
187b8e80941Smrg      this->write_mask = 1;
188b8e80941Smrg   else
189b8e80941Smrg      this->write_mask = 0;
190b8e80941Smrg
191b8e80941Smrg   this->set_lhs(lhs);
192b8e80941Smrg}
193b8e80941Smrg
194b8e80941Smrgir_expression::ir_expression(int op, const struct glsl_type *type,
195b8e80941Smrg			     ir_rvalue *op0, ir_rvalue *op1,
196b8e80941Smrg			     ir_rvalue *op2, ir_rvalue *op3)
197b8e80941Smrg   : ir_rvalue(ir_type_expression)
198b8e80941Smrg{
199b8e80941Smrg   this->type = type;
200b8e80941Smrg   this->operation = ir_expression_operation(op);
201b8e80941Smrg   this->operands[0] = op0;
202b8e80941Smrg   this->operands[1] = op1;
203b8e80941Smrg   this->operands[2] = op2;
204b8e80941Smrg   this->operands[3] = op3;
205b8e80941Smrg   init_num_operands();
206b8e80941Smrg
207b8e80941Smrg#ifndef NDEBUG
208b8e80941Smrg   for (unsigned i = num_operands; i < 4; i++) {
209b8e80941Smrg      assert(this->operands[i] == NULL);
210b8e80941Smrg   }
211b8e80941Smrg
212b8e80941Smrg   for (unsigned i = 0; i < num_operands; i++) {
213b8e80941Smrg      assert(this->operands[i] != NULL);
214b8e80941Smrg   }
215b8e80941Smrg#endif
216b8e80941Smrg}
217b8e80941Smrg
218b8e80941Smrgir_expression::ir_expression(int op, ir_rvalue *op0)
219b8e80941Smrg   : ir_rvalue(ir_type_expression)
220b8e80941Smrg{
221b8e80941Smrg   this->operation = ir_expression_operation(op);
222b8e80941Smrg   this->operands[0] = op0;
223b8e80941Smrg   this->operands[1] = NULL;
224b8e80941Smrg   this->operands[2] = NULL;
225b8e80941Smrg   this->operands[3] = NULL;
226b8e80941Smrg
227b8e80941Smrg   assert(op <= ir_last_unop);
228b8e80941Smrg   init_num_operands();
229b8e80941Smrg   assert(num_operands == 1);
230b8e80941Smrg   assert(this->operands[0]);
231b8e80941Smrg
232b8e80941Smrg   switch (this->operation) {
233b8e80941Smrg   case ir_unop_bit_not:
234b8e80941Smrg   case ir_unop_logic_not:
235b8e80941Smrg   case ir_unop_neg:
236b8e80941Smrg   case ir_unop_abs:
237b8e80941Smrg   case ir_unop_sign:
238b8e80941Smrg   case ir_unop_rcp:
239b8e80941Smrg   case ir_unop_rsq:
240b8e80941Smrg   case ir_unop_sqrt:
241b8e80941Smrg   case ir_unop_exp:
242b8e80941Smrg   case ir_unop_log:
243b8e80941Smrg   case ir_unop_exp2:
244b8e80941Smrg   case ir_unop_log2:
245b8e80941Smrg   case ir_unop_trunc:
246b8e80941Smrg   case ir_unop_ceil:
247b8e80941Smrg   case ir_unop_floor:
248b8e80941Smrg   case ir_unop_fract:
249b8e80941Smrg   case ir_unop_round_even:
250b8e80941Smrg   case ir_unop_sin:
251b8e80941Smrg   case ir_unop_cos:
252b8e80941Smrg   case ir_unop_dFdx:
253b8e80941Smrg   case ir_unop_dFdx_coarse:
254b8e80941Smrg   case ir_unop_dFdx_fine:
255b8e80941Smrg   case ir_unop_dFdy:
256b8e80941Smrg   case ir_unop_dFdy_coarse:
257b8e80941Smrg   case ir_unop_dFdy_fine:
258b8e80941Smrg   case ir_unop_bitfield_reverse:
259b8e80941Smrg   case ir_unop_interpolate_at_centroid:
260b8e80941Smrg   case ir_unop_saturate:
261b8e80941Smrg      this->type = op0->type;
262b8e80941Smrg      break;
263b8e80941Smrg
264b8e80941Smrg   case ir_unop_f2i:
265b8e80941Smrg   case ir_unop_b2i:
266b8e80941Smrg   case ir_unop_u2i:
267b8e80941Smrg   case ir_unop_d2i:
268b8e80941Smrg   case ir_unop_bitcast_f2i:
269b8e80941Smrg   case ir_unop_bit_count:
270b8e80941Smrg   case ir_unop_find_msb:
271b8e80941Smrg   case ir_unop_find_lsb:
272b8e80941Smrg   case ir_unop_subroutine_to_int:
273b8e80941Smrg   case ir_unop_i642i:
274b8e80941Smrg   case ir_unop_u642i:
275b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT,
276b8e80941Smrg					   op0->type->vector_elements, 1);
277b8e80941Smrg      break;
278b8e80941Smrg
279b8e80941Smrg   case ir_unop_b2f:
280b8e80941Smrg   case ir_unop_i2f:
281b8e80941Smrg   case ir_unop_u2f:
282b8e80941Smrg   case ir_unop_d2f:
283b8e80941Smrg   case ir_unop_bitcast_i2f:
284b8e80941Smrg   case ir_unop_bitcast_u2f:
285b8e80941Smrg   case ir_unop_i642f:
286b8e80941Smrg   case ir_unop_u642f:
287b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT,
288b8e80941Smrg					   op0->type->vector_elements, 1);
289b8e80941Smrg      break;
290b8e80941Smrg
291b8e80941Smrg   case ir_unop_f2b:
292b8e80941Smrg   case ir_unop_i2b:
293b8e80941Smrg   case ir_unop_d2b:
294b8e80941Smrg   case ir_unop_i642b:
295b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_BOOL,
296b8e80941Smrg					   op0->type->vector_elements, 1);
297b8e80941Smrg      break;
298b8e80941Smrg
299b8e80941Smrg   case ir_unop_f2d:
300b8e80941Smrg   case ir_unop_i2d:
301b8e80941Smrg   case ir_unop_u2d:
302b8e80941Smrg   case ir_unop_i642d:
303b8e80941Smrg   case ir_unop_u642d:
304b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE,
305b8e80941Smrg					   op0->type->vector_elements, 1);
306b8e80941Smrg      break;
307b8e80941Smrg
308b8e80941Smrg   case ir_unop_i2u:
309b8e80941Smrg   case ir_unop_f2u:
310b8e80941Smrg   case ir_unop_d2u:
311b8e80941Smrg   case ir_unop_bitcast_f2u:
312b8e80941Smrg   case ir_unop_i642u:
313b8e80941Smrg   case ir_unop_u642u:
314b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_UINT,
315b8e80941Smrg					   op0->type->vector_elements, 1);
316b8e80941Smrg      break;
317b8e80941Smrg
318b8e80941Smrg   case ir_unop_i2i64:
319b8e80941Smrg   case ir_unop_u2i64:
320b8e80941Smrg   case ir_unop_b2i64:
321b8e80941Smrg   case ir_unop_f2i64:
322b8e80941Smrg   case ir_unop_d2i64:
323b8e80941Smrg   case ir_unop_u642i64:
324b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT64,
325b8e80941Smrg					   op0->type->vector_elements, 1);
326b8e80941Smrg      break;
327b8e80941Smrg
328b8e80941Smrg   case ir_unop_i2u64:
329b8e80941Smrg   case ir_unop_u2u64:
330b8e80941Smrg   case ir_unop_f2u64:
331b8e80941Smrg   case ir_unop_d2u64:
332b8e80941Smrg   case ir_unop_i642u64:
333b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_UINT64,
334b8e80941Smrg					   op0->type->vector_elements, 1);
335b8e80941Smrg      break;
336b8e80941Smrg   case ir_unop_noise:
337b8e80941Smrg      this->type = glsl_type::float_type;
338b8e80941Smrg      break;
339b8e80941Smrg
340b8e80941Smrg   case ir_unop_unpack_double_2x32:
341b8e80941Smrg   case ir_unop_unpack_uint_2x32:
342b8e80941Smrg      this->type = glsl_type::uvec2_type;
343b8e80941Smrg      break;
344b8e80941Smrg
345b8e80941Smrg   case ir_unop_unpack_int_2x32:
346b8e80941Smrg      this->type = glsl_type::ivec2_type;
347b8e80941Smrg      break;
348b8e80941Smrg
349b8e80941Smrg   case ir_unop_pack_snorm_2x16:
350b8e80941Smrg   case ir_unop_pack_snorm_4x8:
351b8e80941Smrg   case ir_unop_pack_unorm_2x16:
352b8e80941Smrg   case ir_unop_pack_unorm_4x8:
353b8e80941Smrg   case ir_unop_pack_half_2x16:
354b8e80941Smrg      this->type = glsl_type::uint_type;
355b8e80941Smrg      break;
356b8e80941Smrg
357b8e80941Smrg   case ir_unop_pack_double_2x32:
358b8e80941Smrg      this->type = glsl_type::double_type;
359b8e80941Smrg      break;
360b8e80941Smrg
361b8e80941Smrg   case ir_unop_pack_int_2x32:
362b8e80941Smrg      this->type = glsl_type::int64_t_type;
363b8e80941Smrg      break;
364b8e80941Smrg
365b8e80941Smrg   case ir_unop_pack_uint_2x32:
366b8e80941Smrg      this->type = glsl_type::uint64_t_type;
367b8e80941Smrg      break;
368b8e80941Smrg
369b8e80941Smrg   case ir_unop_unpack_snorm_2x16:
370b8e80941Smrg   case ir_unop_unpack_unorm_2x16:
371b8e80941Smrg   case ir_unop_unpack_half_2x16:
372b8e80941Smrg      this->type = glsl_type::vec2_type;
373b8e80941Smrg      break;
374b8e80941Smrg
375b8e80941Smrg   case ir_unop_unpack_snorm_4x8:
376b8e80941Smrg   case ir_unop_unpack_unorm_4x8:
377b8e80941Smrg      this->type = glsl_type::vec4_type;
378b8e80941Smrg      break;
379b8e80941Smrg
380b8e80941Smrg   case ir_unop_unpack_sampler_2x32:
381b8e80941Smrg   case ir_unop_unpack_image_2x32:
382b8e80941Smrg      this->type = glsl_type::uvec2_type;
383b8e80941Smrg      break;
384b8e80941Smrg
385b8e80941Smrg   case ir_unop_pack_sampler_2x32:
386b8e80941Smrg   case ir_unop_pack_image_2x32:
387b8e80941Smrg      this->type = op0->type;
388b8e80941Smrg      break;
389b8e80941Smrg
390b8e80941Smrg   case ir_unop_frexp_sig:
391b8e80941Smrg      this->type = op0->type;
392b8e80941Smrg      break;
393b8e80941Smrg   case ir_unop_frexp_exp:
394b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT,
395b8e80941Smrg					   op0->type->vector_elements, 1);
396b8e80941Smrg      break;
397b8e80941Smrg
398b8e80941Smrg   case ir_unop_get_buffer_size:
399b8e80941Smrg   case ir_unop_ssbo_unsized_array_length:
400b8e80941Smrg      this->type = glsl_type::int_type;
401b8e80941Smrg      break;
402b8e80941Smrg
403b8e80941Smrg   case ir_unop_bitcast_i642d:
404b8e80941Smrg   case ir_unop_bitcast_u642d:
405b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE,
406b8e80941Smrg                                           op0->type->vector_elements, 1);
407b8e80941Smrg      break;
408b8e80941Smrg
409b8e80941Smrg   case ir_unop_bitcast_d2i64:
410b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_INT64,
411b8e80941Smrg                                           op0->type->vector_elements, 1);
412b8e80941Smrg      break;
413b8e80941Smrg   case ir_unop_bitcast_d2u64:
414b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_UINT64,
415b8e80941Smrg                                           op0->type->vector_elements, 1);
416b8e80941Smrg      break;
417b8e80941Smrg
418b8e80941Smrg   default:
419b8e80941Smrg      assert(!"not reached: missing automatic type setup for ir_expression");
420b8e80941Smrg      this->type = op0->type;
421b8e80941Smrg      break;
422b8e80941Smrg   }
423b8e80941Smrg}
424b8e80941Smrg
425b8e80941Smrgir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1)
426b8e80941Smrg   : ir_rvalue(ir_type_expression)
427b8e80941Smrg{
428b8e80941Smrg   this->operation = ir_expression_operation(op);
429b8e80941Smrg   this->operands[0] = op0;
430b8e80941Smrg   this->operands[1] = op1;
431b8e80941Smrg   this->operands[2] = NULL;
432b8e80941Smrg   this->operands[3] = NULL;
433b8e80941Smrg
434b8e80941Smrg   assert(op > ir_last_unop);
435b8e80941Smrg   init_num_operands();
436b8e80941Smrg   assert(num_operands == 2);
437b8e80941Smrg   for (unsigned i = 0; i < num_operands; i++) {
438b8e80941Smrg      assert(this->operands[i] != NULL);
439b8e80941Smrg   }
440b8e80941Smrg
441b8e80941Smrg   switch (this->operation) {
442b8e80941Smrg   case ir_binop_all_equal:
443b8e80941Smrg   case ir_binop_any_nequal:
444b8e80941Smrg      this->type = glsl_type::bool_type;
445b8e80941Smrg      break;
446b8e80941Smrg
447b8e80941Smrg   case ir_binop_add:
448b8e80941Smrg   case ir_binop_sub:
449b8e80941Smrg   case ir_binop_min:
450b8e80941Smrg   case ir_binop_max:
451b8e80941Smrg   case ir_binop_pow:
452b8e80941Smrg   case ir_binop_mul:
453b8e80941Smrg   case ir_binop_div:
454b8e80941Smrg   case ir_binop_mod:
455b8e80941Smrg      if (op0->type->is_scalar()) {
456b8e80941Smrg	 this->type = op1->type;
457b8e80941Smrg      } else if (op1->type->is_scalar()) {
458b8e80941Smrg	 this->type = op0->type;
459b8e80941Smrg      } else {
460b8e80941Smrg         if (this->operation == ir_binop_mul) {
461b8e80941Smrg            this->type = glsl_type::get_mul_type(op0->type, op1->type);
462b8e80941Smrg         } else {
463b8e80941Smrg            assert(op0->type == op1->type);
464b8e80941Smrg            this->type = op0->type;
465b8e80941Smrg         }
466b8e80941Smrg      }
467b8e80941Smrg      break;
468b8e80941Smrg
469b8e80941Smrg   case ir_binop_logic_and:
470b8e80941Smrg   case ir_binop_logic_xor:
471b8e80941Smrg   case ir_binop_logic_or:
472b8e80941Smrg   case ir_binop_bit_and:
473b8e80941Smrg   case ir_binop_bit_xor:
474b8e80941Smrg   case ir_binop_bit_or:
475b8e80941Smrg       assert(!op0->type->is_matrix());
476b8e80941Smrg       assert(!op1->type->is_matrix());
477b8e80941Smrg      if (op0->type->is_scalar()) {
478b8e80941Smrg         this->type = op1->type;
479b8e80941Smrg      } else if (op1->type->is_scalar()) {
480b8e80941Smrg         this->type = op0->type;
481b8e80941Smrg      } else {
482b8e80941Smrg          assert(op0->type->vector_elements == op1->type->vector_elements);
483b8e80941Smrg          this->type = op0->type;
484b8e80941Smrg      }
485b8e80941Smrg      break;
486b8e80941Smrg
487b8e80941Smrg   case ir_binop_equal:
488b8e80941Smrg   case ir_binop_nequal:
489b8e80941Smrg   case ir_binop_gequal:
490b8e80941Smrg   case ir_binop_less:
491b8e80941Smrg      assert(op0->type == op1->type);
492b8e80941Smrg      this->type = glsl_type::get_instance(GLSL_TYPE_BOOL,
493b8e80941Smrg					   op0->type->vector_elements, 1);
494b8e80941Smrg      break;
495b8e80941Smrg
496b8e80941Smrg   case ir_binop_dot:
497b8e80941Smrg      this->type = op0->type->get_base_type();
498b8e80941Smrg      break;
499b8e80941Smrg
500b8e80941Smrg   case ir_binop_imul_high:
501b8e80941Smrg   case ir_binop_carry:
502b8e80941Smrg   case ir_binop_borrow:
503b8e80941Smrg   case ir_binop_lshift:
504b8e80941Smrg   case ir_binop_rshift:
505b8e80941Smrg   case ir_binop_ldexp:
506b8e80941Smrg   case ir_binop_interpolate_at_offset:
507b8e80941Smrg   case ir_binop_interpolate_at_sample:
508b8e80941Smrg      this->type = op0->type;
509b8e80941Smrg      break;
510b8e80941Smrg
511b8e80941Smrg   case ir_binop_vector_extract:
512b8e80941Smrg      this->type = op0->type->get_scalar_type();
513b8e80941Smrg      break;
514b8e80941Smrg
515b8e80941Smrg   default:
516b8e80941Smrg      assert(!"not reached: missing automatic type setup for ir_expression");
517b8e80941Smrg      this->type = glsl_type::float_type;
518b8e80941Smrg   }
519b8e80941Smrg}
520b8e80941Smrg
521b8e80941Smrgir_expression::ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1,
522b8e80941Smrg                             ir_rvalue *op2)
523b8e80941Smrg   : ir_rvalue(ir_type_expression)
524b8e80941Smrg{
525b8e80941Smrg   this->operation = ir_expression_operation(op);
526b8e80941Smrg   this->operands[0] = op0;
527b8e80941Smrg   this->operands[1] = op1;
528b8e80941Smrg   this->operands[2] = op2;
529b8e80941Smrg   this->operands[3] = NULL;
530b8e80941Smrg
531b8e80941Smrg   assert(op > ir_last_binop && op <= ir_last_triop);
532b8e80941Smrg   init_num_operands();
533b8e80941Smrg   assert(num_operands == 3);
534b8e80941Smrg   for (unsigned i = 0; i < num_operands; i++) {
535b8e80941Smrg      assert(this->operands[i] != NULL);
536b8e80941Smrg   }
537b8e80941Smrg
538b8e80941Smrg   switch (this->operation) {
539b8e80941Smrg   case ir_triop_fma:
540b8e80941Smrg   case ir_triop_lrp:
541b8e80941Smrg   case ir_triop_bitfield_extract:
542b8e80941Smrg   case ir_triop_vector_insert:
543b8e80941Smrg      this->type = op0->type;
544b8e80941Smrg      break;
545b8e80941Smrg
546b8e80941Smrg   case ir_triop_csel:
547b8e80941Smrg      this->type = op1->type;
548b8e80941Smrg      break;
549b8e80941Smrg
550b8e80941Smrg   default:
551b8e80941Smrg      assert(!"not reached: missing automatic type setup for ir_expression");
552b8e80941Smrg      this->type = glsl_type::float_type;
553b8e80941Smrg   }
554b8e80941Smrg}
555b8e80941Smrg
556b8e80941Smrg/**
557b8e80941Smrg * This is only here for ir_reader to used for testing purposes. Please use
558b8e80941Smrg * the precomputed num_operands field if you need the number of operands.
559b8e80941Smrg */
560b8e80941Smrgunsigned
561b8e80941Smrgir_expression::get_num_operands(ir_expression_operation op)
562b8e80941Smrg{
563b8e80941Smrg   assert(op <= ir_last_opcode);
564b8e80941Smrg
565b8e80941Smrg   if (op <= ir_last_unop)
566b8e80941Smrg      return 1;
567b8e80941Smrg
568b8e80941Smrg   if (op <= ir_last_binop)
569b8e80941Smrg      return 2;
570b8e80941Smrg
571b8e80941Smrg   if (op <= ir_last_triop)
572b8e80941Smrg      return 3;
573b8e80941Smrg
574b8e80941Smrg   if (op <= ir_last_quadop)
575b8e80941Smrg      return 4;
576b8e80941Smrg
577b8e80941Smrg   unreachable("Could not calculate number of operands");
578b8e80941Smrg}
579b8e80941Smrg
580b8e80941Smrg#include "ir_expression_operation_strings.h"
581b8e80941Smrg
582b8e80941Smrgconst char*
583b8e80941Smrgdepth_layout_string(ir_depth_layout layout)
584b8e80941Smrg{
585b8e80941Smrg   switch(layout) {
586b8e80941Smrg   case ir_depth_layout_none:      return "";
587b8e80941Smrg   case ir_depth_layout_any:       return "depth_any";
588b8e80941Smrg   case ir_depth_layout_greater:   return "depth_greater";
589b8e80941Smrg   case ir_depth_layout_less:      return "depth_less";
590b8e80941Smrg   case ir_depth_layout_unchanged: return "depth_unchanged";
591b8e80941Smrg
592b8e80941Smrg   default:
593b8e80941Smrg      assert(0);
594b8e80941Smrg      return "";
595b8e80941Smrg   }
596b8e80941Smrg}
597b8e80941Smrg
598b8e80941Smrgir_expression_operation
599b8e80941Smrgir_expression::get_operator(const char *str)
600b8e80941Smrg{
601b8e80941Smrg   for (int op = 0; op <= int(ir_last_opcode); op++) {
602b8e80941Smrg      if (strcmp(str, ir_expression_operation_strings[op]) == 0)
603b8e80941Smrg	 return (ir_expression_operation) op;
604b8e80941Smrg   }
605b8e80941Smrg   return (ir_expression_operation) -1;
606b8e80941Smrg}
607b8e80941Smrg
608b8e80941Smrgir_variable *
609b8e80941Smrgir_expression::variable_referenced() const
610b8e80941Smrg{
611b8e80941Smrg   switch (operation) {
612b8e80941Smrg      case ir_binop_vector_extract:
613b8e80941Smrg      case ir_triop_vector_insert:
614b8e80941Smrg         /* We get these for things like a[0] where a is a vector type. In these
615b8e80941Smrg          * cases we want variable_referenced() to return the actual vector
616b8e80941Smrg          * variable this is wrapping.
617b8e80941Smrg          */
618b8e80941Smrg         return operands[0]->variable_referenced();
619b8e80941Smrg      default:
620b8e80941Smrg         return ir_rvalue::variable_referenced();
621b8e80941Smrg   }
622b8e80941Smrg}
623b8e80941Smrg
624b8e80941Smrgir_constant::ir_constant()
625b8e80941Smrg   : ir_rvalue(ir_type_constant)
626b8e80941Smrg{
627b8e80941Smrg   this->const_elements = NULL;
628b8e80941Smrg}
629b8e80941Smrg
630b8e80941Smrgir_constant::ir_constant(const struct glsl_type *type,
631b8e80941Smrg			 const ir_constant_data *data)
632b8e80941Smrg   : ir_rvalue(ir_type_constant)
633b8e80941Smrg{
634b8e80941Smrg   this->const_elements = NULL;
635b8e80941Smrg
636b8e80941Smrg   assert((type->base_type >= GLSL_TYPE_UINT)
637b8e80941Smrg	  && (type->base_type <= GLSL_TYPE_IMAGE));
638b8e80941Smrg
639b8e80941Smrg   this->type = type;
640b8e80941Smrg   memcpy(& this->value, data, sizeof(this->value));
641b8e80941Smrg}
642b8e80941Smrg
643b8e80941Smrgir_constant::ir_constant(float f, unsigned vector_elements)
644b8e80941Smrg   : ir_rvalue(ir_type_constant)
645b8e80941Smrg{
646b8e80941Smrg   assert(vector_elements <= 4);
647b8e80941Smrg   this->type = glsl_type::get_instance(GLSL_TYPE_FLOAT, vector_elements, 1);
648b8e80941Smrg   for (unsigned i = 0; i < vector_elements; i++) {
649b8e80941Smrg      this->value.f[i] = f;
650b8e80941Smrg   }
651b8e80941Smrg   for (unsigned i = vector_elements; i < 16; i++)  {
652b8e80941Smrg      this->value.f[i] = 0;
653b8e80941Smrg   }
654b8e80941Smrg}
655b8e80941Smrg
656b8e80941Smrgir_constant::ir_constant(double d, unsigned vector_elements)
657b8e80941Smrg   : ir_rvalue(ir_type_constant)
658b8e80941Smrg{
659b8e80941Smrg   assert(vector_elements <= 4);
660b8e80941Smrg   this->type = glsl_type::get_instance(GLSL_TYPE_DOUBLE, vector_elements, 1);
661b8e80941Smrg   for (unsigned i = 0; i < vector_elements; i++) {
662b8e80941Smrg      this->value.d[i] = d;
663b8e80941Smrg   }
664b8e80941Smrg   for (unsigned i = vector_elements; i < 16; i++)  {
665b8e80941Smrg      this->value.d[i] = 0.0;
666b8e80941Smrg   }
667b8e80941Smrg}
668b8e80941Smrg
669b8e80941Smrgir_constant::ir_constant(unsigned int u, unsigned vector_elements)
670b8e80941Smrg   : ir_rvalue(ir_type_constant)
671b8e80941Smrg{
672b8e80941Smrg   assert(vector_elements <= 4);
673b8e80941Smrg   this->type = glsl_type::get_instance(GLSL_TYPE_UINT, vector_elements, 1);
674b8e80941Smrg   for (unsigned i = 0; i < vector_elements; i++) {
675b8e80941Smrg      this->value.u[i] = u;
676b8e80941Smrg   }
677b8e80941Smrg   for (unsigned i = vector_elements; i < 16; i++) {
678b8e80941Smrg      this->value.u[i] = 0;
679b8e80941Smrg   }
680b8e80941Smrg}
681b8e80941Smrg
682b8e80941Smrgir_constant::ir_constant(int integer, unsigned vector_elements)
683b8e80941Smrg   : ir_rvalue(ir_type_constant)
684b8e80941Smrg{
685b8e80941Smrg   assert(vector_elements <= 4);
686b8e80941Smrg   this->type = glsl_type::get_instance(GLSL_TYPE_INT, vector_elements, 1);
687b8e80941Smrg   for (unsigned i = 0; i < vector_elements; i++) {
688b8e80941Smrg      this->value.i[i] = integer;
689b8e80941Smrg   }
690b8e80941Smrg   for (unsigned i = vector_elements; i < 16; i++) {
691b8e80941Smrg      this->value.i[i] = 0;
692b8e80941Smrg   }
693b8e80941Smrg}
694b8e80941Smrg
695b8e80941Smrgir_constant::ir_constant(uint64_t u64, unsigned vector_elements)
696b8e80941Smrg   : ir_rvalue(ir_type_constant)
697b8e80941Smrg{
698b8e80941Smrg   assert(vector_elements <= 4);
699b8e80941Smrg   this->type = glsl_type::get_instance(GLSL_TYPE_UINT64, vector_elements, 1);
700b8e80941Smrg   for (unsigned i = 0; i < vector_elements; i++) {
701b8e80941Smrg      this->value.u64[i] = u64;
702b8e80941Smrg   }
703b8e80941Smrg   for (unsigned i = vector_elements; i < 16; i++) {
704b8e80941Smrg      this->value.u64[i] = 0;
705b8e80941Smrg   }
706b8e80941Smrg}
707b8e80941Smrg
708b8e80941Smrgir_constant::ir_constant(int64_t int64, unsigned vector_elements)
709b8e80941Smrg   : ir_rvalue(ir_type_constant)
710b8e80941Smrg{
711b8e80941Smrg   assert(vector_elements <= 4);
712b8e80941Smrg   this->type = glsl_type::get_instance(GLSL_TYPE_INT64, vector_elements, 1);
713b8e80941Smrg   for (unsigned i = 0; i < vector_elements; i++) {
714b8e80941Smrg      this->value.i64[i] = int64;
715b8e80941Smrg   }
716b8e80941Smrg   for (unsigned i = vector_elements; i < 16; i++) {
717b8e80941Smrg      this->value.i64[i] = 0;
718b8e80941Smrg   }
719b8e80941Smrg}
720b8e80941Smrg
721b8e80941Smrgir_constant::ir_constant(bool b, unsigned vector_elements)
722b8e80941Smrg   : ir_rvalue(ir_type_constant)
723b8e80941Smrg{
724b8e80941Smrg   assert(vector_elements <= 4);
725b8e80941Smrg   this->type = glsl_type::get_instance(GLSL_TYPE_BOOL, vector_elements, 1);
726b8e80941Smrg   for (unsigned i = 0; i < vector_elements; i++) {
727b8e80941Smrg      this->value.b[i] = b;
728b8e80941Smrg   }
729b8e80941Smrg   for (unsigned i = vector_elements; i < 16; i++) {
730b8e80941Smrg      this->value.b[i] = false;
731b8e80941Smrg   }
732b8e80941Smrg}
733b8e80941Smrg
734b8e80941Smrgir_constant::ir_constant(const ir_constant *c, unsigned i)
735b8e80941Smrg   : ir_rvalue(ir_type_constant)
736b8e80941Smrg{
737b8e80941Smrg   this->const_elements = NULL;
738b8e80941Smrg   this->type = c->type->get_base_type();
739b8e80941Smrg
740b8e80941Smrg   switch (this->type->base_type) {
741b8e80941Smrg   case GLSL_TYPE_UINT:  this->value.u[0] = c->value.u[i]; break;
742b8e80941Smrg   case GLSL_TYPE_INT:   this->value.i[0] = c->value.i[i]; break;
743b8e80941Smrg   case GLSL_TYPE_FLOAT: this->value.f[0] = c->value.f[i]; break;
744b8e80941Smrg   case GLSL_TYPE_BOOL:  this->value.b[0] = c->value.b[i]; break;
745b8e80941Smrg   case GLSL_TYPE_DOUBLE: this->value.d[0] = c->value.d[i]; break;
746b8e80941Smrg   default:              assert(!"Should not get here."); break;
747b8e80941Smrg   }
748b8e80941Smrg}
749b8e80941Smrg
750b8e80941Smrgir_constant::ir_constant(const struct glsl_type *type, exec_list *value_list)
751b8e80941Smrg   : ir_rvalue(ir_type_constant)
752b8e80941Smrg{
753b8e80941Smrg   this->const_elements = NULL;
754b8e80941Smrg   this->type = type;
755b8e80941Smrg
756b8e80941Smrg   assert(type->is_scalar() || type->is_vector() || type->is_matrix()
757b8e80941Smrg	  || type->is_struct() || type->is_array());
758b8e80941Smrg
759b8e80941Smrg   /* If the constant is a record, the types of each of the entries in
760b8e80941Smrg    * value_list must be a 1-for-1 match with the structure components.  Each
761b8e80941Smrg    * entry must also be a constant.  Just move the nodes from the value_list
762b8e80941Smrg    * to the list in the ir_constant.
763b8e80941Smrg    */
764b8e80941Smrg   if (type->is_array() || type->is_struct()) {
765b8e80941Smrg      this->const_elements = ralloc_array(this, ir_constant *, type->length);
766b8e80941Smrg      unsigned i = 0;
767b8e80941Smrg      foreach_in_list(ir_constant, value, value_list) {
768b8e80941Smrg	 assert(value->as_constant() != NULL);
769b8e80941Smrg
770b8e80941Smrg	 this->const_elements[i++] = value;
771b8e80941Smrg      }
772b8e80941Smrg      return;
773b8e80941Smrg   }
774b8e80941Smrg
775b8e80941Smrg   for (unsigned i = 0; i < 16; i++) {
776b8e80941Smrg      this->value.u[i] = 0;
777b8e80941Smrg   }
778b8e80941Smrg
779b8e80941Smrg   ir_constant *value = (ir_constant *) (value_list->get_head_raw());
780b8e80941Smrg
781b8e80941Smrg   /* Constructors with exactly one scalar argument are special for vectors
782b8e80941Smrg    * and matrices.  For vectors, the scalar value is replicated to fill all
783b8e80941Smrg    * the components.  For matrices, the scalar fills the components of the
784b8e80941Smrg    * diagonal while the rest is filled with 0.
785b8e80941Smrg    */
786b8e80941Smrg   if (value->type->is_scalar() && value->next->is_tail_sentinel()) {
787b8e80941Smrg      if (type->is_matrix()) {
788b8e80941Smrg	 /* Matrix - fill diagonal (rest is already set to 0) */
789b8e80941Smrg         assert(type->is_float() || type->is_double());
790b8e80941Smrg         for (unsigned i = 0; i < type->matrix_columns; i++) {
791b8e80941Smrg            if (type->is_float())
792b8e80941Smrg               this->value.f[i * type->vector_elements + i] =
793b8e80941Smrg                  value->value.f[0];
794b8e80941Smrg            else
795b8e80941Smrg               this->value.d[i * type->vector_elements + i] =
796b8e80941Smrg                  value->value.d[0];
797b8e80941Smrg         }
798b8e80941Smrg      } else {
799b8e80941Smrg	 /* Vector or scalar - fill all components */
800b8e80941Smrg	 switch (type->base_type) {
801b8e80941Smrg	 case GLSL_TYPE_UINT:
802b8e80941Smrg	 case GLSL_TYPE_INT:
803b8e80941Smrg	    for (unsigned i = 0; i < type->components(); i++)
804b8e80941Smrg	       this->value.u[i] = value->value.u[0];
805b8e80941Smrg	    break;
806b8e80941Smrg	 case GLSL_TYPE_FLOAT:
807b8e80941Smrg	    for (unsigned i = 0; i < type->components(); i++)
808b8e80941Smrg	       this->value.f[i] = value->value.f[0];
809b8e80941Smrg	    break;
810b8e80941Smrg	 case GLSL_TYPE_DOUBLE:
811b8e80941Smrg	    for (unsigned i = 0; i < type->components(); i++)
812b8e80941Smrg	       this->value.d[i] = value->value.d[0];
813b8e80941Smrg	    break;
814b8e80941Smrg	 case GLSL_TYPE_UINT64:
815b8e80941Smrg	 case GLSL_TYPE_INT64:
816b8e80941Smrg	    for (unsigned i = 0; i < type->components(); i++)
817b8e80941Smrg	       this->value.u64[i] = value->value.u64[0];
818b8e80941Smrg	    break;
819b8e80941Smrg	 case GLSL_TYPE_BOOL:
820b8e80941Smrg	    for (unsigned i = 0; i < type->components(); i++)
821b8e80941Smrg	       this->value.b[i] = value->value.b[0];
822b8e80941Smrg	    break;
823b8e80941Smrg	 case GLSL_TYPE_SAMPLER:
824b8e80941Smrg	 case GLSL_TYPE_IMAGE:
825b8e80941Smrg	    this->value.u64[0] = value->value.u64[0];
826b8e80941Smrg	    break;
827b8e80941Smrg	 default:
828b8e80941Smrg	    assert(!"Should not get here.");
829b8e80941Smrg	    break;
830b8e80941Smrg	 }
831b8e80941Smrg      }
832b8e80941Smrg      return;
833b8e80941Smrg   }
834b8e80941Smrg
835b8e80941Smrg   if (type->is_matrix() && value->type->is_matrix()) {
836b8e80941Smrg      assert(value->next->is_tail_sentinel());
837b8e80941Smrg
838b8e80941Smrg      /* From section 5.4.2 of the GLSL 1.20 spec:
839b8e80941Smrg       * "If a matrix is constructed from a matrix, then each component
840b8e80941Smrg       *  (column i, row j) in the result that has a corresponding component
841b8e80941Smrg       *  (column i, row j) in the argument will be initialized from there."
842b8e80941Smrg       */
843b8e80941Smrg      unsigned cols = MIN2(type->matrix_columns, value->type->matrix_columns);
844b8e80941Smrg      unsigned rows = MIN2(type->vector_elements, value->type->vector_elements);
845b8e80941Smrg      for (unsigned i = 0; i < cols; i++) {
846b8e80941Smrg	 for (unsigned j = 0; j < rows; j++) {
847b8e80941Smrg	    const unsigned src = i * value->type->vector_elements + j;
848b8e80941Smrg	    const unsigned dst = i * type->vector_elements + j;
849b8e80941Smrg	    this->value.f[dst] = value->value.f[src];
850b8e80941Smrg	 }
851b8e80941Smrg      }
852b8e80941Smrg
853b8e80941Smrg      /* "All other components will be initialized to the identity matrix." */
854b8e80941Smrg      for (unsigned i = cols; i < type->matrix_columns; i++)
855b8e80941Smrg	 this->value.f[i * type->vector_elements + i] = 1.0;
856b8e80941Smrg
857b8e80941Smrg      return;
858b8e80941Smrg   }
859b8e80941Smrg
860b8e80941Smrg   /* Use each component from each entry in the value_list to initialize one
861b8e80941Smrg    * component of the constant being constructed.
862b8e80941Smrg    */
863b8e80941Smrg   unsigned i = 0;
864b8e80941Smrg   for (;;) {
865b8e80941Smrg      assert(value->as_constant() != NULL);
866b8e80941Smrg      assert(!value->is_tail_sentinel());
867b8e80941Smrg
868b8e80941Smrg      for (unsigned j = 0; j < value->type->components(); j++) {
869b8e80941Smrg	 switch (type->base_type) {
870b8e80941Smrg	 case GLSL_TYPE_UINT:
871b8e80941Smrg	    this->value.u[i] = value->get_uint_component(j);
872b8e80941Smrg	    break;
873b8e80941Smrg	 case GLSL_TYPE_INT:
874b8e80941Smrg	    this->value.i[i] = value->get_int_component(j);
875b8e80941Smrg	    break;
876b8e80941Smrg	 case GLSL_TYPE_FLOAT:
877b8e80941Smrg	    this->value.f[i] = value->get_float_component(j);
878b8e80941Smrg	    break;
879b8e80941Smrg	 case GLSL_TYPE_BOOL:
880b8e80941Smrg	    this->value.b[i] = value->get_bool_component(j);
881b8e80941Smrg	    break;
882b8e80941Smrg	 case GLSL_TYPE_DOUBLE:
883b8e80941Smrg	    this->value.d[i] = value->get_double_component(j);
884b8e80941Smrg	    break;
885b8e80941Smrg         case GLSL_TYPE_UINT64:
886b8e80941Smrg	    this->value.u64[i] = value->get_uint64_component(j);
887b8e80941Smrg	    break;
888b8e80941Smrg	 case GLSL_TYPE_INT64:
889b8e80941Smrg	    this->value.i64[i] = value->get_int64_component(j);
890b8e80941Smrg	    break;
891b8e80941Smrg	 default:
892b8e80941Smrg	    /* FINISHME: What to do?  Exceptions are not the answer.
893b8e80941Smrg	     */
894b8e80941Smrg	    break;
895b8e80941Smrg	 }
896b8e80941Smrg
897b8e80941Smrg	 i++;
898b8e80941Smrg	 if (i >= type->components())
899b8e80941Smrg	    break;
900b8e80941Smrg      }
901b8e80941Smrg
902b8e80941Smrg      if (i >= type->components())
903b8e80941Smrg	 break; /* avoid downcasting a list sentinel */
904b8e80941Smrg      value = (ir_constant *) value->next;
905b8e80941Smrg   }
906b8e80941Smrg}
907b8e80941Smrg
908b8e80941Smrgir_constant *
909b8e80941Smrgir_constant::zero(void *mem_ctx, const glsl_type *type)
910b8e80941Smrg{
911b8e80941Smrg   assert(type->is_scalar() || type->is_vector() || type->is_matrix()
912b8e80941Smrg	  || type->is_struct() || type->is_array());
913b8e80941Smrg
914b8e80941Smrg   ir_constant *c = new(mem_ctx) ir_constant;
915b8e80941Smrg   c->type = type;
916b8e80941Smrg   memset(&c->value, 0, sizeof(c->value));
917b8e80941Smrg
918b8e80941Smrg   if (type->is_array()) {
919b8e80941Smrg      c->const_elements = ralloc_array(c, ir_constant *, type->length);
920b8e80941Smrg
921b8e80941Smrg      for (unsigned i = 0; i < type->length; i++)
922b8e80941Smrg	 c->const_elements[i] = ir_constant::zero(c, type->fields.array);
923b8e80941Smrg   }
924b8e80941Smrg
925b8e80941Smrg   if (type->is_struct()) {
926b8e80941Smrg      c->const_elements = ralloc_array(c, ir_constant *, type->length);
927b8e80941Smrg
928b8e80941Smrg      for (unsigned i = 0; i < type->length; i++) {
929b8e80941Smrg         c->const_elements[i] =
930b8e80941Smrg            ir_constant::zero(mem_ctx, type->fields.structure[i].type);
931b8e80941Smrg      }
932b8e80941Smrg   }
933b8e80941Smrg
934b8e80941Smrg   return c;
935b8e80941Smrg}
936b8e80941Smrg
937b8e80941Smrgbool
938b8e80941Smrgir_constant::get_bool_component(unsigned i) const
939b8e80941Smrg{
940b8e80941Smrg   switch (this->type->base_type) {
941b8e80941Smrg   case GLSL_TYPE_UINT:  return this->value.u[i] != 0;
942b8e80941Smrg   case GLSL_TYPE_INT:   return this->value.i[i] != 0;
943b8e80941Smrg   case GLSL_TYPE_FLOAT: return ((int)this->value.f[i]) != 0;
944b8e80941Smrg   case GLSL_TYPE_BOOL:  return this->value.b[i];
945b8e80941Smrg   case GLSL_TYPE_DOUBLE: return this->value.d[i] != 0.0;
946b8e80941Smrg   case GLSL_TYPE_SAMPLER:
947b8e80941Smrg   case GLSL_TYPE_IMAGE:
948b8e80941Smrg   case GLSL_TYPE_UINT64: return this->value.u64[i] != 0;
949b8e80941Smrg   case GLSL_TYPE_INT64:  return this->value.i64[i] != 0;
950b8e80941Smrg   default:              assert(!"Should not get here."); break;
951b8e80941Smrg   }
952b8e80941Smrg
953b8e80941Smrg   /* Must return something to make the compiler happy.  This is clearly an
954b8e80941Smrg    * error case.
955b8e80941Smrg    */
956b8e80941Smrg   return false;
957b8e80941Smrg}
958b8e80941Smrg
959b8e80941Smrgfloat
960b8e80941Smrgir_constant::get_float_component(unsigned i) const
961b8e80941Smrg{
962b8e80941Smrg   switch (this->type->base_type) {
963b8e80941Smrg   case GLSL_TYPE_UINT:  return (float) this->value.u[i];
964b8e80941Smrg   case GLSL_TYPE_INT:   return (float) this->value.i[i];
965b8e80941Smrg   case GLSL_TYPE_FLOAT: return this->value.f[i];
966b8e80941Smrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0f : 0.0f;
967b8e80941Smrg   case GLSL_TYPE_DOUBLE: return (float) this->value.d[i];
968b8e80941Smrg   case GLSL_TYPE_SAMPLER:
969b8e80941Smrg   case GLSL_TYPE_IMAGE:
970b8e80941Smrg   case GLSL_TYPE_UINT64: return (float) this->value.u64[i];
971b8e80941Smrg   case GLSL_TYPE_INT64:  return (float) this->value.i64[i];
972b8e80941Smrg   default:              assert(!"Should not get here."); break;
973b8e80941Smrg   }
974b8e80941Smrg
975b8e80941Smrg   /* Must return something to make the compiler happy.  This is clearly an
976b8e80941Smrg    * error case.
977b8e80941Smrg    */
978b8e80941Smrg   return 0.0;
979b8e80941Smrg}
980b8e80941Smrg
981b8e80941Smrgdouble
982b8e80941Smrgir_constant::get_double_component(unsigned i) const
983b8e80941Smrg{
984b8e80941Smrg   switch (this->type->base_type) {
985b8e80941Smrg   case GLSL_TYPE_UINT:  return (double) this->value.u[i];
986b8e80941Smrg   case GLSL_TYPE_INT:   return (double) this->value.i[i];
987b8e80941Smrg   case GLSL_TYPE_FLOAT: return (double) this->value.f[i];
988b8e80941Smrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1.0 : 0.0;
989b8e80941Smrg   case GLSL_TYPE_DOUBLE: return this->value.d[i];
990b8e80941Smrg   case GLSL_TYPE_SAMPLER:
991b8e80941Smrg   case GLSL_TYPE_IMAGE:
992b8e80941Smrg   case GLSL_TYPE_UINT64: return (double) this->value.u64[i];
993b8e80941Smrg   case GLSL_TYPE_INT64:  return (double) this->value.i64[i];
994b8e80941Smrg   default:              assert(!"Should not get here."); break;
995b8e80941Smrg   }
996b8e80941Smrg
997b8e80941Smrg   /* Must return something to make the compiler happy.  This is clearly an
998b8e80941Smrg    * error case.
999b8e80941Smrg    */
1000b8e80941Smrg   return 0.0;
1001b8e80941Smrg}
1002b8e80941Smrg
1003b8e80941Smrgint
1004b8e80941Smrgir_constant::get_int_component(unsigned i) const
1005b8e80941Smrg{
1006b8e80941Smrg   switch (this->type->base_type) {
1007b8e80941Smrg   case GLSL_TYPE_UINT:  return this->value.u[i];
1008b8e80941Smrg   case GLSL_TYPE_INT:   return this->value.i[i];
1009b8e80941Smrg   case GLSL_TYPE_FLOAT: return (int) this->value.f[i];
1010b8e80941Smrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
1011b8e80941Smrg   case GLSL_TYPE_DOUBLE: return (int) this->value.d[i];
1012b8e80941Smrg   case GLSL_TYPE_SAMPLER:
1013b8e80941Smrg   case GLSL_TYPE_IMAGE:
1014b8e80941Smrg   case GLSL_TYPE_UINT64: return (int) this->value.u64[i];
1015b8e80941Smrg   case GLSL_TYPE_INT64:  return (int) this->value.i64[i];
1016b8e80941Smrg   default:              assert(!"Should not get here."); break;
1017b8e80941Smrg   }
1018b8e80941Smrg
1019b8e80941Smrg   /* Must return something to make the compiler happy.  This is clearly an
1020b8e80941Smrg    * error case.
1021b8e80941Smrg    */
1022b8e80941Smrg   return 0;
1023b8e80941Smrg}
1024b8e80941Smrg
1025b8e80941Smrgunsigned
1026b8e80941Smrgir_constant::get_uint_component(unsigned i) const
1027b8e80941Smrg{
1028b8e80941Smrg   switch (this->type->base_type) {
1029b8e80941Smrg   case GLSL_TYPE_UINT:  return this->value.u[i];
1030b8e80941Smrg   case GLSL_TYPE_INT:   return this->value.i[i];
1031b8e80941Smrg   case GLSL_TYPE_FLOAT: return (unsigned) this->value.f[i];
1032b8e80941Smrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
1033b8e80941Smrg   case GLSL_TYPE_DOUBLE: return (unsigned) this->value.d[i];
1034b8e80941Smrg   case GLSL_TYPE_SAMPLER:
1035b8e80941Smrg   case GLSL_TYPE_IMAGE:
1036b8e80941Smrg   case GLSL_TYPE_UINT64: return (unsigned) this->value.u64[i];
1037b8e80941Smrg   case GLSL_TYPE_INT64:  return (unsigned) this->value.i64[i];
1038b8e80941Smrg   default:              assert(!"Should not get here."); break;
1039b8e80941Smrg   }
1040b8e80941Smrg
1041b8e80941Smrg   /* Must return something to make the compiler happy.  This is clearly an
1042b8e80941Smrg    * error case.
1043b8e80941Smrg    */
1044b8e80941Smrg   return 0;
1045b8e80941Smrg}
1046b8e80941Smrg
1047b8e80941Smrgint64_t
1048b8e80941Smrgir_constant::get_int64_component(unsigned i) const
1049b8e80941Smrg{
1050b8e80941Smrg   switch (this->type->base_type) {
1051b8e80941Smrg   case GLSL_TYPE_UINT:  return this->value.u[i];
1052b8e80941Smrg   case GLSL_TYPE_INT:   return this->value.i[i];
1053b8e80941Smrg   case GLSL_TYPE_FLOAT: return (int64_t) this->value.f[i];
1054b8e80941Smrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
1055b8e80941Smrg   case GLSL_TYPE_DOUBLE: return (int64_t) this->value.d[i];
1056b8e80941Smrg   case GLSL_TYPE_SAMPLER:
1057b8e80941Smrg   case GLSL_TYPE_IMAGE:
1058b8e80941Smrg   case GLSL_TYPE_UINT64: return (int64_t) this->value.u64[i];
1059b8e80941Smrg   case GLSL_TYPE_INT64:  return this->value.i64[i];
1060b8e80941Smrg   default:              assert(!"Should not get here."); break;
1061b8e80941Smrg   }
1062b8e80941Smrg
1063b8e80941Smrg   /* Must return something to make the compiler happy.  This is clearly an
1064b8e80941Smrg    * error case.
1065b8e80941Smrg    */
1066b8e80941Smrg   return 0;
1067b8e80941Smrg}
1068b8e80941Smrg
1069b8e80941Smrguint64_t
1070b8e80941Smrgir_constant::get_uint64_component(unsigned i) const
1071b8e80941Smrg{
1072b8e80941Smrg   switch (this->type->base_type) {
1073b8e80941Smrg   case GLSL_TYPE_UINT:  return this->value.u[i];
1074b8e80941Smrg   case GLSL_TYPE_INT:   return this->value.i[i];
1075b8e80941Smrg   case GLSL_TYPE_FLOAT: return (uint64_t) this->value.f[i];
1076b8e80941Smrg   case GLSL_TYPE_BOOL:  return this->value.b[i] ? 1 : 0;
1077b8e80941Smrg   case GLSL_TYPE_DOUBLE: return (uint64_t) this->value.d[i];
1078b8e80941Smrg   case GLSL_TYPE_SAMPLER:
1079b8e80941Smrg   case GLSL_TYPE_IMAGE:
1080b8e80941Smrg   case GLSL_TYPE_UINT64: return this->value.u64[i];
1081b8e80941Smrg   case GLSL_TYPE_INT64:  return (uint64_t) this->value.i64[i];
1082b8e80941Smrg   default:              assert(!"Should not get here."); break;
1083b8e80941Smrg   }
1084b8e80941Smrg
1085b8e80941Smrg   /* Must return something to make the compiler happy.  This is clearly an
1086b8e80941Smrg    * error case.
1087b8e80941Smrg    */
1088b8e80941Smrg   return 0;
1089b8e80941Smrg}
1090b8e80941Smrg
1091b8e80941Smrgir_constant *
1092b8e80941Smrgir_constant::get_array_element(unsigned i) const
1093b8e80941Smrg{
1094b8e80941Smrg   assert(this->type->is_array());
1095b8e80941Smrg
1096b8e80941Smrg   /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec:
1097b8e80941Smrg    *
1098b8e80941Smrg    *     "Behavior is undefined if a shader subscripts an array with an index
1099b8e80941Smrg    *     less than 0 or greater than or equal to the size the array was
1100b8e80941Smrg    *     declared with."
1101b8e80941Smrg    *
1102b8e80941Smrg    * Most out-of-bounds accesses are removed before things could get this far.
1103b8e80941Smrg    * There are cases where non-constant array index values can get constant
1104b8e80941Smrg    * folded.
1105b8e80941Smrg    */
1106b8e80941Smrg   if (int(i) < 0)
1107b8e80941Smrg      i = 0;
1108b8e80941Smrg   else if (i >= this->type->length)
1109b8e80941Smrg      i = this->type->length - 1;
1110b8e80941Smrg
1111b8e80941Smrg   return const_elements[i];
1112b8e80941Smrg}
1113b8e80941Smrg
1114b8e80941Smrgir_constant *
1115b8e80941Smrgir_constant::get_record_field(int idx)
1116b8e80941Smrg{
1117b8e80941Smrg   assert(this->type->is_struct());
1118b8e80941Smrg   assert(idx >= 0 && (unsigned) idx < this->type->length);
1119b8e80941Smrg
1120b8e80941Smrg   return const_elements[idx];
1121b8e80941Smrg}
1122b8e80941Smrg
1123b8e80941Smrgvoid
1124b8e80941Smrgir_constant::copy_offset(ir_constant *src, int offset)
1125b8e80941Smrg{
1126b8e80941Smrg   switch (this->type->base_type) {
1127b8e80941Smrg   case GLSL_TYPE_UINT:
1128b8e80941Smrg   case GLSL_TYPE_INT:
1129b8e80941Smrg   case GLSL_TYPE_FLOAT:
1130b8e80941Smrg   case GLSL_TYPE_DOUBLE:
1131b8e80941Smrg   case GLSL_TYPE_SAMPLER:
1132b8e80941Smrg   case GLSL_TYPE_IMAGE:
1133b8e80941Smrg   case GLSL_TYPE_UINT64:
1134b8e80941Smrg   case GLSL_TYPE_INT64:
1135b8e80941Smrg   case GLSL_TYPE_BOOL: {
1136b8e80941Smrg      unsigned int size = src->type->components();
1137b8e80941Smrg      assert (size <= this->type->components() - offset);
1138b8e80941Smrg      for (unsigned int i=0; i<size; i++) {
1139b8e80941Smrg	 switch (this->type->base_type) {
1140b8e80941Smrg	 case GLSL_TYPE_UINT:
1141b8e80941Smrg	    value.u[i+offset] = src->get_uint_component(i);
1142b8e80941Smrg	    break;
1143b8e80941Smrg	 case GLSL_TYPE_INT:
1144b8e80941Smrg	    value.i[i+offset] = src->get_int_component(i);
1145b8e80941Smrg	    break;
1146b8e80941Smrg	 case GLSL_TYPE_FLOAT:
1147b8e80941Smrg	    value.f[i+offset] = src->get_float_component(i);
1148b8e80941Smrg	    break;
1149b8e80941Smrg	 case GLSL_TYPE_BOOL:
1150b8e80941Smrg	    value.b[i+offset] = src->get_bool_component(i);
1151b8e80941Smrg	    break;
1152b8e80941Smrg	 case GLSL_TYPE_DOUBLE:
1153b8e80941Smrg	    value.d[i+offset] = src->get_double_component(i);
1154b8e80941Smrg	    break;
1155b8e80941Smrg	 case GLSL_TYPE_SAMPLER:
1156b8e80941Smrg	 case GLSL_TYPE_IMAGE:
1157b8e80941Smrg	 case GLSL_TYPE_UINT64:
1158b8e80941Smrg	    value.u64[i+offset] = src->get_uint64_component(i);
1159b8e80941Smrg	    break;
1160b8e80941Smrg	 case GLSL_TYPE_INT64:
1161b8e80941Smrg	    value.i64[i+offset] = src->get_int64_component(i);
1162b8e80941Smrg	    break;
1163b8e80941Smrg	 default: // Shut up the compiler
1164b8e80941Smrg	    break;
1165b8e80941Smrg	 }
1166b8e80941Smrg      }
1167b8e80941Smrg      break;
1168b8e80941Smrg   }
1169b8e80941Smrg
1170b8e80941Smrg   case GLSL_TYPE_STRUCT:
1171b8e80941Smrg   case GLSL_TYPE_ARRAY: {
1172b8e80941Smrg      assert (src->type == this->type);
1173b8e80941Smrg      for (unsigned i = 0; i < this->type->length; i++) {
1174b8e80941Smrg	 this->const_elements[i] = src->const_elements[i]->clone(this, NULL);
1175b8e80941Smrg      }
1176b8e80941Smrg      break;
1177b8e80941Smrg   }
1178b8e80941Smrg
1179b8e80941Smrg   default:
1180b8e80941Smrg      assert(!"Should not get here.");
1181b8e80941Smrg      break;
1182b8e80941Smrg   }
1183b8e80941Smrg}
1184b8e80941Smrg
1185b8e80941Smrgvoid
1186b8e80941Smrgir_constant::copy_masked_offset(ir_constant *src, int offset, unsigned int mask)
1187b8e80941Smrg{
1188b8e80941Smrg   assert (!type->is_array() && !type->is_struct());
1189b8e80941Smrg
1190b8e80941Smrg   if (!type->is_vector() && !type->is_matrix()) {
1191b8e80941Smrg      offset = 0;
1192b8e80941Smrg      mask = 1;
1193b8e80941Smrg   }
1194b8e80941Smrg
1195b8e80941Smrg   int id = 0;
1196b8e80941Smrg   for (int i=0; i<4; i++) {
1197b8e80941Smrg      if (mask & (1 << i)) {
1198b8e80941Smrg	 switch (this->type->base_type) {
1199b8e80941Smrg	 case GLSL_TYPE_UINT:
1200b8e80941Smrg	    value.u[i+offset] = src->get_uint_component(id++);
1201b8e80941Smrg	    break;
1202b8e80941Smrg	 case GLSL_TYPE_INT:
1203b8e80941Smrg	    value.i[i+offset] = src->get_int_component(id++);
1204b8e80941Smrg	    break;
1205b8e80941Smrg	 case GLSL_TYPE_FLOAT:
1206b8e80941Smrg	    value.f[i+offset] = src->get_float_component(id++);
1207b8e80941Smrg	    break;
1208b8e80941Smrg	 case GLSL_TYPE_BOOL:
1209b8e80941Smrg	    value.b[i+offset] = src->get_bool_component(id++);
1210b8e80941Smrg	    break;
1211b8e80941Smrg	 case GLSL_TYPE_DOUBLE:
1212b8e80941Smrg	    value.d[i+offset] = src->get_double_component(id++);
1213b8e80941Smrg	    break;
1214b8e80941Smrg	 case GLSL_TYPE_SAMPLER:
1215b8e80941Smrg	 case GLSL_TYPE_IMAGE:
1216b8e80941Smrg	 case GLSL_TYPE_UINT64:
1217b8e80941Smrg	    value.u64[i+offset] = src->get_uint64_component(id++);
1218b8e80941Smrg	    break;
1219b8e80941Smrg	 case GLSL_TYPE_INT64:
1220b8e80941Smrg	    value.i64[i+offset] = src->get_int64_component(id++);
1221b8e80941Smrg	    break;
1222b8e80941Smrg	 default:
1223b8e80941Smrg	    assert(!"Should not get here.");
1224b8e80941Smrg	    return;
1225b8e80941Smrg	 }
1226b8e80941Smrg      }
1227b8e80941Smrg   }
1228b8e80941Smrg}
1229b8e80941Smrg
1230b8e80941Smrgbool
1231b8e80941Smrgir_constant::has_value(const ir_constant *c) const
1232b8e80941Smrg{
1233b8e80941Smrg   if (this->type != c->type)
1234b8e80941Smrg      return false;
1235b8e80941Smrg
1236b8e80941Smrg   if (this->type->is_array() || this->type->is_struct()) {
1237b8e80941Smrg      for (unsigned i = 0; i < this->type->length; i++) {
1238b8e80941Smrg	 if (!this->const_elements[i]->has_value(c->const_elements[i]))
1239b8e80941Smrg	    return false;
1240b8e80941Smrg      }
1241b8e80941Smrg      return true;
1242b8e80941Smrg   }
1243b8e80941Smrg
1244b8e80941Smrg   for (unsigned i = 0; i < this->type->components(); i++) {
1245b8e80941Smrg      switch (this->type->base_type) {
1246b8e80941Smrg      case GLSL_TYPE_UINT:
1247b8e80941Smrg	 if (this->value.u[i] != c->value.u[i])
1248b8e80941Smrg	    return false;
1249b8e80941Smrg	 break;
1250b8e80941Smrg      case GLSL_TYPE_INT:
1251b8e80941Smrg	 if (this->value.i[i] != c->value.i[i])
1252b8e80941Smrg	    return false;
1253b8e80941Smrg	 break;
1254b8e80941Smrg      case GLSL_TYPE_FLOAT:
1255b8e80941Smrg	 if (this->value.f[i] != c->value.f[i])
1256b8e80941Smrg	    return false;
1257b8e80941Smrg	 break;
1258b8e80941Smrg      case GLSL_TYPE_BOOL:
1259b8e80941Smrg	 if (this->value.b[i] != c->value.b[i])
1260b8e80941Smrg	    return false;
1261b8e80941Smrg	 break;
1262b8e80941Smrg      case GLSL_TYPE_DOUBLE:
1263b8e80941Smrg	 if (this->value.d[i] != c->value.d[i])
1264b8e80941Smrg	    return false;
1265b8e80941Smrg	 break;
1266b8e80941Smrg      case GLSL_TYPE_SAMPLER:
1267b8e80941Smrg      case GLSL_TYPE_IMAGE:
1268b8e80941Smrg      case GLSL_TYPE_UINT64:
1269b8e80941Smrg	 if (this->value.u64[i] != c->value.u64[i])
1270b8e80941Smrg	    return false;
1271b8e80941Smrg	 break;
1272b8e80941Smrg      case GLSL_TYPE_INT64:
1273b8e80941Smrg	 if (this->value.i64[i] != c->value.i64[i])
1274b8e80941Smrg	    return false;
1275b8e80941Smrg	 break;
1276b8e80941Smrg      default:
1277b8e80941Smrg	 assert(!"Should not get here.");
1278b8e80941Smrg	 return false;
1279b8e80941Smrg      }
1280b8e80941Smrg   }
1281b8e80941Smrg
1282b8e80941Smrg   return true;
1283b8e80941Smrg}
1284b8e80941Smrg
1285b8e80941Smrgbool
1286b8e80941Smrgir_constant::is_value(float f, int i) const
1287b8e80941Smrg{
1288b8e80941Smrg   if (!this->type->is_scalar() && !this->type->is_vector())
1289b8e80941Smrg      return false;
1290b8e80941Smrg
1291b8e80941Smrg   /* Only accept boolean values for 0/1. */
1292b8e80941Smrg   if (int(bool(i)) != i && this->type->is_boolean())
1293b8e80941Smrg      return false;
1294b8e80941Smrg
1295b8e80941Smrg   for (unsigned c = 0; c < this->type->vector_elements; c++) {
1296b8e80941Smrg      switch (this->type->base_type) {
1297b8e80941Smrg      case GLSL_TYPE_FLOAT:
1298b8e80941Smrg	 if (this->value.f[c] != f)
1299b8e80941Smrg	    return false;
1300b8e80941Smrg	 break;
1301b8e80941Smrg      case GLSL_TYPE_INT:
1302b8e80941Smrg	 if (this->value.i[c] != i)
1303b8e80941Smrg	    return false;
1304b8e80941Smrg	 break;
1305b8e80941Smrg      case GLSL_TYPE_UINT:
1306b8e80941Smrg	 if (this->value.u[c] != unsigned(i))
1307b8e80941Smrg	    return false;
1308b8e80941Smrg	 break;
1309b8e80941Smrg      case GLSL_TYPE_BOOL:
1310b8e80941Smrg	 if (this->value.b[c] != bool(i))
1311b8e80941Smrg	    return false;
1312b8e80941Smrg	 break;
1313b8e80941Smrg      case GLSL_TYPE_DOUBLE:
1314b8e80941Smrg	 if (this->value.d[c] != double(f))
1315b8e80941Smrg	    return false;
1316b8e80941Smrg	 break;
1317b8e80941Smrg      case GLSL_TYPE_SAMPLER:
1318b8e80941Smrg      case GLSL_TYPE_IMAGE:
1319b8e80941Smrg      case GLSL_TYPE_UINT64:
1320b8e80941Smrg	 if (this->value.u64[c] != uint64_t(i))
1321b8e80941Smrg	    return false;
1322b8e80941Smrg	 break;
1323b8e80941Smrg      case GLSL_TYPE_INT64:
1324b8e80941Smrg	 if (this->value.i64[c] != i)
1325b8e80941Smrg	    return false;
1326b8e80941Smrg	 break;
1327b8e80941Smrg      default:
1328b8e80941Smrg	 /* The only other base types are structures, arrays, and samplers.
1329b8e80941Smrg	  * Samplers cannot be constants, and the others should have been
1330b8e80941Smrg	  * filtered out above.
1331b8e80941Smrg	  */
1332b8e80941Smrg	 assert(!"Should not get here.");
1333b8e80941Smrg	 return false;
1334b8e80941Smrg      }
1335b8e80941Smrg   }
1336b8e80941Smrg
1337b8e80941Smrg   return true;
1338b8e80941Smrg}
1339b8e80941Smrg
1340b8e80941Smrgbool
1341b8e80941Smrgir_constant::is_zero() const
1342b8e80941Smrg{
1343b8e80941Smrg   return is_value(0.0, 0);
1344b8e80941Smrg}
1345b8e80941Smrg
1346b8e80941Smrgbool
1347b8e80941Smrgir_constant::is_one() const
1348b8e80941Smrg{
1349b8e80941Smrg   return is_value(1.0, 1);
1350b8e80941Smrg}
1351b8e80941Smrg
1352b8e80941Smrgbool
1353b8e80941Smrgir_constant::is_negative_one() const
1354b8e80941Smrg{
1355b8e80941Smrg   return is_value(-1.0, -1);
1356b8e80941Smrg}
1357b8e80941Smrg
1358b8e80941Smrgbool
1359b8e80941Smrgir_constant::is_uint16_constant() const
1360b8e80941Smrg{
1361b8e80941Smrg   if (!type->is_integer())
1362b8e80941Smrg      return false;
1363b8e80941Smrg
1364b8e80941Smrg   return value.u[0] < (1 << 16);
1365b8e80941Smrg}
1366b8e80941Smrg
1367b8e80941Smrgir_loop::ir_loop()
1368b8e80941Smrg   : ir_instruction(ir_type_loop)
1369b8e80941Smrg{
1370b8e80941Smrg}
1371b8e80941Smrg
1372b8e80941Smrg
1373b8e80941Smrgir_dereference_variable::ir_dereference_variable(ir_variable *var)
1374b8e80941Smrg   : ir_dereference(ir_type_dereference_variable)
1375b8e80941Smrg{
1376b8e80941Smrg   assert(var != NULL);
1377b8e80941Smrg
1378b8e80941Smrg   this->var = var;
1379b8e80941Smrg   this->type = var->type;
1380b8e80941Smrg}
1381b8e80941Smrg
1382b8e80941Smrg
1383b8e80941Smrgir_dereference_array::ir_dereference_array(ir_rvalue *value,
1384b8e80941Smrg					   ir_rvalue *array_index)
1385b8e80941Smrg   : ir_dereference(ir_type_dereference_array)
1386b8e80941Smrg{
1387b8e80941Smrg   this->array_index = array_index;
1388b8e80941Smrg   this->set_array(value);
1389b8e80941Smrg}
1390b8e80941Smrg
1391b8e80941Smrg
1392b8e80941Smrgir_dereference_array::ir_dereference_array(ir_variable *var,
1393b8e80941Smrg					   ir_rvalue *array_index)
1394b8e80941Smrg   : ir_dereference(ir_type_dereference_array)
1395b8e80941Smrg{
1396b8e80941Smrg   void *ctx = ralloc_parent(var);
1397b8e80941Smrg
1398b8e80941Smrg   this->array_index = array_index;
1399b8e80941Smrg   this->set_array(new(ctx) ir_dereference_variable(var));
1400b8e80941Smrg}
1401b8e80941Smrg
1402b8e80941Smrg
1403b8e80941Smrgvoid
1404b8e80941Smrgir_dereference_array::set_array(ir_rvalue *value)
1405b8e80941Smrg{
1406b8e80941Smrg   assert(value != NULL);
1407b8e80941Smrg
1408b8e80941Smrg   this->array = value;
1409b8e80941Smrg
1410b8e80941Smrg   const glsl_type *const vt = this->array->type;
1411b8e80941Smrg
1412b8e80941Smrg   if (vt->is_array()) {
1413b8e80941Smrg      type = vt->fields.array;
1414b8e80941Smrg   } else if (vt->is_matrix()) {
1415b8e80941Smrg      type = vt->column_type();
1416b8e80941Smrg   } else if (vt->is_vector()) {
1417b8e80941Smrg      type = vt->get_base_type();
1418b8e80941Smrg   }
1419b8e80941Smrg}
1420b8e80941Smrg
1421b8e80941Smrg
1422b8e80941Smrgir_dereference_record::ir_dereference_record(ir_rvalue *value,
1423b8e80941Smrg					     const char *field)
1424b8e80941Smrg   : ir_dereference(ir_type_dereference_record)
1425b8e80941Smrg{
1426b8e80941Smrg   assert(value != NULL);
1427b8e80941Smrg
1428b8e80941Smrg   this->record = value;
1429b8e80941Smrg   this->type = this->record->type->field_type(field);
1430b8e80941Smrg   this->field_idx = this->record->type->field_index(field);
1431b8e80941Smrg}
1432b8e80941Smrg
1433b8e80941Smrg
1434b8e80941Smrgir_dereference_record::ir_dereference_record(ir_variable *var,
1435b8e80941Smrg					     const char *field)
1436b8e80941Smrg   : ir_dereference(ir_type_dereference_record)
1437b8e80941Smrg{
1438b8e80941Smrg   void *ctx = ralloc_parent(var);
1439b8e80941Smrg
1440b8e80941Smrg   this->record = new(ctx) ir_dereference_variable(var);
1441b8e80941Smrg   this->type = this->record->type->field_type(field);
1442b8e80941Smrg   this->field_idx = this->record->type->field_index(field);
1443b8e80941Smrg}
1444b8e80941Smrg
1445b8e80941Smrgbool
1446b8e80941Smrgir_dereference::is_lvalue(const struct _mesa_glsl_parse_state *state) const
1447b8e80941Smrg{
1448b8e80941Smrg   ir_variable *var = this->variable_referenced();
1449b8e80941Smrg
1450b8e80941Smrg   /* Every l-value derference chain eventually ends in a variable.
1451b8e80941Smrg    */
1452b8e80941Smrg   if ((var == NULL) || var->data.read_only)
1453b8e80941Smrg      return false;
1454b8e80941Smrg
1455b8e80941Smrg   /* From section 4.1.7 of the ARB_bindless_texture spec:
1456b8e80941Smrg    *
1457b8e80941Smrg    * "Samplers can be used as l-values, so can be assigned into and used as
1458b8e80941Smrg    *  "out" and "inout" function parameters."
1459b8e80941Smrg    *
1460b8e80941Smrg    * From section 4.1.X of the ARB_bindless_texture spec:
1461b8e80941Smrg    *
1462b8e80941Smrg    * "Images can be used as l-values, so can be assigned into and used as
1463b8e80941Smrg    *  "out" and "inout" function parameters."
1464b8e80941Smrg    */
1465b8e80941Smrg   if ((!state || state->has_bindless()) &&
1466b8e80941Smrg       (this->type->contains_sampler() || this->type->contains_image()))
1467b8e80941Smrg      return true;
1468b8e80941Smrg
1469b8e80941Smrg   /* From section 4.1.7 of the GLSL 4.40 spec:
1470b8e80941Smrg    *
1471b8e80941Smrg    *   "Opaque variables cannot be treated as l-values; hence cannot
1472b8e80941Smrg    *    be used as out or inout function parameters, nor can they be
1473b8e80941Smrg    *    assigned into."
1474b8e80941Smrg    */
1475b8e80941Smrg   if (this->type->contains_opaque())
1476b8e80941Smrg      return false;
1477b8e80941Smrg
1478b8e80941Smrg   return true;
1479b8e80941Smrg}
1480b8e80941Smrg
1481b8e80941Smrg
1482b8e80941Smrgstatic const char * const tex_opcode_strs[] = { "tex", "txb", "txl", "txd", "txf", "txf_ms", "txs", "lod", "tg4", "query_levels", "texture_samples", "samples_identical" };
1483b8e80941Smrg
1484b8e80941Smrgconst char *ir_texture::opcode_string()
1485b8e80941Smrg{
1486b8e80941Smrg   assert((unsigned int) op < ARRAY_SIZE(tex_opcode_strs));
1487b8e80941Smrg   return tex_opcode_strs[op];
1488b8e80941Smrg}
1489b8e80941Smrg
1490b8e80941Smrgir_texture_opcode
1491b8e80941Smrgir_texture::get_opcode(const char *str)
1492b8e80941Smrg{
1493b8e80941Smrg   const int count = sizeof(tex_opcode_strs) / sizeof(tex_opcode_strs[0]);
1494b8e80941Smrg   for (int op = 0; op < count; op++) {
1495b8e80941Smrg      if (strcmp(str, tex_opcode_strs[op]) == 0)
1496b8e80941Smrg	 return (ir_texture_opcode) op;
1497b8e80941Smrg   }
1498b8e80941Smrg   return (ir_texture_opcode) -1;
1499b8e80941Smrg}
1500b8e80941Smrg
1501b8e80941Smrg
1502b8e80941Smrgvoid
1503b8e80941Smrgir_texture::set_sampler(ir_dereference *sampler, const glsl_type *type)
1504b8e80941Smrg{
1505b8e80941Smrg   assert(sampler != NULL);
1506b8e80941Smrg   assert(type != NULL);
1507b8e80941Smrg   this->sampler = sampler;
1508b8e80941Smrg   this->type = type;
1509b8e80941Smrg
1510b8e80941Smrg   if (this->op == ir_txs || this->op == ir_query_levels ||
1511b8e80941Smrg       this->op == ir_texture_samples) {
1512b8e80941Smrg      assert(type->base_type == GLSL_TYPE_INT);
1513b8e80941Smrg   } else if (this->op == ir_lod) {
1514b8e80941Smrg      assert(type->vector_elements == 2);
1515b8e80941Smrg      assert(type->is_float());
1516b8e80941Smrg   } else if (this->op == ir_samples_identical) {
1517b8e80941Smrg      assert(type == glsl_type::bool_type);
1518b8e80941Smrg      assert(sampler->type->is_sampler());
1519b8e80941Smrg      assert(sampler->type->sampler_dimensionality == GLSL_SAMPLER_DIM_MS);
1520b8e80941Smrg   } else {
1521b8e80941Smrg      assert(sampler->type->sampled_type == (int) type->base_type);
1522b8e80941Smrg      if (sampler->type->sampler_shadow)
1523b8e80941Smrg	 assert(type->vector_elements == 4 || type->vector_elements == 1);
1524b8e80941Smrg      else
1525b8e80941Smrg	 assert(type->vector_elements == 4);
1526b8e80941Smrg   }
1527b8e80941Smrg}
1528b8e80941Smrg
1529b8e80941Smrg
1530b8e80941Smrgvoid
1531b8e80941Smrgir_swizzle::init_mask(const unsigned *comp, unsigned count)
1532b8e80941Smrg{
1533b8e80941Smrg   assert((count >= 1) && (count <= 4));
1534b8e80941Smrg
1535b8e80941Smrg   memset(&this->mask, 0, sizeof(this->mask));
1536b8e80941Smrg   this->mask.num_components = count;
1537b8e80941Smrg
1538b8e80941Smrg   unsigned dup_mask = 0;
1539b8e80941Smrg   switch (count) {
1540b8e80941Smrg   case 4:
1541b8e80941Smrg      assert(comp[3] <= 3);
1542b8e80941Smrg      dup_mask |= (1U << comp[3])
1543b8e80941Smrg	 & ((1U << comp[0]) | (1U << comp[1]) | (1U << comp[2]));
1544b8e80941Smrg      this->mask.w = comp[3];
1545b8e80941Smrg
1546b8e80941Smrg   case 3:
1547b8e80941Smrg      assert(comp[2] <= 3);
1548b8e80941Smrg      dup_mask |= (1U << comp[2])
1549b8e80941Smrg	 & ((1U << comp[0]) | (1U << comp[1]));
1550b8e80941Smrg      this->mask.z = comp[2];
1551b8e80941Smrg
1552b8e80941Smrg   case 2:
1553b8e80941Smrg      assert(comp[1] <= 3);
1554b8e80941Smrg      dup_mask |= (1U << comp[1])
1555b8e80941Smrg	 & ((1U << comp[0]));
1556b8e80941Smrg      this->mask.y = comp[1];
1557b8e80941Smrg
1558b8e80941Smrg   case 1:
1559b8e80941Smrg      assert(comp[0] <= 3);
1560b8e80941Smrg      this->mask.x = comp[0];
1561b8e80941Smrg   }
1562b8e80941Smrg
1563b8e80941Smrg   this->mask.has_duplicates = dup_mask != 0;
1564b8e80941Smrg
1565b8e80941Smrg   /* Based on the number of elements in the swizzle and the base type
1566b8e80941Smrg    * (i.e., float, int, unsigned, or bool) of the vector being swizzled,
1567b8e80941Smrg    * generate the type of the resulting value.
1568b8e80941Smrg    */
1569b8e80941Smrg   type = glsl_type::get_instance(val->type->base_type, mask.num_components, 1);
1570b8e80941Smrg}
1571b8e80941Smrg
1572b8e80941Smrgir_swizzle::ir_swizzle(ir_rvalue *val, unsigned x, unsigned y, unsigned z,
1573b8e80941Smrg		       unsigned w, unsigned count)
1574b8e80941Smrg   : ir_rvalue(ir_type_swizzle), val(val)
1575b8e80941Smrg{
1576b8e80941Smrg   const unsigned components[4] = { x, y, z, w };
1577b8e80941Smrg   this->init_mask(components, count);
1578b8e80941Smrg}
1579b8e80941Smrg
1580b8e80941Smrgir_swizzle::ir_swizzle(ir_rvalue *val, const unsigned *comp,
1581b8e80941Smrg		       unsigned count)
1582b8e80941Smrg   : ir_rvalue(ir_type_swizzle), val(val)
1583b8e80941Smrg{
1584b8e80941Smrg   this->init_mask(comp, count);
1585b8e80941Smrg}
1586b8e80941Smrg
1587b8e80941Smrgir_swizzle::ir_swizzle(ir_rvalue *val, ir_swizzle_mask mask)
1588b8e80941Smrg   : ir_rvalue(ir_type_swizzle), val(val), mask(mask)
1589b8e80941Smrg{
1590b8e80941Smrg   this->type = glsl_type::get_instance(val->type->base_type,
1591b8e80941Smrg					mask.num_components, 1);
1592b8e80941Smrg}
1593b8e80941Smrg
1594b8e80941Smrg#define X 1
1595b8e80941Smrg#define R 5
1596b8e80941Smrg#define S 9
1597b8e80941Smrg#define I 13
1598b8e80941Smrg
1599b8e80941Smrgir_swizzle *
1600b8e80941Smrgir_swizzle::create(ir_rvalue *val, const char *str, unsigned vector_length)
1601b8e80941Smrg{
1602b8e80941Smrg   void *ctx = ralloc_parent(val);
1603b8e80941Smrg
1604b8e80941Smrg   /* For each possible swizzle character, this table encodes the value in
1605b8e80941Smrg    * \c idx_map that represents the 0th element of the vector.  For invalid
1606b8e80941Smrg    * swizzle characters (e.g., 'k'), a special value is used that will allow
1607b8e80941Smrg    * detection of errors.
1608b8e80941Smrg    */
1609b8e80941Smrg   static const unsigned char base_idx[26] = {
1610b8e80941Smrg   /* a  b  c  d  e  f  g  h  i  j  k  l  m */
1611b8e80941Smrg      R, R, I, I, I, I, R, I, I, I, I, I, I,
1612b8e80941Smrg   /* n  o  p  q  r  s  t  u  v  w  x  y  z */
1613b8e80941Smrg      I, I, S, S, R, S, S, I, I, X, X, X, X
1614b8e80941Smrg   };
1615b8e80941Smrg
1616b8e80941Smrg   /* Each valid swizzle character has an entry in the previous table.  This
1617b8e80941Smrg    * table encodes the base index encoded in the previous table plus the actual
1618b8e80941Smrg    * index of the swizzle character.  When processing swizzles, the first
1619b8e80941Smrg    * character in the string is indexed in the previous table.  Each character
1620b8e80941Smrg    * in the string is indexed in this table, and the value found there has the
1621b8e80941Smrg    * value form the first table subtracted.  The result must be on the range
1622b8e80941Smrg    * [0,3].
1623b8e80941Smrg    *
1624b8e80941Smrg    * For example, the string "wzyx" will get X from the first table.  Each of
1625b8e80941Smrg    * the charcaters will get X+3, X+2, X+1, and X+0 from this table.  After
1626b8e80941Smrg    * subtraction, the swizzle values are { 3, 2, 1, 0 }.
1627b8e80941Smrg    *
1628b8e80941Smrg    * The string "wzrg" will get X from the first table.  Each of the characters
1629b8e80941Smrg    * will get X+3, X+2, R+0, and R+1 from this table.  After subtraction, the
1630b8e80941Smrg    * swizzle values are { 3, 2, 4, 5 }.  Since 4 and 5 are outside the range
1631b8e80941Smrg    * [0,3], the error is detected.
1632b8e80941Smrg    */
1633b8e80941Smrg   static const unsigned char idx_map[26] = {
1634b8e80941Smrg   /* a    b    c    d    e    f    g    h    i    j    k    l    m */
1635b8e80941Smrg      R+3, R+2, 0,   0,   0,   0,   R+1, 0,   0,   0,   0,   0,   0,
1636b8e80941Smrg   /* n    o    p    q    r    s    t    u    v    w    x    y    z */
1637b8e80941Smrg      0,   0,   S+2, S+3, R+0, S+0, S+1, 0,   0,   X+3, X+0, X+1, X+2
1638b8e80941Smrg   };
1639b8e80941Smrg
1640b8e80941Smrg   int swiz_idx[4] = { 0, 0, 0, 0 };
1641b8e80941Smrg   unsigned i;
1642b8e80941Smrg
1643b8e80941Smrg
1644b8e80941Smrg   /* Validate the first character in the swizzle string and look up the base
1645b8e80941Smrg    * index value as described above.
1646b8e80941Smrg    */
1647b8e80941Smrg   if ((str[0] < 'a') || (str[0] > 'z'))
1648b8e80941Smrg      return NULL;
1649b8e80941Smrg
1650b8e80941Smrg   const unsigned base = base_idx[str[0] - 'a'];
1651b8e80941Smrg
1652b8e80941Smrg
1653b8e80941Smrg   for (i = 0; (i < 4) && (str[i] != '\0'); i++) {
1654b8e80941Smrg      /* Validate the next character, and, as described above, convert it to a
1655b8e80941Smrg       * swizzle index.
1656b8e80941Smrg       */
1657b8e80941Smrg      if ((str[i] < 'a') || (str[i] > 'z'))
1658b8e80941Smrg	 return NULL;
1659b8e80941Smrg
1660b8e80941Smrg      swiz_idx[i] = idx_map[str[i] - 'a'] - base;
1661b8e80941Smrg      if ((swiz_idx[i] < 0) || (swiz_idx[i] >= (int) vector_length))
1662b8e80941Smrg	 return NULL;
1663b8e80941Smrg   }
1664b8e80941Smrg
1665b8e80941Smrg   if (str[i] != '\0')
1666b8e80941Smrg	 return NULL;
1667b8e80941Smrg
1668b8e80941Smrg   return new(ctx) ir_swizzle(val, swiz_idx[0], swiz_idx[1], swiz_idx[2],
1669b8e80941Smrg			      swiz_idx[3], i);
1670b8e80941Smrg}
1671b8e80941Smrg
1672b8e80941Smrg#undef X
1673b8e80941Smrg#undef R
1674b8e80941Smrg#undef S
1675b8e80941Smrg#undef I
1676b8e80941Smrg
1677b8e80941Smrgir_variable *
1678b8e80941Smrgir_swizzle::variable_referenced() const
1679b8e80941Smrg{
1680b8e80941Smrg   return this->val->variable_referenced();
1681b8e80941Smrg}
1682b8e80941Smrg
1683b8e80941Smrg
1684b8e80941Smrgbool ir_variable::temporaries_allocate_names = false;
1685b8e80941Smrg
1686b8e80941Smrgconst char ir_variable::tmp_name[] = "compiler_temp";
1687b8e80941Smrg
1688b8e80941Smrgir_variable::ir_variable(const struct glsl_type *type, const char *name,
1689b8e80941Smrg			 ir_variable_mode mode)
1690b8e80941Smrg   : ir_instruction(ir_type_variable)
1691b8e80941Smrg{
1692b8e80941Smrg   this->type = type;
1693b8e80941Smrg
1694b8e80941Smrg   if (mode == ir_var_temporary && !ir_variable::temporaries_allocate_names)
1695b8e80941Smrg      name = NULL;
1696b8e80941Smrg
1697b8e80941Smrg   /* The ir_variable clone method may call this constructor with name set to
1698b8e80941Smrg    * tmp_name.
1699b8e80941Smrg    */
1700b8e80941Smrg   assert(name != NULL
1701b8e80941Smrg          || mode == ir_var_temporary
1702b8e80941Smrg          || mode == ir_var_function_in
1703b8e80941Smrg          || mode == ir_var_function_out
1704b8e80941Smrg          || mode == ir_var_function_inout);
1705b8e80941Smrg   assert(name != ir_variable::tmp_name
1706b8e80941Smrg          || mode == ir_var_temporary);
1707b8e80941Smrg   if (mode == ir_var_temporary
1708b8e80941Smrg       && (name == NULL || name == ir_variable::tmp_name)) {
1709b8e80941Smrg      this->name = ir_variable::tmp_name;
1710b8e80941Smrg   } else if (name == NULL ||
1711b8e80941Smrg              strlen(name) < ARRAY_SIZE(this->name_storage)) {
1712b8e80941Smrg      strcpy(this->name_storage, name ? name : "");
1713b8e80941Smrg      this->name = this->name_storage;
1714b8e80941Smrg   } else {
1715b8e80941Smrg      this->name = ralloc_strdup(this, name);
1716b8e80941Smrg   }
1717b8e80941Smrg
1718b8e80941Smrg   this->u.max_ifc_array_access = NULL;
1719b8e80941Smrg
1720b8e80941Smrg   this->data.explicit_location = false;
1721b8e80941Smrg   this->data.has_initializer = false;
1722b8e80941Smrg   this->data.location = -1;
1723b8e80941Smrg   this->data.location_frac = 0;
1724b8e80941Smrg   this->data.binding = 0;
1725b8e80941Smrg   this->data.warn_extension_index = 0;
1726b8e80941Smrg   this->constant_value = NULL;
1727b8e80941Smrg   this->constant_initializer = NULL;
1728b8e80941Smrg   this->data.depth_layout = ir_depth_layout_none;
1729b8e80941Smrg   this->data.used = false;
1730b8e80941Smrg   this->data.always_active_io = false;
1731b8e80941Smrg   this->data.read_only = false;
1732b8e80941Smrg   this->data.centroid = false;
1733b8e80941Smrg   this->data.sample = false;
1734b8e80941Smrg   this->data.patch = false;
1735b8e80941Smrg   this->data.explicit_invariant = false;
1736b8e80941Smrg   this->data.invariant = false;
1737b8e80941Smrg   this->data.how_declared = ir_var_declared_normally;
1738b8e80941Smrg   this->data.mode = mode;
1739b8e80941Smrg   this->data.interpolation = INTERP_MODE_NONE;
1740b8e80941Smrg   this->data.max_array_access = -1;
1741b8e80941Smrg   this->data.offset = 0;
1742b8e80941Smrg   this->data.precision = GLSL_PRECISION_NONE;
1743b8e80941Smrg   this->data.memory_read_only = false;
1744b8e80941Smrg   this->data.memory_write_only = false;
1745b8e80941Smrg   this->data.memory_coherent = false;
1746b8e80941Smrg   this->data.memory_volatile = false;
1747b8e80941Smrg   this->data.memory_restrict = false;
1748b8e80941Smrg   this->data.from_ssbo_unsized_array = false;
1749b8e80941Smrg   this->data.fb_fetch_output = false;
1750b8e80941Smrg   this->data.bindless = false;
1751b8e80941Smrg   this->data.bound = false;
1752b8e80941Smrg
1753b8e80941Smrg   if (type != NULL) {
1754b8e80941Smrg      if (type->is_interface())
1755b8e80941Smrg         this->init_interface_type(type);
1756b8e80941Smrg      else if (type->without_array()->is_interface())
1757b8e80941Smrg         this->init_interface_type(type->without_array());
1758b8e80941Smrg   }
1759b8e80941Smrg}
1760b8e80941Smrg
1761b8e80941Smrg
1762b8e80941Smrgconst char *
1763b8e80941Smrginterpolation_string(unsigned interpolation)
1764b8e80941Smrg{
1765b8e80941Smrg   switch (interpolation) {
1766b8e80941Smrg   case INTERP_MODE_NONE:          return "no";
1767b8e80941Smrg   case INTERP_MODE_SMOOTH:        return "smooth";
1768b8e80941Smrg   case INTERP_MODE_FLAT:          return "flat";
1769b8e80941Smrg   case INTERP_MODE_NOPERSPECTIVE: return "noperspective";
1770b8e80941Smrg   }
1771b8e80941Smrg
1772b8e80941Smrg   assert(!"Should not get here.");
1773b8e80941Smrg   return "";
1774b8e80941Smrg}
1775b8e80941Smrg
1776b8e80941Smrgconst char *const ir_variable::warn_extension_table[] = {
1777b8e80941Smrg   "",
1778b8e80941Smrg   "GL_ARB_shader_stencil_export",
1779b8e80941Smrg   "GL_AMD_shader_stencil_export",
1780b8e80941Smrg};
1781b8e80941Smrg
1782b8e80941Smrgvoid
1783b8e80941Smrgir_variable::enable_extension_warning(const char *extension)
1784b8e80941Smrg{
1785b8e80941Smrg   for (unsigned i = 0; i < ARRAY_SIZE(warn_extension_table); i++) {
1786b8e80941Smrg      if (strcmp(warn_extension_table[i], extension) == 0) {
1787b8e80941Smrg         this->data.warn_extension_index = i;
1788b8e80941Smrg         return;
1789b8e80941Smrg      }
1790b8e80941Smrg   }
1791b8e80941Smrg
1792b8e80941Smrg   assert(!"Should not get here.");
1793b8e80941Smrg   this->data.warn_extension_index = 0;
1794b8e80941Smrg}
1795b8e80941Smrg
1796b8e80941Smrgconst char *
1797b8e80941Smrgir_variable::get_extension_warning() const
1798b8e80941Smrg{
1799b8e80941Smrg   return this->data.warn_extension_index == 0
1800b8e80941Smrg      ? NULL : warn_extension_table[this->data.warn_extension_index];
1801b8e80941Smrg}
1802b8e80941Smrg
1803b8e80941Smrgir_function_signature::ir_function_signature(const glsl_type *return_type,
1804b8e80941Smrg                                             builtin_available_predicate b)
1805b8e80941Smrg   : ir_instruction(ir_type_function_signature),
1806b8e80941Smrg     return_type(return_type), is_defined(false),
1807b8e80941Smrg     intrinsic_id(ir_intrinsic_invalid), builtin_avail(b), _function(NULL)
1808b8e80941Smrg{
1809b8e80941Smrg   this->origin = NULL;
1810b8e80941Smrg}
1811b8e80941Smrg
1812b8e80941Smrg
1813b8e80941Smrgbool
1814b8e80941Smrgir_function_signature::is_builtin() const
1815b8e80941Smrg{
1816b8e80941Smrg   return builtin_avail != NULL;
1817b8e80941Smrg}
1818b8e80941Smrg
1819b8e80941Smrg
1820b8e80941Smrgbool
1821b8e80941Smrgir_function_signature::is_builtin_available(const _mesa_glsl_parse_state *state) const
1822b8e80941Smrg{
1823b8e80941Smrg   /* We can't call the predicate without a state pointer, so just say that
1824b8e80941Smrg    * the signature is available.  At compile time, we need the filtering,
1825b8e80941Smrg    * but also receive a valid state pointer.  At link time, we're resolving
1826b8e80941Smrg    * imported built-in prototypes to their definitions, which will always
1827b8e80941Smrg    * be an exact match.  So we can skip the filtering.
1828b8e80941Smrg    */
1829b8e80941Smrg   if (state == NULL)
1830b8e80941Smrg      return true;
1831b8e80941Smrg
1832b8e80941Smrg   assert(builtin_avail != NULL);
1833b8e80941Smrg   return builtin_avail(state);
1834b8e80941Smrg}
1835b8e80941Smrg
1836b8e80941Smrg
1837b8e80941Smrgstatic bool
1838b8e80941Smrgmodes_match(unsigned a, unsigned b)
1839b8e80941Smrg{
1840b8e80941Smrg   if (a == b)
1841b8e80941Smrg      return true;
1842b8e80941Smrg
1843b8e80941Smrg   /* Accept "in" vs. "const in" */
1844b8e80941Smrg   if ((a == ir_var_const_in && b == ir_var_function_in) ||
1845b8e80941Smrg       (b == ir_var_const_in && a == ir_var_function_in))
1846b8e80941Smrg      return true;
1847b8e80941Smrg
1848b8e80941Smrg   return false;
1849b8e80941Smrg}
1850b8e80941Smrg
1851b8e80941Smrg
1852b8e80941Smrgconst char *
1853b8e80941Smrgir_function_signature::qualifiers_match(exec_list *params)
1854b8e80941Smrg{
1855b8e80941Smrg   /* check that the qualifiers match. */
1856b8e80941Smrg   foreach_two_lists(a_node, &this->parameters, b_node, params) {
1857b8e80941Smrg      ir_variable *a = (ir_variable *) a_node;
1858b8e80941Smrg      ir_variable *b = (ir_variable *) b_node;
1859b8e80941Smrg
1860b8e80941Smrg      if (a->data.read_only != b->data.read_only ||
1861b8e80941Smrg	  !modes_match(a->data.mode, b->data.mode) ||
1862b8e80941Smrg	  a->data.interpolation != b->data.interpolation ||
1863b8e80941Smrg	  a->data.centroid != b->data.centroid ||
1864b8e80941Smrg          a->data.sample != b->data.sample ||
1865b8e80941Smrg          a->data.patch != b->data.patch ||
1866b8e80941Smrg          a->data.memory_read_only != b->data.memory_read_only ||
1867b8e80941Smrg          a->data.memory_write_only != b->data.memory_write_only ||
1868b8e80941Smrg          a->data.memory_coherent != b->data.memory_coherent ||
1869b8e80941Smrg          a->data.memory_volatile != b->data.memory_volatile ||
1870b8e80941Smrg          a->data.memory_restrict != b->data.memory_restrict) {
1871b8e80941Smrg
1872b8e80941Smrg	 /* parameter a's qualifiers don't match */
1873b8e80941Smrg	 return a->name;
1874b8e80941Smrg      }
1875b8e80941Smrg   }
1876b8e80941Smrg   return NULL;
1877b8e80941Smrg}
1878b8e80941Smrg
1879b8e80941Smrg
1880b8e80941Smrgvoid
1881b8e80941Smrgir_function_signature::replace_parameters(exec_list *new_params)
1882b8e80941Smrg{
1883b8e80941Smrg   /* Destroy all of the previous parameter information.  If the previous
1884b8e80941Smrg    * parameter information comes from the function prototype, it may either
1885b8e80941Smrg    * specify incorrect parameter names or not have names at all.
1886b8e80941Smrg    */
1887b8e80941Smrg   new_params->move_nodes_to(&parameters);
1888b8e80941Smrg}
1889b8e80941Smrg
1890b8e80941Smrg
1891b8e80941Smrgir_function::ir_function(const char *name)
1892b8e80941Smrg   : ir_instruction(ir_type_function)
1893b8e80941Smrg{
1894b8e80941Smrg   this->subroutine_index = -1;
1895b8e80941Smrg   this->name = ralloc_strdup(this, name);
1896b8e80941Smrg}
1897b8e80941Smrg
1898b8e80941Smrg
1899b8e80941Smrgbool
1900b8e80941Smrgir_function::has_user_signature()
1901b8e80941Smrg{
1902b8e80941Smrg   foreach_in_list(ir_function_signature, sig, &this->signatures) {
1903b8e80941Smrg      if (!sig->is_builtin())
1904b8e80941Smrg	 return true;
1905b8e80941Smrg   }
1906b8e80941Smrg   return false;
1907b8e80941Smrg}
1908b8e80941Smrg
1909b8e80941Smrg
1910b8e80941Smrgir_rvalue *
1911b8e80941Smrgir_rvalue::error_value(void *mem_ctx)
1912b8e80941Smrg{
1913b8e80941Smrg   ir_rvalue *v = new(mem_ctx) ir_rvalue(ir_type_unset);
1914b8e80941Smrg
1915b8e80941Smrg   v->type = glsl_type::error_type;
1916b8e80941Smrg   return v;
1917b8e80941Smrg}
1918b8e80941Smrg
1919b8e80941Smrg
1920b8e80941Smrgvoid
1921b8e80941Smrgvisit_exec_list(exec_list *list, ir_visitor *visitor)
1922b8e80941Smrg{
1923b8e80941Smrg   foreach_in_list_safe(ir_instruction, node, list) {
1924b8e80941Smrg      node->accept(visitor);
1925b8e80941Smrg   }
1926b8e80941Smrg}
1927b8e80941Smrg
1928b8e80941Smrg
1929b8e80941Smrgstatic void
1930b8e80941Smrgsteal_memory(ir_instruction *ir, void *new_ctx)
1931b8e80941Smrg{
1932b8e80941Smrg   ir_variable *var = ir->as_variable();
1933b8e80941Smrg   ir_function *fn = ir->as_function();
1934b8e80941Smrg   ir_constant *constant = ir->as_constant();
1935b8e80941Smrg   if (var != NULL && var->constant_value != NULL)
1936b8e80941Smrg      steal_memory(var->constant_value, ir);
1937b8e80941Smrg
1938b8e80941Smrg   if (var != NULL && var->constant_initializer != NULL)
1939b8e80941Smrg      steal_memory(var->constant_initializer, ir);
1940b8e80941Smrg
1941b8e80941Smrg   if (fn != NULL && fn->subroutine_types)
1942b8e80941Smrg      ralloc_steal(new_ctx, fn->subroutine_types);
1943b8e80941Smrg
1944b8e80941Smrg   /* The components of aggregate constants are not visited by the normal
1945b8e80941Smrg    * visitor, so steal their values by hand.
1946b8e80941Smrg    */
1947b8e80941Smrg   if (constant != NULL &&
1948b8e80941Smrg       (constant->type->is_array() || constant->type->is_struct())) {
1949b8e80941Smrg      for (unsigned int i = 0; i < constant->type->length; i++) {
1950b8e80941Smrg         steal_memory(constant->const_elements[i], ir);
1951b8e80941Smrg      }
1952b8e80941Smrg   }
1953b8e80941Smrg
1954b8e80941Smrg   ralloc_steal(new_ctx, ir);
1955b8e80941Smrg}
1956b8e80941Smrg
1957b8e80941Smrg
1958b8e80941Smrgvoid
1959b8e80941Smrgreparent_ir(exec_list *list, void *mem_ctx)
1960b8e80941Smrg{
1961b8e80941Smrg   foreach_in_list(ir_instruction, node, list) {
1962b8e80941Smrg      visit_tree(node, steal_memory, mem_ctx);
1963b8e80941Smrg   }
1964b8e80941Smrg}
1965b8e80941Smrg
1966b8e80941Smrg
1967b8e80941Smrgstatic ir_rvalue *
1968b8e80941Smrgtry_min_one(ir_rvalue *ir)
1969b8e80941Smrg{
1970b8e80941Smrg   ir_expression *expr = ir->as_expression();
1971b8e80941Smrg
1972b8e80941Smrg   if (!expr || expr->operation != ir_binop_min)
1973b8e80941Smrg      return NULL;
1974b8e80941Smrg
1975b8e80941Smrg   if (expr->operands[0]->is_one())
1976b8e80941Smrg      return expr->operands[1];
1977b8e80941Smrg
1978b8e80941Smrg   if (expr->operands[1]->is_one())
1979b8e80941Smrg      return expr->operands[0];
1980b8e80941Smrg
1981b8e80941Smrg   return NULL;
1982b8e80941Smrg}
1983b8e80941Smrg
1984b8e80941Smrgstatic ir_rvalue *
1985b8e80941Smrgtry_max_zero(ir_rvalue *ir)
1986b8e80941Smrg{
1987b8e80941Smrg   ir_expression *expr = ir->as_expression();
1988b8e80941Smrg
1989b8e80941Smrg   if (!expr || expr->operation != ir_binop_max)
1990b8e80941Smrg      return NULL;
1991b8e80941Smrg
1992b8e80941Smrg   if (expr->operands[0]->is_zero())
1993b8e80941Smrg      return expr->operands[1];
1994b8e80941Smrg
1995b8e80941Smrg   if (expr->operands[1]->is_zero())
1996b8e80941Smrg      return expr->operands[0];
1997b8e80941Smrg
1998b8e80941Smrg   return NULL;
1999b8e80941Smrg}
2000b8e80941Smrg
2001b8e80941Smrgir_rvalue *
2002b8e80941Smrgir_rvalue::as_rvalue_to_saturate()
2003b8e80941Smrg{
2004b8e80941Smrg   ir_expression *expr = this->as_expression();
2005b8e80941Smrg
2006b8e80941Smrg   if (!expr)
2007b8e80941Smrg      return NULL;
2008b8e80941Smrg
2009b8e80941Smrg   ir_rvalue *max_zero = try_max_zero(expr);
2010b8e80941Smrg   if (max_zero) {
2011b8e80941Smrg      return try_min_one(max_zero);
2012b8e80941Smrg   } else {
2013b8e80941Smrg      ir_rvalue *min_one = try_min_one(expr);
2014b8e80941Smrg      if (min_one) {
2015b8e80941Smrg	 return try_max_zero(min_one);
2016b8e80941Smrg      }
2017b8e80941Smrg   }
2018b8e80941Smrg
2019b8e80941Smrg   return NULL;
2020b8e80941Smrg}
2021b8e80941Smrg
2022b8e80941Smrg
2023b8e80941Smrgunsigned
2024b8e80941Smrgvertices_per_prim(GLenum prim)
2025b8e80941Smrg{
2026b8e80941Smrg   switch (prim) {
2027b8e80941Smrg   case GL_POINTS:
2028b8e80941Smrg      return 1;
2029b8e80941Smrg   case GL_LINES:
2030b8e80941Smrg      return 2;
2031b8e80941Smrg   case GL_TRIANGLES:
2032b8e80941Smrg      return 3;
2033b8e80941Smrg   case GL_LINES_ADJACENCY:
2034b8e80941Smrg      return 4;
2035b8e80941Smrg   case GL_TRIANGLES_ADJACENCY:
2036b8e80941Smrg      return 6;
2037b8e80941Smrg   default:
2038b8e80941Smrg      assert(!"Bad primitive");
2039b8e80941Smrg      return 3;
2040b8e80941Smrg   }
2041b8e80941Smrg}
2042b8e80941Smrg
2043b8e80941Smrg/**
2044b8e80941Smrg * Generate a string describing the mode of a variable
2045b8e80941Smrg */
2046b8e80941Smrgconst char *
2047b8e80941Smrgmode_string(const ir_variable *var)
2048b8e80941Smrg{
2049b8e80941Smrg   switch (var->data.mode) {
2050b8e80941Smrg   case ir_var_auto:
2051b8e80941Smrg      return (var->data.read_only) ? "global constant" : "global variable";
2052b8e80941Smrg
2053b8e80941Smrg   case ir_var_uniform:
2054b8e80941Smrg      return "uniform";
2055b8e80941Smrg
2056b8e80941Smrg   case ir_var_shader_storage:
2057b8e80941Smrg      return "buffer";
2058b8e80941Smrg
2059b8e80941Smrg   case ir_var_shader_in:
2060b8e80941Smrg      return "shader input";
2061b8e80941Smrg
2062b8e80941Smrg   case ir_var_shader_out:
2063b8e80941Smrg      return "shader output";
2064b8e80941Smrg
2065b8e80941Smrg   case ir_var_function_in:
2066b8e80941Smrg   case ir_var_const_in:
2067b8e80941Smrg      return "function input";
2068b8e80941Smrg
2069b8e80941Smrg   case ir_var_function_out:
2070b8e80941Smrg      return "function output";
2071b8e80941Smrg
2072b8e80941Smrg   case ir_var_function_inout:
2073b8e80941Smrg      return "function inout";
2074b8e80941Smrg
2075b8e80941Smrg   case ir_var_system_value:
2076b8e80941Smrg      return "shader input";
2077b8e80941Smrg
2078b8e80941Smrg   case ir_var_temporary:
2079b8e80941Smrg      return "compiler temporary";
2080b8e80941Smrg
2081b8e80941Smrg   case ir_var_mode_count:
2082b8e80941Smrg      break;
2083b8e80941Smrg   }
2084b8e80941Smrg
2085b8e80941Smrg   assert(!"Should not get here.");
2086b8e80941Smrg   return "invalid variable";
2087b8e80941Smrg}
2088